377064 - Add org.eclipse.jpt.ui to 2.3.5 patches stream to fix noted
bug.
diff --git a/jpa/plugins/org.eclipse.jpt.ui/.classpath b/jpa/plugins/org.eclipse.jpt.ui/.classpath
new file mode 100644
index 0000000..5ee7c76
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/.classpath
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" path="src"/>
+	<classpathentry kind="src" path="property_files"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
+	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins">
+		<accessrules>
+			<accessrule kind="accessible" pattern="org/eclipse/wst/**"/>
+			<accessrule kind="accessible" pattern="org/eclipse/jst/**"/>
+		</accessrules>
+	</classpathentry>
+	<classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/jpa/plugins/org.eclipse.jpt.ui/.gitignore b/jpa/plugins/org.eclipse.jpt.ui/.gitignore
new file mode 100644
index 0000000..c5e82d7
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/.gitignore
@@ -0,0 +1 @@
+bin
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/.jetproperties b/jpa/plugins/org.eclipse.jpt.ui/.jetproperties
new file mode 100644
index 0000000..2907c83
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/.jetproperties
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<jet-settings>
+	<template-container>templates</template-container>	<source-container>src</source-container>
+</jet-settings>
diff --git a/jpa/plugins/org.eclipse.jpt.ui/.options b/jpa/plugins/org.eclipse.jpt.ui/.options
new file mode 100644
index 0000000..37e1229
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/.options
@@ -0,0 +1,14 @@
+# Debugging options for org.eclipse.jpt.ui plug-in
+
+# Turn on debugging for the org.eclipse.jpt.ui plugin.
+org.eclipse.jpt.ui/debug=false
+
+# Turn on debugging for unit-tests
+org.eclipse.jpt.ui/debug/unit-tests=false
+
+# Turn on debugging for events occurring in the UI panes
+org.eclipse.jpt.ui/debug/ui/layout=false
+org.eclipse.jpt.ui/debug/ui/detailsView=false
+
+# Turn on debugging for events coming from ConnectionProfile
+org.eclipse.jpt.ui/debug/ui/db=false
diff --git a/jpa/plugins/org.eclipse.jpt.ui/.project b/jpa/plugins/org.eclipse.jpt.ui/.project
new file mode 100644
index 0000000..f1b147f
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/.project
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.jpt.ui</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.emf.codegen.JETBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.ManifestBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.SchemaBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.emf.codegen.jet.IJETNature</nature>
+		<nature>org.eclipse.pde.PluginNature</nature>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>
diff --git a/jpa/plugins/org.eclipse.jpt.ui/.settings/org.eclipse.core.resources.prefs b/jpa/plugins/org.eclipse.jpt.ui/.settings/org.eclipse.core.resources.prefs
new file mode 100644
index 0000000..2c6dda4
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/.settings/org.eclipse.core.resources.prefs
@@ -0,0 +1,3 @@
+#Tue Jan 15 11:12:14 EST 2008
+eclipse.preferences.version=1
+encoding/<project>=ISO-8859-1
diff --git a/jpa/plugins/org.eclipse.jpt.ui/.settings/org.eclipse.jdt.core.prefs b/jpa/plugins/org.eclipse.jpt.ui/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..d909c10
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,7 @@
+#Sun May 27 14:55:01 EDT 2007
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.5
diff --git a/jpa/plugins/org.eclipse.jpt.ui/META-INF/MANIFEST.MF b/jpa/plugins/org.eclipse.jpt.ui/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..62fcd65
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/META-INF/MANIFEST.MF
@@ -0,0 +1,96 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: %pluginName
+Bundle-Vendor: %providerName
+Bundle-SymbolicName: org.eclipse.jpt.ui;singleton:=true
+Bundle-Version: 2.3.3.qualifier
+Bundle-Activator: org.eclipse.jpt.ui.JptUiPlugin
+Bundle-ActivationPolicy: lazy
+Bundle-ClassPath: .
+Bundle-Localization: plugin
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
+Require-Bundle: org.eclipse.core.expressions;bundle-version="[3.4.0,4.0.0)",
+ org.eclipse.core.resources;bundle-version="[3.4.0,4.0.0)",
+ org.eclipse.draw2d;bundle-version="[3.4.0,4.0.0)",
+ org.eclipse.emf.codegen;bundle-version="[2.4.0,3.0.0)",
+ org.eclipse.emf.ecore.xmi;bundle-version="[2.5.0,3.0.0)",
+ org.eclipse.help;bundle-version="[3.4.0,4.0.0)",
+ org.eclipse.jdt.core;bundle-version="[3.4.0,4.0.0)",
+ org.eclipse.jdt.ui;bundle-version="[3.4.0,4.0.0)",
+ org.eclipse.jem.util;bundle-version="[2.0.100,3.0.0)",
+ org.eclipse.jface.text;bundle-version="[3.4.0,4.0.0)",
+ org.eclipse.jpt.core;bundle-version="[2.0.0,3.0.0)",
+ org.eclipse.jpt.db;bundle-version="[1.2.0,2.0.0)",
+ org.eclipse.jpt.db.ui;bundle-version="[1.0.1,2.0.0)",
+ org.eclipse.jpt.gen;bundle-version="[1.1.0,2.0.0)",
+ org.eclipse.jpt.utility;bundle-version="[1.2.0,2.0.0)",
+ org.eclipse.jst.common.annotations.controller;bundle-version="[1.1.100,1.2.0)",
+ org.eclipse.jst.common.project.facet.core;bundle-version="[1.3.100,2.0.0)",
+ org.eclipse.jst.common.project.facet.ui;bundle-version="[1.3.100,2.0.0)",
+ org.eclipse.jst.j2ee;bundle-version="[1.1.200,1.2.0)",
+ org.eclipse.jst.j2ee.ui;bundle-version="[1.1.200,2.0.0)",
+ org.eclipse.ui.ide;bundle-version="[3.4.0,4.0.0)",
+ org.eclipse.ui.views.properties.tabbed;bundle-version="[3.4.0,4.0.0)",
+ org.eclipse.ui.navigator;bundle-version="[3.3.100,4.0.0)",
+ org.eclipse.ui.navigator.resources;bundle-version="[3.3.100,4.0.0)",
+ org.eclipse.ui.workbench.texteditor;bundle-version="[3.4.0,4.0.0)",
+ org.eclipse.wst.common.emf;bundle-version="[1.1.200,2.0.0)",
+ org.eclipse.wst.common.frameworks.ui;bundle-version="[1.1.200,1.3.0)",
+ org.eclipse.wst.common.project.facet.ui;bundle-version="[1.3.0,2.0.0)",
+ org.eclipse.wst.sse.ui;bundle-version="[1.1.0,1.3.0)",
+ org.eclipse.wst.web.ui;bundle-version="[1.1.200,2.0.0)"
+Export-Package: org.eclipse.jpt.ui,
+ org.eclipse.jpt.ui.details,
+ org.eclipse.jpt.ui.details.java,
+ org.eclipse.jpt.ui.details.orm,
+ org.eclipse.jpt.ui.internal;x-internal:=true,
+ org.eclipse.jpt.ui.internal.actions;x-internal:=true,
+ org.eclipse.jpt.ui.internal.commands;x-internal:=true,
+ org.eclipse.jpt.ui.internal.details;x-internal:=true,
+ org.eclipse.jpt.ui.internal.details.db;x-internal:=true,
+ org.eclipse.jpt.ui.internal.details.java;x-internal:=true,
+ org.eclipse.jpt.ui.internal.details.orm;x-internal:=true,
+ org.eclipse.jpt.ui.internal.dialogs;x-internal:=true,
+ org.eclipse.jpt.ui.internal.editors;x-internal:=true,
+ org.eclipse.jpt.ui.internal.jface;x-internal:=true,
+ org.eclipse.jpt.ui.internal.jpa2;x-internal:=true,
+ org.eclipse.jpt.ui.internal.jpa2.details;x-internal:=true,
+ org.eclipse.jpt.ui.internal.jpa2.details.java;x-internal:=true,
+ org.eclipse.jpt.ui.internal.jpa2.details.orm;x-internal:=true,
+ org.eclipse.jpt.ui.internal.jpa2.persistence;x-internal:=true,
+ org.eclipse.jpt.ui.internal.jpa2.persistence.connection;x-internal:=true,
+ org.eclipse.jpt.ui.internal.jpa2.persistence.options;x-internal:=true,
+ org.eclipse.jpt.ui.internal.jpa2.platform.generic;x-internal:=true,
+ org.eclipse.jpt.ui.internal.listeners;x-internal:=true,
+ org.eclipse.jpt.ui.internal.menus;x-internal:=true,
+ org.eclipse.jpt.ui.internal.navigator;x-internal:=true,
+ org.eclipse.jpt.ui.internal.persistence;x-internal:=true,
+ org.eclipse.jpt.ui.internal.persistence.details;x-internal:=true,
+ org.eclipse.jpt.ui.internal.perspective;x-internal:=true,
+ org.eclipse.jpt.ui.internal.platform;x-internal:=true,
+ org.eclipse.jpt.ui.internal.platform.base;x-internal:=true,
+ org.eclipse.jpt.ui.internal.platform.generic;x-internal:=true,
+ org.eclipse.jpt.ui.internal.preferences;x-internal:=true,
+ org.eclipse.jpt.ui.internal.properties;x-internal:=true,
+ org.eclipse.jpt.ui.internal.selection;x-internal:=true,
+ org.eclipse.jpt.ui.internal.structure;x-internal:=true,
+ org.eclipse.jpt.ui.internal.swt;x-internal:=true,
+ org.eclipse.jpt.ui.internal.util;
+  x-friends:="org.eclipse.jpt.jaxb.ui",
+ org.eclipse.jpt.ui.internal.utility;x-internal:=true,
+ org.eclipse.jpt.ui.internal.utility.swt;x-internal:=true,
+ org.eclipse.jpt.ui.internal.views;x-internal:=true,
+ org.eclipse.jpt.ui.internal.views.structure;x-internal:=true,
+ org.eclipse.jpt.ui.internal.widgets;x-internal:=true,
+ org.eclipse.jpt.ui.internal.wizards;x-internal:=true,
+ org.eclipse.jpt.ui.internal.wizards.entity;x-internal:=true,
+ org.eclipse.jpt.ui.internal.wizards.entity.data.model;x-internal:=true,
+ org.eclipse.jpt.ui.internal.wizards.entity.data.operation;x-internal:=true,
+ org.eclipse.jpt.ui.internal.wizards.gen;x-internal:=true,
+ org.eclipse.jpt.ui.internal.wizards.orm;x-internal:=true,
+ org.eclipse.jpt.ui.jface,
+ org.eclipse.jpt.ui.jpa2.details.java,
+ org.eclipse.jpt.ui.jpa2.details.orm,
+ org.eclipse.jpt.ui.navigator,
+ org.eclipse.jpt.ui.structure
+Import-Package: com.ibm.icu.text;version="4.0.1"
diff --git a/jpa/plugins/org.eclipse.jpt.ui/about.html b/jpa/plugins/org.eclipse.jpt.ui/about.html
new file mode 100644
index 0000000..be534ba
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/about.html
@@ -0,0 +1,34 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
+<HTML>
+
+<head>
+<title>About</title>
+<meta http-equiv=Content-Type content="text/html; charset=ISO-8859-1">
+</head>
+
+<BODY lang="EN-US">
+
+<H3>About This Content</H3>
+
+<P>May 02, 2008</P>
+
+<H3>License</H3>
+
+<P>The Eclipse Foundation makes available all content in this plug-in 
+("Content"). Unless otherwise indicated below, the Content is provided to you 
+under the terms and conditions of the Eclipse Public License Version 1.0 
+("EPL"). A copy of the EPL is available at
+<A href="http://www.eclipse.org/org/documents/epl-v10.php">http://www.eclipse.org/org/documents/epl-v10.php</A>. 
+For purposes of the EPL, "Program" will mean the Content.</P>
+
+<P>If you did not receive this Content directly from the Eclipse Foundation, the 
+Content is being redistributed by another party ("Redistributor") and different 
+terms and conditions may apply to your use of any object code in the Content. 
+Check the Redistributor's license that was provided with the Content. If no such 
+license exists, contact the Redistributor. Unless otherwise indicated below, the 
+terms and conditions of the EPL still apply to any source code in the Content 
+and such source code may be obtained at
+<A href="http://www.eclipse.org/">http://www.eclipse.org/</A>.</P>
+
+</BODY>
+</HTML>
diff --git a/jpa/plugins/org.eclipse.jpt.ui/build.properties b/jpa/plugins/org.eclipse.jpt.ui/build.properties
new file mode 100644
index 0000000..83fdfc7
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/build.properties
@@ -0,0 +1,26 @@
+################################################################################
+# Copyright (c) 2006, 2009 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
+################################################################################
+javacSource = 1.5
+javacTarget = 1.5
+source.. = src/,\
+               property_files/
+output.. = bin/
+bin.includes = .,\
+               META-INF/,\
+               about.html,\
+               icons/,\
+               plugin.xml,\
+               plugin.properties,\
+               templates/,\
+               images/
+jars.compile.order = .
+src.includes = templates/,\
+               schema/
+
diff --git a/jpa/plugins/org.eclipse.jpt.ui/component.xml b/jpa/plugins/org.eclipse.jpt.ui/component.xml
new file mode 100644
index 0000000..2283459
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/component.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Copyright (c) 2007, 2010 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
+ -->
+
+<component  xmlns="http://eclipse.org/wtp/releng/tools/component-model" name="org.eclipse.jpt.ui"><description url=""></description><component-depends unrestricted="true"></component-depends><plugin id="org.eclipse.jpt.ui" fragment="false"/></component>
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/icons/full/dtool16/new_entity_wiz.gif b/jpa/plugins/org.eclipse.jpt.ui/icons/full/dtool16/new_entity_wiz.gif
new file mode 100644
index 0000000..55f7cc9
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/icons/full/dtool16/new_entity_wiz.gif
Binary files differ
diff --git a/jpa/plugins/org.eclipse.jpt.ui/icons/full/dtool16/new_jpa_file_wiz.gif b/jpa/plugins/org.eclipse.jpt.ui/icons/full/dtool16/new_jpa_file_wiz.gif
new file mode 100644
index 0000000..610f604
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/icons/full/dtool16/new_jpa_file_wiz.gif
Binary files differ
diff --git a/jpa/plugins/org.eclipse.jpt.ui/icons/full/dtool16/new_jpaproject_wiz.gif b/jpa/plugins/org.eclipse.jpt.ui/icons/full/dtool16/new_jpaproject_wiz.gif
new file mode 100644
index 0000000..633768f
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/icons/full/dtool16/new_jpaproject_wiz.gif
Binary files differ
diff --git a/jpa/plugins/org.eclipse.jpt.ui/icons/full/etool16/jpa_facet.gif b/jpa/plugins/org.eclipse.jpt.ui/icons/full/etool16/jpa_facet.gif
new file mode 100644
index 0000000..c0ab917
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/icons/full/etool16/jpa_facet.gif
Binary files differ
diff --git a/jpa/plugins/org.eclipse.jpt.ui/icons/full/etool16/new_entity_wiz.gif b/jpa/plugins/org.eclipse.jpt.ui/icons/full/etool16/new_entity_wiz.gif
new file mode 100644
index 0000000..8533ca1
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/icons/full/etool16/new_entity_wiz.gif
Binary files differ
diff --git a/jpa/plugins/org.eclipse.jpt.ui/icons/full/etool16/new_jpa_file_wiz.gif b/jpa/plugins/org.eclipse.jpt.ui/icons/full/etool16/new_jpa_file_wiz.gif
new file mode 100644
index 0000000..6e0042e
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/icons/full/etool16/new_jpa_file_wiz.gif
Binary files differ
diff --git a/jpa/plugins/org.eclipse.jpt.ui/icons/full/etool16/new_jpaproject_wiz.gif b/jpa/plugins/org.eclipse.jpt.ui/icons/full/etool16/new_jpaproject_wiz.gif
new file mode 100644
index 0000000..12da807
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/icons/full/etool16/new_jpaproject_wiz.gif
Binary files differ
diff --git a/jpa/plugins/org.eclipse.jpt.ui/icons/full/eview16/jpa_details.gif b/jpa/plugins/org.eclipse.jpt.ui/icons/full/eview16/jpa_details.gif
new file mode 100644
index 0000000..3280138
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/icons/full/eview16/jpa_details.gif
Binary files differ
diff --git a/jpa/plugins/org.eclipse.jpt.ui/icons/full/eview16/jpa_perspective.gif b/jpa/plugins/org.eclipse.jpt.ui/icons/full/eview16/jpa_perspective.gif
new file mode 100644
index 0000000..c0ab917
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/icons/full/eview16/jpa_perspective.gif
Binary files differ
diff --git a/jpa/plugins/org.eclipse.jpt.ui/icons/full/eview16/jpa_structure.gif b/jpa/plugins/org.eclipse.jpt.ui/icons/full/eview16/jpa_structure.gif
new file mode 100644
index 0000000..682c90a
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/icons/full/eview16/jpa_structure.gif
Binary files differ
diff --git a/jpa/plugins/org.eclipse.jpt.ui/icons/full/obj16/basic.gif b/jpa/plugins/org.eclipse.jpt.ui/icons/full/obj16/basic.gif
new file mode 100644
index 0000000..a547d74
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/icons/full/obj16/basic.gif
Binary files differ
diff --git a/jpa/plugins/org.eclipse.jpt.ui/icons/full/obj16/element-collection.gif b/jpa/plugins/org.eclipse.jpt.ui/icons/full/obj16/element-collection.gif
new file mode 100644
index 0000000..64706d2
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/icons/full/obj16/element-collection.gif
Binary files differ
diff --git a/jpa/plugins/org.eclipse.jpt.ui/icons/full/obj16/embeddable.gif b/jpa/plugins/org.eclipse.jpt.ui/icons/full/obj16/embeddable.gif
new file mode 100644
index 0000000..8856f78
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/icons/full/obj16/embeddable.gif
Binary files differ
diff --git a/jpa/plugins/org.eclipse.jpt.ui/icons/full/obj16/embedded-id.gif b/jpa/plugins/org.eclipse.jpt.ui/icons/full/obj16/embedded-id.gif
new file mode 100644
index 0000000..c1c8e21
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/icons/full/obj16/embedded-id.gif
Binary files differ
diff --git a/jpa/plugins/org.eclipse.jpt.ui/icons/full/obj16/embedded.gif b/jpa/plugins/org.eclipse.jpt.ui/icons/full/obj16/embedded.gif
new file mode 100644
index 0000000..c2ae664
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/icons/full/obj16/embedded.gif
Binary files differ
diff --git a/jpa/plugins/org.eclipse.jpt.ui/icons/full/obj16/entity-mappings.gif b/jpa/plugins/org.eclipse.jpt.ui/icons/full/obj16/entity-mappings.gif
new file mode 100644
index 0000000..c349c96
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/icons/full/obj16/entity-mappings.gif
Binary files differ
diff --git a/jpa/plugins/org.eclipse.jpt.ui/icons/full/obj16/entity.gif b/jpa/plugins/org.eclipse.jpt.ui/icons/full/obj16/entity.gif
new file mode 100644
index 0000000..d606f48
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/icons/full/obj16/entity.gif
Binary files differ
diff --git a/jpa/plugins/org.eclipse.jpt.ui/icons/full/obj16/id.gif b/jpa/plugins/org.eclipse.jpt.ui/icons/full/obj16/id.gif
new file mode 100644
index 0000000..a205ec3
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/icons/full/obj16/id.gif
Binary files differ
diff --git a/jpa/plugins/org.eclipse.jpt.ui/icons/full/obj16/jpa-content.gif b/jpa/plugins/org.eclipse.jpt.ui/icons/full/obj16/jpa-content.gif
new file mode 100644
index 0000000..c0ab917
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/icons/full/obj16/jpa-content.gif
Binary files differ
diff --git a/jpa/plugins/org.eclipse.jpt.ui/icons/full/obj16/jpa-file.gif b/jpa/plugins/org.eclipse.jpt.ui/icons/full/obj16/jpa-file.gif
new file mode 100644
index 0000000..b4e9f47
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/icons/full/obj16/jpa-file.gif
Binary files differ
diff --git a/jpa/plugins/org.eclipse.jpt.ui/icons/full/obj16/jpa-jar-file.gif b/jpa/plugins/org.eclipse.jpt.ui/icons/full/obj16/jpa-jar-file.gif
new file mode 100644
index 0000000..e92828d
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/icons/full/obj16/jpa-jar-file.gif
Binary files differ
diff --git a/jpa/plugins/org.eclipse.jpt.ui/icons/full/obj16/many-to-many.gif b/jpa/plugins/org.eclipse.jpt.ui/icons/full/obj16/many-to-many.gif
new file mode 100644
index 0000000..48885b2
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/icons/full/obj16/many-to-many.gif
Binary files differ
diff --git a/jpa/plugins/org.eclipse.jpt.ui/icons/full/obj16/many-to-one.gif b/jpa/plugins/org.eclipse.jpt.ui/icons/full/obj16/many-to-one.gif
new file mode 100644
index 0000000..2e1e2b9
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/icons/full/obj16/many-to-one.gif
Binary files differ
diff --git a/jpa/plugins/org.eclipse.jpt.ui/icons/full/obj16/mapped-superclass.gif b/jpa/plugins/org.eclipse.jpt.ui/icons/full/obj16/mapped-superclass.gif
new file mode 100644
index 0000000..8cc3764
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/icons/full/obj16/mapped-superclass.gif
Binary files differ
diff --git a/jpa/plugins/org.eclipse.jpt.ui/icons/full/obj16/null-attribute-mapping.gif b/jpa/plugins/org.eclipse.jpt.ui/icons/full/obj16/null-attribute-mapping.gif
new file mode 100644
index 0000000..70a9c23
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/icons/full/obj16/null-attribute-mapping.gif
Binary files differ
diff --git a/jpa/plugins/org.eclipse.jpt.ui/icons/full/obj16/null-type-mapping.gif b/jpa/plugins/org.eclipse.jpt.ui/icons/full/obj16/null-type-mapping.gif
new file mode 100644
index 0000000..6279478
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/icons/full/obj16/null-type-mapping.gif
Binary files differ
diff --git a/jpa/plugins/org.eclipse.jpt.ui/icons/full/obj16/one-to-many.gif b/jpa/plugins/org.eclipse.jpt.ui/icons/full/obj16/one-to-many.gif
new file mode 100644
index 0000000..1e90027
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/icons/full/obj16/one-to-many.gif
Binary files differ
diff --git a/jpa/plugins/org.eclipse.jpt.ui/icons/full/obj16/one-to-one.gif b/jpa/plugins/org.eclipse.jpt.ui/icons/full/obj16/one-to-one.gif
new file mode 100644
index 0000000..578ec36
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/icons/full/obj16/one-to-one.gif
Binary files differ
diff --git a/jpa/plugins/org.eclipse.jpt.ui/icons/full/obj16/persistence-unit.gif b/jpa/plugins/org.eclipse.jpt.ui/icons/full/obj16/persistence-unit.gif
new file mode 100644
index 0000000..9cc45f6
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/icons/full/obj16/persistence-unit.gif
Binary files differ
diff --git a/jpa/plugins/org.eclipse.jpt.ui/icons/full/obj16/persistence.gif b/jpa/plugins/org.eclipse.jpt.ui/icons/full/obj16/persistence.gif
new file mode 100644
index 0000000..d1f616d
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/icons/full/obj16/persistence.gif
Binary files differ
diff --git a/jpa/plugins/org.eclipse.jpt.ui/icons/full/obj16/transient.gif b/jpa/plugins/org.eclipse.jpt.ui/icons/full/obj16/transient.gif
new file mode 100644
index 0000000..cc5d83d
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/icons/full/obj16/transient.gif
Binary files differ
diff --git a/jpa/plugins/org.eclipse.jpt.ui/icons/full/obj16/version.gif b/jpa/plugins/org.eclipse.jpt.ui/icons/full/obj16/version.gif
new file mode 100644
index 0000000..202a810
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/icons/full/obj16/version.gif
Binary files differ
diff --git a/jpa/plugins/org.eclipse.jpt.ui/icons/full/obj16/warning.gif b/jpa/plugins/org.eclipse.jpt.ui/icons/full/obj16/warning.gif
new file mode 100644
index 0000000..14009e9
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/icons/full/obj16/warning.gif
Binary files differ
diff --git a/jpa/plugins/org.eclipse.jpt.ui/icons/full/wizban/jpa_facet_wizban.gif b/jpa/plugins/org.eclipse.jpt.ui/icons/full/wizban/jpa_facet_wizban.gif
new file mode 100644
index 0000000..8ce181f
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/icons/full/wizban/jpa_facet_wizban.gif
Binary files differ
diff --git a/jpa/plugins/org.eclipse.jpt.ui/icons/full/wizban/new_entity_wizban.gif b/jpa/plugins/org.eclipse.jpt.ui/icons/full/wizban/new_entity_wizban.gif
new file mode 100644
index 0000000..b1d934c
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/icons/full/wizban/new_entity_wizban.gif
Binary files differ
diff --git a/jpa/plugins/org.eclipse.jpt.ui/icons/full/wizban/new_jpa_file_wizban.gif b/jpa/plugins/org.eclipse.jpt.ui/icons/full/wizban/new_jpa_file_wizban.gif
new file mode 100644
index 0000000..e846223
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/icons/full/wizban/new_jpa_file_wizban.gif
Binary files differ
diff --git a/jpa/plugins/org.eclipse.jpt.ui/images/buttons/add-connection.gif b/jpa/plugins/org.eclipse.jpt.ui/images/buttons/add-connection.gif
new file mode 100644
index 0000000..864034f
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/images/buttons/add-connection.gif
Binary files differ
diff --git a/jpa/plugins/org.eclipse.jpt.ui/images/buttons/add.png b/jpa/plugins/org.eclipse.jpt.ui/images/buttons/add.png
new file mode 100644
index 0000000..6bd3486
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/images/buttons/add.png
Binary files differ
diff --git a/jpa/plugins/org.eclipse.jpt.ui/images/buttons/browse-mini.png b/jpa/plugins/org.eclipse.jpt.ui/images/buttons/browse-mini.png
new file mode 100644
index 0000000..1f64f24
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/images/buttons/browse-mini.png
Binary files differ
diff --git a/jpa/plugins/org.eclipse.jpt.ui/images/buttons/browse.png b/jpa/plugins/org.eclipse.jpt.ui/images/buttons/browse.png
new file mode 100644
index 0000000..8081fd9
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/images/buttons/browse.png
Binary files differ
diff --git a/jpa/plugins/org.eclipse.jpt.ui/images/buttons/collapse-all.png b/jpa/plugins/org.eclipse.jpt.ui/images/buttons/collapse-all.png
new file mode 100644
index 0000000..3582d18
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/images/buttons/collapse-all.png
Binary files differ
diff --git a/jpa/plugins/org.eclipse.jpt.ui/images/buttons/delete.png b/jpa/plugins/org.eclipse.jpt.ui/images/buttons/delete.png
new file mode 100644
index 0000000..afba8b4
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/images/buttons/delete.png
Binary files differ
diff --git a/jpa/plugins/org.eclipse.jpt.ui/images/buttons/deselect-all.png b/jpa/plugins/org.eclipse.jpt.ui/images/buttons/deselect-all.png
new file mode 100644
index 0000000..49544f5
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/images/buttons/deselect-all.png
Binary files differ
diff --git a/jpa/plugins/org.eclipse.jpt.ui/images/buttons/dot.gif b/jpa/plugins/org.eclipse.jpt.ui/images/buttons/dot.gif
new file mode 100644
index 0000000..57a514d
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/images/buttons/dot.gif
Binary files differ
diff --git a/jpa/plugins/org.eclipse.jpt.ui/images/buttons/edit.png b/jpa/plugins/org.eclipse.jpt.ui/images/buttons/edit.png
new file mode 100644
index 0000000..306d6a1
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/images/buttons/edit.png
Binary files differ
diff --git a/jpa/plugins/org.eclipse.jpt.ui/images/buttons/expand-all.png b/jpa/plugins/org.eclipse.jpt.ui/images/buttons/expand-all.png
new file mode 100644
index 0000000..db729a3
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/images/buttons/expand-all.png
Binary files differ
diff --git a/jpa/plugins/org.eclipse.jpt.ui/images/buttons/list-of-values.png b/jpa/plugins/org.eclipse.jpt.ui/images/buttons/list-of-values.png
new file mode 100644
index 0000000..8081fd9
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/images/buttons/list-of-values.png
Binary files differ
diff --git a/jpa/plugins/org.eclipse.jpt.ui/images/buttons/move-down.png b/jpa/plugins/org.eclipse.jpt.ui/images/buttons/move-down.png
new file mode 100644
index 0000000..f6e5281
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/images/buttons/move-down.png
Binary files differ
diff --git a/jpa/plugins/org.eclipse.jpt.ui/images/buttons/move-up.png b/jpa/plugins/org.eclipse.jpt.ui/images/buttons/move-up.png
new file mode 100644
index 0000000..7c8b1cc
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/images/buttons/move-up.png
Binary files differ
diff --git a/jpa/plugins/org.eclipse.jpt.ui/images/buttons/reconnect.png b/jpa/plugins/org.eclipse.jpt.ui/images/buttons/reconnect.png
new file mode 100644
index 0000000..df00946
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/images/buttons/reconnect.png
Binary files differ
diff --git a/jpa/plugins/org.eclipse.jpt.ui/images/buttons/restore-defaults.png b/jpa/plugins/org.eclipse.jpt.ui/images/buttons/restore-defaults.png
new file mode 100644
index 0000000..2d74ae4
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/images/buttons/restore-defaults.png
Binary files differ
diff --git a/jpa/plugins/org.eclipse.jpt.ui/images/buttons/select-all.png b/jpa/plugins/org.eclipse.jpt.ui/images/buttons/select-all.png
new file mode 100644
index 0000000..4eaff2b
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/images/buttons/select-all.png
Binary files differ
diff --git a/jpa/plugins/org.eclipse.jpt.ui/images/buttons/warningstd.png b/jpa/plugins/org.eclipse.jpt.ui/images/buttons/warningstd.png
new file mode 100644
index 0000000..a7b471c
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/images/buttons/warningstd.png
Binary files differ
diff --git a/jpa/plugins/org.eclipse.jpt.ui/images/diagram/export-as-img-hover.png b/jpa/plugins/org.eclipse.jpt.ui/images/diagram/export-as-img-hover.png
new file mode 100644
index 0000000..0751b32
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/images/diagram/export-as-img-hover.png
Binary files differ
diff --git a/jpa/plugins/org.eclipse.jpt.ui/images/diagram/export-as-img.png b/jpa/plugins/org.eclipse.jpt.ui/images/diagram/export-as-img.png
new file mode 100644
index 0000000..5fb4dc2
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/images/diagram/export-as-img.png
Binary files differ
diff --git a/jpa/plugins/org.eclipse.jpt.ui/images/diagram/header_left_bg.png b/jpa/plugins/org.eclipse.jpt.ui/images/diagram/header_left_bg.png
new file mode 100644
index 0000000..abfffe4
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/images/diagram/header_left_bg.png
Binary files differ
diff --git a/jpa/plugins/org.eclipse.jpt.ui/images/diagram/header_mid_bg.png b/jpa/plugins/org.eclipse.jpt.ui/images/diagram/header_mid_bg.png
new file mode 100644
index 0000000..caa828d
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/images/diagram/header_mid_bg.png
Binary files differ
diff --git a/jpa/plugins/org.eclipse.jpt.ui/images/diagram/header_right_bg.png b/jpa/plugins/org.eclipse.jpt.ui/images/diagram/header_right_bg.png
new file mode 100644
index 0000000..bd74144
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/images/diagram/header_right_bg.png
Binary files differ
diff --git a/jpa/plugins/org.eclipse.jpt.ui/images/diagram/print-hover.png b/jpa/plugins/org.eclipse.jpt.ui/images/diagram/print-hover.png
new file mode 100644
index 0000000..468a09b
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/images/diagram/print-hover.png
Binary files differ
diff --git a/jpa/plugins/org.eclipse.jpt.ui/images/diagram/print.png b/jpa/plugins/org.eclipse.jpt.ui/images/diagram/print.png
new file mode 100644
index 0000000..ee15ba1
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/images/diagram/print.png
Binary files differ
diff --git a/jpa/plugins/org.eclipse.jpt.ui/images/diagram/shadow-bottom.png b/jpa/plugins/org.eclipse.jpt.ui/images/diagram/shadow-bottom.png
new file mode 100644
index 0000000..d84b339
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/images/diagram/shadow-bottom.png
Binary files differ
diff --git a/jpa/plugins/org.eclipse.jpt.ui/images/diagram/shadow-lower-left.png b/jpa/plugins/org.eclipse.jpt.ui/images/diagram/shadow-lower-left.png
new file mode 100644
index 0000000..fa25df3
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/images/diagram/shadow-lower-left.png
Binary files differ
diff --git a/jpa/plugins/org.eclipse.jpt.ui/images/diagram/shadow-lower-right.png b/jpa/plugins/org.eclipse.jpt.ui/images/diagram/shadow-lower-right.png
new file mode 100644
index 0000000..a58c953
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/images/diagram/shadow-lower-right.png
Binary files differ
diff --git a/jpa/plugins/org.eclipse.jpt.ui/images/diagram/shadow-side.png b/jpa/plugins/org.eclipse.jpt.ui/images/diagram/shadow-side.png
new file mode 100644
index 0000000..585ed6a
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/images/diagram/shadow-side.png
Binary files differ
diff --git a/jpa/plugins/org.eclipse.jpt.ui/images/diagram/shadow-upper-right.png b/jpa/plugins/org.eclipse.jpt.ui/images/diagram/shadow-upper-right.png
new file mode 100644
index 0000000..ccabb96
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/images/diagram/shadow-upper-right.png
Binary files differ
diff --git a/jpa/plugins/org.eclipse.jpt.ui/images/diagram/toolbar_bg.png b/jpa/plugins/org.eclipse.jpt.ui/images/diagram/toolbar_bg.png
new file mode 100644
index 0000000..c483a49
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/images/diagram/toolbar_bg.png
Binary files differ
diff --git a/jpa/plugins/org.eclipse.jpt.ui/images/objects/column.gif b/jpa/plugins/org.eclipse.jpt.ui/images/objects/column.gif
new file mode 100644
index 0000000..5f1551b
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/images/objects/column.gif
Binary files differ
diff --git a/jpa/plugins/org.eclipse.jpt.ui/images/objects/columnKey.gif b/jpa/plugins/org.eclipse.jpt.ui/images/objects/columnKey.gif
new file mode 100644
index 0000000..4f38515
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/images/objects/columnKey.gif
Binary files differ
diff --git a/jpa/plugins/org.eclipse.jpt.ui/images/objects/file.png b/jpa/plugins/org.eclipse.jpt.ui/images/objects/file.png
new file mode 100644
index 0000000..f5c1810
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/images/objects/file.png
Binary files differ
diff --git a/jpa/plugins/org.eclipse.jpt.ui/images/objects/folder.png b/jpa/plugins/org.eclipse.jpt.ui/images/objects/folder.png
new file mode 100644
index 0000000..9759da4
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/images/objects/folder.png
Binary files differ
diff --git a/jpa/plugins/org.eclipse.jpt.ui/images/objects/forward.gif b/jpa/plugins/org.eclipse.jpt.ui/images/objects/forward.gif
new file mode 100644
index 0000000..562bd70
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/images/objects/forward.gif
Binary files differ
diff --git a/jpa/plugins/org.eclipse.jpt.ui/images/objects/moveRight.gif b/jpa/plugins/org.eclipse.jpt.ui/images/objects/moveRight.gif
new file mode 100644
index 0000000..7a1511d
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/images/objects/moveRight.gif
Binary files differ
diff --git a/jpa/plugins/org.eclipse.jpt.ui/images/objects/package.png b/jpa/plugins/org.eclipse.jpt.ui/images/objects/package.png
new file mode 100644
index 0000000..471cc43
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/images/objects/package.png
Binary files differ
diff --git a/jpa/plugins/org.eclipse.jpt.ui/images/objects/table.gif b/jpa/plugins/org.eclipse.jpt.ui/images/objects/table.gif
new file mode 100644
index 0000000..a99388a
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/images/objects/table.gif
Binary files differ
diff --git a/jpa/plugins/org.eclipse.jpt.ui/images/objects/table_obj.gif b/jpa/plugins/org.eclipse.jpt.ui/images/objects/table_obj.gif
new file mode 100644
index 0000000..e2ccabb
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/images/objects/table_obj.gif
Binary files differ
diff --git a/jpa/plugins/org.eclipse.jpt.ui/images/overlays/error.gif b/jpa/plugins/org.eclipse.jpt.ui/images/overlays/error.gif
new file mode 100644
index 0000000..119dccc
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/images/overlays/error.gif
Binary files differ
diff --git a/jpa/plugins/org.eclipse.jpt.ui/images/overlays/warning.png b/jpa/plugins/org.eclipse.jpt.ui/images/overlays/warning.png
new file mode 100644
index 0000000..8c1e86c
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/images/overlays/warning.png
Binary files differ
diff --git a/jpa/plugins/org.eclipse.jpt.ui/images/save-image-16.png b/jpa/plugins/org.eclipse.jpt.ui/images/save-image-16.png
new file mode 100644
index 0000000..eca4774
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/images/save-image-16.png
Binary files differ
diff --git a/jpa/plugins/org.eclipse.jpt.ui/plugin.properties b/jpa/plugins/org.eclipse.jpt.ui/plugin.properties
new file mode 100644
index 0000000..3140500
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/plugin.properties
@@ -0,0 +1,73 @@
+###############################################################################
+# Copyright (c) 2006, 2009 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
+###############################################################################
+
+# ====================================================================
+# To code developer:
+#   Do NOT change the properties between this line and the
+#   "%%% END OF TRANSLATED PROPERTIES %%%" line.
+#   Make a new property name, append to the end of the file and change
+#   the code to use the new property.
+# ====================================================================
+
+# ====================================================================
+# %%% END OF TRANSLATED PROPERTIES %%%
+# ====================================================================
+pluginName= Dali Java Persistence Tools - UI
+providerName=Eclipse Web Tools Platform
+
+JPA_PLATFORM_UI="JPA Platform UI"
+
+jpaNavigatorContent=JPA Content
+
+jpaWizardCategoryName = JPA
+newJpaProjectWizardName = JPA Project
+newJpaProjectWizardDesc = Create a JPA project
+newJpaEntityWizardName = Entity
+newJpaEntityWizardDesc = Create a JPA Entity 
+newJpaMappingFileWizardName = Mapping File
+newJpaMappingFileWizardDesc = Create a JPA Mapping File
+newJpaEntityFromTableWizardName = Entities from Tables
+newJpaEntityFromTableWizardDesc = Create JPA Entities from database tables 
+
+upgradeToLatestVersion = Upgrade Document Version
+jpaStructureViewCommandCategory = JPA Structure View
+addPersistentClass = Add Class ...
+removePersistentClass = Remove Class
+addPersistentAttributeToXml = Add Attribute to XML
+addPersistentAttributeToXmlAndMap = Add Attribute to XML and Map ...
+removePersistentAttributeFromXml = Remove Attribute from XML
+mapAs=Map As
+mapAsMnemonic=M
+mapAsSpecifiedMappingParameterName=specified mapping key
+mapAsDefaultMappingParameterName=default mapping key
+
+jpaMenuName = JPA Tools
+generateEntities = Generate Entities from Tables...
+generateDDL = Generate Tables from Entities...
+convertToJPAProject = Convert to JPA Project ...
+synchronizeClasses = Synchronize Class List
+
+persistenceEditor=Persistence XML Editor
+
+jpaProblemSeveritiesPageName=Errors/Warnings
+jpaPreferencePage = Java Persistence
+
+jpaProjectPropertiesPage = Java Persistence
+
+jpaPerspective = JPA
+jpaPerspectiveDescription = This perspective is designed to support Java Persistence (JPA) development. It offers a Project Explorer, JPA Details, JPA Structure and a Data Source Explorer.
+jpaDetails = JPA Details
+jpaStructure = JPA Structure
+JpaProposalCategory = JPA Proposals
+
+JptCreationActionSet.label = Jpt Creation
+JptCreationActionSet.description = Jpt Creation Action Set
+
+NewEntityAction.label = New Entity
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/plugin.xml b/jpa/plugins/org.eclipse.jpt.ui/plugin.xml
new file mode 100644
index 0000000..10c5cc7
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/plugin.xml
Binary files differ
diff --git a/jpa/plugins/org.eclipse.jpt.ui/property_files/jpt_ui.properties b/jpa/plugins/org.eclipse.jpt.ui/property_files/jpt_ui.properties
new file mode 100644
index 0000000..304aacf
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/property_files/jpt_ui.properties
@@ -0,0 +1,140 @@
+################################################################################
+# Copyright (c) 2006, 2010 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
+################################################################################
+
+ChooserPane_browseButton=Browse...
+
+AccessTypeComposite_access=Access:
+AccessTypeComposite_field=Field
+AccessTypeComposite_property=Property
+
+AddPersistentAttributeDialog_title=Add Attribute
+AddPersistentAttributeDialog_attributeLabel=Attribute:
+AddPersistentAttributeDialog_mappingLabel=Map as:
+AddPersistentAttributeDialog_noMappingKeyError=You must specify a mapping type
+
+AddPersistentClassDialog_title=Add Class
+AddPersistentClassDialog_classLabel=Class:
+AddPersistentClassDialog_classDialog_title=Persistent Class Selection
+AddPersistentClassDialog_classDialog_message=Choose a class:
+AddPersistentClassDialog_mappingLabel=Map as:
+AddPersistentClassDialog_noClassError=You must specify a class
+AddPersistentClassDialog_duplicateClassWarning=File already contains that persistent class
+AddPersistentClassDialog_classNotFoundWarning=Cannot resolve class
+AddPersistentClassDialog_noMappingKeyError=You must specify a mapping type
+
+AddRemovePane_AddButtonText=Add...
+AddRemovePane_RemoveButtonText=Remove
+
+ClassChooserPane_dialogMessage=&Enter type name prefix or pattern (*, ?, or camel case):
+ClassChooserPane_dialogTitle=Class Selection
+
+DatabaseSchemaWizardPage_title=Database Schema
+DatabaseSchemaWizardPage_desc=Select a database schema
+DatabaseSchemaWizardPage_schemaSettings=Schema settings
+DatabaseSchemaWizardPage_addConnectionToProject=<a>Add a connection to JPA project...</a>
+DatabaseSchemaWizardPage_connectLink=<a>Connect</a>
+DatabaseSchemaWizardPage_schema=Schema:
+DatabaseSchemaWizardPage_connectionInfo=(Note: JPA project must have a connection and it must be active to select a schema)
+DatabaseSchemaWizardPage_schemaInfo=(Note: Must have active connection to select schema)
+
+EnumComboViewer_default=Default ()
+EnumComboViewer_defaultWithDefault=Default ({0})
+
+Error_openingEditor=Error Opening Editor
+
+General_browse=Br&owse...
+General_revert=Revert
+General_deselectAll=Deselect All
+General_selectAll=Select All
+
+GenerateDDLWizard_title=DDL Generation
+
+GenerateEntitiesWizard_generateEntities=Generate Entities
+GenerateEntitiesWizardPage_chooseEntityTable=Choose tables to generate entities from.
+GenerateEntitiesWizardPage_generateEntities=Generate Entities from Tables
+GenerateEntitiesWizardPage_synchronizeClasses=Synchronize classes in persistence.xml
+GenerateEntitiesWizardPage_tables=Tables:
+GenerateEntitiesWizardPage_tableColumn=Table
+GenerateEntitiesWizardPage_entityNameColumn=Entity Name
+
+EntitiesGenerator_jobName=Generating Entities
+
+GenericPlatformUiDialog_notSupportedMessageTitle=DDL Generation
+GenericPlatformUiDialog_notSupportedMessageText=DDL Generation is not supported by the Generic Platform.
+
+JpaContent_label=JPA Content
+
+JpaStructureView_structureNotAvailable=JPA structure is not available.
+JpaStructureView_linkWithEditorText=Link with Editor
+JpaStructureView_linkWithEditorDesc=Link with Active Editor
+JpaStructureView_linkWithEditorTooltip=Link with Editor
+JpaStructureView_numItemsSelected={0} items selected
+
+JpaDetailsView_viewNotAvailable=Details are not available for the current selection.
+
+JpaFacetWizardPage_title=JPA Facet
+JpaFacetWizardPage_description=Configure JPA settings.
+JpaFacetWizardPage_platformLabel=&Platform
+JpaFacetWizardPage_connectionLabel=&Connection
+JpaFacetWizardPage_connectionLink=<a>Add connection ...</a>
+JpaFacetWizardPage_connectLink=<a>Connect</a>
+JpaFacetWizardPage_addDriverLibraryLabel=&Add driver library to build path
+JpaFacetWizardPage_driverLibraryLabel=&Driver:
+JpaFacetWizardPage_overrideDefaultCatalogLabel=&Override default catalog from connection
+JpaFacetWizardPage_defaultCatalogLabel=Catalo&g:
+JpaFacetWizardPage_overrideDefaultSchemaLabel=O&verride default schema from connection
+JpaFacetWizardPage_defaultSchemaLabel=&Schema:
+JpaFacetWizardPage_jpaImplementationLabel=JPA implementation
+JpaFacetWizardPage_userServerLibLabel=Implementation provided by server runtime
+JpaFacetWizardPage_specifyLibLabel=Implementation library:
+JpaFacetWizardPage_jpaPrefsLink=<a>Configure default JPA implementation library ...</a>
+JpaFacetWizardPage_userLibsLink=<a>Configure user libraries ...</a>
+JpaFacetWizardPage_persistentClassManagementLabel=Persistent class management
+JpaFacetWizardPage_discoverClassesButton=Discover annotated classes a&utomatically
+JpaFacetWizardPage_listClassesButton=Annotated classes must be &listed in persistence.xml
+JpaFacetWizardPage_createOrmXmlButton=Create &mapping file (orm.xml)
+JpaFacetWizardPage_metamodelLabel=Canonical metamodel (JPA 2.0)
+JpaFacetWizardPage_metamodelSourceFolderLink=<a>Source fol&der:</a>
+JpaFacetWizardPage_none=<None>
+
+JpaPreferencesPage_Description=Expand the tree to edit preferences for a specific feature.
+
+JpaProblemSeveritiesPage_Description=Select the severity level for the following optional Java Persistence validation problems:
+JpaProblemSeveritiesPage_Error=Error
+JpaProblemSeveritiesPage_Ignore=Ignore
+JpaProblemSeveritiesPage_Info=Info
+JpaProblemSeveritiesPage_Warning=Warning
+
+MappingFileWizard_title=New Mapping File
+MappingFileWizardPage_title=Mapping file
+MappingFileWizardPage_desc=Specify mapping file location and properties
+MappingFileWizardPage_projectLabel=&Project:
+MappingFileWizardPage_sourceFolderLabel=Source fol&der:
+MappingFileWizardPage_filePathLabel=File pat&h:
+MappingFileWizardPage_accessLabel=Default a&ccess:
+MappingFileWizardPage_addToPersistenceUnitButton=&Add to persistence unit
+MappingFileWizardPage_persistenceUnitLabel=Persistence &unit:
+MappingFileWizardPage_incorrectSourceFolderError=Selection must be a valid source folder
+MappingFileWizardPage_accessLabel_sourceFolderDialogTitle=Source Folder Selection
+MappingFileWizardPage_accessLabel_sourceFolderDialogDesc=Choose a source folder:
+
+NewJpaProjectWizard_title=New JPA Project
+NewJpaProjectWizard_firstPage_title=JPA Project
+NewJpaProjectWizard_firstPage_description=Configure JPA project settings.
+
+OrmItemLabelProviderFactory_entityMappingsLabel=Entity Mappings
+
+PackageChooserPane_dialogTitle=Package Selection
+PackageChooserPane_dialogMessage=Choose a folder: 
+
+PersistenceItemLabelProviderFactory_persistenceLabel=Persistence
+
+OverwriteConfirmerDialog_title=Overwrite Existing Class
+OverwriteConfirmerDialog_text=Overwrite source code for the class ''{0}''?
diff --git a/jpa/plugins/org.eclipse.jpt.ui/property_files/jpt_ui_details.properties b/jpa/plugins/org.eclipse.jpt.ui/property_files/jpt_ui_details.properties
new file mode 100644
index 0000000..2313f78
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/property_files/jpt_ui_details.properties
@@ -0,0 +1,330 @@
+################################################################################
+# Copyright (c) 2006, 2010 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
+################################################################################
+
+Boolean_True=True
+Boolean_False=False
+NoneSelected=<None>
+DefaultEmpty=Default
+DefaultWithOneParam=Default ({0})
+ProviderDefault=Default (<Provider-Specific>)
+NoNameSet=<No name set>
+
+MapAsComposite_changeMappingType=here
+MapAsComposite_default=Default
+MapAsComposite_dialogTitle=Mapping Type Selection
+MapAsComposite_labelText=&Enter mapping type or pattern (*, ?, or camel case):
+MapAsComposite_mappedAttributeText=Attribute ''{0}'' is mapped as {1}.
+MapAsComposite_mappedTypeText=Type ''{0}'' is mapped as {1}.
+MapAsComposite_unmappedAttributeText=Attribute ''{0}'' is not mapped, click here to change the mapping type.
+MapAsComposite_unmappedTypeText=Type ''{0}'' is not mapped, click here to change the mapping type.
+MapAsComposite_virtualAttributeText=Attribute ''{0}'' is not mapped.
+
+BasicSection_title=Basic
+EmbeddedSection_title=Embedded
+EmbeddedIdSection_title=Embedded ID
+EmbeddableSection_title=Embeddable
+EntitySection_title=Entity
+IdSection_title=ID
+ManyToManySection_title=Many to Many
+ManyToOneSection_title=Many to One
+MappedSuperclassSection_title=Mapped Superclass
+OneToManySection_title=One to Many
+OneToOneSection_title=One to One
+VersionSection_title=Version
+
+BasicMappingUiProvider_label=Basic
+EmbeddedMappingUiProvider_label=Embedded
+EmbeddedIdMappingUiProvider_label=Embedded ID
+IdMappingUiProvider_label=ID
+OneToManyMappingUiProvider_label=One to Many
+OneToOneMappingUiProvider_label=One to One
+ManyToManyMappingUiProvider_label=Many to Many
+ManyToOneMappingUiProvider_label=Many to One
+TransientMappingUiProvider_label=Transient
+VersionMappingUiProvider_label=Version
+BasicMappingUiProvider_linkLabel=basic
+EmbeddedMappingUiProvider_linkLabel=embedded
+EmbeddedIdMappingUiProvider_linkLabel=embedded ID
+IdMappingUiProvider_linkLabel=ID
+OneToManyMappingUiProvider_linkLabel=one to many
+OneToOneMappingUiProvider_linkLabel=one to one
+ManyToManyMappingUiProvider_linkLabel=many to many
+ManyToOneMappingUiProvider_linkLabel=many to one
+TransientMappingUiProvider_linkLabel=transient
+VersionMappingUiProvider_linkLabel=version
+
+DefaultBasicMappingUiProvider_label=Default (Basic)
+DefaultEmbeddedMappingUiProvider_label=Default (Embedded)
+DefaultBasicMappingUiProvider_linkLabel=default (basic)
+DefaultEmbeddedMappingUiProvider_linkLabel=default (embedded)
+
+EmbeddableUiProvider_label=Embeddable
+EntityUiProvider_label=Entity
+MappedSuperclassUiProvider_label=Mapped Superclass
+NullTypeMappingUiProvider_label=Unmapped
+
+EmbeddableUiProvider_linkLabel=embeddable
+EntityUiProvider_linkLabel=entity
+MappedSuperclassUiProvider_linkLabel=mapped superclass
+
+
+AddQueryDialog_title=Add Query
+AddQueryDialog_descriptionTitle=Create new query
+AddQueryDialog_namedQuery=Named Query
+AddQueryDialog_namedNativeQuery= Named Native Query
+AddQueryDialog_description=Create a new query setting both the 'name' and the 'type' 
+QueryStateObject_nameMustBeSpecified=A name must be specified.
+QueryStateObject_typeMustBeSpecified=A query type must be specified
+AddQueryDialog_name=Name:
+AddQueryDialog_queryType=Type:
+NamedQueryComposite_nameTextLabel=Name:
+
+EntityComposite_inheritance=Inheritance
+EntityComposite_queries=Queries
+EntityComposite_tableDefault=Default ({0})
+EntityComposite_tableNoDefaultSpecified=Default ()
+
+EntityGeneralSection_name=Name:
+
+EntityNameComposite_name=Name:
+
+BasicGeneralSection_name=Name:
+BasicGeneralSection_nameDefault=Default ({0})
+BasicGeneralSection_fetchLabel=Fetch:
+BasicGeneralSection_optionalLabel=Optional
+BasicGeneralSection_optionalLabelDefault=Optional ({0})
+BasicGeneralSection_lobLabel=Lob
+BasicGeneralSection_temporalLabel=Temporal:
+BasicGeneralSection_enumeratedLabel=Enumerated:
+TypeSection_type=Type
+TypeSection_default=Default
+TypeSection_lob=Lob
+TypeSection_temporal=Temporal:
+TypeSection_enumerated=Enumerated:
+
+TableChooser_label=Name:
+CatalogChooser_label=Catalog:
+SchemaChooser_label=Schema:
+TableComposite_tableSection=Table
+
+TargetEntityChooser_label=Target entity:
+TargetEntityChooser_browse=Browse...
+TargetEntityChooser_selectTypeTitle=Select Type
+
+IdClassComposite_label=ID class:
+
+Joining_title=Joining Strategy
+Joining_mappedByLabel=Mapped by
+Joining_mappedByAttributeLabel=Attribute:
+Joining_joinColumnJoiningLabel=Join columns
+Joining_primaryKeyJoinColumnJoiningLabel=Primary key join columns
+Joining_joinTableJoiningLabel=Join table
+
+JoinTableComposite_inverseJoinColumn=Inverse join columns
+JoinTableComposite_joinColumn=Join columns
+JoinTableComposite_name=Name:
+JoinTableComposite_schema=Schema:
+JoinTableComposite_catalog=Catalog:
+JoinTableComposite_overrideDefaultJoinColumns=Override default
+JoinTableComposite_overrideDefaultInverseJoinColumns=Override default
+
+MultiRelationshipMappingComposite_general=General
+MultiRelationshipMappingComposite_joinTable=Join Table
+MultiRelationshipMappingComposite_targetEntity=Target entity:
+MultiRelationshipMappingComposite_cascadeType=Cascade type:
+MultiRelationshipMappingComposite_fetchType=Fetch type:
+MultiRelationshipMappingComposite_mappedBy=Mapped by:
+
+ColumnComposite_columnDefinition=Column definition:
+ColumnComposite_columnSection=Column
+ColumnComposite_details=Details
+ColumnComposite_insertable=Insertable
+ColumnComposite_insertableWithDefault=Insertable ({0})
+ColumnComposite_length=Length:
+ColumnComposite_name=Name:
+ColumnComposite_nullable=Nullable
+ColumnComposite_nullableWithDefault=Nullable ({0})
+ColumnComposite_precision=Precision:
+ColumnComposite_scale=Scale:
+ColumnComposite_table=Table:
+ColumnComposite_unique=Unique
+ColumnComposite_uniqueWithDefault=Unique ({0})
+ColumnComposite_updatable=Updatable
+ColumnComposite_updatableWithDefault=Updatable ({0})
+
+JoinColumnsComposite_edit=Edit...
+JoinColumnsComposite_mappingBetweenTwoParams={0} -> {1}
+JoinColumnsComposite_mappingBetweenTwoParamsDefault=Default ({0} -> {1})
+JoinColumnsComposite_mappingBetweenTwoParamsBothDefault=Default ({0}) -> Default ({1})
+JoinColumnsComposite_mappingBetweenTwoParamsFirstDefault=Default ({0}) -> {1}
+JoinColumnsComposite_mappingBetweenTwoParamsSecDefault={0} -> Default ({1})
+JoiningStrategyJoinColumnsComposite_overrideDefaultJoinColumns=Override default
+
+PrimaryKeyJoinColumnsComposite_overrideDefaultPrimaryKeyJoinColumns=Override default
+PrimaryKeyJoinColumnsComposite_edit=Edit...
+PrimaryKeyJoinColumnsComposite_primaryKeyJoinColumn=Primary key join columns
+PrimaryKeyJoinColumnsComposite_mappingBetweenTwoParams={0} -> {1}
+PrimaryKeyJoinColumnsComposite_mappingBetweenTwoParamsDefault=Default ({0} -> {1})
+PrimaryKeyJoinColumnsComposite_mappingBetweenTwoParamsBothDefault=Default ({0}) -> Default ({1})
+PrimaryKeyJoinColumnsComposite_mappingBetweenTwoParamsFirstDefault=Default ({0}) -> {1}
+PrimaryKeyJoinColumnsComposite_mappingBetweenTwoParamsSecDefault={0} -> Default ({1})
+
+JoinColumnDialog_addJoinColumnDescriptionTitle=Create New Join Column
+JoinColumnDialog_addJoinColumnTitle=Add Join Column
+JoinColumnDialog_description=Specify a mapped column for joining an entity association.
+JoinColumnDialog_editJoinColumnDescriptionTitle=Edit Join Column
+JoinColumnDialog_editJoinColumnTitle=Edit Join Column
+JoinColumnDialog_name=&Name:
+JoinColumnDialog_referencedColumnName=&Referenced column name:
+
+JoinColumnDialogPane_columnDefinition=&Column definition:
+JoinColumnDialogPane_insertable=&Insertable
+JoinColumnDialogPane_insertableWithDefault=&Insertable ({0})
+JoinColumnDialogPane_nullable=&Nullable
+JoinColumnDialogPane_nullableWithDefault=&Nullable ({0})
+JoinColumnDialogPane_table=&Table:
+JoinColumnDialogPane_unique=&Unique
+JoinColumnDialogPane_uniqueWithDefault=&Unique ({0})
+JoinColumnDialogPane_updatable=&Updatable
+JoinColumnDialogPane_updatableWithDefault=&Updatable ({0})
+
+InverseJoinColumnDialog_editInverseJoinColumnTitle=Edit Inverse Join Column
+
+PrimaryKeyJoinColumnInSecondaryTableDialog_addDescriptionTitle=Create New Primary Key Join Column
+PrimaryKeyJoinColumnInSecondaryTableDialog_addTitle=Add Primary Key Join Column
+PrimaryKeyJoinColumnInSecondaryTableDialog_editDescriptionTitle=Edit Primary Key Join Column
+PrimaryKeyJoinColumnInSecondaryTableDialog_editTitle=Edit Primary Key Join Column
+
+PrimaryKeyJoinColumnDialog_addDescriptionTitle=Create New Primary Key Join Column
+PrimaryKeyJoinColumnDialog_addTitle=Add Primary Key Join Column
+PrimaryKeyJoinColumnDialog_editDescriptionTitle=Edit Primary Key Join Column
+PrimaryKeyJoinColumnDialog_editTitle=Edit Primary Key Join Column
+
+OverridesComposite_attributeOverridesSection=Attribute Overrides
+OverridesComposite_attributeOverridesGroup=Attribute overrides
+OverridesComposite_overrideDefault=Override default
+
+OverridesComposite_association=Association Override
+OverridesComposite_attribute=Attribute Override
+OverridesComposite_noName=<Name not set>
+AssociationOverridesComposite_joinColumn=Join columns
+
+InheritanceComposite_detailsGroupBox=Details
+InheritanceComposite_discriminatorColumnGroupBox=Discriminator column
+InheritanceComposite_discriminatorValue=Discriminator value:
+AbstractInheritanceComposite_joined=Joined
+AbstractInheritanceComposite_single_table=Single Table
+InheritanceComposite_strategy=Strategy:
+AbstractInheritanceComposite_table_per_class=Table per Class
+
+DiscriminatorColumnComposite_discriminatorType=Type:
+DiscriminatorColumnComposite_name=Name:
+DiscriminatorColumnComposite_char=Character
+DiscriminatorColumnComposite_integer=Integer
+DiscriminatorColumnComposite_string=String
+
+GeneratorsComposite_sequenceGeneratorCheckBox=Sequence generator
+GeneratorsComposite_sequenceGeneratorSection=Sequence Generator
+GeneratorsComposite_tableGeneratorCheckBox=Table generator
+GeneratorsComposite_tableGeneratorSection=Table Generator
+
+IdMappingComposite_pk_generation=PK Generation
+IdMappingComposite_primaryKeyGenerationCheckBox=Primary key generation
+IdMappingComposite_primaryKeyGenerationSection=Primary Key Generation
+IdMappingComposite_tableGeneratorCheckBox=Table generator
+IdMappingComposite_tableGeneratorSection=Table Generator
+IdMappingComposite_sequenceGeneratorCheckBox=Sequence generator
+IdMappingComposite_sequenceGeneratorSection=Sequence Generator
+
+GeneratedValueComposite_generatedValue=Generated Value
+GeneratedValueComposite_generatorName=Generator name:
+GeneratedValueComposite_strategy=Strategy:
+GeneratedValueComposite_auto=Auto
+GeneratedValueComposite_identity=Identity
+GeneratedValueComposite_sequence=Sequence
+GeneratedValueComposite_table=Table
+
+SequenceGeneratorComposite_catalog=Catalog:
+SequenceGeneratorComposite_default=Default
+SequenceGeneratorComposite_name=Name:
+SequenceGeneratorComposite_schema=Schema:
+SequenceGeneratorComposite_sequence=Sequence:
+SequenceGeneratorComposite_sequenceGenerator=Sequence Generator
+
+TableGeneratorComposite_catalog=Catalog:
+TableGeneratorComposite_default=Default
+TableGeneratorComposite_name=Name:
+TableGeneratorComposite_pkColumn=Primary key column:
+TableGeneratorComposite_pkColumnValue=Primary key column value:
+TableGeneratorComposite_schema=Schema:
+TableGeneratorComposite_table=Table:
+TableGeneratorComposite_tableGenerator=Table Generator
+TableGeneratorComposite_valueColumn=Value column:
+
+GeneratorComposite_allocationSize=Allocation size:
+GeneratorComposite_initialValue=Initial value:
+
+OrderingComposite_orderingGroup=Ordering
+OrderingComposite_none=None
+OrderingComposite_primaryKey=Primary key
+OrderingComposite_custom=Custom
+
+SecondaryTablesComposite_secondaryTables=Secondary Tables
+SecondaryTablesComposite_edit=Edit...
+
+SecondaryTableDialog_addSecondaryTable=Add Secondary Table
+SecondaryTableDialog_editSecondaryTable=Edit Secondary Table
+SecondaryTableDialog_name=Name:
+SecondaryTableDialog_catalog=Catalog:
+SecondaryTableDialog_schema=Schema:
+SecondaryTableDialog_defaultSchema=Default ({0})
+SecondaryTableDialog_defaultCatalog=Default ({0})
+
+AccessTypeCombo_default=Default
+MetaDataCompleteCombo_Default=Default ({0})
+
+OptionalComposite_false=False
+OptionalComposite_true=True
+
+EnumTypeComposite_ordinal=Ordinal
+EnumTypeComposite_string=String
+
+FetchTypeComposite_eager=Eager
+FetchTypeComposite_lazy=Lazy
+
+TemporalTypeComposite_date=Date
+TemporalTypeComposite_time=Time
+TemporalTypeComposite_timestamp=Timestamp
+
+CascadeComposite_all=All
+CascadeComposite_cascadeTitle=Cascade
+CascadeComposite_merge=Merge
+CascadeComposite_persist=Persist
+CascadeComposite_refresh=Refresh
+CascadeComposite_remove=Remove
+
+QueriesComposite_displayString=<Name not set> {0}
+
+NamedNativeQueryPropertyComposite_query=Query:
+NamedNativeQueryPropertyComposite_queryHintsGroupBox=Query hints
+NamedNativeQueryPropertyComposite_resultClass=Result class:
+
+NamedQueryPropertyComposite_query=Query:
+NamedQueryPropertyComposite_queryHintsGroupBox=Query hints
+
+NewNameStateObject_nameMustBeSpecified=A name must be specified.
+NewNameStateObject_nameAlreadyExists=A query with this name already exists.
+
+QueryHintsComposite_nameColumn=Name
+QueryHintsComposite_valueColumn=Value
+
+OrmSecondaryTablesComposite_defineInXml=Define in XML
+
+NullAttributeMappingUiProvider_label=Unmapped
diff --git a/jpa/plugins/org.eclipse.jpt.ui/property_files/jpt_ui_details2_0.properties b/jpa/plugins/org.eclipse.jpt.ui/property_files/jpt_ui_details2_0.properties
new file mode 100644
index 0000000..6114fe4
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/property_files/jpt_ui_details2_0.properties
@@ -0,0 +1,52 @@
+################################################################################
+# Copyright (c) 2009, 2010 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
+################################################################################
+
+CascadePane2_0_detach=Detach
+
+CollectionTable2_0Composite_title=Collection Table
+CollectionTable2_0Composite_joinColumn=Join columns
+CollectionTable2_0Composite_name=Name:
+CollectionTable2_0Composite_schema=Schema:
+CollectionTable2_0Composite_catalog=Catalog:
+CollectionTable2_0Composite_overrideDefaultJoinColumns=Override default
+
+DerivedIdentity_title=Derived Identity
+DerivedIdentity_nullDerivedIdentity=None
+DerivedIdentity_idDerivedIdentity=Id
+DerivedIdentity_mapsIdDerivedIdentity=Maps id:
+DerivedIdentity_mapsIdUnspecifiedValue=<undetermined value>
+
+ElementCollectionMapping2_0_label=Element Collection
+ElementCollectionMapping2_0_linkLabel=element collection
+ElementCollectionSection_title=Element Collection
+AbstractElementCollectionMapping2_0_Composite_valueSectionTitle=Value
+Entity_cacheableLabel=Cacheable
+Entity_cacheableWithDefaultLabel=Cacheable ({0})
+
+EmbeddedIdMapping2_0MappedByRelationshipPane_label=Embedded ID is mapped by a relationship.
+IdMapping2_0MappedByRelationshipPane_label=ID is mapped by a relationship.
+
+OrderingComposite_orderColumn=Order column
+
+OrphanRemoval2_0Composite_orphanRemovalLabel=Orphan removal
+OrphanRemoval2_0Composite_orphanRemovalLabelDefault=Orphan removal ({0})
+
+LockModeComposite_lockModeLabel = Lock mode:
+
+LockModeComposite_read = Read
+LockModeComposite_write = Write
+LockModeComposite_optimistic = Optimistic
+LockModeComposite_optimistic_force_increment = Optimistic Force Increment
+LockModeComposite_pessimistic_read = Pessimistic Read
+LockModeComposite_pessimistic_write = Pessimistic Write
+LockModeComposite_pessimistic_force_increment = Pessimistic Force Increment
+LockModeComposite_none = None
+
+TargetClassComposite_label=Target class:
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/property_files/jpt_ui_details_orm.properties b/jpa/plugins/org.eclipse.jpt.ui/property_files/jpt_ui_details_orm.properties
new file mode 100644
index 0000000..28bb243
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/property_files/jpt_ui_details_orm.properties
@@ -0,0 +1,56 @@
+################################################################################
+# Copyright (c) 2006, 2010 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
+################################################################################
+
+Boolean_False=False
+Boolean_True=True
+EntityMappingsSection_title=Entity Mappings
+EntityMappingsDetailsPage_access=Access:
+EntityMappingsDetailsPage_catalog=Catalog:
+EntityMappingsDetailsPage_field=Field
+EntityMappingsDetailsPage_package=Package:
+EntityMappingsDetailsPage_property=Property
+EntityMappingsDetailsPage_schema=Schema:
+EntityMappingsPage_catalogDefault=Default ({0}
+EntityMappingsPage_catalogNoDefaultSpecified=Default
+EntityMappingsPage_schemaDefault=Default ({0})
+EntityMappingsPage_schemaNoDefaultSpecified=Default
+MetadataCompleteComposite_metadataComplete=Metadata complete
+MetadataCompleteComposite_metadataCompleteWithDefault=Metadata complete ({0})
+OrmGeneratorsComposite_displayString=<Name not set> {0}
+OrmGeneratorsComposite_groupBox=Generators
+OrmMappingNameChooser_name=Name:
+OrmJavaClassChooser_javaClass=Java class:
+OrmQueriesComposite_groupBox=Queries
+PersistenceUnitMetadataComposite_access=Access:
+PersistenceUnitMetadataComposite_delimitedIdentifiersCheckBox=Delimited identifiers
+PersistenceUnitMetadataComposite_cascadePersistCheckBox=Cascade persist
+PersistenceUnitMetadataComposite_catalog=Catalog:
+PersistenceUnitMetadataComposite_field=Field
+PersistenceUnitMetadataComposite_persistenceUnitSection=Persistence Unit
+PersistenceUnitMetadataComposite_property=Property
+PersistenceUnitMetadataComposite_schema=Schema:
+PersistenceUnitMetadataComposite_xmlMappingMetadataCompleteCheckBox=XML mapping metadata complete
+PersistenceUnitMetadataSection_catalogDefault=Default ({0})
+PersistenceUnitMetadataSection_schemaDefault=Default ({0})
+
+AddGeneratorDialog_name=Name:
+AddGeneratorDialog_generatorType=Type:
+AddGeneratorDialog_title=Add Generator
+AddGeneratorDialog_descriptionTitle=Create new generator
+AddGeneratorDialog_description=Create a new generator setting both the 'name' and the 'type'
+AddGeneratorDialog_tableGenerator=Table Generator
+AddGeneratorDialog_sequenceGenerator=Sequence Generator
+GeneratorStateObject_nameMustBeSpecified=A name must be specified.
+GeneratorStateObject_typeMustBeSpecified=A generator type must be specified.
+
+
+UnsupportedOrmMappingUiProvider_label=Unsupported
+
+UnsupportedOrmMappingUiProvider_linkLabel=unsupported
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/property_files/jpt_ui_entity_gen.properties b/jpa/plugins/org.eclipse.jpt.ui/property_files/jpt_ui_entity_gen.properties
new file mode 100644
index 0000000..b5b18ec
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/property_files/jpt_ui_entity_gen.properties
@@ -0,0 +1,111 @@
+###############################################################################
+# Copyright (c) 2006, 2010 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
+############################################################################### 
+
+cardinality=Car&dinality:
+property=P&roperty:
+cascade=&Cascade:
+connection=&Connection:
+schema=&Schema:
+schemaInfo=(Note: You must have an active connection to select schema.)
+addConnectionLink=Add connections...
+connectLink=Connect
+connectingToDatabase=Connecting to database
+manyToOne=&Many to one
+manyToMany=Man&y to many
+oneToMany=&One to many
+oneToOne=&One to one
+manyToOneDesc=Each %s has many %s.
+oneToOneDesc=There is one %s per %s.
+manyToManyDesc=Each %s has many %s, and each %s has many %s.
+
+add=&Add
+remove=&Remove
+
+GenerateEntitiesWizard_generateEntities=Generate Custom Entities
+
+GenerateEntitiesWizard_selectJPAProject=JPA Project Selection
+GenerateEntitiesWizard_selectJPAProject_msg=Select a JPA project.
+
+GenerateEntitiesWizard_tableSelectPage_selectTable=Select Tables
+GenerateEntitiesWizard_tableSelectPage_chooseEntityTable=Select tables to generate entities from.
+GenerateEntitiesWizard_tableSelectPage_updatePersistenceXml=Update class list in persistence.xml
+GenerateEntitiesWizard_tableSelectPage_tables=&Tables:
+GenerateEntitiesWizard_tableSelectPage_tableColumn=Table
+GenerateEntitiesWizard_tableSelectPage_Restore_Defaults=Restore Defaults
+
+GenerateEntitiesWizard_assocPage_title=Table Associations
+GenerateEntitiesWizard_assocPage_label=Table &associations
+GenerateEntitiesWizard_assocPage_desc=Edit a table association by selecting it and modifying the controls in the editing panel.
+GenerateEntitiesWizard_assocPage_newAssoc=New Association
+GenerateEntitiesWizard_assocPage_delAssoc=Delete Selected Association
+
+
+GenerateEntitiesWizard_defaultTablePage_title=Customize Default Entity Generation
+GenerateEntitiesWizard_defaultTablePage_tableMapping=Table mapping
+GenerateEntitiesWizard_defaultTablePage_domainJavaClass=Domain java class
+
+GenerateEntitiesWizard_defaultTablePage_desc=Optionally customize aspects of entities that will be generated by default from database tables. A Java package should be specified.
+GenerateEntitiesWizard_defaultTablePage_access=Entity &access:
+GenerateEntitiesWizard_defaultTablePage_fetch=Associations &fetch:
+GenerateEntitiesWizard_defaultTablePage_collType=Collection properties &type:
+GenerateEntitiesWizard_defaultTablePage_genOptionalAnnotations = Always generate optional JPA annotations and DDL parameters
+GenerateEntitiesWizard_defaultTablePage_genOptionalAnnotations_desc =  Generate optional JPA annotations and DDL parameters like 'unique', 'nullable', 'length', 'precision' and 'scale', which are optional and only used by automatic table creation to specify table creation data.
+GenerateEntitiesWizard_defaultTablePage_keyGen=Key &generator:
+GenerateEntitiesWizard_defaultTablePage_sequence=Sequence &name:
+GenerateEntitiesWizard_defaultTablePage_sequenceNote=You can use the patterns %s and/or %s in the sequence name.\n\
+			These patterns will be replaced by the table name and the primary key \n\
+			column name when a table mapping is generated.
+
+
+GenerateEntitiesWizard_tablesAndColumnsPage_title=Customize Individual Entities
+GenerateEntitiesWizard_tablesAndColumnsPage_desc=Customize detail of individual entities by selecting the associated tables or columns and changing values in the editing panel.
+GenerateEntitiesWizard_tablesAndColumnsPage_labelTableAndColumns=&Tables and columns
+
+GenerateEntitiesWizard_tablePanel_className=&Class name:
+GenerateEntitiesWizard_colPanel_genProp=Generate this property
+GenerateEntitiesWizard_colPanel_colMapping=Column mapping
+GenerateEntitiesWizard_colPanel_propName=Property &name:
+GenerateEntitiesWizard_colPanel_propType=Mapping t&ype:
+GenerateEntitiesWizard_colPanel_mapKind=Mapping &kind:
+GenerateEntitiesWizard_colPanel_beanProp=Domain Java Class
+GenerateEntitiesWizard_colPanel_getterScope=Getter scope:
+GenerateEntitiesWizard_colPanel_setterScope=Setter scope:
+GenerateEntitiesWizard_colPanel_colUpdateable=Column is &updatable
+GenerateEntitiesWizard_colPanel_colInsertable=Column is &insertable
+
+GenerateEntitiesWizard_newAssoc_title=Create New Association
+
+GenerateEntitiesWizard_newAssoc_tablesPage_title=Association Tables
+GenerateEntitiesWizard_newAssoc_tablesPage_desc=Specify the association tables.
+GenerateEntitiesWizard_newAssoc_tablesPage_assocKind=Association kind
+GenerateEntitiesWizard_newAssoc_tablesPage_assocTables=Association &tables:
+GenerateEntitiesWizard_newAssoc_tablesPage_table1=Table &1:
+GenerateEntitiesWizard_newAssoc_tablesPage_table2=Table &2:
+GenerateEntitiesWizard_newAssoc_tablesPage_intermediateTable=Join table:
+GenerateEntitiesWizard_newAssoc_tablesPage_simpleAssoc=&Simple association
+GenerateEntitiesWizard_newAssoc_tablesPage_m2mAssoc=&Many to many association
+
+GenerateEntitiesWizard_newAssoc_cardinalityPage_title=Association Cardinality
+GenerateEntitiesWizard_newAssoc_cardinalityPage_desc=Specify the association cardinality.
+
+GenerateEntitiesWizard_newAssoc_colsPage_title=Join Columns
+GenerateEntitiesWizard_newAssoc_colsPage_desc=Specify the join columns.
+GenerateEntitiesWizard_newAssoc_colsPage_label=Specify the join columns between the %s and %s tables:
+
+GenerateEntitiesWizard_assocEditor_entityRef=Generate a reference to %s in %s
+GenerateEntitiesWizard_assocEditor_setRef=Generate a reference to a collection of %s in %s
+GenerateEntitiesWizard_assocEditor_tableJoin=Table &join:
+GenerateEntitiesWizard_assocEditor_joinedWhen=The table rows are joined when:\n%s
+GenerateEntitiesWizard_assocEditor_genAssoc=Generate &this association
+GenerateEntitiesWizard_doNotShowWarning = Don't show me this warning again
+
+selectCascadeDlgTitle=Select Cascade
+selectTableDlgTitle=Table Selection
+selectTableDlgDesc=&Select a table:
diff --git a/jpa/plugins/org.eclipse.jpt.ui/property_files/jpt_ui_entity_wizard.properties b/jpa/plugins/org.eclipse.jpt.ui/property_files/jpt_ui_entity_wizard.properties
new file mode 100644
index 0000000..064f384
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/property_files/jpt_ui_entity_wizard.properties
@@ -0,0 +1,57 @@
+################################################################################
+# Copyright (c) 2008, 2010 by SAP AG, Walldorf. 
+# 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:
+#     SAP AG - initial API and implementation
+#     Dimiter Dimitrov, d.dimitrov@sap.com - initial API and implementation     
+################################################################################
+
+ENTITY_WIZARD_TITLE=New JPA Entity
+ENTITY_WIZARD_PAGE_TITLE=Entity class
+ENTITY_WIZARD_PAGE_DESCRIPTION=Create a new JPA entity. Only JPA enabled projects may be selected.
+DEFAULT_PACKAGE_WARNING=The usage of the default package is not recommended.
+ENTITY_PROPERTIES_TITLE=Entity Properties
+ENTITY_PROPERTIES_DESCRIPTION=Set entity name, table name, fields, and access type.
+ENTITY=Entit&y
+MAPPED_AS_SUPERCLASS=Mapped super&class
+INHERITANCE_GROUP=Inheritance
+INHERITANCE_CHECK_BOX=&Inheritance:
+XML_STORAGE_GROUP=XML entity mappings
+XML_SUPPORT=Add to entity mappings in &XML
+CHOOSE_XML=M&apping file:
+MAPPING_XML_TITLE=Mapping File
+XML_NAME_TITLE=XML name:
+CHOOSE_MAPPING_XML_MESSAGE=Choose mapping XML
+INVALID_XML_NAME=The mapping file does not exist
+TYPE_DIALOG_TITLE=Choose Type
+TYPE_DIALOG_DESCRIPTION=Choose the type of the entity field.
+ENTITY_NAME=Entity na&me:
+TABLE_NAME_GROUP=Table name
+TABLE_NAME=&Table name:
+USE_DEFAULT=&Use default
+ENTITY_FIELDS_GROUP=Entity field&s
+ENTITY_FIELDS_DIALOG_TITLE=Entity Fields
+KEY=Key
+NAME_COLUMN=Name
+TYPE_COLUMN=Type
+NAME_TEXT_FIELD=Na&me:
+TYPE_TEXT_FIELD=&Type:
+BROWSE_BUTTON_LABEL=B&rowse...
+ADD_BUTTON_LABEL=&Add...
+EDIT_BUTTON_LABEL=&Edit...
+REMOVE_BUTTON_LABEL=&Remove
+DUPLICATED_ENTITY_NAMES_MESSAGE=There are duplicate names on created entity fields. Please resolve the duplication.
+ACCESS_TYPE=Access type
+FIELD_BASED=Fiel&d
+PROPERTY_BASED=&Property
+NO_JPA_PROJECTS=No JPA projects in the workspace
+APPLY_CHANGES_TO_PERSISTENCE_XML=Apply changes to persistence XML
+ADD_MAPPED_SUPERCLASS_TO_XML=Add mapped superclass to XML
+ADD_ENTITY_TO_XML=Add entity to XML
+EntityDataModelProvider_typeNotInProjectClasspath=''{0}'' does not exist on the project classpath
+EntityDataModelProvider_invalidPKType=''{0}'' is not a valid simple primary key type
+EntityDataModelProvider_invalidArgument=Invalid argument ''{0}''
diff --git a/jpa/plugins/org.eclipse.jpt.ui/property_files/jpt_ui_persistence.properties b/jpa/plugins/org.eclipse.jpt.ui/property_files/jpt_ui_persistence.properties
new file mode 100644
index 0000000..ae091e7
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/property_files/jpt_ui_persistence.properties
@@ -0,0 +1,59 @@
+################################################################################
+# Copyright (c) 2006, 2009 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
+################################################################################
+
+Boolean_False=False
+Boolean_True=True
+
+ArchiveFileSelectionDialog_jarPathHelpLabel=The correct path to the JAR file selected will vary on your deployment environment.  You may alter it here to correctly reflect your particular environment.
+ArchiveFileSelectionDialog_jarPathLabel=JAR file path:
+
+PersistenceEditor_page_help=Help
+PersistenceEditor_sourceTab=Source
+
+PersistenceUnitClassesComposite_description=Specify the list of classes to be managed in this persistence unit.
+PersistenceUnitClassesComposite_excludeUnlistedMappedClasses=Exclude unlisted classes
+PersistenceUnitClassesComposite_excludeUnlistedMappedClassesWithDefault=Exclude unlisted classes ({0})
+PersistenceUnitClassesComposite_mappedClassesNoName=<name not set>
+PersistenceUnitClassesComposite_open=Open
+
+PersistenceUnitConnectionGeneralComposite_default=Default(JTA)
+PersistenceUnitConnectionGeneralComposite_jta=JTA
+PersistenceUnitConnectionGeneralComposite_resource_local=Resource Local
+
+PersistenceUnitConnectionComposite_connection=Connection
+PersistenceUnitConnectionComposite_database=Database
+PersistenceUnitConnectionComposite_general=General
+
+PersistenceUnitConnectionDatabaseComposite_jtaDatasourceName=JTA data source name:
+PersistenceUnitConnectionDatabaseComposite_nonJtaDatasourceName=Non-JTA data source name:
+
+PersistenceUnitConnectionGeneralComposite_transactionType=Transaction type:
+
+PersistenceUnitGeneralComposite_general=General
+PersistenceUnitGeneralComposite_jarFiles=JAR Files
+PersistenceUnitGeneralComposite_jpaMappingDescriptors=XML Mapping Files
+PersistenceUnitGeneralComposite_jpaMappingDescriptors_description=Specify the XML mapping files for this persistence unit.
+PersistenceUnitGeneralComposite_mappedClasses=Managed Classes
+PersistenceUnitGeneralComposite_name=Name:
+PersistenceUnitGeneralComposite_persistenceProvider=Persistence provider:
+PersistenceUnitGeneralComposite_description=Description:
+
+PersistenceUnitJarFilesComposite_noFileName=<File name not set>
+PersistenceUnitMappingFilesComposite_jarFileDialog_title=JAR File Selection
+PersistenceUnitMappingFilesComposite_jarFileDialog_message=Choose a JAR file to be added to the persistence unit.
+
+PersistenceUnitMappingFilesComposite_mappingFileDialog_message=Choose the XML mapping files to be added to the persistence unit.
+PersistenceUnitMappingFilesComposite_mappingFileDialog_title=JPA XML Mapping File Selection
+PersistenceUnitMappingFilesComposite_ormNoName=<name not set>
+
+PersistenceUnitPropertiesComposite_nameColumn=Name
+PersistenceUnitPropertiesComposite_properties=Properties
+PersistenceUnitPropertiesComposite_properties_description=This table lists all properties that are defined for this persistence unit.
+PersistenceUnitPropertiesComposite_valueColumn=Value
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/property_files/jpt_ui_persistence2_0.properties b/jpa/plugins/org.eclipse.jpt.ui/property_files/jpt_ui_persistence2_0.properties
new file mode 100644
index 0000000..7603cf1
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/property_files/jpt_ui_persistence2_0.properties
@@ -0,0 +1,59 @@
+################################################################################
+# Copyright (c) 2009, 2010 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
+################################################################################
+
+ConnectionPropertiesComposite_Database_GroupBox = Database
+
+DataSourcePropertiesComposite_jtaDataSourceLabel = JTA data source:
+DataSourcePropertiesComposite_nonJtaDataSourceLabel = Non-JTA data source:
+
+GenericPersistenceUnit2_0ConnectionComposite_sectionTitle = Persistence Unit Connection
+GenericPersistenceUnit2_0ConnectionComposite_sectionDescription = Configure the data source or JDBC connection properties.
+
+JdbcConnectionPropertiesComposite_ConnectionDialog_Message = &Enter connection name or pattern (*, ?, or camel case):
+JdbcConnectionPropertiesComposite_ConnectionDialog_Title = Connection Selection
+GenericPersistenceUnit2_0ConnectionTab_title = Connection
+
+GenericPersistenceUnit2_0OptionsComposite_miscellaneousSectionTitle = Miscellaneous Options
+GenericPersistenceUnit2_0OptionsComposite_miscellaneousSectionDescription = Configure the miscellaneous options.
+GenericPersistenceUnit2_0OptionsTab_title = Options
+
+JdbcConnectionPropertiesComposite_populateFromConnectionHyperLink =	Populate from connection...
+JdbcConnectionPropertiesComposite_driverLabel = Driver:
+JdbcConnectionPropertiesComposite_urlLabel = URL:
+JdbcConnectionPropertiesComposite_userLabel = User:
+JdbcConnectionPropertiesComposite_passwordLabel = Password:
+
+JdbcPropertiesComposite_JdbcConnectionProperties_GroupBox = JDBC connection properties
+
+LockingConfigurationComposite_lockTimeoutLabel = Lock timeout:
+QueryConfigurationComposite_queryTimeoutLabel = Query timeout:
+
+TransactionTypeComposite_transactionTypeLabel = Transaction type:
+
+TransactionTypeComposite_jta = JTA
+TransactionTypeComposite_resource_local = Resource Local
+
+SharedCacheModeComposite_sharedCacheModeLabel = Shared cache mode:
+
+SharedCacheModeComposite_all = All
+SharedCacheModeComposite_none = None
+SharedCacheModeComposite_enable_selective = Enable Selective
+SharedCacheModeComposite_disable_selective = Disable Selective
+SharedCacheModeComposite_unspecified = Unspecified
+
+ValidationModeComposite_validationModeLabel = Validation mode:
+
+ValidationModeComposite_auto = Auto
+ValidationModeComposite_callback = Callback
+ValidationModeComposite_none = None
+
+ValidationConfigurationComposite_groupPrePersistLabel = Validate pre-persist group:
+ValidationConfigurationComposite_groupPreUpdateLabel = Validate pre-update group:
+ValidationConfigurationComposite_groupPreRemoveLabel = Validate pre-remove group:
diff --git a/jpa/plugins/org.eclipse.jpt.ui/property_files/jpt_ui_validation_preferences.properties b/jpa/plugins/org.eclipse.jpt.ui/property_files/jpt_ui_validation_preferences.properties
new file mode 100644
index 0000000..93aa07e
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/property_files/jpt_ui_validation_preferences.properties
@@ -0,0 +1,183 @@
+################################################################################
+# Copyright (c) 2009, 2010 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
+################################################################################
+PROJECT_LEVEL_CATEGORY=Project
+
+NO_JPA_PROJECT=Project has JPA facet, but JPA project couldn't be created:
+PROJECT_NO_CONNECTION=No connection specified for project:
+PROJECT_INVALID_CONNECTION=Connection does not exist:
+PROJECT_INACTIVE_CONNECTION=Connection is not active:
+PROJECT_NO_PERSISTENCE_XML=No persistence.xml file found in project:
+PROJECT_MULTIPLE_PERSISTENCE_XML=Multiple persistence.xml files in project:
+
+XML_VERSION_NOT_LATEST=XML document version not most recent:
+
+PERSISTENCE_NO_PERSISTENCE_UNIT=No persistence unit defined:
+PERSISTENCE_MULTIPLE_PERSISTENCE_UNITS=Multiple persistence units defined:
+PERSISTENCE_XML_INVALID_CONTENT=Invalid content (no root node):
+
+PERSISTENCE_UNIT_LEVEL_CATEGORY=Persistence unit
+
+PERSISTENCE_UNIT_UNSPECIFIED_MAPPING_FILE=Unspecified mapping file:
+PERSISTENCE_UNIT_UNSUPPORTED_MAPPING_FILE_CONTENT=Mapping file does not have supported content:
+PERSISTENCE_UNIT_NONEXISTENT_MAPPING_FILE=Mapping file cannot be resolved:
+PERSISTENCE_UNIT_INVALID_MAPPING_FILE=Mapping file does not have ORM content:
+PERSISTENCE_UNIT_DUPLICATE_MAPPING_FILE=Duplicate mapping file:
+PERSISTENCE_UNIT_UNSPECIFIED_CLASS=Unspecified class:
+PERSISTENCE_UNIT_NONEXISTENT_CLASS=Class cannot be resolved:
+PERSISTENCE_UNIT_INVALID_CLASS=Class is included in a persistence unit but is not mapped:
+PERSISTENCE_UNIT_DUPLICATE_CLASS=Duplicate class:
+PERSISTENCE_UNIT_REDUNDANT_CLASS=Class is already specified in mapping file:
+PERSISTENCE_UNIT_DUPLICATE_JAR_FILE=Duplicate JAR file:
+PERSISTENCE_UNIT_UNSPECIFIED_JAR_FILE=Unspecified JAR file:
+PERSISTENCE_UNIT_JAR_FILE_DEPLOYMENT_PATH_WARNING=The path to the JAR file will vary:
+PERSISTENCE_UNIT_NONEXISTENT_JAR_FILE=JAR file cannot be resolved:
+MAPPING_FILE_EXTRANEOUS_PERSISTENCE_UNIT_DEFAULTS=Extraneous persistence unit defaults found:
+PERSISTENT_TYPE_MAPPED_BUT_NOT_INCLUDED_IN_PERSISTENCE_UNIT=Class is mapped, but is not in a persistence unit:
+PERSISTENT_TYPE_ANNOTATED_BUT_NOT_INCLUDED_IN_PERSISTENCE_UNIT=Class is annotated, but is not in a persistence unit:
+
+TYPE_LEVEL_CATEGORY=Type
+
+PERSISTENT_TYPE_UNSPECIFIED_CLASS=Class is unspecified in orm.xml:
+PERSISTENT_TYPE_UNRESOLVED_CLASS=Class in orm.xml cannot be resolved to a java class:
+ENTITY_NO_PK=Entity has no primary key:
+ENTITY_SINGLE_TABLE_DESCENDANT_DEFINES_TABLE=No table should be defined for non-root entity using single-table inheritance:
+ENTITY_ABSTRACT_TABLE_PER_CLASS_DEFINES_TABLE=No table should be defined for abstract entity using table-per-concrete-class inheritance:
+ENTITY_ABSTRACT_DISCRIMINATOR_VALUE_DEFINED = No discriminator value should be defined for abstract entity:
+ENTITY_TABLE_PER_CLASS_DISCRIMINATOR_VALUE_DEFINED = No discriminator value should be defined for entity using table-per-concrete-class inheritance:
+ENTITY_NON_ROOT_DISCRIMINATOR_COLUMN_DEFINED =No discriminator column should be defined for non-root entity:
+ENTITY_TABLE_PER_CLASS_DISCRIMINATOR_COLUMN_DEFINED = No discriminator column should be defined for entity using table-per-concrete-class inheritance:
+
+ATTRIBUTE_LEVEL_CATEGORY=Attribute
+
+PERSISTENT_ATTRIBUTE_UNSPECIFIED_NAME=Attribute in orm.xml has unspecified name:
+PERSISTENT_ATTRIBUTE_UNRESOLVED_NAME=Attribute in orm.xml cannot be resolved in the java class:
+PERSISTENT_ATTRIBUTE_INHERITED_ATTRIBUTES_NOT_SUPPORTED=In orm.xml referenced inherited attribute may not be supported:
+PERSISTENT_ATTRIBUTE_INVALID_MAPPING=Attribute has invalid mapping type:
+PERSISTENT_ATTRIBUTE_FINAL_FIELD=The java field for attribute is final:
+PERSISTENT_ATTRIBUTE_PUBLIC_FIELD=The java field for attribute is public:
+MAPPING_UNRESOLVED_MAPPED_BY=Cannot resolve attribute name:
+MAPPING_INVALID_MAPPED_BY=Attribute has invalid mapping for this relationship:
+MAPPING_MAPPED_BY_WITH_JOIN_TABLE=Cannot specify join table if attribute is mapped by another attribute:
+MAPPING_MAPPED_BY_ON_BOTH_SIDES=Relationship must have an owner:
+TARGET_ENTITY_NOT_DEFINED=Target entity is not defined:
+TARGET_ENTITY_IS_NOT_AN_ENTITY=Target entity is not an Entity:
+MAPS_ID_VALUE_NOT_SPECIFIED="Maps ID" attribute value not specified:
+MAPS_ID_VALUE_NOT_RESOLVED="Maps ID" attribute value not resolved:
+MAPS_ID_VALUE_INVALID="Maps ID" attribute value invalid:
+ORDER_COLUMN_AND_ORDER_BY_BOTH_SPECIFIED=OrderColumn and OrderBy annotations are both specified:
+ELEMENT_COLLECTION_TARGET_CLASS_NOT_DEFINED=Element collection target class not defined:
+ELEMENT_COLLECTION_TARGET_CLASS_MUST_BE_EMBEDDABLE_OR_BASIC_TYPE=Element collection target class is not embeddable or basic type:
+ELEMENT_COLLECTION_MAP_KEY_CLASS_NOT_DEFINED=Element collection map key class not defined:
+
+DATABASE_CATEGORY=Database
+TABLE_CATEGORY=Table
+
+TABLE_UNRESOLVED_CATALOG=Catalog cannot be resolved for table:
+TABLE_UNRESOLVED_SCHEMA=Schema cannot be resolved for table:
+TABLE_UNRESOLVED_NAME=Table cannot be resolved:
+SECONDARY_TABLE_UNRESOLVED_CATALOG=Catalog cannot be resolved for secondary table:
+SECONDARY_TABLE_UNRESOLVED_SCHEMA=Schema cannot be resolved for secondary table:
+SECONDARY_TABLE_UNRESOLVED_NAME=Secondary table cannot be resolved:
+JOIN_TABLE_UNRESOLVED_CATALOG=Catalog cannot be resolved for join table:
+JOIN_TABLE_UNRESOLVED_SCHEMA=Schema cannot be resolved for join table:
+JOIN_TABLE_UNRESOLVED_NAME=Join table cannot be resolved:
+VIRTUAL_SECONDARY_TABLE_PRIMARY_KEY_JOIN_COLUMN_UNRESOLVED_NAME=Implied secondary table primary key join column cannot be resolved:
+VIRTUAL_SECONDARY_TABLE_PRIMARY_KEY_JOIN_COLUMN_UNRESOLVED_REFERENCED_COLUMN_NAME=Implied secondary table primary key join column referenced column name cannot be resolved:
+VIRTUAL_SECONDARY_TABLE_PRIMARY_KEY_JOIN_COLUMN_NAME_MUST_BE_SPECIFIED_MULTIPLE_JOIN_COLUMNS=Implied secondary table primary key join column name must be specified when there are multiples:
+VIRTUAL_SECONDARY_TABLE_PRIMARY_KEY_JOIN_COLUMN_REFERENCED_COLUMN_NAME_MUST_BE_SPECIFIED_MULTIPLE_JOIN_COLUMNS=Implied secondary table primary key join column referenced column name must be specified when there are multiples:
+COLLECTION_TABLE_UNRESOLVED_CATALOG=Catalog cannot be resolved for collection table:
+COLLECTION_TABLE_UNRESOLVED_SCHEMA=Schema cannot be resolved for collection table:
+COLLECTION_TABLE_UNRESOLVED_NAME=Collection table cannot be resolved:
+
+COLUMN_CATEGORY=Column
+
+COLUMN_UNRESOLVED_TABLE=Table for column cannot be resolved:
+COLUMN_UNRESOLVED_NAME=Column cannot be resolved:
+COLUMN_TABLE_NOT_VALID=Table for column not valid given the context:
+JOIN_COLUMN_TABLE_NOT_VALID=Table for join column is not valid:
+JOIN_COLUMN_UNRESOLVED_NAME=Join column cannot be resolved:
+JOIN_COLUMN_NAME_MUST_BE_SPECIFIED_MULTIPLE_JOIN_COLUMNS=Join column name must be specified when there are multiples:
+JOIN_COLUMN_UNRESOLVED_REFERENCED_COLUMN_NAME=Referenced column in join column cannot be resolved:
+JOIN_COLUMN_REFERENCED_COLUMN_NAME_MUST_BE_SPECIFIED_MULTIPLE_JOIN_COLUMNS=Join column referenced column name must be specified when there are multiples:
+INVERSE_JOIN_COLUMN_TABLE_NOT_VALID=Table for inverse join column is not valid:
+INVERSE_JOIN_COLUMN_UNRESOLVED_NAME=Inverse join column cannot be resolved:
+INVERSE_JOIN_COLUMN_NAME_MUST_BE_SPECIFIED_MULTIPLE_JOIN_COLUMNS=Inverse join column name must be specified when there are multiples:
+INVERSE_JOIN_COLUMN_UNRESOLVED_REFERENCED_COLUMN_NAME=Referenced column in inverse join column cannot be resolved:
+INVERSE_JOIN_COLUMN_REFERENCED_COLUMN_NAME_MUST_BE_SPECIFIED_MULTIPLE_JOIN_COLUMNS=Inverse join column referenced column name must be specified when there are multiples:
+PRIMARY_KEY_JOIN_COLUMN_UNRESOLVED_NAME=Primary key join column cannot be resolved:
+PRIMARY_KEY_JOIN_COLUMN_UNRESOLVED_REFERENCED_COLUMN_NAME=Referenced column in primary key join column cannot be resolved:
+PRIMARY_KEY_JOIN_COLUMN_NAME_MUST_BE_SPECIFIED_MULTIPLE_JOIN_COLUMNS=Primary key join column name must be specified when there are multiples:
+PRIMARY_KEY_JOIN_COLUMN_REFERENCED_COLUMN_NAME_MUST_BE_SPECIFIED_MULTIPLE_JOIN_COLUMNS=Primary key join column referenced column name must be specified when there are multiples:
+MAP_KEY_COLUMN_TABLE_NOT_VALID=Table for map key column is not valid:
+ORDER_COLUMN_UNRESOLVED_NAME=Order column cannot be resolved:
+VIRTUAL_PRIMARY_KEY_JOIN_COLUMN_UNRESOLVED_NAME=Implied primary key join column cannot be resolved:
+VIRTUAL_PRIMARY_KEY_JOIN_COLUMN_UNRESOLVED_REFERENCED_COLUMN_NAME=Implied primary key join column referenced column name cannot be resolved:
+
+OVERRIDES_CATEGORY=Attribute/association overrides
+IMPLIED_ATTRIBUTE_LEVEL_CATEGORY=Implied attributes
+
+VIRTUAL_MAP_KEY_ATTRIBUTE_OVERRIDE_COLUMN_TABLE_NOT_VALID=Implied map key attribute override table for column is not valid:
+VIRTUAL_ATTRIBUTE_OVERRIDE_COLUMN_UNRESOLVED_NAME=Implied attribute override column cannot be resolved:
+VIRTUAL_ATTRIBUTE_OVERRIDE_COLUMN_TABLE_NOT_VALID=Implied attribute override table for column not valid:
+VIRTUAL_ASSOCIATION_OVERRIDE_JOIN_COLUMN_TABLE_NOT_VALID=Implied association override table for join column is not valid:
+VIRTUAL_ASSOCIATION_OVERRIDE_JOIN_COLUMN_UNRESOLVED_NAME=Implied association override join column cannot be resolved:
+VIRTUAL_ASSOCIATION_OVERRIDE_JOIN_COLUMN_UNRESOLVED_REFERENCED_COLUMN_NAME=Implied association override referenced column in join column cannot be resolved:
+VIRTUAL_ASSOCIATION_OVERRIDE_JOIN_COLUMN_NAME_MUST_BE_SPECIFIED_MULTIPLE_JOIN_COLUMNS=Implied association override join column name must be specified when there are multiples:
+VIRTUAL_ASSOCIATION_OVERRIDE_JOIN_COLUMN_REFERENCED_COLUMN_NAME_MUST_BE_SPECIFIED_MULTIPLE_JOIN_COLUMNS=Implied association override join column referenced column name must be specified when there are multiples:
+
+VIRTUAL_ATTRIBUTE_JOIN_TABLE_UNRESOLVED_CATALOG=Catalog cannot be resolved for join table:
+VIRTUAL_ATTRIBUTE_JOIN_TABLE_UNRESOLVED_SCHEMA=Schema cannot be resolved for join table:
+VIRTUAL_ATTRIBUTE_JOIN_TABLE_UNRESOLVED_NAME=Join table cannot be resolved:
+VIRTUAL_ATTRIBUTE_ATTRIBUTE_OVERRIDE_COLUMN_TABLE_NOT_VALID=Attribute override table for column not valid:
+VIRTUAL_ATTRIBUTE_COLUMN_TABLE_NOT_VALID=Table for column not valid:
+VIRTUAL_ATTRIBUTE_ATTRIBUTE_OVERRIDE_COLUMN_UNRESOLVED_NAME=Attribute override column cannot be resolved:
+VIRTUAL_ATTRIBUTE_COLUMN_UNRESOLVED_NAME=Column cannot be resolved:
+VIRTUAL_ATTRIBUTE_JOIN_COLUMN_UNRESOLVED_TABLE=Table for join column cannot be resolved:
+VIRTUAL_ATTRIBUTE_JOIN_COLUMN_UNRESOLVED_NAME=Join column cannot be resolved:
+VIRTUAL_ATTRIBUTE_JOIN_COLUMN_NAME_MUST_BE_SPECIFIED_MULTIPLE_JOIN_COLUMNS=Join column name must be specified when there are multiples:
+VIRTUAL_ATTRIBUTE_JOIN_COLUMN_UNRESOLVED_REFERENCED_COLUMN_NAME=Referenced column in join column cannot be resolved:
+VIRTUAL_ATTRIBUTE_JOIN_COLUMN_REFERENCED_COLUMN_NAME_MUST_BE_SPECIFIED_MULTIPLE_JOIN_COLUMNS=Join column referenced column name must be specified when there are multiples:
+VIRTUAL_ATTRIBUTE_TARGET_ENTITY_IS_NOT_AN_ENTITY=Target entity is not an Entity:
+VIRTUAL_ATTRIBUTE_TARGET_ENTITY_NOT_DEFINED=Target entity is not defined:
+VIRTUAL_ATTRIBUTE_COLLECTION_TABLE_UNRESOLVED_CATALOG=Catalog cannot be resolved for collection table:
+VIRTUAL_ATTRIBUTE_COLLECTION_TABLE_UNRESOLVED_SCHEMA=Schema cannot be resolved for collection table:
+VIRTUAL_ATTRIBUTE_COLLECTION_TABLE_UNRESOLVED_NAME=Collection table cannot be resolved:
+VIRTUAL_ATTRIBUTE_ORDER_COLUMN_UNRESOLVED_NAME=Order column cannot be resolved:
+VIRTUAL_ATTRIBUTE_ELEMENT_COLLECTION_TARGET_CLASS_NOT_DEFINED=Element collection target class not defined:
+VIRTUAL_ATTRIBUTE_ELEMENT_COLLECTION_TARGET_CLASS_MUST_BE_EMBEDDABLE_OR_BASIC_TYPE=Element collection target class is not embeddable or basic type:
+VIRTUAL_ATTRIBUTE_ELEMENT_COLLECTION_MAP_KEY_CLASS_NOT_DEFINED=Element collection map key class not defined:
+VIRTUAL_ATTRIBUTE_JOIN_COLUMN_TABLE_NOT_VALID=Table for join column is not valid:
+VIRTUAL_ATTRIBUTE_INVERSE_JOIN_COLUMN_TABLE_NOT_VALID=Table for inverse join column is not valid:
+VIRTUAL_ATTRIBUTE_INVERSE_JOIN_COLUMN_UNRESOLVED_NAME=Inverse join column cannot be resolved:
+VIRTUAL_ATTRIBUTE_INVERSE_JOIN_COLUMN_NAME_MUST_BE_SPECIFIED_MULTIPLE_JOIN_COLUMNS=Inverse join column name must be specified when there are multiples:
+VIRTUAL_ATTRIBUTE_INVERSE_JOIN_COLUMN_UNRESOLVED_REFERENCED_COLUMN_NAME=Referenced column in inverse join column cannot be resolved:
+VIRTUAL_ATTRIBUTE_INVERSE_JOIN_COLUMN_REFERENCED_COLUMN_NAME_MUST_BE_SPECIFIED_MULTIPLE_JOIN_COLUMNS=Inverse join column referenced column name must be specified when there are multiples:
+VIRTUAL_ATTRIBUTE_MAP_KEY_COLUMN_TABLE_NOT_VALID=Table for map key column is not valid:
+VIRTUAL_ATTRIBUTE_MAP_KEY_ATTRIBUTE_OVERRIDE_COLUMN_TABLE_NOT_VALID=Map key attribute override table for column not valid:
+
+
+VIRTUAL_ATTRIBUTE_ASSOCIATION_OVERRIDE_JOIN_COLUMN_TABLE_NOT_VALID=Association override table for join column is not valid:
+VIRTUAL_ATTRIBUTE_ASSOCIATION_OVERRIDE_JOIN_COLUMN_UNRESOLVED_NAME=Association override join column cannot be resolved:
+VIRTUAL_ATTRIBUTE_ASSOCIATION_OVERRIDE_JOIN_COLUMN_REFERENCED_COLUMN_UNRESOLVED_NAME=Association override join column referenced column name cannot be resolved:
+VIRTUAL_ATTRIBUTE_ASSOCIATION_OVERRIDE_JOIN_COLUMN_NAME_MUST_BE_SPECIFIED_MULTIPLE_JOIN_COLUMNS=Association override join column name must be specified when there are multiples:
+VIRTUAL_ATTRIBUTE_ASSOCIATION_OVERRIDE_JOIN_COLUMN_REFERENCED_COLUMN_NAME_MUST_BE_SPECIFIED_MULTIPLE_JOIN_COLUMNS=Association override join column referenced column name must be specified when there are multiples:
+
+INHERITANCE_CATEGORY=Inheritance
+
+DISCRIMINATOR_COLUMN_UNRESOLVED_NAME=Discriminator column cannot be resolved:
+ENTITY_TABLE_PER_CLASS_NOT_SUPPORTED_ON_PLATFORM=Entity cannot use table-per-concrete-class inheritance:
+ENTITY_TABLE_PER_CLASS_NOT_PORTABLE_ON_PLATFORM=Entity uses table-per-concrete-class inheritance which is not portable:
+
+QUERIES_GENERATORS_CATEGORY=Queries and generators
+
+GENERATOR_DUPLICATE_NAME=Duplicate generator defined:
+ID_MAPPING_UNRESOLVED_GENERATOR_NAME=Unresolved generator name:
+GENERATED_VALUE_UNRESOLVED_GENERATOR=Generator is not defined in the persistence unit:
+QUERY_DUPLICATE_NAME=Duplicate query defined:
diff --git a/jpa/plugins/org.eclipse.jpt.ui/schema/jpaPlatformUis.exsd b/jpa/plugins/org.eclipse.jpt.ui/schema/jpaPlatformUis.exsd
new file mode 100644
index 0000000..ef34ed6
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/schema/jpaPlatformUis.exsd
@@ -0,0 +1,139 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.eclipse.jpt.ui" xmlns="http://www.w3.org/2001/XMLSchema">
+<annotation>
+      <appinfo>
+         <meta.schema plugin="org.eclipse.jpt.ui" id="jpaPlatforms" name="JPA Platform UIs"/>
+      </appinfo>
+      <documentation>
+         [Enter description of this extension point.]
+      </documentation>
+   </annotation>
+
+   <element name="extension">
+      <annotation>
+         <appinfo>
+            <meta.element />
+         </appinfo>
+      </annotation>
+      <complexType>
+         <sequence>
+            <element ref="jpaPlatformUi" minOccurs="1" maxOccurs="unbounded"/>
+         </sequence>
+         <attribute name="point" type="string" use="required">
+            <annotation>
+               <documentation>
+                  
+               </documentation>
+            </annotation>
+         </attribute>
+         <attribute name="id" type="string">
+            <annotation>
+               <documentation>
+                  
+               </documentation>
+            </annotation>
+         </attribute>
+         <attribute name="name" type="string">
+            <annotation>
+               <documentation>
+                  
+               </documentation>
+               <appinfo>
+                  <meta.attribute translatable="true"/>
+               </appinfo>
+            </annotation>
+         </attribute>
+      </complexType>
+   </element>
+
+   <element name="jpaPlatformUi">
+      <annotation>
+         <documentation>
+            Extend this extension point and you must also extend the org.eclipse.jpt.core.jpaPlatforms extension point.  The jpaPlatformId must match the id of a core.jpaPlatform extension.  One jpaPlatform will be chosen per JpaProject.  The possible jpaPlatforms will be displayed to the user as a project property.
+         </documentation>
+      </annotation>
+      <complexType>
+         <attribute name="id" type="string" use="required">
+            <annotation>
+               <documentation>
+                  
+               </documentation>
+            </annotation>
+         </attribute>
+         <attribute name="jpaPlatform" type="string" use="required">
+            <annotation>
+               <documentation>
+                  The jpaPlatformId must match the corresponding org.eclipse.jpt.core.jpaPlatform extension id.
+               </documentation>
+            </annotation>
+         </attribute>
+         <attribute name="factoryClass" type="string" use="required">
+            <annotation>
+               <documentation>
+                  The class that implements &lt;samp&gt;org.eclipse.jpt.ui.JpaPlatformUiFactory&lt;/samp&gt;.
+               </documentation>
+               <appinfo>
+                  <meta.attribute kind="java" basedOn=":org.eclipse.jpt.ui.JpaPlatformUiFactory"/>
+               </appinfo>
+            </annotation>
+         </attribute>
+      </complexType>
+   </element>
+
+   <annotation>
+      <appinfo>
+         <meta.section type="since"/>
+      </appinfo>
+      <documentation>
+         2.2
+      </documentation>
+   </annotation>
+
+   <annotation>
+      <appinfo>
+         <meta.section type="examples"/>
+      </appinfo>
+      <documentation>
+         [Enter extension point usage example here.]
+      </documentation>
+   </annotation>
+
+   <annotation>
+      <appinfo>
+         <meta.section type="apiinfo"/>
+      </appinfo>
+      <documentation>
+         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.
+      </documentation>
+   </annotation>
+
+   <annotation>
+      <appinfo>
+         <meta.section type="implementation"/>
+      </appinfo>
+      <documentation>
+         [Enter information about supplied implementation of this extension point.]
+      </documentation>
+   </annotation>
+
+   <annotation>
+      <appinfo>
+         <meta.section type="copyright"/>
+      </appinfo>
+      <documentation>
+         Copyright (c) 2006, 2009 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
+      </documentation>
+   </annotation>
+
+</schema>
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/JpaPlatformUi.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/JpaPlatformUi.java
new file mode 100644
index 0000000..6d01e49
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/JpaPlatformUi.java
@@ -0,0 +1,125 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2009 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.ui;
+
+import java.util.Iterator;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jpt.core.JpaFile;
+import org.eclipse.jpt.core.JpaPlatform;
+import org.eclipse.jpt.core.JpaProject;
+import org.eclipse.jpt.core.JpaResourceType;
+import org.eclipse.jpt.core.JpaStructureNode;
+import org.eclipse.jpt.core.context.AttributeMapping;
+import org.eclipse.jpt.core.context.PersistentAttribute;
+import org.eclipse.jpt.core.context.PersistentType;
+import org.eclipse.jpt.core.context.TypeMapping;
+import org.eclipse.jpt.ui.details.DefaultMappingUiDefinition;
+import org.eclipse.jpt.ui.details.JpaComposite;
+import org.eclipse.jpt.ui.details.JpaDetailsPage;
+import org.eclipse.jpt.ui.details.MappingUiDefinition;
+import org.eclipse.jpt.ui.navigator.JpaNavigatorProvider;
+import org.eclipse.jpt.ui.structure.JpaStructureProvider;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * This interface is to be implemented by a JPA vendor to provide extensions to
+ * JPA UI functionality.  This is intended to work in conjunction with a core
+ * JPA platform ({@link JpaPlatform}) implementation with the same ID.
+ * <p>
+ * Any implementation should be <i>stateless</i> in nature.
+ * <p>
+ * The "generic" extension supplies UI for the core platform extension with the same
+ * ID.
+ *
+ * See the extension point: org.eclipse.jpt.ui.jpaPlatform
+ *
+ * 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.
+ */
+public interface JpaPlatformUi
+{
+	// ********** navigator provider **********
+	
+	/**
+	 * Return the {@link JpaNavigatorProvider} for this platform, 
+	 * which determines Project Explorer content and look
+	 */
+	JpaNavigatorProvider getNavigatorProvider();
+	
+	
+	// ********** structure providers **********
+	
+	/**
+	 * Return a structure provider for the specified JPA file.
+	 */
+	JpaStructureProvider getStructureProvider(JpaFile jpaFile);
+	
+	
+	// ********** details providers **********
+	
+	JpaDetailsPage<? extends JpaStructureNode> buildJpaDetailsPage(
+			Composite parent,
+			JpaStructureNode structureNode,
+			WidgetFactory widgetFactory);
+	
+	
+	// ********** file ui definitions **********
+	
+	/**
+	 * Return a resource ui definition for the specified resource type.
+	 */
+	ResourceUiDefinition getResourceUiDefinition(JpaResourceType resourceType);
+	
+	
+	// ********** type mappings **********
+	
+	JpaComposite buildTypeMappingComposite(
+			JpaResourceType resourceType, 
+			String mappingKey, 
+			Composite parent, 
+			PropertyValueModel<TypeMapping> mappingHolder,
+			WidgetFactory widgetFactory);
+	
+	DefaultMappingUiDefinition<PersistentType, ? extends TypeMapping>
+			getDefaultTypeMappingUiDefinition(JpaResourceType resourceType);
+	
+	Iterator<MappingUiDefinition<PersistentType, ? extends TypeMapping>>
+			typeMappingUiDefinitions(JpaResourceType resourceType);
+	
+	
+	// ********** attribute mappings **********
+	
+	JpaComposite buildAttributeMappingComposite(
+			JpaResourceType resourceType, 
+			String mappingKey, 
+			Composite parent,
+			PropertyValueModel<AttributeMapping> mappingHolder,
+			WidgetFactory widgetFactory);
+	
+	DefaultMappingUiDefinition<PersistentAttribute, ? extends AttributeMapping> 
+			getDefaultAttributeMappingUiDefinition(JpaResourceType resourceType, String mappingKey);
+	
+	Iterator<MappingUiDefinition<PersistentAttribute, ? extends AttributeMapping>>
+			attributeMappingUiDefinitions(JpaResourceType resourceType);
+	
+	
+	// ********** entity generation **********
+	
+	void generateEntities(JpaProject project, IStructuredSelection selection);
+	
+	
+	// ********** DDL generation **********
+	
+	void generateDDL(JpaProject project, IStructuredSelection selection);
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/JpaPlatformUiFactory.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/JpaPlatformUiFactory.java
new file mode 100644
index 0000000..77c05fe
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/JpaPlatformUiFactory.java
@@ -0,0 +1,26 @@
+/*******************************************************************************
+ * Copyright (c) 2009 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.ui;
+
+/**
+ * This interface is to be implemented by a JPA vendor to build a JpaPlatformUi.
+ *
+ * See the extension point: org.eclipse.jpt.ui.jpaPlatform
+ *
+ * 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.
+ */
+public interface JpaPlatformUiFactory
+{
+	JpaPlatformUi buildJpaPlatformUi();
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/JpaPlatformUiProvider.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/JpaPlatformUiProvider.java
new file mode 100644
index 0000000..a853d88
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/JpaPlatformUiProvider.java
@@ -0,0 +1,46 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2009 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.ui;
+
+import java.util.ListIterator;
+import org.eclipse.jpt.core.JpaPlatform;
+import org.eclipse.jpt.ui.details.JpaDetailsProvider;
+
+/**
+ * This interface is to be implemented by a JPA vendor to provide extensions to
+ * JPA UI functionality.  This is intended to work in conjunction with a core
+ * JPA platform ({@link JpaPlatform}) implementation with the same ID.
+ * <p>
+ * Any implementation should be <i>stateless</i> in nature.
+ * <p>
+ * The "generic" extension supplies UI for the core platform extension with the same
+ * ID.
+ *
+ * See the extension point: org.eclipse.jpt.ui.jpaPlatformUis
+ *
+ * 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.
+ */
+public interface JpaPlatformUiProvider
+{
+	/**
+	 * Return the details providers that apply to this platform.
+	 */
+	ListIterator<JpaDetailsProvider> detailsProviders();
+	
+	/**
+	 * Return the resource ui definitions that apply to this platform.
+	 */
+	ListIterator<ResourceUiDefinition> resourceUiDefinitions();
+	
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/JptUiPlugin.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/JptUiPlugin.java
new file mode 100644
index 0000000..24ae9da
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/JptUiPlugin.java
@@ -0,0 +1,236 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2010 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.ui;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.resource.ImageRegistry;
+import org.eclipse.jpt.core.JpaPlatform;
+import org.eclipse.jpt.core.JptCorePlugin;
+import org.eclipse.jpt.ui.internal.platform.JpaPlatformUiRegistry;
+import org.eclipse.jpt.ui.navigator.JpaNavigatorProvider;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Listener;
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+import org.osgi.framework.BundleContext;
+
+/**
+ * Dali UI plug-in.
+ * <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.
+ */
+@SuppressWarnings("nls")
+public class JptUiPlugin
+	extends AbstractUIPlugin
+{
+	private final Listener focusListener;
+
+
+	// ********** constants **********
+
+	/**
+	 * The plug-in identifier of JPA UI support (value {@value}).
+	 */
+	public static final String PLUGIN_ID = "org.eclipse.jpt.ui";
+	public static final String PLUGIN_ID_ = PLUGIN_ID + '.';
+
+	private static final String FOCUS_DATA_KEY = PLUGIN_ID_ + "focus";
+	private static final Object FOCUS_DATA = new Object();
+
+
+	// ********** singleton **********
+
+	private static JptUiPlugin INSTANCE;
+
+	/**
+	 * Returns the singleton JPT UI plug-in.
+	 */
+	public static JptUiPlugin instance() {
+		return INSTANCE;
+	}
+
+
+	// ********** logging **********
+
+	public static void log(IStatus status) {
+        INSTANCE.getLog().log(status);
+    }
+
+	public static void log(String msg) {
+        log(new Status(IStatus.ERROR, PLUGIN_ID, IStatus.OK, msg, null));
+    }
+
+	public static void log(Throwable throwable) {
+		log(new Status(IStatus.ERROR, PLUGIN_ID, IStatus.OK, throwable.getLocalizedMessage(), throwable));
+	}
+
+
+	// ********** images **********
+
+	/**
+	 * Return an image descriptor for the specified <code>.gif<code>
+	 * file in the icons folder.
+	 */
+	public static ImageDescriptor getImageDescriptor(String key) {
+		if ( ! key.startsWith("icons/")) {
+			key = "icons/" + key;
+		}
+		if ( ! key.endsWith(".gif")) {
+			key = key + ".gif";
+		}
+		return imageDescriptorFromPlugin(PLUGIN_ID, key);
+	}
+
+	/**
+	 * Return an image for the specified <code>.gif<code>
+	 * file in the icons folder.
+	 */
+	//TODO we are using the ImageRegistry here and storing all our icons for the life of the plugin, 
+	//which means until the workspace is closed.  This is better than before where we constantly 
+	//created new images. Bug 306437 is about cleaning this up and using Local Resource Managers 
+	//on our views so that closing the JPA perspective would mean our icons are disposed.
+	public static Image getImage(String key) {
+		ImageRegistry imageRegistry = instance().getImageRegistry();
+		Image image = imageRegistry.get(key);
+		if (image == null) {
+			imageRegistry.put(key, getImageDescriptor(key));
+			image = imageRegistry.get(key);
+		}
+		return image;
+	}
+
+
+	// ********** construction **********
+
+	public JptUiPlugin() {
+		super();
+		this.focusListener = this.buildFocusListener();
+		if (INSTANCE != null) {
+			throw new IllegalStateException();
+		}
+		INSTANCE = this;
+	}
+
+	/**
+	 * We are registered to receive only {@link SWT#FocusIn} events
+	 */
+	private Listener buildFocusListener() {
+		return new Listener() {
+			public void handleEvent(Event event) {
+				JptUiPlugin.this.focusIn((Control) event.widget);
+			}
+		};
+	}
+
+
+	// ********** focus handling **********
+
+	/**
+	 * This method is called whenever a "focus in" event is generated.
+	 * If the control gaining focus is part of one of our composites (typically
+	 * a JPA Details View), we stop listening to Java change events
+	 * (and assume all changes to the Java model are generated by us).
+	 * If the control gaining focus is *not* part of one of our composites,
+	 * we start listening to the Java change events again.
+	 */
+	void focusIn(Control control) {
+		while (control != null) {
+			if (control.getData(FOCUS_DATA_KEY) == FOCUS_DATA) {
+				this.focusIn();
+				return;
+			}
+			control = control.getParent();
+		}
+		this.focusOut();
+	}
+
+	/**
+	 * This method is called whenever a Dali UI control that affects Java
+	 * source code gains the UI focus. When this happens we deactivate
+	 * the Dali Java change listener so we ignore any changes to the Java
+	 * source code that probably originated from Dali. This means we will miss
+	 * any changes to the Java source code that is caused by non-UI activity;
+	 * but, we hope, these changes are unrelated to JPA annotations etc.
+	 * @see #focusOut()
+	 */
+	private void focusIn() {
+		JptCorePlugin.setJavaElementChangeListenerIsActive(false);
+	}
+
+	/**
+	 * This method is called whenever a non-Dali UI control gains the UI focus.
+	 * When this happens we activate the Dali Java change listener so that we
+	 * begin to keep the Dali model synchronized with the Java source code.
+	 * @see #focusIn()
+	 */
+	private void focusOut() {
+		JptCorePlugin.setJavaElementChangeListenerIsActive(true);
+	}
+
+	/**
+	 * Tag the specified control so that whenever it (or any of its children,
+	 * grandchildren, etc.) has the focus, the Dali model ignores any Java
+	 * change events. This method is to be called when the control is first
+	 * constructed.
+	 */
+	public void controlAffectsJavaSource(Control control) {
+		control.setData(FOCUS_DATA_KEY, FOCUS_DATA);
+	}
+
+
+	// ********** platform **********
+
+	/**
+	 * Return the JPA platform UI corresponding to the specified JPA platform.
+	 */
+	public JpaPlatformUi getJpaPlatformUi(JpaPlatform jpaPlatform) {
+		return JpaPlatformUiRegistry.instance().getJpaPlatformUi(jpaPlatform.getId());
+	}
+
+	public JpaNavigatorProvider getJpaNavigatorProvider(JpaPlatform jpaPlatform) {
+		JpaPlatformUi platform = this.getJpaPlatformUi(jpaPlatform);
+		return (platform == null) ? null : platform.getNavigatorProvider();
+	}
+
+
+	// ********** plug-in implementation **********
+
+	/**
+	 * Register our SWT listener with the display so we receive notification
+	 * of every "focus in" event.
+	 */
+	@Override
+	public void start(BundleContext context) throws Exception {
+		super.start(context);
+		Display.getDefault().addFilter(SWT.FocusIn, this.focusListener);
+	}
+
+	/**
+	 * Unregister our SWT listener with the display.
+	 */
+	@Override
+	public void stop(BundleContext context) throws Exception {
+		try {
+			Display.getDefault().removeFilter(SWT.FocusIn, this.focusListener);
+		} finally {
+			super.stop(context);
+		}
+	}
+
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/MappingResourceUiDefinition.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/MappingResourceUiDefinition.java
new file mode 100644
index 0000000..00e6a9d
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/MappingResourceUiDefinition.java
@@ -0,0 +1,72 @@
+/*******************************************************************************
+ * Copyright (c) 2009 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.ui;
+
+import java.util.Iterator;
+import org.eclipse.jpt.core.context.AttributeMapping;
+import org.eclipse.jpt.core.context.PersistentAttribute;
+import org.eclipse.jpt.core.context.PersistentType;
+import org.eclipse.jpt.core.context.TypeMapping;
+import org.eclipse.jpt.ui.details.DefaultMappingUiDefinition;
+import org.eclipse.jpt.ui.details.JpaComposite;
+import org.eclipse.jpt.ui.details.MappingUiDefinition;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ *
+ * 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.
+ */
+public interface MappingResourceUiDefinition extends ResourceUiDefinition
+{
+	/**
+	 * 
+	 */
+	JpaComposite buildAttributeMappingComposite(
+			String key, 
+			PropertyValueModel<AttributeMapping> mappingHolder, 
+			Composite parent, WidgetFactory widgetFactory);
+	
+	/**
+	 * Return an iterator of attribute mapping ui definitions appropriate for this file type
+	 */
+	Iterator<MappingUiDefinition<PersistentAttribute, ? extends AttributeMapping>> 
+			attributeMappingUiDefinitions();
+	
+	/**
+	 * Return a default attribute mapping ui definition for the given key or null
+	 */
+	DefaultMappingUiDefinition<PersistentAttribute, ? extends AttributeMapping> 
+			getDefaultAttributeMappingUiDefinition(String key);
+	
+	/**
+	 * 
+	 */
+	JpaComposite buildTypeMappingComposite(
+			String key, 
+			PropertyValueModel<TypeMapping> mappingHolder, 
+			Composite parent, WidgetFactory widgetFactory);
+	
+	/**
+	 * 
+	 */
+	Iterator<MappingUiDefinition<PersistentType, ? extends TypeMapping>> 
+			typeMappingUiDefinitions();
+	
+	/**
+	 * Return a default type mapping ui provider or null
+	 */
+	DefaultMappingUiDefinition<PersistentType, ? extends TypeMapping> 
+			getDefaultTypeMappingUiDefinition();
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/PersistenceXmlResourceUiDefinition.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/PersistenceXmlResourceUiDefinition.java
new file mode 100644
index 0000000..ae0070e
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/PersistenceXmlResourceUiDefinition.java
@@ -0,0 +1,33 @@
+/*******************************************************************************
+ * Copyright (c) 2009 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.ui;
+
+import java.util.ListIterator;
+import org.eclipse.jpt.core.context.persistence.PersistenceUnit;
+import org.eclipse.jpt.ui.details.JpaPageComposite;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ *
+ * 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.
+ */
+public interface PersistenceXmlResourceUiDefinition extends ResourceUiDefinition
+{
+	ListIterator<JpaPageComposite> buildPersistenceUnitComposites(
+		PropertyValueModel<PersistenceUnit> subjectHolder,
+		Composite parent,
+		WidgetFactory widgetFactory);
+
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/ResourceUiDefinition.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/ResourceUiDefinition.java
new file mode 100644
index 0000000..eee4213
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/ResourceUiDefinition.java
@@ -0,0 +1,34 @@
+/*******************************************************************************
+ * Copyright (c) 2009 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.ui;
+
+import org.eclipse.jpt.core.JpaResourceType;
+import org.eclipse.jpt.ui.structure.JpaStructureProvider;
+
+/**
+ *
+ * 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.
+ */
+public interface ResourceUiDefinition
+{
+	/**
+	 * Return whether this definition provides UI for resource of the given type
+	 */
+	boolean providesUi(JpaResourceType resourceType);
+	
+	/**
+	 * Return the structure provider association with this mapping file type.
+	 */
+	JpaStructureProvider getStructureProvider();
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/WidgetFactory.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/WidgetFactory.java
new file mode 100644
index 0000000..cfee242
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/WidgetFactory.java
@@ -0,0 +1,240 @@
+/*******************************************************************************
+ * Copyright (c) 2008 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.ui;
+
+import org.eclipse.swt.custom.CCombo;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.DateTime;
+import org.eclipse.swt.widgets.Group;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.List;
+import org.eclipse.swt.widgets.Spinner;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.ui.forms.widgets.FormText;
+import org.eclipse.ui.forms.widgets.Hyperlink;
+import org.eclipse.ui.forms.widgets.Section;
+
+/**
+ * A widget factory is responsible for creating an SWT widget based on the right
+ * style. Some style shows the widgets differently, for instance, the flat style
+ * shows the widgets with less borders.
+ * <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.
+ *
+ * @version 2.0
+ * @since 2.0
+ */
+public interface WidgetFactory {
+
+	/**
+	 * Creates a new regular button.
+	 *
+	 * @param parent The parent container
+	 * @param text The button's text
+	 * @return A new <code>Button</code>
+	 */
+	Button createButton(Composite parent, String text);
+
+	/**
+	 * Creates a new non-editable custom <code>Combo</code>.
+	 *
+	 * @deprecated
+	 * @param parent The parent container
+	 * @return A new <code>CCombo</code>
+	 */
+	@Deprecated
+	CCombo createCCombo(Composite parent);
+
+	/**
+	 * Creates a new check box button.
+	 *
+	 * @param parent The parent container
+	 * @param text The button's text
+	 * @return A new <code>Button</code>
+	 */
+	Button createCheckBox(Composite parent, String text);
+
+	/**
+	 * Creates a new non-editable <code>Combo</code>.
+	 *
+	 * @param parent The parent container
+	 * @return A new <code>Combo</code>
+	 */
+	Combo createCombo(Composite parent);
+
+	/**
+	 * Creates a new container.
+	 *
+	 * @param parent The parent container
+	 * @return A new <code>Composite</code>
+	 */
+	Composite createComposite(Composite parent);
+
+	/**
+	 * Creates a new DateTime.
+	 *
+	 * @param container The parent container
+	 * @param style The style is to tell the type of widget
+	 * (<code>SWT.DATE</code> or <code>SWT.TIME</code> or <code>SWT.CALENDAR</code>)
+	 * @return A new <code>DateTime</code>
+	 */
+	DateTime createDateTime(Composite parent, int style);
+	
+	/**
+	 * Creates a new editable custom <code>CCombo</code>.
+	 *
+	 * @deprecated
+	 * @param parent The parent container
+	 * @return A new <code>CCombo</code>
+	 */
+	@Deprecated
+	CCombo createEditableCCombo(Composite parent);
+
+	/**
+	 * Creates a new editable <code>Combo</code>.
+	 *
+	 * @param parent The parent container
+	 * @return A new <code>Combo</code>
+	 */
+	Combo createEditableCombo(Composite parent);
+
+	/**
+	 * Creates a new titled pane (group box).
+	 *
+	 * @param parent The parent container
+	 * @param title The group pane's title
+	 * @return A new <code>Group</code>
+	 */
+	Group createGroup(Composite parent, String title);
+
+	/**
+	 * Creates a new label that is shown as a hyperlink.
+	 *
+	 * @param parent The parent container
+	 * @param text The label's text
+	 * @return A new <code>Hyperlink</code>
+	 */
+	Hyperlink createHyperlink(Composite parent, String text);
+
+	/**
+	 * Creates a new label.
+	 *
+	 * @param container The parent container
+	 * @param labelText The label's text
+	 * @return A new <code>Label</code>
+	 */
+	Label createLabel(Composite container, String labelText);
+
+	/**
+	 * Creates a new list.
+	 *
+	 * @param container The parent container
+	 * @param style The style is usually to tell what type of selection
+	 * (<code>SWT.MULTI</code> or <code>SWT.SINGLE</code>)
+	 * @return A new <code>Label</code>
+	 */
+	List createList(Composite container, int style);
+
+	/**
+	 * Creates a new label that can be wrapped on multiple lines.
+	 *
+	 * @param container The parent container
+	 * @param labelText The label's text
+	 * @return A new <code>FormText</code>
+	 */
+	FormText createMultiLineLabel(Composite container, String labelText);
+
+	/**
+	 * Creates a new editable text area.
+	 *
+	 * @param parent The parent container
+	 * @param parent The number of lines the text area should display
+	 * @return A new <code>Text</code>
+	 */
+	Text createMultiLineText(Composite parent);
+
+	/**
+	 * Creates a new editable text field that handles password.
+	 *
+	 * @param container The parent container
+	 * @return A new <code>Text</code>
+	 */
+	Text createPasswordText(Composite container);
+
+	/**
+	 * Creates a new push button (toggle between selected and unselected).
+	 *
+	 * @param parent The parent container
+	 * @param text The button's text
+	 * @return A new <code>Button</code>
+	 */
+	Button createPushButton(Composite parent, String text);
+
+	/**
+	 * Creates a new radio button.
+	 *
+	 * @param parent The parent container
+	 * @param text The button's text
+	 * @return A new <code>Button</code>
+	 */
+	Button createRadioButton(Composite parent, String text);
+
+	/**
+	 * Creates a new section, which is a collapsable pane with a title bar.
+	 *
+	 * @param parent The parent container
+	 * @param style The style of the title bar, which can be
+	 * <code>ExpandableComposite.TWISTIE</code> and
+	 * <code>ExpandableComposite.TITLE_BAR</code>
+	 * @return A new <code>Section</code>
+	 */
+	Section createSection(Composite parent, int style);
+
+	/**
+	 * Creates a new spinner.
+	 *
+	 * @param parent The parent container
+	 * @return A new <code>Spinner</code>
+	 */
+	Spinner createSpinner(Composite parent);
+
+	/**
+	 * Creates a new table.
+	 *
+	 * @param container The parent container
+	 * @param style The style to apply to the table
+	 * @return A new <code>Table</code>
+	 */
+	Table createTable(Composite parent, int style);
+
+	/**
+	 * Creates a new editable text field.
+	 *
+	 * @param container The parent container
+	 * @return A new <code>Text</code>
+	 */
+	Text createText(Composite parent);
+
+	/**
+	 * Creates a new tri-state check box.
+	 *
+	 * @param parent The parent container
+	 * @param text The button's text
+	 * @return A new <code>Button</code> that has 3 selection states
+	 */
+	Button createTriStateCheckBox(Composite parent, String text);
+}
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/details/DefaultMappingUiDefinition.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/details/DefaultMappingUiDefinition.java
new file mode 100644
index 0000000..194b536
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/details/DefaultMappingUiDefinition.java
@@ -0,0 +1,28 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2009 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.ui.details;
+
+/**
+ * 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.
+ */
+public interface DefaultMappingUiDefinition<M, T>
+	extends MappingUiDefinition<M, T>
+{
+	/**
+	 * Returns a unique string that corresponds to the key of the mapping in the
+	 * core.  For a default mapping the method getKey() will return null since
+	 * that is for the specified mapping.  This will return the default mapping key, not null
+	 */
+	String getDefaultKey();
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/details/JpaComposite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/details/JpaComposite.java
new file mode 100644
index 0000000..207e785
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/details/JpaComposite.java
@@ -0,0 +1,45 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2009 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.ui.details;
+
+import org.eclipse.swt.widgets.Control;
+
+/**
+ * A {@link JpaComposite} defines the common behavior of the JPA related
+ * widgets.
+ *
+ * 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.
+ */
+public interface JpaComposite {
+
+	/**
+	 * Returns the actual <code>Composite</code>.
+	 *
+	 * @return This composite's actual widget
+	 */
+	Control getControl();
+
+	/**
+	 * Changes the enablement state of the widgets of this pane.
+	 *
+	 * @param enabled <code>true</code> to enable the widgets or <code>false</code>
+	 * to disable them
+	 */
+	void enableWidgets(boolean enabled);
+
+	/**
+	 * Notifies this composite it should dispose any resources.
+	 */
+	void dispose();
+}
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/details/JpaDetailsPage.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/details/JpaDetailsPage.java
new file mode 100644
index 0000000..51f8d77
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/details/JpaDetailsPage.java
@@ -0,0 +1,51 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2009 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.ui.details;
+
+import org.eclipse.jpt.core.JpaStructureNode;
+import org.eclipse.swt.widgets.Control;
+
+/**
+ * A details page is used to show the property pane for a given context node. The
+ * {@link JpaDetailsProvider} is responsible for creating the pane.
+ *
+ * @see JpaDetailsProvider
+ *
+ * @version 2.0
+ * @since 2.0
+ * 
+ * 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.
+ */
+public interface JpaDetailsPage<T extends JpaStructureNode>
+{
+	/**
+	 * Returns this details' page's widget.
+	 *
+	 * @return The container of the widgets shown by this details page
+	 */
+	Control getControl();
+
+	/**
+	 * Sets the subject for this details page.
+	 *
+	 * @param subject Either the new subject or <code>null</code> if the subject
+	 * needs to be removed
+	 */
+	void setSubject(T subject);
+	
+	/**
+	 * Dispose the details page and any resources it holds.
+	 */
+	void dispose();
+}
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/details/JpaDetailsProvider.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/details/JpaDetailsProvider.java
new file mode 100644
index 0000000..10bc880
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/details/JpaDetailsProvider.java
@@ -0,0 +1,50 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2009 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.ui.details;
+
+import org.eclipse.jpt.core.JpaStructureNode;
+import org.eclipse.jpt.ui.WidgetFactory;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * This provider is responsible to create the {@link JpaDetailsPage}
+ * responsible to show the information for a given content node id.
+ *
+ * @see JpaDetailsPage
+ *
+ * @version 3.0
+ * @since 2.0
+ *
+ * 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.
+ */
+public interface JpaDetailsProvider
+{
+	/**
+	 * Return whether this provider returns a details page for the given structure node
+	 */
+	boolean providesDetails(JpaStructureNode structureNode);
+	
+	/**
+	 * Creates a new details page based on the given content node id.
+	 *
+	 * @param parent The parent container
+	 * @param contentNodeId The unique identifier used to determine which details
+	 * page to create
+	 * @param widgetFactory The factory used to create various widgets
+	 */
+	//TODO Should we pass in JpaUiFactory so these pages can be built using the factory and overriden?
+	JpaDetailsPage<? extends JpaStructureNode> buildDetailsPage(
+			Composite parent,
+			WidgetFactory widgetFactory);
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/details/JpaPageComposite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/details/JpaPageComposite.java
new file mode 100644
index 0000000..3bcb12d
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/details/JpaPageComposite.java
@@ -0,0 +1,47 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2010 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.ui.details;
+
+import org.eclipse.jface.resource.ImageDescriptor;
+
+/**
+ * A {@link JpaPageComposite} defines the common behavior of the JPA
+ * related widgets that is shown as a page within an editor.
+ * <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.
+ */
+public interface JpaPageComposite extends JpaComposite {
+
+	/**
+	 * Returns the help ID. This ID will be used if the help button is invoked.
+	 *
+	 * @return Either the help ID of this page or <code>null</code> if no help
+	 * is required
+	 */
+	String getHelpID();
+
+	/**
+	 * The image of the tab showing this page.
+	 *
+	 * @return The page's image
+	 */
+	ImageDescriptor getPageImageDescriptor();
+
+	/**
+	 * The text of the tab showing this page.
+	 *
+	 * @return The page's text
+	 */
+	String getPageText();
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/details/MappingUiDefinition.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/details/MappingUiDefinition.java
new file mode 100644
index 0000000..011b797
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/details/MappingUiDefinition.java
@@ -0,0 +1,65 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2010 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.ui.details;
+
+import org.eclipse.swt.graphics.Image;
+
+/**
+ * A UI provider is responsible to provide the support for displaying the
+ * information for a certain mapping type.
+ * 
+ * T represents the type of the mapping the definition represents
+ * M represents the type of the object being mapped
+ *
+ * @version 2.3
+ * @since 2.0
+ * 
+ * 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.
+ */
+public interface MappingUiDefinition<M, T>
+{
+	/**
+	 * Returns a unique string that corresponds to the key of the mapping in the
+	 * core (JavaAttributeMappingDefinition and/or OrmAttributeMappingProvider).
+	 *
+	 * @return The key representing the mapping
+	 */
+	String getKey();
+	
+	/**
+	 * Returns a human readable text of the mapping type.
+	 *
+	 * @return A display string for the mapping type
+	 */
+	String getLabel();
+
+	/**
+	 * Returns a human readable text of the mapping type to be used in the mapping change link label
+	 */
+	String getLinkLabel();
+	
+	/**
+	 * Returns an image that represents the mapping type defined by this provider.
+	 *
+	 * @return An image representing a mapping or <code>null</code> if no image
+	 * is required
+	 */
+	Image getImage();
+	
+	/**
+	 * Return whether the mapping type represented by this definition is enabled for the given
+	 * mappable object.  This is almost always true.
+	 */
+	boolean isEnabledFor(M mappableObject);
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/details/java/DefaultJavaAttributeMappingUiDefinition.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/details/java/DefaultJavaAttributeMappingUiDefinition.java
new file mode 100644
index 0000000..0380105
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/details/java/DefaultJavaAttributeMappingUiDefinition.java
@@ -0,0 +1,27 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2009 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.ui.details.java;
+
+import org.eclipse.jpt.core.context.AttributeMapping;
+import org.eclipse.jpt.core.context.PersistentAttribute;
+import org.eclipse.jpt.ui.details.DefaultMappingUiDefinition;
+
+/**
+ * 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.
+ */
+public interface DefaultJavaAttributeMappingUiDefinition<T extends AttributeMapping> 
+	extends JavaAttributeMappingUiDefinition<T>, DefaultMappingUiDefinition<PersistentAttribute, T>
+{
+	
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/details/java/DefaultJavaTypeMappingUiDefinition.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/details/java/DefaultJavaTypeMappingUiDefinition.java
new file mode 100644
index 0000000..d74ffde
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/details/java/DefaultJavaTypeMappingUiDefinition.java
@@ -0,0 +1,27 @@
+/*******************************************************************************
+ * Copyright (c) 2009 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.ui.details.java;
+
+import org.eclipse.jpt.core.context.PersistentType;
+import org.eclipse.jpt.core.context.TypeMapping;
+import org.eclipse.jpt.ui.details.DefaultMappingUiDefinition;
+
+/**
+ * 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.
+ */
+public interface DefaultJavaTypeMappingUiDefinition<T extends TypeMapping>
+	extends JavaTypeMappingUiDefinition<T>, DefaultMappingUiDefinition<PersistentType, T>
+{
+	
+}
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/details/java/JavaAttributeMappingUiDefinition.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/details/java/JavaAttributeMappingUiDefinition.java
new file mode 100644
index 0000000..d518be9
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/details/java/JavaAttributeMappingUiDefinition.java
@@ -0,0 +1,48 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2009 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.ui.details.java;
+
+import org.eclipse.jpt.core.context.AttributeMapping;
+import org.eclipse.jpt.core.context.PersistentAttribute;
+import org.eclipse.jpt.ui.WidgetFactory;
+import org.eclipse.jpt.ui.details.JpaComposite;
+import org.eclipse.jpt.ui.details.MappingUiDefinition;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * 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.
+ */
+public interface JavaAttributeMappingUiDefinition<T extends AttributeMapping>
+	extends MappingUiDefinition<PersistentAttribute, T>
+{
+	/**
+	 * Creates <code>JpaComposite</code> that corresponds to this mapping type.
+	 * This will be displayed by the <code>PersistentAttributeDetailsPage</code>
+	 * when the mapping key matches the key given by this provider. The
+	 * composites will be stored in a Map with the mapping key as the key.
+	 *
+	 * @param factory The UI factory responsible to create the right composite
+	 * for any mapping type
+	 * @param subjectHolder The holder of the subject being displayed
+	 * @param parent The parent container
+	 * @param widgetFactory The factory used to create the various widgets
+	 * @return The composite displaying the information for a certain mapping
+	 */
+	JpaComposite buildAttributeMappingComposite(
+			JavaUiFactory factory,
+			PropertyValueModel<T> subjectHolder,
+			Composite parent,
+			WidgetFactory widgetFactory);
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/details/java/JavaTypeMappingUiDefinition.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/details/java/JavaTypeMappingUiDefinition.java
new file mode 100644
index 0000000..a5754e0
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/details/java/JavaTypeMappingUiDefinition.java
@@ -0,0 +1,48 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2009 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.ui.details.java;
+
+import org.eclipse.jpt.core.context.PersistentType;
+import org.eclipse.jpt.core.context.TypeMapping;
+import org.eclipse.jpt.ui.WidgetFactory;
+import org.eclipse.jpt.ui.details.JpaComposite;
+import org.eclipse.jpt.ui.details.MappingUiDefinition;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * 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.
+ */
+public interface JavaTypeMappingUiDefinition<T extends TypeMapping>
+	extends MappingUiDefinition<PersistentType, T>
+{
+	/**
+	 * Creates <code>JpaComposite</code> that corresponds to this mapping type.
+	 * This will be displayed by the <code>PersistentTypeDetailsPage</code> when
+	 * the mapping key matches the key given by this provider. The composites
+	 * will be stored in a Map with the mapping key as the key.
+	 *
+	 * @param factory The UI factory responsible to create the right composite
+	 * for any mapping type
+	 * @param subjectHolder The holder of the subject being displayed
+	 * @param parent The parent container
+	 * @param widgetFactory The factory used to create the various widgets
+	 * @return The composite displaying the information for a certain mapping
+	 */
+	JpaComposite buildTypeMappingComposite(
+			JavaUiFactory factory,
+			PropertyValueModel<T> subjectHolder,
+			Composite parent,
+			WidgetFactory widgetFactory);
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/details/java/JavaUiFactory.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/details/java/JavaUiFactory.java
new file mode 100644
index 0000000..18f9bda
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/details/java/JavaUiFactory.java
@@ -0,0 +1,265 @@
+/*******************************************************************************
+ * Copyright (c) 2009 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.ui.details.java;
+
+import org.eclipse.jpt.core.context.java.JavaBasicMapping;
+import org.eclipse.jpt.core.context.java.JavaEmbeddable;
+import org.eclipse.jpt.core.context.java.JavaEmbeddedIdMapping;
+import org.eclipse.jpt.core.context.java.JavaEmbeddedMapping;
+import org.eclipse.jpt.core.context.java.JavaEntity;
+import org.eclipse.jpt.core.context.java.JavaIdMapping;
+import org.eclipse.jpt.core.context.java.JavaManyToManyMapping;
+import org.eclipse.jpt.core.context.java.JavaManyToOneMapping;
+import org.eclipse.jpt.core.context.java.JavaMappedSuperclass;
+import org.eclipse.jpt.core.context.java.JavaOneToManyMapping;
+import org.eclipse.jpt.core.context.java.JavaOneToOneMapping;
+import org.eclipse.jpt.core.context.java.JavaTransientMapping;
+import org.eclipse.jpt.core.context.java.JavaVersionMapping;
+import org.eclipse.jpt.core.context.orm.OrmEmbeddable;
+import org.eclipse.jpt.core.context.orm.OrmEntity;
+import org.eclipse.jpt.core.context.orm.OrmMappedSuperclass;
+import org.eclipse.jpt.ui.WidgetFactory;
+import org.eclipse.jpt.ui.details.JpaComposite;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * Use {@link JavaUiFactory} to create any java JPA composites
+ * <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.
+ *
+ *
+ * @version 3.0
+ * @since 3.0
+ */
+public interface JavaUiFactory
+{	
+	
+	// **************** java type mapping composites ***************************
+	
+	/**
+	 * Creates a new <code>JpaComposite</code> used to edit a <code>JavaMappedSuperclass</code>.
+	 *
+	 * @param subjectHolder The holder of the mapped superclass
+	 * @param parent The parent container
+	 * @param widgetFactory The factory used to create the widgets
+	 * @return A new <code>JpaComposite</code>
+	 */
+	JpaComposite createJavaMappedSuperclassComposite(
+		PropertyValueModel<JavaMappedSuperclass> subjectHolder,
+		Composite parent,
+		WidgetFactory widgetFactory);
+	
+	/**
+	 * Creates a new <code>JpaComposite</code> used to edit an <code>JavaEntity</code>.
+	 *
+	 * @param subjectHolder The holder of the java entity
+	 * @param parent The parent container
+	 * @param widgetFactory The factory used to create the widgets
+	 * @return A new <code>JpaComposite</code>
+	 */
+	JpaComposite createJavaEntityComposite(
+		PropertyValueModel<JavaEntity> subjectHolder,
+		Composite parent,
+		WidgetFactory widgetFactory);
+	
+	/**
+	 * Creates a new <code>JpaComposite</code> used to edit a <code>JavaEmbeddable</code>.
+	 *
+	 * @param subjectHolder The holder of the embeddable
+	 * @param parent The parent container
+	 * @param widgetFactory The factory used to create the widgets
+	 * @return A new <code>JpaComposite</code>
+	 */
+	JpaComposite createJavaEmbeddableComposite(
+		PropertyValueModel<JavaEmbeddable> subjectHolder,
+		Composite parent,
+		WidgetFactory widgetFactory);
+	
+	
+	// **************** orm type mapping composites ****************************
+	
+	/**
+	 * Creates a new <code>JpaComposite</code> used to edit an <code>OrmMappedSuperclass</code>.
+	 *
+	 * @param subjectHolder The holder of the mapped superclass
+	 * @param parent The parent container
+	 * @param widgetFactory The factory used to create the widgets
+	 * @return A new <code>JpaComposite</code>
+	 */
+	JpaComposite createOrmMappedSuperclassComposite(
+		PropertyValueModel<OrmMappedSuperclass> subjectHolder,
+		Composite parent,
+		WidgetFactory widgetFactory);
+	
+	/**
+	 * Creates a new <code>JpaComposite</code> used to edit an <code>OrmEntity</code>.
+	 *
+	 * @param subjectHolder The holder of the orm entity
+	 * @param parent The parent container
+	 * @param widgetFactory The factory used to create the widgets
+	 * @return A new <code>JpaComposite</code>
+	 */
+	JpaComposite createOrmEntityComposite(
+		PropertyValueModel<OrmEntity> subjectHolder,
+		Composite parent,
+		WidgetFactory widgetFactory);
+
+	/**
+	 * Creates a new <code>JpaComposite</code> used to edit an <code>OrmEmbeddable</code>.
+	 *
+	 * @param subjectHolder The holder of the embeddable
+	 * @param parent The parent container
+	 * @param widgetFactory The factory used to create the widgets
+	 * @return A new <code>JpaComposite</code>
+	 */
+	JpaComposite createOrmEmbeddableComposite(
+		PropertyValueModel<OrmEmbeddable> subjectHolder,
+		Composite parent,
+		WidgetFactory widgetFactory);
+	
+	
+	// **************** java attribute mapping composites **********************
+	
+	/**
+	 * Creates a new <code>JpaComposite</code> used to edit a <code>JavaIdMapping</code>.
+	 *
+	 * @param subjectHolder The holder of the ID mapping
+	 * @param parent The parent container
+	 * @param widgetFactory The factory used to create the widgets
+	 * @return A new <code>JpaComposite</code>
+	 */
+	JpaComposite createJavaIdMappingComposite(
+		PropertyValueModel<JavaIdMapping> subjectHolder,
+		Composite parent,
+		WidgetFactory widgetFactory);
+	
+	/**
+	 * Creates a new <code>JpaComposite</code> used to edit a <code>JavaEmbeddedIdMapping</code>.
+	 *
+	 * @param subjectHolder The holder of the embedded ID mapping
+	 * @param parent The parent container
+	 * @param widgetFactory The factory used to create the widgets
+	 * @return A new <code>JpaComposite</code>
+	 */
+	JpaComposite createJavaEmbeddedIdMappingComposite(
+		PropertyValueModel<JavaEmbeddedIdMapping> subjectHolder,
+		Composite parent,
+		WidgetFactory widgetFactory);
+	
+	/**
+	 * Creates a new <code>JpaComposite</code> used to edit a <code>JavaBasicMapping</code>.
+	 *
+	 * @param subjectHolder The holder of the basic mapping
+	 * @param parent The parent container
+	 * @param widgetFactory The factory used to create the widgets
+	 * @return A new <code>JpaComposite</code>
+	 */
+	JpaComposite createJavaBasicMappingComposite(
+		PropertyValueModel<JavaBasicMapping> subjectHolder,
+		Composite parent,
+		WidgetFactory widgetFactory);
+	
+	/**
+	 * Creates a new <code>JpaComposite</code> used to edit a <code>JavaVersionMapping</code>.
+	 *
+	 * @param subjectHolder The holder of the version mapping
+	 * @param parent The parent container
+	 * @param widgetFactory The factory used to create the widgets
+	 * @return A new <code>JpaComposite</code>
+	 */
+	JpaComposite createJavaVersionMappingComposite(
+		PropertyValueModel<JavaVersionMapping> subjectHolder,
+		Composite parent,
+		WidgetFactory widgetFactory);
+	
+	/**
+	 * Creates a new <code>JpaComposite</code> used to edit a <code>JavaManyToOneMapping</code>.
+	 *
+	 * @param subjectHolder The holder of the many to one mapping
+	 * @param parent The parent container
+	 * @param widgetFactory The factory used to create the widgets
+	 * @return A new <code>JpaComposite</code>
+	 */
+	JpaComposite createJavaManyToOneMappingComposite(
+		PropertyValueModel<JavaManyToOneMapping> subjectHolder,
+		Composite parent,
+		WidgetFactory widgetFactory);
+	
+	/**
+	 * Creates a new <code>JpaComposite</code> used to edit a <code>JavaOneToManyMapping</code>.
+	 *
+	 * @param subjectHolder The holder of the one to many mapping
+	 * @param parent The parent container
+	 * @param widgetFactory The factory used to create the widgets
+	 * @return A new <code>JpaComposite</code>
+	 */
+	JpaComposite createJavaOneToManyMappingComposite(
+		PropertyValueModel<JavaOneToManyMapping> subjectHolder,
+		Composite parent,
+		WidgetFactory widgetFactory);
+	
+	/**
+	 * Creates a new <code>JpaComposite</code> used to edit a <code>JavaOneToOneMapping</code>.
+	 *
+	 * @param subjectHolder The holder of the one to one mapping
+	 * @param parent The parent container
+	 * @param widgetFactory The factory used to create the widgets
+	 * @return A new <code>JpaComposite</code>
+	 */
+	JpaComposite createJavaOneToOneMappingComposite(
+		PropertyValueModel<JavaOneToOneMapping> subjectHolder,
+		Composite parent,
+		WidgetFactory widgetFactory);
+	
+	/**
+	 * Creates a new <code>JpaComposite</code> used to edit a <code>JavaManyToManyMapping</code>.
+	 *
+	 * @param subjectHolder The holder of the many to many mapping
+	 * @param parent The parent container
+	 * @param widgetFactory The factory used to create the widgets
+	 * @return A new <code>JpaComposite</code>
+	 */
+	JpaComposite createJavaManyToManyMappingComposite(
+		PropertyValueModel<JavaManyToManyMapping> subjectHolder,
+		Composite parent,
+		WidgetFactory widgetFactory);
+	
+	/**
+	 * Creates a new <code>JpaComposite</code> used to edit a <code>JavaEmbeddedMapping</code>.
+	 *
+	 * @param subjectHolder The holder of the embedded mapping
+	 * @param parent The parent container
+	 * @param widgetFactory The factory used to create the widgets
+	 * @return A new <code>JpaComposite</code>
+	 */
+	JpaComposite createJavaEmbeddedMappingComposite(
+		PropertyValueModel<JavaEmbeddedMapping> subjectHolder,
+		Composite parent,
+		WidgetFactory widgetFactory);
+	
+	/**
+	 * Creates a new <code>JpaComposite</code> used to edit a <code>JavaTransientMapping</code>.
+	 *
+	 * @param subjectHolder The holder of the transient mapping
+	 * @param parent The parent container
+	 * @param widgetFactory The factory used to create the widgets
+	 * @return A new <code>JpaComposite</code>
+	 */
+	JpaComposite createJavaTransientMappingComposite(
+		PropertyValueModel<JavaTransientMapping> subjectHolder,
+		Composite parent,
+		WidgetFactory widgetFactory);
+	
+}
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/details/orm/OrmAttributeMappingUiDefinition.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/details/orm/OrmAttributeMappingUiDefinition.java
new file mode 100644
index 0000000..897fde2
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/details/orm/OrmAttributeMappingUiDefinition.java
@@ -0,0 +1,48 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2009 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.ui.details.orm;
+
+import org.eclipse.jpt.core.context.AttributeMapping;
+import org.eclipse.jpt.core.context.PersistentAttribute;
+import org.eclipse.jpt.ui.WidgetFactory;
+import org.eclipse.jpt.ui.details.JpaComposite;
+import org.eclipse.jpt.ui.details.MappingUiDefinition;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * 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.
+ */
+public interface OrmAttributeMappingUiDefinition<T extends AttributeMapping>
+	extends MappingUiDefinition<PersistentAttribute, T>
+{
+	/**
+	 * Creates <code>JpaComposite</code> that corresponds to this mapping type.
+	 * This will be displayed by the <code>PersistentAttributeDetailsPage</code>
+	 * when the mapping key matches the key given by this provider. The
+	 * composites will be stored in a Map with the mapping key as the key.
+	 *
+	 * @param factory The UI factory responsible to create the right composite
+	 * for any mapping type
+	 * @param subjectHolder The holder of the subject being displayed
+	 * @param parent The parent container
+	 * @param widgetFactory The factory used to create the various widgets
+	 * @return The composite displaying the information for a certain mapping
+	 */
+	JpaComposite buildAttributeMappingComposite(
+			OrmXmlUiFactory factory,
+			PropertyValueModel<T> subjectHolder,
+			Composite parent,
+			WidgetFactory widgetFactory);
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/details/orm/OrmTypeMappingUiDefinition.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/details/orm/OrmTypeMappingUiDefinition.java
new file mode 100644
index 0000000..b449a77
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/details/orm/OrmTypeMappingUiDefinition.java
@@ -0,0 +1,48 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2009 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.ui.details.orm;
+
+import org.eclipse.jpt.core.context.PersistentType;
+import org.eclipse.jpt.core.context.TypeMapping;
+import org.eclipse.jpt.ui.WidgetFactory;
+import org.eclipse.jpt.ui.details.JpaComposite;
+import org.eclipse.jpt.ui.details.MappingUiDefinition;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * 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.
+ */
+public interface OrmTypeMappingUiDefinition<T extends TypeMapping>
+	extends MappingUiDefinition<PersistentType, T>
+{
+	/**
+	 * Creates <code>JpaComposite</code> that correponds to this mapping type.
+	 * This will be displayed by the <code>PersistentTypeDetailsPage</code> when
+	 * the mapping key matches the key given by this provider. The composites
+	 * will be stored in a Map with the mapping key as the key.
+	 *
+	 * @param factory The UI factory responsible to create the right composite
+	 * for any mapping type
+	 * @param subjectHolder The holder of the subject being displayed
+	 * @param parent The parent container
+	 * @param widgetFactory The factory used to create the various widgets
+	 * @return The composite displaying the information for a certain mapping
+	 */
+	JpaComposite buildTypeMappingComposite(
+			OrmXmlUiFactory factory,
+			PropertyValueModel<T> subjectHolder,
+			Composite parent,
+			WidgetFactory widgetFactory);
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/details/orm/OrmXmlUiFactory.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/details/orm/OrmXmlUiFactory.java
new file mode 100644
index 0000000..beeb7c6
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/details/orm/OrmXmlUiFactory.java
@@ -0,0 +1,220 @@
+/*******************************************************************************
+ * Copyright (c) 2009 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.ui.details.orm;
+
+import org.eclipse.jpt.core.context.orm.OrmBasicMapping;
+import org.eclipse.jpt.core.context.orm.OrmEmbeddable;
+import org.eclipse.jpt.core.context.orm.OrmEmbeddedIdMapping;
+import org.eclipse.jpt.core.context.orm.OrmEmbeddedMapping;
+import org.eclipse.jpt.core.context.orm.OrmEntity;
+import org.eclipse.jpt.core.context.orm.OrmIdMapping;
+import org.eclipse.jpt.core.context.orm.OrmManyToManyMapping;
+import org.eclipse.jpt.core.context.orm.OrmManyToOneMapping;
+import org.eclipse.jpt.core.context.orm.OrmMappedSuperclass;
+import org.eclipse.jpt.core.context.orm.OrmOneToManyMapping;
+import org.eclipse.jpt.core.context.orm.OrmOneToOneMapping;
+import org.eclipse.jpt.core.context.orm.OrmTransientMapping;
+import org.eclipse.jpt.core.context.orm.OrmVersionMapping;
+import org.eclipse.jpt.ui.WidgetFactory;
+import org.eclipse.jpt.ui.details.JpaComposite;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * Use {@link OrmXmlUiFactory} to create any ORM JPA composites
+ * <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.
+ *
+ * @see org.eclipse.jpt.ui.internal.BaseJpaUiFactory
+ *
+ * @version 2.0
+ * @since 1.0
+ */
+public interface OrmXmlUiFactory
+{
+	
+	// **************** orm type mapping composites ****************************
+	
+	/**
+	 * Creates a new <code>JpaComposite</code> used to edit an <code>OrmMappedSuperclass</code>.
+	 *
+	 * @param subjectHolder The holder of the mapped superclass
+	 * @param parent The parent container
+	 * @param widgetFactory The factory used to create the widgets
+	 * @return A new <code>JpaComposite</code>
+	 */
+	JpaComposite createOrmMappedSuperclassComposite(
+		PropertyValueModel<OrmMappedSuperclass> subjectHolder,
+		Composite parent,
+		WidgetFactory widgetFactory);
+	
+	/**
+	 * Creates a new <code>JpaComposite</code> used to edit an <code>OrmEntity</code>.
+	 *
+	 * @param subjectHolder The holder of the orm entity
+	 * @param parent The parent container
+	 * @param widgetFactory The factory used to create the widgets
+	 * @return A new <code>JpaComposite</code>
+	 */
+	JpaComposite createOrmEntityComposite(
+		PropertyValueModel<OrmEntity> subjectHolder,
+		Composite parent,
+		WidgetFactory widgetFactory);
+
+	/**
+	 * Creates a new <code>JpaComposite</code> used to edit an <code>OrmEmbeddable</code>.
+	 *
+	 * @param subjectHolder The holder of the embeddable
+	 * @param parent The parent container
+	 * @param widgetFactory The factory used to create the widgets
+	 * @return A new <code>JpaComposite</code>
+	 */
+	JpaComposite createOrmEmbeddableComposite(
+		PropertyValueModel<OrmEmbeddable> subjectHolder,
+		Composite parent,
+		WidgetFactory widgetFactory);
+	
+
+	// **************** orm attribute mapping composites ***********************
+	
+	/**
+	 * Creates a new <code>JpaComposite</code> used to edit an <code>OrmIdMapping</code>.
+	 *
+	 * @param subjectHolder The holder of the ID mapping
+	 * @param parent The parent container
+	 * @param widgetFactory The factory used to create the widgets
+	 * @return A new <code>JpaComposite</code>
+	 */
+	JpaComposite createOrmIdMappingComposite(
+		PropertyValueModel<OrmIdMapping> subjectHolder,
+		Composite parent,
+		WidgetFactory widgetFactory);
+	
+	/**
+	 * Creates a new <code>JpaComposite</code> used to edit an <code>OrmEmbeddedIdMapping</code>.
+	 *
+	 * @param subjectHolder The holder of the embedded ID mapping
+	 * @param parent The parent container
+	 * @param widgetFactory The factory used to create the widgets
+	 * @return A new <code>JpaComposite</code>
+	 */
+	JpaComposite createOrmEmbeddedIdMappingComposite(
+		PropertyValueModel<OrmEmbeddedIdMapping> subjectHolder,
+		Composite parent,
+		WidgetFactory widgetFactory);
+	
+	/**
+	 * Creates a new <code>JpaComposite</code> used to edit an <code>OrmBasicMapping</code>.
+	 *
+	 * @param subjectHolder The holder of the basic mapping
+	 * @param parent The parent container
+	 * @param widgetFactory The factory used to create the widgets
+	 * @return A new <code>JpaComposite</code>
+	 */
+	JpaComposite createOrmBasicMappingComposite(
+		PropertyValueModel<OrmBasicMapping> subjectHolder,
+		Composite parent,
+		WidgetFactory widgetFactory);
+	
+	/**
+	 * Creates a new <code>JpaComposite</code> used to edit an <code>OrmVersionMapping</code>.
+	 *
+	 * @param subjectHolder The holder of the version mapping
+	 * @param parent The parent container
+	 * @param widgetFactory The factory used to create the widgets
+	 * @return A new <code>JpaComposite</code>
+	 */
+	JpaComposite createOrmVersionMappingComposite(
+		PropertyValueModel<OrmVersionMapping> subjectHolder,
+		Composite parent,
+		WidgetFactory widgetFactory);
+	
+	/**
+	 * Creates a new <code>JpaComposite</code> used to edit an <code>OrmManyToOneMapping</code>.
+	 *
+	 * @param subjectHolder The holder of the many to one mapping
+	 * @param parent The parent container
+	 * @param widgetFactory The factory used to create the widgets
+	 * @return A new <code>JpaComposite</code>
+	 */
+	JpaComposite createOrmManyToOneMappingComposite(
+		PropertyValueModel<OrmManyToOneMapping> subjectHolder,
+		Composite parent,
+		WidgetFactory widgetFactory);
+	
+	/**
+	 * Creates a new <code>JpaComposite</code> used to edit an <code>OrmOneToManyMapping</code>.
+	 *
+	 * @param subjectHolder The holder of the one to many mapping
+	 * @param parent The parent container
+	 * @param widgetFactory The factory used to create the widgets
+	 * @return A new <code>JpaComposite</code>
+	 */
+	JpaComposite createOrmOneToManyMappingComposite(
+		PropertyValueModel<OrmOneToManyMapping> subjectHolder,
+		Composite parent,
+		WidgetFactory widgetFactory);
+	
+	/**
+	 * Creates a new <code>JpaComposite</code> used to edit an <code>OrmOneToOneMapping</code>.
+	 *
+	 * @param subjectHolder The holder of the one to one mapping
+	 * @param parent The parent container
+	 * @param widgetFactory The factory used to create the widgets
+	 * @return A new <code>JpaComposite</code>
+	 */
+	JpaComposite createOrmOneToOneMappingComposite(
+		PropertyValueModel<OrmOneToOneMapping> subjectHolder,
+		Composite parent,
+		WidgetFactory widgetFactory);
+	
+	/**
+	 * Creates a new <code>JpaComposite</code> used to edit an <code>OrmManyToManyMapping</code>.
+	 *
+	 * @param subjectHolder The holder of the many to many mapping
+	 * @param parent The parent container
+	 * @param widgetFactory The factory used to create the widgets
+	 * @return A new <code>JpaComposite</code>
+	 */
+	JpaComposite createOrmManyToManyMappingComposite(
+		PropertyValueModel<OrmManyToManyMapping> subjectHolder,
+		Composite parent,
+		WidgetFactory widgetFactory);
+		
+	/**
+	 * Creates a new <code>JpaComposite</code> used to edit an <code>OrmEmbeddedMapping</code>.
+	 *
+	 * @param subjectHolder The holder of the embedded mapping
+	 * @param parent The parent container
+	 * @param widgetFactory The factory used to create the widgets
+	 * @return A new <code>JpaComposite</code>
+	 */
+	JpaComposite createOrmEmbeddedMappingComposite(
+		PropertyValueModel<OrmEmbeddedMapping> subjectHolder,
+		Composite parent,
+		WidgetFactory widgetFactory);
+	
+	/**
+	 * Creates a new <code>JpaComposite</code> used to edit an <code>OrmTransientMapping</code>.
+	 *
+	 * @param subjectHolder The holder of the transient mapping
+	 * @param parent The parent container
+	 * @param widgetFactory The factory used to create the widgets
+	 * @return A new <code>JpaComposite</code>
+	 */
+	JpaComposite createOrmTransientMappingComposite(
+		PropertyValueModel<OrmTransientMapping> subjectHolder,
+		Composite parent,
+		WidgetFactory widgetFactory);
+}
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/AbstractJpaPlatformUiProvider.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/AbstractJpaPlatformUiProvider.java
new file mode 100644
index 0000000..d2a1f93
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/AbstractJpaPlatformUiProvider.java
@@ -0,0 +1,88 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2009 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.ui.internal;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.ListIterator;
+import org.eclipse.jpt.ui.JpaPlatformUiProvider;
+import org.eclipse.jpt.ui.ResourceUiDefinition;
+import org.eclipse.jpt.ui.details.JpaDetailsProvider;
+import org.eclipse.jpt.utility.internal.iterators.ArrayListIterator;
+
+/**
+ * All the state in the JPA platform ui provider should be "static" (i.e. unchanging once
+ * it is initialized).
+ */
+public abstract class AbstractJpaPlatformUiProvider implements JpaPlatformUiProvider
+{
+	private JpaDetailsProvider[] detailsProviders;
+
+	private ResourceUiDefinition[] resourceUiDefinitions;
+	
+	/**
+	 * zero-argument constructor
+	 */
+	public AbstractJpaPlatformUiProvider() {
+		super();
+	}
+
+
+	// ********** details providers **********
+
+	public ListIterator<JpaDetailsProvider> detailsProviders() {
+		return new ArrayListIterator<JpaDetailsProvider>(getDetailsProviders());
+	}
+	
+	protected synchronized JpaDetailsProvider[] getDetailsProviders() {
+		if (this.detailsProviders == null) {
+			this.detailsProviders = this.buildDetailsProviders();
+		}
+		return this.detailsProviders;
+	}
+
+	protected JpaDetailsProvider[] buildDetailsProviders() {
+		ArrayList<JpaDetailsProvider> providers = new ArrayList<JpaDetailsProvider>();
+		this.addDetailsProvidersTo(providers);
+		return providers.toArray(new JpaDetailsProvider[providers.size()]);
+	}
+
+	/**
+	 * Implement this to specify JPA details providers.
+	 */
+	protected abstract void addDetailsProvidersTo(List<JpaDetailsProvider> providers);
+	
+	
+	
+	// ********** structure providers **********
+
+	public ListIterator<ResourceUiDefinition> resourceUiDefinitions() {
+		return new ArrayListIterator<ResourceUiDefinition>(getResourceUiDefinitions());
+	}
+	
+	protected synchronized ResourceUiDefinition[] getResourceUiDefinitions() {
+		if (this.resourceUiDefinitions == null) {
+			this.resourceUiDefinitions = this.buildResourceUiDefinitions();
+		}
+		return this.resourceUiDefinitions;
+	}
+
+	protected ResourceUiDefinition[] buildResourceUiDefinitions() {
+		ArrayList<ResourceUiDefinition> definitions = new ArrayList<ResourceUiDefinition>();
+		this.addResourceUiDefinitionsTo(definitions);
+		return definitions.toArray(new ResourceUiDefinition[definitions.size()]);
+	}
+
+	/**
+	 * Implement this to specify JPA mapping file ui definitions.
+	 */
+	protected abstract void addResourceUiDefinitionsTo(List<ResourceUiDefinition> definitions);
+	
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/EditorPartAdapterFactory.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/EditorPartAdapterFactory.java
new file mode 100644
index 0000000..9476858
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/EditorPartAdapterFactory.java
@@ -0,0 +1,65 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2009 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.ui.internal;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.runtime.IAdapterFactory;
+import org.eclipse.jpt.core.JpaFile;
+import org.eclipse.jpt.core.JptCorePlugin;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IFileEditorInput;
+
+/**
+ * Factory to build adapters for a editor part:
+ *   - JPA file (if the editor part is a file editor etc.)
+ * 
+ * See org.eclipse.jpt.ui plugin.xml.
+ */
+public class EditorPartAdapterFactory
+	implements IAdapterFactory
+{
+	private static final Class<?>[] ADAPTER_LIST = new Class[] { JpaFile.class };
+
+	public Class<?>[] getAdapterList() {
+		return ADAPTER_LIST;
+	}
+
+	public Object getAdapter(Object adaptableObject, @SuppressWarnings("unchecked") Class adapterType) {
+		if (adaptableObject instanceof IEditorPart) {
+			return this.getAdapter((IEditorPart) adaptableObject, adapterType);
+		}
+		return null;
+	}
+
+	private Object getAdapter(IEditorPart editorPart, Class<?> adapterType) {
+		if (adapterType == JpaFile.class) {
+			return this.getJpaFile(editorPart);
+		}
+		return null;
+	}
+
+	private JpaFile getJpaFile(IEditorPart editorPart) {
+		IEditorInput editorInput = editorPart.getEditorInput();
+		if (editorInput instanceof IFileEditorInput) {
+			return this.getJpaFile((IFileEditorInput) editorInput);
+		}
+		return null;
+	}
+
+	private JpaFile getJpaFile(IFileEditorInput fileEditorInput) {
+		return this.getJpaFile(fileEditorInput.getFile());
+	}
+
+	private JpaFile getJpaFile(IFile file) {
+		return JptCorePlugin.getJpaFile(file);
+	}
+
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/GenericJpaPlatformUiProvider.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/GenericJpaPlatformUiProvider.java
new file mode 100644
index 0000000..f3b92c1c
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/GenericJpaPlatformUiProvider.java
@@ -0,0 +1,70 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2009 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.ui.internal;
+
+import java.util.List;
+import org.eclipse.jpt.ui.JpaPlatformUiProvider;
+import org.eclipse.jpt.ui.ResourceUiDefinition;
+import org.eclipse.jpt.ui.details.JpaDetailsProvider;
+import org.eclipse.jpt.ui.internal.details.java.GenericJavaResourceUiDefinition;
+import org.eclipse.jpt.ui.internal.details.java.JavaPersistentAttributeDetailsProvider;
+import org.eclipse.jpt.ui.internal.details.java.JavaPersistentTypeDetailsProvider;
+import org.eclipse.jpt.ui.internal.details.orm.EntityMappingsDetailsProvider;
+import org.eclipse.jpt.ui.internal.details.orm.OrmPersistentAttributeDetailsProvider;
+import org.eclipse.jpt.ui.internal.details.orm.OrmPersistentTypeDetailsProvider;
+import org.eclipse.jpt.ui.internal.details.orm.OrmXmlUiDefinition;
+import org.eclipse.jpt.ui.internal.persistence.details.PersistenceXmlUiDefinition;
+
+/**
+ * All the state in the JPA platform should be "static" (i.e. unchanging once
+ * it is initialized).
+ */
+public class GenericJpaPlatformUiProvider extends AbstractJpaPlatformUiProvider
+{
+
+	// singleton
+	private static final JpaPlatformUiProvider INSTANCE = new GenericJpaPlatformUiProvider();
+
+	/**
+	 * Return the singleton.
+	 */
+	public static JpaPlatformUiProvider instance() {
+		return INSTANCE;
+	}
+
+	/**
+	 * Ensure single instance.
+	 */
+	private GenericJpaPlatformUiProvider() {
+		super();
+	}
+
+
+	// ********** details providers **********
+	
+	@Override
+	protected void addDetailsProvidersTo(List<JpaDetailsProvider> providers) {
+		providers.add(JavaPersistentTypeDetailsProvider.instance());
+		providers.add(JavaPersistentAttributeDetailsProvider.instance());
+		providers.add(EntityMappingsDetailsProvider.instance());
+		providers.add(OrmPersistentTypeDetailsProvider.instance());
+		providers.add(OrmPersistentAttributeDetailsProvider.instance());
+	}
+	
+	
+	// ********** resource ui definitions **********
+	
+	@Override
+	protected void addResourceUiDefinitionsTo(List<ResourceUiDefinition> defintions) {
+		defintions.add(GenericJavaResourceUiDefinition.instance());
+		defintions.add(OrmXmlUiDefinition.instance());
+		defintions.add(PersistenceXmlUiDefinition.instance());
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/ImageRepository.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/ImageRepository.java
new file mode 100644
index 0000000..97c1ecd
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/ImageRepository.java
@@ -0,0 +1,149 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2010 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.ui.internal;
+
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.resource.ResourceManager;
+import org.eclipse.jpt.ui.JptUiPlugin;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+
+@SuppressWarnings("nls")
+public final class ImageRepository {
+
+	// ***** overlays *****
+	public static Image getErrorOverlayImage(ResourceManager resourceManager) {
+		return getImage(resourceManager, ERROR_OVERLAY_DESCRIPTOR);
+	}
+	private static final ImageDescriptor ERROR_OVERLAY_DESCRIPTOR = buildImageDescriptor("overlays/error.gif");
+
+	public static Image getWarningOverlayImage(ResourceManager resourceManager) {
+		return getImage(resourceManager, WARNING_OVERLAY_DESCRIPTOR);
+	}
+	private static final ImageDescriptor WARNING_OVERLAY_DESCRIPTOR = buildImageDescriptor("overlays/warning.png");
+
+	// ***** buttons *****
+	public static Image getAddButtonImage(ResourceManager resourceManager) {
+		return getImage(resourceManager, ADD_BUTTON_DESCRIPTOR);
+	}
+	private static final ImageDescriptor ADD_BUTTON_DESCRIPTOR = buildImageDescriptor("buttons/add.png");
+
+	public static Image getEditButtonImage(ResourceManager resourceManager) {
+		return getImage(resourceManager, EDIT_BUTTON_DESCRIPTOR);
+	}
+	private static final ImageDescriptor EDIT_BUTTON_DESCRIPTOR = buildImageDescriptor("buttons/edit.png");
+
+	public static Image getDeleteButtonImage(ResourceManager resourceManager) {
+		return getImage(resourceManager, DELETE_BUTTON_DESCRIPTOR);
+	}
+	private static final ImageDescriptor DELETE_BUTTON_DESCRIPTOR = buildImageDescriptor("buttons/delete.png");
+
+	public static Image getMoveUpButtonImage(ResourceManager resourceManager) {
+		return getImage(resourceManager, MOVE_UP_BUTTON_DESCRIPTOR);
+	}
+	private static final ImageDescriptor MOVE_UP_BUTTON_DESCRIPTOR = buildImageDescriptor("buttons/move-up.png");
+
+	public static Image getMoveDownButtonImage(ResourceManager resourceManager) {
+		return getImage(resourceManager, MOVE_DOWN_BUTTON_DESCRIPTOR);
+	}
+	private static final ImageDescriptor MOVE_DOWN_BUTTON_DESCRIPTOR = buildImageDescriptor("buttons/move-down.png");
+
+	public static Image getExpandAllButtonImage(ResourceManager resourceManager) {
+		return getImage(resourceManager, EXPAND_ALL_BUTTON_DESCRIPTOR);
+	}
+	private static final ImageDescriptor EXPAND_ALL_BUTTON_DESCRIPTOR = buildImageDescriptor("buttons/expand-all.png");
+
+	public static Image getCollapseAllButtonImage(ResourceManager resourceManager) {
+		return getImage(resourceManager, COLLAPSE_ALL_BUTTON_DESCRIPTOR);
+	}
+	private static final ImageDescriptor COLLAPSE_ALL_BUTTON_DESCRIPTOR = buildImageDescriptor("buttons/collapse-all.png");
+
+	public static Image getRestoreDefaultsButtonImage(ResourceManager resourceManager) {
+		return getImage(resourceManager, RESTORE_DEFAULTS_BUTTON_DESCRIPTOR);
+	}
+	private static final ImageDescriptor RESTORE_DEFAULTS_BUTTON_DESCRIPTOR = buildImageDescriptor("buttons/restore-defaults.png");
+
+	public static Image getBrowseButtonImage(ResourceManager resourceManager) {
+		return getImage(resourceManager, BROWSE_BUTTON_DESCRIPTOR);
+	}
+	private static final ImageDescriptor BROWSE_BUTTON_DESCRIPTOR = buildImageDescriptor("buttons/browse.png");
+
+	public static Image getMiniBrowseButtonImage(ResourceManager resourceManager) {
+		return getImage(resourceManager, MINI_BROWSE_BUTTON_DESCRIPTOR);
+	}
+	private static final ImageDescriptor MINI_BROWSE_BUTTON_DESCRIPTOR = buildImageDescriptor("buttons/browse-mini.png");
+
+	public static Image getSelectAllButtonImage(ResourceManager resourceManager) {
+		return getImage(resourceManager, SELECT_ALL_BUTTON_DESCRIPTOR);
+	}
+	private static final ImageDescriptor SELECT_ALL_BUTTON_DESCRIPTOR = buildImageDescriptor("buttons/select-all.png");
+
+	public static Image getDeselectAllButtonImage(ResourceManager resourceManager) {
+		return getImage(resourceManager, DESELECT_ALL_BUTTON_DESCRIPTOR);
+	}
+	private static final ImageDescriptor DESELECT_ALL_BUTTON_DESCRIPTOR = buildImageDescriptor("buttons/deselect-all.png");
+
+	public static Image getAddConnectionButtonImage(ResourceManager resourceManager) {
+		return getImage(resourceManager, ADD_CONNECTION_BUTTON_DESCRIPTOR);
+	}
+	private static final ImageDescriptor ADD_CONNECTION_BUTTON_DESCRIPTOR = buildImageDescriptor("buttons/add-connection.gif");
+
+	public static Image getReconnectButtonImage(ResourceManager resourceManager) {
+		return getImage(resourceManager, RECONNECT_BUTTON_DESCRIPTOR);
+	}
+	private static final ImageDescriptor RECONNECT_BUTTON_DESCRIPTOR = buildImageDescriptor("buttons/reconnect.png");
+
+	// ***** objects *****
+	public static Image getFileImage(ResourceManager resourceManager) {
+		return getImage(resourceManager, FILE_DESCRIPTOR);
+	}
+	private static final ImageDescriptor FILE_DESCRIPTOR = buildImageDescriptor("objects/file.png");
+
+	public static Image getFolderImage(ResourceManager resourceManager) {
+		return getImage(resourceManager, FOLDER_DESCRIPTOR);
+	}
+	private static final ImageDescriptor FOLDER_DESCRIPTOR = buildImageDescriptor("objects/folder.png");
+
+	public static Image getPackageImage(ResourceManager resourceManager) {
+		return getImage(resourceManager, PACKAGE_DESCRIPTOR);
+	}
+	private static final ImageDescriptor PACKAGE_DESCRIPTOR = buildImageDescriptor("objects/package.png");
+
+	public static Image getTableImage(ResourceManager resourceManager) {
+		return getImage(resourceManager, TABLE_DESCRIPTOR);
+	}
+	private static final ImageDescriptor TABLE_DESCRIPTOR = buildImageDescriptor("objects/table.gif");
+
+	public static Image getTableObjImage(ResourceManager resourceManager) {
+		return getImage(resourceManager, TABLE_OBJ_DESCRIPTOR);
+	}
+	private static final ImageDescriptor TABLE_OBJ_DESCRIPTOR = buildImageDescriptor("objects/table_obj.gif");
+
+	public static Image getColumnImage(ResourceManager resourceManager) {
+		return getImage(resourceManager, COLUMN_DESCRIPTOR);
+	}
+	private static final ImageDescriptor COLUMN_DESCRIPTOR = buildImageDescriptor("objects/column.gif");
+
+	public static Image getKeyColumnImage(ResourceManager resourceManager) {
+		return getImage(resourceManager, KEY_COLUMN_DESCRIPTOR);
+	}
+	private static final ImageDescriptor KEY_COLUMN_DESCRIPTOR = buildImageDescriptor("objects/columnKey.gif");
+
+
+	private static ImageDescriptor buildImageDescriptor(String fileName) {
+		return AbstractUIPlugin.imageDescriptorFromPlugin(JptUiPlugin.PLUGIN_ID, "images/" + fileName);
+	}
+
+
+	private static Image getImage(ResourceManager resourceManager, ImageDescriptor descriptor) {
+		return resourceManager.createImage(descriptor);
+	}
+
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/JpaHelpContextIds.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/JpaHelpContextIds.java
new file mode 100644
index 0000000..06318dd
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/JpaHelpContextIds.java
@@ -0,0 +1,151 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 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.ui.internal;
+
+import org.eclipse.jpt.ui.JptUiPlugin;
+
+/**
+ * Help context ids for the Dali JPA UI.
+ * <p>
+ * This interface contains constants only; it is not intended to be
+ * implemented.
+ * </p>
+ */
+@SuppressWarnings("nls")
+public interface JpaHelpContextIds {
+
+	//ContextID prefix
+	public static final String PREFIX = JptUiPlugin.PLUGIN_ID + ".";
+
+	//Persistent Type composites
+	public static final String ENTITY_ACCESS_TYPE = PREFIX + "entity_accessType";
+	public static final String ENTITY_ATTRIBUTE_OVERRIDES = PREFIX + "entity_attributeOverrides";
+	public static final String ENTITY_ATTRIBUTE_OVERRIDES_COLUMN = PREFIX + "entity_attributeOverridesColumn";
+	public static final String ENTITY_CATALOG = PREFIX + "entity_catalog";
+	public static final String ENTITY_INHERITANCE_STRATEGY = PREFIX + "entity_inheritanceStrategy";
+	public static final String ENTITY_INHERITANCE_DISCRIMINATOR_TYPE = PREFIX + "entity_inheritanceDiscriminatorType";
+	public static final String ENTITY_INHERITANCE_DISCRIMINATOR_COLUMN = PREFIX + "entity_inheritanceDiscriminatorColumn";
+	public static final String ENTITY_INHERITANCE_DISCRIMINATOR_VALUE = PREFIX + "entity_inheritanceDiscriminatorValue";
+	public static final String ENTITY_NAME = PREFIX + "entity_name";
+	public static final String ENTITY_ORM_PACKAGE = PREFIX + "orm_package";
+	public static final String ENTITY_ORM_SCHEMA = PREFIX + "orm_schema";
+	public static final String ENTITY_ORM_CATALOG = PREFIX + "orm_catalog";
+	public static final String ENTITY_ORM_ACCESS = PREFIX + "orm_access";
+	public static final String ENTITY_ORM_DELIMITED_IDENTIFIERS = PREFIX + "orm_delimited_identifiers";
+	public static final String ENTITY_ORM_CASCADE = PREFIX + "orm_cascade";
+	public static final String ENTITY_ORM_XML = PREFIX + "orm_xml";
+	public static final String ENTITY_SCHEMA = PREFIX + "entity_schema";
+	public static final String ENTITY_TABLE = PREFIX + "entity_table";
+	public static final String ENTITY_CACHEABLE = PREFIX + "entity_cacheable";
+
+	//Persistent Attribute composites
+	public static final String MAPPING_CASCADE_TYPE = PREFIX + "mapping_cascadeType";
+	public static final String MAPPING_COLUMN = PREFIX + "mapping_column";
+	public static final String MAPPING_COLUMN_INSERTABLE = PREFIX + "mapping_columnInsertable";
+	public static final String MAPPING_COLUMN_LENGTH = PREFIX + "mapping_columnLength";
+	public static final String MAPPING_COLUMN_NULLABLE = PREFIX + "mapping_columnNullable";
+	public static final String MAPPING_COLUMN_PRECISION = PREFIX + "mapping_columnPrecision";
+	public static final String MAPPING_COLUMN_SCALE = PREFIX + "mapping_columnScale";
+	public static final String MAPPING_COLUMN_TABLE = PREFIX + "mapping_columnTable";
+	public static final String MAPPING_COLUMN_UNIQUE = PREFIX + "mapping_columnUnique";
+	public static final String MAPPING_COLUMN_UPDATABLE= PREFIX + "mapping_columnUpdatable";
+	public static final String MAPPING_EMBEDDED_ATTRIBUTE_OVERRIDES = PREFIX + "mapping_embeddedAttributeOverrides";
+	public static final String MAPPING_EMBEDDED_ATTRIBUTE_OVERRIDES_COLUMN = PREFIX + "mapping_embeddedAttributeOverridesColumn";
+	public static final String MAPPING_ENUMERATED = PREFIX + "mapping_enumerated";
+	public static final String MAPPING_FETCH_TYPE = PREFIX + "mapping_fetchType";
+	public static final String MAPPING_GENERATED_VALUE_STRATEGY = PREFIX + "mapping_generatedValueStrategy";
+	public static final String MAPPING_GENERATED_VALUE_GENERATOR_NAME = PREFIX + "mapping_generatedValueGeneratorName";
+	public static final String MAPPING_JOIN_COLUMN_NAME = PREFIX + "mapping_joinColumnName";
+	public static final String MAPPING_JOIN_REFERENCED_COLUMN = PREFIX + "mapping_joinReferencedColumn";
+	public static final String MAPPING_JOIN_TABLE_NAME = PREFIX + "mapping_joinTableName";
+	public static final String MAPPING_JOIN_TABLE_SCHEMA = PREFIX + "mapping_joinTableSchema";
+	public static final String MAPPING_JOIN_TABLE_CATALOG = PREFIX + "mapping_joinTableCatalog";
+	public static final String MAPPING_JOIN_TABLE_COLUMNS = PREFIX + "mapping_joinTableJoinColumns";
+	public static final String MAPPING_JOIN_TABLE_INVERSE_JOIN_COLUMNS = PREFIX + "mapping_joinTableInverseJoinColumns";
+	public static final String MAPPING_LOB = PREFIX + "mapping_lob";
+	public static final String MAPPING_MAP_AS = PREFIX + "mapping_mapAs";
+	public static final String MAPPING_MAPPED_BY = PREFIX + "mapping_mappedBy";
+	public static final String MAPPING_NAMED_NATIVE_QUERIES = "named_native_queries";
+	public static final String MAPPING_NAMED_QUERIES = PREFIX + "named_queries";
+	public static final String MAPPING_OPTIONAL = PREFIX + "mapping_optional";
+	public static final String MAPPING_ORDER_BY = PREFIX + "mapping_orderBy";
+	public static final String MAPPING_ORDER_BY_NO_ORDERING = PREFIX + "mapping_orderByNoOrdering";
+	public static final String MAPPING_ORDER_BY_PRIMARY_KEY_ORDERING = PREFIX + "mapping_orderByPrimaryKeyOrdering";
+	public static final String MAPPING_ORDER_BY_CUSTOM_ORDERING = PREFIX + "mapping_orderByCustomOrdering";
+	public static final String MAPPING_ORDER_COLUMN_ORDERING = PREFIX + "mapping_orderColumnOrdering";
+	public static final String MAPPING_ORDER_COLUMN_ORDERING_COLUMN = PREFIX + "mapping_orderColumnOrderingColumn";
+	public static final String MAPPING_PRIMARY_KEY_GENERATION = PREFIX + "mapping_primaryKeyGeneration";
+	public static final String MAPPING_SEQUENCE_GENERATOR = PREFIX + "mapping_sequenceGenerator";
+	public static final String MAPPING_SEQUENCE_GENERATOR_NAME = PREFIX + "mapping_sequenceGeneratorName";
+	public static final String MAPPING_SEQUENCE_GENERATOR_SEQUENCE = PREFIX + "mapping_sequenceGeneratorSequence";
+	public static final String MAPPING_TABLE_GENERATOR = PREFIX + "mapping_tableGenerator";
+	public static final String MAPPING_TABLE_GENERATOR_CATALOG = PREFIX + "mapping_tableGeneratorCatalog";
+	public static final String MAPPING_TABLE_GENERATOR_NAME = PREFIX + "mapping_tableGeneratorName";
+	public static final String MAPPING_TABLE_GENERATOR_PRIMARY_KEY_COLUMN = PREFIX + "mapping_tableGeneratorPrimaryKeyColumn";
+	public static final String MAPPING_TABLE_GENERATOR_PRIMARY_KEY_COLUMN_VALUE = PREFIX + "mapping_tableGeneratorPrimaryKeyColumnValue";
+	public static final String MAPPING_TABLE_GENERATOR_SCHEMA = PREFIX + "mapping_tableGeneratorSchema";
+	public static final String MAPPING_TABLE_GENERATOR_TABLE= PREFIX + "mapping_tableGeneratorTable";
+	public static final String MAPPING_TABLE_GENERATOR_VALUE_COLUMN = PREFIX + "mapping_tableGeneratorValueColumn";
+	public static final String MAPPING_TARGET_ENTITY = PREFIX + "mapping_targetEntity";
+	public static final String MAPPING_TEMPORAL = PREFIX + "mapping_temporal";
+
+	//Project properties
+	public static final String PROPERTIES_JAVA_PERSISTENCE = PREFIX + "properties_javaPersistence";
+	public static final String PROPERTIES_JAVA_PERSISTENCE_CONNECTION = PREFIX + "properties_javaPersistenceConnection";
+	public static final String PROPERTIES_JAVA_PERSISTENCE_SCHEMA = PREFIX + "properties_javaPersistenceSchema";
+	public static final String PROPERTIES_JAVA_PERSISTENCE_METAMODEL = PREFIX + "properties_canonicalMetamodel";
+	
+	//Dialogs, Wizards
+	public static final String DIALOG_CREATE_ORM = PREFIX + "dialog_createORM";
+	public static final String DIALOG_EDIT_INVERSE_JOIN_COLUNN = PREFIX + "dialog_editInverseJoinColumn";
+	public static final String DIALOG_GENERATE_ENTITIES = PREFIX + "dialog_generateEntities";
+	public static final String DIALOG_GENERATE_ENTITIES_SOURCE = PREFIX + "dialog_generateEntities_source";
+	public static final String DIALOG_GENERATE_ENTITIES_PACKAGE = PREFIX + "dialog_generateEntities_package";
+	public static final String DIALOG_GENERATE_ENTITIES_TABLES = PREFIX + "dialog_generateEntities_tables";
+	public static final String DIALOG_JPA_FACET = PREFIX + "dialog_JPAFacet";
+	public static final String DIALOG_JPA_PLATFORM = PREFIX + "dialog_JPAPlatform";
+	
+	//New JPA Project wizard:
+	public static final String NEW_JPA_PROJECT = PREFIX + "dialog_newJPAProject";
+ 	public static final String NEW_JPA_PROJECT_CONTENT_PAGE_CLASSPATH = PREFIX + "dialog_addJavaPersistence_classpath";
+ 	public static final String NEW_JPA_PROJECT_CONTENT_PAGE_DATABASE = PREFIX + "dialog_addJavaPersistence_database";
+ 	public static final String NEW_JPA_PROJECT_CONTENT_PAGE_PACKAGING = PREFIX + "dialog_addJavaPersistence_packaging";
+ 	public static final String NEW_JPA_PROJECT_CREATION_PAGE = PREFIX + "dialog_addJavaPersistence";
+	public static final String NEW_JPA_PROJECT_JPA_FACET = PREFIX + "dialog_newJPAProjectFacet";
+
+	//Other
+	public static final String PERSISTENCE_OUTLINE = PREFIX + "persistenceOutline";
+
+	//Persistence Xml Editor
+	public static final String PERSISTENCE_XML_CONNECTION = PREFIX + "persistence_connection";
+	public static final String PERSISTENCE_XML_GENERAL = PREFIX + "persistence_general";
+	public static final String PERSISTENCE_XML_PROPERTIES  = PREFIX + "persistence_properties";
+	public static final String PERSISTENCE_XML_SOURCE  = PREFIX + "persistence_source";
+
+	//New JPA Entity wizard
+	public static final String NEW_JPA_ENTITY_ENTITY_CLASS  = PREFIX + "dialog_entityClassPage";
+	public static final String NEW_JPA_ENTITY_ENTITY_PROPERTIES  = PREFIX + "dialog_entityPropertiesPage";
+	
+	//Generate Entities Wizard
+	public static final String GENERATE_ENTITIES_WIZARD_ASSOCIATION_CARDINALITY = PREFIX + "dialog_associationCardinalityPage";
+	public static final String GENERATE_ENTITIES_WIZARD_ASSOCIATION_TABLES = PREFIX + "dialog_associationTablesPage";
+	public static final String GENERATE_ENTITIES_WIZARD_CUSTOMIZE_DEFAULT_ENTITY_GENERATION = PREFIX + "dialog_customizeDefaultEntityGeneration";
+	public static final String GENERATE_ENTITIES_WIZARD_CUSTOMIZE_INDIVIDUAL_ENTITIES = PREFIX + "dialog_customizeIndividualEntities";
+	public static final String GENERATE_ENTITIES_WIZARD_JOIN_COLUMNS = PREFIX + "dialog_joinColumnsPage";
+	public static final String GENERATE_ENTITIES_WIZARD_SELECT_CASCADE = PREFIX + "dialog_selectCascade";
+	public static final String GENERATE_ENTITIES_WIZARD_SELECT_TABLES = PREFIX + "dialog_selectTablesPage";
+	public static final String GENERATE_ENTITIES_WIZARD_TABLE_ASSOCIATIONS = PREFIX + "dialog_tableAssociationsPage";
+
+	public static final String MAPPING_COLLECTION_TABLE_NAME = PREFIX + "mapping_collectionTableName";
+	public static final String MAPPING_COLLECTION_TABLE_SCHEMA = PREFIX + "mapping_collectionTableSchema";
+	public static final String MAPPING_COLLECTION_TABLE_CATALOG = PREFIX + "mapping_collectionTableCatalog";
+	
+	public static final String MAPPING_ELEMENT_COLLECTION_TARGET_CLASS = PREFIX + "mapping_elementCollectionTargetClass";
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/JpaJavaCompletionProposalComputer.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/JpaJavaCompletionProposalComputer.java
new file mode 100644
index 0000000..7035767
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/JpaJavaCompletionProposalComputer.java
@@ -0,0 +1,187 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 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.ui.internal;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.jdt.core.CompletionContext;
+import org.eclipse.jdt.core.ICompilationUnit;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.core.dom.CompilationUnit;
+import org.eclipse.jdt.ui.text.java.ContentAssistInvocationContext;
+import org.eclipse.jdt.ui.text.java.IJavaCompletionProposalComputer;
+import org.eclipse.jdt.ui.text.java.JavaContentAssistInvocationContext;
+import org.eclipse.jface.text.contentassist.CompletionProposal;
+import org.eclipse.jface.text.contentassist.ICompletionProposal;
+import org.eclipse.jpt.core.JpaFile;
+import org.eclipse.jpt.core.JpaStructureNode;
+import org.eclipse.jpt.core.JptCorePlugin;
+import org.eclipse.jpt.core.context.java.JavaPersistentType;
+import org.eclipse.jpt.core.internal.utility.jdt.ASTTools;
+import org.eclipse.jpt.utility.Filter;
+import org.eclipse.jpt.utility.internal.CollectionTools;
+import org.eclipse.jpt.utility.internal.StringTools;
+
+/**
+ * JPA Java code-completion proposal computer
+ */
+public class JpaJavaCompletionProposalComputer implements IJavaCompletionProposalComputer {
+
+	public JpaJavaCompletionProposalComputer() {
+		super();
+	}
+
+	public void sessionStarted() {
+		// do nothing
+	}
+
+	@SuppressWarnings("unchecked")
+	public List computeCompletionProposals(ContentAssistInvocationContext context, IProgressMonitor monitor) {
+		return (context instanceof JavaContentAssistInvocationContext) ?
+					this.computeCompletionProposals((JavaContentAssistInvocationContext) context)
+				:
+					Collections.emptyList();
+	}
+
+	/**
+	 * We fail silently here because (it seems) <em>expected</em> exceptions occur
+	 * more frequently than intermittent <em>unexpected</em> exceptions that might
+	 * merit investigation (and a logged stacktrace might be the only hint as
+	 * to what happened).
+	 * <p>
+	 * We will get an <em>expected</em> exception (typically a {@link NullPointerException NPE})
+	 * here if the user:<ol>
+	 * <li>modifies the Java source file in a way that puts it drastically out
+	 *     of sync with the Dali context model (e.g. deleting a field or
+	 *     annotation)
+	 * <li>immediately invokes Content Assist (typically <code>Ctrl+Space</code>)
+	 * </ol>
+	 * The AST we build here will be based on the just-modified Java source; but,
+	 * since the user moved quickly and we will not have yet received any Java
+	 * change notification (since we only get a Java change notification when
+	 * the user has paused typing for at least 0.5 seconds), the context model
+	 * will still be based on the unmodified Java source. As the new AST is
+	 * passed down through the context model to the resource model all the code
+	 * expects to find the AST in sync with the model. When this is not the
+	 * case (e.g. a field in the resource model is no longer present in the AST
+	 * because the user has deleted it or modified the code in such a way that
+	 * the parser can no longer detect the field) the model will probably choke
+	 * when it cannot find the corresponding AST node.
+	 * <p>
+	 * It seems reasonable, in these situations, to simply return no completion
+	 * proposals. If the user simply waits a moment and tries again, we will be
+	 * able to successfully calculate some proposals.
+	 * <p>
+	 * ~bjv
+	 */
+	private List<ICompletionProposal> computeCompletionProposals(JavaContentAssistInvocationContext context) {
+		try {
+			return this.computeCompletionProposals_(context);
+		} catch (Exception ex) {
+			// JptCorePlugin.log(ex);  // don't log "expected" exceptions (?)
+			return Collections.emptyList();
+		}
+	}
+
+	private List<ICompletionProposal> computeCompletionProposals_(JavaContentAssistInvocationContext context) {
+		ICompilationUnit cu = context.getCompilationUnit();
+		if (cu == null) {
+			return Collections.emptyList();
+		}
+
+		IFile file = this.getCorrespondingResource(cu);
+		if (file == null) {
+			return Collections.emptyList();
+		}
+
+		JpaFile jpaFile = JptCorePlugin.getJpaFile(file);
+		if (jpaFile == null) {
+			return Collections.emptyList();
+		}
+		
+		Collection<JpaStructureNode> rootStructureNodes = CollectionTools.collection(jpaFile.rootStructureNodes());
+		if (rootStructureNodes.isEmpty()) {
+			return Collections.emptyList();
+		}
+
+		CompletionContext cc = context.getCoreContext();
+
+		// the context's "token" is really a sort of "prefix" - it does NOT
+		// correspond to the "start" and "end" we get below... 
+		char[] prefix = cc.getToken();
+		Filter<String> filter = ((prefix == null) ? Filter.Null.<String>instance() : new IgnoreCasePrefixFilter(prefix));
+		// the token "start" is the offset of the token's first character
+		int tokenStart = cc.getTokenStart();
+		// the token "end" is the offset of the token's last character (yuk)
+		int tokenEnd = cc.getTokenEnd();
+		if (tokenStart == -1) {  // not sure why this happens - see bug 242286
+			return Collections.emptyList();
+		}
+
+//		System.out.println("prefix: " + ((prefix == null) ? "[null]" : new String(prefix)));
+//		System.out.println("token start: " + tokenStart);
+//		System.out.println("token end: " + tokenEnd);
+//		String source = cu.getSource();
+//		String token = source.substring(Math.max(0, tokenStart), Math.min(source.length(), tokenEnd + 1));
+//		System.out.println("token: =>" + token + "<=");
+//		String snippet = source.substring(Math.max(0, tokenStart - 20), Math.min(source.length(), tokenEnd + 21));
+//		System.out.println("surrounding snippet: =>" + snippet + "<=");
+
+		// TODO move this parser call into the model...
+		CompilationUnit astRoot = ASTTools.buildASTRoot(cu);
+		List<ICompletionProposal> proposals = new ArrayList<ICompletionProposal>();
+		for (JpaStructureNode structureNode : rootStructureNodes) {
+			for (Iterator<String> stream = ((JavaPersistentType) structureNode).javaCompletionProposals(context.getInvocationOffset(), filter, astRoot); stream.hasNext(); ) {
+				String s = stream.next();
+				proposals.add(new CompletionProposal(s, tokenStart, tokenEnd - tokenStart + 1, s.length()));
+			}
+		}
+		return proposals;
+	}
+
+	private IFile getCorrespondingResource(ICompilationUnit cu) {
+		try {
+			return (IFile) cu.getCorrespondingResource();
+		} catch (JavaModelException ex) {
+			JptCorePlugin.log(ex);
+			return null;
+		}
+	}
+
+	@SuppressWarnings("unchecked")
+	public List computeContextInformation(ContentAssistInvocationContext context, IProgressMonitor monitor) {
+		return Collections.emptyList();
+	}
+
+	public String getErrorMessage() {
+		return null;
+	}
+
+	public void sessionEnded() {
+		// do nothing
+	}
+
+	private static class IgnoreCasePrefixFilter implements Filter<String> {
+		private final char[] prefix;
+		IgnoreCasePrefixFilter(char[] prefix) {
+			super();
+			this.prefix = prefix;
+		}
+		public boolean accept(String s) {
+			return StringTools.stringStartsWithIgnoreCase(s.toCharArray(), this.prefix);
+		}
+	}
+
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/JpaMappingImageHelper.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/JpaMappingImageHelper.java
new file mode 100644
index 0000000..e96c6db
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/JpaMappingImageHelper.java
@@ -0,0 +1,85 @@
+/*******************************************************************************
+ *  Copyright (c) 2008, 2010 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.ui.internal;
+
+import org.eclipse.jpt.core.MappingKeys;
+import org.eclipse.jpt.core.jpa2.MappingKeys2_0;
+import org.eclipse.jpt.ui.JptUiPlugin;
+import org.eclipse.swt.graphics.Image;
+
+public class JpaMappingImageHelper
+{
+
+	public static Image imageForTypeMapping(String mappingKey) {
+		return JptUiPlugin.getImage(iconKeyForTypeMapping(mappingKey));
+	}
+
+	public static String iconKeyForTypeMapping(String mappingKey) {
+		if (MappingKeys.NULL_TYPE_MAPPING_KEY == mappingKey) {
+			return JptUiIcons.NULL_TYPE_MAPPING;
+		}
+		else if (MappingKeys.ENTITY_TYPE_MAPPING_KEY.equals(mappingKey)) {
+			return JptUiIcons.ENTITY;
+		}
+		else if (MappingKeys.EMBEDDABLE_TYPE_MAPPING_KEY.equals(mappingKey)) {
+			return JptUiIcons.EMBEDDABLE;
+		}
+		else if (MappingKeys.MAPPED_SUPERCLASS_TYPE_MAPPING_KEY.equals(mappingKey)) {
+			return JptUiIcons.MAPPED_SUPERCLASS;
+		}
+		return null;
+	}
+
+	public static Image imageForAttributeMapping(String mappingKey) {
+		return JptUiPlugin.getImage(iconKeyForAttributeMapping(mappingKey));
+	}
+
+	public static String iconKeyForAttributeMapping(String mappingKey) {
+		if (MappingKeys.NULL_ATTRIBUTE_MAPPING_KEY == mappingKey) {
+			return JptUiIcons.NULL_ATTRIBUTE_MAPPING;
+		}
+		else if (MappingKeys.BASIC_ATTRIBUTE_MAPPING_KEY.equals(mappingKey)) {
+			return JptUiIcons.BASIC;
+		}
+		else if (MappingKeys.ID_ATTRIBUTE_MAPPING_KEY.equals(mappingKey)) {
+			return JptUiIcons.ID;
+		}
+		else if (MappingKeys.VERSION_ATTRIBUTE_MAPPING_KEY.equals(mappingKey)) {
+			return JptUiIcons.VERSION;
+		}
+		else if (MappingKeys.EMBEDDED_ID_ATTRIBUTE_MAPPING_KEY.equals(mappingKey)) {
+			return JptUiIcons.EMBEDDED_ID;
+		}
+		else if (MappingKeys.EMBEDDED_ATTRIBUTE_MAPPING_KEY.equals(mappingKey)) {
+			return JptUiIcons.EMBEDDED;
+		}
+		else if (MappingKeys.ONE_TO_ONE_ATTRIBUTE_MAPPING_KEY.equals(mappingKey)) {
+			return JptUiIcons.ONE_TO_ONE;
+		}
+		else if (MappingKeys.ONE_TO_MANY_ATTRIBUTE_MAPPING_KEY.equals(mappingKey)) {
+			return JptUiIcons.ONE_TO_MANY;
+		}
+		else if (MappingKeys.MANY_TO_ONE_ATTRIBUTE_MAPPING_KEY.equals(mappingKey)) {
+			return JptUiIcons.MANY_TO_ONE;
+		}
+		else if (MappingKeys.MANY_TO_MANY_ATTRIBUTE_MAPPING_KEY.equals(mappingKey)) {
+			return JptUiIcons.MANY_TO_MANY;
+		}
+		else if (MappingKeys2_0.ELEMENT_COLLECTION_ATTRIBUTE_MAPPING_KEY.equals(mappingKey)) {
+			return JptUiIcons.ELEMENT_COLLECTION;
+		}
+		else if (MappingKeys.TRANSIENT_ATTRIBUTE_MAPPING_KEY.equals(mappingKey)) {
+			return JptUiIcons.TRANSIENT;
+		}
+		//return the JPA_CONTENT icon instead of null, might as well have an icon if one is not defined
+		return JptUiIcons.JPA_CONTENT;
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/JptUiIcons.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/JptUiIcons.java
new file mode 100644
index 0000000..4cbea01
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/JptUiIcons.java
@@ -0,0 +1,127 @@
+/*******************************************************************************
+ *  Copyright (c) 2007, 2010 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.ui.internal;
+
+import org.eclipse.draw2d.ImageUtilities;
+import org.eclipse.jpt.ui.JptUiPlugin;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.ImageData;
+
+@SuppressWarnings("nls")
+public class JptUiIcons
+{
+    /**
+	 * Creates and returns a new SWT image that is a grayed out version of the image 
+	 * corresponding  to the passed in key. Stores this gray image in the JptUiPlugin 
+	 * ImageRegistry with -gray appended to the key.
+	 * Clients of this method should not dispose of the image.
+	 * 
+	 * @return a new grayed out image
+	 */
+	public static Image ghost(String key) {
+		Image existingImage = JptUiPlugin.instance().getImageRegistry().get(key + "-gray");
+		if (existingImage != null) {
+			return existingImage;
+		}
+
+		Image grayImage = buildGhostImage(key);
+		JptUiPlugin.instance().getImageRegistry().put(key + "-gray", grayImage);
+		return grayImage;
+	}
+	
+	private static Image buildGhostImage(String key) {
+		Image originalImage = JptUiPlugin.getImage(key);
+		Color lightGray = new Color(originalImage.getDevice(), 223, 223, 223);
+		ImageData imageData = ImageUtilities.createShadedImage(originalImage, lightGray);
+
+		Image shadedImage = new Image(originalImage.getDevice(), imageData);
+		Image grayImage = new Image(originalImage.getDevice(), shadedImage, SWT.IMAGE_GRAY);
+
+		lightGray.dispose();
+		shadedImage.dispose();
+		return grayImage;
+	}	
+
+
+	// **************** General JPA icons **************************************
+	
+	public static final String JPA_CONTENT = "full/obj16/jpa-content";
+	
+	public static final String JPA_FILE = "full/obj16/jpa-file";
+	
+	public static final String JAR_FILE = "full/obj16/jpa-jar-file";
+	
+	public static final String WARNING = "full/obj16/warning";
+	
+	
+	// **************** Wizard icons *******************************************
+	
+	public static final String JPA_WIZ_BANNER = "full/wizban/jpa_facet_wizban";
+	
+	public static final String ENTITY_WIZ_BANNER = "full/wizban/new_entity_wizban";
+	
+	public static final String JPA_FILE_WIZ_BANNER = "full/wizban/new_jpa_file_wizban";
+	
+	
+	// **************** Persistence icons **************************************
+
+	public static final String PERSISTENCE = "full/obj16/persistence";
+
+	public static final String PERSISTENCE_UNIT = "full/obj16/persistence-unit";
+
+	public static final String MAPPING_FILE_REF = "full/obj16/jpa-file";
+
+	public static final String CLASS_REF = "full/obj16/null-type-mapping";
+	
+	public static final String JAR_FILE_REF = "full/obj16/jpa-jar-file";
+
+
+	// **************** Orm icons **********************************************
+
+	public static final String ENTITY_MAPPINGS = "full/obj16/entity-mappings";
+
+
+	// **************** Orm/Java common icons **********************************
+	
+	public static final String ENTITY = "full/obj16/entity";
+	
+	public static final String EMBEDDABLE = "full/obj16/embeddable";
+	
+	public static final String MAPPED_SUPERCLASS = "full/obj16/mapped-superclass";
+	
+	public static final String NULL_TYPE_MAPPING = "full/obj16/null-type-mapping";
+	
+	public static final String ID = "full/obj16/id";
+	
+	public static final String EMBEDDED_ID = "full/obj16/embedded-id";
+	
+	public static final String BASIC = "full/obj16/basic";
+	
+	public static final String VERSION = "full/obj16/version";
+	
+	public static final String MANY_TO_ONE = "full/obj16/many-to-one";
+	
+	public static final String ONE_TO_MANY = "full/obj16/one-to-many";
+	
+	public static final String ONE_TO_ONE = "full/obj16/one-to-one";
+	
+	public static final String MANY_TO_MANY = "full/obj16/many-to-many";
+	
+	public static final String ELEMENT_COLLECTION = "full/obj16/element-collection";
+	
+	public static final String EMBEDDED = "full/obj16/embedded";
+	
+	public static final String TRANSIENT = "full/obj16/transient";
+	
+	public static final String NULL_ATTRIBUTE_MAPPING = "full/obj16/null-attribute-mapping";
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/JptUiMessages.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/JptUiMessages.java
new file mode 100644
index 0000000..2d7c45f
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/JptUiMessages.java
@@ -0,0 +1,138 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2010 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.ui.internal;
+
+import org.eclipse.osgi.util.NLS;
+
+/**
+ * Localized messages used by Dali UI.
+ *
+ * @version 2.3
+ * @since 1.0
+ */
+public class JptUiMessages {
+
+	public static String ChooserPane_browseButton;
+	public static String AccessTypeComposite_access;
+	public static String AccessTypeComposite_field;
+	public static String AccessTypeComposite_property;
+	public static String AddPersistentAttributeDialog_attributeLabel;
+	public static String AddPersistentAttributeDialog_mappingLabel;
+	public static String AddPersistentAttributeDialog_noMappingKeyError;
+	public static String AddPersistentAttributeDialog_title;
+	public static String AddPersistentClassDialog_classDialog_message;
+	public static String AddPersistentClassDialog_classDialog_title;
+	public static String AddPersistentClassDialog_classLabel;
+	public static String AddPersistentClassDialog_classNotFoundWarning;
+	public static String AddPersistentClassDialog_duplicateClassWarning;
+	public static String AddPersistentClassDialog_mappingLabel;
+	public static String AddPersistentClassDialog_noClassError;
+	public static String AddPersistentClassDialog_noMappingKeyError;
+	public static String AddPersistentClassDialog_title;
+	public static String AddRemovePane_AddButtonText;
+	public static String AddRemovePane_RemoveButtonText;
+	public static String ClassChooserPane_dialogMessage;
+	public static String ClassChooserPane_dialogTitle;
+	public static String DatabaseSchemaWizardPage_title;
+	public static String DatabaseSchemaWizardPage_desc;
+	public static String DatabaseSchemaWizardPage_schemaSettings;
+	public static String DatabaseSchemaWizardPage_addConnectionToProject;
+	public static String DatabaseSchemaWizardPage_connectLink;
+	public static String DatabaseSchemaWizardPage_schema;
+	public static String DatabaseSchemaWizardPage_connectionInfo;
+	public static String DatabaseSchemaWizardPage_schemaInfo;
+	public static String EnumComboViewer_default;
+	public static String EnumComboViewer_defaultWithDefault;
+	public static String Error_openingEditor;
+	public static String General_browse;
+	public static String General_revert;
+	public static String General_deselectAll;
+	public static String General_selectAll;
+	public static String GenerateDDLWizard_title;
+	public static String GenerateEntitiesWizard_generateEntities;
+	public static String GenerateEntitiesWizardPage_chooseEntityTable;
+	public static String GenerateEntitiesWizardPage_entityNameColumn;
+	public static String GenerateEntitiesWizardPage_generateEntities;
+	public static String GenerateEntitiesWizardPage_synchronizeClasses;
+	public static String GenerateEntitiesWizardPage_tableColumn;
+	public static String GenerateEntitiesWizardPage_tables;
+	public static String GenericPlatformUiDialog_notSupportedMessageText;
+	public static String GenericPlatformUiDialog_notSupportedMessageTitle;
+	public static String JpaContent_label;
+	public static String JpaDetailsView_viewNotAvailable;
+	public static String JpaFacetWizardPage_addDriverLibraryLabel;
+	public static String JpaFacetWizardPage_connectionLabel;
+	public static String JpaFacetWizardPage_connectionLink;
+	public static String JpaFacetWizardPage_connectLink;
+	public static String JpaFacetWizardPage_createOrmXmlButton;
+	public static String JpaFacetWizardPage_defaultCatalogLabel;
+	public static String JpaFacetWizardPage_defaultSchemaLabel;
+	public static String JpaFacetWizardPage_description;
+	public static String JpaFacetWizardPage_discoverClassesButton;
+	public static String JpaFacetWizardPage_driverLibraryLabel;
+	public static String JpaFacetWizardPage_metamodelSourceFolderLink;
+	public static String JpaFacetWizardPage_jpaImplementationLabel;
+	public static String JpaFacetWizardPage_jpaPrefsLink;
+	public static String JpaFacetWizardPage_listClassesButton;
+	public static String JpaFacetWizardPage_metamodelLabel;
+	public static String JpaFacetWizardPage_none;
+	public static String JpaFacetWizardPage_overrideDefaultCatalogLabel;
+	public static String JpaFacetWizardPage_overrideDefaultSchemaLabel;
+	public static String JpaFacetWizardPage_persistentClassManagementLabel;
+	public static String JpaFacetWizardPage_platformLabel;
+	public static String JpaFacetWizardPage_specifyLibLabel;
+	public static String JpaFacetWizardPage_title;
+	public static String JpaFacetWizardPage_userLibsLink;
+	public static String JpaFacetWizardPage_userServerLibLabel;
+	public static String JpaStructureView_linkWithEditorDesc;
+	public static String JpaStructureView_linkWithEditorText;
+	public static String JpaStructureView_linkWithEditorTooltip;
+	public static String JpaStructureView_structureNotAvailable;
+	public static String JpaStructureView_numItemsSelected;
+	public static String MappingFileWizard_title;
+	public static String MappingFileWizardPage_title;
+	public static String MappingFileWizardPage_desc;
+	public static String MappingFileWizardPage_projectLabel;
+	public static String MappingFileWizardPage_sourceFolderLabel;
+	public static String MappingFileWizardPage_filePathLabel;
+	public static String MappingFileWizardPage_accessLabel;
+	public static String MappingFileWizardPage_addToPersistenceUnitButton;
+	public static String MappingFileWizardPage_persistenceUnitLabel;
+	public static String MappingFileWizardPage_incorrectSourceFolderError;
+	public static String MappingFileWizardPage_accessLabel_sourceFolderDialogTitle;
+	public static String MappingFileWizardPage_accessLabel_sourceFolderDialogDesc;
+	public static String NewJpaProjectWizard_firstPage_description;
+	public static String NewJpaProjectWizard_firstPage_title;
+	public static String NewJpaProjectWizard_title;
+	public static String OrmItemLabelProviderFactory_entityMappingsLabel;
+	public static String OverwriteConfirmerDialog_text;
+	public static String OverwriteConfirmerDialog_title;
+	public static String PackageChooserPane_dialogMessage;
+	public static String PackageChooserPane_dialogTitle;
+	public static String PersistenceItemLabelProviderFactory_persistenceLabel;
+	public static String EntitiesGenerator_jobName;
+	public static String JpaPreferencesPage_Description;
+	public static String JpaProblemSeveritiesPage_Description;
+	public static String JpaProblemSeveritiesPage_Error;
+	public static String JpaProblemSeveritiesPage_Ignore;
+	public static String JpaProblemSeveritiesPage_Info;
+	public static String JpaProblemSeveritiesPage_Warning;
+
+	private static final String BUNDLE_NAME = "jpt_ui"; //$NON-NLS-1$
+	private static final Class<?> BUNDLE_CLASS = JptUiMessages.class;
+	static {
+		NLS.initializeMessages(BUNDLE_NAME, BUNDLE_CLASS);
+	}
+
+	private JptUiMessages() {
+		throw new UnsupportedOperationException();
+	}
+
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/JptUiValidationPreferenceMessages.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/JptUiValidationPreferenceMessages.java
new file mode 100644
index 0000000..4a3fb3b
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/JptUiValidationPreferenceMessages.java
@@ -0,0 +1,192 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2010 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.ui.internal;
+
+import org.eclipse.osgi.util.NLS;
+
+public class JptUiValidationPreferenceMessages {
+
+	public static String PROJECT_LEVEL_CATEGORY;
+	public static String NO_JPA_PROJECT;
+	public static String PROJECT_NO_CONNECTION;
+	public static String PROJECT_INVALID_CONNECTION;
+	public static String PROJECT_INACTIVE_CONNECTION;
+	public static String PROJECT_NO_PERSISTENCE_XML;
+	
+	public static String XML_VERSION_NOT_LATEST;
+	
+	public static String PROJECT_MULTIPLE_PERSISTENCE_XML;
+	public static String PERSISTENCE_NO_PERSISTENCE_UNIT;
+	public static String PERSISTENCE_MULTIPLE_PERSISTENCE_UNITS;
+	public static String PERSISTENCE_XML_INVALID_CONTENT;
+
+	public static String PERSISTENCE_UNIT_LEVEL_CATEGORY;
+	public static String PERSISTENCE_UNIT_UNSPECIFIED_MAPPING_FILE;
+	public static String PERSISTENCE_UNIT_UNSUPPORTED_MAPPING_FILE_CONTENT;
+	public static String PERSISTENCE_UNIT_NONEXISTENT_MAPPING_FILE;
+	public static String PERSISTENCE_UNIT_INVALID_MAPPING_FILE;
+	public static String PERSISTENCE_UNIT_DUPLICATE_MAPPING_FILE;
+	public static String PERSISTENCE_UNIT_UNSPECIFIED_CLASS;
+	public static String PERSISTENCE_UNIT_NONEXISTENT_CLASS;
+	public static String PERSISTENCE_UNIT_INVALID_CLASS;
+	public static String PERSISTENCE_UNIT_DUPLICATE_CLASS;
+	public static String PERSISTENCE_UNIT_REDUNDANT_CLASS;
+	public static String PERSISTENCE_UNIT_DUPLICATE_JAR_FILE;
+	public static String PERSISTENCE_UNIT_UNSPECIFIED_JAR_FILE;
+	public static String PERSISTENCE_UNIT_JAR_FILE_DEPLOYMENT_PATH_WARNING;
+	public static String PERSISTENCE_UNIT_NONEXISTENT_JAR_FILE;
+	public static String MAPPING_FILE_EXTRANEOUS_PERSISTENCE_UNIT_DEFAULTS;
+	public static String PERSISTENT_TYPE_MAPPED_BUT_NOT_INCLUDED_IN_PERSISTENCE_UNIT;
+	public static String PERSISTENT_TYPE_ANNOTATED_BUT_NOT_INCLUDED_IN_PERSISTENCE_UNIT;
+	public static String PERSISTENT_TYPE_UNSPECIFIED_CLASS;
+	public static String PERSISTENT_TYPE_UNRESOLVED_CLASS;
+
+	public static String TYPE_LEVEL_CATEGORY;
+	public static String ENTITY_NO_PK;
+	public static String ENTITY_SINGLE_TABLE_DESCENDANT_DEFINES_TABLE;
+	public static String ENTITY_ABSTRACT_TABLE_PER_CLASS_DEFINES_TABLE;
+	public static String ENTITY_ABSTRACT_DISCRIMINATOR_VALUE_DEFINED;
+	public static String ENTITY_TABLE_PER_CLASS_DISCRIMINATOR_VALUE_DEFINED;
+	public static String ENTITY_NON_ROOT_DISCRIMINATOR_COLUMN_DEFINED;
+	public static String ENTITY_TABLE_PER_CLASS_DISCRIMINATOR_COLUMN_DEFINED;
+	public static String PERSISTENT_ATTRIBUTE_UNSPECIFIED_NAME;
+	public static String PERSISTENT_ATTRIBUTE_UNRESOLVED_NAME;
+	public static String PERSISTENT_ATTRIBUTE_INHERITED_ATTRIBUTES_NOT_SUPPORTED;
+	public static String PERSISTENT_ATTRIBUTE_INVALID_MAPPING;
+	public static String PERSISTENT_ATTRIBUTE_FINAL_FIELD;
+	public static String PERSISTENT_ATTRIBUTE_PUBLIC_FIELD;
+
+	public static String ATTRIBUTE_LEVEL_CATEGORY;
+	public static String MAPPING_UNRESOLVED_MAPPED_BY;
+	public static String MAPPING_INVALID_MAPPED_BY;
+	public static String MAPPING_MAPPED_BY_WITH_JOIN_TABLE;
+	public static String MAPPING_MAPPED_BY_ON_BOTH_SIDES;
+	public static String TARGET_ENTITY_NOT_DEFINED;
+	public static String TARGET_ENTITY_IS_NOT_AN_ENTITY;
+	public static String MAPS_ID_VALUE_NOT_SPECIFIED;
+	public static String MAPS_ID_VALUE_NOT_RESOLVED;
+	public static String MAPS_ID_VALUE_INVALID;
+	public static String ORDER_COLUMN_AND_ORDER_BY_BOTH_SPECIFIED;
+	public static String ELEMENT_COLLECTION_TARGET_CLASS_NOT_DEFINED;
+	public static String ELEMENT_COLLECTION_TARGET_CLASS_MUST_BE_EMBEDDABLE_OR_BASIC_TYPE;
+	public static String ELEMENT_COLLECTION_MAP_KEY_CLASS_NOT_DEFINED;
+	
+	public static String DATABASE_CATEGORY;
+	public static String TABLE_CATEGORY;
+	public static String COLUMN_CATEGORY;
+	public static String OVERRIDES_CATEGORY;
+	public static String IMPLIED_ATTRIBUTE_LEVEL_CATEGORY;
+	
+	public static String TABLE_UNRESOLVED_CATALOG;
+	public static String TABLE_UNRESOLVED_SCHEMA;
+	public static String TABLE_UNRESOLVED_NAME;
+	public static String SECONDARY_TABLE_UNRESOLVED_CATALOG;
+	public static String SECONDARY_TABLE_UNRESOLVED_SCHEMA;
+	public static String SECONDARY_TABLE_UNRESOLVED_NAME;
+	public static String JOIN_TABLE_UNRESOLVED_CATALOG;
+	public static String JOIN_TABLE_UNRESOLVED_SCHEMA;
+	public static String JOIN_TABLE_UNRESOLVED_NAME;
+	public static String COLUMN_TABLE_NOT_VALID;
+	public static String COLUMN_UNRESOLVED_TABLE;
+	public static String COLUMN_UNRESOLVED_NAME;
+	public static String JOIN_COLUMN_TABLE_NOT_VALID;
+	public static String JOIN_COLUMN_UNRESOLVED_NAME;
+	public static String JOIN_COLUMN_NAME_MUST_BE_SPECIFIED_MULTIPLE_JOIN_COLUMNS;
+	public static String JOIN_COLUMN_UNRESOLVED_REFERENCED_COLUMN_NAME;
+	public static String JOIN_COLUMN_REFERENCED_COLUMN_NAME_MUST_BE_SPECIFIED_MULTIPLE_JOIN_COLUMNS;
+	public static String INVERSE_JOIN_COLUMN_TABLE_NOT_VALID;
+	public static String INVERSE_JOIN_COLUMN_UNRESOLVED_NAME;
+	public static String INVERSE_JOIN_COLUMN_NAME_MUST_BE_SPECIFIED_MULTIPLE_JOIN_COLUMNS;
+	public static String INVERSE_JOIN_COLUMN_UNRESOLVED_REFERENCED_COLUMN_NAME;
+	public static String INVERSE_JOIN_COLUMN_REFERENCED_COLUMN_NAME_MUST_BE_SPECIFIED_MULTIPLE_JOIN_COLUMNS;
+	public static String PRIMARY_KEY_JOIN_COLUMN_UNRESOLVED_NAME;
+	public static String PRIMARY_KEY_JOIN_COLUMN_UNRESOLVED_REFERENCED_COLUMN_NAME;
+	public static String PRIMARY_KEY_JOIN_COLUMN_NAME_MUST_BE_SPECIFIED_MULTIPLE_JOIN_COLUMNS;
+	public static String PRIMARY_KEY_JOIN_COLUMN_REFERENCED_COLUMN_NAME_MUST_BE_SPECIFIED_MULTIPLE_JOIN_COLUMNS;
+	public static String VIRTUAL_PRIMARY_KEY_JOIN_COLUMN_UNRESOLVED_NAME;
+	public static String VIRTUAL_PRIMARY_KEY_JOIN_COLUMN_UNRESOLVED_REFERENCED_COLUMN_NAME;
+	public static String VIRTUAL_SECONDARY_TABLE_PRIMARY_KEY_JOIN_COLUMN_UNRESOLVED_NAME;
+	public static String VIRTUAL_SECONDARY_TABLE_PRIMARY_KEY_JOIN_COLUMN_UNRESOLVED_REFERENCED_COLUMN_NAME;
+	public static String VIRTUAL_SECONDARY_TABLE_PRIMARY_KEY_JOIN_COLUMN_NAME_MUST_BE_SPECIFIED_MULTIPLE_JOIN_COLUMNS;
+	public static String VIRTUAL_SECONDARY_TABLE_PRIMARY_KEY_JOIN_COLUMN_REFERENCED_COLUMN_NAME_MUST_BE_SPECIFIED_MULTIPLE_JOIN_COLUMNS;
+	public static String MAP_KEY_COLUMN_TABLE_NOT_VALID;
+	public static String VIRTUAL_MAP_KEY_ATTRIBUTE_OVERRIDE_COLUMN_TABLE_NOT_VALID;
+	
+	public static String COLLECTION_TABLE_UNRESOLVED_CATALOG;
+	public static String COLLECTION_TABLE_UNRESOLVED_SCHEMA;
+	public static String COLLECTION_TABLE_UNRESOLVED_NAME;
+	public static String ORDER_COLUMN_UNRESOLVED_NAME;
+	
+	public static String VIRTUAL_ATTRIBUTE_JOIN_TABLE_UNRESOLVED_CATALOG;
+	public static String VIRTUAL_ATTRIBUTE_JOIN_TABLE_UNRESOLVED_SCHEMA;
+	public static String VIRTUAL_ATTRIBUTE_JOIN_TABLE_UNRESOLVED_NAME;
+	public static String VIRTUAL_ATTRIBUTE_OVERRIDE_COLUMN_TABLE_NOT_VALID;
+	public static String VIRTUAL_ATTRIBUTE_ATTRIBUTE_OVERRIDE_COLUMN_TABLE_NOT_VALID;
+	public static String VIRTUAL_ATTRIBUTE_COLUMN_TABLE_NOT_VALID;
+	public static String VIRTUAL_ATTRIBUTE_ATTRIBUTE_OVERRIDE_COLUMN_UNRESOLVED_NAME;
+	public static String VIRTUAL_ATTRIBUTE_COLUMN_UNRESOLVED_NAME;
+	public static String VIRTUAL_ATTRIBUTE_OVERRIDE_COLUMN_UNRESOLVED_NAME;
+	public static String VIRTUAL_ATTRIBUTE_JOIN_COLUMN_UNRESOLVED_TABLE;
+	public static String VIRTUAL_ATTRIBUTE_JOIN_COLUMN_UNRESOLVED_NAME;
+	public static String VIRTUAL_ATTRIBUTE_JOIN_COLUMN_NAME_MUST_BE_SPECIFIED_MULTIPLE_JOIN_COLUMNS;
+	public static String VIRTUAL_ATTRIBUTE_JOIN_COLUMN_UNRESOLVED_REFERENCED_COLUMN_NAME;
+	public static String VIRTUAL_ATTRIBUTE_JOIN_COLUMN_REFERENCED_COLUMN_NAME_MUST_BE_SPECIFIED_MULTIPLE_JOIN_COLUMNS;
+	public static String VIRTUAL_ATTRIBUTE_TARGET_ENTITY_IS_NOT_AN_ENTITY;
+	public static String VIRTUAL_ATTRIBUTE_TARGET_ENTITY_NOT_DEFINED;
+	public static String VIRTUAL_ATTRIBUTE_COLLECTION_TABLE_UNRESOLVED_CATALOG;
+	public static String VIRTUAL_ATTRIBUTE_COLLECTION_TABLE_UNRESOLVED_SCHEMA;
+	public static String VIRTUAL_ATTRIBUTE_COLLECTION_TABLE_UNRESOLVED_NAME;
+	public static String VIRTUAL_ATTRIBUTE_ORDER_COLUMN_UNRESOLVED_NAME;
+	public static String VIRTUAL_ATTRIBUTE_ELEMENT_COLLECTION_TARGET_CLASS_NOT_DEFINED;
+	public static String VIRTUAL_ATTRIBUTE_ELEMENT_COLLECTION_TARGET_CLASS_MUST_BE_EMBEDDABLE_OR_BASIC_TYPE;
+	public static String VIRTUAL_ATTRIBUTE_ELEMENT_COLLECTION_MAP_KEY_CLASS_NOT_DEFINED;
+	public static String VIRTUAL_ATTRIBUTE_JOIN_COLUMN_TABLE_NOT_VALID;
+	public static String VIRTUAL_ATTRIBUTE_INVERSE_JOIN_COLUMN_TABLE_NOT_VALID;
+	public static String VIRTUAL_ATTRIBUTE_INVERSE_JOIN_COLUMN_UNRESOLVED_NAME;
+	public static String VIRTUAL_ATTRIBUTE_INVERSE_JOIN_COLUMN_NAME_MUST_BE_SPECIFIED_MULTIPLE_JOIN_COLUMNS;
+	public static String VIRTUAL_ATTRIBUTE_INVERSE_JOIN_COLUMN_UNRESOLVED_REFERENCED_COLUMN_NAME;
+	public static String VIRTUAL_ATTRIBUTE_INVERSE_JOIN_COLUMN_REFERENCED_COLUMN_NAME_MUST_BE_SPECIFIED_MULTIPLE_JOIN_COLUMNS;
+	public static String VIRTUAL_ATTRIBUTE_MAP_KEY_COLUMN_TABLE_NOT_VALID;
+	public static String VIRTUAL_ATTRIBUTE_MAP_KEY_ATTRIBUTE_OVERRIDE_COLUMN_TABLE_NOT_VALID;
+	
+	public static String VIRTUAL_ASSOCIATION_OVERRIDE_JOIN_COLUMN_UNRESOLVED_NAME;
+	public static String VIRTUAL_ASSOCIATION_OVERRIDE_JOIN_COLUMN_UNRESOLVED_REFERENCED_COLUMN_NAME;
+	public static String VIRTUAL_ASSOCIATION_OVERRIDE_JOIN_COLUMN_TABLE_NOT_VALID;
+	public static String VIRTUAL_ASSOCIATION_OVERRIDE_JOIN_COLUMN_NAME_MUST_BE_SPECIFIED_MULTIPLE_JOIN_COLUMNS;
+	public static String VIRTUAL_ASSOCIATION_OVERRIDE_JOIN_COLUMN_REFERENCED_COLUMN_NAME_MUST_BE_SPECIFIED_MULTIPLE_JOIN_COLUMNS;
+	public static String VIRTUAL_ATTRIBUTE_ASSOCIATION_OVERRIDE_JOIN_COLUMN_TABLE_NOT_VALID;
+	public static String VIRTUAL_ATTRIBUTE_ASSOCIATION_OVERRIDE_JOIN_COLUMN_UNRESOLVED_NAME;
+	public static String VIRTUAL_ATTRIBUTE_ASSOCIATION_OVERRIDE_JOIN_COLUMN_REFERENCED_COLUMN_UNRESOLVED_NAME;
+	public static String VIRTUAL_ATTRIBUTE_ASSOCIATION_OVERRIDE_JOIN_COLUMN_NAME_MUST_BE_SPECIFIED_MULTIPLE_JOIN_COLUMNS;
+	public static String VIRTUAL_ATTRIBUTE_ASSOCIATION_OVERRIDE_JOIN_COLUMN_REFERENCED_COLUMN_NAME_MUST_BE_SPECIFIED_MULTIPLE_JOIN_COLUMNS;
+
+	public static String INHERITANCE_CATEGORY;
+	public static String DISCRIMINATOR_COLUMN_UNRESOLVED_NAME;
+	public static String ENTITY_TABLE_PER_CLASS_NOT_SUPPORTED_ON_PLATFORM;
+	public static String ENTITY_TABLE_PER_CLASS_NOT_PORTABLE_ON_PLATFORM;
+
+	public static String QUERIES_GENERATORS_CATEGORY;
+	public static String GENERATOR_DUPLICATE_NAME;
+	public static String ID_MAPPING_UNRESOLVED_GENERATOR_NAME;
+	public static String GENERATED_VALUE_UNRESOLVED_GENERATOR;
+	public static String QUERY_DUPLICATE_NAME;
+
+	private static final String BUNDLE_NAME = "jpt_ui_validation_preferences"; //$NON-NLS-1$
+	private static final Class<?> BUNDLE_CLASS = JptUiValidationPreferenceMessages.class;
+	static {
+		NLS.initializeMessages(BUNDLE_NAME, BUNDLE_CLASS);
+	}
+
+	private JptUiValidationPreferenceMessages() {
+		throw new UnsupportedOperationException();
+	}
+
+
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/Tracing.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/Tracing.java
new file mode 100644
index 0000000..d262085
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/Tracing.java
@@ -0,0 +1,161 @@
+/*******************************************************************************
+ * Copyright (c) 2008 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.ui.internal;
+
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.jpt.ui.JptUiPlugin;
+
+/**
+ * This tracing class manages to convert the string value into boolean values or
+ * integer values that are associated with the tracing debug flags. Those flags
+ * are specified in the .options file. The supported keys are defined here as
+ * constants for quick reference.
+ *
+ * @version 2.0
+ * @since 2.0
+ */
+@SuppressWarnings("nls")
+public final class Tracing
+{
+	/**
+	 * A constant used to retrieve the value associated with "/debug".
+	 */
+	public static final String DEBUG = "/debug";
+
+	/**
+	 * A constant used to retrieve the value associated with "/debug/ui/db".
+	 */
+	public static final String UI_DB = "/debug/ui/db";
+
+	/**
+	 * A constant used to retrieve the value associated with "/debug/ui/detailsView".
+	 */
+	public static final String UI_DETAILS_VIEW = "/debug/ui/detailsView";
+
+	/**
+	 * A constant used to retrieve the value associated with "/debug/ui/layout".
+	 */
+	public static final String UI_LAYOUT = "/debug/ui/layout";
+
+	/**
+	 * A constant used to retrieve the value associated with "/unit-tests".
+	 */
+	public static final String UNIT_TESTS = "/unit-tests";
+
+	/**
+	 * Can't instantiate this <code>Tracing</code> class.
+	 */
+	private Tracing()
+	{
+		super();
+		throw new UnsupportedOperationException("Tracing cannot be instantiated");
+	}
+
+	/**
+	 * Retrieves the debug value associated with the given flag. The default
+	 * value is <code>false</code>.
+	 *
+	 * @param flag The flag to retrieve the debug value, which should be
+	 * contained in the .options file, the flag should start with "/"
+	 * @return <code>true</code> if the given flag is active; <code>false</code>
+	 * otherwise
+	 */
+	public static boolean booleanDebugOption(String flag)
+	{
+		return booleanDebugOption(flag, false);
+	}
+
+	/**
+	 * Retrieves the debug value associated with the given flag.
+	 *
+	 * @param flag The flag to retrieve the debug value, which should be
+	 * contained in the .options file, the flag should start with "/"
+	 * @param defaultValue The default value if the value associated with the
+	 * given flag could not be found
+	 * @return <code>true</code> if the given flag is active; <code>false</code>
+	 * otherwise
+	 */
+	public static boolean booleanDebugOption(String flag, boolean defaultValue)
+	{
+		String string = Platform.getDebugOption(JptUiPlugin.PLUGIN_ID + flag);
+		return (string == null) ? defaultValue : Boolean.parseBoolean(string.trim());
+	}
+
+	/**
+	 * Retrieves the debug value associated with the given flag. The default value
+	 * is 0.
+	 *
+	 * @param flag The flag to retrieve the debug value, which should be
+	 * contained in the .options file, the flag should start with "/"
+	 * @return The value associated with the given flag, or the given default
+	 * value
+	 */
+	public static int intDebugOption(String flag)
+	{
+		return intDebugOption(flag, 0);
+	}
+
+	/**
+	 * Retrieves the debug value associated with the given flag.
+	 *
+	 * @param flag The flag to retrieve the debug value, which should be
+	 * contained in the .options file, the flag should start with "/"
+	 * @param defaultValue The default value if the value associated with the
+	 * given flag could not be found
+	 * @return The value associated with the given flag, or the given default
+	 * value
+	 */
+	public static int intDebugOption(String flag, int defaultValue)
+	{
+		String string = Platform.getDebugOption(JptUiPlugin.PLUGIN_ID + flag);
+		return (string == null) ?  defaultValue : Integer.parseInt(string);
+	}
+
+	/**
+	 * Logs the given messages, appends it with this plug-in id.
+	 *
+	 * @param message The message to be logged
+	 */
+	public static void log(String message)
+	{
+		System.out.print("[" + JptUiPlugin.PLUGIN_ID + "] ");
+		System.out.println(message);
+	}
+
+	/**
+	 * Retrieves the debug value associated with the given flag. The default value
+	 * is an empty string.
+	 *
+	 * @param flag The flag to retrieve the debug value, which should be
+	 * contained in the .options file, the flag should start with "/"
+	 * @return The value associated with the given flag, or the given default
+	 * value
+	 */
+	public static String stringDebugOption(String flag)
+	{
+		return stringDebugOption(flag, "");
+	}
+
+	/**
+	 * Retrieves the debug value associated with the given flag.
+	 *
+	 * @param flag The flag to retrieve the debug value, which should be
+	 * contained in the .options file, the flag should start with "/"
+	 * @param defaultValue The default value if the value associated with the
+	 * given flag could not be found
+	 * @return The value associated with the given flag, or the given default
+	 * value
+	 */
+	public static String stringDebugOption(String flag, String defaultValue)
+	{
+		String string = Platform.getDebugOption(JptUiPlugin.PLUGIN_ID + flag);
+		return (string != null) ? string : defaultValue;
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/actions/GenerateDDLAction.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/actions/GenerateDDLAction.java
new file mode 100644
index 0000000..b2e675f
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/actions/GenerateDDLAction.java
@@ -0,0 +1,27 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2009 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.ui.internal.actions;
+
+import org.eclipse.jpt.core.JpaProject;
+
+/**
+ *  GenerateDDLAction
+ */
+public class GenerateDDLAction extends ProjectAction {
+	
+	public GenerateDDLAction() {
+		super();
+	}
+
+	@Override
+	protected void execute(JpaProject project) {
+        this.getJpaPlatformUi(project).generateDDL(project, this.getCurrentSelection());
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/actions/GenerateEntitiesAction.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/actions/GenerateEntitiesAction.java
new file mode 100644
index 0000000..30d2de5
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/actions/GenerateEntitiesAction.java
@@ -0,0 +1,26 @@
+/*******************************************************************************
+* Copyright (c) 2007, 2009 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.ui.internal.actions;
+
+import org.eclipse.jpt.core.JpaProject;
+
+/**
+ *  GenerateEntitiesAction
+ */
+public class GenerateEntitiesAction extends ProjectAction {
+	public GenerateEntitiesAction() {
+		super();
+	}
+
+	@Override
+	protected void execute(JpaProject project) {
+        this.getJpaPlatformUi(project).generateEntities(project, this.getCurrentSelection());
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/actions/MigrateJavaProjectAction.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/actions/MigrateJavaProjectAction.java
new file mode 100644
index 0000000..88c7ef4
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/actions/MigrateJavaProjectAction.java
@@ -0,0 +1,82 @@
+/*******************************************************************************
+ *  Copyright (c) 2008  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.ui.internal.actions;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.wizard.WizardDialog;
+import org.eclipse.jpt.core.JptCorePlugin;
+import org.eclipse.jpt.ui.JptUiPlugin;
+import org.eclipse.jst.j2ee.internal.project.J2EEProjectUtilities;
+import org.eclipse.jst.j2ee.project.facet.JavaProjectMigrationOperation;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.ui.IObjectActionDelegate;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.wst.common.project.facet.core.IFacetedProject;
+import org.eclipse.wst.common.project.facet.core.IFacetedProjectWorkingCopy;
+import org.eclipse.wst.common.project.facet.core.IProjectFacetVersion;
+import org.eclipse.wst.common.project.facet.core.ProjectFacetsManager;
+import org.eclipse.wst.common.project.facet.ui.ModifyFacetedProjectWizard;
+
+public class MigrateJavaProjectAction implements IObjectActionDelegate
+{
+	private ISelection currentSelection;
+	
+	
+	public MigrateJavaProjectAction() {
+		super();
+	}
+	
+	
+	public void setActivePart(IAction action, IWorkbenchPart targetPart) {
+		// do nothing
+	}
+	
+	public void selectionChanged(IAction action, ISelection selection) {
+		this.currentSelection = selection;
+	}
+	
+	public void run(IAction action) {
+		// This action is currently enabled only for a singly selected, java,
+		// non-faceted IProject
+		IProject project = (IProject) ((IStructuredSelection) currentSelection).getFirstElement();
+		execute(project);
+	}
+	
+	private void execute(IProject project) {
+		// add facets nature, java facet, and utility facet to project
+		JavaProjectMigrationOperation operation = 
+			J2EEProjectUtilities.createFlexJavaProjectForProjectOperation(project, false);
+		operation.execute(null, null);
+		
+		IFacetedProject facetedProject;
+		try {
+			// get the faceted project
+			facetedProject = ProjectFacetsManager.create(project);
+		}
+		catch (CoreException ce) {
+			JptUiPlugin.log(ce);
+			return;
+		}
+		
+		// launch the UI with JPA facet preselected
+		final ModifyFacetedProjectWizard wizard = new ModifyFacetedProjectWizard(facetedProject);
+		IFacetedProjectWorkingCopy facetedProjectWorkingCopy = wizard.getFacetedProjectWorkingCopy();
+		IProjectFacetVersion jpa1_0 = ProjectFacetsManager.getProjectFacet(JptCorePlugin.FACET_ID).getDefaultVersion();
+		facetedProjectWorkingCopy.addProjectFacet(jpa1_0);
+		
+		final WizardDialog dialog = new WizardDialog(Display.getCurrent().getActiveShell(), wizard);
+		dialog.open();
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/actions/OpenJpaResourceAction.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/actions/OpenJpaResourceAction.java
new file mode 100644
index 0000000..bba8a40
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/actions/OpenJpaResourceAction.java
@@ -0,0 +1,101 @@
+/*******************************************************************************
+ *  Copyright (c) 2008, 2009  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.ui.internal.actions;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.content.IContentType;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jpt.core.JpaStructureNode;
+import org.eclipse.jpt.core.context.JpaContextNode;
+import org.eclipse.jpt.core.context.JpaRootContextNode;
+import org.eclipse.jpt.ui.internal.JptUiMessages;
+import org.eclipse.jpt.ui.internal.selection.DefaultJpaSelection;
+import org.eclipse.jpt.ui.internal.selection.JpaSelectionManager;
+import org.eclipse.jpt.ui.internal.selection.SelectionManagerFactory;
+import org.eclipse.ui.IEditorDescriptor;
+import org.eclipse.ui.IEditorRegistry;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.actions.BaseSelectionListenerAction;
+import org.eclipse.ui.ide.IDE;
+import org.eclipse.ui.part.FileEditorInput;
+
+public class OpenJpaResourceAction extends BaseSelectionListenerAction
+{
+	private JpaContextNode selectedNode;
+	
+	
+	public OpenJpaResourceAction() {
+		super("Open");   //$NON-NLS-1$
+	}
+	
+	
+	@Override
+	public boolean updateSelection(IStructuredSelection s) {
+		selectedNode = null;
+		
+		if (! super.updateSelection(s)) {
+			return false;
+		}
+		
+		if (s.size() != 1) {
+			return false;
+		}
+		
+		if (s.getFirstElement() instanceof JpaRootContextNode) {
+			return false;
+		}
+		
+		selectedNode = (JpaContextNode) s.getFirstElement();
+
+		return true;
+	}
+	
+	@Override
+	public void run() {
+		if (! isEnabled()) {
+			return;
+		}
+		
+		IResource resource = selectedNode.getResource();
+		
+		if (resource != null && resource.exists() && resource.getType() == IResource.FILE) {
+			openEditor((IFile) resource);
+				
+			
+			if (selectedNode instanceof JpaStructureNode) {
+				JpaSelectionManager selectionManager =
+					SelectionManagerFactory.getSelectionManager(PlatformUI.getWorkbench().getActiveWorkbenchWindow());
+				selectionManager.select(new DefaultJpaSelection((JpaStructureNode) selectedNode), null);
+			}
+		}
+	}
+	
+	protected void openEditor(IFile file) {
+		IEditorRegistry registry = PlatformUI.getWorkbench().getEditorRegistry();
+		IContentType contentType = IDE.getContentType(file);
+		IEditorDescriptor editorDescriptor = registry.getDefaultEditor(file.getName(), contentType);
+		if (editorDescriptor == null) {
+			return;  // no editor associated...
+		}
+		
+		IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
+		
+		try {
+			page.openEditor(new FileEditorInput(file), editorDescriptor.getId());
+		} 
+		catch (Exception e) {
+			MessageDialog.openError(page.getWorkbenchWindow().getShell(), JptUiMessages.Error_openingEditor, e.getMessage());
+		}
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/actions/ProjectAction.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/actions/ProjectAction.java
new file mode 100644
index 0000000..115c7e1
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/actions/ProjectAction.java
@@ -0,0 +1,94 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2009 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.ui.internal.actions;
+
+import java.util.Iterator;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jpt.core.JpaProject;
+import org.eclipse.jpt.core.JptCorePlugin;
+import org.eclipse.jpt.ui.JpaPlatformUi;
+import org.eclipse.jpt.ui.internal.platform.JpaPlatformUiRegistry;
+import org.eclipse.ui.IObjectActionDelegate;
+import org.eclipse.ui.IWorkbenchPart;
+
+/**
+ * Override any of the #execute() methods.
+ */
+public abstract class ProjectAction implements IObjectActionDelegate {
+
+	private ISelection currentSelection;
+    
+
+	public ProjectAction() {
+		super();
+	}
+
+	public void setActivePart(IAction action, IWorkbenchPart targetPart) {
+		// do nothing
+	}
+
+	public void selectionChanged(IAction action, ISelection selection) {
+        this.currentSelection = selection;
+	}
+
+	protected IStructuredSelection getCurrentSelection() {
+		if (this.currentSelection instanceof IStructuredSelection) {
+			return (IStructuredSelection) this.currentSelection;
+		}
+		return null;
+	}
+	
+	public void run(IAction action) {
+		if (this.currentSelection instanceof IStructuredSelection) {
+			for (Iterator stream = ((IStructuredSelection) this.currentSelection).iterator(); stream.hasNext(); ) {
+				this.execute(stream.next());
+			}
+		}
+	}
+
+	protected void execute(Object selection) {
+		IProject project = this.projectFromSelection(selection);
+		if (project != null) {
+			this.execute(project);
+		}
+	}
+
+	protected IProject projectFromSelection(Object selection) {
+		if (selection instanceof IProject) {
+			return (IProject) selection;
+		}
+		if (selection instanceof IJavaProject) {
+			return ((IJavaProject) selection).getProject();
+		}
+		return null;
+	}
+
+	protected JpaPlatformUi getJpaPlatformUi(JpaProject project) {
+		String coreJpaPlatformId = project.getJpaPlatform().getId();
+        return JpaPlatformUiRegistry.instance().getJpaPlatformUi(coreJpaPlatformId); 
+	}
+	
+	protected void execute(IProject project) {
+		JpaProject jpaProject = JptCorePlugin.getJpaProject(project);
+		if (jpaProject == null) {
+			return;
+		}
+		this.execute(jpaProject);
+	}
+
+	protected void execute(JpaProject project) {
+		throw new UnsupportedOperationException();
+	}
+
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/actions/SynchronizeClassesAction.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/actions/SynchronizeClassesAction.java
new file mode 100644
index 0000000..6e0a10e
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/actions/SynchronizeClassesAction.java
@@ -0,0 +1,49 @@
+/*******************************************************************************
+ *  Copyright (c) 2007, 2008 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.ui.internal.actions;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.jpt.core.context.persistence.PersistenceXml;
+import org.eclipse.jpt.core.internal.synch.SynchronizeClassesJob;
+import org.eclipse.ui.IObjectActionDelegate;
+import org.eclipse.ui.IWorkbenchPart;
+
+public class SynchronizeClassesAction 
+	implements IObjectActionDelegate 
+{
+	private IFile file;
+	
+	public void setActivePart(IAction action, IWorkbenchPart targetPart) {
+		// no-op for now
+	}
+
+	public void run(IAction action) {
+		SynchronizeClassesJob job = new SynchronizeClassesJob(file);
+		job.schedule();
+	}
+
+	public void selectionChanged(IAction action, ISelection selection) {
+		// Action is contributed for IFile's named "persistence.xml" and
+		// for PeristenceXml objects.
+		// There is always only one element in actual selection.
+		Object selectedObject = ((StructuredSelection) selection).getFirstElement();
+		
+		if (selectedObject instanceof IFile) {
+			file = (IFile) selectedObject;
+		}
+		else if (selectedObject instanceof PersistenceXml) {
+			file = (IFile) ((PersistenceXml) selectedObject).getResource();
+		}
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/commands/AddPersistentAttributeToXmlAndMapHandler.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/commands/AddPersistentAttributeToXmlAndMapHandler.java
new file mode 100644
index 0000000..3f944e9
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/commands/AddPersistentAttributeToXmlAndMapHandler.java
@@ -0,0 +1,69 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 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.ui.internal.commands;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.eclipse.core.commands.AbstractHandler;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jpt.core.context.orm.OrmPersistentAttribute;
+import org.eclipse.jpt.core.context.orm.OrmPersistentType;
+import org.eclipse.jpt.ui.internal.dialogs.AddPersistentAttributeToXmlAndMapDialog;
+import org.eclipse.jpt.ui.internal.selection.DefaultJpaSelection;
+import org.eclipse.jpt.ui.internal.selection.JpaSelectionManager;
+import org.eclipse.jpt.ui.internal.selection.SelectionManagerFactory;
+import org.eclipse.jpt.utility.internal.CollectionTools;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.handlers.HandlerUtil;
+
+public class AddPersistentAttributeToXmlAndMapHandler extends AbstractHandler
+{
+	@SuppressWarnings("unchecked")
+	public Object execute(ExecutionEvent executionEvent) throws ExecutionException {
+		final IWorkbenchWindow window = 
+			HandlerUtil.getActiveWorkbenchWindowChecked(executionEvent);
+		
+		final List<OrmPersistentAttribute> newAttributes = new ArrayList<OrmPersistentAttribute>();
+		
+		IStructuredSelection selection 
+			= (IStructuredSelection) HandlerUtil.getCurrentSelectionChecked(executionEvent);
+		
+		
+		// only applies for multiply selected OrmPersistentAttribute objects in a tree
+		for (OrmPersistentAttribute attribute : (Iterable<OrmPersistentAttribute>) CollectionTools.iterable(selection.iterator())) {
+			OrmPersistentType type = attribute.getOwningPersistentType();
+			String attributeName = attribute.getName();
+			
+			AddPersistentAttributeToXmlAndMapDialog dialog = new AddPersistentAttributeToXmlAndMapDialog(window.getShell(), attribute);
+			dialog.create();
+			dialog.setBlockOnOpen(true);
+			dialog.open();
+			
+			OrmPersistentAttribute newAttribute = type.getAttributeNamed(attributeName);
+			if (newAttribute != null) {
+				newAttributes.add(newAttribute);
+			}
+		}
+		
+		if (newAttributes.size() == 1) {
+			window.getShell().getDisplay().asyncExec(
+				new Runnable() {
+					public void run() {
+						JpaSelectionManager selectionManager = SelectionManagerFactory.getSelectionManager(window);
+						selectionManager.select(new DefaultJpaSelection(newAttributes.get(0)), null);
+					}
+				});
+		}
+		
+		return null;
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/commands/AddPersistentAttributeToXmlHandler.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/commands/AddPersistentAttributeToXmlHandler.java
new file mode 100644
index 0000000..0b54dba
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/commands/AddPersistentAttributeToXmlHandler.java
@@ -0,0 +1,62 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2010 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.ui.internal.commands;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.eclipse.core.commands.AbstractHandler;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jpt.core.context.orm.OrmPersistentAttribute;
+import org.eclipse.jpt.core.context.orm.OrmPersistentType;
+import org.eclipse.jpt.ui.internal.selection.DefaultJpaSelection;
+import org.eclipse.jpt.ui.internal.selection.JpaSelectionManager;
+import org.eclipse.jpt.ui.internal.selection.SelectionManagerFactory;
+import org.eclipse.jpt.utility.internal.CollectionTools;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.handlers.HandlerUtil;
+
+public class AddPersistentAttributeToXmlHandler extends AbstractHandler
+{	
+	@SuppressWarnings("unchecked")
+	public Object execute(ExecutionEvent executionEvent) throws ExecutionException {
+		final IWorkbenchWindow window = 
+			HandlerUtil.getActiveWorkbenchWindowChecked(executionEvent);
+		
+		final List<OrmPersistentAttribute> newAttributes = new ArrayList<OrmPersistentAttribute>();
+		
+		IStructuredSelection selection = 
+			(IStructuredSelection) HandlerUtil.getCurrentSelectionChecked(executionEvent);
+		
+		// only applies for multiply selected OrmPersistentAttribute objects in a tree
+		for (OrmPersistentAttribute attribute : (Iterable<OrmPersistentAttribute>) CollectionTools.iterable(selection.iterator())) {
+			OrmPersistentType type = attribute.getOwningPersistentType();
+			String attributeName = attribute.getName();
+			attribute.makeSpecified();
+			OrmPersistentAttribute newAttribute = type.getAttributeNamed(attributeName);
+			if (newAttribute != null) {
+				newAttributes.add(newAttribute);
+			}
+		}
+		
+		if (newAttributes.size() == 1) {
+			window.getShell().getDisplay().asyncExec(
+				new Runnable() {
+					public void run() {
+						JpaSelectionManager selectionManager = SelectionManagerFactory.getSelectionManager(window);
+						selectionManager.select(new DefaultJpaSelection(newAttributes.get(0)), null);
+					}
+				});
+		}
+		
+		return null;
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/commands/AddPersistentClassHandler.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/commands/AddPersistentClassHandler.java
new file mode 100644
index 0000000..d91ba4b
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/commands/AddPersistentClassHandler.java
@@ -0,0 +1,57 @@
+/*******************************************************************************
+ *  Copyright (c) 2008  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.ui.internal.commands;
+
+import org.eclipse.core.commands.AbstractHandler;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jpt.core.context.orm.EntityMappings;
+import org.eclipse.jpt.core.context.orm.OrmPersistentType;
+import org.eclipse.jpt.ui.internal.dialogs.AddPersistentClassDialog;
+import org.eclipse.jpt.ui.internal.selection.DefaultJpaSelection;
+import org.eclipse.jpt.ui.internal.selection.JpaSelectionManager;
+import org.eclipse.jpt.ui.internal.selection.SelectionManagerFactory;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.handlers.HandlerUtil;
+
+public class AddPersistentClassHandler extends AbstractHandler
+{
+	public Object execute(ExecutionEvent executionEvent) throws ExecutionException {
+		final IWorkbenchWindow window = 
+			HandlerUtil.getActiveWorkbenchWindowChecked(executionEvent);
+		
+		IStructuredSelection selection 
+			= (IStructuredSelection) HandlerUtil.getCurrentSelectionChecked(executionEvent);
+		
+		// only applies for a singly selected EntityMappings object in a tree
+		EntityMappings entityMappings =
+			(EntityMappings) selection.getFirstElement();
+		
+		AddPersistentClassDialog dialog = 
+			new AddPersistentClassDialog(window.getShell(), entityMappings);
+		dialog.create();
+		dialog.setBlockOnOpen(true);
+		final OrmPersistentType type = dialog.openAndReturnType();
+		
+		if (type != null) {
+			window.getShell().getDisplay().asyncExec(
+				new Runnable() {
+					public void run() {
+						JpaSelectionManager selectionManager = SelectionManagerFactory.getSelectionManager(window);
+						selectionManager.select(new DefaultJpaSelection(type), null);
+					}
+				});
+		}
+		
+		return null;
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/commands/PersistentAttributeMapAsHandler.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/commands/PersistentAttributeMapAsHandler.java
new file mode 100644
index 0000000..0b829e7
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/commands/PersistentAttributeMapAsHandler.java
@@ -0,0 +1,143 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2009 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.ui.internal.commands;
+
+import java.util.Map;
+import org.eclipse.core.commands.AbstractHandler;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jpt.core.context.PersistentAttribute;
+import org.eclipse.ui.ISources;
+import org.eclipse.ui.IViewPart;
+import org.eclipse.ui.commands.IElementUpdater;
+import org.eclipse.ui.handlers.HandlerUtil;
+import org.eclipse.ui.menus.UIElement;
+import org.eclipse.ui.services.IEvaluationService;
+
+/**
+ * This handler is responsible to change the mapping type of the selected
+ * <code>PersistentAttribute</code>.
+ * <p>
+ * This handler is defined in the JPT plugin.xml. It will be invoked by the
+ * mapping action dynamically created by the <code>PersistentAttributeMapAsContribution</code>.
+ *
+ * @see PersistentAttribute
+ * @see PersistentAttributeMapAsContribution
+ *
+ * @version 2.0
+ * @since 2.0
+ */
+@SuppressWarnings("nls")
+public class PersistentAttributeMapAsHandler extends AbstractHandler
+	implements IElementUpdater
+{
+	/**
+	 * The unique identifier of the Map As command used for <code>PersistentAttribute</code>
+	 * defined in the <code>JptUiPlugin</code> plugin.xml.
+	 */
+	public static final String COMMAND_ID = "org.eclipse.jpt.ui.persistentAttributeMapAs";
+	
+	/**
+	 * The unique identifier of the Map As command parameter used for <code>PersistentAttribute</code>
+	 * defined in the <code>JptUiPlugin</code> plugin.xml.
+	 */
+	public static final String SPECIFIED_MAPPING_COMMAND_PARAMETER_ID = "specifiedPersistentAttributeMappingKey";
+	
+	public static final String DEFAULT_MAPPING_COMMAND_PARAMETER_ID = "defaultPersistentAttributeMappingKey";
+	
+	/**
+	 * Creates a new <code>PersistentAttributeMapAsHandler</code>.
+	 */
+	public PersistentAttributeMapAsHandler() {
+		super();
+	}
+
+	public Object execute(ExecutionEvent event) throws ExecutionException {
+
+		// Retrieve the selection from the ExecutionEvent
+		IStructuredSelection selection = (IStructuredSelection)
+			HandlerUtil.getCurrentSelectionChecked(event);
+
+		// Retrieve the value of the unique parameter passed to the command
+		String mappingKey = event.getParameter(SPECIFIED_MAPPING_COMMAND_PARAMETER_ID);
+
+		// Change the mapping key for all the selected items
+		for (Object item : selection.toArray()) {
+			PersistentAttribute attribute = (PersistentAttribute) item;
+			attribute.setSpecifiedMappingKey(mappingKey);
+		}
+
+		return null;
+	}
+	
+	public void updateElement(UIElement element, @SuppressWarnings("unchecked") Map parameters) {
+		// Retrieve the selection for the UIElement
+		
+		// Due to Bug 226746, we have to use API workaround to retrieve current 
+		// selection
+		IEvaluationService es 
+			= (IEvaluationService) element.getServiceLocator().getService(IEvaluationService.class);
+		IViewPart part = 
+			(IViewPart) es.getCurrentState().getVariable(ISources.ACTIVE_PART_NAME);
+		IStructuredSelection selection 
+			= (IStructuredSelection) part.getSite().getSelectionProvider().getSelection();
+		
+		element.setChecked(selectedElementsMappingKeysMatch(selection, parameters));
+	}
+	
+	//Check all the selected persistent attribute and verify that they have the same mapping type.
+	//They must all be either default mappings or specified mappings as well.
+	protected boolean selectedElementsMappingKeysMatch(IStructuredSelection selection, @SuppressWarnings("unchecked") Map parameters) {
+		String handlerSpecifiedMappingKey = (String) parameters.get(SPECIFIED_MAPPING_COMMAND_PARAMETER_ID);
+		String handlerDefaultMappingKey = (String) parameters.get(DEFAULT_MAPPING_COMMAND_PARAMETER_ID);
+		
+		String commonDefaultKey = null;
+		String commonSpecifiedKey = null;
+		for (Object obj : selection.toArray()) {
+			if (! (obj instanceof PersistentAttribute)) {
+				//oddly enough, you have to check instanceof here, seems like a bug in the framework
+				return false;
+			}
+			
+			PersistentAttribute persistentAttribute = (PersistentAttribute) obj;
+			if (persistentAttribute.getSpecifiedMapping() == null) {
+				if (commonSpecifiedKey != null) {
+					return false;
+				}
+				if (commonDefaultKey == null) {
+					commonDefaultKey = persistentAttribute.getMappingKey();					
+				}
+				else if (!commonDefaultKey.equals(persistentAttribute.getMappingKey())) {
+					return false;
+				}
+			}
+			else {
+				if (commonDefaultKey != null) {
+					return false;
+				}
+				if (commonSpecifiedKey == null) {
+					commonSpecifiedKey = persistentAttribute.getMappingKey();
+				}
+				else if (!commonSpecifiedKey.equals(persistentAttribute.getMappingKey())) {
+					return false;
+				}
+			}
+		}
+		if (handlerSpecifiedMappingKey != null) {
+			return handlerSpecifiedMappingKey.equals(commonSpecifiedKey);
+		}
+		else if (handlerDefaultMappingKey != null) {
+			return handlerDefaultMappingKey.equals(commonDefaultKey);
+		}
+		return false;
+	}
+	
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/commands/PersistentTypeMapAsHandler.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/commands/PersistentTypeMapAsHandler.java
new file mode 100644
index 0000000..b1a9030
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/commands/PersistentTypeMapAsHandler.java
@@ -0,0 +1,124 @@
+/*******************************************************************************
+ * Copyright (c) 2008 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.ui.internal.commands;
+
+import java.util.Iterator;
+import java.util.Map;
+import org.eclipse.core.commands.AbstractHandler;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jpt.core.context.PersistentType;
+import org.eclipse.jpt.ui.internal.menus.PersistentTypeMapAsContribution;
+import org.eclipse.ui.ISources;
+import org.eclipse.ui.IViewPart;
+import org.eclipse.ui.commands.IElementUpdater;
+import org.eclipse.ui.handlers.HandlerUtil;
+import org.eclipse.ui.menus.UIElement;
+import org.eclipse.ui.services.IEvaluationService;
+
+/**
+ * This handler is responsible to change the mapping type of the selected
+ * <code>PersistentType</code>.
+ * <p>
+ * This handler is defined in the JPT plugin.xml. It will be invoked by the
+ * mapping action dynamically created by the <code>PersistentTypeMapAsContribution</code>.
+ *
+ * @see PersistentType
+ * @see PersistentTypeMapAsContribution
+ *
+ * @version 2.0
+ * @since 2.0
+ */
+@SuppressWarnings("nls")
+public class PersistentTypeMapAsHandler extends AbstractHandler
+	implements IElementUpdater
+{
+	/**
+	 * The unique identifier of the Map As command used for {@link PersistentType}
+	 * defined in the <code>JptUiPlugin</code> plugin.xml.
+	 */
+	public static final String COMMAND_ID = "org.eclipse.jpt.ui.persistentTypeMapAs";
+	
+	/**
+	 * The unique identifier of the Map As command parameter used for {@link PersistentType}
+	 * defined in the <code>JptUiPlugin</code> plugin.xml.
+	 */
+	public static final String COMMAND_PARAMETER_ID = "persistentTypeMappingKey";
+	
+	
+	/**
+	 * Creates a new <code>PersistentTypeMapAsHandler</code>.
+	 */
+	public PersistentTypeMapAsHandler() {
+		super();
+	}
+
+	public Object execute(ExecutionEvent event) throws ExecutionException {
+
+		// Retrieve the selection from the ExecutionEvent
+		IStructuredSelection selection = (IStructuredSelection)
+			HandlerUtil.getCurrentSelectionChecked(event);
+
+		// Retrieve the value of the unique parameter passed to the command
+		String mappingKey = event.getParameter(COMMAND_PARAMETER_ID);
+
+		// Change the mapping key for all the selected items
+		for (Object item : selection.toArray()) {
+			PersistentType type = (PersistentType) item;
+			type.setMappingKey(mappingKey);
+		}
+
+		return null;
+	}
+	
+	@SuppressWarnings("unchecked")
+	public void updateElement(UIElement element, Map parameters) {
+		// Retrieve the selection for the UIElement
+		
+		// Due to Bug 226746, we have to use API workaround to retrieve current 
+		// selection
+		IEvaluationService es 
+			= (IEvaluationService) element.getServiceLocator().getService(IEvaluationService.class);
+		IViewPart part = 
+			(IViewPart) es.getCurrentState().getVariable(ISources.ACTIVE_PART_NAME);
+		IStructuredSelection selection 
+			= (IStructuredSelection) part.getSite().getSelectionProvider().getSelection();
+		
+		String commonMappingKey = commonMappingKey(selection);
+		
+		String handlerMappingKey = (String) parameters.get(COMMAND_PARAMETER_ID);
+		if (handlerMappingKey != null) {
+			element.setChecked(handlerMappingKey.equals(commonMappingKey));
+		}
+	}
+	
+	@SuppressWarnings("unchecked")
+	protected String commonMappingKey(IStructuredSelection selection) {
+		String commonKey = null;
+		for (Iterator stream = selection.iterator(); stream.hasNext(); ) {
+			Object obj = stream.next();
+			
+			if (! (obj instanceof PersistentType)) {
+				return null;
+			}
+			
+			PersistentType persistentType = (PersistentType) obj;
+			
+			if (commonKey == null) {
+				commonKey = persistentType.getMappingKey();
+			}
+			else if (! commonKey.equals(persistentType.getMappingKey())) {
+				return null;
+			}
+		}
+		return commonKey;
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/commands/RemovePersistentAttributeFromXmlHandler.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/commands/RemovePersistentAttributeFromXmlHandler.java
new file mode 100644
index 0000000..5a3dbb7
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/commands/RemovePersistentAttributeFromXmlHandler.java
@@ -0,0 +1,63 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2010 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.ui.internal.commands;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.eclipse.core.commands.AbstractHandler;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jpt.core.context.orm.OrmPersistentAttribute;
+import org.eclipse.jpt.core.context.orm.OrmPersistentType;
+import org.eclipse.jpt.ui.internal.selection.DefaultJpaSelection;
+import org.eclipse.jpt.ui.internal.selection.JpaSelectionManager;
+import org.eclipse.jpt.ui.internal.selection.SelectionManagerFactory;
+import org.eclipse.jpt.utility.internal.CollectionTools;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.handlers.HandlerUtil;
+
+public class RemovePersistentAttributeFromXmlHandler extends AbstractHandler
+{	
+	@SuppressWarnings("unchecked")
+	public Object execute(ExecutionEvent executionEvent) throws ExecutionException {
+		final IWorkbenchWindow window = 
+			HandlerUtil.getActiveWorkbenchWindowChecked(executionEvent);
+		
+		final List<OrmPersistentAttribute> newAttributes = new ArrayList<OrmPersistentAttribute>();
+		
+		IStructuredSelection selection = 
+			(IStructuredSelection) HandlerUtil.getCurrentSelectionChecked(executionEvent);
+		
+		// only applies for multiply selected OrmPersistentAttribute objects in a tree
+		for (OrmPersistentAttribute attribute : (Iterable<OrmPersistentAttribute>) CollectionTools.iterable(selection.iterator())) {
+			OrmPersistentType type = attribute.getOwningPersistentType();
+			String attributeName = attribute.getName();
+			attribute.makeVirtual();
+			OrmPersistentAttribute newAttribute = type.getAttributeNamed(attributeName);
+			if (newAttribute != null) {
+				newAttributes.add(newAttribute);
+			}
+		}
+		
+		if (newAttributes.size() == 1) {
+			window.getShell().getDisplay().asyncExec(
+				new Runnable() {
+					public void run() {
+						JpaSelectionManager selectionManager = SelectionManagerFactory.getSelectionManager(window);
+						selectionManager.select(new DefaultJpaSelection(newAttributes.get(0)), null);
+					}
+				});
+		}
+		
+		return null;
+	}
+
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/commands/RemovePersistentClassHandler.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/commands/RemovePersistentClassHandler.java
new file mode 100644
index 0000000..8b6a3c8
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/commands/RemovePersistentClassHandler.java
@@ -0,0 +1,37 @@
+/*******************************************************************************
+ *  Copyright (c) 2007, 2009 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.ui.internal.commands;
+
+import java.util.Iterator;
+import org.eclipse.core.commands.AbstractHandler;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jpt.core.context.orm.EntityMappings;
+import org.eclipse.jpt.core.context.orm.OrmPersistentType;
+import org.eclipse.ui.handlers.HandlerUtil;
+
+public class RemovePersistentClassHandler extends AbstractHandler
+{
+	@SuppressWarnings("unchecked")
+	public Object execute(ExecutionEvent executionEvent) throws ExecutionException {
+		IStructuredSelection selection = 
+			(IStructuredSelection) HandlerUtil.getCurrentSelectionChecked(executionEvent);
+		
+		// only applies for multiply selected OrmPersistentType objects in a tree
+		for (Iterator<OrmPersistentType> stream = selection.iterator(); stream.hasNext(); ) {
+			OrmPersistentType persistentType = stream.next();
+			((EntityMappings) persistentType.getMappingFileRoot()).removePersistentType(persistentType);
+		}
+		
+		return null;
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/commands/UpgradeXmlFileVersionHandler.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/commands/UpgradeXmlFileVersionHandler.java
new file mode 100644
index 0000000..7ca61cc
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/commands/UpgradeXmlFileVersionHandler.java
@@ -0,0 +1,63 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2010 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.ui.internal.commands;
+
+import org.eclipse.core.commands.AbstractHandler;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.content.IContentType;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jpt.core.JpaProject;
+import org.eclipse.jpt.core.JptCorePlugin;
+import org.eclipse.jpt.core.context.XmlFile;
+import org.eclipse.jpt.core.resource.xml.JpaRootEObject;
+import org.eclipse.jpt.core.resource.xml.JpaXmlResource;
+import org.eclipse.ui.handlers.HandlerUtil;
+
+public class UpgradeXmlFileVersionHandler extends AbstractHandler
+{
+	public Object execute(ExecutionEvent event) throws ExecutionException {
+		IStructuredSelection selection 
+			= (IStructuredSelection) HandlerUtil.getCurrentSelectionChecked(event);
+
+		for (Object selectedObject : selection.toArray()) {
+			upgradeXmlFileVersion(selectedObject);
+		}
+		return null;
+	}
+
+	protected void upgradeXmlFileVersion(Object selectedObject) {
+		JpaXmlResource xmlResource = 
+			(JpaXmlResource) Platform.getAdapterManager().getAdapter(selectedObject, JpaXmlResource.class);
+		if (xmlResource == null) {
+			XmlFile xmlFile = 
+				(XmlFile) Platform.getAdapterManager().getAdapter(selectedObject, XmlFile.class);
+			if (xmlFile != null) {
+				xmlResource = xmlFile.getXmlResource();
+			}
+		}
+		if (xmlResource == null) {
+			return;
+		}
+
+		final JpaRootEObject root = xmlResource.getRootObject();
+		IContentType contentType = xmlResource.getContentType();
+		JpaProject jpaProject = JptCorePlugin.getJpaProject(xmlResource.getProject());
+		final String newVersion = jpaProject.getJpaPlatform().getMostRecentSupportedResourceType(contentType).getVersion();
+
+		xmlResource.modify(
+			new Runnable() {
+				public void run() {
+					root.setVersion(newVersion);
+				}
+			});
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/AbstractBasicMappingComposite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/AbstractBasicMappingComposite.java
new file mode 100644
index 0000000..639350b
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/AbstractBasicMappingComposite.java
@@ -0,0 +1,216 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2010 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.ui.internal.details;
+
+import org.eclipse.jpt.core.context.BasicMapping;
+import org.eclipse.jpt.core.context.Column;
+import org.eclipse.jpt.core.context.Converter;
+import org.eclipse.jpt.core.context.ConvertibleMapping;
+import org.eclipse.jpt.core.context.EnumeratedConverter;
+import org.eclipse.jpt.core.context.TemporalConverter;
+import org.eclipse.jpt.ui.WidgetFactory;
+import org.eclipse.jpt.ui.details.JpaComposite;
+import org.eclipse.jpt.ui.internal.widgets.Pane;
+import org.eclipse.jpt.utility.internal.model.value.PropertyAspectAdapter;
+import org.eclipse.jpt.utility.internal.model.value.SimplePropertyValueModel;
+import org.eclipse.jpt.utility.internal.model.value.TransformationPropertyValueModel;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.jpt.utility.model.value.WritablePropertyValueModel;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * Here the layout of this pane:
+ * <pre>
+ * -----------------------------------------------------------------------------
+ * | ------------------------------------------------------------------------- |
+ * | |                                                                       | |
+ * | | ColumnComposite                                                       | |
+ * | |                                                                       | |
+ * | ------------------------------------------------------------------------- |
+ * | ------------------------------------------------------------------------- |
+ * | |                                                                       | |
+ * | | FetchTypeComposite                                                    | |
+ * | |                                                                       | |
+ * | ------------------------------------------------------------------------- |
+ * | ------------------------------------------------------------------------- |
+ * | |                                                                       | |
+ * | | TemporalTypeComposite                                                 | |
+ * | |                                                                       | |
+ * | ------------------------------------------------------------------------- |
+ * | ------------------------------------------------------------------------- |
+ * | |                                                                       | |
+ * | | EnumTypeComposite                                                     | |
+ * | |                                                                       | |
+ * | ------------------------------------------------------------------------- |
+ * | ------------------------------------------------------------------------- |
+ * | |                                                                       | |
+ * | | OptionalComposite                                                     | |
+ * | |                                                                       | |
+ * | ------------------------------------------------------------------------- |
+ * | ------------------------------------------------------------------------- |
+ * | |                                                                       | |
+ * | | LobComposite                                                          | |
+ * | |                                                                       | |
+ * | ------------------------------------------------------------------------- |
+ * -----------------------------------------------------------------------------</pre>
+ *
+ * @see BasicMapping
+ * @see ColumnComposite
+ * @see EnumTypeComposite
+ * @see FetchTypeComposite
+ * @see LobComposite
+ * @see OptionalComposite
+ * @see TemporalTypeComposite
+ *
+ * @version 2.3
+ * @since 1.0
+ */
+public abstract class AbstractBasicMappingComposite<T extends BasicMapping> 
+	extends Pane<T>
+	implements JpaComposite
+{
+	/**
+	 * Creates a new <code>BasicMappingComposite</code>.
+	 *
+	 * @param subjectHolder The holder of the subject <code>IBasicMapping</code>
+	 * @param parent The parent container
+	 * @param widgetFactory The factory used to create various common widgets
+	 */
+	protected AbstractBasicMappingComposite(PropertyValueModel<? extends T> subjectHolder,
+	                             Composite parent,
+	                             WidgetFactory widgetFactory) {
+
+		super(subjectHolder, parent, widgetFactory);
+	}
+
+	@Override
+	protected void initializeLayout(Composite container) {
+		initializeBasicCollapsibleSection(container);
+		initializeTypeCollapsibleSection(container);
+	}
+	
+	protected void initializeBasicCollapsibleSection(Composite container) {
+		container = addCollapsibleSection(
+			container,
+			JptUiDetailsMessages.BasicSection_title,
+			new SimplePropertyValueModel<Boolean>(Boolean.TRUE)
+		);
+
+		this.initializeBasicSection(container);
+	}
+	
+	protected void initializeBasicSection(Composite container) {
+		new ColumnComposite(this, buildColumnHolder(), container);
+		new FetchTypeComposite(this, container);
+		new OptionalComposite(this, addSubPane(container, 4));
+	}
+	
+	protected void initializeTypeCollapsibleSection(Composite container) {
+		container = addCollapsibleSection(
+			container,
+			JptUiDetailsMessages.TypeSection_type
+		);
+		this.initializeTypeSection(container);
+	}
+
+	protected void initializeTypeSection(Composite container) {
+		((GridLayout) container.getLayout()).numColumns = 2;
+
+		// No converter
+		Button noConverterButton = addRadioButton(
+			container, 
+			JptUiDetailsMessages.TypeSection_default, 
+			buildConverterBooleanHolder(Converter.NO_CONVERTER), 
+			null);
+		((GridData) noConverterButton.getLayoutData()).horizontalSpan = 2;
+		
+		// Lob
+		Button lobButton = addRadioButton(
+			container, 
+			JptUiDetailsMessages.TypeSection_lob, 
+			buildConverterBooleanHolder(Converter.LOB_CONVERTER), 
+			null);
+		((GridData) lobButton.getLayoutData()).horizontalSpan = 2;
+		
+		PropertyValueModel<Converter> converterHolder = buildConverterHolder();
+		// Temporal
+		addRadioButton(
+			container, 
+			JptUiDetailsMessages.TypeSection_temporal, 
+			buildConverterBooleanHolder(Converter.TEMPORAL_CONVERTER), 
+			null);
+		registerSubPane(new TemporalTypeComposite(buildTemporalConverterHolder(converterHolder), container, getWidgetFactory()));
+		
+		
+		// Enumerated
+		addRadioButton(
+			container, 
+			JptUiDetailsMessages.TypeSection_enumerated, 
+			buildConverterBooleanHolder(Converter.ENUMERATED_CONVERTER), 
+			null);
+		registerSubPane(new EnumTypeComposite(buildEnumeratedConverterHolder(converterHolder), container, getWidgetFactory()));
+	}
+
+	protected PropertyValueModel<Column> buildColumnHolder() {
+		return new TransformationPropertyValueModel<T, Column>(getSubjectHolder()) {
+			@Override
+			protected Column transform_(T value) {
+				return value.getColumn();
+			}
+		};
+	}
+	
+	protected PropertyValueModel<Converter> buildConverterHolder() {
+		return new PropertyAspectAdapter<T, Converter>(getSubjectHolder(), ConvertibleMapping.CONVERTER_PROPERTY) {
+			@Override
+			protected Converter buildValue_() {
+				return this.subject.getConverter();
+			}
+		};
+	}
+	
+	protected PropertyValueModel<TemporalConverter> buildTemporalConverterHolder(PropertyValueModel<Converter> converterHolder) {
+		return new TransformationPropertyValueModel<Converter, TemporalConverter>(converterHolder) {
+			@Override
+			protected TemporalConverter transform_(Converter converter) {
+				return converter.getType() == Converter.TEMPORAL_CONVERTER ? (TemporalConverter) converter : null;
+			}
+		};
+	}
+	
+	protected PropertyValueModel<EnumeratedConverter> buildEnumeratedConverterHolder(PropertyValueModel<Converter> converterHolder) {
+		return new TransformationPropertyValueModel<Converter, EnumeratedConverter>(converterHolder) {
+			@Override
+			protected EnumeratedConverter transform_(Converter converter) {
+				return converter.getType() == Converter.ENUMERATED_CONVERTER ? (EnumeratedConverter) converter : null;
+			}
+		};
+	}
+	
+	protected WritablePropertyValueModel<Boolean> buildConverterBooleanHolder(final String converterType) {
+		return new PropertyAspectAdapter<BasicMapping, Boolean>(getSubjectHolder(), ConvertibleMapping.CONVERTER_PROPERTY) {
+			@Override
+			protected Boolean buildValue_() {
+				Converter converter = this.subject.getConverter();
+				return Boolean.valueOf(converter.getType() == converterType);
+			}
+
+			@Override
+			protected void setValue_(Boolean value) {
+				if (value.booleanValue()) {
+					this.subject.setConverter(converterType);
+				}
+			}
+		};
+	}
+}
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/AbstractBasicMappingUiDefinition.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/AbstractBasicMappingUiDefinition.java
new file mode 100644
index 0000000..319b09e
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/AbstractBasicMappingUiDefinition.java
@@ -0,0 +1,41 @@
+/*******************************************************************************
+ *  Copyright (c) 2008, 2009  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.ui.internal.details;
+
+import org.eclipse.jpt.core.MappingKeys;
+import org.eclipse.jpt.core.context.BasicMapping;
+import org.eclipse.jpt.ui.internal.JpaMappingImageHelper;
+import org.eclipse.swt.graphics.Image;
+
+public abstract class AbstractBasicMappingUiDefinition<M, T extends BasicMapping>
+	extends AbstractMappingUiDefinition<M, T>
+{
+	protected AbstractBasicMappingUiDefinition() {
+		super();
+	}
+	
+	
+	public Image getImage() {
+		return JpaMappingImageHelper.imageForAttributeMapping(getKey());
+	}
+	
+	public String getLabel() {
+		return JptUiDetailsMessages.BasicMappingUiProvider_label;
+	}
+	
+	public String getLinkLabel() {
+		return JptUiDetailsMessages.BasicMappingUiProvider_linkLabel;
+	}
+	
+	public String getKey() {
+		return MappingKeys.BASIC_ATTRIBUTE_MAPPING_KEY;
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/AbstractEmbeddableComposite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/AbstractEmbeddableComposite.java
new file mode 100644
index 0000000..adbabca
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/AbstractEmbeddableComposite.java
@@ -0,0 +1,66 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 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.ui.internal.details;
+
+import org.eclipse.jpt.core.context.Embeddable;
+import org.eclipse.jpt.ui.WidgetFactory;
+import org.eclipse.jpt.ui.details.JpaComposite;
+import org.eclipse.jpt.ui.internal.details.JptUiDetailsMessages;
+import org.eclipse.jpt.ui.internal.widgets.Pane;
+import org.eclipse.jpt.utility.internal.model.value.SimplePropertyValueModel;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * This pane does not have any widgets.
+ *
+ * @see Embeddable
+ * @see JavaUiFactory - The factory creating this pane
+ * @see EmbeddableUiProvider
+ *
+ * @version 2.3
+ * @since 2.1
+ */
+public abstract class AbstractEmbeddableComposite<T extends Embeddable> 
+	extends Pane<T>
+	implements JpaComposite
+{
+	/**
+	 * Creates a new <code>EmbeddableComposite</code>.
+	 *
+	 * @param subjectHolder The holder of this pane's subject
+	 * @param parent The parent container
+	 * @param widgetFactory The factory used to create various common widgets
+	 */
+	protected AbstractEmbeddableComposite(PropertyValueModel<? extends T> subjectHolder,
+	                           Composite parent,
+	                           WidgetFactory widgetFactory) {
+
+		super(subjectHolder, parent, widgetFactory);
+	}
+
+	@Override
+	protected void initializeLayout(Composite container) {
+	}
+	
+	protected void initializeEmbeddableCollapsibleSection(Composite container) {
+		container = addCollapsibleSection(
+			container,
+			JptUiDetailsMessages.EmbeddableSection_title,
+			new SimplePropertyValueModel<Boolean>(Boolean.TRUE)
+		);
+
+		this.initializeEmbeddableSection(container);
+	}
+	
+	protected void initializeEmbeddableSection(Composite container) {
+		
+	}
+}
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/AbstractEmbeddableUiDefinition.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/AbstractEmbeddableUiDefinition.java
new file mode 100644
index 0000000..d6198ef
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/AbstractEmbeddableUiDefinition.java
@@ -0,0 +1,41 @@
+/*******************************************************************************
+ *  Copyright (c) 2008, 2009  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.ui.internal.details;
+
+import org.eclipse.jpt.core.MappingKeys;
+import org.eclipse.jpt.core.context.Embeddable;
+import org.eclipse.jpt.ui.internal.JpaMappingImageHelper;
+import org.eclipse.swt.graphics.Image;
+
+public abstract class AbstractEmbeddableUiDefinition<M, T extends Embeddable> 
+	extends AbstractMappingUiDefinition<M, T>
+{
+	protected AbstractEmbeddableUiDefinition() {
+		super();
+	}
+	
+	
+	public String getKey() {
+		return MappingKeys.EMBEDDABLE_TYPE_MAPPING_KEY;
+	}
+	
+	public String getLabel() {
+		return JptUiDetailsMessages.EmbeddableUiProvider_label;
+	}
+	
+	public String getLinkLabel() {
+		return JptUiDetailsMessages.EmbeddableUiProvider_linkLabel;
+	}
+	
+	public Image getImage() {
+		return JpaMappingImageHelper.imageForTypeMapping(getKey());
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/AbstractEmbeddedIdMappingComposite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/AbstractEmbeddedIdMappingComposite.java
new file mode 100644
index 0000000..089c21e
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/AbstractEmbeddedIdMappingComposite.java
@@ -0,0 +1,48 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 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.ui.internal.details;
+
+import org.eclipse.jpt.core.context.EmbeddedIdMapping;
+import org.eclipse.jpt.ui.WidgetFactory;
+import org.eclipse.jpt.ui.details.JpaComposite;
+import org.eclipse.jpt.ui.internal.widgets.Pane;
+import org.eclipse.jpt.utility.internal.model.value.SimplePropertyValueModel;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+public abstract class AbstractEmbeddedIdMappingComposite<T extends EmbeddedIdMapping> 
+	extends Pane<T>
+	implements JpaComposite
+{
+	protected AbstractEmbeddedIdMappingComposite(
+			PropertyValueModel<? extends T> subjectHolder,
+			Composite parent,
+			WidgetFactory widgetFactory) {
+		
+		super(subjectHolder, parent, widgetFactory);
+	}
+	
+	
+	@Override
+	protected void initializeLayout(Composite container) {
+		initializeEmbeddedIdCollapsibleSection(container);
+	}
+	
+	protected void initializeEmbeddedIdCollapsibleSection(Composite container) {
+		container = addCollapsibleSection(
+				container,
+				JptUiDetailsMessages.EmbeddedIdSection_title,
+				new SimplePropertyValueModel<Boolean>(Boolean.TRUE));
+		
+		this.initializeEmbeddedIdSection(container);
+	}
+	
+	protected abstract void initializeEmbeddedIdSection(Composite container);
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/AbstractEmbeddedIdMappingUiDefinition.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/AbstractEmbeddedIdMappingUiDefinition.java
new file mode 100644
index 0000000..6b36bad
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/AbstractEmbeddedIdMappingUiDefinition.java
@@ -0,0 +1,42 @@
+/*******************************************************************************
+ *  Copyright (c) 2008, 2009  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.ui.internal.details;
+
+import org.eclipse.jpt.core.MappingKeys;
+import org.eclipse.jpt.core.context.EmbeddedIdMapping;
+import org.eclipse.jpt.ui.internal.JpaMappingImageHelper;
+import org.eclipse.swt.graphics.Image;
+
+
+public abstract class AbstractEmbeddedIdMappingUiDefinition<M, T extends EmbeddedIdMapping>
+	extends AbstractMappingUiDefinition<M, T>
+{
+	protected AbstractEmbeddedIdMappingUiDefinition() {
+		super();
+	}
+	
+	
+	public String getKey() {
+		return MappingKeys.EMBEDDED_ID_ATTRIBUTE_MAPPING_KEY;
+	}
+
+	public String getLabel() {
+		return JptUiDetailsMessages.EmbeddedIdMappingUiProvider_label;
+	}
+
+	public String getLinkLabel() {
+		return JptUiDetailsMessages.EmbeddedIdMappingUiProvider_linkLabel;
+	}
+
+	public Image getImage() {
+		return JpaMappingImageHelper.imageForAttributeMapping(getKey());
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/AbstractEmbeddedMappingComposite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/AbstractEmbeddedMappingComposite.java
new file mode 100644
index 0000000..e5622ff
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/AbstractEmbeddedMappingComposite.java
@@ -0,0 +1,75 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 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.ui.internal.details;
+
+import org.eclipse.jpt.core.context.EmbeddedMapping;
+import org.eclipse.jpt.ui.WidgetFactory;
+import org.eclipse.jpt.ui.details.JpaComposite;
+import org.eclipse.jpt.ui.internal.widgets.Pane;
+import org.eclipse.jpt.utility.internal.model.value.SimplePropertyValueModel;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * Here the layout of this pane:
+ * <pre>
+ * -----------------------------------------------------------------------------
+ * | ------------------------------------------------------------------------- |
+ * | |                                                                       | |
+ * | | EmbeddedAttributeOverridesComposite                                   | |
+ * | |                                                                       | |
+ * | ------------------------------------------------------------------------- |
+ * -----------------------------------------------------------------------------</pre>
+ *
+ * @see EmbeddedMapping
+ *
+ * @version 2.3
+ * @since 1.0
+ */
+public abstract class AbstractEmbeddedMappingComposite<T extends EmbeddedMapping> 
+	extends Pane<T>
+	implements JpaComposite
+{
+	/**
+	 * Creates a new <code>EmbeddedMappingComposite</code>.
+	 *
+	 * @param subjectHolder The holder of the subject <code>EmbeddedMapping</code>
+	 * @param parent The parent container
+	 * @param widgetFactory The factory used to create various common widgets
+	 */
+	protected AbstractEmbeddedMappingComposite(PropertyValueModel<? extends T> subjectHolder,
+	                                Composite parent,
+	                                WidgetFactory widgetFactory) {
+
+		super(subjectHolder, parent, widgetFactory);
+	}
+
+	@Override
+	protected void initializeLayout(Composite container) {
+		initializeEmbeddedCollapsibleSection(container);
+	}
+	
+	protected void initializeEmbeddedCollapsibleSection(Composite container) {
+		container = addCollapsibleSection(
+			container,
+			JptUiDetailsMessages.EmbeddedSection_title,
+			new SimplePropertyValueModel<Boolean>(Boolean.TRUE)
+		);
+
+		this.initializeEmbeddedSection(container);
+	}
+	
+	protected void initializeEmbeddedSection(Composite container) {
+		new EmbeddedMappingOverridesComposite(
+			this,
+			container
+		);
+	}
+}
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/AbstractEmbeddedMappingOverridesComposite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/AbstractEmbeddedMappingOverridesComposite.java
new file mode 100644
index 0000000..80a548b
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/AbstractEmbeddedMappingOverridesComposite.java
@@ -0,0 +1,39 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2010 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.ui.internal.details;
+
+import org.eclipse.jpt.core.context.AttributeOverrideContainer;
+import org.eclipse.jpt.core.context.BaseEmbeddedMapping;
+import org.eclipse.jpt.ui.internal.widgets.Pane;
+import org.eclipse.jpt.utility.internal.model.value.PropertyAspectAdapter;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+public abstract class AbstractEmbeddedMappingOverridesComposite<T extends BaseEmbeddedMapping>
+	extends AbstractOverridesComposite<T>
+{
+	protected AbstractEmbeddedMappingOverridesComposite(
+			Pane<? extends T> parentPane,
+			Composite parent) {
+		
+		super(parentPane, parent);
+	}
+	
+	
+	@Override
+	protected PropertyValueModel<AttributeOverrideContainer> buildAttributeOverrideContainerHolder() {
+		return new PropertyAspectAdapter<T, AttributeOverrideContainer>(getSubjectHolder()) {
+			@Override
+			protected AttributeOverrideContainer buildValue_() {
+				return this.subject.getAttributeOverrideContainer();
+			}
+		};
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/AbstractEmbeddedMappingUiDefinition.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/AbstractEmbeddedMappingUiDefinition.java
new file mode 100644
index 0000000..00d3494
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/AbstractEmbeddedMappingUiDefinition.java
@@ -0,0 +1,41 @@
+/*******************************************************************************
+ *  Copyright (c) 2008, 2009  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.ui.internal.details;
+
+import org.eclipse.jpt.core.MappingKeys;
+import org.eclipse.jpt.core.context.EmbeddedMapping;
+import org.eclipse.jpt.ui.internal.JpaMappingImageHelper;
+import org.eclipse.swt.graphics.Image;
+
+public abstract class AbstractEmbeddedMappingUiDefinition<M, T extends EmbeddedMapping>
+	extends AbstractMappingUiDefinition<M, T>
+{
+	protected AbstractEmbeddedMappingUiDefinition() {
+		super();
+	}
+	
+	
+	public String getKey() {
+		return MappingKeys.EMBEDDED_ATTRIBUTE_MAPPING_KEY;
+	}
+
+	public String getLabel() {
+		return JptUiDetailsMessages.EmbeddedMappingUiProvider_label;
+	}
+
+	public String getLinkLabel() {
+		return JptUiDetailsMessages.EmbeddedMappingUiProvider_linkLabel;
+	}
+
+	public Image getImage() {
+		return JpaMappingImageHelper.imageForAttributeMapping(getKey());
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/AbstractEntityComposite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/AbstractEntityComposite.java
new file mode 100644
index 0000000..60b18ff
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/AbstractEntityComposite.java
@@ -0,0 +1,216 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2010 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.ui.internal.details;
+
+import org.eclipse.jpt.core.context.Entity;
+import org.eclipse.jpt.core.context.GeneratorContainer;
+import org.eclipse.jpt.core.context.IdClassReference;
+import org.eclipse.jpt.core.context.QueryContainer;
+import org.eclipse.jpt.ui.WidgetFactory;
+import org.eclipse.jpt.ui.details.JpaComposite;
+import org.eclipse.jpt.ui.internal.widgets.Pane;
+import org.eclipse.jpt.utility.internal.model.value.PropertyAspectAdapter;
+import org.eclipse.jpt.utility.internal.model.value.SimplePropertyValueModel;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * Here the layout of this pane:
+ * <pre>
+ * -----------------------------------------------------------------------------
+ * | ------------------------------------------------------------------------- |
+ * | |                                                                       | |
+ * | | EntityNameComposite                                                   | |
+ * | |                                                                       | |
+ * | ------------------------------------------------------------------------- |
+ * | ------------------------------------------------------------------------- |
+ * | |                                                                       | |
+ * | | TableComposite                                                        | |
+ * | |                                                                       | |
+ * | ------------------------------------------------------------------------- |
+ * | ------------------------------------------------------------------------- |
+ * | |                                                                       | |
+ * | | IdClassComposite                                                      | |
+ * | |                                                                       | |
+ * | ------------------------------------------------------------------------- |
+ * |                                                                           |
+ * | - v Attribute Overrides ------------------------------------------------- |
+ * | ------------------------------------------------------------------------- |
+ * | |                                                                       | |
+ * | | OverridesComposite                                                    | |
+ * | |                                                                       | |
+ * | ------------------------------------------------------------------------- |
+ * |                                                                           |
+ * | - v Secondary Tables ---------------------------------------------------- |
+ * | ------------------------------------------------------------------------- |
+ * | |                                                                       | |
+ * | | Pane                                                                  | |
+ * | |                                                                       | |
+ * | ------------------------------------------------------------------------- |
+ * |                                                                           |
+ * | - v Inheritance --------------------------------------------------------- |
+ * | ------------------------------------------------------------------------- |
+ * | |                                                                       | |
+ * | | InheritanceComposite                                                  | |
+ * | |                                                                       | |
+ * | ------------------------------------------------------------------------- |
+ * |                                                                           |
+ * | - v Queries ------------------------------------------------------------- |
+ * | ------------------------------------------------------------------------- |
+ * | |                                                                       | |
+ * | | QueriesComposite                                                      | |
+ * | |                                                                       | |
+ * | ------------------------------------------------------------------------- |
+ * |                                                                           |
+ * | - v Generators ---------------------------------------------------------- |
+ * | ------------------------------------------------------------------------- |
+ * | |                                                                       | |
+ * | | GeneratorsComposite                                                   | |
+ * | |                                                                       | |
+ * | ------------------------------------------------------------------------- |
+ * -----------------------------------------------------------------------------</pre>
+ *
+ * @see Entity
+ * @see EntityNameComposite
+ * @see InheritanceComposite
+ * @see IdClassComposite
+ * @see EntityOverridesComposite
+ * @see TableComposite
+ * @see GenerationComposite
+ *
+ * TODO talk to JavaEditor people about what we can do to hook in TabbedProperties for the JavaEditor
+ *
+ * @version 2.3
+ * @since 1.0
+ */
+public abstract class AbstractEntityComposite<T extends Entity>
+	extends Pane<T>
+    implements JpaComposite
+{
+	/**
+	 * Creates a new <code>AbstractEntityComposite</code>.
+	 *
+	 * @param subjectHolder The holder of the subject <code>IEntity</code>
+	 * @param parent The parent container
+	 * @param widgetFactory The factory used to create various common widgets
+	 */
+	protected AbstractEntityComposite(
+			PropertyValueModel<? extends T> subjectHolder,
+	        Composite parent,
+	        WidgetFactory widgetFactory) {
+		
+		super(subjectHolder, parent, widgetFactory);
+	}
+	
+	
+	protected abstract void initializeSecondaryTablesSection(Composite container);
+	
+	protected abstract void initializeInheritanceSection(Composite container);
+	
+	@Override
+	protected void initializeLayout(Composite container) {
+		this.initializeEntityCollapsibleSection(container);
+		this.initializeQueriesCollapsibleSection(container);
+		this.initializeInheritanceCollapsibleSection(container);
+		this.initializeAttributeOverridesCollapsibleSection(container);
+		this.initializeGeneratorsCollapsibleSection(container);
+		this.initializeSecondaryTablesCollapsibleSection(container);
+	}
+	
+	protected void initializeEntityCollapsibleSection(Composite container) {
+		container = addCollapsibleSection(
+			container,
+			JptUiDetailsMessages.EntitySection_title,
+			new SimplePropertyValueModel<Boolean>(Boolean.TRUE)
+		);
+
+		this.initializeEntitySection(container);
+	}
+	
+	protected void initializeEntitySection(Composite container) {
+		new TableComposite(this, container);
+		new EntityNameComposite(this, container);
+		new IdClassComposite(this, buildIdClassReferenceHolder(), container);
+	}
+	
+	protected PropertyValueModel<IdClassReference> buildIdClassReferenceHolder() {
+		return new PropertyAspectAdapter<Entity, IdClassReference>(getSubjectHolder()) {
+			@Override
+			protected IdClassReference buildValue_() {
+				return this.subject.getIdClassReference();
+			}
+		};
+	}
+	
+	protected void initializeQueriesCollapsibleSection(Composite container) {
+		container = addCollapsibleSection(
+				container,
+				JptUiDetailsMessages.EntityComposite_queries);
+		this.initializeQueriesSection(container, buildQueryContainerHolder());
+	}
+	
+	protected void initializeQueriesSection(Composite container, PropertyValueModel<QueryContainer> queryContainerHolder) {
+		new QueriesComposite(this, queryContainerHolder, container);
+	}
+	
+	private PropertyValueModel<QueryContainer> buildQueryContainerHolder() {
+		return new PropertyAspectAdapter<Entity, QueryContainer>(getSubjectHolder()) {
+			@Override
+			protected QueryContainer buildValue_() {
+				return this.subject.getQueryContainer();
+			}
+		};
+	}
+	
+	protected void initializeAttributeOverridesCollapsibleSection(Composite container) {
+		container = addCollapsibleSection(
+				container,
+				JptUiDetailsMessages.OverridesComposite_attributeOverridesSection);
+		initializeAttributeOverridesSection(container);
+	}
+	
+	protected void initializeAttributeOverridesSection(Composite container) {
+		new EntityOverridesComposite(this, container);
+	}
+	
+	protected void initializeInheritanceCollapsibleSection(Composite container) {
+		container = addCollapsibleSection(
+				container,
+				JptUiDetailsMessages.EntityComposite_inheritance);
+		initializeInheritanceSection(container);
+	}
+	
+	protected void initializeGeneratorsCollapsibleSection(Composite container) {
+		container = addCollapsibleSection(
+				container,
+				JptUiDetailsMessages.IdMappingComposite_primaryKeyGenerationSection);
+		initializeGeneratorsSection(container, buildGeneratorContainer());
+	}
+	
+	protected void initializeGeneratorsSection(Composite container, PropertyValueModel<GeneratorContainer> generatorContainerHolder) {
+		new GenerationComposite(this, generatorContainerHolder, container);
+	}
+	
+	private PropertyValueModel<GeneratorContainer> buildGeneratorContainer() {
+		return new PropertyAspectAdapter<Entity, GeneratorContainer>(getSubjectHolder()) {
+			@Override
+			protected GeneratorContainer buildValue_() {
+				return this.subject.getGeneratorContainer();
+			}
+		};
+	}
+	
+	protected void initializeSecondaryTablesCollapsibleSection(Composite container) {
+		container = addCollapsibleSection(
+				container,
+				JptUiDetailsMessages.SecondaryTablesComposite_secondaryTables);
+		initializeSecondaryTablesSection(container);
+	}
+}
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/AbstractEntityMappingsDetailsProvider.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/AbstractEntityMappingsDetailsProvider.java
new file mode 100644
index 0000000..9325433
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/AbstractEntityMappingsDetailsProvider.java
@@ -0,0 +1,32 @@
+/*******************************************************************************
+* Copyright (c) 2009 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.ui.internal.details;
+
+import org.eclipse.jpt.core.JpaResourceType;
+import org.eclipse.jpt.core.JpaStructureNode;
+import org.eclipse.jpt.core.context.orm.OrmStructureNodes;
+import org.eclipse.jpt.ui.details.JpaDetailsProvider;
+import org.eclipse.jpt.utility.internal.StringTools;
+
+public abstract class AbstractEntityMappingsDetailsProvider
+	implements JpaDetailsProvider
+{
+	protected AbstractEntityMappingsDetailsProvider() {
+		super();
+	}
+	
+	
+	public final boolean providesDetails(JpaStructureNode structureNode) {
+		return StringTools.stringsAreEqual(structureNode.getId(), OrmStructureNodes.ENTITY_MAPPINGS_ID)
+				&& providesDetails(structureNode.getResourceType());
+	}
+	
+	protected abstract boolean providesDetails(JpaResourceType resourceType);
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/AbstractEntityOverridesComposite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/AbstractEntityOverridesComposite.java
new file mode 100644
index 0000000..9e1dd93
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/AbstractEntityOverridesComposite.java
@@ -0,0 +1,55 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 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.ui.internal.details;
+
+import org.eclipse.jpt.core.context.AssociationOverrideContainer;
+import org.eclipse.jpt.core.context.AttributeOverrideContainer;
+import org.eclipse.jpt.core.context.Entity;
+import org.eclipse.jpt.ui.internal.widgets.Pane;
+import org.eclipse.jpt.utility.internal.model.value.PropertyAspectAdapter;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+public abstract class AbstractEntityOverridesComposite
+	extends AbstractOverridesComposite<Entity>
+{
+	protected AbstractEntityOverridesComposite(
+			Pane<? extends Entity> parentPane,
+			Composite parent) {
+		
+		super(parentPane, parent);
+	}
+	
+	
+	@Override
+	protected boolean supportsAssociationOverrides() {
+		return true;
+	}	
+	
+	@Override
+	protected PropertyValueModel<AttributeOverrideContainer> buildAttributeOverrideContainerHolder() {
+		return new PropertyAspectAdapter<Entity, AttributeOverrideContainer>(getSubjectHolder()) {
+			@Override
+			protected AttributeOverrideContainer buildValue_() {
+				return this.subject.getAttributeOverrideContainer();
+			}
+		};
+	}
+	
+	@Override
+	protected PropertyValueModel<AssociationOverrideContainer> buildAssociationOverrideContainerHolder() {
+		return new PropertyAspectAdapter<Entity, AssociationOverrideContainer>(getSubjectHolder()) {
+			@Override
+			protected AssociationOverrideContainer buildValue_() {
+				return this.subject.getAssociationOverrideContainer();
+			}
+		};
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/AbstractEntityUiDefinition.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/AbstractEntityUiDefinition.java
new file mode 100644
index 0000000..1023e36
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/AbstractEntityUiDefinition.java
@@ -0,0 +1,41 @@
+/*******************************************************************************
+ *  Copyright (c) 2008, 2009  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.ui.internal.details;
+
+import org.eclipse.jpt.core.MappingKeys;
+import org.eclipse.jpt.core.context.Entity;
+import org.eclipse.jpt.ui.internal.JpaMappingImageHelper;
+import org.eclipse.swt.graphics.Image;
+
+public abstract class AbstractEntityUiDefinition<M, T extends Entity> 
+	extends AbstractMappingUiDefinition<M, T>
+{
+	protected AbstractEntityUiDefinition() {
+		super();
+	}
+	
+	
+	public String getKey() {
+		return MappingKeys.ENTITY_TYPE_MAPPING_KEY;
+	}
+	
+	public String getLabel() {
+		return JptUiDetailsMessages.EntityUiProvider_label;
+	}
+	
+	public String getLinkLabel() {
+		return JptUiDetailsMessages.EntityUiProvider_linkLabel;
+	}
+	
+	public Image getImage() {
+		return JpaMappingImageHelper.imageForTypeMapping(getKey());
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/AbstractIdMappingComposite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/AbstractIdMappingComposite.java
new file mode 100644
index 0000000..70a8605
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/AbstractIdMappingComposite.java
@@ -0,0 +1,136 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2010 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.ui.internal.details;
+
+import org.eclipse.jpt.core.context.Column;
+import org.eclipse.jpt.core.context.Converter;
+import org.eclipse.jpt.core.context.ConvertibleMapping;
+import org.eclipse.jpt.core.context.IdMapping;
+import org.eclipse.jpt.core.context.TemporalConverter;
+import org.eclipse.jpt.ui.WidgetFactory;
+import org.eclipse.jpt.ui.details.JpaComposite;
+import org.eclipse.jpt.ui.internal.widgets.Pane;
+import org.eclipse.jpt.utility.internal.model.value.PropertyAspectAdapter;
+import org.eclipse.jpt.utility.internal.model.value.SimplePropertyValueModel;
+import org.eclipse.jpt.utility.internal.model.value.TransformationPropertyValueModel;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.jpt.utility.model.value.WritablePropertyValueModel;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+
+public abstract class AbstractIdMappingComposite<T extends IdMapping>
+	extends Pane<T>
+    implements JpaComposite
+{
+	public AbstractIdMappingComposite(
+			PropertyValueModel<? extends T> subjectHolder,
+	        Composite parent,
+	        WidgetFactory widgetFactory) {
+		
+		super(subjectHolder, parent, widgetFactory);
+	}
+	
+	
+	@Override
+	protected void initializeLayout(Composite container) {
+		initializeIdCollapsibleSection(container);
+		initializeTypeCollapsibleSection(container);
+		initializeGenerationCollapsibleSection(container);
+	}
+	
+	protected void initializeIdCollapsibleSection(Composite container) {
+		container = addCollapsibleSection(
+				container,
+				JptUiDetailsMessages.IdSection_title,
+				new SimplePropertyValueModel<Boolean>(Boolean.TRUE));
+
+		this.initializeIdSection(container);
+	}
+	
+	protected abstract void initializeIdSection(Composite container);
+	
+	protected void initializeTypeCollapsibleSection(Composite container) {
+		container = addCollapsibleSection(
+				container,
+				JptUiDetailsMessages.TypeSection_type);
+		this.initializeTypeSection(container);
+	}
+	
+	protected void initializeTypeSection(Composite container) {
+		((GridLayout) container.getLayout()).numColumns = 2;
+		
+		// No converter
+		Button noConverterButton = addRadioButton(
+				container, 
+				JptUiDetailsMessages.TypeSection_default, 
+				buildConverterBooleanHolder(Converter.NO_CONVERTER), 
+				null);
+		((GridData) noConverterButton.getLayoutData()).horizontalSpan = 2;
+				
+		PropertyValueModel<Converter> converterHolder = buildConverterHolder();
+		// Temporal
+		addRadioButton(
+				container, 
+				JptUiDetailsMessages.TypeSection_temporal, 
+				buildConverterBooleanHolder(Converter.TEMPORAL_CONVERTER), 
+				null);
+		registerSubPane(new TemporalTypeComposite(buildTemporalConverterHolder(converterHolder), container, getWidgetFactory()));
+	}
+	
+	protected void initializeGenerationCollapsibleSection(Composite container) {
+		new IdMappingGenerationComposite(this, container);
+	}
+	
+	protected PropertyValueModel<? extends Column> buildColumnHolder() {
+		return new TransformationPropertyValueModel<T, Column>(getSubjectHolder())  {
+			@Override
+			protected Column transform_(T value) {
+				return value.getColumn();
+			}
+		};
+	}
+	
+	protected WritablePropertyValueModel<Boolean> buildConverterBooleanHolder(final String converterType) {
+		return new PropertyAspectAdapter<T, Boolean>(getSubjectHolder(), ConvertibleMapping.CONVERTER_PROPERTY) {
+			@Override
+			protected Boolean buildValue_() {
+				Converter converter = this.subject.getConverter();
+				return Boolean.valueOf(converter.getType() == converterType);
+			}
+			
+			@Override
+			protected void setValue_(Boolean value) {
+				if (value.booleanValue()) {
+					this.subject.setConverter(converterType);
+				}
+			}
+		};
+	}
+	
+	protected PropertyValueModel<Converter> buildConverterHolder() {
+		return new PropertyAspectAdapter<T, Converter>(getSubjectHolder(), ConvertibleMapping.CONVERTER_PROPERTY) {
+			@Override
+			protected Converter buildValue_() {
+				return this.subject.getConverter();
+			}
+		};
+	}
+	
+	protected PropertyValueModel<TemporalConverter> buildTemporalConverterHolder(PropertyValueModel<Converter> converterHolder) {
+		return new TransformationPropertyValueModel<Converter, TemporalConverter>(converterHolder) {
+			@Override
+			protected TemporalConverter transform_(Converter converter) {
+				return converter.getType() == Converter.TEMPORAL_CONVERTER ? (TemporalConverter) converter : null;
+			}
+		};
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/AbstractIdMappingUiDefinition.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/AbstractIdMappingUiDefinition.java
new file mode 100644
index 0000000..f532c84
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/AbstractIdMappingUiDefinition.java
@@ -0,0 +1,42 @@
+/*******************************************************************************
+ *  Copyright (c) 2008, 2009  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.ui.internal.details;
+
+import org.eclipse.jpt.core.MappingKeys;
+import org.eclipse.jpt.core.context.IdMapping;
+import org.eclipse.jpt.ui.internal.JpaMappingImageHelper;
+import org.eclipse.swt.graphics.Image;
+
+
+public abstract class AbstractIdMappingUiDefinition<M, T extends IdMapping>
+	extends AbstractMappingUiDefinition<M, T>
+{
+	protected AbstractIdMappingUiDefinition() {
+		super();
+	}
+	
+	
+	public Image getImage() {
+		return JpaMappingImageHelper.imageForAttributeMapping(getKey());
+	}
+	
+	public String getLabel() {
+		return JptUiDetailsMessages.IdMappingUiProvider_label;
+	}
+	
+	public String getLinkLabel() {
+		return JptUiDetailsMessages.IdMappingUiProvider_linkLabel;
+	}
+	
+	public String getKey() {
+		return MappingKeys.ID_ATTRIBUTE_MAPPING_KEY;
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/AbstractInheritanceComposite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/AbstractInheritanceComposite.java
new file mode 100644
index 0000000..254cfca
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/AbstractInheritanceComposite.java
@@ -0,0 +1,290 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2010 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.ui.internal.details;
+
+import java.util.Collection;
+
+import org.eclipse.jpt.core.context.Entity;
+import org.eclipse.jpt.core.context.InheritanceType;
+import org.eclipse.jpt.ui.internal.JpaHelpContextIds;
+import org.eclipse.jpt.ui.internal.widgets.EnumFormComboViewer;
+import org.eclipse.jpt.ui.internal.widgets.Pane;
+import org.eclipse.jpt.utility.internal.StringConverter;
+import org.eclipse.jpt.utility.internal.model.value.PropertyAspectAdapter;
+import org.eclipse.jpt.utility.internal.model.value.PropertyListValueModelAdapter;
+import org.eclipse.jpt.utility.model.value.ListValueModel;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.jpt.utility.model.value.WritablePropertyValueModel;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Label;
+
+/**
+ * Here the layout of this pane:
+ * <pre>
+ * -----------------------------------------------------------------------------
+ * |                      ---------------------------------------------------- |
+ * | Strategy:            | EnumComboViewer                                |v| |
+ * |                      ---------------------------------------------------- |
+ * |                      ---------------------------------------------------- |
+ * | Value:               | I                                              |v| |
+ * |                      ---------------------------------------------------- |
+ * |                                                                           |
+ * | > Discriminator Column                                                    |
+ * |                                                                           |
+ * |                      ---------------------------------------------------- |
+ * | Name:                | ColumnCombo                                    |v| |
+ * |                      ---------------------------------------------------- |
+ * |                      ---------------------------------------------------- |
+ * | Type:                | EnumComboViewer                                |v| |
+ * |                      ---------------------------------------------------- |
+ * |                      ---------------------------------------------------- |
+ * | Column Definition:   | I                                                | |
+ * |                      ---------------------------------------------------- |
+ * |                      -------------                                        |
+ * | Length:              | I       |I|                                        |
+ * |                      -------------                                        |
+ * | ------------------------------------------------------------------------- |
+ * | |                                                                       | |
+ * | | PrimaryKeyJoinColumnsComposite                                        | |
+ * | |                                                                       | |
+ * | ------------------------------------------------------------------------- |
+ * -----------------------------------------------------------------------------</pre>
+ *
+ * @see Entity
+ * @see AbstractEntityComposite - The parent container
+ * @see ColumnCombo
+ * @see EnumComboViewer
+ * @see PrimaryKeyJoinColumnsComposite
+ *
+ * @version 2.0
+ * @since 2.0
+ */
+@SuppressWarnings("nls")
+public abstract class AbstractInheritanceComposite<T extends Entity> extends Pane<T> {
+
+	/**
+	 * A key used to represent the default value, this is required to convert
+	 * the selected item from a combo to <code>null</code>. This key is most
+	 * likely never typed the user and it will help to convert the value to
+	 * <code>null</code> when it's time to set the new selected value into the
+	 * model.
+	 */
+	protected static String DEFAULT_KEY = "?!#!?#?#?default?#?!#?!#?";
+	
+	protected static String NONE_KEY = "?!#!?#?#?none?#?!#?!#?";
+
+	/**
+	 * Creates a new <code>InheritanceComposite</code>.
+	 *
+	 * @param parentPane The parent container of this one
+	 * @param parent The parent container
+	 */
+	public AbstractInheritanceComposite(Pane<? extends T> parentPane,
+	                            Composite parent) {
+
+		super(parentPane, parent, false);
+	}
+
+	@Override
+	protected void initializeLayout(Composite container) {
+
+		int groupBoxMargin = getGroupBoxMargin();
+
+		Composite subPane = addSubPane(
+			container, 0, groupBoxMargin, 0, groupBoxMargin
+		);
+
+		// Strategy widgets
+		addLabeledComposite(
+			subPane,
+			JptUiDetailsMessages.InheritanceComposite_strategy,
+			addStrategyCombo(subPane),
+			JpaHelpContextIds.ENTITY_INHERITANCE_STRATEGY
+		);
+
+		// Discrinator Value widgets
+		PropertyValueModel<Boolean> dvEnabled = this.buildDiscriminatorValueEnabledHolder();
+		Combo discriminatorValueCombo = addEditableCombo(
+			subPane,
+			buildDiscriminatorValueListHolder(),
+			buildDiscriminatorValueHolder(),
+			buildDiscriminatorValueConverter(),
+			dvEnabled
+		);
+		Label discriminatorValueLabel = addLabel(
+			subPane, 
+			JptUiDetailsMessages.InheritanceComposite_discriminatorValue,
+			dvEnabled
+		);
+		addLabeledComposite(
+			subPane,
+			discriminatorValueLabel,
+			discriminatorValueCombo,
+			null,
+			JpaHelpContextIds.ENTITY_INHERITANCE_DISCRIMINATOR_VALUE
+		);
+	
+		new DiscriminatorColumnComposite<Entity>(this, container);
+
+		// Primary Key Join Columns widgets
+		addPrimaryKeyJoinColumnsComposite(addSubPane(container, 5));
+	}
+	
+	protected WritablePropertyValueModel<Boolean> buildDiscriminatorValueEnabledHolder() {
+		return new PropertyAspectAdapter<Entity, Boolean>(getSubjectHolder(), Entity.SPECIFIED_DISCRIMINATOR_VALUE_IS_ALLOWED_PROPERTY) {
+			@Override
+			protected Boolean buildValue_() {
+				return Boolean.valueOf(this.subject.specifiedDiscriminatorValueIsAllowed());
+			}
+		};
+	}
+
+	private ListValueModel<String> buildDefaultDiscriminatorListValueHolder() {
+		return new PropertyListValueModelAdapter<String>(
+			buildDefaultDiscriminatorValueHolder()
+		);
+	}
+
+	private WritablePropertyValueModel<String> buildDefaultDiscriminatorValueHolder() {
+		return new PropertyAspectAdapter<Entity, String>(getSubjectHolder(), Entity.DEFAULT_DISCRIMINATOR_VALUE_PROPERTY, Entity.DISCRIMINATOR_VALUE_IS_UNDEFINED_PROPERTY) {
+			@Override
+			protected String buildValue_() {
+				String value = this.subject.getDefaultDiscriminatorValue();
+				if (value == null && this.subject.discriminatorValueIsUndefined()) {
+					return NONE_KEY;
+				}
+
+				if (value == null) {
+					value = DEFAULT_KEY;
+				}
+				else {
+					value = DEFAULT_KEY + value;
+				}
+
+				return value;
+			}
+		};
+	}
+
+	private StringConverter<String> buildDiscriminatorValueConverter() {
+		return new StringConverter<String>() {
+			public String convertToString(String value) {
+
+				if (getSubject() == null) {
+					//this is part of a list given to a combo, combos don't take kindly to null
+					return JptUiDetailsMessages.NoneSelected;
+				}
+
+				if (value == null) {
+					value = getSubject().getDefaultDiscriminatorValue();
+					if (value == null && getSubject().discriminatorValueIsUndefined()) {
+						value = NONE_KEY;
+					}
+					else {
+						value = (value != null) ? 
+								DEFAULT_KEY + value
+							: 
+								DEFAULT_KEY;
+					}
+				}
+				if (value.startsWith(DEFAULT_KEY)) {
+					String defaultName = value.substring(DEFAULT_KEY.length());
+
+					if (defaultName.length() > 0) {
+						value = NLS.bind(
+							JptUiDetailsMessages.DefaultWithOneParam,
+							defaultName
+						);
+					}
+					else {
+						value = JptUiDetailsMessages.ProviderDefault;
+					}
+				}
+				if (value.startsWith(NONE_KEY)) {
+					value = JptUiDetailsMessages.NoneSelected;
+				}
+				return value;
+			}
+		};
+	}
+
+	private WritablePropertyValueModel<String> buildDiscriminatorValueHolder() {
+		return new PropertyAspectAdapter<Entity, String>(getSubjectHolder(), Entity.SPECIFIED_DISCRIMINATOR_VALUE_PROPERTY) {
+			@Override
+			protected String buildValue_() {
+				return this.subject.getSpecifiedDiscriminatorValue();
+			}
+
+			@Override
+			protected void setValue_(String value) {
+
+				// Convert the default value or an empty string to null
+				if ((value != null) &&
+				   ((value.length() == 0) || value.startsWith(DEFAULT_KEY) || value.startsWith(NONE_KEY))) {
+
+					value = null;
+				}
+
+				this.subject.setSpecifiedDiscriminatorValue(value);
+			}
+		};
+	}
+
+	private ListValueModel<String> buildDiscriminatorValueListHolder() {
+		return buildDefaultDiscriminatorListValueHolder();
+	}
+
+	private EnumFormComboViewer<Entity, InheritanceType> addStrategyCombo(Composite container) {
+
+		return new EnumFormComboViewer<Entity, InheritanceType>(this, container) {
+
+			@Override
+			protected void addPropertyNames(Collection<String> propertyNames) {
+				super.addPropertyNames(propertyNames);
+				propertyNames.add(Entity.DEFAULT_INHERITANCE_STRATEGY_PROPERTY);
+				propertyNames.add(Entity.SPECIFIED_INHERITANCE_STRATEGY_PROPERTY);
+			}
+
+			@Override
+			protected InheritanceType[] getChoices() {
+				return InheritanceType.values();
+			}
+
+			@Override
+			protected InheritanceType getDefaultValue() {
+				return getSubject().getDefaultInheritanceStrategy();
+			}
+
+			@Override
+			protected String displayString(InheritanceType value) {
+				return buildDisplayString(
+					JptUiDetailsMessages.class,
+					AbstractInheritanceComposite.class,
+					value
+				);
+			}
+
+			@Override
+			protected InheritanceType getValue() {
+				return getSubject().getSpecifiedInheritanceStrategy();
+			}
+
+			@Override
+			protected void setValue(InheritanceType value) {
+				getSubject().setSpecifiedInheritanceStrategy(value);
+			}
+		};
+	}
+
+	protected abstract void addPrimaryKeyJoinColumnsComposite(Composite container);
+
+}
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/AbstractJoiningStrategyPane.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/AbstractJoiningStrategyPane.java
new file mode 100644
index 0000000..ccf2175
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/AbstractJoiningStrategyPane.java
@@ -0,0 +1,97 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2010 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.ui.internal.details;
+
+import org.eclipse.jpt.core.context.JoiningStrategy;
+import org.eclipse.jpt.core.context.RelationshipReference;
+import org.eclipse.jpt.ui.internal.util.ControlSwitcher;
+import org.eclipse.jpt.ui.internal.widgets.Pane;
+import org.eclipse.jpt.utility.internal.Transformer;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.jpt.utility.model.value.WritablePropertyValueModel;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.ui.part.PageBook;
+
+/**
+ * Abstract superclass for joining strategy form panes
+ * 
+ * Here is the basic layout of this pane:  
+ * <pre>
+ * -----------------------------------------------------------------------------
+ * | o <label> _______________________________________________________________ |
+ * | |                                                                       | |
+ * | |          (joining strategy details composite)                         | |
+ * | |                                                                       | |
+ * | ------------------------------------------------------------------------- |
+ * -----------------------------------------------------------------------------</pre>
+ *
+ * @see {@link OwnableRelationshipReference}
+ * @see {@link MappedByJoiningStrategy}
+ * @see {@link OneToOneJoiningStrategyPane}
+ *
+ * @version 2.3
+ * @since 2.1
+ */
+public abstract class AbstractJoiningStrategyPane
+		<R extends RelationshipReference, S extends JoiningStrategy> 
+	extends Pane<R>
+{
+	protected Composite strategyDetailsComposite;
+	
+	
+	/**
+	 * Creates a new <code>AbstractJoiningStrategyPane</code>.
+	 *
+	 * @param parentPane The parent form pane
+	 * @param parent The parent container
+	 */
+	protected AbstractJoiningStrategyPane(
+			Pane<? extends R> parentPane, 
+			Composite parent) {
+		super(parentPane, parent);
+	}
+	
+	protected AbstractJoiningStrategyPane(Pane<?> parentPane, 
+		PropertyValueModel<? extends R> subjectHolder,
+        Composite parent) {
+
+		super(parentPane, subjectHolder, parent);
+	}
+	
+	protected abstract WritablePropertyValueModel<Boolean> buildUsesStrategyHolder();
+	
+	
+	@Override
+	protected void initializeLayout(Composite container) {
+		PageBook pageBook = new PageBook(container, SWT.NULL);
+		GridData gd = new GridData(GridData.FILL_HORIZONTAL);
+		gd.horizontalIndent = 5;
+		pageBook.setLayoutData(gd);
+		
+		this.strategyDetailsComposite = buildStrategyDetailsComposite(pageBook);
+		
+		new ControlSwitcher(this.buildUsesStrategyHolder(), buildPageBookTransformer(), pageBook);
+	}
+	
+	protected abstract Composite buildStrategyDetailsComposite(Composite parent);
+	
+	protected Transformer<Boolean, Control> buildPageBookTransformer() {
+		return new Transformer<Boolean, Control>() {
+			public Control transform(Boolean usesStrategy) {
+				return (usesStrategy.booleanValue()) ? 
+					AbstractJoiningStrategyPane.this.strategyDetailsComposite :
+					null;
+			}
+		};
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/AbstractJpaDetailsPage.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/AbstractJpaDetailsPage.java
new file mode 100644
index 0000000..ee3e520
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/AbstractJpaDetailsPage.java
@@ -0,0 +1,53 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 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.ui.internal.details;
+
+import org.eclipse.jpt.core.JpaStructureNode;
+import org.eclipse.jpt.ui.JpaPlatformUi;
+import org.eclipse.jpt.ui.WidgetFactory;
+import org.eclipse.jpt.ui.details.JpaDetailsPage;
+import org.eclipse.jpt.ui.internal.platform.JpaPlatformUiRegistry;
+import org.eclipse.jpt.ui.internal.widgets.Pane;
+import org.eclipse.jpt.utility.internal.model.value.SimplePropertyValueModel;
+import org.eclipse.jpt.utility.model.value.WritablePropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * The base class for the details view.
+ *
+ * @see JpaStructureNode
+ *
+ * @version 3.0
+ * @since 1.0
+ */
+public abstract class AbstractJpaDetailsPage<T extends JpaStructureNode>
+	extends Pane<T>
+	implements JpaDetailsPage<T>
+{
+	/**
+	 * Creates a new <code>BaseJpaDetailsPage</code>.
+	 *
+	 * @param parent The parent container
+	 * @param widgetFactory The factory used to create various common widgets
+	 */
+	protected AbstractJpaDetailsPage(Composite parent, WidgetFactory widgetFactory) {
+		super(new SimplePropertyValueModel<T>(), parent, widgetFactory);
+	}
+
+	protected JpaPlatformUi getJpaPlatformUi() {
+		String platformId = getSubject().getJpaProject().getJpaPlatform().getId();
+		return JpaPlatformUiRegistry.instance().getJpaPlatformUi(platformId);
+	}
+
+	public final void setSubject(T subject) {
+		WritablePropertyValueModel<T> subjectHolder = (WritablePropertyValueModel<T>) getSubjectHolder();
+		subjectHolder.setValue(subject);
+	}
+}
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/AbstractManyToManyMappingComposite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/AbstractManyToManyMappingComposite.java
new file mode 100644
index 0000000..655c6b2
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/AbstractManyToManyMappingComposite.java
@@ -0,0 +1,140 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2010 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.ui.internal.details;
+
+import org.eclipse.jpt.core.context.AccessHolder;
+import org.eclipse.jpt.core.context.Cascade;
+import org.eclipse.jpt.core.context.ManyToManyMapping;
+import org.eclipse.jpt.core.context.ManyToManyRelationshipReference;
+import org.eclipse.jpt.ui.WidgetFactory;
+import org.eclipse.jpt.ui.details.JpaComposite;
+import org.eclipse.jpt.ui.internal.widgets.Pane;
+import org.eclipse.jpt.utility.internal.model.value.PropertyAspectAdapter;
+import org.eclipse.jpt.utility.internal.model.value.SimplePropertyValueModel;
+import org.eclipse.jpt.utility.internal.model.value.TransformationPropertyValueModel;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * Here the layout of this pane:
+ * <pre>
+ * -----------------------------------------------------------------------------
+ * | ------------------------------------------------------------------------- |
+ * | |                                                                       | |
+ * | | TargetEntityComposite                                                 | |
+ * | |                                                                       | |
+ * | ------------------------------------------------------------------------- |
+ * | ------------------------------------------------------------------------- |
+ * | |                                                                       | |
+ * | | JoiningStrategyComposite                                              | |
+ * | |                                                                       | |
+ * | ------------------------------------------------------------------------- |
+ * | ------------------------------------------------------------------------- |
+ * | |                                                                       | |
+ * | | FetchTypeComposite                                                    | |
+ * | |                                                                       | |
+ * | ------------------------------------------------------------------------- |
+ * | ------------------------------------------------------------------------- |
+ * | |                                                                       | |
+ * | | CascadeComposite                                                      | |
+ * | |                                                                       | |
+ * | ------------------------------------------------------------------------- |
+ * | ------------------------------------------------------------------------- |
+ * | |                                                                       | |
+ * | | OrderingComposite                                                     | |
+ * | |                                                                       | |
+ * | ------------------------------------------------------------------------- |
+ * -----------------------------------------------------------------------------</pre>
+ *
+ * @see {@link ManyToManyMapping}
+ * @see {@link TargetEntityComposite}
+ * @see {@link ManyToManyJoiningStrategyPane}
+ * @see {@link FetchTypeComposite}
+ * @see {@link CascadeComposite}
+ * @see {@link OrderingComposite}
+ *
+ * @version 2.3
+ * @since 1.0
+ */
+public abstract class AbstractManyToManyMappingComposite<T extends ManyToManyMapping, R extends ManyToManyRelationshipReference> 
+	extends Pane<T>
+    implements JpaComposite
+{
+	/**
+	 * Creates a new <code>ManyToManyMappingComposite</code>.
+	 *
+	 * @param subjectHolder The holder of the subject <code>IManyToManyMapping</code>
+	 * @param parent The parent container
+	 * @param widgetFactory The factory used to create various common widgets
+	 */
+	protected AbstractManyToManyMappingComposite(PropertyValueModel<? extends T> subjectHolder,
+	                                  Composite parent,
+	                                  WidgetFactory widgetFactory) {
+
+		super(subjectHolder, parent, widgetFactory);
+	}
+
+	@Override
+	protected void initializeLayout(Composite container) {
+		initializeManyToManyCollapsibleSection(container);
+		initializeJoiningStrategyCollapsibleSection(container);
+		initializeOrderingCollapsibleSection(container);
+	}
+	
+	protected void initializeManyToManyCollapsibleSection(Composite container) {
+		container = addCollapsibleSection(
+			container,
+			JptUiDetailsMessages.ManyToManySection_title,
+			new SimplePropertyValueModel<Boolean>(Boolean.TRUE)
+		);
+
+		this.initializeManyToManySection(container);
+	}
+
+	protected abstract void initializeManyToManySection(Composite container);
+
+	protected void initializeJoiningStrategyCollapsibleSection(Composite container) {
+		new ManyToManyJoiningStrategyPane(this, buildJoiningHolder(), container);
+	}
+
+	protected void initializeOrderingCollapsibleSection(Composite container) {
+		new OrderingComposite(this, container);
+	}
+
+	
+	protected PropertyValueModel<R> buildJoiningHolder() {
+		return new TransformationPropertyValueModel<T, R>(
+				getSubjectHolder()) {
+			@SuppressWarnings("unchecked")
+			@Override
+			protected R transform_(T value) {
+				return (R) value.getRelationshipReference();
+			}
+		};
+	}
+	
+	protected PropertyValueModel<Cascade> buildCascadeHolder() {
+		return new TransformationPropertyValueModel<T, Cascade>(getSubjectHolder()) {
+			@Override
+			protected Cascade transform_(T value) {
+				return value.getCascade();
+			}
+		};
+	}
+	
+	protected PropertyValueModel<AccessHolder> buildAccessHolderHolder() {
+		return new PropertyAspectAdapter<T, AccessHolder>(getSubjectHolder()) {
+			@Override
+			protected AccessHolder buildValue_() {
+				return this.subject.getPersistentAttribute();
+			}
+		};
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/AbstractManyToManyMappingUiDefinition.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/AbstractManyToManyMappingUiDefinition.java
new file mode 100644
index 0000000..dae50f0
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/AbstractManyToManyMappingUiDefinition.java
@@ -0,0 +1,41 @@
+/*******************************************************************************
+ *  Copyright (c) 2008, 2009  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.ui.internal.details;
+
+import org.eclipse.jpt.core.MappingKeys;
+import org.eclipse.jpt.core.context.ManyToManyMapping;
+import org.eclipse.jpt.ui.internal.JpaMappingImageHelper;
+import org.eclipse.swt.graphics.Image;
+
+public abstract class AbstractManyToManyMappingUiDefinition<M, T extends ManyToManyMapping>
+	extends AbstractMappingUiDefinition<M, T>
+{
+	protected AbstractManyToManyMappingUiDefinition() {
+		super();
+	}
+	
+	
+	public Image getImage() {
+		return JpaMappingImageHelper.imageForAttributeMapping(getKey());
+	}
+	
+	public String getLabel() {
+		return JptUiDetailsMessages.ManyToManyMappingUiProvider_label;
+	}
+	
+	public String getLinkLabel() {
+		return JptUiDetailsMessages.ManyToManyMappingUiProvider_linkLabel;
+	}
+	
+	public String getKey() {
+		return MappingKeys.MANY_TO_MANY_ATTRIBUTE_MAPPING_KEY;
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/AbstractManyToOneMappingComposite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/AbstractManyToOneMappingComposite.java
new file mode 100644
index 0000000..3df3d1b
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/AbstractManyToOneMappingComposite.java
@@ -0,0 +1,80 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2010 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.ui.internal.details;
+
+import org.eclipse.jpt.core.context.Cascade;
+import org.eclipse.jpt.core.context.ManyToOneMapping;
+import org.eclipse.jpt.core.context.ManyToOneRelationshipReference;
+import org.eclipse.jpt.ui.WidgetFactory;
+import org.eclipse.jpt.ui.details.JpaComposite;
+import org.eclipse.jpt.ui.internal.widgets.Pane;
+import org.eclipse.jpt.utility.internal.model.value.SimplePropertyValueModel;
+import org.eclipse.jpt.utility.internal.model.value.TransformationPropertyValueModel;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+public abstract class AbstractManyToOneMappingComposite<T extends ManyToOneMapping, R extends ManyToOneRelationshipReference> 
+	extends Pane<T>
+	implements JpaComposite
+{
+	protected AbstractManyToOneMappingComposite(
+			PropertyValueModel<? extends T> subjectHolder,
+	        Composite parent,
+	        WidgetFactory widgetFactory) {
+
+		super(subjectHolder, parent, widgetFactory);
+	}
+
+	@Override
+	protected void initializeLayout(Composite container) {
+		initializeManyToOneCollapsibleSection(container);
+		initializeJoiningStrategyCollapsibleSection(container);
+	}
+	
+	protected void initializeManyToOneCollapsibleSection(Composite container) {
+		container = addCollapsibleSection(
+			container,
+			JptUiDetailsMessages.ManyToOneSection_title,
+			new SimplePropertyValueModel<Boolean>(Boolean.TRUE)
+		);
+
+		this.initializeManyToOneSection(container);
+	}
+
+	protected abstract void initializeManyToOneSection(Composite container);
+
+	protected void initializeJoiningStrategyCollapsibleSection(Composite container) {
+		new ManyToOneJoiningStrategyPane(this, buildJoiningHolder(), container);
+	}
+
+	protected PropertyValueModel<Cascade> buildCascadeHolder() {
+		return new TransformationPropertyValueModel<T, Cascade>(getSubjectHolder()) {
+			@Override
+			protected Cascade transform_(T value) {
+				return value.getCascade();
+			}
+		};
+	}
+
+	protected PropertyValueModel<R> buildJoiningHolder() {
+		return new TransformationPropertyValueModel<T, R>(
+				getSubjectHolder()) {
+			@SuppressWarnings("unchecked")
+			@Override
+			protected R transform_(T value) {
+				return (R) value.getRelationshipReference();
+			}
+		};
+	}
+	
+	protected Composite addPane(Composite container, int groupBoxMargin) {
+		return addSubPane(container, 0, groupBoxMargin, 0, groupBoxMargin);
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/AbstractManyToOneMappingUiDefinition.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/AbstractManyToOneMappingUiDefinition.java
new file mode 100644
index 0000000..075980b
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/AbstractManyToOneMappingUiDefinition.java
@@ -0,0 +1,41 @@
+/*******************************************************************************
+ *  Copyright (c) 2008, 2009  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.ui.internal.details;
+
+import org.eclipse.jpt.core.MappingKeys;
+import org.eclipse.jpt.core.context.ManyToOneMapping;
+import org.eclipse.jpt.ui.internal.JpaMappingImageHelper;
+import org.eclipse.swt.graphics.Image;
+
+public abstract class AbstractManyToOneMappingUiDefinition<M, T extends ManyToOneMapping>
+	extends AbstractMappingUiDefinition<M, T>
+{
+	protected AbstractManyToOneMappingUiDefinition() {
+		super();
+	}
+	
+	
+	public Image getImage() {
+		return JpaMappingImageHelper.imageForAttributeMapping(getKey());
+	}
+	
+	public String getLabel() {
+		return JptUiDetailsMessages.ManyToOneMappingUiProvider_label;
+	}
+	
+	public String getLinkLabel() {
+		return JptUiDetailsMessages.ManyToOneMappingUiProvider_linkLabel;
+	}
+	
+	public String getKey() {
+		return MappingKeys.MANY_TO_ONE_ATTRIBUTE_MAPPING_KEY;
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/AbstractMappedSuperclassComposite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/AbstractMappedSuperclassComposite.java
new file mode 100644
index 0000000..d110bf2
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/AbstractMappedSuperclassComposite.java
@@ -0,0 +1,62 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2010 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.ui.internal.details;
+
+import org.eclipse.jpt.core.context.IdClassReference;
+import org.eclipse.jpt.core.context.MappedSuperclass;
+import org.eclipse.jpt.ui.WidgetFactory;
+import org.eclipse.jpt.ui.details.JpaComposite;
+import org.eclipse.jpt.ui.internal.widgets.Pane;
+import org.eclipse.jpt.utility.internal.model.value.PropertyAspectAdapter;
+import org.eclipse.jpt.utility.internal.model.value.SimplePropertyValueModel;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+
+public abstract class AbstractMappedSuperclassComposite<T extends MappedSuperclass>
+	extends Pane<T>
+    implements JpaComposite
+{
+	protected AbstractMappedSuperclassComposite(
+			PropertyValueModel<? extends T> subjectHolder,
+	        Composite parent,
+	        WidgetFactory widgetFactory) {
+		
+		super(subjectHolder, parent, widgetFactory);
+	}
+	
+	@Override
+	protected void initializeLayout(Composite container) {
+		this.initializeMappedSuperclassCollapsibleSection(container);
+	}
+	
+	protected void initializeMappedSuperclassCollapsibleSection(Composite container) {
+		container = addCollapsibleSection(
+			container,
+			JptUiDetailsMessages.MappedSuperclassSection_title,
+			new SimplePropertyValueModel<Boolean>(Boolean.TRUE)
+		);
+
+		this.initializeMappedSuperclassSection(container);
+	}
+	
+	protected void initializeMappedSuperclassSection(Composite container) {
+		new IdClassComposite(this, buildIdClassReferenceHolder(), container);
+	}
+
+	protected PropertyValueModel<IdClassReference> buildIdClassReferenceHolder() {
+		return new PropertyAspectAdapter<T, IdClassReference>(getSubjectHolder()) {
+			@Override
+			protected IdClassReference buildValue_() {
+				return this.subject.getIdClassReference();
+			}
+		};
+	}
+}
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/AbstractMappedSuperclassUiDefinition.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/AbstractMappedSuperclassUiDefinition.java
new file mode 100644
index 0000000..e309a2b
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/AbstractMappedSuperclassUiDefinition.java
@@ -0,0 +1,41 @@
+/*******************************************************************************
+ *  Copyright (c) 2008, 2009  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.ui.internal.details;
+
+import org.eclipse.jpt.core.MappingKeys;
+import org.eclipse.jpt.core.context.MappedSuperclass;
+import org.eclipse.jpt.ui.internal.JpaMappingImageHelper;
+import org.eclipse.swt.graphics.Image;
+
+public abstract class AbstractMappedSuperclassUiDefinition<M, T extends MappedSuperclass>
+	extends AbstractMappingUiDefinition<M, T>
+{
+	protected AbstractMappedSuperclassUiDefinition() {
+		super();
+	}
+	
+	
+	public String getKey() {
+		return MappingKeys.MAPPED_SUPERCLASS_TYPE_MAPPING_KEY;
+	}
+	
+	public String getLabel() {
+		return JptUiDetailsMessages.MappedSuperclassUiProvider_label;
+	}
+	
+	public String getLinkLabel() {
+		return JptUiDetailsMessages.MappedSuperclassUiProvider_linkLabel;
+	}
+	
+	public Image getImage() {
+		return JpaMappingImageHelper.imageForTypeMapping(getKey());
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/AbstractMappingUiDefinition.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/AbstractMappingUiDefinition.java
new file mode 100644
index 0000000..60c037c
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/AbstractMappingUiDefinition.java
@@ -0,0 +1,25 @@
+/*******************************************************************************
+ *  Copyright (c) 2010  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.ui.internal.details;
+
+import org.eclipse.jpt.ui.details.MappingUiDefinition;
+
+public abstract class AbstractMappingUiDefinition<M, T>
+	implements MappingUiDefinition<M, T>
+{
+	protected AbstractMappingUiDefinition() {
+		super();
+	}
+	
+	
+	public boolean isEnabledFor(M mappableObject) {
+		return true;
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/AbstractOneToManyMappingComposite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/AbstractOneToManyMappingComposite.java
new file mode 100644
index 0000000..7f5108f
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/AbstractOneToManyMappingComposite.java
@@ -0,0 +1,132 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2010 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.ui.internal.details;
+
+import org.eclipse.jpt.core.context.Cascade;
+import org.eclipse.jpt.core.context.OneToManyMapping;
+import org.eclipse.jpt.core.context.OneToManyRelationshipReference;
+import org.eclipse.jpt.ui.WidgetFactory;
+import org.eclipse.jpt.ui.details.JpaComposite;
+import org.eclipse.jpt.ui.internal.widgets.Pane;
+import org.eclipse.jpt.utility.internal.model.value.SimplePropertyValueModel;
+import org.eclipse.jpt.utility.internal.model.value.TransformationPropertyValueModel;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * Here the layout of this pane:
+ * <pre>
+ * -----------------------------------------------------------------------------
+ * | ------------------------------------------------------------------------- |
+ * | |                                                                       | |
+ * | | TargetEntityComposite                                                 | |
+ * | |                                                                       | |
+ * | ------------------------------------------------------------------------- |
+ * | ------------------------------------------------------------------------- |
+ * | |                                                                       | |
+ * | | JoiningStrategyComposite                                              | |
+ * | |                                                                       | |
+ * | ------------------------------------------------------------------------- |
+ * | ------------------------------------------------------------------------- |
+ * | |                                                                       | |
+ * | | FetchTypeComposite                                                    | |
+ * | |                                                                       | |
+ * | ------------------------------------------------------------------------- |
+ * | ------------------------------------------------------------------------- |
+ * | |                                                                       | |
+ * | | CascadeComposite                                                      | |
+ * | |                                                                       | |
+ * | ------------------------------------------------------------------------- |
+ * | ------------------------------------------------------------------------- |
+ * | |                                                                       | |
+ * | | OrderingComposite                                                     | |
+ * | |                                                                       | |
+ * | ------------------------------------------------------------------------- |
+ * -----------------------------------------------------------------------------</pre>
+ *
+ * @see OneToManyMapping
+ * @see CascadeComposite
+ * @see FetchTypeComposite
+ * @see JoinTableComposite
+ * @see OrderingComposite
+ * @see TargetEntityComposite
+ *
+ * @version 2.3
+ * @since 1.0
+ */
+public abstract class AbstractOneToManyMappingComposite<T extends OneToManyMapping, R extends OneToManyRelationshipReference> 
+	extends Pane<T>
+	implements JpaComposite
+{
+	/**
+	 * Creates a new <code>OneToManyMappingComposite</code>.
+	 *
+	 * @param subjectHolder The holder of the subject <code>IOneToManyMapping</code>
+	 * @param parent The parent container
+	 * @param widgetFactory The factory used to create various common widgets
+	 */
+	protected AbstractOneToManyMappingComposite(PropertyValueModel<? extends T> subjectHolder,
+	                                 Composite parent,
+	                                 WidgetFactory widgetFactory) {
+
+		super(subjectHolder, parent, widgetFactory);
+	}
+
+	@Override
+	protected void initializeLayout(Composite container) {
+		initializeOneToManyCollapsibleSection(container);
+		initializeJoiningStrategyCollapsibleSection(container);
+		initializeOrderingCollapsibleSection(container);
+	}
+	
+	protected void initializeOneToManyCollapsibleSection(Composite container) {
+		container = addCollapsibleSection(
+			container,
+			JptUiDetailsMessages.OneToManySection_title,
+			new SimplePropertyValueModel<Boolean>(Boolean.TRUE)
+		);
+
+		this.initializeOneToManySection(container);
+	}
+
+	protected abstract void initializeOneToManySection(Composite container);
+
+	protected void initializeJoiningStrategyCollapsibleSection(Composite container) {
+		new OneToManyJoiningStrategyPane(this, buildJoiningHolder(), container);
+	}
+
+	protected void initializeOrderingCollapsibleSection(Composite container) {
+		new OrderingComposite(this, container);
+	}
+
+	protected PropertyValueModel<R> buildJoiningHolder() {
+		return new TransformationPropertyValueModel<T, R>(getSubjectHolder()) {
+			@SuppressWarnings("unchecked")
+			@Override
+			protected R transform_(T value) {
+				return (R) value.getRelationshipReference();
+			}
+		};
+	}	
+	
+	protected PropertyValueModel<Cascade> buildCascadeHolder() {
+		return new TransformationPropertyValueModel<T, Cascade>(getSubjectHolder()) {
+			@Override
+			protected Cascade transform_(T value) {
+				return value.getCascade();
+			}
+		};
+	}
+
+	protected Composite addPane(Composite container, int groupBoxMargin) {
+		return addSubPane(container, 0, groupBoxMargin, 0, groupBoxMargin);
+	}
+
+}
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/AbstractOneToManyMappingUiDefinition.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/AbstractOneToManyMappingUiDefinition.java
new file mode 100644
index 0000000..d5aaf12
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/AbstractOneToManyMappingUiDefinition.java
@@ -0,0 +1,41 @@
+/*******************************************************************************
+ *  Copyright (c) 2008, 2009  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.ui.internal.details;
+
+import org.eclipse.jpt.core.MappingKeys;
+import org.eclipse.jpt.core.context.OneToManyMapping;
+import org.eclipse.jpt.ui.internal.JpaMappingImageHelper;
+import org.eclipse.swt.graphics.Image;
+
+public abstract class AbstractOneToManyMappingUiDefinition<M, T extends OneToManyMapping>
+	extends AbstractMappingUiDefinition<M, T>
+{
+	protected AbstractOneToManyMappingUiDefinition() {
+		super();
+	}
+	
+	
+	public Image getImage() {
+		return JpaMappingImageHelper.imageForAttributeMapping(getKey());
+	}
+	
+	public String getLabel() {
+		return JptUiDetailsMessages.OneToManyMappingUiProvider_label;
+	}
+	
+	public String getLinkLabel() {
+		return JptUiDetailsMessages.OneToManyMappingUiProvider_linkLabel;
+	}
+	
+	public String getKey() {
+		return MappingKeys.ONE_TO_MANY_ATTRIBUTE_MAPPING_KEY;
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/AbstractOneToOneMappingComposite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/AbstractOneToOneMappingComposite.java
new file mode 100644
index 0000000..747d38d
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/AbstractOneToOneMappingComposite.java
@@ -0,0 +1,80 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 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.ui.internal.details;
+
+import org.eclipse.jpt.core.context.Cascade;
+import org.eclipse.jpt.core.context.OneToOneMapping;
+import org.eclipse.jpt.core.context.OneToOneRelationshipReference;
+import org.eclipse.jpt.ui.WidgetFactory;
+import org.eclipse.jpt.ui.details.JpaComposite;
+import org.eclipse.jpt.ui.internal.widgets.Pane;
+import org.eclipse.jpt.utility.internal.model.value.SimplePropertyValueModel;
+import org.eclipse.jpt.utility.internal.model.value.TransformationPropertyValueModel;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+public abstract class AbstractOneToOneMappingComposite<T extends OneToOneMapping, R extends OneToOneRelationshipReference> 
+	extends Pane<T>
+	implements JpaComposite
+{
+	protected AbstractOneToOneMappingComposite(
+			PropertyValueModel<? extends T> subjectHolder,
+	        Composite parent,
+	        WidgetFactory widgetFactory) {
+
+		super(subjectHolder, parent, widgetFactory);
+	}
+
+	@Override
+	protected void initializeLayout(Composite container) {
+		initializeOneToOneCollapsibleSection(container);
+		initializeJoiningStrategyCollapsibleSection(container);
+	}
+	
+	protected void initializeOneToOneCollapsibleSection(Composite container) {
+		container = addCollapsibleSection(
+			container,
+			JptUiDetailsMessages.OneToOneSection_title,
+			new SimplePropertyValueModel<Boolean>(Boolean.TRUE)
+		);
+
+		this.initializeOneToOneSection(container);
+	}
+
+	protected abstract void initializeOneToOneSection(Composite container);
+
+	protected void initializeJoiningStrategyCollapsibleSection(Composite container) {
+		new OneToOneJoiningStrategyPane(this, buildJoiningHolder(), container);
+	}
+
+	protected Composite addPane(Composite container, int groupBoxMargin) {
+		return addSubPane(container, 0, groupBoxMargin, 0, groupBoxMargin);
+	}
+
+	protected PropertyValueModel<R> buildJoiningHolder() {
+		return new TransformationPropertyValueModel<T, R>(
+				getSubjectHolder()) {
+			@SuppressWarnings("unchecked")
+			@Override
+			protected R transform_(T value) {
+				return (R) value.getRelationshipReference();
+			}
+		};
+	}
+
+	protected PropertyValueModel<Cascade> buildCascadeHolder() {
+		return new TransformationPropertyValueModel<T, Cascade>(getSubjectHolder()) {
+			@Override
+			protected Cascade transform_(T value) {
+				return value.getCascade();
+			}
+		};
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/AbstractOneToOneMappingUiDefinition.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/AbstractOneToOneMappingUiDefinition.java
new file mode 100644
index 0000000..fa5b9c6
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/AbstractOneToOneMappingUiDefinition.java
@@ -0,0 +1,41 @@
+/*******************************************************************************
+ *  Copyright (c) 2008, 2009  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.ui.internal.details;
+
+import org.eclipse.jpt.core.MappingKeys;
+import org.eclipse.jpt.core.context.OneToOneMapping;
+import org.eclipse.jpt.ui.internal.JpaMappingImageHelper;
+import org.eclipse.swt.graphics.Image;
+
+public abstract class AbstractOneToOneMappingUiDefinition<M, T extends OneToOneMapping>
+	extends AbstractMappingUiDefinition<M, T>
+{
+	protected AbstractOneToOneMappingUiDefinition() {
+		super();
+	}
+	
+	
+	public Image getImage() {
+		return JpaMappingImageHelper.imageForAttributeMapping(getKey());
+	}
+	
+	public String getLabel() {
+		return JptUiDetailsMessages.OneToOneMappingUiProvider_label;
+	}
+	
+	public String getLinkLabel() {
+		return JptUiDetailsMessages.OneToOneMappingUiProvider_linkLabel;
+	}
+	
+	public String getKey() {
+		return MappingKeys.ONE_TO_ONE_ATTRIBUTE_MAPPING_KEY;
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/AbstractOrderingComposite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/AbstractOrderingComposite.java
new file mode 100644
index 0000000..f429b98
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/AbstractOrderingComposite.java
@@ -0,0 +1,140 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 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.ui.internal.details;
+
+import org.eclipse.jpt.core.context.CollectionMapping;
+import org.eclipse.jpt.core.context.Orderable;
+import org.eclipse.jpt.ui.WidgetFactory;
+import org.eclipse.jpt.ui.internal.widgets.Pane;
+import org.eclipse.jpt.utility.internal.model.value.PropertyAspectAdapter;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.jpt.utility.model.value.WritablePropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Text;
+
+/**
+ * Here the layout of this pane:
+ * <pre>
+ * -----------------------------------------------------------------------------
+ * | - Ordering -------------------------------------------------------------- |
+ * | |                                                                       | |
+ * | | o None                                                                | |
+ * | |                                                                       | |
+ * | | o Primary Key                                                         | |
+ * | |                                                                       | |
+ * | | o Custom                                                              | |
+ * | |   ------------------------------------------------------------------- | |
+ * | |   | I                                                               | | |
+ * | |   ------------------------------------------------------------------- | |
+ * | ------------------------------------------------------------------------- |
+ * -----------------------------------------------------------------------------</pre>
+ *
+ * @see CollectionMapping
+ * @see ManyToManyMappingComposite - A container of this pane
+ * @see OneToManyMappingComposite - A container of this pane
+ *
+ * @version 3.0
+ * @since 1.0
+ */
+public abstract class AbstractOrderingComposite extends Pane<CollectionMapping>
+{
+	/**
+	 * Creates a new <code>OrderingComposite</code>.
+	 *
+	 * @param parentPane The parent container of this one
+	 * @param parent The parent container
+	 */
+	protected AbstractOrderingComposite(Pane<? extends CollectionMapping> parentPane,
+	                         Composite parent) {
+
+		super(parentPane, parent);
+	}
+
+	/**
+	 * Creates a new <code>OrderingComposite</code>.
+	 *
+	 * @param subjectHolder The holder of the subject <code>IMultiRelationshipMapping</code>
+	 * @param parent The parent container
+	 * @param widgetFactory The factory used to create various common widgets
+	 */
+	protected AbstractOrderingComposite(PropertyValueModel<? extends CollectionMapping> subjectHolder,
+	                         Composite parent,
+	                         WidgetFactory widgetFactory) {
+
+		super(subjectHolder, parent, widgetFactory);
+	}
+
+	
+	protected PropertyValueModel<Orderable> buildOrderableHolder() {
+		return new PropertyAspectAdapter<CollectionMapping, Orderable>(getSubjectHolder()) {
+			@Override
+			protected Orderable buildValue_() {
+				return this.subject.getOrderable();
+			}
+		};
+	}
+
+	protected WritablePropertyValueModel<Boolean> buildNoOrderingHolder(PropertyValueModel<Orderable> orderableHolder) {
+		return new PropertyAspectAdapter<Orderable, Boolean>(orderableHolder, Orderable.NO_ORDERING_PROPERTY) {
+			@Override
+			protected Boolean buildValue_() {
+				return Boolean.valueOf(this.subject.isNoOrdering());
+			}
+
+			@Override
+			protected void setValue_(Boolean value) {
+				this.subject.setNoOrdering(value.booleanValue());
+			}
+		};
+	}
+
+	protected WritablePropertyValueModel<Boolean> buildPrimaryKeyOrderingHolder(PropertyValueModel<Orderable> orderableHolder) {
+		return new PropertyAspectAdapter<Orderable, Boolean>(orderableHolder, Orderable.PK_ORDERING_PROPERTY) {
+			@Override
+			protected Boolean buildValue_() {
+				return Boolean.valueOf(this.subject.isPkOrdering());
+			}
+
+			@Override
+			protected void setValue_(Boolean value) {
+				this.subject.setPkOrdering(value.booleanValue());
+			}
+		};
+	}
+
+	protected WritablePropertyValueModel<Boolean> buildCustomOrderingHolder(PropertyValueModel<Orderable> orderableHolder) {
+		return new PropertyAspectAdapter<Orderable, Boolean>(orderableHolder, Orderable.CUSTOM_ORDERING_PROPERTY) {
+			@Override
+			protected Boolean buildValue_() {
+				return Boolean.valueOf(this.subject.isCustomOrdering());
+			}
+
+			@Override
+			protected void setValue_(Boolean value) {
+				this.subject.setCustomOrdering(value.booleanValue());
+			}
+		};
+	}
+
+	protected WritablePropertyValueModel<String> buildSpecifiedOrderByHolder(PropertyValueModel<Orderable> orderableHolder) {
+		return new PropertyAspectAdapter<Orderable, String>(orderableHolder, Orderable.SPECIFIED_ORDER_BY_PROPERTY) {
+			@Override
+			protected String buildValue_() {
+				return this.subject.getSpecifiedOrderBy();
+			}
+
+			@Override
+			protected void setValue_(String value) {
+				this.subject.setSpecifiedOrderBy(value);
+			}
+		};
+	}
+
+}
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/AbstractOverridesComposite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/AbstractOverridesComposite.java
new file mode 100644
index 0000000..e993d63
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/AbstractOverridesComposite.java
@@ -0,0 +1,404 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 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.ui.internal.details;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.ListIterator;
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.jpt.core.context.AssociationOverride;
+import org.eclipse.jpt.core.context.AssociationOverrideContainer;
+import org.eclipse.jpt.core.context.AttributeOverride;
+import org.eclipse.jpt.core.context.AttributeOverrideContainer;
+import org.eclipse.jpt.core.context.BaseOverride;
+import org.eclipse.jpt.core.context.JpaContextNode;
+import org.eclipse.jpt.ui.internal.JpaHelpContextIds;
+import org.eclipse.jpt.ui.internal.util.ControlSwitcher;
+import org.eclipse.jpt.ui.internal.util.PaneEnabler;
+import org.eclipse.jpt.ui.internal.utility.swt.SWTTools;
+import org.eclipse.jpt.ui.internal.widgets.AddRemoveListPane;
+import org.eclipse.jpt.ui.internal.widgets.Pane;
+import org.eclipse.jpt.ui.internal.widgets.AddRemovePane.Adapter;
+import org.eclipse.jpt.utility.internal.StringTools;
+import org.eclipse.jpt.utility.internal.Transformer;
+import org.eclipse.jpt.utility.internal.model.value.CachingTransformationPropertyValueModel;
+import org.eclipse.jpt.utility.internal.model.value.CachingTransformationWritablePropertyValueModel;
+import org.eclipse.jpt.utility.internal.model.value.CompositeListValueModel;
+import org.eclipse.jpt.utility.internal.model.value.ItemPropertyListValueModelAdapter;
+import org.eclipse.jpt.utility.internal.model.value.ListAspectAdapter;
+import org.eclipse.jpt.utility.internal.model.value.SimplePropertyValueModel;
+import org.eclipse.jpt.utility.internal.model.value.TransformationPropertyValueModel;
+import org.eclipse.jpt.utility.internal.model.value.TransformationWritablePropertyValueModel;
+import org.eclipse.jpt.utility.internal.model.value.swing.ObjectListSelectionModel;
+import org.eclipse.jpt.utility.model.value.ListValueModel;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.jpt.utility.model.value.WritablePropertyValueModel;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.ui.part.PageBook;
+
+@SuppressWarnings("nls")
+public abstract class AbstractOverridesComposite<T extends JpaContextNode>
+	extends Pane<T>
+{
+	private Pane<AttributeOverride> attributeOverridePane;
+	private Pane<AssociationOverride> associationOverridePane;
+	
+	private WritablePropertyValueModel<BaseOverride> selectedOverrideHolder;
+	private WritablePropertyValueModel<Boolean> overrideVirtualOverrideHolder;
+	
+	
+	protected AbstractOverridesComposite(
+			Pane<? extends T> parentPane,
+			Composite parent) {
+		
+		super(parentPane, parent, false);
+	}
+	
+	
+	@Override
+	protected void initialize() {
+		super.initialize();
+		this.selectedOverrideHolder = buildSelectedOverrideHolder();
+	}
+	
+	private WritablePropertyValueModel<BaseOverride> buildSelectedOverrideHolder() {
+		return new SimplePropertyValueModel<BaseOverride>();
+	}
+	
+	protected abstract boolean supportsAssociationOverrides();
+	
+	@Override
+	protected void initializeLayout(Composite container) {
+		// Overrides group pane
+		container = addTitledGroup(
+				container,
+				JptUiDetailsMessages.OverridesComposite_attributeOverridesGroup);
+		
+		// Overrides list pane
+		initializeOverridesList(container);
+		
+		int groupBoxMargin = getGroupBoxMargin();
+		
+		// Override Default check box
+		Button overrideCheckBox = addCheckBox(
+				addSubPane(container, 0, groupBoxMargin, 0, groupBoxMargin),
+				JptUiDetailsMessages.OverridesComposite_overrideDefault,
+				getOverrideVirtualOverrideHolder(),
+				null);
+		SWTTools.controlVisibleState(buildSelectedOverrideBooleanHolder(), overrideCheckBox);
+		
+		// Property pane
+		PageBook pageBook = addPageBook(container);
+		initializeOverridePanes(pageBook);
+		installOverrideControlSwitcher(this.selectedOverrideHolder, pageBook);
+	}
+	
+	protected void initializeOverridePanes(PageBook pageBook) {
+		initializeAttributeOverridePane(pageBook);
+		if (supportsAssociationOverrides()) {
+			initializeAssociationOverridePane(pageBook);
+		}
+	}
+	
+	private PropertyValueModel<Boolean> buildSelectedOverrideBooleanHolder() {
+		return new TransformationPropertyValueModel<BaseOverride, Boolean>(this.selectedOverrideHolder) {
+			@Override
+			protected Boolean transform(BaseOverride value) {
+				return Boolean.valueOf(value != null);
+			}
+		};
+	}
+	
+	private void initializeOverridesList(Composite container) {
+		new AddRemoveListPane<T>(
+				this,
+				addSubPane(container, 8),
+				buildOverridesAdapter(),
+				buildOverridesListModel(),
+				this.selectedOverrideHolder,
+				buildOverrideLabelProvider(),
+				JpaHelpContextIds.ENTITY_ATTRIBUTE_OVERRIDES) {
+			
+			@Override
+			protected void initializeButtonPane(Composite container, String helpId) {
+				//no buttons: no way to add/remove/edit overrides, they are all defaulted in
+			}
+			
+			@Override
+			protected void updateButtons() {
+				//no buttons: no way to add/remove/edit overrides, they are all defaulted in
+			}
+		};
+	}
+	
+	protected void initializeAttributeOverridePane(PageBook pageBook) {
+		PropertyValueModel<AttributeOverride>  attributeOverrideHolder = buildAttributeOverrideHolder();
+		this.attributeOverridePane = buildAttributeOverridePane(pageBook, attributeOverrideHolder);
+		installAttributeOverridePaneEnabler(this.attributeOverridePane, attributeOverrideHolder);
+	}
+	
+	protected Pane<AttributeOverride> buildAttributeOverridePane(PageBook pageBook, PropertyValueModel<AttributeOverride> attributeOverrideHolder) {
+		return new AttributeOverrideComposite(this, attributeOverrideHolder, pageBook);
+	}
+	
+	private void installAttributeOverridePaneEnabler(Pane<AttributeOverride> pane, PropertyValueModel<AttributeOverride> overrideHolder) {
+		new PaneEnabler(
+				buildOverrideBooleanHolder(overrideHolder),
+				pane);
+	}
+	
+	private PropertyValueModel<Boolean> buildOverrideBooleanHolder(PropertyValueModel<? extends BaseOverride> overrideHolder) {
+		return new CachingTransformationPropertyValueModel<BaseOverride, Boolean>(overrideHolder) {
+			@Override
+			protected Boolean transform_(BaseOverride value) {
+				return Boolean.valueOf(!value.isVirtual());
+			}
+		};
+	}
+	
+	protected void initializeAssociationOverridePane(PageBook pageBook) {
+		PropertyValueModel<AssociationOverride>  associationOverrideHolder = buildAssociationOverrideHolder();
+		this.associationOverridePane = buildAssociationOverridePane(pageBook, associationOverrideHolder);
+		installAssociationOverridePaneEnabler(this.associationOverridePane, associationOverrideHolder);
+	}
+	
+	protected Pane<AssociationOverride> buildAssociationOverridePane(PageBook pageBook, PropertyValueModel<AssociationOverride> associationOverrideHolder) {
+		return new AssociationOverrideComposite(this, associationOverrideHolder, pageBook);		
+	}
+	
+	private void installAssociationOverridePaneEnabler(Pane<AssociationOverride> pane, PropertyValueModel<AssociationOverride> overrideHolder) {
+		new PaneEnabler(
+				buildOverrideBooleanHolder(overrideHolder),
+				pane);
+	}
+	
+	private void installOverrideControlSwitcher(
+			PropertyValueModel<BaseOverride> overrideHolder,
+			PageBook pageBook) {
+		
+		new ControlSwitcher(
+				overrideHolder,
+				buildPaneTransformer(),
+				pageBook);
+	}
+	
+	private WritablePropertyValueModel<AssociationOverride> buildAssociationOverrideHolder() {
+		return new TransformationWritablePropertyValueModel<BaseOverride, AssociationOverride>(this.selectedOverrideHolder) {
+			@Override
+			protected AssociationOverride transform_(BaseOverride value) {
+				return (value instanceof AssociationOverride) ? (AssociationOverride) value : null;
+			}
+		};
+	}
+	
+	private WritablePropertyValueModel<AttributeOverride> buildAttributeOverrideHolder() {
+		return new TransformationWritablePropertyValueModel<BaseOverride, AttributeOverride>(this.selectedOverrideHolder) {
+			@Override
+			protected AttributeOverride transform_(BaseOverride value) {
+				return (value instanceof AttributeOverride) ? (AttributeOverride) value : null;
+			}
+		};
+	}
+	
+	private ListValueModel<AssociationOverride> buildDefaultAssociationOverridesListHolder(PropertyValueModel<AssociationOverrideContainer> containerHolder) {
+		return new ListAspectAdapter<AssociationOverrideContainer, AssociationOverride>(containerHolder, AssociationOverrideContainer.VIRTUAL_ASSOCIATION_OVERRIDES_LIST) {
+			@Override
+			protected ListIterator<AssociationOverride> listIterator_() {
+				return this.subject.virtualAssociationOverrides();
+			}
+			
+			@Override
+			protected int size_() {
+				return this.subject.virtualAssociationOverridesSize();
+			}
+		};
+	}
+	
+	private ListValueModel<AttributeOverride> buildDefaultAttributeOverridesListHolder(PropertyValueModel<AttributeOverrideContainer> containerHolder) {
+		return new ListAspectAdapter<AttributeOverrideContainer, AttributeOverride>(containerHolder, AttributeOverrideContainer.VIRTUAL_ATTRIBUTE_OVERRIDES_LIST) {
+			@Override
+			protected ListIterator<AttributeOverride> listIterator_() {
+				return this.subject.virtualAttributeOverrides();
+			}
+			
+			@Override
+			protected int size_() {
+				return this.subject.virtualAttributeOverridesSize();
+			}
+		};
+	}
+	
+	protected WritablePropertyValueModel<Boolean> getOverrideVirtualOverrideHolder() {
+		if (this.overrideVirtualOverrideHolder == null) {
+			this.overrideVirtualOverrideHolder = buildOverrideVirtualOverrideHolder();
+		}
+		return this.overrideVirtualOverrideHolder;
+	}
+	
+	private WritablePropertyValueModel<Boolean> buildOverrideVirtualOverrideHolder() {
+		return new CachingTransformationWritablePropertyValueModel<BaseOverride, Boolean>(this.selectedOverrideHolder) {
+			@Override
+			public void setValue(Boolean value) {
+				updateOverride(value.booleanValue());
+			}
+			
+			@Override
+			protected Boolean transform_(BaseOverride value) {
+				return Boolean.valueOf(!value.isVirtual());
+			}
+		};
+	}
+	
+	private String buildOverrideDisplayString(BaseOverride override) {
+		String overrideType;
+		
+		// Retrieve the type
+		if (override instanceof AssociationOverride) {
+			overrideType = JptUiDetailsMessages.OverridesComposite_association;
+		}
+		else {
+			overrideType = JptUiDetailsMessages.OverridesComposite_attribute;
+		}
+		
+		// Format the name
+		String name = override.getName();
+		
+		if (StringTools.stringIsEmpty(name)) {
+			name = JptUiDetailsMessages.OverridesComposite_noName;
+		}
+		
+		// Format: <name> (Attribute/Association Override)
+		StringBuilder sb = new StringBuilder();
+		sb.append(name);
+		sb.append(" (");
+		sb.append(overrideType);
+		sb.append(") ");
+		return sb.toString();
+	}
+	
+	protected ILabelProvider buildOverrideLabelProvider() {
+		return new LabelProvider() {
+			@Override
+			public String getText(Object element) {
+				return buildOverrideDisplayString((BaseOverride) element);
+			}
+		};
+	}
+	
+	protected Adapter buildOverridesAdapter() {
+		return new AddRemoveListPane.AbstractAdapter() {
+			public void addNewItem(ObjectListSelectionModel listSelectionModel) {
+				//no way to add/remove/edit overrides, they are all defaulted in
+			}
+			
+			public void removeSelectedItems(ObjectListSelectionModel listSelectionModel) {
+				//no way to add/remove/edit overrides, they are all defaulted in
+			}
+		};
+	}
+	
+	protected ListValueModel<BaseOverride> buildOverridesListHolder() {
+		PropertyValueModel<AttributeOverrideContainer> attributeOverrideContainerHolder = buildAttributeOverrideContainerHolder();
+		List<ListValueModel<? extends BaseOverride>> list = new ArrayList<ListValueModel<? extends BaseOverride>>();
+		
+		list.add(buildSpecifiedAttributeOverridesListHolder(attributeOverrideContainerHolder));
+		list.add(buildDefaultAttributeOverridesListHolder(attributeOverrideContainerHolder));
+		
+		if (supportsAssociationOverrides()) {
+			PropertyValueModel<AssociationOverrideContainer> associationOverrideContainerHolder = buildAssociationOverrideContainerHolder();
+			list.add(buildSpecifiedAssociationOverridesListHolder(associationOverrideContainerHolder));
+			list.add(buildDefaultAssociationOverridesListHolder(associationOverrideContainerHolder));
+		}
+		
+		return new CompositeListValueModel<ListValueModel<? extends BaseOverride>, BaseOverride>(list);
+	}
+	
+	protected abstract PropertyValueModel<AttributeOverrideContainer> buildAttributeOverrideContainerHolder();
+	
+	protected abstract PropertyValueModel<AssociationOverrideContainer> buildAssociationOverrideContainerHolder();
+	
+	private ListValueModel<BaseOverride> buildOverridesListModel() {
+		return new ItemPropertyListValueModelAdapter<BaseOverride>(
+				buildOverridesListHolder(),
+				BaseOverride.NAME_PROPERTY);
+	}
+	
+	private Transformer<BaseOverride, Control> buildPaneTransformer() {
+		return new Transformer<BaseOverride, Control>() {
+			public Control transform(BaseOverride override) {
+				return AbstractOverridesComposite.this.transformSelectedOverride(override);
+			}
+		};
+	}
+	
+	/**
+	 * Given the selected override, return the control that will be displayed
+	 */
+	protected Control transformSelectedOverride(BaseOverride selectedOverride) {
+		if (selectedOverride instanceof AttributeOverride) {
+			return AbstractOverridesComposite.this.attributeOverridePane.getControl();
+		}
+		
+		if (selectedOverride instanceof AssociationOverride) {
+			return AbstractOverridesComposite.this.associationOverridePane.getControl();
+		}
+		
+		return null;
+	}
+	
+	private ListValueModel<AssociationOverride> buildSpecifiedAssociationOverridesListHolder(PropertyValueModel<AssociationOverrideContainer> containerHolder) {
+		return new ListAspectAdapter<AssociationOverrideContainer, AssociationOverride>(containerHolder, AssociationOverrideContainer.SPECIFIED_ASSOCIATION_OVERRIDES_LIST) {
+			@Override
+			protected ListIterator<AssociationOverride> listIterator_() {
+				return this.subject.specifiedAssociationOverrides();
+			}
+			
+			@Override
+			protected int size_() {
+				return this.subject.specifiedAssociationOverridesSize();
+			}
+		};
+	}
+	
+	private ListValueModel<AttributeOverride> buildSpecifiedAttributeOverridesListHolder(PropertyValueModel<AttributeOverrideContainer> containerHolder) {
+		return new ListAspectAdapter<AttributeOverrideContainer, AttributeOverride>(containerHolder, AttributeOverrideContainer.SPECIFIED_ATTRIBUTE_OVERRIDES_LIST) {
+			@Override
+			protected ListIterator<AttributeOverride> listIterator_() {
+				return this.subject.specifiedAttributeOverrides();
+			}
+			
+			@Override
+			protected int size_() {
+				return this.subject.specifiedAttributeOverridesSize();
+			}
+		};
+	}
+	
+	private void updateOverride(boolean selected) {
+		if (isPopulating()) {
+			return;
+		}
+		
+		setPopulating(true);
+		
+		try {
+			BaseOverride override = this.selectedOverrideHolder.getValue();
+			
+			BaseOverride newOverride = override.setVirtual(!selected);
+			this.selectedOverrideHolder.setValue(newOverride);
+		}
+		finally {
+			setPopulating(false);
+		}
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/AbstractPrimaryKeyJoinColumnsComposite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/AbstractPrimaryKeyJoinColumnsComposite.java
new file mode 100644
index 0000000..6795998
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/AbstractPrimaryKeyJoinColumnsComposite.java
@@ -0,0 +1,353 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2009 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.ui.internal.details;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.ListIterator;
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.jpt.core.context.BaseJoinColumn;
+import org.eclipse.jpt.core.context.Entity;
+import org.eclipse.jpt.core.context.NamedColumn;
+import org.eclipse.jpt.core.context.PrimaryKeyJoinColumn;
+import org.eclipse.jpt.ui.internal.JpaHelpContextIds;
+import org.eclipse.jpt.ui.internal.util.PaneEnabler;
+import org.eclipse.jpt.ui.internal.widgets.AddRemoveListPane;
+import org.eclipse.jpt.ui.internal.widgets.Pane;
+import org.eclipse.jpt.ui.internal.widgets.PostExecution;
+import org.eclipse.jpt.ui.internal.widgets.AddRemovePane.AbstractAdapter;
+import org.eclipse.jpt.ui.internal.widgets.AddRemovePane.Adapter;
+import org.eclipse.jpt.utility.internal.model.value.CompositeListValueModel;
+import org.eclipse.jpt.utility.internal.model.value.ItemPropertyListValueModelAdapter;
+import org.eclipse.jpt.utility.internal.model.value.ListAspectAdapter;
+import org.eclipse.jpt.utility.internal.model.value.ListPropertyValueModelAdapter;
+import org.eclipse.jpt.utility.internal.model.value.SimplePropertyValueModel;
+import org.eclipse.jpt.utility.internal.model.value.swing.ObjectListSelectionModel;
+import org.eclipse.jpt.utility.model.value.ListValueModel;
+import org.eclipse.jpt.utility.model.value.WritablePropertyValueModel;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Group;
+
+/**
+ * Here the layout of this pane:
+ * <pre>
+ * -----------------------------------------------------------------------------
+ * | - Join Columns ---------------------------------------------------------- |
+ * | |                                                                       | |
+ * | | x Override Default                                                    | |
+ * | |                                                                       | |
+ * | | --------------------------------------------------------------------- | |
+ * | | |                                                                   | | |
+ * | | | AddRemoveListPane                                                 | | |
+ * | | |                                                                   | | |
+ * | | --------------------------------------------------------------------- | |
+ * | ------------------------------------------------------------------------- |
+ * -----------------------------------------------------------------------------</pre>
+ *
+ * @see Entity
+ * @see InheritanceComposite - The container of this pane
+ *
+ * @version 2.0
+ * @since 2.0
+ */
+public abstract class AbstractPrimaryKeyJoinColumnsComposite<T extends Entity> extends Pane<T>
+{
+	protected WritablePropertyValueModel<PrimaryKeyJoinColumn> joinColumnHolder;
+
+	/**
+	 * Creates a new <code>PrimaryKeyJoinColumnsComposite</code>.
+	 *
+	 * @param parentPane The parent controller of this one
+	 * @param parent The parent container
+	 */
+	public AbstractPrimaryKeyJoinColumnsComposite(Pane<? extends T> subjectHolder,
+	                                      Composite parent) {
+
+		super(subjectHolder, parent, false);
+	}
+
+	private void addJoinColumn(PrimaryKeyJoinColumnStateObject stateObject) {
+
+		Entity subject = getSubject();
+		int index = subject.specifiedPrimaryKeyJoinColumnsSize();
+
+		PrimaryKeyJoinColumn joinColumn = subject.addSpecifiedPrimaryKeyJoinColumn(index);
+		stateObject.updateJoinColumn(joinColumn);
+	}
+
+	private void addPrimaryKeyJoinColumn() {
+
+		PrimaryKeyJoinColumnDialog dialog = new PrimaryKeyJoinColumnDialog(
+			getShell(),
+			getSubject(),
+			null
+		);
+
+		dialog.openDialog(buildAddPrimaryKeyJoinColumnPostExecution());
+	}
+
+	private PostExecution<PrimaryKeyJoinColumnDialog> buildAddPrimaryKeyJoinColumnPostExecution() {
+		return new PostExecution<PrimaryKeyJoinColumnDialog>() {
+			public void execute(PrimaryKeyJoinColumnDialog dialog) {
+				if (dialog.wasConfirmed()) {
+					addJoinColumn(dialog.getSubject());
+				}
+			}
+		};
+	}
+
+	protected abstract ListValueModel<? extends PrimaryKeyJoinColumn> buildDefaultJoinColumnsListHolder();
+
+	private PostExecution<PrimaryKeyJoinColumnDialog> buildEditPrimaryKeyJoinColumnPostExecution() {
+		return new PostExecution<PrimaryKeyJoinColumnDialog>() {
+			public void execute(PrimaryKeyJoinColumnDialog dialog) {
+				if (dialog.wasConfirmed()) {
+					editJoinColumn(dialog.getSubject());
+				}
+			}
+		};
+	}
+
+	private WritablePropertyValueModel<PrimaryKeyJoinColumn> buildJoinColumnHolder() {
+		return new SimplePropertyValueModel<PrimaryKeyJoinColumn>();
+	}
+
+	private String buildJoinColumnLabel(PrimaryKeyJoinColumn joinColumn) {
+		if (joinColumn.isVirtual()) {
+			return NLS.bind(
+				JptUiDetailsMessages.PrimaryKeyJoinColumnsComposite_mappingBetweenTwoParamsDefault,
+				joinColumn.getName(),
+				joinColumn.getReferencedColumnName()
+			);
+		}
+
+		if (joinColumn.getSpecifiedName() == null) {
+			if (joinColumn.getSpecifiedReferencedColumnName() == null) {
+				return NLS.bind(
+					JptUiDetailsMessages.PrimaryKeyJoinColumnsComposite_mappingBetweenTwoParamsBothDefault,
+					joinColumn.getName(),
+					joinColumn.getReferencedColumnName()
+				);
+			}
+
+			return NLS.bind(
+				JptUiDetailsMessages.PrimaryKeyJoinColumnsComposite_mappingBetweenTwoParamsFirstDefault,
+				joinColumn.getName(),
+				joinColumn.getReferencedColumnName()
+			);
+		}
+
+		if (joinColumn.getSpecifiedReferencedColumnName() == null) {
+			return NLS.bind(
+				JptUiDetailsMessages.PrimaryKeyJoinColumnsComposite_mappingBetweenTwoParamsSecDefault,
+				joinColumn.getName(),
+				joinColumn.getReferencedColumnName()
+			);
+		}
+
+		return NLS.bind(
+			JptUiDetailsMessages.PrimaryKeyJoinColumnsComposite_mappingBetweenTwoParams,
+			joinColumn.getName(),
+			joinColumn.getReferencedColumnName()
+		);
+	}
+
+	private Adapter buildJoinColumnsAdapter() {
+		return new AbstractAdapter() {
+			public void addNewItem(ObjectListSelectionModel listSelectionModel) {
+				addPrimaryKeyJoinColumn();
+			}
+
+			@Override
+			public boolean hasOptionalButton() {
+				return true;
+			}
+
+			@Override
+			public String optionalButtonText() {
+				return JptUiDetailsMessages.PrimaryKeyJoinColumnsComposite_edit;
+			}
+
+			@Override
+			public void optionOnSelection(ObjectListSelectionModel listSelectionModel) {
+				editPrimaryKeyJoinColumn(listSelectionModel);
+			}
+
+			public void removeSelectedItems(ObjectListSelectionModel listSelectionModel) {
+
+				int[] selectedIndices = listSelectionModel.selectedIndices();
+				Entity entity = getSubject();
+
+				for (int index = selectedIndices.length; --index >= 0; ) {
+					entity.removeSpecifiedPrimaryKeyJoinColumn(selectedIndices[index]);
+				}
+			}
+		};
+	}
+
+	private ILabelProvider buildJoinColumnsListLabelProvider() {
+		return new LabelProvider() {
+			@Override
+			public String getText(Object element) {
+				return buildJoinColumnLabel((PrimaryKeyJoinColumn) element);
+			}
+		};
+	}
+
+	private WritablePropertyValueModel<Boolean> buildOverrideDefaultJoinColumnHolder() {
+		return new OverrideDefaultJoinColumnHolder();
+	}
+
+	private ListValueModel<PrimaryKeyJoinColumn> buildPrimaryKeyJoinColumnsListHolder() {
+		List<ListValueModel<? extends PrimaryKeyJoinColumn>> list = new ArrayList<ListValueModel<? extends PrimaryKeyJoinColumn>>();
+		list.add(buildSpecifiedJoinColumnsListHolder());
+		list.add(buildDefaultJoinColumnsListHolder());
+		return new CompositeListValueModel<ListValueModel<? extends PrimaryKeyJoinColumn>, PrimaryKeyJoinColumn>(list);
+	}
+
+	private ListValueModel<PrimaryKeyJoinColumn> buildPrimaryKeyJoinColumnsListModel() {
+		return new ItemPropertyListValueModelAdapter<PrimaryKeyJoinColumn>(
+			buildPrimaryKeyJoinColumnsListHolder(),
+			NamedColumn.SPECIFIED_NAME_PROPERTY,
+			NamedColumn.DEFAULT_NAME_PROPERTY,
+			BaseJoinColumn.SPECIFIED_REFERENCED_COLUMN_NAME_PROPERTY,
+			BaseJoinColumn.DEFAULT_REFERENCED_COLUMN_NAME_PROPERTY
+		);
+	}
+
+	private ListValueModel<PrimaryKeyJoinColumn> buildSpecifiedJoinColumnsListHolder() {
+		return new ListAspectAdapter<Entity, PrimaryKeyJoinColumn>(getSubjectHolder(), Entity.SPECIFIED_PRIMARY_KEY_JOIN_COLUMNS_LIST) {
+			@Override
+			protected ListIterator<PrimaryKeyJoinColumn> listIterator_() {
+				return subject.specifiedPrimaryKeyJoinColumns();
+			}
+
+			@Override
+			protected int size_() {
+				return subject.specifiedPrimaryKeyJoinColumnsSize();
+			}
+		};
+	}
+
+	private void editJoinColumn(PrimaryKeyJoinColumnStateObject stateObject) {
+		stateObject.updateJoinColumn(stateObject.getJoinColumn());
+	}
+
+	private void editPrimaryKeyJoinColumn(ObjectListSelectionModel listSelectionModel) {
+
+		PrimaryKeyJoinColumn joinColumn = (PrimaryKeyJoinColumn) listSelectionModel.selectedValue();
+
+		PrimaryKeyJoinColumnDialog dialog = new PrimaryKeyJoinColumnDialog(
+			getShell(),
+			getSubject(),
+			joinColumn
+		);
+
+		dialog.openDialog(buildEditPrimaryKeyJoinColumnPostExecution());
+	}
+
+	/*
+	 * (non-Javadoc)
+	 */
+	@Override
+	protected void initialize() {
+		super.initialize();
+		joinColumnHolder = buildJoinColumnHolder();
+	}
+
+	/*
+	 * (non-Javadoc)
+	 */
+	@Override
+	protected void initializeLayout(Composite container) {
+
+		// Primary Key Join Columns group pane
+		Group groupPane = addTitledGroup(
+			container,
+			JptUiDetailsMessages.PrimaryKeyJoinColumnsComposite_primaryKeyJoinColumn
+		);
+
+		// Override Default Join Columns check box
+		addCheckBox(
+			addSubPane(groupPane, 8),
+			JptUiDetailsMessages.PrimaryKeyJoinColumnsComposite_overrideDefaultPrimaryKeyJoinColumns,
+			buildOverrideDefaultJoinColumnHolder(),
+			null
+		);
+
+		// Primary Key Join Columns list pane
+		AddRemoveListPane<Entity> joinColumnsListPane = new AddRemoveListPane<Entity>(
+			this,
+			groupPane,
+			buildJoinColumnsAdapter(),
+			buildPrimaryKeyJoinColumnsListModel(),
+			joinColumnHolder,
+			buildJoinColumnsListLabelProvider(),
+			JpaHelpContextIds.MAPPING_JOIN_TABLE_COLUMNS
+		);
+
+		installJoinColumnsListPaneEnabler(joinColumnsListPane);
+	}
+
+	private void installJoinColumnsListPaneEnabler(AddRemoveListPane<Entity> pane) {
+		new PaneEnabler(
+			buildOverrideDefaultJoinColumnHolder(),
+			pane
+		);
+	}
+
+	private void updateJoinColumns(boolean selected) {
+
+		if (isPopulating()) {
+			return;
+		}
+
+		setPopulating(true);
+
+		try {
+			// Add a join column by creating a specified one using the default
+			// one if it exists
+			if (selected) {
+
+				switchDefaultToSpecified();
+			}
+			// Remove all the specified join columns
+			else {
+				for (int index = getSubject().specifiedPrimaryKeyJoinColumnsSize(); --index >= 0; ) {
+					getSubject().removeSpecifiedPrimaryKeyJoinColumn(index);
+				}
+			}
+		}
+		finally {
+			setPopulating(false);
+		}
+	}
+
+	protected abstract void switchDefaultToSpecified();
+	
+	private class OverrideDefaultJoinColumnHolder extends ListPropertyValueModelAdapter<Boolean>
+	                                              implements WritablePropertyValueModel<Boolean> {
+
+		public OverrideDefaultJoinColumnHolder() {
+			super(buildSpecifiedJoinColumnsListHolder());
+		}
+
+		@Override
+		protected Boolean buildValue() {
+			return listHolder.size() > 0;
+		}
+
+		public void setValue(Boolean value) {
+			updateJoinColumns(value);
+		}
+	}
+}
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/AbstractSecondaryTablesComposite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/AbstractSecondaryTablesComposite.java
new file mode 100644
index 0000000..19b1881
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/AbstractSecondaryTablesComposite.java
@@ -0,0 +1,177 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2010 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.ui.internal.details;
+
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.jface.window.Window;
+import org.eclipse.jpt.core.context.Entity;
+import org.eclipse.jpt.core.context.SecondaryTable;
+import org.eclipse.jpt.ui.WidgetFactory;
+import org.eclipse.jpt.ui.internal.widgets.AddRemoveListPane;
+import org.eclipse.jpt.ui.internal.widgets.Pane;
+import org.eclipse.jpt.utility.internal.model.value.SimplePropertyValueModel;
+import org.eclipse.jpt.utility.internal.model.value.swing.ObjectListSelectionModel;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.jpt.utility.model.value.WritablePropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * Here the layout of this pane:
+ * <pre>
+ * -----------------------------------------------------------------------------
+ * | ------------------------------------------------------------------------- |
+ * | |                                                                       | |
+ * | | AddRemoveListPane                                                     | |
+ * | |                                                                       | |
+ * | ------------------------------------------------------------------------- |
+ * | ------------------------------------------------------------------------- |
+ * | |                                                                       | |
+ * | | PrimaryKeyJoinColumnsInSecondaryTableComposite                        | |
+ * | |                                                                       | |
+ * | ------------------------------------------------------------------------- |
+ * -----------------------------------------------------------------------------</pre>
+ *
+ * @see OrmEntity
+ * @see OrmEntityComposite - The container of this pane
+ * @see AddRemoveListPane
+ * @see PrimaryKeyJoinColumnsInSecondaryTableComposite
+ *
+ * @version 2.0
+ * @since 1.0
+ */
+public abstract class AbstractSecondaryTablesComposite<T extends Entity> extends Pane<T>
+{
+	/**
+	 * Creates a new <code>SecondaryTablesComposite</code>.
+	 *
+	 * @param parentPane The parent container of this one
+	 * @param parent The parent container
+	 */
+	public AbstractSecondaryTablesComposite(Pane<? extends T> parentPane,
+	                                Composite parent) {
+
+		super(parentPane, parent, false);
+	}
+
+	/**
+	 * Creates a new <code>SecondaryTablesComposite</code>.
+	 *
+	 * @param subjectHolder The holder of the subject <code>IEntity</code>
+	 * @param parent The parent container
+	 * @param widgetFactory The factory used to create various common widgets
+	 */
+	public AbstractSecondaryTablesComposite(PropertyValueModel<? extends T> subjectHolder,
+	                                Composite parent,
+	                                WidgetFactory widgetFactory) {
+
+		super(subjectHolder, parent, widgetFactory);
+	}
+
+	protected void addSecondaryTableFromDialog(SecondaryTableDialog dialog, ObjectListSelectionModel listSelectionModel) {
+		if (dialog.open() != Window.OK) {
+			return;
+		}
+
+		SecondaryTable secondaryTable = this.getSubject().addSpecifiedSecondaryTable();
+		secondaryTable.setSpecifiedName(dialog.getSelectedTable());
+		secondaryTable.setSpecifiedCatalog(dialog.getSelectedCatalog());
+		secondaryTable.setSpecifiedSchema(dialog.getSelectedSchema());
+
+		listSelectionModel.setSelectedValue(secondaryTable);
+	}
+
+	protected WritablePropertyValueModel<SecondaryTable> buildSecondaryTableHolder() {
+		return new SimplePropertyValueModel<SecondaryTable>();
+	}
+
+	protected ILabelProvider buildSecondaryTableLabelProvider() {
+		return new LabelProvider() {
+			@Override
+			public String getText(Object element) {
+				// TODO display a qualified name instead
+				SecondaryTable secondaryTable = (SecondaryTable) element;
+				if (secondaryTable.getName() != null) {
+					return secondaryTable.getName();
+				}
+				return "";//TODO
+			}
+		};
+	}
+
+	protected SecondaryTableDialog buildSecondaryTableDialogForAdd() {
+		return new SecondaryTableDialog(getShell(), getSubject().getJpaProject(), getSubject().getTable().getDefaultCatalog(), getSubject().getTable().getDefaultSchema());
+	}
+	
+	protected AddRemoveListPane.Adapter buildSecondaryTablesAdapter() {
+		return new AddRemoveListPane.AbstractAdapter() {
+
+			public void addNewItem(ObjectListSelectionModel listSelectionModel) {
+				SecondaryTableDialog dialog = buildSecondaryTableDialogForAdd();
+				addSecondaryTableFromDialog(dialog, listSelectionModel);
+			}
+
+			@Override
+			public boolean hasOptionalButton() {
+				return true;
+			}
+
+			@Override
+			public String optionalButtonText() {
+				return JptUiDetailsMessages.SecondaryTablesComposite_edit;
+			}
+
+			@Override
+			public void optionOnSelection(ObjectListSelectionModel listSelectionModel) {
+				SecondaryTable secondaryTable = (SecondaryTable) listSelectionModel.selectedValue();
+				SecondaryTableDialog dialog = new SecondaryTableDialog(getShell(), getSubject().getJpaProject(), secondaryTable);
+				editSecondaryTableFromDialog(dialog, secondaryTable);
+			}
+
+			public void removeSelectedItems(ObjectListSelectionModel listSelectionModel) {
+				Entity entity = getSubject();
+				int[] selectedIndices = listSelectionModel.selectedIndices();
+
+				for (int index = selectedIndices.length; --index >= 0; ) {
+					entity.removeSpecifiedSecondaryTable(selectedIndices[index]);
+				}
+			}
+			
+			@Override
+			public boolean enableOptionOnSelectionChange(ObjectListSelectionModel listSelectionModel) {
+				if (listSelectionModel.selectedValuesSize() != 1) {
+					return false;
+				}
+				SecondaryTable secondaryTable = (SecondaryTable) listSelectionModel.selectedValue();
+				return !secondaryTable.isVirtual();
+			}
+			
+			@Override
+			public boolean enableRemoveOnSelectionChange(ObjectListSelectionModel listSelectionModel) {
+				if (listSelectionModel.selectedValue() == null) {
+					return false;
+				}
+				SecondaryTable secondaryTable = (SecondaryTable) listSelectionModel.selectedValue();
+				return !secondaryTable.isVirtual();				
+			}
+		};
+	}
+
+	protected void editSecondaryTableFromDialog(SecondaryTableDialog dialog, SecondaryTable secondaryTable) {
+		if (dialog.open() != Window.OK) {
+			return;
+		}
+
+		secondaryTable.setSpecifiedName(dialog.getSelectedTable());
+		secondaryTable.setSpecifiedCatalog(dialog.getSelectedCatalog());
+		secondaryTable.setSpecifiedSchema(dialog.getSelectedSchema());
+	}
+
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/AbstractTransientMappingUiDefinition.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/AbstractTransientMappingUiDefinition.java
new file mode 100644
index 0000000..ae680dd
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/AbstractTransientMappingUiDefinition.java
@@ -0,0 +1,41 @@
+/*******************************************************************************
+ *  Copyright (c) 2008, 2009  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.ui.internal.details;
+
+import org.eclipse.jpt.core.MappingKeys;
+import org.eclipse.jpt.core.context.TransientMapping;
+import org.eclipse.jpt.ui.internal.JpaMappingImageHelper;
+import org.eclipse.swt.graphics.Image;
+
+public abstract class AbstractTransientMappingUiDefinition<M, T extends TransientMapping>
+	extends AbstractMappingUiDefinition<M, T>
+{
+	protected AbstractTransientMappingUiDefinition() {
+		super();
+	}
+	
+	
+	public Image getImage() {
+		return JpaMappingImageHelper.imageForAttributeMapping(getKey());
+	}
+	
+	public String getLabel() {
+		return JptUiDetailsMessages.TransientMappingUiProvider_label;
+	}
+	
+	public String getLinkLabel() {
+		return JptUiDetailsMessages.TransientMappingUiProvider_linkLabel;
+	}
+	
+	public String getKey() {
+		return MappingKeys.TRANSIENT_ATTRIBUTE_MAPPING_KEY;
+	}		
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/AbstractVersionMappingComposite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/AbstractVersionMappingComposite.java
new file mode 100644
index 0000000..d3780f8
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/AbstractVersionMappingComposite.java
@@ -0,0 +1,161 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 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.ui.internal.details;
+
+import org.eclipse.jpt.core.context.Column;
+import org.eclipse.jpt.core.context.Converter;
+import org.eclipse.jpt.core.context.ConvertibleMapping;
+import org.eclipse.jpt.core.context.TemporalConverter;
+import org.eclipse.jpt.core.context.VersionMapping;
+import org.eclipse.jpt.ui.WidgetFactory;
+import org.eclipse.jpt.ui.details.JpaComposite;
+import org.eclipse.jpt.ui.internal.widgets.Pane;
+import org.eclipse.jpt.utility.internal.model.value.PropertyAspectAdapter;
+import org.eclipse.jpt.utility.internal.model.value.SimplePropertyValueModel;
+import org.eclipse.jpt.utility.internal.model.value.TransformationPropertyValueModel;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.jpt.utility.model.value.WritablePropertyValueModel;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * Here the layout of this pane:
+ * <pre>
+ * -----------------------------------------------------------------------------
+ * | ------------------------------------------------------------------------- |
+ * | |                                                                       | |
+ * | | ColumnComposite                                                       | |
+ * | |                                                                       | |
+ * | ------------------------------------------------------------------------- |
+ * | ------------------------------------------------------------------------- |
+ * | |                                                                       | |
+ * | | TemporalTypeComposite                                                 | |
+ * | |                                                                       | |
+ * | ------------------------------------------------------------------------- |
+ * -----------------------------------------------------------------------------</pre>
+ *
+ * @see VersionMapping
+ * @see ColumnComposite
+ * @see TemporalTypeComposite
+ *
+ * @version 2.3
+ * @since 1.0
+ */
+public abstract class AbstractVersionMappingComposite<T extends VersionMapping> 
+	extends Pane<T>
+	implements JpaComposite
+{
+	/**
+	 * Creates a new <code>VersionMappingComposite</code>.
+	 *
+	 * @param subjectHolder The holder of the subject <code>IVersionMapping</code>
+	 * @param parent The parent container
+	 * @param widgetFactory The factory used to create various common widgets
+	 */
+	protected AbstractVersionMappingComposite(PropertyValueModel<? extends T> subjectHolder,
+	                               Composite parent,
+	                               WidgetFactory widgetFactory) {
+
+		super(subjectHolder, parent, widgetFactory);
+	}
+
+	@Override
+	protected void initializeLayout(Composite container) {
+		initializeVersionCollapsibleSection(container);
+		initializeTypeCollapsibleSection(container);
+	}
+	
+	protected void initializeVersionCollapsibleSection(Composite container) {
+		container = addCollapsibleSection(
+			container,
+			JptUiDetailsMessages.VersionSection_title,
+			new SimplePropertyValueModel<Boolean>(Boolean.TRUE)
+		);
+
+		this.initializeVersionSection(container);
+	}
+
+	protected abstract void initializeVersionSection(Composite container);
+
+	protected void initializeTypeCollapsibleSection(Composite container) {
+		container = addCollapsibleSection(
+			container,
+			JptUiDetailsMessages.TypeSection_type
+		);
+		this.initializeTypeSection(container);
+	}
+	
+	protected void initializeTypeSection(Composite container) {
+		((GridLayout) container.getLayout()).numColumns = 2;
+
+		// No converter
+		Button noConverterButton = addRadioButton(
+			container, 
+			JptUiDetailsMessages.TypeSection_default, 
+			buildConverterBooleanHolder(Converter.NO_CONVERTER), 
+			null);
+		((GridData) noConverterButton.getLayoutData()).horizontalSpan = 2;
+				
+		PropertyValueModel<Converter> converterHolder = buildConverterHolder();
+		// Temporal
+		addRadioButton(
+			container, 
+			JptUiDetailsMessages.TypeSection_temporal, 
+			buildConverterBooleanHolder(Converter.TEMPORAL_CONVERTER), 
+			null);
+		registerSubPane(new TemporalTypeComposite(buildTemporalConverterHolder(converterHolder), container, getWidgetFactory()));
+	}
+
+	protected PropertyValueModel<Column> buildColumnHolder() {
+		return new TransformationPropertyValueModel<T, Column>(getSubjectHolder()) {
+			@Override
+			protected Column transform_(T value) {
+				return value.getColumn();
+			}
+		};
+	}
+
+	protected WritablePropertyValueModel<Boolean> buildConverterBooleanHolder(final String converterType) {
+		return new PropertyAspectAdapter<T, Boolean>(getSubjectHolder(), ConvertibleMapping.CONVERTER_PROPERTY) {
+			@Override
+			protected Boolean buildValue_() {
+				Converter converter = this.subject.getConverter();
+				return Boolean.valueOf(converter.getType() == converterType);
+			}
+
+			@Override
+			protected void setValue_(Boolean value) {
+				if (value.booleanValue()) {
+					this.subject.setConverter(converterType);
+				}
+			}
+		};
+	}
+
+	private PropertyValueModel<Converter> buildConverterHolder() {
+		return new PropertyAspectAdapter<VersionMapping, Converter>(getSubjectHolder(), ConvertibleMapping.CONVERTER_PROPERTY) {
+			@Override
+			protected Converter buildValue_() {
+				return this.subject.getConverter();
+			}
+		};
+	}
+	
+	private PropertyValueModel<TemporalConverter> buildTemporalConverterHolder(PropertyValueModel<Converter> converterHolder) {
+		return new TransformationPropertyValueModel<Converter, TemporalConverter>(converterHolder) {
+			@Override
+			protected TemporalConverter transform_(Converter converter) {
+				return converter.getType() == Converter.TEMPORAL_CONVERTER ? (TemporalConverter) converter : null;
+			}
+		};
+	}
+}
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/AbstractVersionMappingUiDefinition.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/AbstractVersionMappingUiDefinition.java
new file mode 100644
index 0000000..69bae06
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/AbstractVersionMappingUiDefinition.java
@@ -0,0 +1,41 @@
+/*******************************************************************************
+ *  Copyright (c) 2008, 2009  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.ui.internal.details;
+
+import org.eclipse.jpt.core.MappingKeys;
+import org.eclipse.jpt.core.context.VersionMapping;
+import org.eclipse.jpt.ui.internal.JpaMappingImageHelper;
+import org.eclipse.swt.graphics.Image;
+
+public abstract class AbstractVersionMappingUiDefinition<M, T extends VersionMapping>
+	extends AbstractMappingUiDefinition<M, T>
+{
+	protected AbstractVersionMappingUiDefinition() {
+		super();
+	}
+	
+	
+	public Image getImage() {
+		return JpaMappingImageHelper.imageForAttributeMapping(getKey());
+	}
+	
+	public String getLabel() {
+		return JptUiDetailsMessages.VersionMappingUiProvider_label;
+	}
+	
+	public String getLinkLabel() {
+		return JptUiDetailsMessages.VersionMappingUiProvider_linkLabel;
+	}
+	
+	public String getKey() {
+		return MappingKeys.VERSION_ATTRIBUTE_MAPPING_KEY;
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/AccessTypeComposite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/AccessTypeComposite.java
new file mode 100644
index 0000000..7361e40
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/AccessTypeComposite.java
@@ -0,0 +1,117 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2010 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.ui.internal.details;
+
+import java.util.Collection;
+
+import org.eclipse.jpt.core.context.AccessHolder;
+import org.eclipse.jpt.core.context.AccessType;
+import org.eclipse.jpt.ui.internal.JptUiMessages;
+import org.eclipse.jpt.ui.internal.widgets.EnumFormComboViewer;
+import org.eclipse.jpt.ui.internal.widgets.Pane;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * Here the layout of this pane:
+ * <pre>
+ * -----------------------------------------------------------------------------
+ * |              ------------------------------------------------------------ |
+ * | Access Type: |                                                        |v| |
+ * |              ------------------------------------------------------------ |
+ * -----------------------------------------------------------------------------</pre>
+ *
+ * @see AccessHolder
+ * @see OrmEntityComposite - A container of this pane
+ * @see OrmEmbeddableComposite - A container of this pane
+ * @see OrmMappedSuperclassComposite - A container of this pane
+ *
+ * @version 2.2
+ * @since 1.0
+ */
+public class AccessTypeComposite extends Pane<AccessHolder> {
+
+	/**
+	 * Creates a new <code>AccessTypeComposite</code>.
+	 *
+	 * @param parentPane The parent container of this one
+	 * @param subjectHolder The holder of this pane's subject
+	 * @param parent The parent container
+	 */
+	public AccessTypeComposite(Pane<?> parentPane,
+	                           PropertyValueModel<? extends AccessHolder> subjectHolder,
+	                           Composite parent) {
+
+		super(parentPane, subjectHolder, parent);
+	}
+	
+	public AccessTypeComposite(Pane<?> parentPane,
+        PropertyValueModel<? extends AccessHolder> subjectHolder,
+        Composite parent,
+        boolean automaticallyAlignWidgets) {
+
+		super(parentPane, subjectHolder, parent, automaticallyAlignWidgets);
+	}
+
+	@Override
+	protected void initializeLayout(Composite container) {
+
+		EnumFormComboViewer<AccessHolder, AccessType> comboViewer =
+			addAccessTypeComboViewer(container);
+
+		addLabeledComposite(
+			container,
+			JptUiMessages.AccessTypeComposite_access,
+			comboViewer.getControl()
+		);
+	}
+	
+	private EnumFormComboViewer<AccessHolder, AccessType> addAccessTypeComboViewer(Composite container) {
+
+		return new EnumFormComboViewer<AccessHolder, AccessType>(this, container) {
+
+			@Override
+			protected void addPropertyNames(Collection<String> propertyNames) {
+				super.addPropertyNames(propertyNames);
+				propertyNames.add(AccessHolder.DEFAULT_ACCESS_PROPERTY);
+				propertyNames.add(AccessHolder.SPECIFIED_ACCESS_PROPERTY);
+			}
+
+			@Override
+			protected AccessType[] getChoices() {
+				return AccessType.values();
+			}
+
+			@Override
+			protected AccessType getDefaultValue() {
+				return getSubject().getDefaultAccess();
+			}
+
+			@Override
+			protected String displayString(AccessType value) {
+				return buildDisplayString(
+					JptUiMessages.class,
+					AccessTypeComposite.this,
+					value
+				);
+			}
+
+			@Override
+			protected AccessType getValue() {
+				return getSubject().getSpecifiedAccess();
+			}
+
+			@Override
+			protected void setValue(AccessType value) {
+				getSubject().setSpecifiedAccess(value);
+			}
+		};
+	}
+}
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/AddQueryDialog.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/AddQueryDialog.java
new file mode 100644
index 0000000..969ba92
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/AddQueryDialog.java
@@ -0,0 +1,186 @@
+/*******************************************************************************
+ * Copyright (c) 2009 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.ui.internal.details;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.eclipse.jpt.core.context.Query;
+import org.eclipse.jpt.ui.internal.widgets.DialogPane;
+import org.eclipse.jpt.ui.internal.widgets.ValidatingDialog;
+import org.eclipse.jpt.utility.internal.StringConverter;
+import org.eclipse.jpt.utility.internal.model.value.PropertyAspectAdapter;
+import org.eclipse.jpt.utility.internal.model.value.StaticListValueModel;
+import org.eclipse.jpt.utility.model.value.ListValueModel;
+import org.eclipse.jpt.utility.model.value.WritablePropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Text;
+
+/**
+ * Clients can use this dialog to prompt the user for SecondaryTable settings.
+ * Use the following once the dialog is closed:
+ *     @see #getSelectedTable()
+ *     @see #getSelectedCatalog()
+ *     @see #getSelectedSchema()
+ * @version 2.1
+ * @since 2.1
+ */
+public class AddQueryDialog extends ValidatingDialog<AddQueryStateObject> {
+
+	
+	// ********** constructors **********
+
+	/**
+	 * Use this constructor to edit an existing conversion value
+	 */
+	public AddQueryDialog(Shell parent) {
+		super(parent);
+	}
+
+	@Override
+	protected AddQueryStateObject buildStateObject() {
+		return new AddQueryStateObject();
+	}
+
+	// ********** open **********
+
+	@Override
+	protected void configureShell(Shell shell) {
+		super.configureShell(shell);
+		shell.setText(this.getTitle());
+	}
+
+	@Override
+	protected String getTitle() {
+		return JptUiDetailsMessages.AddQueryDialog_title;
+	}
+
+	@Override
+	protected String getDescriptionTitle() {
+		return JptUiDetailsMessages.AddQueryDialog_descriptionTitle;
+	}
+	
+	@Override
+	protected String getDescription() {
+		return JptUiDetailsMessages.AddQueryDialog_description;
+	}
+	
+	@Override
+	protected DialogPane<AddQueryStateObject> buildLayout(Composite container) {
+		return new QueryDialogPane(container);
+	}
+	
+	@Override
+	public void create() {
+		super.create();
+
+		QueryDialogPane pane = (QueryDialogPane) getPane();
+		pane.selectAll();
+
+		getButton(OK).setEnabled(false);
+	}
+
+
+	// ********** public API **********
+
+	/**
+	 * Return the data value set in the text widget.
+	 */
+	public String getName() {
+		return getSubject().getName();
+	}
+
+	/**
+	 * Return the object value set in the text widget.
+	 */
+	public String getQueryType() {
+		return getSubject().getQueryType();
+	}
+	
+	private class QueryDialogPane extends DialogPane<AddQueryStateObject> {
+
+		private Text nameText;
+
+		QueryDialogPane(Composite parent) {
+			super(AddQueryDialog.this.getSubjectHolder(), parent);
+		}
+
+		@Override
+		protected void initializeLayout(Composite container) {
+			this.nameText = addLabeledText(
+				container,
+				JptUiDetailsMessages.AddQueryDialog_name,
+				buildNameHolder()
+			);
+			
+			addLabeledCombo(
+				container, 
+				JptUiDetailsMessages.AddQueryDialog_queryType, 
+				buildQueryTypeListHolder(), 
+				buildQueryTypeHolder(), 
+				buildStringConverter(),
+				null);
+		}
+
+		protected ListValueModel<String> buildQueryTypeListHolder() {
+			List<String> queryTypes = new ArrayList<String>();
+			queryTypes.add(Query.NAMED_QUERY);
+			queryTypes.add(Query.NAMED_NATIVE_QUERY);
+			
+			return new StaticListValueModel<String>(queryTypes);
+		}
+		
+		private StringConverter<String> buildStringConverter() {
+			return new StringConverter<String>() {
+				public String convertToString(String value) {
+					if (value == Query.NAMED_QUERY) {
+						return JptUiDetailsMessages.AddQueryDialog_namedQuery;
+					}
+					if (value == Query.NAMED_NATIVE_QUERY) {
+						return JptUiDetailsMessages.AddQueryDialog_namedNativeQuery;
+					}
+					return value;
+				}
+			};
+		}
+		
+		private WritablePropertyValueModel<String> buildNameHolder() {
+			return new PropertyAspectAdapter<AddQueryStateObject, String>(getSubjectHolder(), AddQueryStateObject.NAME_PROPERTY) {
+				@Override
+				protected String buildValue_() {
+					return this.subject.getName();
+				}
+
+				@Override
+				protected void setValue_(String value) {
+					this.subject.setName(value);
+				}
+			};
+		}
+
+		private WritablePropertyValueModel<String> buildQueryTypeHolder() {
+			return new PropertyAspectAdapter<AddQueryStateObject, String>(getSubjectHolder(), AddQueryStateObject.QUERY_TYPE_PROPERTY) {
+				@Override
+				protected String buildValue_() {
+					return this.subject.getQueryType();
+				}
+
+				@Override
+				protected void setValue_(String value) {
+					this.subject.setQueryType(value);
+				}
+			};
+		}
+
+		void selectAll() {
+			this.nameText.selectAll();
+		}
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/AddQueryStateObject.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/AddQueryStateObject.java
new file mode 100644
index 0000000..9dd862c
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/AddQueryStateObject.java
@@ -0,0 +1,124 @@
+/*******************************************************************************
+ * Copyright (c) 2009 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.ui.internal.details;
+
+import java.util.List;
+import org.eclipse.jpt.utility.internal.StringTools;
+import org.eclipse.jpt.utility.internal.node.AbstractNode;
+import org.eclipse.jpt.utility.internal.node.Node;
+import org.eclipse.jpt.utility.internal.node.Problem;
+
+/**
+ * This is the state object used by the <code>AddQueryDialog</code>, which stores
+ * the current name and validates it when it is modified.
+ *
+ * @see AddQueryDialog
+ *
+ * @version 2.1
+ * @since 2.1
+ */
+final class AddQueryStateObject extends AbstractNode
+{
+	/**
+	 * The initial name or <code>null</code>
+	 */
+	private String name;
+
+	/**
+	 * The initial queryType or <code>null</code>
+	 */
+	private String queryType;
+
+	/**
+	 * The <code>Validator</code> used to validate this state object.
+	 */
+	private Validator validator;
+
+	/**
+	 * Notifies a change in the data value property.
+	 */
+	static final String NAME_PROPERTY = "nameProperty"; //$NON-NLS-1$
+	
+	/**
+	 * Notifies a change in the query type property.
+	 */
+	static final String QUERY_TYPE_PROPERTY = "queryTypeProperty"; //$NON-NLS-1$
+
+	/**
+	 * Creates a new <code>NewNameStateObject</code>.
+	 *
+	 * @param name The initial input or <code>null</code> if no initial value can
+	 * be specified
+	 * @param names The collection of names that can't be used or an empty
+	 * collection if none are available
+	 */
+	AddQueryStateObject() {
+		super(null);
+
+	}
+
+	private void addNameProblemsTo(List<Problem> currentProblems) {
+		if (StringTools.stringIsEmpty(this.name)) {
+			currentProblems.add(buildProblem(JptUiDetailsMessages.QueryStateObject_nameMustBeSpecified));
+		}
+	}
+
+	private void addQueryTypeProblemsTo(List<Problem> currentProblems) {
+		if (StringTools.stringIsEmpty(this.queryType)) {
+			currentProblems.add(buildProblem(JptUiDetailsMessages.QueryStateObject_typeMustBeSpecified));
+		}
+	}
+
+	@Override
+	protected void addProblemsTo(List<Problem> currentProblems) {
+		super.addProblemsTo(currentProblems);
+		addNameProblemsTo(currentProblems);
+		addQueryTypeProblemsTo(currentProblems);
+	}
+
+	@Override
+	protected void checkParent(Node parentNode) {
+		//no parent
+	}
+
+	public String displayString() {
+		return null;
+	}
+
+	String getName() {
+		return this.name;
+	}
+
+	String getQueryType() {
+		return this.queryType;
+	}
+
+	public void setName(String newName) {
+		String oldName = this.name;
+		this.name = newName;
+		firePropertyChanged(NAME_PROPERTY, oldName, newName);
+	}
+
+	public void setQueryType(String newQueryType) {
+		String old = this.queryType;
+		this.queryType = newQueryType;
+		firePropertyChanged(QUERY_TYPE_PROPERTY, old, newQueryType);
+	}
+
+	@Override
+	public void setValidator(Validator validator) {
+		this.validator = validator;
+	}
+
+	@Override
+	public Validator getValidator() {
+		return this.validator;
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/AssociationOverrideComposite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/AssociationOverrideComposite.java
new file mode 100644
index 0000000..8363028
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/AssociationOverrideComposite.java
@@ -0,0 +1,80 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 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.ui.internal.details;
+
+import org.eclipse.jpt.core.context.AssociationOverride;
+import org.eclipse.jpt.core.context.AssociationOverrideRelationshipReference;
+import org.eclipse.jpt.ui.internal.widgets.Pane;
+import org.eclipse.jpt.utility.internal.model.value.TransformationPropertyValueModel;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * Here the layout of this pane:
+ * <pre>
+ * -----------------------------------------------------------------------------
+ * |                                                                           |
+ * | JoinColumnsComposite                                                      |
+ * |                                                                           |
+ * -----------------------------------------------------------------------------</pre>
+ *
+ * @see AssociationOverride
+ * @see EntityOverridesComposite - The parent container
+ * @see JoinColumnJoiningStrategyPane
+ *
+ * @version 2.2
+ * @since 1.0
+ */
+public class AssociationOverrideComposite
+	extends Pane<AssociationOverride>
+{
+	/**
+	 * Creates a new <code>AssociationOverrideComposite</code>.
+	 *
+	 * @param subjectHolder The holder of the subject <code>AssociationOverride</code>
+	 * @param parent The parent container
+	 * @param widgetFactory The factory used to create various common widgets
+	 */
+	public AssociationOverrideComposite(Pane<?> parentPane, 
+			PropertyValueModel<? extends AssociationOverride> subjectHolder,
+			Composite parent) {
+		
+		super(parentPane, subjectHolder, parent);
+	}
+	
+	
+	@Override
+	protected void initializeLayout(Composite container) {
+		Composite composite = addTitledGroup(
+				container,
+				JptUiDetailsMessages.Joining_title);
+		
+		addJoinColumnJoiningStrategyPane(composite);
+		
+		addSubPane(composite, 5);
+	}
+	
+	protected void addJoinColumnJoiningStrategyPane(Composite container) {
+		JoinColumnJoiningStrategyPane.
+			buildJoinColumnJoiningStrategyPaneWithoutIncludeOverrideCheckBox(
+				this, 
+				buildRelationshipReferenceHolder(), 
+				container);		
+	}
+	
+	private PropertyValueModel<AssociationOverrideRelationshipReference> buildRelationshipReferenceHolder() {
+		return new TransformationPropertyValueModel<AssociationOverride, AssociationOverrideRelationshipReference>(getSubjectHolder()) {
+			@Override
+			protected AssociationOverrideRelationshipReference transform_(AssociationOverride value) {
+				return value.getRelationshipReference();
+			}
+		};
+	}
+}
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/AttributeOverrideComposite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/AttributeOverrideComposite.java
new file mode 100644
index 0000000..5812be8
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/AttributeOverrideComposite.java
@@ -0,0 +1,70 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 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.ui.internal.details;
+
+import org.eclipse.jpt.core.context.AttributeOverride;
+import org.eclipse.jpt.core.context.Column;
+import org.eclipse.jpt.ui.internal.widgets.Pane;
+import org.eclipse.jpt.utility.internal.model.value.TransformationPropertyValueModel;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * Here the layout of this pane:
+ * <pre>
+ * -----------------------------------------------------------------------------
+ * |                                                                           |
+ * | ColumnComposite                                                           |
+ * |                                                                           |
+ * -----------------------------------------------------------------------------</pre>
+ *
+ * @see AttributeOverride
+ * @see EntityOverridesComposite - The parent container
+ * @see ColumnComposite
+ *
+ * @version 2.0
+ * @since 1.0
+ */
+public class AttributeOverrideComposite extends Pane<AttributeOverride>
+{
+
+	/**
+	 * Creates a new <code>AttributeOverrideComposite</code>.
+	 *
+	 * @param subjectHolder The holder of the subject <code>AttributeOverride</code>
+	 * @param parent The parent container
+	 * @param widgetFactory The factory used to create various common widgets
+	 */
+	public AttributeOverrideComposite(Pane<?> parentPane, 
+								PropertyValueModel<? extends AttributeOverride> subjectHolder,
+								Composite parent) {
+
+		super(parentPane, subjectHolder, parent);
+	}
+
+	@Override
+	protected void initializeLayout(Composite container) {
+		new ColumnComposite(
+			this,
+			buildColumnHolder(),
+			container,
+			false
+		);
+	}
+	
+	private PropertyValueModel<Column> buildColumnHolder() {
+		return new TransformationPropertyValueModel<AttributeOverride, Column>(getSubjectHolder()) {
+			@Override
+			protected Column transform_(AttributeOverride value) {
+				return value.getColumn();
+			}
+		};
+	}
+}
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/BaseJoinColumnDialog.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/BaseJoinColumnDialog.java
new file mode 100644
index 0000000..17c4e9f
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/BaseJoinColumnDialog.java
@@ -0,0 +1,109 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2009 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.ui.internal.details;
+
+import org.eclipse.jpt.core.context.BaseJoinColumn;
+import org.eclipse.jpt.ui.internal.widgets.ValidatingDialog;
+import org.eclipse.swt.widgets.Shell;
+
+/**
+ * The abstract definition the dialog showing the information for a join column
+ * to edit or to create.
+ *
+ * @see BaseJoinColumnStateObject
+ *
+ * @version 2.0
+ * @since 1.0
+ */
+public abstract class BaseJoinColumnDialog<T extends BaseJoinColumnStateObject> extends ValidatingDialog<T> {
+
+	/**
+	 * Either the join column to edit or <code>null</code> if this state object
+	 * is used to create a new one.
+	 */
+	private BaseJoinColumn joinColumn;
+
+	/**
+	 * The owner of the join column to create or where it is located.
+	 */
+	private Object owner;
+
+	/**
+	 * Creates a new <code>BaseJoinColumnDialog</code>.
+	 *
+	 * @param parent The parent shell
+	 * @param owner The owner of the join column to create or where it is located
+	 * @param joinColumn Either the join column to edit or <code>null</code> if
+	 * this state object is used to create a new one
+	 */
+	public BaseJoinColumnDialog(Shell parent,
+	                            Object owner,
+	                            BaseJoinColumn joinColumn) {
+
+		super(parent);
+
+		this.owner      = owner;
+		this.joinColumn = joinColumn;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 */
+	@Override
+	protected String getDescription() {
+		return JptUiDetailsMessages.JoinColumnDialog_description;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 */
+	@Override
+	protected String getDescriptionTitle() {
+
+		if (joinColumn == null) {
+			return JptUiDetailsMessages.JoinColumnDialog_addJoinColumnDescriptionTitle;
+		}
+
+		return JptUiDetailsMessages.JoinColumnDialog_editJoinColumnDescriptionTitle;
+	}
+
+	/**
+	 * Returns the join column used by this state object for editing or
+	 * <code>null</code> if this state object is used to create a new one.
+	 *
+	 * @return Either the edited join column or <code>null</code>
+	 */
+	public BaseJoinColumn getJoinColumn() {
+		return joinColumn;
+	}
+
+	/**
+	 * Returns the owner where the join column is located or where a new one can
+	 * be added.
+	 *
+	 * @return The parent of the join column
+	 */
+	protected Object getOwner() {
+		return owner;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 */
+	@Override
+	protected String getTitle() {
+
+		if (joinColumn == null) {
+			return JptUiDetailsMessages.JoinColumnDialog_addJoinColumnTitle;
+		}
+
+		return JptUiDetailsMessages.JoinColumnDialog_editJoinColumnTitle;
+	}
+}
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/BaseJoinColumnDialogPane.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/BaseJoinColumnDialogPane.java
new file mode 100644
index 0000000..3fa5004
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/BaseJoinColumnDialogPane.java
@@ -0,0 +1,441 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2009 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.ui.internal.details;
+
+import java.util.ArrayList;
+import java.util.ListIterator;
+import org.eclipse.jpt.ui.internal.JpaHelpContextIds;
+import org.eclipse.jpt.ui.internal.util.SWTUtil;
+import org.eclipse.jpt.ui.internal.widgets.DialogPane;
+import org.eclipse.jpt.utility.internal.StringConverter;
+import org.eclipse.jpt.utility.internal.model.value.CompositeListValueModel;
+import org.eclipse.jpt.utility.internal.model.value.ListAspectAdapter;
+import org.eclipse.jpt.utility.internal.model.value.PropertyAspectAdapter;
+import org.eclipse.jpt.utility.internal.model.value.PropertyListValueModelAdapter;
+import org.eclipse.jpt.utility.internal.model.value.TransformationPropertyValueModel;
+import org.eclipse.jpt.utility.model.value.ListValueModel;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.jpt.utility.model.value.WritablePropertyValueModel;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * Here the layout of this pane:
+ * <pre>
+ * -----------------------------------------------------------------------------
+ * |                         ------------------------------------------------- |
+ * | Name:                   | I                                           |v| |
+ * |                         ------------------------------------------------- |
+ * |                         ------------------------------------------------- |
+ * | Referenced Column Name: | I                                           |v| |
+ * |                         ------------------------------------------------- |
+ * |                         ------------------------------------------------- |
+ * | Table:                  | I                                           |v| |
+ * |                         ------------------------------------------------- |
+ * |                         ------------------------------------------------- |
+ * | Column Definition:      | I                                             | |
+ * |                         ------------------------------------------------- |
+ * -----------------------------------------------------------------------------</pre>
+ *
+ * @see BaseJoinColumnStateObject
+ * @see InverseJoinColumnInJoinTableDialog - A container of this pane
+ * @see JoinColumnInReferenceTableDialog - A container of this pane
+ * @see PrimaryKeyJoinColumnDialog - A container of this pane
+ * @see PrimaryKeyJoinColumnInSecondaryTableDialog - A container of this pane
+ *
+ * @version 2.0
+ * @since 2.0
+ */
+@SuppressWarnings("nls")
+public class BaseJoinColumnDialogPane<T extends BaseJoinColumnStateObject> extends DialogPane<T>
+{
+	/**
+	 * A key used to represent the default value, this is required to convert
+	 * the selected item from a combo to <code>null</code>. This key is most
+	 * likely never typed the user and it will help to convert the value to
+	 * <code>null</code> when it's time to set the new selected value into the
+	 * model.
+	 */
+	protected static String DEFAULT_KEY = "?!#!?#?#?default?#?!#?!#?";
+
+	/**
+	 * Creates a new <code>BaseJoinColumnDialogPane</code>.
+	 *
+	 * @param subjectHolder The holder of this pane's subject
+	 * @param parent The parent container
+	 */
+	public BaseJoinColumnDialogPane(PropertyValueModel<? extends T> subjectHolder,
+	                                Composite parent) {
+
+		super(subjectHolder, parent);
+	}
+
+	private WritablePropertyValueModel<String> buildColumnDefinitionHolder() {
+		return new PropertyAspectAdapter<BaseJoinColumnStateObject, String>(getSubjectHolder(), BaseJoinColumnStateObject.COLUMN_DEFINITION_PROPERTY) {
+			@Override
+			protected String buildValue_() {
+				return subject.getColumnDefinition();
+			}
+
+			@Override
+			protected void setValue_(String value) {
+				if (value.length() == 0) {
+					value = null;
+				}
+				subject.setColumnDefinition(value);
+			}
+		};
+	}
+
+	/*
+	 * (non-Javadoc)
+	 */
+	@Override
+	protected Composite addContainer(Composite parent) {
+		return addSubPane(parent, 0, 7, 0, 5);
+	}
+
+	private PropertyValueModel<String> buildDefaultNameHolder() {
+		return new TransformationPropertyValueModel<BaseJoinColumnStateObject, String>(getSubjectHolder()) {
+			@Override
+			protected String transform_(BaseJoinColumnStateObject value) {
+				String name = value.getDefaultName();
+
+				if (name == null) {
+					name = DEFAULT_KEY;
+				}
+				else {
+					name = DEFAULT_KEY + name;
+				}
+
+				return name;
+			}
+		};
+	}
+
+	private ListValueModel<String> buildDefaultNameListHolder() {
+		return new PropertyListValueModelAdapter<String>(
+			buildDefaultNameHolder()
+		);
+	}
+
+	private PropertyValueModel<String> buildDefaultReferencedColumnNameHolder() {
+		return new TransformationPropertyValueModel<BaseJoinColumnStateObject, String>(getSubjectHolder()) {
+			@Override
+			protected String transform_(BaseJoinColumnStateObject value) {
+				String name = value.getDefaultReferencedColumnName();
+
+				if (name == null) {
+					name = DEFAULT_KEY;
+				}
+				else {
+					name = DEFAULT_KEY + name;
+				}
+
+				return name;
+			}
+		};
+	}
+
+	private ListValueModel<String> buildDefaultReferencedColumnNameListHolder() {
+		return new PropertyListValueModelAdapter<String>(
+			buildDefaultReferencedColumnNameHolder()
+		);
+	}
+
+	private PropertyValueModel<String> buildDefaultTableHolder() {
+		return new TransformationPropertyValueModel<BaseJoinColumnStateObject, String>(getSubjectHolder()) {
+			@Override
+			protected String transform_(BaseJoinColumnStateObject value) {
+				String name = value.getDefaultTable();
+
+				if (name == null) {
+					name = DEFAULT_KEY;
+				}
+				else {
+					name = DEFAULT_KEY + name;
+				}
+
+				return name;
+			}
+		};
+	}
+
+	private ListValueModel<String> buildDefaultTableListHolder() {
+		return new PropertyListValueModelAdapter<String>(
+			buildDefaultTableHolder()
+		);
+	}
+
+	private StringConverter<String> buildDisplayableStringConverter(final DefaultValueHandler handler) {
+		return new StringConverter<String>() {
+			public String convertToString(String value) {
+
+				if (getSubject() == null) {
+					return null;
+				}
+
+				if (value == null) {
+					value = handler.getDefaultValue();
+
+					if (value != null) {
+						value = DEFAULT_KEY + value;
+					}
+					else {
+						value = DEFAULT_KEY;
+					}
+				}
+
+				if (value.startsWith(DEFAULT_KEY)) {
+					String defaultName = value.substring(DEFAULT_KEY.length());
+
+					if (defaultName.length() > 0) {
+						value = NLS.bind(
+							JptUiDetailsMessages.DefaultWithOneParam,
+							defaultName
+						);
+					}
+					else {
+						value = JptUiDetailsMessages.DefaultEmpty;
+					}
+				}
+
+				return value;
+			}
+		};
+	}
+
+	private WritablePropertyValueModel<String> buildNameHolder() {
+		return new PropertyAspectAdapter<BaseJoinColumnStateObject, String>(getSubjectHolder(), BaseJoinColumnStateObject.NAME_PROPERTY) {
+			@Override
+			protected String buildValue_() {
+				return subject.getName();
+			}
+
+			@Override
+			protected void setValue_(String value) {
+
+				// Convert the default value or an empty string to null
+				if ((value != null) &&
+				   ((value.length() == 0) || value.startsWith(DEFAULT_KEY))) {
+
+					value = null;
+				}
+
+				subject.setName(value);
+			}
+		};
+	}
+
+	private ListValueModel<String> buildNameListHolder() {
+		return new ListAspectAdapter<BaseJoinColumnStateObject, String>(getSubjectHolder(), BaseJoinColumnStateObject.NAMES_LIST) {
+			@Override
+			protected ListIterator<String> listIterator_() {
+				return subject.names();
+			}
+			@Override
+			protected int size_() {
+				return subject.columnsSize();
+			}
+		};
+	}
+
+	private ListValueModel<String> buildNamesListHolder() {
+		ArrayList<ListValueModel<String>> holders = new ArrayList<ListValueModel<String>>(2);
+		holders.add(buildDefaultNameListHolder());
+		holders.add(buildNameListHolder());
+		return new CompositeListValueModel<ListValueModel<String>, String>(holders);
+	}
+
+	private StringConverter<String> buildNameStringConverter() {
+		return buildDisplayableStringConverter(new DefaultValueHandler() {
+			public String getDefaultValue() {
+				return getSubject().getDefaultName();
+			}
+		});
+	}
+
+	private WritablePropertyValueModel<String> buildReferencedColumnNameHolder() {
+		return new PropertyAspectAdapter<BaseJoinColumnStateObject, String>(getSubjectHolder(), BaseJoinColumnStateObject.REFERENCED_COLUMN_NAME_PROPERTY) {
+			@Override
+			protected String buildValue_() {
+				return subject.getReferencedColumnName();
+			}
+
+			@Override
+			protected void setValue_(String value) {
+
+				// Convert the default value or an empty string to null
+				if ((value != null) &&
+				   ((value.length() == 0) || value.startsWith(DEFAULT_KEY))) {
+
+					value = null;
+				}
+
+				subject.setReferencedColumnName(value);
+			}
+		};
+	}
+
+	private ListValueModel<String> buildReferencedColumnNameListHolder() {
+		return new ListAspectAdapter<BaseJoinColumnStateObject, String>(getSubjectHolder(), BaseJoinColumnStateObject.REFERENCE_COLUMN_NAMES_LIST) {
+			@Override
+			protected ListIterator<String> listIterator_() {
+				return subject.referenceColumnNames();
+			}
+			@Override
+			protected int size_() {
+				return subject.referenceColumnsSize();
+			}
+		};
+	}
+
+	private ListValueModel<String> buildReferencedColumnNamesListHolder() {
+		ArrayList<ListValueModel<String>> holders = new ArrayList<ListValueModel<String>>(2);
+		holders.add(buildDefaultReferencedColumnNameListHolder());
+		holders.add(buildReferencedColumnNameListHolder());
+		return new CompositeListValueModel<ListValueModel<String>, String>(holders);
+	}
+
+	private StringConverter<String> buildReferencedColumnNameStringConverter() {
+		return buildDisplayableStringConverter(new DefaultValueHandler() {
+			public String getDefaultValue() {
+				return getSubject().getDefaultReferencedColumnName();
+			}
+		});
+	}
+
+	private WritablePropertyValueModel<String> buildTableHolder() {
+		return new PropertyAspectAdapter<BaseJoinColumnStateObject, String>(getSubjectHolder(), BaseJoinColumnStateObject.TABLE_PROPERTY) {
+			@Override
+			protected String buildValue_() {
+				return subject.getTable();
+			}
+
+			@Override
+			protected void setValue_(String value) {
+
+				// Convert the default value or an empty string to null
+				if ((value != null) &&
+				   ((value.length() == 0) || value.startsWith(DEFAULT_KEY))) {
+
+					value = null;
+				}
+
+				subject.setTable(value);
+			}
+		};
+	}
+
+	private ListValueModel<String> buildTableListHolder() {
+		return new ListAspectAdapter<BaseJoinColumnStateObject, String>(getSubjectHolder(), "") {
+			@Override
+			protected ListIterator<String> listIterator_() {
+				return subject.tables();
+			}
+		};
+	}
+
+	private ListValueModel<String> buildTablesListHolder() {
+		ArrayList<ListValueModel<String>> holders = new ArrayList<ListValueModel<String>>(2);
+		holders.add(buildDefaultTableListHolder());
+		holders.add(buildTableListHolder());
+		return new CompositeListValueModel<ListValueModel<String>, String>(holders);
+	}
+
+	private StringConverter<String> buildTableStringConverter() {
+		return buildDisplayableStringConverter(new DefaultValueHandler() {
+			public String getDefaultValue() {
+				return getSubject().getDefaultTable();
+			}
+		});
+	}
+
+	/*
+	 * (non-Javadoc)
+	 */
+	@Override
+	protected void initializeLayout(Composite container) {
+
+		// Name widgets
+		Combo nameCombo = addLabeledEditableCombo(
+			container,
+			JptUiDetailsMessages.JoinColumnDialog_name,
+			buildNamesListHolder(),
+			buildNameHolder(),
+			buildNameStringConverter(),
+			JpaHelpContextIds.MAPPING_JOIN_COLUMN_NAME
+		);
+
+		SWTUtil.attachDefaultValueHandler(nameCombo);
+
+		// Referenced Column Name widgets
+		Combo referencedColumnNameCombo = addLabeledEditableCombo(
+			container,
+			JptUiDetailsMessages.JoinColumnDialog_referencedColumnName,
+			buildReferencedColumnNamesListHolder(),
+			buildReferencedColumnNameHolder(),
+			buildReferencedColumnNameStringConverter(),
+			JpaHelpContextIds.MAPPING_JOIN_REFERENCED_COLUMN
+		);
+
+		SWTUtil.attachDefaultValueHandler(referencedColumnNameCombo);
+
+		// Table widgets
+		if (isTableEditable()) {
+
+			Combo tableCombo = addLabeledEditableCombo(
+				container,
+				JptUiDetailsMessages.JoinColumnDialogPane_table,
+				buildTablesListHolder(),
+				buildTableHolder(),
+				buildTableStringConverter(),
+				JpaHelpContextIds.MAPPING_JOIN_REFERENCED_COLUMN
+			);
+
+			SWTUtil.attachDefaultValueHandler(tableCombo);
+		}
+		else {
+			Combo tableCombo = addLabeledCombo(
+				container,
+				JptUiDetailsMessages.JoinColumnDialogPane_table,
+				buildTablesListHolder(),
+				buildTableHolder(),
+				buildTableStringConverter(),
+				JpaHelpContextIds.MAPPING_JOIN_REFERENCED_COLUMN
+			);
+
+			tableCombo.setEnabled(false);
+		}
+
+		// Column Definition widgets
+		addLabeledText(
+			container,
+			JptUiDetailsMessages.JoinColumnDialogPane_columnDefinition,
+			buildColumnDefinitionHolder()
+		);
+	}
+
+	/**
+	 * Determines whether the table combo should be editable or not. The default
+	 * is to keep the combo read-only.
+	 *
+	 * @return <code>true</code> to support the editing of the selected table;
+	 * <code>false</code> otherwise
+	 */
+	protected boolean isTableEditable() {
+		return false;
+	}
+
+	protected static interface DefaultValueHandler {
+		String getDefaultValue();
+	}
+}
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/BaseJoinColumnStateObject.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/BaseJoinColumnStateObject.java
new file mode 100644
index 0000000..a6ccf83
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/BaseJoinColumnStateObject.java
@@ -0,0 +1,396 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2009 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.ui.internal.details;
+
+import java.util.ListIterator;
+import org.eclipse.jpt.core.context.BaseJoinColumn;
+import org.eclipse.jpt.db.Table;
+import org.eclipse.jpt.utility.internal.CollectionTools;
+import org.eclipse.jpt.utility.internal.iterators.EmptyListIterator;
+import org.eclipse.jpt.utility.internal.node.AbstractNode;
+import org.eclipse.jpt.utility.internal.node.Node;
+
+/**
+ * The abstract definition of a state object used to edit or create a new
+ * join column.
+ *
+ * @see AbstractJoinColumn
+ *
+ * @version 2.0
+ * @since 2.0
+ */
+@SuppressWarnings("nls")
+public abstract class BaseJoinColumnStateObject extends AbstractNode
+{
+	/**
+	 * The SQL fragment that is used when generating the DDL for the column.
+	 */
+	private String columnDefinition;
+
+	/**
+	 * Either the join column is being edited or <code>null</code> the state
+	 * object is being created.
+	 */
+	private BaseJoinColumn joinColumn;
+
+	/**
+	 * The join column's name or <code>null</code> if not defined.
+	 */
+	private String name;
+
+	/**
+	 * The owner of the join column to create or where it is located.
+	 */
+	private Object owner;
+
+	/**
+	 * The referenced column name or <code>null</code> if not defined.
+	 */
+	private String referencedColumnName;
+
+	/**
+	 * The table
+	 */
+	private String table;
+
+	/**
+	 * Keeps track of the <code>Validator</code> since this is the root object.
+	 */
+	private Validator validator;
+
+	/**
+	 * Identifies a change in the column definition property.
+	 */
+	public static final String COLUMN_DEFINITION_PROPERTY = "columnDefinition";
+
+	/**
+	 * Identifies a change in the name property.
+	 */
+	public static final String NAME_PROPERTY = "name";
+
+	/**
+	 * Identifies a change in the list of names.
+	 */
+	public static final String NAMES_LIST = "names";
+
+	/**
+	 * Identifies a change in the list of reference column names.
+	 */
+	public static final String REFERENCE_COLUMN_NAMES_LIST = "referenceColumnNames";
+
+	/**
+	 * Identifies a change in the referenced column name property.
+	 */
+	public static final String REFERENCED_COLUMN_NAME_PROPERTY = "referencedColumnName";
+
+	/**
+	 * Identifies a change in the table property.
+	 */
+	public static final String TABLE_PROPERTY = "table";
+
+	/**
+	 * Creates a new <code>AbstractJoinColumnStateObject</code>.
+	 *
+	 * @param owner The owner of the join column to create or where it is located
+	 * @param joinColumn Either the join column to edit or <code>null</code> if
+	 * this state object is used to create a new one
+	 */
+	public BaseJoinColumnStateObject(Object owner, BaseJoinColumn joinColumn) {
+		super(null);
+		initialize(owner, joinColumn);
+	}
+
+	@Override
+	protected final void checkParent(Node parentNode) {
+		// This is the root of the Join Column state object
+	}
+
+	private static ListIterator<String> columnNames(Table table) {
+		if (table == null) {
+			return EmptyListIterator.instance();
+		}
+		return CollectionTools.list(table.getSortedColumnIdentifiers()).listIterator();
+	}
+	
+	private static int columnsSize(Table table) {
+		if (table == null) {
+			return 0;
+		}
+		return table.getColumnsSize();
+	}
+	
+	public final String displayString() {
+		return "";
+	}
+
+	/**
+	 * Returns the SQL fragment that is used when generating the DDL for the
+	 * column.
+	 *
+	 * @return The edited column name or <code>null</code> if not used
+	 */
+	public String getColumnDefinition() {
+		return columnDefinition;
+	}
+
+	/**
+	 * Returns the default name if the join column is being edited otherwise
+	 * <code>null</code> is returned.
+	 *
+	 * @return Either the default name defined by the join column or <code>null</code>
+	 */
+	public String getDefaultName() {
+		if (this.joinColumn == null) {
+			return null;
+		}
+
+		return this.joinColumn.getDefaultName();
+	}
+
+	/**
+	 * Returns the default referenced column name if the join column is being
+	 * edited otherwise <code>null</code> is returned.
+	 *
+	 * @return Either the default referenced column name defined by the join
+	 * column or <code>null</code>
+	 */
+	public String getDefaultReferencedColumnName() {
+		if (this.joinColumn == null) {
+			return null;
+		}
+
+		return this.joinColumn.getDefaultReferencedColumnName();
+	}
+
+	/**
+	 * Returns
+	 *
+	 * @return
+	 */
+	public abstract String getDefaultTable();
+
+	/**
+	 * Returns the edited join column or <code>null</code> if this state object
+	 * is used to create a new one.
+	 *
+	 * @return The edited join column or <code>null</code>
+	 */
+	public BaseJoinColumn getJoinColumn() {
+		return this.joinColumn;
+	}
+
+	/**
+	 * Returns the name of the join column.
+	 *
+	 * @return Either join column's name or <code>null</code> to use the default
+	 * name
+	 */
+	public String getName() {
+		return this.name;
+	}
+
+	/**
+	 * Returns the database table if one can be found.
+	 *
+	 * @return The database table
+	 */
+	public abstract Table getNameTable();
+
+	/**
+	 * Returns the owner where the join column is located or where a new one can
+	 * be added.
+	 *
+	 * @return The parent of the join column
+	 */
+	public Object getOwner() {
+		return owner;
+	}
+
+	/**
+	 * Returns the referenced column name of the join column.
+	 *
+	 * @return Either join column's referenced column name or <code>null</code>
+	 * to use the default name
+	 */
+	public String getReferencedColumnName() {
+		return this.referencedColumnName;
+	}
+
+	/**
+	 * Returns
+	 *
+	 * @return
+	 */
+	public abstract Table getReferencedNameTable();
+
+	/**
+	 * Returns
+	 *
+	 * @return
+	 */
+	public String getTable() {
+		return table;
+	}
+
+	@Override
+	public final Validator getValidator() {
+		return this.validator;
+	}
+
+	@Override
+	protected void initialize() {
+		super.initialize();
+		validator = NULL_VALIDATOR;
+	}
+
+	/**
+	 * Initializes this state object.
+	 *
+	 * @param owner The owner of the join column to create or where it is located
+	 * @param joinColumn Either the join column to edit or <code>null</code> if
+	 * this state object is used to create a new one
+	 */
+	protected void initialize(Object o, BaseJoinColumn jc) {
+
+		this.owner      = o;
+		this.joinColumn = jc;
+		this.table      = this.getInitialTable();
+
+		if (jc != null) {
+			this.name                 = jc.getSpecifiedName();
+			this.columnDefinition     = jc.getColumnDefinition();
+			this.referencedColumnName = jc.getSpecifiedReferencedColumnName();
+		}
+	}
+
+	/**
+	 * Returns
+	 */
+	protected abstract String getInitialTable();
+
+	/**
+	 * Returns the column names if the database table can be resolved.
+	 *
+	 * @return The names of the table's columns or an empty iterator if the table
+	 * can't be resolved
+	 */
+	public ListIterator<String> names() {
+		return columnNames(getNameTable());
+	}
+
+	public int columnsSize() {
+		return columnsSize(getNameTable());
+	}
+	
+	/**
+	 * Returns the reference column names if the database table can be resolved.
+	 *
+	 * @return The names of the table's columns or an empty iterator if the table
+	 * can't be resolved
+	 */
+	public ListIterator<String> referenceColumnNames() {
+		return columnNames(getReferencedNameTable());
+	}
+	
+	public int referenceColumnsSize() {
+		return columnsSize(getReferencedNameTable());
+	}
+
+	/**
+	 * Sets the SQL fragment that is used when generating the DDL for the column.
+	 *
+	 * @param columnDefinition The new join column's column definition or
+	 * <code>null</code> to clear the value
+	 */
+	public void setColumnDefinition(String columnDefinition) {
+		String oldColumnDefinition = this.columnDefinition;
+		this.columnDefinition = columnDefinition;
+		firePropertyChanged(COLUMN_DEFINITION_PROPERTY, oldColumnDefinition, columnDefinition);
+	}
+
+	/**
+	 * Sets the name of the join column.
+	 *
+	 * @param name The new join column's name or <code>null</code> to use the
+	 * default name
+	 */
+	public void setName(String name) {
+		String oldName = this.name;
+		this.name = name;
+		firePropertyChanged(NAME_PROPERTY, oldName, name);
+	}
+
+	/**
+	 * Sets the referenced column name of the join column.
+	 *
+	 * @param referencedColumnName The new join column's referenced column name
+	 * or <code>null</code> to use the default referenced column name
+	 */
+	public void setReferencedColumnName(String referencedColumnName) {
+		String oldReferencedColumnName = this.referencedColumnName;
+		this.referencedColumnName = referencedColumnName;
+		firePropertyChanged(REFERENCED_COLUMN_NAME_PROPERTY, oldReferencedColumnName, referencedColumnName);
+	}
+
+	public void setTable(String table) {
+		String oldTable = this.table;
+		this.table = table;
+		firePropertyChanged(TABLE_PROPERTY, oldTable, table);
+		tableChanged();
+	}
+
+	@Override
+	public final void setValidator(Validator validator) {
+		this.validator = validator;
+	}
+
+	/**
+	 * The table from which the column names are used has changed, notifies the
+	 * listeners the list of names and reference column names should be updated.
+	 */
+	protected void tableChanged() {
+		fireListChanged(NAMES_LIST, CollectionTools.list(this.names()));
+		fireListChanged(REFERENCE_COLUMN_NAMES_LIST, CollectionTools.list(this.referenceColumnNames()));
+	}
+
+	/**
+	 * Retrieves the list of all the table names contains in the associated
+	 * schema. The default returns an empty iterator.
+	 *
+	 * @return The names of the tables
+	 */
+	public ListIterator<String> tables() {
+		return EmptyListIterator.instance();
+	}
+
+	/**
+	 * Updates the given join column with the values contained in this state
+	 * object.
+	 *
+	 * @param joinColumn The join column to update
+	 */
+	public void updateJoinColumn(BaseJoinColumn jc) {
+
+		// Name
+		if (valuesAreDifferent(name, jc.getSpecifiedName())) {
+			jc.setSpecifiedName(name);
+		}
+
+		// Referenced Column Name
+		if (valuesAreDifferent(referencedColumnName, jc.getSpecifiedReferencedColumnName())) {
+			jc.setSpecifiedReferencedColumnName(referencedColumnName);
+		}
+
+		// Column Definition
+		if (valuesAreDifferent(columnDefinition, jc.getColumnDefinition())) {
+			jc.setColumnDefinition(columnDefinition);
+		}
+	}
+}
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/BasicMappingComposite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/BasicMappingComposite.java
new file mode 100644
index 0000000..54a9776
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/BasicMappingComposite.java
@@ -0,0 +1,80 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2009 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.ui.internal.details;
+
+import org.eclipse.jpt.core.context.BasicMapping;
+import org.eclipse.jpt.ui.WidgetFactory;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * Here the layout of this pane:
+ * <pre>
+ * -----------------------------------------------------------------------------
+ * | ------------------------------------------------------------------------- |
+ * | |                                                                       | |
+ * | | ColumnComposite                                                       | |
+ * | |                                                                       | |
+ * | ------------------------------------------------------------------------- |
+ * | ------------------------------------------------------------------------- |
+ * | |                                                                       | |
+ * | | FetchTypeComposite                                                    | |
+ * | |                                                                       | |
+ * | ------------------------------------------------------------------------- |
+ * | ------------------------------------------------------------------------- |
+ * | |                                                                       | |
+ * | | TemporalTypeComposite                                                 | |
+ * | |                                                                       | |
+ * | ------------------------------------------------------------------------- |
+ * | ------------------------------------------------------------------------- |
+ * | |                                                                       | |
+ * | | EnumTypeComposite                                                     | |
+ * | |                                                                       | |
+ * | ------------------------------------------------------------------------- |
+ * | ------------------------------------------------------------------------- |
+ * | |                                                                       | |
+ * | | OptionalComposite                                                     | |
+ * | |                                                                       | |
+ * | ------------------------------------------------------------------------- |
+ * | ------------------------------------------------------------------------- |
+ * | |                                                                       | |
+ * | | LobComposite                                                          | |
+ * | |                                                                       | |
+ * | ------------------------------------------------------------------------- |
+ * -----------------------------------------------------------------------------</pre>
+ *
+ * @see BasicMapping
+ * @see ColumnComposite
+ * @see EnumTypeComposite
+ * @see FetchTypeComposite
+ * @see LobComposite
+ * @see OptionalComposite
+ * @see TemporalTypeComposite
+ *
+ * @version 2.0
+ * @since 1.0
+ */
+public class BasicMappingComposite extends AbstractBasicMappingComposite<BasicMapping>
+{
+	/**
+	 * Creates a new <code>BasicMappingComposite</code>.
+	 *
+	 * @param subjectHolder The holder of the subject <code>IBasicMapping</code>
+	 * @param parent The parent container
+	 * @param widgetFactory The factory used to create various common widgets
+	 */
+	public BasicMappingComposite(PropertyValueModel<? extends BasicMapping> subjectHolder,
+	                             Composite parent,
+	                             WidgetFactory widgetFactory) {
+
+		super(subjectHolder, parent, widgetFactory);
+	}
+
+}
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/CascadeComposite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/CascadeComposite.java
new file mode 100644
index 0000000..4c36fea
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/CascadeComposite.java
@@ -0,0 +1,211 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 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.ui.internal.details;
+
+import org.eclipse.jpt.core.context.Cascade;
+import org.eclipse.jpt.core.context.RelationshipMapping;
+import org.eclipse.jpt.ui.WidgetFactory;
+import org.eclipse.jpt.ui.internal.widgets.Pane;
+import org.eclipse.jpt.utility.internal.model.value.PropertyAspectAdapter;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.jpt.utility.model.value.WritablePropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Group;
+
+/**
+ * Here the layout of this pane:
+ * <pre>
+ * -----------------------------------------------------------------------------
+ * | - Cascade --------------------------------------------------------------- |
+ * | |                                                                       | |
+ * | | x All       x Persist   x Merge     x Remove    x Refresh             | |
+ * | |                                                                       | |
+ * | ------------------------------------------------------------------------- |
+ * -----------------------------------------------------------------------------</pre>
+ *
+ * @see Cascade
+ * @see RelationshipMapping
+ * @see ManyToManyMappingComposite - A container of this pane
+ * @see ManyToOneMappingComposite - A container of this pane
+ * @see OneToManyMappingComposite - A container of this pane
+ * @see OneToOneMappingComposite - A container of this pane
+ *
+ * @version 2.0
+ * @since 1.0
+ */
+public class CascadeComposite<T extends Cascade> extends Pane<T>
+{
+	/**
+	 * Creates a new <code>CascadeComposite</code>.
+	 *
+	 * @param parentPane The parent container of this one
+	 * @param subjectHolder The holder of the subject <code>ICascade</code>
+	 * @param parent The parent container
+	 */
+	public CascadeComposite(
+			Pane<? extends RelationshipMapping> parentPane,
+	        PropertyValueModel<T> subjectHolder,
+	        Composite parent) {
+		
+		super(parentPane, subjectHolder, parent, false);
+	}
+	
+	/**
+	 * Creates a new <code>ColumnComposite</code>.
+	 *
+	 * @param subjectHolder The holder of the subject <code>ICascade</code>
+	 * @param parent The parent container
+	 * @param widgetFactory The factory used to create various common widgets
+	 */
+	public CascadeComposite(
+			PropertyValueModel<T> subjectHolder,
+			Composite parent,
+		    WidgetFactory widgetFactory) {
+		
+		super(subjectHolder, parent, widgetFactory);
+	}
+	
+	
+	@Override
+	protected void initializeLayout(Composite container) {
+		// Cascade group
+		Group cascadeGroup = addCascadeGroup(container);
+		
+		// Container of the check boxes
+		container = addSubPane(cascadeGroup, 5, 8, 0, 0, 0);
+		
+		addAllCheckBox(container);
+		addPersistCheckBox(container);
+		addMergeCheckBox(container);
+		addRemoveCheckBox(container);
+		addRefreshCheckBox(container);
+	}
+	
+	protected void addAllCheckBox(Composite container) {
+		// All check box
+		addCheckBox(
+				container,
+				JptUiDetailsMessages.CascadeComposite_all,
+				buildCascadeTypeAllHolder(),
+				null);
+	}
+	
+	protected void addPersistCheckBox(Composite container) {
+		// Persist check box
+		addCheckBox(
+				container,
+				JptUiDetailsMessages.CascadeComposite_persist,
+				buildCascadeTypePersistHolder(),
+				null);
+	}
+	
+	protected void addMergeCheckBox(Composite container) {
+		// Merge check box
+		addCheckBox(
+				container,
+				JptUiDetailsMessages.CascadeComposite_merge,
+				buildCascadeTypeMergeHolder(),
+				null);
+	}
+	
+	protected void addRemoveCheckBox(Composite container) {
+		// Remove check box
+		addCheckBox(
+				container,
+				JptUiDetailsMessages.CascadeComposite_remove,
+				buildCascadeTypeRemoveHolder(),
+				null);
+	}
+	
+	protected void addRefreshCheckBox(Composite container) {
+		// Refresh check box
+		addCheckBox(
+				container,
+				JptUiDetailsMessages.CascadeComposite_refresh,
+				buildCascadeTypeRefreshHolder(),
+				null);
+	}
+	
+	protected Group addCascadeGroup(Composite container) {
+		return addTitledGroup(
+				container,
+				JptUiDetailsMessages.CascadeComposite_cascadeTitle);
+	}
+	
+	protected WritablePropertyValueModel<Boolean> buildCascadeTypeAllHolder() {
+		return new PropertyAspectAdapter<Cascade, Boolean>(getSubjectHolder(), Cascade.ALL_PROPERTY) {
+			@Override
+			protected Boolean buildValue_() {
+				return subject.isAll();
+			}
+
+			@Override
+			protected void setValue_(Boolean value) {
+				subject.setAll(value);
+			}
+		};
+	}
+	
+	protected WritablePropertyValueModel<Boolean> buildCascadeTypeMergeHolder() {
+		return new PropertyAspectAdapter<Cascade, Boolean>(getSubjectHolder(), Cascade.MERGE_PROPERTY) {
+			@Override
+			protected Boolean buildValue_() {
+				return subject.isMerge();
+			}
+
+			@Override
+			protected void setValue_(Boolean value) {
+				subject.setMerge(value);
+			}
+		};
+	}
+	
+	protected WritablePropertyValueModel<Boolean> buildCascadeTypePersistHolder() {
+		return new PropertyAspectAdapter<Cascade, Boolean>(getSubjectHolder(), Cascade.PERSIST_PROPERTY) {
+			@Override
+			protected Boolean buildValue_() {
+				return subject.isPersist();
+			}
+			
+			@Override
+			protected void setValue_(Boolean value) {
+				subject.setPersist(value);
+			}
+		};
+	}
+	
+	protected WritablePropertyValueModel<Boolean> buildCascadeTypeRefreshHolder() {
+		return new PropertyAspectAdapter<Cascade, Boolean>(getSubjectHolder(), Cascade.REFRESH_PROPERTY) {
+			@Override
+			protected Boolean buildValue_() {
+				return subject.isRefresh();
+			}
+			
+			@Override
+			protected void setValue_(Boolean value) {
+				subject.setRefresh(value);
+			}
+		};
+	}
+	
+	protected WritablePropertyValueModel<Boolean> buildCascadeTypeRemoveHolder() {
+		return new PropertyAspectAdapter<Cascade, Boolean>(getSubjectHolder(), Cascade.REMOVE_PROPERTY) {
+			@Override
+			protected Boolean buildValue_() {
+				return subject.isRemove();
+			}
+			
+			@Override
+			protected void setValue_(Boolean value) {
+				subject.setRemove(value);
+			}
+		};
+	}
+}
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/ColumnComposite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/ColumnComposite.java
new file mode 100644
index 0000000..67505ac
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/ColumnComposite.java
@@ -0,0 +1,573 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 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.ui.internal.details;
+
+import java.util.Collection;
+import java.util.Iterator;
+import org.eclipse.jpt.core.context.BaseColumn;
+import org.eclipse.jpt.core.context.Column;
+import org.eclipse.jpt.core.context.NamedColumn;
+import org.eclipse.jpt.db.Table;
+import org.eclipse.jpt.ui.internal.JpaHelpContextIds;
+import org.eclipse.jpt.ui.internal.details.db.ColumnCombo;
+import org.eclipse.jpt.ui.internal.details.db.DatabaseObjectCombo;
+import org.eclipse.jpt.ui.internal.widgets.IntegerCombo;
+import org.eclipse.jpt.ui.internal.widgets.Pane;
+import org.eclipse.jpt.utility.internal.CollectionTools;
+import org.eclipse.jpt.utility.internal.model.value.PropertyAspectAdapter;
+import org.eclipse.jpt.utility.internal.model.value.SimplePropertyValueModel;
+import org.eclipse.jpt.utility.internal.model.value.TransformationPropertyValueModel;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.jpt.utility.model.value.WritablePropertyValueModel;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.swt.widgets.Composite;
+
+public class ColumnComposite
+	extends Pane<Column>
+{
+	public ColumnComposite(
+			Pane<?> parentPane,
+			PropertyValueModel<? extends Column> subjectHolder,
+			Composite parent) {
+		
+		super(parentPane, subjectHolder, parent, false);
+	}
+	
+	public ColumnComposite(
+			Pane<?> parentPane,
+			PropertyValueModel<? extends Column> subjectHolder,
+			Composite parent,
+			boolean automaticallyAlignWidgets) {
+		
+		super(parentPane, subjectHolder, parent, automaticallyAlignWidgets);
+	}
+	
+	public ColumnComposite(
+			Pane<?> parentPane,
+			PropertyValueModel<? extends Column> subjectHolder,
+			Composite parent,
+			boolean automaticallyAlignWidgets,
+			boolean parentManagePane) {
+		
+		super(parentPane, subjectHolder, parent, automaticallyAlignWidgets, parentManagePane);
+	}
+	
+	
+	private ColumnCombo<Column> addColumnCombo(Composite container) {
+		
+		return new ColumnCombo<Column>(this, container) {
+			@Override
+			protected void addPropertyNames(Collection<String> propertyNames) {
+				super.addPropertyNames(propertyNames);
+				propertyNames.add(NamedColumn.DEFAULT_NAME_PROPERTY);
+				propertyNames.add(NamedColumn.SPECIFIED_NAME_PROPERTY);
+				propertyNames.add(BaseColumn.DEFAULT_TABLE_PROPERTY);
+				propertyNames.add(BaseColumn.SPECIFIED_TABLE_PROPERTY);
+			}
+			
+			@Override
+			protected void propertyChanged(String propertyName) {
+				if (propertyName == BaseColumn.DEFAULT_TABLE_PROPERTY ||
+				    propertyName == BaseColumn.SPECIFIED_TABLE_PROPERTY) {
+					this.doPopulate();
+				} else {
+					super.propertyChanged(propertyName);
+				}
+			}
+			
+			@Override
+			protected String getDefaultValue() {
+				return getSubject().getDefaultName();
+			}
+			
+			@Override
+			protected void setValue(String value) {
+				getSubject().setSpecifiedName(value);
+			}
+			
+			@Override
+			protected Table getDbTable_() {
+				return getSubject().getDbTable();
+			}
+			
+			@Override
+			protected String getValue() {
+				return getSubject().getSpecifiedName();
+			}
+			
+			@Override
+			protected String buildNullDefaultValueEntry() {
+				return NLS.bind(
+						JptUiDetailsMessages.DefaultWithOneParam,
+						JptUiDetailsMessages.NoneSelected);
+			}
+			
+			@Override
+			public String toString() {
+				return "ColumnComposite.columnCombo"; //$NON-NLS-1$
+			}
+		};
+	}
+	
+	private WritablePropertyValueModel<String> buildColumnDefinitionHolder() {
+		return new PropertyAspectAdapter<Column, String>(getSubjectHolder(), NamedColumn.COLUMN_DEFINITION_PROPERTY) {
+			@Override
+			protected String buildValue_() {
+				return this.subject.getColumnDefinition();
+			}
+			
+			@Override
+			protected void setValue_(String value) {
+				if (value.length() == 0) {
+					value = null;
+				}
+				this.subject.setColumnDefinition(value);
+			}
+		};
+	}
+	
+	private WritablePropertyValueModel<Boolean> buildInsertableHolder() {
+		return new PropertyAspectAdapter<Column, Boolean>(getSubjectHolder(), BaseColumn.SPECIFIED_INSERTABLE_PROPERTY) {
+			@Override
+			protected Boolean buildValue_() {
+				return this.subject.getSpecifiedInsertable();
+			}
+
+			@Override
+			protected void setValue_(Boolean value) {
+				this.subject.setSpecifiedInsertable(value);
+			}
+		};
+	}
+	
+	private PropertyValueModel<String> buildInsertableStringHolder() {
+		return new TransformationPropertyValueModel<Boolean, String>(buildDefaultInsertableHolder()) {
+			@Override
+			protected String transform(Boolean value) {
+				if (value != null) {
+					String defaultStringValue = value.booleanValue() ? JptUiDetailsMessages.Boolean_True : JptUiDetailsMessages.Boolean_False;
+					return NLS.bind(JptUiDetailsMessages.ColumnComposite_insertableWithDefault, defaultStringValue);
+				}
+				return JptUiDetailsMessages.ColumnComposite_insertable;
+			}
+		};
+	}
+	
+	private PropertyValueModel<Boolean> buildDefaultInsertableHolder() {
+		return new PropertyAspectAdapter<Column, Boolean>(
+				getSubjectHolder(),
+				BaseColumn.SPECIFIED_INSERTABLE_PROPERTY,
+				BaseColumn.DEFAULT_INSERTABLE_PROPERTY) {
+			
+			@Override
+			protected Boolean buildValue_() {
+				if (this.subject.getSpecifiedInsertable() != null) {
+					return null;
+				}
+				return Boolean.valueOf(this.subject.isDefaultInsertable());
+			}
+		};
+	}
+	
+	private WritablePropertyValueModel<Boolean> buildNullableHolder() {
+		return new PropertyAspectAdapter<Column, Boolean>(
+				getSubjectHolder(),
+				BaseColumn.SPECIFIED_NULLABLE_PROPERTY) {
+			
+			@Override
+			protected Boolean buildValue_() {
+				return this.subject.getSpecifiedNullable();
+			}
+			
+			@Override
+			protected void setValue_(Boolean value) {
+				this.subject.setSpecifiedNullable(value);
+			}
+		};
+	}
+	
+	private PropertyValueModel<String> buildNullableStringHolder() {
+		return new TransformationPropertyValueModel<Boolean, String>(buildDefaultNullableHolder()) {
+			@Override
+			protected String transform(Boolean value) {
+				if (value != null) {
+					String defaultStringValue = value.booleanValue() ? JptUiDetailsMessages.Boolean_True : JptUiDetailsMessages.Boolean_False;
+					return NLS.bind(JptUiDetailsMessages.ColumnComposite_nullableWithDefault, defaultStringValue);
+				}
+				return JptUiDetailsMessages.ColumnComposite_nullable;
+			}
+		};
+	}
+	
+	private PropertyValueModel<Boolean> buildDefaultNullableHolder() {
+		return new PropertyAspectAdapter<Column, Boolean>(
+				getSubjectHolder(),
+				BaseColumn.SPECIFIED_NULLABLE_PROPERTY,
+				BaseColumn.DEFAULT_NULLABLE_PROPERTY) {
+			
+			@Override
+			protected Boolean buildValue_() {
+				if (this.subject.getSpecifiedNullable() != null) {
+					return null;
+				}
+				return Boolean.valueOf(this.subject.isDefaultNullable());
+			}
+		};
+	}
+	
+	private Pane<Column> addTableCombo(Composite container) {
+		
+		return new DatabaseObjectCombo<Column>(this, container) {
+			
+			@Override
+			protected void addPropertyNames(Collection<String> propertyNames) {
+				super.addPropertyNames(propertyNames);
+				propertyNames.add(BaseColumn.DEFAULT_TABLE_PROPERTY);
+				propertyNames.add(BaseColumn.SPECIFIED_TABLE_PROPERTY);
+			}
+			
+			@Override
+			protected String getDefaultValue() {
+				return this.getSubject().getDefaultTable();
+			}
+			
+			@Override
+			protected void setValue(String value) {
+				this.getSubject().setSpecifiedTable(value);
+			}
+			
+			@Override
+			protected String getValue() {
+				return this.getSubject().getSpecifiedTable();
+			}
+			
+			@Override
+			protected Iterable<String> getValues_() {
+				return CollectionTools.iterable(this.values());
+			}
+			
+			protected Iterator<String> values() {
+				return this.getSubject().candidateTableNames();
+			}
+			
+			@Override
+			protected String buildNullDefaultValueEntry() {
+				return NLS.bind(
+						JptUiDetailsMessages.DefaultWithOneParam,
+						JptUiDetailsMessages.NoneSelected);
+			}
+			
+			@Override
+			public String toString() {
+				return "ColumnComposite.tableCombo"; //$NON-NLS-1$
+			}
+		};
+	}
+	
+	private WritablePropertyValueModel<Boolean> buildUniqueHolder() {
+		return new PropertyAspectAdapter<Column, Boolean>(
+				getSubjectHolder(),
+				BaseColumn.SPECIFIED_UNIQUE_PROPERTY) {
+			
+			@Override
+			protected Boolean buildValue_() {
+				return this.subject.getSpecifiedUnique();
+			}
+			
+			@Override
+			protected void setValue_(Boolean value) {
+				this.subject.setSpecifiedUnique(value);
+			}
+		};
+	}
+	
+	private PropertyValueModel<String> buildUniqueStringHolder() {
+		
+		return new TransformationPropertyValueModel<Boolean, String>(buildDefaultUniqueHolder()) {
+			
+			@Override
+			protected String transform(Boolean value) {
+				if (value != null) {
+					String defaultStringValue = value.booleanValue() ? JptUiDetailsMessages.Boolean_True : JptUiDetailsMessages.Boolean_False;
+					return NLS.bind(JptUiDetailsMessages.ColumnComposite_uniqueWithDefault, defaultStringValue);
+				}
+				return JptUiDetailsMessages.ColumnComposite_unique;
+			}
+		};
+	}
+	
+	private PropertyValueModel<Boolean> buildDefaultUniqueHolder() {
+		return new PropertyAspectAdapter<Column, Boolean>(
+				getSubjectHolder(),
+				BaseColumn.SPECIFIED_UNIQUE_PROPERTY,
+				BaseColumn.DEFAULT_UNIQUE_PROPERTY) {
+			
+			@Override
+			protected Boolean buildValue_() {
+				if (this.subject.getSpecifiedUnique() != null) {
+					return null;
+				}
+				return Boolean.valueOf(this.subject.isDefaultUnique());
+			}
+		};
+	}
+	
+	private WritablePropertyValueModel<Boolean> buildUpdatableHolder() {
+		return new PropertyAspectAdapter<Column, Boolean>(
+				getSubjectHolder(),
+				BaseColumn.DEFAULT_UPDATABLE_PROPERTY,
+				BaseColumn.SPECIFIED_UPDATABLE_PROPERTY) {
+			
+			@Override
+			protected Boolean buildValue_() {
+				return this.subject.getSpecifiedUpdatable();
+			}
+			
+			@Override
+			protected void setValue_(Boolean value) {
+				this.subject.setSpecifiedUpdatable(value);
+			}
+		};
+	}
+	
+	private PropertyValueModel<String> buildUpdatableStringHolder() {
+		
+		return new TransformationPropertyValueModel<Boolean, String>(buildDefaultUpdatableHolder()) {
+			
+			@Override
+			protected String transform(Boolean value) {
+				if (value != null) {
+					String defaultStringValue = value.booleanValue() ? JptUiDetailsMessages.Boolean_True : JptUiDetailsMessages.Boolean_False;
+					return NLS.bind(JptUiDetailsMessages.ColumnComposite_updatableWithDefault, defaultStringValue);
+				}
+				return JptUiDetailsMessages.ColumnComposite_updatable;
+			}
+		};
+	}
+	
+	private PropertyValueModel<Boolean> buildDefaultUpdatableHolder() {
+		return new PropertyAspectAdapter<Column, Boolean>(
+				getSubjectHolder(),
+				BaseColumn.SPECIFIED_UPDATABLE_PROPERTY,
+				BaseColumn.DEFAULT_UPDATABLE_PROPERTY) {
+			
+			@Override
+			protected Boolean buildValue_() {
+				if (this.subject.getSpecifiedUpdatable() != null) {
+					return null;
+				}
+				return Boolean.valueOf(this.subject.isDefaultUpdatable());
+			}
+		};
+	}
+	
+	@Override
+	protected void initializeLayout(Composite container) {
+		// Column group pane
+		container = addTitledGroup(
+				container,
+				JptUiDetailsMessages.ColumnComposite_columnSection);
+		
+		// Column widgets
+		addLabeledComposite(
+				container,
+				JptUiDetailsMessages.ColumnComposite_name,
+				addColumnCombo(container),
+				JpaHelpContextIds.MAPPING_COLUMN);
+		
+		// Table widgets
+		addLabeledComposite(
+				container,
+				JptUiDetailsMessages.ColumnComposite_table,
+				addTableCombo(container),
+				JpaHelpContextIds.MAPPING_COLUMN_TABLE);
+		
+		// Details sub-pane
+		container = addCollapsibleSubSection(
+				container,
+				JptUiDetailsMessages.ColumnComposite_details,
+				new SimplePropertyValueModel<Boolean>(Boolean.FALSE));
+		
+		new DetailsComposite(this, getSubjectHolder(), addSubPane(container, 0, 16));
+	}
+	
+	protected class DetailsComposite extends Pane<Column> {
+				
+		public DetailsComposite(
+				Pane<?> parentPane,
+	            PropertyValueModel<? extends Column> subjectHolder,
+	            Composite parent) {
+			
+			super(parentPane, subjectHolder, parent, false);
+		}
+		
+		@Override
+		protected void initializeLayout(Composite container) {
+			// Insertable tri-state check box
+			addTriStateCheckBoxWithDefault(
+					addSubPane(container, 4),
+					JptUiDetailsMessages.ColumnComposite_insertable,
+					buildInsertableHolder(),
+					buildInsertableStringHolder(),
+					JpaHelpContextIds.MAPPING_COLUMN_INSERTABLE);
+			
+			// Updatable tri-state check box
+			addTriStateCheckBoxWithDefault(
+					container,
+					JptUiDetailsMessages.ColumnComposite_updatable,
+					buildUpdatableHolder(),
+					buildUpdatableStringHolder(),
+					JpaHelpContextIds.MAPPING_COLUMN_UPDATABLE);
+			
+			// Unique tri-state check box
+			addTriStateCheckBoxWithDefault(
+					container,
+					JptUiDetailsMessages.ColumnComposite_unique,
+					buildUniqueHolder(),
+					buildUniqueStringHolder(),
+					JpaHelpContextIds.MAPPING_COLUMN_UNIQUE);
+			
+			// Nullable tri-state check box
+			addTriStateCheckBoxWithDefault(
+					container,
+					JptUiDetailsMessages.ColumnComposite_nullable,
+					buildNullableHolder(),
+					buildNullableStringHolder(),
+					JpaHelpContextIds.MAPPING_COLUMN_NULLABLE);
+			
+			addLengthCombo(container);
+			addPrecisionCombo(container);
+			addScaleCombo(container);
+			
+			// Column Definition widgets
+			addLabeledText(
+					container,
+					JptUiDetailsMessages.ColumnComposite_columnDefinition,
+					buildColumnDefinitionHolder());
+		}
+		
+		private void addLengthCombo(Composite container) {
+			new IntegerCombo<Column>(this, container) {
+				@Override
+				protected String getLabelText() {
+					return JptUiDetailsMessages.ColumnComposite_length;
+				}
+				
+				@Override
+				protected String getHelpId() {
+					return JpaHelpContextIds.MAPPING_COLUMN_LENGTH;
+				}
+				
+				@Override
+				protected PropertyValueModel<Integer> buildDefaultHolder() {
+					return new PropertyAspectAdapter<Column, Integer>(getSubjectHolder(), Column.DEFAULT_LENGTH_PROPERTY) {
+						@Override
+						protected Integer buildValue_() {
+							return Integer.valueOf(this.subject.getDefaultLength());
+						}
+					};
+				}
+				
+				@Override
+				protected WritablePropertyValueModel<Integer> buildSelectedItemHolder() {
+					return new PropertyAspectAdapter<Column, Integer>(getSubjectHolder(), Column.SPECIFIED_LENGTH_PROPERTY) {
+						@Override
+						protected Integer buildValue_() {
+							return this.subject.getSpecifiedLength();
+						}
+						
+						@Override
+						protected void setValue_(Integer value) {
+							this.subject.setSpecifiedLength(value);
+						}
+					};
+				}
+			};
+		}
+		
+		private void addPrecisionCombo(Composite container) {
+			new IntegerCombo<Column>(this, container) {	
+				@Override
+				protected String getLabelText() {
+					return JptUiDetailsMessages.ColumnComposite_precision;
+				}
+				
+				@Override
+				protected String getHelpId() {
+					return JpaHelpContextIds.MAPPING_COLUMN_PRECISION;
+				}
+				
+				@Override
+				protected PropertyValueModel<Integer> buildDefaultHolder() {
+					return new PropertyAspectAdapter<Column, Integer>(getSubjectHolder(), Column.DEFAULT_PRECISION_PROPERTY) {
+						@Override
+						protected Integer buildValue_() {
+							return Integer.valueOf(this.subject.getDefaultPrecision());
+						}
+					};
+				}
+				
+				@Override
+				protected WritablePropertyValueModel<Integer> buildSelectedItemHolder() {
+					return new PropertyAspectAdapter<Column, Integer>(getSubjectHolder(), Column.SPECIFIED_PRECISION_PROPERTY) {
+						@Override
+						protected Integer buildValue_() {
+							return this.subject.getSpecifiedPrecision();
+						}
+						
+						@Override
+						protected void setValue_(Integer value) {
+							this.subject.setSpecifiedPrecision(value);
+						}
+					};
+				}
+			};
+		}
+		
+		private void addScaleCombo(Composite container) {
+			new IntegerCombo<Column>(this, container) {	
+				@Override
+				protected String getLabelText() {
+					return JptUiDetailsMessages.ColumnComposite_scale;
+				}
+				
+				@Override
+				protected String getHelpId() {
+					return JpaHelpContextIds.MAPPING_COLUMN_SCALE;
+				}
+				
+				@Override
+				protected PropertyValueModel<Integer> buildDefaultHolder() {
+					return new PropertyAspectAdapter<Column, Integer>(getSubjectHolder(), Column.DEFAULT_SCALE_PROPERTY) {
+						@Override
+						protected Integer buildValue_() {
+							return Integer.valueOf(this.subject.getDefaultScale());
+						}
+					};
+				}
+				
+				@Override
+				protected WritablePropertyValueModel<Integer> buildSelectedItemHolder() {
+					return new PropertyAspectAdapter<Column, Integer>(getSubjectHolder(), Column.SPECIFIED_SCALE_PROPERTY) {
+						@Override
+						protected Integer buildValue_() {
+							return this.subject.getSpecifiedScale();
+						}
+						
+						@Override
+						protected void setValue_(Integer value) {
+							this.subject.setSpecifiedScale(value);
+						}
+					};
+				}
+			};
+		}
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/DiscriminatorColumnComposite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/DiscriminatorColumnComposite.java
new file mode 100644
index 0000000..bb51d77
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/DiscriminatorColumnComposite.java
@@ -0,0 +1,308 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2010 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.ui.internal.details;
+
+import java.util.Collection;
+
+import org.eclipse.jpt.core.context.DiscriminatorColumn;
+import org.eclipse.jpt.core.context.DiscriminatorType;
+import org.eclipse.jpt.core.context.Entity;
+import org.eclipse.jpt.core.context.NamedColumn;
+import org.eclipse.jpt.db.Table;
+import org.eclipse.jpt.ui.internal.JpaHelpContextIds;
+import org.eclipse.jpt.ui.internal.details.db.ColumnCombo;
+import org.eclipse.jpt.ui.internal.util.PaneEnabler;
+import org.eclipse.jpt.ui.internal.widgets.EnumFormComboViewer;
+import org.eclipse.jpt.ui.internal.widgets.IntegerCombo;
+import org.eclipse.jpt.ui.internal.widgets.Pane;
+import org.eclipse.jpt.utility.internal.model.value.PropertyAspectAdapter;
+import org.eclipse.jpt.utility.internal.model.value.SimplePropertyValueModel;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.jpt.utility.model.value.WritablePropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * Here the layout of this pane:
+ * <pre>
+ * -----------------------------------------------------------------------------
+ * |                                                                           |
+ * | > Discriminator Column                                                    |
+ * |                                                                           |
+ * |                      ---------------------------------------------------- |
+ * | Name:                | ColumnCombo                                    |v| |
+ * |                      ---------------------------------------------------- |
+ * |                      ---------------------------------------------------- |
+ * | Type:                | EnumComboViewer                                |v| |
+ * |                      ---------------------------------------------------- |
+ * | > Details																   |
+ * |                                                                           |
+ * |                      ---------------------------------------------------- |
+ * | Column Definition:   | I                                                | |
+ * |                      ---------------------------------------------------- |
+ * |                      -------------                                        |
+ * | Length:              | I       |I|                                        |
+ * |                      -------------                                        |
+ * -----------------------------------------------------------------------------</pre>
+ *
+ * @see Entity
+ * @see AbstractEntityComposite - The parent container
+ * @see ColumnCombo
+ * @see EnumComboViewer
+ * @see PrimaryKeyJoinColumnsComposite
+ *
+ * @version 2.0
+ * @since 2.0
+ */
+public class DiscriminatorColumnComposite<T extends Entity> extends Pane<T> {
+
+	/**
+	 * Creates a new <code>InheritanceComposite</code>.
+	 *
+	 * @param parentPane The parent container of this one
+	 * @param parent The parent container
+	 */
+	public DiscriminatorColumnComposite(Pane<? extends T> parentPane,
+	                            Composite parent) {
+
+		super(parentPane, parent, false);
+	}
+
+	@Override
+	protected void initializeLayout(Composite container) {
+		// Discriminator Column sub-pane
+		Composite discriminatorColumnContainer = addTitledGroup(
+			addSubPane(container, 10),
+			JptUiDetailsMessages.InheritanceComposite_discriminatorColumnGroupBox
+		);
+
+		PropertyValueModel<DiscriminatorColumn> discriminatorColumnHolder =
+			buildDiscriminatorColumnHolder();
+
+		// Name widgets
+		addLabeledComposite(
+			discriminatorColumnContainer,
+			JptUiDetailsMessages.DiscriminatorColumnComposite_name,
+			addDiscriminatorColumnCombo(container, discriminatorColumnHolder),
+			JpaHelpContextIds.ENTITY_INHERITANCE_DISCRIMINATOR_COLUMN
+		);
+
+		// Discriminator Type widgets
+		addLabeledComposite(
+			discriminatorColumnContainer,
+			JptUiDetailsMessages.DiscriminatorColumnComposite_discriminatorType,
+			addDiscriminatorTypeCombo(container, discriminatorColumnHolder),
+			JpaHelpContextIds.ENTITY_INHERITANCE_DISCRIMINATOR_TYPE
+		);
+
+		container = addCollapsibleSubSection(
+			discriminatorColumnContainer,
+			JptUiDetailsMessages.InheritanceComposite_detailsGroupBox,
+			new SimplePropertyValueModel<Boolean>(Boolean.FALSE)
+		);
+		
+		new DetailsComposite(this, discriminatorColumnHolder, addSubPane(container, 0, 16));
+		
+		new PaneEnabler(buildDiscriminatorColumnEnabledHolder(), this);
+	}
+
+	private ColumnCombo<DiscriminatorColumn> addDiscriminatorColumnCombo(
+		Composite container,
+		PropertyValueModel<DiscriminatorColumn> discriminatorColumnHolder) {
+
+		return new ColumnCombo<DiscriminatorColumn>(
+			this,
+			discriminatorColumnHolder,
+			container)
+		{
+
+			@Override
+			protected void addPropertyNames(Collection<String> propertyNames) {
+				super.addPropertyNames(propertyNames);
+				propertyNames.add(NamedColumn.SPECIFIED_NAME_PROPERTY);
+				propertyNames.add(NamedColumn.DEFAULT_NAME_PROPERTY);
+			}
+
+			@Override
+			protected String getDefaultValue() {
+				return getSubject().getDefaultName();
+			}
+
+			@Override
+			protected void setValue(String value) {
+				getSubject().setSpecifiedName(value);
+			}
+
+			@Override
+			protected Table getDbTable_() {
+				return getSubject().getDbTable();
+			}
+
+			@Override
+			protected String getValue() {
+				return getSubject().getSpecifiedName();
+			}
+			
+			@Override
+			protected String buildNullDefaultValueEntry() {
+				return JptUiDetailsMessages.NoneSelected;
+			}
+		};
+	}
+
+	private PropertyValueModel<DiscriminatorColumn> buildDiscriminatorColumnHolder() {
+		return new PropertyAspectAdapter<Entity, DiscriminatorColumn>(getSubjectHolder()) {
+			@Override
+			protected DiscriminatorColumn buildValue_() {
+				return this.subject.getDiscriminatorColumn();
+			}
+		};
+	}
+
+	private EnumFormComboViewer<DiscriminatorColumn, DiscriminatorType> addDiscriminatorTypeCombo(
+		Composite container,
+		PropertyValueModel<DiscriminatorColumn> discriminatorColumnHolder) {
+
+		return new EnumFormComboViewer<DiscriminatorColumn, DiscriminatorType>(
+			this,
+			discriminatorColumnHolder,
+			container)
+		{
+			@Override
+			protected void addPropertyNames(Collection<String> propertyNames) {
+				super.addPropertyNames(propertyNames);
+				propertyNames.add(DiscriminatorColumn.DEFAULT_DISCRIMINATOR_TYPE_PROPERTY);
+				propertyNames.add(DiscriminatorColumn.SPECIFIED_DISCRIMINATOR_TYPE_PROPERTY);
+			}
+
+			@Override
+			protected DiscriminatorType[] getChoices() {
+				return DiscriminatorType.values();
+			}
+
+			@Override
+			protected DiscriminatorType getDefaultValue() {
+				return getSubject().getDefaultDiscriminatorType();
+			}
+
+			@Override
+			protected String displayString(DiscriminatorType value) {
+				return buildDisplayString(
+					JptUiDetailsMessages.class,
+					DiscriminatorColumnComposite.class,
+					value
+				);
+			}
+			
+			@Override
+			protected String nullDisplayString() {
+				return JptUiDetailsMessages.NoneSelected;
+			}
+			
+			@Override
+			protected DiscriminatorType getValue() {
+				return getSubject().getSpecifiedDiscriminatorType();
+			}
+
+			@Override
+			protected void setValue(DiscriminatorType value) {
+				getSubject().setSpecifiedDiscriminatorType(value);
+			}
+		};
+	}
+	
+	protected WritablePropertyValueModel<Boolean> buildDiscriminatorColumnEnabledHolder() {
+		return new PropertyAspectAdapter<Entity, Boolean>(getSubjectHolder(), Entity.SPECIFIED_DISCRIMINATOR_COLUMN_IS_ALLOWED_PROPERTY) {
+			@Override
+			protected Boolean buildValue_() {
+				return Boolean.valueOf(this.subject.specifiedDiscriminatorColumnIsAllowed());
+			}
+		};
+	}
+	
+	protected class DetailsComposite extends Pane<DiscriminatorColumn> {
+		public DetailsComposite(Pane<?> parentPane,
+            PropertyValueModel<? extends DiscriminatorColumn> subjectHolder,
+            Composite parent) {
+
+			super(parentPane, subjectHolder, parent, false);
+		}
+
+		@Override
+		protected void initializeLayout(Composite container) {
+			// Length widgets
+			addLengthCombo(container);
+
+			// Column Definition widgets
+			addLabeledText(
+				container,
+				JptUiDetailsMessages.ColumnComposite_columnDefinition,
+				buildColumnDefinitionHolder(getSubjectHolder())
+			);
+		}
+		
+		private void addLengthCombo(Composite container) {
+			new IntegerCombo<DiscriminatorColumn>(this, container) {
+				
+				@Override
+				protected String getLabelText() {
+					return JptUiDetailsMessages.ColumnComposite_length;
+				}
+			
+				@Override
+				protected String getHelpId() {
+					return JpaHelpContextIds.MAPPING_COLUMN_LENGTH;
+				}
+
+				@Override
+				protected PropertyValueModel<Integer> buildDefaultHolder() {
+					return new PropertyAspectAdapter<DiscriminatorColumn, Integer>(getSubjectHolder(), DiscriminatorColumn.DEFAULT_LENGTH_PROPERTY) {
+						@Override
+						protected Integer buildValue_() {
+							return Integer.valueOf(this.subject.getDefaultLength());
+						}
+					};
+				}
+				
+				@Override
+				protected WritablePropertyValueModel<Integer> buildSelectedItemHolder() {
+					return new PropertyAspectAdapter<DiscriminatorColumn, Integer>(getSubjectHolder(), DiscriminatorColumn.SPECIFIED_LENGTH_PROPERTY) {
+						@Override
+						protected Integer buildValue_() {
+							return this.subject.getSpecifiedLength();
+						}
+
+						@Override
+						protected void setValue_(Integer value) {
+							this.subject.setSpecifiedLength(value);
+						}
+					};
+				}
+			};
+		}
+		
+		private WritablePropertyValueModel<String> buildColumnDefinitionHolder(PropertyValueModel<DiscriminatorColumn> discriminatorColumnHolder) {
+
+			return new PropertyAspectAdapter<DiscriminatorColumn, String>(discriminatorColumnHolder, NamedColumn.COLUMN_DEFINITION_PROPERTY) {
+				@Override
+				protected String buildValue_() {
+					return this.subject.getColumnDefinition();
+				}
+
+				@Override
+				protected void setValue_(String value) {
+					if (value.length() == 0) {
+						value = null;
+					}
+					this.subject.setColumnDefinition(value);
+				}
+			};
+		}
+	}
+}
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/EmbeddedIdMappingComposite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/EmbeddedIdMappingComposite.java
new file mode 100644
index 0000000..3041165
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/EmbeddedIdMappingComposite.java
@@ -0,0 +1,35 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 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.ui.internal.details;
+
+import org.eclipse.jpt.core.context.EmbeddedIdMapping;
+import org.eclipse.jpt.ui.WidgetFactory;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+public class EmbeddedIdMappingComposite
+	extends AbstractEmbeddedIdMappingComposite<EmbeddedIdMapping>
+{
+	public EmbeddedIdMappingComposite(
+			PropertyValueModel<? extends EmbeddedIdMapping> subjectHolder,
+			Composite parent,
+			WidgetFactory widgetFactory) {
+		
+		super(subjectHolder, parent, widgetFactory);
+	}
+	
+	
+	@Override
+	protected void initializeEmbeddedIdSection(Composite container) {
+		new EmbeddedMappingOverridesComposite(
+				this,
+				container);
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/EmbeddedMappingComposite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/EmbeddedMappingComposite.java
new file mode 100644
index 0000000..01a3965
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/EmbeddedMappingComposite.java
@@ -0,0 +1,50 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 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.ui.internal.details;
+
+import org.eclipse.jpt.core.context.EmbeddedMapping;
+import org.eclipse.jpt.ui.WidgetFactory;
+import org.eclipse.jpt.ui.details.JpaComposite;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * Here the layout of this pane:
+ * <pre>
+ * -----------------------------------------------------------------------------
+ * | ------------------------------------------------------------------------- |
+ * | |                                                                       | |
+ * | | EmbeddedAttributeOverridesComposite                                   | |
+ * | |                                                                       | |
+ * | ------------------------------------------------------------------------- |
+ * -----------------------------------------------------------------------------</pre>
+ *
+ * @see EmbeddedMapping
+ *
+ * @version 2.3
+ * @since 1.0
+ */
+public class EmbeddedMappingComposite extends AbstractEmbeddedMappingComposite<EmbeddedMapping>
+                                      implements JpaComposite
+{
+	/**
+	 * Creates a new <code>EmbeddedMappingComposite</code>.
+	 *
+	 * @param subjectHolder The holder of the subject <code>EmbeddedMapping</code>
+	 * @param parent The parent container
+	 * @param widgetFactory The factory used to create various common widgets
+	 */
+	public EmbeddedMappingComposite(PropertyValueModel<? extends EmbeddedMapping> subjectHolder,
+	                                Composite parent,
+	                                WidgetFactory widgetFactory) {
+
+		super(subjectHolder, parent, widgetFactory);
+	}
+}
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/EmbeddedMappingOverridesComposite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/EmbeddedMappingOverridesComposite.java
new file mode 100644
index 0000000..fcbf0b1
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/EmbeddedMappingOverridesComposite.java
@@ -0,0 +1,50 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 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.ui.internal.details;
+
+import org.eclipse.jpt.core.context.AssociationOverrideContainer;
+import org.eclipse.jpt.core.context.AttributeOverrideContainer;
+import org.eclipse.jpt.core.context.BaseEmbeddedMapping;
+import org.eclipse.jpt.ui.internal.widgets.Pane;
+import org.eclipse.jpt.utility.internal.model.value.PropertyAspectAdapter;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+public class EmbeddedMappingOverridesComposite
+	extends AbstractEmbeddedMappingOverridesComposite<BaseEmbeddedMapping>
+{
+	public EmbeddedMappingOverridesComposite(
+			Pane<? extends BaseEmbeddedMapping> parentPane,
+			Composite parent) {
+		
+		super(parentPane, parent);
+	}
+	
+	
+	@Override
+	protected boolean supportsAssociationOverrides() {
+		return false;
+	}	
+	
+	@Override
+	protected PropertyValueModel<AttributeOverrideContainer> buildAttributeOverrideContainerHolder() {
+		return new PropertyAspectAdapter<BaseEmbeddedMapping, AttributeOverrideContainer>(getSubjectHolder()) {
+			@Override
+			protected AttributeOverrideContainer buildValue_() {
+				return this.subject.getAttributeOverrideContainer();
+			}
+		};
+	}
+	
+	@Override
+	protected PropertyValueModel<AssociationOverrideContainer> buildAssociationOverrideContainerHolder() {
+		throw new UnsupportedOperationException();
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/EntityNameComposite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/EntityNameComposite.java
new file mode 100644
index 0000000..c5f3c7b
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/EntityNameComposite.java
@@ -0,0 +1,121 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2010 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.ui.internal.details;
+
+import org.eclipse.jpt.core.context.Entity;
+import org.eclipse.jpt.ui.internal.JpaHelpContextIds;
+import org.eclipse.jpt.ui.internal.util.SWTUtil;
+import org.eclipse.jpt.ui.internal.widgets.Pane;
+import org.eclipse.jpt.utility.internal.model.value.PropertyAspectAdapter;
+import org.eclipse.jpt.utility.internal.model.value.PropertyListValueModelAdapter;
+import org.eclipse.jpt.utility.model.value.ListValueModel;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.jpt.utility.model.value.WritablePropertyValueModel;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * Here the layout of this pane:
+ * <pre>
+ * -----------------------------------------------------------------------------
+ * |              ------------------------------------------------------------ |
+ * | Entity Name: | I                                                      |v| |
+ * |              ------------------------------------------------------------ |
+ * -----------------------------------------------------------------------------</pre>
+ *
+ * @see Entity
+ * @see AbstractEntityComposite - The parent container
+ *
+ * @version 2.3
+ * @since 1.0
+ */
+public class EntityNameComposite
+	extends Pane<Entity>
+{
+	/**
+	 * Creates a new <code>EntityNameComposite</code>.
+	 *
+	 * @param parentPane The parent container of this one
+	 * @param parent The parent container
+	 */
+	public EntityNameComposite(
+			Pane<? extends Entity> parentPane,
+			Composite parent) {
+		
+		super(parentPane, parent);
+	}
+	
+	
+	@Override
+	protected void initializeLayout(Composite container) {
+		Combo combo = addLabeledEditableCombo(
+			container,
+			JptUiDetailsMessages.EntityNameComposite_name,
+			buildDefaultEntityNameListHolder(),
+			buildEntityNameHolder(),
+			JpaHelpContextIds.ENTITY_NAME);
+		
+		SWTUtil.attachDefaultValueHandler(combo);
+	}
+	
+	private ListValueModel<String> buildDefaultEntityNameListHolder() {
+		return new PropertyListValueModelAdapter<String>(
+			buildDefaultEntityNameHolder()
+		);
+	}
+
+	private PropertyValueModel<String> buildDefaultEntityNameHolder() {
+		return new PropertyAspectAdapter<Entity, String>(getSubjectHolder(), Entity.DEFAULT_NAME_PROPERTY) {
+			@Override
+			protected String buildValue_() {
+				return defaultValue(this.subject);
+			}
+		};
+	}
+
+	private WritablePropertyValueModel<String> buildEntityNameHolder() {
+		return new PropertyAspectAdapter<Entity, String>(getSubjectHolder(), Entity.SPECIFIED_NAME_PROPERTY, Entity.DEFAULT_NAME_PROPERTY) {
+			@Override
+			protected String buildValue_() {
+
+				String name = this.subject.getSpecifiedName();
+
+				if (name == null) {
+					name = defaultValue(this.subject);
+				}
+
+				return name;
+			}
+
+			@Override
+			protected void setValue_(String value) {
+
+				if (defaultValue(this.subject).equals(value)) {
+					value = null;
+				}
+
+				this.subject.setSpecifiedName(value);
+			}
+		};
+	}
+
+	private String defaultValue(Entity subject) {
+		String defaultValue = subject.getDefaultName();
+
+		if (defaultValue != null) {
+			return NLS.bind(
+				JptUiDetailsMessages.DefaultWithOneParam,
+				defaultValue
+			);
+		}
+		return JptUiDetailsMessages.DefaultEmpty;
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/EntityOverridesComposite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/EntityOverridesComposite.java
new file mode 100644
index 0000000..314689f
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/EntityOverridesComposite.java
@@ -0,0 +1,25 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 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.ui.internal.details;
+
+import org.eclipse.jpt.core.context.Entity;
+import org.eclipse.jpt.ui.internal.widgets.Pane;
+import org.eclipse.swt.widgets.Composite;
+
+public class EntityOverridesComposite
+	extends AbstractEntityOverridesComposite
+{
+	public EntityOverridesComposite(
+			Pane<? extends Entity> parentPane,
+			Composite parent) {
+		
+		super(parentPane, parent);
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/EnumTypeComposite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/EnumTypeComposite.java
new file mode 100644
index 0000000..1f53f2f
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/EnumTypeComposite.java
@@ -0,0 +1,115 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2010 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.ui.internal.details;
+
+import java.util.Collection;
+
+import org.eclipse.jpt.core.context.EnumType;
+import org.eclipse.jpt.core.context.EnumeratedConverter;
+import org.eclipse.jpt.ui.WidgetFactory;
+import org.eclipse.jpt.ui.internal.util.PaneEnabler;
+import org.eclipse.jpt.ui.internal.widgets.EnumFormComboViewer;
+import org.eclipse.jpt.ui.internal.widgets.Pane;
+import org.eclipse.jpt.utility.internal.model.value.TransformationPropertyValueModel;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * Here the layout of this pane:
+ * <pre>
+ * -----------------------------------------------------------------------------
+ * |            -------------------------------------------------------------- |
+ * | Enum Type: |                                                          |v| |
+ * |            -------------------------------------------------------------- |
+ * -----------------------------------------------------------------------------</pre>
+ *
+ * @see BasicMapping
+ * @see BasicMappingComposite - A container of this widget
+ *
+ * @version 2.0
+ * @since 1.0
+ */
+public class EnumTypeComposite extends Pane<EnumeratedConverter>
+{
+	/**
+	 * Creates a new <code>EnumTypeComposite</code>.
+	 *
+	 * @param parentPane The parent container of this one
+	 * @param parent The parent container
+	 */
+	public EnumTypeComposite(PropertyValueModel<? extends EnumeratedConverter> subjectHolder,
+			Composite parent,
+			WidgetFactory widgetFactory) {
+
+		super(subjectHolder, parent, widgetFactory);
+	}
+
+	private EnumFormComboViewer<EnumeratedConverter, EnumType> addEnumTypeCombo(Composite container) {
+
+		return new EnumFormComboViewer<EnumeratedConverter, EnumType>(this, container) {
+
+			@Override
+			protected void addPropertyNames(Collection<String> propertyNames) {
+				super.addPropertyNames(propertyNames);
+				propertyNames.add(EnumeratedConverter.SPECIFIED_ENUM_TYPE_PROPERTY);
+			}
+
+			@Override
+			protected EnumType[] getChoices() {
+				return EnumType.values();
+			}
+
+			@Override
+			protected EnumType getDefaultValue() {
+				return getSubject().getDefaultEnumType();
+			}
+
+			@Override
+			protected String displayString(EnumType value) {
+				return buildDisplayString(
+					JptUiDetailsMessages.class,
+					EnumTypeComposite.this,
+					value
+				);
+			}
+
+			@Override
+			protected EnumType getValue() {
+				return getSubject().getSpecifiedEnumType();
+			}
+
+			@Override
+			protected void setValue(EnumType value) {
+				getSubject().setSpecifiedEnumType(value);
+			}
+		};
+	}
+
+	@Override
+	protected void initializeLayout(Composite container) {
+		//JpaHelpContextIds.MAPPING_ENUMERATED
+		addEnumTypeCombo(container);
+		
+		new PaneEnabler(buildBooleanHolder(), this);
+	}
+	
+	
+	protected PropertyValueModel<Boolean> buildBooleanHolder() {
+		return new TransformationPropertyValueModel<EnumeratedConverter, Boolean>(getSubjectHolder()) {
+			@Override
+			protected Boolean transform(EnumeratedConverter value) {
+				if (getSubject() != null && getSubject().getParent().getPersistentAttribute().isVirtual()) {
+					return Boolean.FALSE;
+				}
+				return Boolean.valueOf(value != null);
+			}
+		};
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/FetchTypeComposite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/FetchTypeComposite.java
new file mode 100644
index 0000000..5474b45
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/FetchTypeComposite.java
@@ -0,0 +1,109 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2010 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.ui.internal.details;
+
+import java.util.Collection;
+
+import org.eclipse.jpt.core.context.FetchType;
+import org.eclipse.jpt.core.context.Fetchable;
+import org.eclipse.jpt.ui.internal.JpaHelpContextIds;
+import org.eclipse.jpt.ui.internal.widgets.EnumFormComboViewer;
+import org.eclipse.jpt.ui.internal.widgets.Pane;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * Here the layout of this pane:
+ * <pre>
+ * -----------------------------------------------------------------------------
+ * |        ------------------------------------------------------------------ |
+ * | Fetch: |                                                              |v| |
+ * |        ------------------------------------------------------------------ |
+ * -----------------------------------------------------------------------------</pre>
+ *
+ * @see Fetchable
+ * @see BasicMappingComposite - A container of this widget
+ * @see ManyToManyMappingComposite - A container of this widget
+ * @see ManyToOneMappingComposite - A container of this widget
+ * @see OneToManyMappingComposite - A container of this widget
+ * @see OneToOneMappingComposite - A container of this widget
+ *
+ * @version 2.0
+ * @since 1.0
+ */
+public class FetchTypeComposite extends Pane<Fetchable> {
+
+	/**
+	 * Creates a new <code>FetchTypeComposite</code>.
+	 *
+	 * @param parentPane The parent container of this one
+	 * @param parent The parent container
+	 */
+	public FetchTypeComposite(Pane<? extends Fetchable> parentPane,
+	                          Composite parent) {
+
+		super(parentPane, parent);
+	}
+
+	private EnumFormComboViewer<Fetchable, FetchType> addFetchTypeCombo(Composite container) {
+
+		return new EnumFormComboViewer<Fetchable, FetchType>(this, container) {
+
+			@Override
+			protected void addPropertyNames(Collection<String> propertyNames) {
+				super.addPropertyNames(propertyNames);
+				propertyNames.add(Fetchable.DEFAULT_FETCH_PROPERTY);
+				propertyNames.add(Fetchable.SPECIFIED_FETCH_PROPERTY);
+			}
+
+			@Override
+			protected FetchType[] getChoices() {
+				return FetchType.values();
+			}
+
+			@Override
+			protected FetchType getDefaultValue() {
+				return getSubject().getDefaultFetch();
+			}
+
+			@Override
+			protected String displayString(FetchType value) {
+				return buildDisplayString(
+					JptUiDetailsMessages.class,
+					FetchTypeComposite.this,
+					value
+				);
+			}
+
+			@Override
+			protected FetchType getValue() {
+				return getSubject().getSpecifiedFetch();
+			}
+
+			@Override
+			protected void setValue(FetchType value) {
+				getSubject().setSpecifiedFetch(value);
+			}
+		};
+	}
+
+	/*
+	 * (non-Javadoc)
+	 */
+	@Override
+	protected void initializeLayout(Composite container) {
+
+		addLabeledComposite(
+			container,
+			JptUiDetailsMessages.BasicGeneralSection_fetchLabel,
+			addFetchTypeCombo(container),
+			JpaHelpContextIds.MAPPING_FETCH_TYPE
+		);
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/GeneratedValueComposite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/GeneratedValueComposite.java
new file mode 100644
index 0000000..d9cb2be
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/GeneratedValueComposite.java
@@ -0,0 +1,205 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 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.ui.internal.details;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.ListIterator;
+import org.eclipse.jpt.core.context.GeneratedValue;
+import org.eclipse.jpt.core.context.GenerationType;
+import org.eclipse.jpt.core.context.IdMapping;
+import org.eclipse.jpt.core.context.persistence.PersistenceUnit;
+import org.eclipse.jpt.ui.internal.JpaHelpContextIds;
+import org.eclipse.jpt.ui.internal.widgets.EnumFormComboViewer;
+import org.eclipse.jpt.ui.internal.widgets.Pane;
+import org.eclipse.jpt.utility.internal.ArrayTools;
+import org.eclipse.jpt.utility.internal.CollectionTools;
+import org.eclipse.jpt.utility.internal.model.value.CompositeListValueModel;
+import org.eclipse.jpt.utility.internal.model.value.ListAspectAdapter;
+import org.eclipse.jpt.utility.internal.model.value.PropertyAspectAdapter;
+import org.eclipse.jpt.utility.model.value.ListValueModel;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.jpt.utility.model.value.WritablePropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * Here the layout of this pane:
+ * <pre>
+ * -----------------------------------------------------------------------------
+ * |                 --------------------------------------------------------- |
+ * | Strategy:       | I                                                   |v| |
+ * |                 --------------------------------------------------------- |
+ * |                 --------------------------------------------------------- |
+ * | Generator Name: | I                                                   |v| |
+ * |                 --------------------------------------------------------- |
+ * -----------------------------------------------------------------------------</pre>
+ *
+ * @see IdMapping
+ * @see GeneratedValue
+ * @see IdMappingGenerationComposite - The parent container
+ *
+ * @version 2.3
+ * @since 1.0
+ */
+public class GeneratedValueComposite extends Pane<IdMapping>
+{
+
+	/**
+	 * Creates a new <code>GeneratedValueComposite</code>.
+	 *
+	 * @param parentPane The parent container of this one
+	 * @param parent The parent container
+	 */
+	public GeneratedValueComposite(Pane<? extends IdMapping> parentPane,
+	 	                            Composite parent) {
+
+		super(parentPane, parent);
+	}
+
+	@Override
+	protected void initializeLayout(Composite container) {
+
+		// Strategy widgets
+		addLabeledComposite(
+			container,
+			JptUiDetailsMessages.GeneratedValueComposite_strategy,
+			addStrategyComboViewer(container),
+			JpaHelpContextIds.MAPPING_GENERATED_VALUE_STRATEGY
+		);
+
+		addLabeledEditableCombo(
+			container,
+			JptUiDetailsMessages.GeneratedValueComposite_generatorName,
+			buildGeneratorNameListHolder(),
+			buildGeneratorNameHolder(),
+			JpaHelpContextIds.MAPPING_GENERATED_VALUE_STRATEGY
+		);
+	}
+
+	private EnumFormComboViewer<GeneratedValue, GenerationType> addStrategyComboViewer(Composite parent) {
+
+		return new EnumFormComboViewer<GeneratedValue, GenerationType>(this, buildGeneratedValueHolder(), parent) {
+
+			@Override
+			protected void addPropertyNames(Collection<String> propertyNames) {
+				super.addPropertyNames(propertyNames);
+				propertyNames.add(GeneratedValue.DEFAULT_STRATEGY_PROPERTY);
+				propertyNames.add(GeneratedValue.SPECIFIED_STRATEGY_PROPERTY);
+			}
+
+			@Override
+			protected GenerationType[] getChoices() {
+				return GenerationType.values();
+			}
+
+			@Override
+			protected GenerationType getDefaultValue() {
+				return getSubject().getDefaultStrategy();
+			}
+
+			@Override
+			protected String displayString(GenerationType value) {
+				return buildDisplayString(
+					JptUiDetailsMessages.class,
+					GeneratedValueComposite.this,
+					value
+				);
+			}
+
+			@Override
+			protected GenerationType getValue() {
+				return getSubject().getSpecifiedStrategy();
+			}
+
+			@Override
+			protected void setValue(GenerationType value) {
+				retrieveGeneratedValue().setSpecifiedStrategy(value);
+			}
+		};
+	}
+
+	private PropertyValueModel<GeneratedValue> buildGeneratedValueHolder() {
+		return new PropertyAspectAdapter<IdMapping, GeneratedValue>(getSubjectHolder(), IdMapping.GENERATED_VALUE_PROPERTY) {
+			@Override
+			protected GeneratedValue buildValue_() {
+				return getSubject().getGeneratedValue();
+			}
+		};
+	}
+	
+	protected final WritablePropertyValueModel<String> buildGeneratorNameHolder() {
+		return new PropertyAspectAdapter<GeneratedValue, String>(buildGeneratedValueHolder(), GeneratedValue.SPECIFIED_GENERATOR_PROPERTY) {
+			@Override
+			protected String buildValue_() {
+				return this.subject.getSpecifiedGenerator();
+			}
+
+			@Override
+			public void setValue(String value) {
+				if (this.subject != null) {
+					setValue_(value);
+					return;
+				}
+				if (value.length() == 0) {
+					return;
+				}
+				retrieveGeneratedValue().setSpecifiedGenerator(value);
+			}
+
+			@Override
+			protected void setValue_(String value) {
+				if (value.length() == 0) {
+					value = null;
+				}
+				this.subject.setSpecifiedGenerator(value);
+			}
+		};
+	}
+
+	/**
+	 * Use the CompositeListValueModel even though it only contains 1 list value model
+	 * This prevents the combo items from being reset when the list of generators
+	 * hasn't really changed.  This keeps the cursor from going back to the beginning
+	 * of the list every time the generator name is edited in the combo.
+	 * AbstractComboModelAdapter.listChanged() does not handle this case well, 
+	 * the CompositeListValueModel does handle listChanged events well.
+	 */
+	protected ListValueModel<String> buildGeneratorNameListHolder() {
+		java.util.List<ListValueModel<String>> list = new ArrayList<ListValueModel<String>>();
+		list.add(new ListAspectAdapter<PersistenceUnit, String>(
+			buildPersistenceUnitHolder(),
+			PersistenceUnit.GENERATORS_LIST)
+		{
+			@Override
+			protected ListIterator<String> listIterator_() {
+				return CollectionTools.listIterator(ArrayTools.sort(this.subject.uniqueGeneratorNames()));
+			}
+		});
+		return new CompositeListValueModel<ListValueModel<String>, String>(list);
+	}
+
+	protected PropertyValueModel<PersistenceUnit> buildPersistenceUnitHolder() {
+		return new PropertyAspectAdapter<IdMapping, PersistenceUnit>(getSubjectHolder()) {
+			@Override
+			protected PersistenceUnit buildValue_() {
+				return getSubject().getPersistenceUnit();
+			}
+		};
+	}
+
+	private GeneratedValue retrieveGeneratedValue() {
+		GeneratedValue generatedValue = getSubject().getGeneratedValue();
+
+		if (generatedValue == null) {
+			generatedValue = getSubject().addGeneratedValue();
+		}
+		return generatedValue;
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/GenerationComposite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/GenerationComposite.java
new file mode 100644
index 0000000..8e71439
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/GenerationComposite.java
@@ -0,0 +1,234 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2009 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.ui.internal.details;
+
+import org.eclipse.jpt.core.context.GeneratorContainer;
+import org.eclipse.jpt.core.context.SequenceGenerator;
+import org.eclipse.jpt.core.context.TableGenerator;
+import org.eclipse.jpt.ui.internal.JpaHelpContextIds;
+import org.eclipse.jpt.ui.internal.details.GeneratorComposite.GeneratorBuilder;
+import org.eclipse.jpt.ui.internal.widgets.Pane;
+import org.eclipse.jpt.utility.internal.model.value.PropertyAspectAdapter;
+import org.eclipse.jpt.utility.internal.model.value.SimplePropertyValueModel;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.jpt.utility.model.value.WritablePropertyValueModel;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * Here the layout of this pane:
+ * <pre>
+ * -----------------------------------------------------------------------------
+ * | v Table Generator                                                         |
+ * |                                                                           |
+ * |   x Table Generator                                                       |
+ * |   ----------------------------------------------------------------------- |
+ * |   |                                                                     | |
+ * |   | TableGeneratorComposite                                             | |
+ * |   |                                                                     | |
+ * |   ----------------------------------------------------------------------- |
+ * |                                                                           |
+ * | v Sequence Generator                                                      |
+ * |                                                                           |
+ * |   x Sequence Generator                                                    |
+ * |   ----------------------------------------------------------------------- |
+ * |   |                                                                     | |
+ * |   | SequenceGeneratorComposite                                          | |
+ * |   |                                                                     | |
+ * |   ----------------------------------------------------------------------- |
+ * -----------------------------------------------------------------------------</pre>
+ *
+ * @see GeneratorContainer
+ * @see TableGeneratorComposite
+ * @see SequenceGeneratorComposite
+ * @see AbstractEntityComposite - The parent container
+ *
+ * @version 2.2
+ * @since 2.0
+ */
+public class GenerationComposite extends Pane<GeneratorContainer>
+{
+
+	//These are built to stand alone because we do not want the panels to collapse just
+	//because the generator is removed either in the source or using the check box in the UI.  
+	//We don't want these to be built on the model generator properties.
+	private WritablePropertyValueModel<Boolean> sequenceGeneratorExpansionStateHolder;
+	private WritablePropertyValueModel<Boolean> tableGeneratorExpansionStateHolder;
+
+	
+	public GenerationComposite(
+		Pane<?> parentPane, 
+		PropertyValueModel<? extends GeneratorContainer> subjectHolder,
+		Composite parent) {
+
+			super(parentPane, subjectHolder, parent, false);
+	}
+
+	@Override
+	protected void initialize() {
+		super.initialize();
+		this.sequenceGeneratorExpansionStateHolder = new SimplePropertyValueModel<Boolean>(Boolean.FALSE);
+		this.tableGeneratorExpansionStateHolder    = new SimplePropertyValueModel<Boolean>(Boolean.FALSE);
+	}
+
+	@Override
+	protected void doPopulate() {
+		super.doPopulate();
+		this.sequenceGeneratorExpansionStateHolder.setValue(Boolean.valueOf(getSubject() != null && getSubject().getSequenceGenerator() != null));
+		this.tableGeneratorExpansionStateHolder   .setValue(Boolean.valueOf(getSubject() != null && getSubject().getTableGenerator() != null));
+	}
+
+	@Override
+	protected void initializeLayout(Composite container) {
+
+		this.initializeTableGeneratorPane(container);
+		this.initializeSequenceGeneratorPane(container);
+	}
+
+	private void initializeSequenceGeneratorPane(Composite container) {
+
+		// Sequence Generator sub-section
+		container = this.addCollapsibleSubSection(
+			this.addSubPane(container, 10),
+			JptUiDetailsMessages.GeneratorsComposite_sequenceGeneratorSection,
+			this.sequenceGeneratorExpansionStateHolder
+		);
+
+		// Sequence Generator check box
+		Button sequenceGeneratorCheckBox = addCheckBox(
+			this.addSubPane(container, 5),
+			JptUiDetailsMessages.GeneratorsComposite_sequenceGeneratorCheckBox,
+			this.buildSequenceGeneratorBooleanHolder(),
+			JpaHelpContextIds.MAPPING_SEQUENCE_GENERATOR
+		);
+
+		// Sequence Generator pane
+		this.addSequenceGeneratorComposite(container, 0, sequenceGeneratorCheckBox.getBorderWidth() + 16);
+	}
+	
+	protected void addSequenceGeneratorComposite(Composite container, int topMargin, int leftMargin) {
+		new SequenceGeneratorComposite(
+			this,
+			this.buildSequenceGeneratorHolder(),
+			this.addSubPane(container, topMargin, leftMargin),
+			this.buildSequenceGeneratorBuilder()
+		);
+	}
+
+	protected PropertyValueModel<SequenceGenerator> buildSequenceGeneratorHolder() {
+		return new PropertyAspectAdapter<GeneratorContainer, SequenceGenerator>(getSubjectHolder(), GeneratorContainer.SEQUENCE_GENERATOR_PROPERTY) {
+			@Override
+			protected SequenceGenerator buildValue_() {
+				return this.subject.getSequenceGenerator();
+			}
+		};
+	}
+
+	protected GeneratorBuilder<SequenceGenerator> buildSequenceGeneratorBuilder() {
+		return new GeneratorBuilder<SequenceGenerator>() {
+			public SequenceGenerator addGenerator() {
+				return getSubject().addSequenceGenerator();
+			}
+		};
+	}
+	
+	private WritablePropertyValueModel<Boolean> buildSequenceGeneratorBooleanHolder() {
+		return new PropertyAspectAdapter<GeneratorContainer, Boolean>(getSubjectHolder(), GeneratorContainer.SEQUENCE_GENERATOR_PROPERTY) {
+			@Override
+			protected Boolean buildValue_() {
+				return Boolean.valueOf(this.subject.getSequenceGenerator() != null);
+			}
+
+			@Override
+			protected void setValue_(Boolean value) {
+
+				if (value.booleanValue() && (this.subject.getSequenceGenerator() == null)) {
+					this.subject.addSequenceGenerator();
+				}
+				else if (!value.booleanValue() && (this.subject.getSequenceGenerator() != null)) {
+					this.subject.removeSequenceGenerator();
+				}
+			}
+		};
+	}
+
+ 	private void initializeTableGeneratorPane(Composite container) {
+
+		// Table Generator sub-section
+		container = addCollapsibleSubSection(
+			container,
+			JptUiDetailsMessages.GeneratorsComposite_tableGeneratorSection,
+			this.tableGeneratorExpansionStateHolder
+		);
+
+		Button tableGeneratorCheckBox = addCheckBox(
+			this.addSubPane(container, 5),
+			JptUiDetailsMessages.GeneratorsComposite_tableGeneratorCheckBox,
+			this.buildTableGeneratorBooleanHolder(),
+			JpaHelpContextIds.MAPPING_TABLE_GENERATOR
+		);
+
+
+		// Table Generator pane
+		new TableGeneratorComposite(
+			this,
+			this.buildTableGeneratorHolder(),
+			this.addSubPane(container, 0, tableGeneratorCheckBox.getBorderWidth() + 16),
+			this.buildTableGeneratorBuilder()
+		);
+	}
+
+	private PropertyValueModel<TableGenerator> buildTableGeneratorHolder() {
+		return new PropertyAspectAdapter<GeneratorContainer, TableGenerator>(getSubjectHolder(), GeneratorContainer.TABLE_GENERATOR_PROPERTY) {
+			@Override
+			protected TableGenerator buildValue_() {
+				return this.subject.getTableGenerator();
+			}
+		};
+	}
+
+	private GeneratorBuilder<TableGenerator> buildTableGeneratorBuilder() {
+		return new GeneratorBuilder<TableGenerator>() {
+			public TableGenerator addGenerator() {
+				return getSubject().addTableGenerator();
+			}
+		};
+	}
+
+	protected PropertyValueModel<Boolean> buildTableGeneratorExpanstionStateHolder() {
+		return new PropertyAspectAdapter<GeneratorContainer, Boolean>(getSubjectHolder(), GeneratorContainer.TABLE_GENERATOR_PROPERTY) {
+			@Override
+			protected Boolean buildValue_() {
+				return Boolean.valueOf(this.subject.getTableGenerator() != null);
+			}		
+		};
+	}
+
+	private WritablePropertyValueModel<Boolean> buildTableGeneratorBooleanHolder() {
+		return new PropertyAspectAdapter<GeneratorContainer, Boolean>(getSubjectHolder(), GeneratorContainer.TABLE_GENERATOR_PROPERTY) {
+			@Override
+			protected Boolean buildValue_() {
+				return Boolean.valueOf(this.subject.getTableGenerator() != null);
+			}
+
+			@Override
+			protected void setValue_(Boolean value) {
+
+				if (value.booleanValue() && (this.subject.getTableGenerator() == null)) {
+					this.subject.addTableGenerator();
+				}
+				else if (!value.booleanValue() && (this.subject.getTableGenerator() != null)) {
+					this.subject.removeTableGenerator();
+				}
+			}
+		};
+	}
+
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/GeneratorComposite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/GeneratorComposite.java
new file mode 100644
index 0000000..6571f2b
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/GeneratorComposite.java
@@ -0,0 +1,206 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2009 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.ui.internal.details;
+
+import org.eclipse.jpt.core.JpaProject;
+import org.eclipse.jpt.core.context.Generator;
+import org.eclipse.jpt.core.context.IdMapping;
+import org.eclipse.jpt.ui.internal.widgets.IntegerCombo;
+import org.eclipse.jpt.ui.internal.widgets.Pane;
+import org.eclipse.jpt.utility.internal.model.value.PropertyAspectAdapter;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.jpt.utility.model.value.WritablePropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * This is the generic pane for a generator.
+ *
+ * @see IdMapping
+ * @see Generator
+ * @see SequenceGeneratorComposite - A sub-pane
+ * @see TalbeGeneratorComposite - A sub-pane
+ *
+ * @version 2.2
+ * @since 1.0
+ */
+public abstract class GeneratorComposite<T extends Generator> extends Pane<T>
+{
+
+	protected GeneratorBuilder<T> generatorBuilder;
+
+	protected GeneratorComposite(Pane<?> parentPane,
+        PropertyValueModel<T> subjectHolder,
+        Composite parent,
+        GeneratorBuilder<T> generatorBuilder) {
+
+		super(parentPane, subjectHolder, parent, false);
+		this.generatorBuilder = generatorBuilder;
+	}
+
+	/**
+	 * Creates a new Generator.  This makes it possible for the user
+	 * to set values on a Generator before the model object has been created.
+	 * Allows them not to first have to check the check box to enable the panel.
+	 */
+	protected final T buildGenerator() {
+		return this.generatorBuilder.addGenerator();
+	}
+
+	/**
+	 * Retrieves the <code>Generator</code> and if it is <code>null</code>, then
+	 * create it.
+	 *
+	 * @param subject The subject used to retrieve the generator
+	 * @return The <code>Generator</code> which should never be <code>null</code>
+	 */
+	protected final T retrieveGenerator() {
+		T generator = getSubject();
+
+		if (generator == null) {
+			generator = this.buildGenerator();
+		}
+
+		return generator;
+	}
+
+	protected final WritablePropertyValueModel<String> buildGeneratorNameHolder() {
+		return new PropertyAspectAdapter<Generator, String>(getSubjectHolder(), Generator.NAME_PROPERTY) {
+			@Override
+			protected String buildValue_() {
+				return this.subject.getName();
+			}
+
+			@Override
+			public void setValue(String value) {
+				if (this.subject != null) {
+					setValue_(value);
+					return;
+				}
+				if (value.length() == 0) {
+					return;
+				}
+				retrieveGenerator().setName(value);
+			}
+
+			@Override
+			protected void setValue_(String value) {
+				if (value.length() == 0) {
+					value = null;
+				}
+				this.subject.setName(value);
+			}
+		};
+	}
+
+	protected void addAllocationSizeCombo(Composite container) {
+		new IntegerCombo<Generator>(this, getSubjectHolder(), container) {
+			
+			@Override
+			protected String getLabelText() {
+				return JptUiDetailsMessages.GeneratorComposite_allocationSize;
+			}
+		
+			@Override
+			protected String getHelpId() {
+				return null;//JpaHelpContextIds.MAPPING_COLUMN_LENGTH;
+			}
+
+			@Override
+			protected PropertyValueModel<Integer> buildDefaultHolder() {
+				return new PropertyAspectAdapter<Generator, Integer>(getSubjectHolder(), Generator.DEFAULT_ALLOCATION_SIZE_PROPERTY) {
+					@Override
+					protected Integer buildValue_() {
+						return Integer.valueOf(this.subject.getDefaultAllocationSize());
+					}
+				};
+			}
+			
+			@Override
+			protected WritablePropertyValueModel<Integer> buildSelectedItemHolder() {
+				return new PropertyAspectAdapter<Generator, Integer>(getSubjectHolder(), Generator.SPECIFIED_ALLOCATION_SIZE_PROPERTY) {
+					@Override
+					protected Integer buildValue_() {
+						return this.subject.getSpecifiedAllocationSize();
+					}
+
+					@Override
+					public void setValue(Integer value) {
+						retrieveGenerator().setSpecifiedAllocationSize(value);
+					}
+				};
+			}
+		};	
+	}
+	
+	protected void addInitialValueCombo(Composite container) {
+		new IntegerCombo<Generator>(this, getSubjectHolder(), container) {
+			
+			@Override
+			protected String getLabelText() {
+				return JptUiDetailsMessages.GeneratorComposite_initialValue;
+			}
+		
+			@Override
+			protected String getHelpId() {
+				return null;//JpaHelpContextIds.MAPPING_COLUMN_LENGTH;
+			}
+
+			@Override
+			protected PropertyValueModel<Integer> buildDefaultHolder() {
+				return new PropertyAspectAdapter<Generator, Integer>(getSubjectHolder(), Generator.DEFAULT_INITIAL_VALUE_PROPERTY) {
+					@Override
+					protected Integer buildValue_() {
+						return Integer.valueOf(this.subject.getDefaultInitialValue());
+					}
+				};
+			}
+			
+			@Override
+			protected WritablePropertyValueModel<Integer> buildSelectedItemHolder() {
+				return new PropertyAspectAdapter<Generator, Integer>(getSubjectHolder(), Generator.SPECIFIED_INITIAL_VALUE_PROPERTY) {
+					@Override
+					protected Integer buildValue_() {
+						return this.subject.getSpecifiedInitialValue();
+					}
+
+					@Override
+					public void setValue(Integer value) {
+						retrieveGenerator().setSpecifiedInitialValue(value);
+					}
+				};
+			}
+		};	
+	}
+
+	/**
+	 * Retrieves the JPA project.
+	 *
+	 * @return The JPA project or <code>null</code> if the subject is <code>null</code>
+	 */
+	protected final JpaProject getJpaProject() {
+		return this.getSubject() == null ? null : this.getSubject().getJpaProject();
+	}
+
+	/**
+	 * Returns the property name used to listen to the ID mapping when the
+	 * generator changes.
+	 *
+	 * @return The property name associated with the generator
+	 */
+	protected abstract String getPropertyName();
+
+
+	public interface GeneratorBuilder<T> {
+		/**
+		 * Add a generator to the model and return it
+		 */
+		T addGenerator();
+	}
+}
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/IdClassComposite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/IdClassComposite.java
new file mode 100644
index 0000000..f68b254
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/IdClassComposite.java
@@ -0,0 +1,138 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2010 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.ui.internal.details;
+
+import org.eclipse.jpt.core.JpaProject;
+import org.eclipse.jpt.core.context.IdClassReference;
+import org.eclipse.jpt.ui.internal.widgets.ClassChooserComboPane;
+import org.eclipse.jpt.ui.internal.widgets.Pane;
+import org.eclipse.jpt.utility.internal.model.value.PropertyAspectAdapter;
+import org.eclipse.jpt.utility.internal.model.value.PropertyListValueModelAdapter;
+import org.eclipse.jpt.utility.model.value.ListValueModel;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.jpt.utility.model.value.WritablePropertyValueModel;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * Id class hyperlink label, combo, and browse button
+ *
+ */
+public class IdClassComposite
+	extends Pane<IdClassReference>
+{
+	/**
+	 * Creates a new <code>IdClassComposite</code>.
+	 *
+	 * @param parentPane The parent pane of this one
+	 * @param parent The parent container
+	 */
+	public IdClassComposite(
+			Pane<?> parentPane,
+			PropertyValueModel<? extends IdClassReference> subjectHolder,
+			Composite parent) {
+		
+		super(parentPane, subjectHolder, parent);
+	}
+	
+	public IdClassComposite(
+			Pane<?> parentPane,
+			PropertyValueModel<? extends IdClassReference> subjectHolder,
+			Composite parent,
+        	boolean automaticallyAlignWidgets) {
+		
+		super(parentPane, subjectHolder, parent, automaticallyAlignWidgets);
+	}
+	
+	
+	@Override
+	protected void initializeLayout(Composite container) {
+		new IdClassChooserComboPane(this, container);
+	}
+	
+	
+	private class IdClassChooserComboPane
+		extends ClassChooserComboPane<IdClassReference>
+	{
+		public IdClassChooserComboPane(Pane<IdClassReference> parentPane, Composite parent) {
+			super(parentPane, parent);
+		}
+		
+		
+		@Override
+		protected String getClassName() {
+			return getSubject().getIdClassName();
+		}
+		
+		@Override
+		protected void setClassName(String className) {
+			getSubject().setSpecifiedIdClassName(className);
+		}
+		
+		@Override
+		protected String getLabelText() {
+			return JptUiDetailsMessages.IdClassComposite_label;
+		}
+		
+		@Override
+		protected JpaProject getJpaProject() {
+			return getSubject().getJpaProject();
+		}
+		
+		@Override
+		protected char getEnclosingTypeSeparator() {
+			return getSubject().getIdClassEnclosingTypeSeparator();
+		}
+		
+		@Override
+		protected WritablePropertyValueModel<String> buildTextHolder() {
+			return new PropertyAspectAdapter<IdClassReference, String>(
+					getSubjectHolder(), 
+					IdClassReference.SPECIFIED_ID_CLASS_NAME_PROPERTY,
+					IdClassReference.DEFAULT_ID_CLASS_NAME_PROPERTY) {
+				
+				@Override
+				protected String buildValue_() {
+					String value = this.subject.getSpecifiedIdClassName();
+					return (value == null) ? defaultText(this.subject) : value;
+				}
+				
+				@Override
+				protected void setValue_(String value) {
+					if (value == null 
+							|| value.length() == 0 
+							|| value.equals(defaultText(this.subject))) {
+						value = null;
+					}
+					this.subject.setSpecifiedIdClassName(value);
+				}
+			};
+		}
+		
+		protected String defaultText(IdClassReference idClassReference) {
+			String defaultClassName = idClassReference.getDefaultIdClassName();
+			return (defaultClassName == null) ?
+					JptUiDetailsMessages.NoneSelected
+					: NLS.bind(JptUiDetailsMessages.DefaultWithOneParam, defaultClassName);
+		}
+		
+		@Override
+		protected ListValueModel<String> buildClassListHolder() {
+			return new PropertyListValueModelAdapter<String>(
+				new PropertyAspectAdapter<IdClassReference, String>(
+						getSubjectHolder(), IdClassReference.DEFAULT_ID_CLASS_NAME_PROPERTY) {
+					@Override
+					protected String buildValue_() {
+						return defaultText(this.subject);
+					}
+				});
+		}
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/IdMappingComposite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/IdMappingComposite.java
new file mode 100644
index 0000000..f160d9b
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/IdMappingComposite.java
@@ -0,0 +1,33 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2010 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.ui.internal.details;
+
+import org.eclipse.jpt.core.context.IdMapping;
+import org.eclipse.jpt.ui.WidgetFactory;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+public class IdMappingComposite
+	extends AbstractIdMappingComposite<IdMapping>
+{
+	public IdMappingComposite(
+			PropertyValueModel<? extends IdMapping> subjectHolder,
+	        Composite parent,
+	        WidgetFactory widgetFactory) {
+		
+		super(subjectHolder, parent, widgetFactory);
+	}
+	
+	
+	@Override
+	protected void initializeIdSection(Composite container) {
+		new ColumnComposite(this, buildColumnHolder(), container);
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/IdMappingGenerationComposite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/IdMappingGenerationComposite.java
new file mode 100644
index 0000000..205675e
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/IdMappingGenerationComposite.java
@@ -0,0 +1,348 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2010 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.ui.internal.details;
+
+import org.eclipse.jpt.core.context.GeneratedValue;
+import org.eclipse.jpt.core.context.GeneratorContainer;
+import org.eclipse.jpt.core.context.IdMapping;
+import org.eclipse.jpt.core.context.SequenceGenerator;
+import org.eclipse.jpt.core.context.TableGenerator;
+import org.eclipse.jpt.ui.internal.JpaHelpContextIds;
+import org.eclipse.jpt.ui.internal.details.GeneratorComposite.GeneratorBuilder;
+import org.eclipse.jpt.ui.internal.widgets.Pane;
+import org.eclipse.jpt.utility.internal.model.value.PropertyAspectAdapter;
+import org.eclipse.jpt.utility.internal.model.value.SimplePropertyValueModel;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.jpt.utility.model.value.WritablePropertyValueModel;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * This panel is partially a copy of the GenerationComposite panel. The difference
+ * is that this panel includes the Generated Value composite.  When a table
+ * or sequence generator is added, we set the "name" to be the same as the 
+ * generated value "generator" if it already exists
+ * 
+ * Here is the layout of this pane:
+ * <pre>
+ * -----------------------------------------------------------------------------
+ * | v Primary Key Generation                                                  |
+ * |                                                                           |
+ * |   x Primary Key Generation                                                |
+ * |     --------------------------------------------------------------------- |
+ * |     |                                                                   | |
+ * |     | GeneratedValueComposite                                           | |
+ * |     |                                                                   | |
+ * |     --------------------------------------------------------------------- |
+ * |                                                                           |
+ * |   v Table Generator                                                       |
+ * |                                                                           |
+ * |     x Table Generator                                                     |
+ * |     --------------------------------------------------------------------- |
+ * |     |                                                                   | |
+ * |     | TableGeneratorComposite                                           | |
+ * |     |                                                                   | |
+ * |     --------------------------------------------------------------------- |
+ * |                                                                           |
+ * |   v Sequence Generator                                                    |
+ * |                                                                           |
+ * |     x Sequence Generator                                                  |
+ * |     --------------------------------------------------------------------- |
+ * |     |                                                                   | |
+ * |     | SequenceGeneratorComposite                                        | |
+ * |     |                                                                   | |
+ * |     --------------------------------------------------------------------- |
+ * -----------------------------------------------------------------------------</pre>
+ *
+ * @see IdMapping
+ * @see GeneratedValueComposite
+ * @see TableGeneratorComposite
+ * @see SequenceGeneratorComposite
+ * @see IdMappingComposite - The parent container
+ *
+ * @version 2.2
+ * @since 1.0
+ */
+public class IdMappingGenerationComposite extends Pane<IdMapping>
+{
+
+	//These are built to stand alone because we do not want the panels to collapse just
+	//because the generator is removed either in the source or using the check box in the UI.  
+	//We don't want these to be built on the model generator properties.
+	private WritablePropertyValueModel<Boolean> sequenceGeneratorExpansionStateHolder;
+	private WritablePropertyValueModel<Boolean> tableGeneratorExpansionStateHolder;
+
+
+	/**
+	 * Creates a new <code>GenerationComposite</code>.
+	 *
+	 * @param parentPane The parent container of this one
+	 * @param parent The parent container
+	 */
+	public IdMappingGenerationComposite(Pane<? extends IdMapping> parentPane,
+	                           Composite parent)
+	{
+		super(parentPane, parent, false);
+	}
+	
+	@Override
+	protected void initialize() {
+		super.initialize();
+		this.sequenceGeneratorExpansionStateHolder = new SimplePropertyValueModel<Boolean>(Boolean.FALSE);
+		this.tableGeneratorExpansionStateHolder    = new SimplePropertyValueModel<Boolean>(Boolean.FALSE);
+	}
+
+	@Override
+	protected void doPopulate() {
+		super.doPopulate();
+		this.sequenceGeneratorExpansionStateHolder.setValue(Boolean.valueOf(getSubject() != null && getSubject().getGeneratorContainer().getSequenceGenerator() != null));
+		this.tableGeneratorExpansionStateHolder   .setValue(Boolean.valueOf(getSubject() != null && getSubject().getGeneratorContainer().getTableGenerator() != null));
+	}
+
+	@Override
+	protected void initializeLayout(Composite container) {
+
+		// Primary Key Generation section
+		container = addCollapsibleSection(
+			container,
+			JptUiDetailsMessages.IdMappingComposite_primaryKeyGenerationSection,
+			new SimplePropertyValueModel<Boolean>(Boolean.TRUE)
+		);
+
+		// Primary Key Generation check box
+		Button primaryKeyGenerationCheckBox = addCheckBox(
+			container,
+			JptUiDetailsMessages.IdMappingComposite_primaryKeyGenerationCheckBox,
+			buildPrimaryKeyGenerationHolder(),
+			JpaHelpContextIds.MAPPING_PRIMARY_KEY_GENERATION
+		);
+
+		// Generated Value widgets
+		GeneratedValueComposite generatedValueComposite = new GeneratedValueComposite(
+			this,
+			container
+		);
+
+		GridData gridData = new GridData();
+		gridData.horizontalAlignment       = GridData.FILL;
+		gridData.grabExcessHorizontalSpace = true;
+		gridData.horizontalIndent          = primaryKeyGenerationCheckBox.getBorderWidth() + 16;
+
+		generatedValueComposite.getControl().setLayoutData(gridData);
+
+		PropertyValueModel<GeneratorContainer> generatorHolder = buildGeneratorContainer();
+		// Table Generator pane
+		initializeTableGeneratorPane(addSubPane(container, 10), generatorHolder);
+
+		// Sequence Generator pane
+		initializeSequenceGeneratorPane(addSubPane(container, 10), generatorHolder);
+	}
+
+	private WritablePropertyValueModel<Boolean> buildPrimaryKeyGenerationHolder() {
+		return new PropertyAspectAdapter<IdMapping, Boolean>(getSubjectHolder(), IdMapping.GENERATED_VALUE_PROPERTY) {
+			@Override
+			protected Boolean buildValue_() {
+				return Boolean.valueOf(this.subject.getGeneratedValue() != null);
+			}
+
+			@Override
+			protected void setValue_(Boolean value) {
+
+				if (value.booleanValue() && (this.subject.getGeneratedValue() == null)) {
+					this.subject.addGeneratedValue();
+				}
+				else if (!value.booleanValue() && (this.subject.getGeneratedValue() != null)) {
+					this.subject.removeGeneratedValue();
+				}
+			}
+		};
+	}
+	
+	private PropertyValueModel<GeneratorContainer> buildGeneratorContainer() {
+		return new PropertyAspectAdapter<IdMapping, GeneratorContainer>(getSubjectHolder()) {
+			@Override
+			protected GeneratorContainer buildValue_() {
+				return this.subject.getGeneratorContainer();
+			}
+		};
+	}
+
+	private void initializeSequenceGeneratorPane(Composite container, PropertyValueModel<GeneratorContainer> generatorHolder) {
+
+		// Sequence Generator sub-section
+		container = addCollapsibleSubSection(
+			container,
+			JptUiDetailsMessages.IdMappingComposite_sequenceGeneratorSection,
+			this.sequenceGeneratorExpansionStateHolder
+		);
+
+		// Sequence Generator check box
+		Button sequenceGeneratorCheckBox = addCheckBox(
+			container,
+			JptUiDetailsMessages.IdMappingComposite_sequenceGeneratorCheckBox,
+			buildSequenceGeneratorBooleanHolder(generatorHolder),
+			JpaHelpContextIds.MAPPING_SEQUENCE_GENERATOR
+		);
+
+		// Sequence Generator pane
+		this.buildSequenceGeneratorComposite(
+			container, 
+			buildSequenceGeneratorHolder(generatorHolder),
+			buildSequenceGeneratorBuilder(generatorHolder),
+			0, 
+			sequenceGeneratorCheckBox.getBorderWidth() + 16);
+	}
+
+	private WritablePropertyValueModel<Boolean> buildSequenceGeneratorBooleanHolder(PropertyValueModel<GeneratorContainer> generatorHolder) {
+		return new PropertyAspectAdapter<GeneratorContainer, Boolean>(generatorHolder, GeneratorContainer.SEQUENCE_GENERATOR_PROPERTY) {
+			@Override
+			protected Boolean buildValue_() {
+				return Boolean.valueOf(this.subject.getSequenceGenerator() != null);
+			}
+
+			@Override
+			protected void setValue_(Boolean value) {
+
+				if (value.booleanValue() && (this.subject.getSequenceGenerator() == null)) {
+
+					SequenceGenerator sequenceGenerator = this.subject.addSequenceGenerator();
+					GeneratedValue generatedValue = getSubject().getGeneratedValue();
+
+					if ((generatedValue != null) &&
+					    (generatedValue.getGenerator() != null))
+					{
+						sequenceGenerator.setName(generatedValue.getGenerator());
+					}
+				}
+				else if (!value.booleanValue() && (this.subject.getSequenceGenerator() != null)) {
+					this.subject.removeSequenceGenerator();
+				}
+			}
+		};
+	}
+	
+	protected SequenceGeneratorComposite buildSequenceGeneratorComposite(
+			Composite container, 
+			PropertyValueModel<SequenceGenerator> sequenceGeneratorHolder,
+			GeneratorBuilder<SequenceGenerator> generatorBuilder,
+			int topMargin,
+			int leftMargin) {
+
+		return new SequenceGeneratorComposite(
+			this,
+			sequenceGeneratorHolder,
+			this.addSubPane(container, topMargin, leftMargin),
+			generatorBuilder
+		);
+	}
+
+	private PropertyValueModel<SequenceGenerator> buildSequenceGeneratorHolder(PropertyValueModel<GeneratorContainer> generatorHolder) {
+		return new PropertyAspectAdapter<GeneratorContainer, SequenceGenerator>(generatorHolder, GeneratorContainer.SEQUENCE_GENERATOR_PROPERTY) {
+			@Override
+			protected SequenceGenerator buildValue_() {
+				return this.subject.getSequenceGenerator();
+			}
+		};
+	}
+	private GeneratorBuilder<SequenceGenerator> buildSequenceGeneratorBuilder(final PropertyValueModel<GeneratorContainer> generatorHolder) {
+		return new GeneratorBuilder<SequenceGenerator>() {
+			public SequenceGenerator addGenerator() {
+				return generatorHolder.getValue().addSequenceGenerator();
+			}
+		};
+	}
+	
+	private void initializeTableGeneratorPane(Composite container, PropertyValueModel<GeneratorContainer> generatorHolder) {
+
+		// Table Generator sub-section
+		container = addCollapsibleSubSection(
+			container,
+			JptUiDetailsMessages.IdMappingComposite_tableGeneratorSection,
+			this.tableGeneratorExpansionStateHolder
+		);
+
+		Button tableGeneratorCheckBox = addCheckBox(
+			container,
+			JptUiDetailsMessages.IdMappingComposite_tableGeneratorCheckBox,
+			buildTableGeneratorBooleanHolder(generatorHolder),
+			JpaHelpContextIds.MAPPING_TABLE_GENERATOR
+		);
+
+		// Sequence Generator pane
+		this.buildTableGeneratorComposite(
+			container, 
+			buildTableGeneratorHolder(generatorHolder),
+			buildTableGeneratorBuilder(generatorHolder),
+			0, 
+			tableGeneratorCheckBox.getBorderWidth() + 16);
+	}	
+	
+	protected TableGeneratorComposite buildTableGeneratorComposite(
+			Composite container, 
+			PropertyValueModel<TableGenerator> tableGeneratorHolder,
+			GeneratorBuilder<TableGenerator> generatorBuilder,
+			int topMargin,
+			int leftMargin) {
+
+		return new TableGeneratorComposite(
+			this,
+			tableGeneratorHolder,
+			this.addSubPane(container, topMargin, leftMargin),
+			generatorBuilder
+		);
+	}
+
+	private PropertyValueModel<TableGenerator> buildTableGeneratorHolder(PropertyValueModel<GeneratorContainer> generatorHolder) {
+		return new PropertyAspectAdapter<GeneratorContainer, TableGenerator>(generatorHolder, GeneratorContainer.TABLE_GENERATOR_PROPERTY) {
+			@Override
+			protected TableGenerator buildValue_() {
+				return this.subject.getTableGenerator();
+			}
+		};
+	}
+
+	private GeneratorBuilder<TableGenerator> buildTableGeneratorBuilder(final PropertyValueModel<GeneratorContainer> generatorHolder) {
+		return new GeneratorBuilder<TableGenerator>() {
+			public TableGenerator addGenerator() {
+				return generatorHolder.getValue().addTableGenerator();
+			}
+		};
+	}
+
+ 	private WritablePropertyValueModel<Boolean> buildTableGeneratorBooleanHolder(PropertyValueModel<GeneratorContainer> generatorHolder) {
+		return new PropertyAspectAdapter<GeneratorContainer, Boolean>(generatorHolder, GeneratorContainer.TABLE_GENERATOR_PROPERTY) {
+			@Override
+			protected Boolean buildValue_() {
+				return Boolean.valueOf(this.subject.getTableGenerator() != null);
+			}
+
+			@Override
+			protected void setValue_(Boolean value) {
+
+				if (value.booleanValue() && (this.subject.getTableGenerator() == null)) {
+
+					TableGenerator tableGenerator = this.subject.addTableGenerator();
+					GeneratedValue generatedValue = getSubject().getGeneratedValue();
+
+					if ((generatedValue != null) &&
+					    (generatedValue.getGenerator() != null))
+					{
+						tableGenerator.setName(generatedValue.getGenerator());
+					}
+				}
+				else if (!value.booleanValue() && (this.subject.getTableGenerator() != null)) {
+					this.subject.removeTableGenerator();
+				}
+			}
+		};
+	}
+
+}
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/InverseJoinColumnInJoinTableDialog.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/InverseJoinColumnInJoinTableDialog.java
new file mode 100644
index 0000000..e81ebc3
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/InverseJoinColumnInJoinTableDialog.java
@@ -0,0 +1,88 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2009 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.ui.internal.details;
+
+import org.eclipse.jpt.core.context.JoinColumn;
+import org.eclipse.jpt.core.context.JoinTable;
+import org.eclipse.jpt.ui.internal.widgets.DialogPane;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Shell;
+
+/**
+ *
+ * @see InverseJoinColumnInJoinTableStateObject
+ * @see BaseJoinColumnDialogPane
+ *
+ * @version 2.0
+ * @since 2.0
+ */
+public class InverseJoinColumnInJoinTableDialog extends BaseJoinColumnDialog<InverseJoinColumnInJoinTableStateObject> {
+
+	/**
+	 * Creates a new <code>JoinColumnInJoinTableDialog</code>.
+	 *
+	 * @param parent The parent shell
+	 * @param joinTable The owner of the join column to create or where it is
+	 * located
+	 * @param joinColumn Either the join column to edit or <code>null</code> if
+	 * this state object is used to create a new one
+	 */
+	public InverseJoinColumnInJoinTableDialog(Shell parent,
+	                                          JoinTable joinTable,
+	                                          JoinColumn joinColumn) {
+
+		super(parent, joinTable, joinColumn);
+	}
+
+	/*
+	 * non-Javadoc)
+	 */
+	@Override
+	protected DialogPane<InverseJoinColumnInJoinTableStateObject> buildLayout(Composite container) {
+		return new JoinColumnDialogPane<InverseJoinColumnInJoinTableStateObject>(
+			getSubjectHolder(),
+			container
+		)
+		
+		{
+			@Override
+			protected boolean isTableEditable() {
+				return false;
+			}
+		};
+	}
+
+	/*
+	 * (non-Javadoc)
+	 */
+	@Override
+	protected InverseJoinColumnInJoinTableStateObject buildStateObject() {
+		return new InverseJoinColumnInJoinTableStateObject(
+			getOwner(),
+			getJoinColumn()
+		);
+	}
+
+	/*
+	 * (non-Javadoc)
+	 */
+	@Override
+	public JoinColumn getJoinColumn() {
+		return (JoinColumn) super.getJoinColumn();
+	}
+
+	/*
+	 * (non-Javadoc)
+	 */
+	@Override
+	protected JoinTable getOwner() {
+		return (JoinTable) super.getOwner();
+	}
+}
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/InverseJoinColumnInJoinTableStateObject.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/InverseJoinColumnInJoinTableStateObject.java
new file mode 100644
index 0000000..d45a497
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/InverseJoinColumnInJoinTableStateObject.java
@@ -0,0 +1,94 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2010 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.ui.internal.details;
+
+import java.util.ListIterator;
+import org.eclipse.jpt.core.context.Entity;
+import org.eclipse.jpt.core.context.JoinColumn;
+import org.eclipse.jpt.core.context.JoinTable;
+import org.eclipse.jpt.core.context.RelationshipMapping;
+import org.eclipse.jpt.db.Table;
+import org.eclipse.jpt.utility.internal.iterators.SingleElementListIterator;
+
+/**
+ * The state object used to create or edit a primary key join column on a join
+ * table.
+ *
+ * @see JoinColumn
+ * @see JoinTable
+ * @see InverseJoinColumnInJoinTableDialog
+ *
+ * @version 2.3
+ * @since 2.0
+ */
+public class InverseJoinColumnInJoinTableStateObject 
+	extends JoinColumnStateObject
+{
+	/**
+	 * Creates a new <code>JoinColumnInJoinTableStateObject</code>.
+	 *
+	 * @param joinTable
+	 * @param joinColumn Either the join column to edit or <code>null</code> if
+	 * this state object is used to create a new one
+	 */
+	public InverseJoinColumnInJoinTableStateObject(
+			JoinTable joinTable,
+	        JoinColumn joinColumn) {
+		super(joinTable, joinColumn);
+	}
+	
+	
+	@Override
+	public JoinTable getOwner() {
+		return (JoinTable) super.getOwner();
+	}
+	
+	private RelationshipMapping getRelationshipMapping() {
+		return getOwner().getRelationshipMapping();
+	}
+	
+	@Override
+	public String getDefaultTable() {
+		return null;
+	}
+	
+	@Override
+	public Table getNameTable() {
+		return getOwner().getDbTable();
+	}
+	
+	@Override
+	public Table getReferencedNameTable() {
+		RelationshipMapping relationshipMapping = getRelationshipMapping();
+		if (relationshipMapping == null) {
+			return null;
+		}
+		Entity targetEntity = relationshipMapping.getResolvedTargetEntity();
+		if (targetEntity == null) {
+			return null;
+		}
+		return targetEntity.getPrimaryDbTable();
+	}
+	
+	@Override
+	protected String getInitialTable() {
+		return getOwner().getName();
+	}
+	
+	@Override
+	protected boolean isTableEditable() {
+		return false;
+	}
+	
+	@Override
+	public ListIterator<String> tables() {
+		return new SingleElementListIterator<String>(getInitialTable());
+	}
+}
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/JoinColumnDialog.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/JoinColumnDialog.java
new file mode 100644
index 0000000..b2fdec4
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/JoinColumnDialog.java
@@ -0,0 +1,56 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2009 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.ui.internal.details;
+
+import org.eclipse.jpt.core.context.JoinColumn;
+import org.eclipse.jpt.ui.internal.widgets.DialogPane;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Shell;
+
+/**
+ * The abstract definition of the dialog used to edit an <code>IJoinColumn</code>.
+ *
+ * @see JoinColumn
+ * @see JoinColumnStateObject
+ * @see JoinColumnDialogPane
+ *
+ * @version 2.0
+ * @since 2.0
+ */
+public abstract class JoinColumnDialog<T extends JoinColumnStateObject> extends BaseJoinColumnDialog<T> {
+
+	/**
+	 * Creates a new <code>AbstractJoinColumnDialog</code>.
+	 *
+	 * @param parent The parent shell
+	 * @param owner The owner of the join column to create or where it is located
+	 * @param joinColumn Either the join column to edit or <code>null</code> if
+	 * this state object is used to create a new one
+	 */
+	public JoinColumnDialog(Shell parent, Object owner, JoinColumn joinColumn) {
+		super(parent, owner, joinColumn);
+	}
+
+	/*
+	 * (non-Javadoc)
+	 */
+	@Override
+	protected DialogPane<?> buildLayout(Composite container) {
+		return new JoinColumnDialogPane<T>(getSubjectHolder(), container);
+	}
+
+	/*
+	 * (non-Javadoc)
+	 */
+	@Override
+	public JoinColumn getJoinColumn() {
+		return (JoinColumn) super.getJoinColumn();
+	}
+}
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/JoinColumnDialogPane.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/JoinColumnDialogPane.java
new file mode 100644
index 0000000..116ad32
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/JoinColumnDialogPane.java
@@ -0,0 +1,285 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2009 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.ui.internal.details;
+
+import org.eclipse.jpt.ui.internal.JpaHelpContextIds;
+import org.eclipse.jpt.utility.internal.model.value.PropertyAspectAdapter;
+import org.eclipse.jpt.utility.internal.model.value.TransformationPropertyValueModel;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.jpt.utility.model.value.WritablePropertyValueModel;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * Here the layout of this pane:
+ * <pre>
+ * -----------------------------------------------------------------------------
+ * | ------------------------------------------------------------------------- |
+ * | |                                                                       | |
+ * | | BaseJoinColumnDialogPane                                              | |
+ * | |                                                                       | |
+ * | ------------------------------------------------------------------------- |
+ * |                                                                           |
+ * | x Insertable                                                              |
+ * |                                                                           |
+ * | x Nullable                                                                |
+ * |                                                                           |
+ * | x Unique                                                                  |
+ * |                                                                           |
+ * | x Updatable                                                               |
+ * |                                                                           |
+ * -----------------------------------------------------------------------------</pre>
+ *
+ * @see JoinColumnStateObject
+ * @see JoinColumnDialog - The parent container
+ *
+ * @version 2.0
+ * @since 1.0
+ */
+public class JoinColumnDialogPane<T extends JoinColumnStateObject> extends BaseJoinColumnDialogPane<T>
+{
+	/**
+	 * Creates a new <code>JoinColumnDialogPane</code>.
+	 *
+	 * @param subjectHolder The holder of this pane's subject
+	 * @param parent The parent container
+	 */
+	public JoinColumnDialogPane(PropertyValueModel<? extends T> subjectHolder,
+	                            Composite parent)
+	{
+		super(subjectHolder, parent);
+	}
+
+	private WritablePropertyValueModel<Boolean> buildInsertableHolder() {
+		return new PropertyAspectAdapter<T, Boolean>(getSubjectHolder(), JoinColumnStateObject.INSERTABLE_PROPERTY) {
+			@Override
+			protected Boolean buildValue_() {
+				return this.subject.getInsertable();
+			}
+
+			@Override
+			protected void setValue_(Boolean value) {
+				this.subject.setInsertable(value);
+			}
+		};
+	}
+
+	private PropertyValueModel<String> buildInsertableStringHolder() {
+		return new TransformationPropertyValueModel<Boolean, String>(buildDefaultInsertableHolder()) {
+			@Override
+			protected String transform(Boolean value) {
+				if (value != null) {
+					String defaultStringValue = value.booleanValue() ? JptUiDetailsMessages.Boolean_True : JptUiDetailsMessages.Boolean_False;
+					return NLS.bind(JptUiDetailsMessages.JoinColumnDialogPane_insertableWithDefault, defaultStringValue);
+				}
+				return JptUiDetailsMessages.JoinColumnDialogPane_insertable;
+			}
+		};
+	}
+
+	private PropertyValueModel<Boolean> buildDefaultInsertableHolder() {
+		return new PropertyAspectAdapter<T, Boolean>(
+			getSubjectHolder(),
+			JoinColumnStateObject.INSERTABLE_PROPERTY)
+		{
+			@Override
+			protected Boolean buildValue_() {
+				if (this.subject.getInsertable() != null) {
+					return null;
+				}
+				return Boolean.valueOf(this.subject.isDefaultInsertable());
+			}
+		};
+	}
+
+	private WritablePropertyValueModel<Boolean> buildNullableHolder() {
+		return new PropertyAspectAdapter<T, Boolean>(
+			getSubjectHolder(),
+			JoinColumnStateObject.NULLABLE_PROPERTY)
+		{
+			@Override
+			protected Boolean buildValue_() {
+				return this.subject.getNullable();
+			}
+
+			@Override
+			protected void setValue_(Boolean value) {
+				this.subject.setNullable(value);
+			}
+		};
+	}
+
+	private PropertyValueModel<String> buildNullableStringHolder() {
+
+		return new TransformationPropertyValueModel<Boolean, String>(buildDefaultNullableHolder()) {
+
+			@Override
+			protected String transform(Boolean value) {
+				if (value != null) {
+					String defaultStringValue = value.booleanValue() ? JptUiDetailsMessages.Boolean_True : JptUiDetailsMessages.Boolean_False;
+					return NLS.bind(JptUiDetailsMessages.JoinColumnDialogPane_nullableWithDefault, defaultStringValue);
+				}
+				return JptUiDetailsMessages.JoinColumnDialogPane_nullable;
+			}
+		};
+	}
+
+	private PropertyValueModel<Boolean> buildDefaultNullableHolder() {
+		return new PropertyAspectAdapter<T, Boolean>(
+			getSubjectHolder(),
+			JoinColumnStateObject.NULLABLE_PROPERTY)
+		{
+			@Override
+			protected Boolean buildValue_() {
+				if (this.subject.getNullable() != null) {
+					return null;
+				}
+				return Boolean.valueOf(this.subject.isDefaultNullable());
+			}
+		};
+	}
+
+	private WritablePropertyValueModel<Boolean> buildUniqueHolder() {
+		return new PropertyAspectAdapter<T, Boolean>(
+			getSubjectHolder(),
+			JoinColumnStateObject.UNIQUE_PROPERTY)
+		{
+			@Override
+			protected Boolean buildValue_() {
+				return this.subject.getUnique();
+			}
+
+			@Override
+			protected void setValue_(Boolean value) {
+				this.subject.setUnique(value);
+			}
+		};
+	}
+
+	private PropertyValueModel<String> buildUniqueStringHolder() {
+		return new TransformationPropertyValueModel<Boolean, String>(buildDefaultUniqueHolder()) {
+			@Override
+			protected String transform(Boolean value) {
+				if (value != null) {
+					String defaultStringValue = value.booleanValue() ? JptUiDetailsMessages.Boolean_True : JptUiDetailsMessages.Boolean_False;
+					return NLS.bind(JptUiDetailsMessages.JoinColumnDialogPane_uniqueWithDefault, defaultStringValue);
+				}
+				return JptUiDetailsMessages.JoinColumnDialogPane_unique;
+			}
+		};
+	}
+
+	private PropertyValueModel<Boolean> buildDefaultUniqueHolder() {
+		return new PropertyAspectAdapter<T, Boolean>(
+			getSubjectHolder(),
+			JoinColumnStateObject.UNIQUE_PROPERTY)
+		{
+			@Override
+			protected Boolean buildValue_() {
+				if (this.subject.getUnique() != null) {
+					return null;
+				}
+				return Boolean.valueOf(this.subject.isDefaultUnique());
+			}
+		};
+	}
+
+	private WritablePropertyValueModel<Boolean> buildUpdatableHolder() {
+		return new PropertyAspectAdapter<T, Boolean>(getSubjectHolder(), JoinColumnStateObject.UPDATABLE_PROPERTY) {
+			@Override
+			protected Boolean buildValue_() {
+				return this.subject.getUpdatable();
+			}
+
+			@Override
+			protected void setValue_(Boolean value) {
+				this.subject.setUpdatable(value);
+			}
+		};
+	}
+
+	private PropertyValueModel<String> buildUpdatableStringHolder() {
+		return new TransformationPropertyValueModel<Boolean, String>(buildDefaultUpdatableHolder()) {
+			@Override
+			protected String transform(Boolean value) {
+				if (value != null) {
+					String defaultStringValue = value.booleanValue() ? JptUiDetailsMessages.Boolean_True : JptUiDetailsMessages.Boolean_False;
+					return NLS.bind(JptUiDetailsMessages.JoinColumnDialogPane_updatableWithDefault, defaultStringValue);
+				}
+				return JptUiDetailsMessages.JoinColumnDialogPane_updatable;
+			}
+		};
+	}
+
+	private PropertyValueModel<Boolean> buildDefaultUpdatableHolder() {
+		return new PropertyAspectAdapter<T, Boolean>(
+			getSubjectHolder(),
+			JoinColumnStateObject.UPDATABLE_PROPERTY)
+		{
+			@Override
+			protected Boolean buildValue_() {
+				if (this.subject.getUpdatable() != null) {
+					return null;
+				}
+				return Boolean.valueOf(this.subject.isDefaultUpdatable());
+			}
+		};
+	}
+
+	@Override
+	protected void initializeLayout(Composite container) {
+
+		super.initializeLayout(container);
+
+		// Insertable tri-state check box
+		addTriStateCheckBoxWithDefault(
+			addSubPane(container, 4),
+			JptUiDetailsMessages.JoinColumnDialogPane_insertable,
+			buildInsertableHolder(),
+			buildInsertableStringHolder(),
+			JpaHelpContextIds.MAPPING_COLUMN_INSERTABLE
+		);
+
+		// Updatable tri-state check box
+		addTriStateCheckBoxWithDefault(
+			container,
+			JptUiDetailsMessages.JoinColumnDialogPane_updatable,
+			buildUpdatableHolder(),
+			buildUpdatableStringHolder(),
+			JpaHelpContextIds.MAPPING_COLUMN_UPDATABLE
+		);
+
+		// Unique tri-state check box
+		addTriStateCheckBoxWithDefault(
+			container,
+			JptUiDetailsMessages.ColumnComposite_unique,
+			buildUniqueHolder(),
+			buildUniqueStringHolder(),
+			JpaHelpContextIds.MAPPING_COLUMN_UNIQUE
+		);
+
+		// Nullable tri-state check box
+		addTriStateCheckBoxWithDefault(
+			container,
+			JptUiDetailsMessages.ColumnComposite_nullable,
+			buildNullableHolder(),
+			buildNullableStringHolder(),
+			JpaHelpContextIds.MAPPING_COLUMN_NULLABLE
+		);
+	}
+
+	/*
+	 * (non-Javadoc)
+	 */
+	@Override
+	protected boolean isTableEditable() {
+		return true;
+	}
+}
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/JoinColumnInJoiningStrategyDialog.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/JoinColumnInJoiningStrategyDialog.java
new file mode 100644
index 0000000..5810fcc
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/JoinColumnInJoiningStrategyDialog.java
@@ -0,0 +1,66 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2009 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.ui.internal.details;
+
+import org.eclipse.jpt.core.context.JoinColumn;
+import org.eclipse.jpt.core.context.JoinColumnJoiningStrategy;
+import org.eclipse.swt.widgets.Shell;
+
+/**
+ * This dialog is used to either create or edit a joing column that is located
+ * on a relational mapping.
+ *
+ * @see JoinColumn
+ * @see JoinColumnJoiningStrategy
+ * @see JoinColumnInJoiningStrategyStateObject
+ * @see JoinColumnDialogPane
+ *
+ * @version 2.0
+ * @since 2.0
+ */
+public class JoinColumnInJoiningStrategyDialog 
+	extends JoinColumnDialog<JoinColumnInJoiningStrategyStateObject> 
+{
+	/**
+	 * Creates a new <code>AbstractJoinColumnDialog</code>.
+	 *
+	 * @param parent The parent shell
+	 * @param relationshipMapping The owner of the join column to edit or to
+	 * create
+	 * @param joinColumn The join column to edit or <code>null</code> if this is
+	 * used to create a new one
+	 */
+	JoinColumnInJoiningStrategyDialog(
+		Shell parent,
+	    JoinColumnJoiningStrategy joinColumnOwner,
+	    JoinColumn joinColumn) {
+
+		super(parent, joinColumnOwner, joinColumn);
+	}
+
+	/*
+	 * (non-Javadoc)
+	 */
+	@Override
+	protected JoinColumnInJoiningStrategyStateObject buildStateObject() {
+		return new JoinColumnInJoiningStrategyStateObject(
+			getOwner(),
+			getJoinColumn()
+		);
+	}
+
+	/*
+	 * (non-Javadoc)
+	 */
+	@Override
+	protected JoinColumnJoiningStrategy getOwner() {
+		return (JoinColumnJoiningStrategy) super.getOwner();
+	}
+}
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/JoinColumnInJoiningStrategyStateObject.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/JoinColumnInJoiningStrategyStateObject.java
new file mode 100644
index 0000000..4cd5c81
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/JoinColumnInJoiningStrategyStateObject.java
@@ -0,0 +1,95 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2010 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.ui.internal.details;
+
+import java.util.ListIterator;
+import org.eclipse.jpt.core.context.JoinColumn;
+import org.eclipse.jpt.core.context.JoinColumnJoiningStrategy;
+import org.eclipse.jpt.core.context.TypeMapping;
+import org.eclipse.jpt.db.Schema;
+import org.eclipse.jpt.db.Table;
+import org.eclipse.jpt.utility.internal.CollectionTools;
+
+/**
+ * The state object used to create or edit a primary key join column on a
+ * relationship mapping.
+ *
+ * @see JoinColumn
+ * @see JoinColumnJoiningStrategy
+ * @see JoinColumnInJoiningStrategyDialog
+ *
+ * @version 2.3
+ * @since 2.0
+ */
+public class JoinColumnInJoiningStrategyStateObject 
+	extends JoinColumnStateObject
+{
+	/**
+	 * Creates a new <code>JoinColumnInJoiningStrategyStateObject</code>.
+	 *
+	 * @param joiningStrategy The owner of the join column to create
+	 * @param joinColumn The join column to edit or <code>null</code> if this is
+	 * used to create a new one
+	 */
+	public JoinColumnInJoiningStrategyStateObject(
+			JoinColumnJoiningStrategy joiningStrategy,
+		    JoinColumn joinColumn) {
+		super(joiningStrategy, joinColumn);
+	}
+	
+	
+	@Override
+	public JoinColumnJoiningStrategy getOwner() {
+		return (JoinColumnJoiningStrategy) super.getOwner();
+	}
+
+	@Override
+	public ListIterator<String> tables() {
+		Schema schema = getDbSchema();
+		return schema == null ? super.tables() : CollectionTools.list(schema.getSortedTableIdentifiers()).listIterator();
+	}
+	
+	protected Schema getDbSchema() {
+		TypeMapping typeMapping = getRelationshipSource();
+		return typeMapping == null ? null : typeMapping.getDbSchema();
+	}
+
+	protected TypeMapping getRelationshipSource() {
+		return getOwner().getRelationshipSource();
+	}
+	
+	protected TypeMapping getRelationshipTarget() {
+		return getOwner().getRelationshipTarget();
+	}
+	
+	@Override
+	public String getDefaultTable() {
+		JoinColumn joinColumn = getJoinColumn();
+
+		if (joinColumn != null) {
+			return joinColumn.getDefaultTable();
+		}
+		TypeMapping typeMapping = getRelationshipSource();		
+		return typeMapping == null ? null : typeMapping.getPrimaryTableName();
+	}
+	
+	@Override
+	public Table getNameTable() {
+		TypeMapping typeMapping = getRelationshipSource();
+		return typeMapping == null ? null : typeMapping.getPrimaryDbTable();
+	}
+	
+	@Override
+	public Table getReferencedNameTable() {
+		TypeMapping relationshipTarget = getRelationshipTarget();
+		return relationshipTarget == null ? null : relationshipTarget.getPrimaryDbTable();
+	}
+
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/JoinColumnInReferenceTableDialog.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/JoinColumnInReferenceTableDialog.java
new file mode 100644
index 0000000..d27eacf
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/JoinColumnInReferenceTableDialog.java
@@ -0,0 +1,78 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2009 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.ui.internal.details;
+
+import org.eclipse.jpt.core.context.JoinColumn;
+import org.eclipse.jpt.core.context.JoinTable;
+import org.eclipse.jpt.core.context.ReferenceTable;
+import org.eclipse.jpt.ui.internal.widgets.DialogPane;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Shell;
+
+/**
+ * This dialog is used to either create or edit a join column that is located
+ * on a join table.
+ *
+ * @see JoinColumn
+ * @see JoinTable
+ * @see JoinColumnInReferenceTableStateObject
+ * @see BaseJoinColumnDialogPane
+ *
+ * @version 2.0
+ * @since 1.0
+ */
+public class JoinColumnInReferenceTableDialog extends BaseJoinColumnDialog<JoinColumnInReferenceTableStateObject> {
+
+	/**
+	 * Creates a new <code>JoinColumnInReferenceTableDialog</code>.
+	 *
+	 * @param parent The parent shell
+	 * @param joinTable The parent of the join column to edit or to create
+	 * @param joinColumn Either the join column to edit or <code>null</code> if
+	 * this state object is used to create a new one
+	 */
+	public JoinColumnInReferenceTableDialog(Shell parent,
+	                                   ReferenceTable referenceTable,
+	                                   JoinColumn joinColumn) {
+
+		super(parent, referenceTable, joinColumn);
+	}
+
+	@Override
+	protected DialogPane<JoinColumnInReferenceTableStateObject> buildLayout(Composite container) {
+		return new JoinColumnDialogPane<JoinColumnInReferenceTableStateObject>(
+			getSubjectHolder(),
+			container
+		) {
+			@Override
+			protected boolean isTableEditable() {
+				return false;
+			}
+		};
+	}
+
+	@Override
+	protected JoinColumnInReferenceTableStateObject buildStateObject() {
+		return new JoinColumnInReferenceTableStateObject(
+			getOwner(),
+			getJoinColumn()
+		);
+	}
+
+	@Override
+	public JoinColumn getJoinColumn() {
+		return (JoinColumn) super.getJoinColumn();
+	}
+
+	@Override
+	protected ReferenceTable getOwner() {
+		return (ReferenceTable) super.getOwner();
+	}
+}
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/JoinColumnInReferenceTableStateObject.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/JoinColumnInReferenceTableStateObject.java
new file mode 100644
index 0000000..9b101a7
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/JoinColumnInReferenceTableStateObject.java
@@ -0,0 +1,87 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2010 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.ui.internal.details;
+
+import java.util.ListIterator;
+import org.eclipse.jpt.core.context.JoinColumn;
+import org.eclipse.jpt.core.context.JoinTable;
+import org.eclipse.jpt.core.context.ReferenceTable;
+import org.eclipse.jpt.core.context.TypeMapping;
+import org.eclipse.jpt.db.Table;
+import org.eclipse.jpt.utility.internal.iterators.SingleElementListIterator;
+
+/**
+ * The state object used to create or edit a primary key join column on a
+ * joint table.
+ *
+ * @see JoinColumn
+ * @see JoinTable
+ * @see InverseJoinColumnDialog
+ * @see InverseJoinColumnDialogPane
+ * @see JoinColumnInReferenceTableDialog
+ *
+ * @version 2.0
+ * @since 2.0
+ */
+public class JoinColumnInReferenceTableStateObject 
+	extends JoinColumnStateObject
+{
+	/**
+	 * Creates a new <code>JoinColumnInJoinTableStateObject</code>.
+	 *
+	 * @param joinTable The owner of the join column to create or to edit
+	 * @param joinColumn The join column to edit
+	 */
+	public JoinColumnInReferenceTableStateObject(
+			ReferenceTable referenceTable,
+	        JoinColumn joinColumn) {
+		super(referenceTable, joinColumn);
+	}
+	
+	
+	@Override
+	public ReferenceTable getOwner() {
+		return (ReferenceTable) super.getOwner();
+	}
+	
+	private TypeMapping getTypeMapping() {
+		return getOwner().getPersistentAttribute().getOwningTypeMapping();
+	}
+	
+	@Override
+	public String getDefaultTable() {
+		return null;
+	}
+	
+	@Override
+	public Table getNameTable() {
+		return getOwner().getDbTable();
+	}
+	
+	@Override
+	public Table getReferencedNameTable() {
+		return getTypeMapping().getPrimaryDbTable();
+	}
+	
+	@Override
+	protected String getInitialTable() {
+		return getOwner().getName();
+	}
+	
+	@Override
+	protected boolean isTableEditable() {
+		return false;
+	}
+	
+	@Override
+	public ListIterator<String> tables() {
+		return new SingleElementListIterator<String>(getInitialTable());
+	}
+}
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/JoinColumnJoiningStrategyPane.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/JoinColumnJoiningStrategyPane.java
new file mode 100644
index 0000000..cc33b7e
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/JoinColumnJoiningStrategyPane.java
@@ -0,0 +1,149 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2010 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.ui.internal.details;
+
+import org.eclipse.jpt.core.context.JoinColumnEnabledRelationshipReference;
+import org.eclipse.jpt.core.context.JoinColumnJoiningStrategy;
+import org.eclipse.jpt.core.context.RelationshipReference;
+import org.eclipse.jpt.ui.internal.widgets.Pane;
+import org.eclipse.jpt.utility.internal.model.value.PropertyAspectAdapter;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.jpt.utility.model.value.WritablePropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * Here is the layout of this pane:  
+ * <pre>
+ * -----------------------------------------------------------------------------
+ * | o Join columns __________________________________________________________ |
+ * | | --------------------------------------------------------------------- | |
+ * | | |                                                                   | | |
+ * | | |  JoiningStrategyJoinColumnsComposite                              | | |
+ * | | |                                                                   | | |
+ * | | --------------------------------------------------------------------- | |
+ * | ------------------------------------------------------------------------- |
+ * -----------------------------------------------------------------------------</pre>
+ *
+ * @see {@link JoinColumnEnabledRelationshipReference}
+ * @see {@link JoinColumnJoiningStrategy}
+ * @see {@link OneToOneJoiningStrategyPane}
+ * @see {@link ManyToOneJoiningStrategyPane}
+ *
+ * @version 2.3
+ * @since 2.1
+ */
+public class JoinColumnJoiningStrategyPane
+	extends AbstractJoiningStrategyPane
+		<JoinColumnEnabledRelationshipReference, JoinColumnJoiningStrategy>
+{
+	private final boolean includeOverrideCheckBox;
+	
+	
+	public static JoinColumnJoiningStrategyPane buildJoinColumnJoiningStrategyPaneWithIncludeOverrideCheckBox(
+		Pane<? extends JoinColumnEnabledRelationshipReference> parentPane, 
+		Composite parent) {
+		return new JoinColumnJoiningStrategyPane(parentPane, parent, true);
+	}
+	
+	public static JoinColumnJoiningStrategyPane buildJoinColumnJoiningStrategyPaneWithoutIncludeOverrideCheckBox(
+		Pane<? extends JoinColumnEnabledRelationshipReference> parentPane, 
+		Composite parent) {
+		return new JoinColumnJoiningStrategyPane(parentPane, parent, false);
+	}
+	
+	public static JoinColumnJoiningStrategyPane buildJoinColumnJoiningStrategyPaneWithIncludeOverrideCheckBox(
+		Pane<?> parentPane,
+		PropertyValueModel<? extends JoinColumnEnabledRelationshipReference> subjectHolder,
+        Composite parent) {
+		return new JoinColumnJoiningStrategyPane(parentPane, subjectHolder, parent, true);
+	}
+	
+	public static JoinColumnJoiningStrategyPane buildJoinColumnJoiningStrategyPaneWithoutIncludeOverrideCheckBox(
+		Pane<?> parentPane,
+		PropertyValueModel<? extends JoinColumnEnabledRelationshipReference> subjectHolder,
+        Composite parent) {
+		return new JoinColumnJoiningStrategyPane(parentPane, subjectHolder, parent, false);
+	}
+	
+	
+	private JoinColumnJoiningStrategyPane(
+			Pane<? extends JoinColumnEnabledRelationshipReference> parentPane, 
+			Composite parent,
+	        boolean includeOverrideCheckBox) {
+		super(parentPane, parent);
+		this.includeOverrideCheckBox = includeOverrideCheckBox;
+		initializeLayout2(getControl());
+	}
+	
+	private JoinColumnJoiningStrategyPane(Pane<?> parentPane,
+			PropertyValueModel<? extends JoinColumnEnabledRelationshipReference> subjectHolder,
+			Composite parent,
+			boolean includeOverrideCheckBox) {
+		
+		super(parentPane, subjectHolder, parent);
+		this.includeOverrideCheckBox = includeOverrideCheckBox;
+		initializeLayout2(getControl());
+	}
+
+	@Override
+	protected void initializeLayout(Composite container) {
+		//see initializeLayout2
+	}
+
+	protected void initializeLayout2(Composite container) {
+		super.initializeLayout(container); 
+		//just call super, we are delaying the initializeLayout because of the includeOverrideCheckBox boolean
+	}
+
+	@Override
+	protected Composite buildStrategyDetailsComposite(Composite parent) {
+		PropertyValueModel<JoinColumnJoiningStrategy> joiningStrategyHolder = this.buildJoinColumnJoiningStrategyHolder();
+
+		if (this.includeOverrideCheckBox) {
+			return new JoiningStrategyJoinColumnsWithOverrideOptionComposite(this, joiningStrategyHolder, parent).getControl();
+		}
+		return new JoiningStrategyJoinColumnsComposite(this, joiningStrategyHolder, parent).getControl();
+	}
+
+	@Override
+	protected WritablePropertyValueModel<Boolean> buildUsesStrategyHolder() {
+		return buildUsesJoinColumnJoiningStrategyHolder(getSubjectHolder());
+	}
+
+	protected PropertyValueModel<JoinColumnJoiningStrategy> buildJoinColumnJoiningStrategyHolder() {
+		return new PropertyAspectAdapter
+				<JoinColumnEnabledRelationshipReference, JoinColumnJoiningStrategy>(
+					getSubjectHolder()) {
+			@Override
+			protected JoinColumnJoiningStrategy buildValue_() {
+				return this.subject.getJoinColumnJoiningStrategy();
+			}
+		};
+	}
+
+	public static WritablePropertyValueModel<Boolean> buildUsesJoinColumnJoiningStrategyHolder(PropertyValueModel<? extends JoinColumnEnabledRelationshipReference> subjectHolder) {
+		return new PropertyAspectAdapter<JoinColumnEnabledRelationshipReference, Boolean>(
+				subjectHolder, RelationshipReference.PREDOMINANT_JOINING_STRATEGY_PROPERTY) {
+			@Override
+			protected Boolean buildValue() {
+				return (this.subject == null) ? Boolean.FALSE :
+					Boolean.valueOf(this.subject.usesJoinColumnJoiningStrategy());
+			}
+			
+			@Override
+			protected void setValue_(Boolean value) {
+				if (value == Boolean.TRUE) {
+					this.subject.setJoinColumnJoiningStrategy();
+				}
+				//value == FALSE - selection of another radio button causes this strategy to get unset
+			}
+		};
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/JoinColumnStateObject.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/JoinColumnStateObject.java
new file mode 100644
index 0000000..2cddce5
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/JoinColumnStateObject.java
@@ -0,0 +1,209 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2010 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.ui.internal.details;
+
+import java.util.ListIterator;
+import org.eclipse.jpt.core.context.BaseColumn;
+import org.eclipse.jpt.core.context.BaseJoinColumn;
+import org.eclipse.jpt.core.context.JoinColumn;
+import org.eclipse.jpt.utility.internal.iterators.EmptyListIterator;
+
+/**
+ * The state object used to edit a <code>JoinColumn</code>.
+ *
+ * @see JoinColumn
+ *
+ * @version 2.0
+ * @since 2.0
+ */
+@SuppressWarnings("nls")
+public abstract class JoinColumnStateObject extends BaseJoinColumnStateObject
+{
+	private Boolean insertable;
+	private Boolean nullable;
+	private Boolean unique;
+	private Boolean updatable;
+
+	public static final String INSERTABLE_PROPERTY = "insertable";
+	public static final String NULLABLE_PROPERTY = "nullable";
+	public static final String UNIQUE_PROPERTY = "unique";
+	public static final String UPDATABLE_PROPERTY = "updatable";
+
+	/**
+	 * Creates a new <code>JoinColumnStateObject</code>.
+	 *
+	 * @param owner The owner of the join column to create or where it is located
+	 * @param joinColumn The join column to edit
+	 */
+	public JoinColumnStateObject(Object owner, JoinColumn joinColumn) {
+		super(owner, joinColumn);
+	}
+
+	public boolean isDefaultInsertable() {
+
+		JoinColumn joinColumn = getJoinColumn();
+
+		if (joinColumn != null) {
+			return joinColumn.isDefaultInsertable();
+		}
+
+		return BaseColumn.DEFAULT_INSERTABLE;
+	}
+
+	public boolean isDefaultNullable() {
+
+		JoinColumn joinColumn = getJoinColumn();
+
+		if (joinColumn != null) {
+			return joinColumn.isDefaultNullable();
+		}
+
+		return BaseColumn.DEFAULT_NULLABLE;
+	}
+
+	public boolean isDefaultUnique() {
+
+		JoinColumn joinColumn = getJoinColumn();
+
+		if (joinColumn != null) {
+			return joinColumn.isDefaultUnique();
+		}
+
+		return BaseColumn.DEFAULT_UNIQUE;
+	}
+
+	public boolean isDefaultUpdatable() {
+
+		JoinColumn joinColumn = getJoinColumn();
+
+		if (joinColumn != null) {
+			return joinColumn.isDefaultUpdatable();
+		}
+
+		return BaseColumn.DEFAULT_UPDATABLE;
+	}
+
+	public Boolean getInsertable() {
+		return this.insertable;
+	}
+
+	@Override
+	public JoinColumn getJoinColumn() {
+		return (JoinColumn) super.getJoinColumn();
+	}
+
+	public Boolean getNullable() {
+		return this.nullable;
+	}
+
+	public Boolean getUnique() {
+		return this.unique;
+	}
+
+	public Boolean getUpdatable() {
+		return this.updatable;
+	}
+
+	@Override
+	protected void initialize(Object owner, BaseJoinColumn baseJoinColumn) {
+
+		super.initialize(owner, baseJoinColumn);
+
+		if (baseJoinColumn != null) {
+			JoinColumn joinColumn = (JoinColumn) baseJoinColumn;
+
+			this.insertable       = joinColumn.getSpecifiedInsertable();
+			this.nullable         = joinColumn.getSpecifiedNullable();
+			this.unique           = joinColumn.getSpecifiedUnique();
+			this.updatable        = joinColumn.getSpecifiedUpdatable();
+		}
+	}
+
+	@Override
+	protected String getInitialTable() {
+		JoinColumn joinColumn = getJoinColumn();
+
+		if (joinColumn == null) {
+			return null;
+		}
+
+		return joinColumn.getSpecifiedTable();
+	}
+
+	protected boolean isTableEditable() {
+		return true;
+	}
+
+	public void setInsertable(Boolean insertable) {
+		Boolean oldInsertable = this.insertable;
+		this.insertable = insertable;
+		firePropertyChanged(INSERTABLE_PROPERTY, oldInsertable, insertable);
+	}
+
+	public void setNullable(Boolean nullable) {
+		Boolean oldNullable = this.nullable;
+		this.nullable = nullable;
+		firePropertyChanged(NULLABLE_PROPERTY, oldNullable, nullable);
+	}
+
+	public void setUnique(Boolean unique) {
+		Boolean oldUnique = this.unique;
+		this.unique = unique;
+		firePropertyChanged(UNIQUE_PROPERTY, oldUnique, unique);
+	}
+
+	public void setUpdatable(Boolean updatable) {
+		Boolean oldUpdatable = this.updatable;
+		this.updatable = updatable;
+		firePropertyChanged(UPDATABLE_PROPERTY, oldUpdatable, updatable);
+	}
+
+	@Override
+	public ListIterator<String> tables() {
+		return EmptyListIterator.instance();
+	}
+
+	@Override
+	public void updateJoinColumn(BaseJoinColumn abstractJoinColumn) {
+
+		super.updateJoinColumn(abstractJoinColumn);
+
+		JoinColumn joinColumn = (JoinColumn) abstractJoinColumn;
+
+		// Table
+		if (isTableEditable()) {
+			String table = getTable();
+
+			if (valuesAreDifferent(table, joinColumn.getSpecifiedTable())) {
+				joinColumn.setSpecifiedTable(table);
+			}
+		}
+
+		// Insertable
+		if (joinColumn.getSpecifiedInsertable() != this.insertable){
+			joinColumn.setSpecifiedInsertable(this.insertable);
+		}
+
+		// Updatable
+		if (joinColumn.getSpecifiedUpdatable() != this.updatable){
+			joinColumn.setSpecifiedUpdatable(this.updatable);
+		}
+
+		// Unique
+		if (joinColumn.getSpecifiedUnique() != this.unique){
+			joinColumn.setSpecifiedUnique(this.unique);
+		}
+
+		// Nullable
+		if (joinColumn.getSpecifiedNullable() != this.nullable){
+			joinColumn.setSpecifiedNullable(this.nullable);
+		}
+	}
+}
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/JoinColumnsComposite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/JoinColumnsComposite.java
new file mode 100644
index 0000000..c0ef83f
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/JoinColumnsComposite.java
@@ -0,0 +1,331 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 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.ui.internal.details;
+
+import java.util.ArrayList;
+import java.util.ListIterator;
+
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.jpt.core.JpaNode;
+import org.eclipse.jpt.core.context.BaseJoinColumn;
+import org.eclipse.jpt.core.context.JoinColumn;
+import org.eclipse.jpt.core.context.NamedColumn;
+import org.eclipse.jpt.ui.WidgetFactory;
+import org.eclipse.jpt.ui.internal.JpaHelpContextIds;
+import org.eclipse.jpt.ui.internal.util.PaneEnabler;
+import org.eclipse.jpt.ui.internal.widgets.AddRemoveListPane;
+import org.eclipse.jpt.ui.internal.widgets.Pane;
+import org.eclipse.jpt.ui.internal.widgets.AddRemovePane.AbstractAdapter;
+import org.eclipse.jpt.ui.internal.widgets.AddRemovePane.Adapter;
+import org.eclipse.jpt.utility.internal.model.value.CompositeListValueModel;
+import org.eclipse.jpt.utility.internal.model.value.ItemPropertyListValueModelAdapter;
+import org.eclipse.jpt.utility.internal.model.value.ListAspectAdapter;
+import org.eclipse.jpt.utility.internal.model.value.PropertyAspectAdapter;
+import org.eclipse.jpt.utility.internal.model.value.PropertyListValueModelAdapter;
+import org.eclipse.jpt.utility.internal.model.value.SimplePropertyValueModel;
+import org.eclipse.jpt.utility.internal.model.value.swing.ObjectListSelectionModel;
+import org.eclipse.jpt.utility.model.value.ListValueModel;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.jpt.utility.model.value.WritablePropertyValueModel;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * Here is the layout of this pane:
+ * <pre>
+ * -----------------------------------------------------------------------------
+ * | ------------------------------------------------------------------------- |
+ * | |                                                                       | |
+ * | | AddRemoveListPane                                                     | |
+ * | |                                                                       | |
+ * | ------------------------------------------------------------------------- |
+ * -----------------------------------------------------------------------------</pre>
+ *
+ * @see JoiningStrategyJoinColumnsComposite - A container of this pane
+ * @see JoinTableComposite - A container of this pane
+ * @see EntityOverridesComposite - A container of this pane
+ *
+ * @version 3.0
+ * @since 2.0
+ */
+public class JoinColumnsComposite<T extends JpaNode> extends Pane<T>
+{
+	/**
+	 * The editor used to perform the common behaviors defined in the list pane.
+	 */
+	private JoinColumnsEditor<T> joinColumnsEditor;
+
+	private AddRemoveListPane<T> listPane;
+	
+	/**
+	 * Creates a new <code>JoinColumnsComposite</code>.
+	 *
+	 * @param parentPane The parent controller of this one
+	 * @param parent The parent container
+	 * @param widgetFactory The factory used to create various common widgets
+	 * @param joinColumnsEditor The editor used to perform the common behaviors
+	 * defined in the list pane
+	 */
+	public JoinColumnsComposite(Pane<? extends T> parentPane,
+	                            Composite parent,
+	                            JoinColumnsEditor<T> joinColumnsEditor) {
+
+		super(parentPane, parent);
+		this.joinColumnsEditor = joinColumnsEditor;
+		initializeLayout2();
+	}
+
+	/**
+	 * Creates a new <code>JoinColumnsComposite</code>.
+	 *
+	 * @param parentPane The parent controller of this one
+	 * @param subjectHolder The holder of this pane's subject
+	 * @param parent The parent container
+	 * @param widgetFactory The factory used to create various common widgets
+	 * @param joinColumnsEditor The editor used to perform the common behaviors
+	 * defined in the list pane
+	 */
+	public JoinColumnsComposite(Pane<?> parentPane,
+	                            PropertyValueModel<? extends T> subjectHolder,
+	                            Composite parent,
+	                            JoinColumnsEditor<T> joinColumnsEditor,
+	                            boolean automaticallyAlignWidgets) {
+
+		super(parentPane, subjectHolder, parent, automaticallyAlignWidgets);
+		this.joinColumnsEditor = joinColumnsEditor;
+		initializeLayout2();
+	}
+
+	/**
+	 * Creates a new <code>JoinColumnsComposite</code>.
+	 *
+	 * @param subjectHolder The holder of this pane's subject
+	 * @param parent The parent container
+	 * @param widgetFactory The factory used to create various common widgets
+	 */
+	public JoinColumnsComposite(PropertyValueModel<? extends T> subjectHolder,
+	                            Composite parent,
+	                            WidgetFactory widgetFactory,
+	                            JoinColumnsEditor<T> joinColumnsEditor) {
+
+		super(subjectHolder, parent, widgetFactory);
+		this.joinColumnsEditor = joinColumnsEditor;
+		initializeLayout2();
+	}
+
+	@Override
+	protected void initializeLayout(Composite container) {
+		//see intiailizeLayout2()
+	}
+
+	private void initializeLayout2() {
+		this.listPane = new AddRemoveListPane<T>(
+			this,
+			getControl(),
+			buildJoinColumnsAdapter(),
+			buildJoinColumnsListModel(),
+			buildSelectedJoinColumnHolder(),
+			buildJoinColumnsListLabelProvider(),
+			JpaHelpContextIds.MAPPING_JOIN_TABLE_COLUMNS,
+			false
+		);
+	}
+
+	private WritablePropertyValueModel<JoinColumn> buildSelectedJoinColumnHolder() {
+		return new SimplePropertyValueModel<JoinColumn>();
+	}
+
+	private String buildJoinColumnLabel(JoinColumn joinColumn) {
+
+		if (joinColumn.isVirtual()) {
+			return NLS.bind(
+				JptUiDetailsMessages.JoinColumnsComposite_mappingBetweenTwoParamsDefault,
+				joinColumn.getName(),
+				joinColumn.getReferencedColumnName()
+			);
+		}
+		if (joinColumn.getSpecifiedName() == null) {
+
+			if (joinColumn.getSpecifiedReferencedColumnName() == null) {
+				return NLS.bind(
+					JptUiDetailsMessages.JoinColumnsComposite_mappingBetweenTwoParamsBothDefault,
+					joinColumn.getName(),
+					joinColumn.getReferencedColumnName()
+				);
+			}
+
+			return NLS.bind(
+				JptUiDetailsMessages.JoinColumnsComposite_mappingBetweenTwoParamsFirstDefault,
+				joinColumn.getName(),
+				joinColumn.getReferencedColumnName()
+			);
+		}
+
+		if (joinColumn.getSpecifiedReferencedColumnName() == null) {
+			return NLS.bind(
+				JptUiDetailsMessages.JoinColumnsComposite_mappingBetweenTwoParamsSecDefault,
+				joinColumn.getName(),
+				joinColumn.getReferencedColumnName()
+			);
+		}
+
+		return NLS.bind(
+			JptUiDetailsMessages.JoinColumnsComposite_mappingBetweenTwoParams,
+			joinColumn.getName(),
+			joinColumn.getReferencedColumnName()
+		);
+	}
+
+	private Adapter buildJoinColumnsAdapter() {
+		return new AbstractAdapter() {
+
+			public void addNewItem(ObjectListSelectionModel listSelectionModel) {
+				JoinColumnsComposite.this.joinColumnsEditor.addJoinColumn(getSubject());
+			}
+
+			@Override
+			public boolean hasOptionalButton() {
+				return true;
+			}
+
+			@Override
+			public String optionalButtonText() {
+				return JptUiDetailsMessages.JoinColumnsComposite_edit;
+			}
+
+			@Override
+			public void optionOnSelection(ObjectListSelectionModel listSelectionModel) {
+				JoinColumn joinColumn = (JoinColumn) listSelectionModel.selectedValue();
+				JoinColumnsComposite.this.joinColumnsEditor.editJoinColumn(getSubject(), joinColumn);
+			}
+
+			public void removeSelectedItems(ObjectListSelectionModel listSelectionModel) {
+				JoinColumnsComposite.this.joinColumnsEditor.removeJoinColumns(getSubject(), listSelectionModel.selectedIndices());
+			}
+		};
+	}
+
+	private ListValueModel<JoinColumn> buildJoinColumnsListModel() {
+		return new ItemPropertyListValueModelAdapter<JoinColumn>(buildJoinColumnsListHolder(),
+			NamedColumn.SPECIFIED_NAME_PROPERTY,
+			NamedColumn.DEFAULT_NAME_PROPERTY,
+			BaseJoinColumn.SPECIFIED_REFERENCED_COLUMN_NAME_PROPERTY,
+			BaseJoinColumn.DEFAULT_REFERENCED_COLUMN_NAME_PROPERTY);
+	}
+
+	private ListValueModel<JoinColumn> buildJoinColumnsListHolder() {
+		java.util.List<ListValueModel<JoinColumn>> list = new ArrayList<ListValueModel<JoinColumn>>();
+		list.add(buildSpecifiedJoinColumnsListHolder());
+		list.add(buildDefaultJoinColumnListHolder());
+		return new CompositeListValueModel<ListValueModel<JoinColumn>, JoinColumn>(list);
+	}
+
+	private ListValueModel<JoinColumn> buildSpecifiedJoinColumnsListHolder() {
+		return new ListAspectAdapter<T, JoinColumn>(getSubjectHolder(), this.joinColumnsEditor.getSpecifiedJoinColumnsListPropertyName()) {
+			@Override
+			protected ListIterator<JoinColumn> listIterator_() {
+				return JoinColumnsComposite.this.joinColumnsEditor.specifiedJoinColumns(this.subject);
+			}
+
+			@Override
+			protected int size_() {
+				return JoinColumnsComposite.this.joinColumnsEditor.specifiedJoinColumnsSize(this.subject);
+			}
+		};
+	}
+
+
+	private ListValueModel<JoinColumn> buildDefaultJoinColumnListHolder() {
+		return new PropertyListValueModelAdapter<JoinColumn>(buildDefaultJoinColumnHolder());
+
+	}
+
+	private PropertyValueModel<JoinColumn> buildDefaultJoinColumnHolder() {
+		return new PropertyAspectAdapter<T, JoinColumn>(getSubjectHolder(), this.joinColumnsEditor.getDefaultPropertyName()) {
+			@Override
+			protected JoinColumn buildValue_() {
+				return JoinColumnsComposite.this.joinColumnsEditor.getDefaultJoinColumn(this.subject);
+			}
+		};
+	}
+
+
+	private ILabelProvider buildJoinColumnsListLabelProvider() {
+		return new LabelProvider() {
+			@Override
+			public String getText(Object element) {
+				JoinColumn joinColumn = (JoinColumn) element;
+
+				return buildJoinColumnLabel(joinColumn);
+			}
+		};
+	}
+	
+	public void installJoinColumnsPaneEnabler(PropertyValueModel<Boolean> joinColumnsPaneEnablerHolder) {
+		new PaneEnabler(joinColumnsPaneEnablerHolder, this.listPane);
+	}
+	
+	public void setSelectedJoinColumn(JoinColumn joinColumn) {
+		this.listPane.setSelectedItem(joinColumn);
+	}
+	
+	/**
+	 * The editor is used to complete the behavior of this pane.
+	 */
+	public static interface JoinColumnsEditor<T> {
+
+		/**
+		 * Add a join column to the given subject and return it
+		 */
+		void addJoinColumn(T subject);
+		
+		/**
+		 * Edit the given join column, the Edit button was pressed
+		 * while this join column was selected.
+		 */
+		void editJoinColumn(T subject, JoinColumn joinColumn);
+		
+		/**
+		 * Return whether the subject has specified join columns
+		 */
+		boolean hasSpecifiedJoinColumns(T subject);
+		
+		/**
+		 * Return the spcified join columns from the given subject
+		 */
+		ListIterator<JoinColumn> specifiedJoinColumns(T subject);
+		
+		/**
+		 * Return the number of specified join columns on the given subject
+		 */
+		int specifiedJoinColumnsSize(T subject);
+		
+		/**
+		 * Return the default join column from the given subject or null.
+		 */
+		JoinColumn getDefaultJoinColumn(T subject);
+		
+		/**
+		 * Return the property name of the specified join columns list
+		 */
+		String getSpecifiedJoinColumnsListPropertyName();
+		
+		/**
+		 * Return the property name of the specified join columns list
+		 */
+		String getDefaultPropertyName();
+		
+		/**
+		 * Remove the join columns at the specified indices from the subject
+		 */
+		void removeJoinColumns(T subject, int[] selectedIndices);
+	}
+}
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/JoinTableComposite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/JoinTableComposite.java
new file mode 100644
index 0000000..e15cf70
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/JoinTableComposite.java
@@ -0,0 +1,417 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2010 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.ui.internal.details;
+
+import java.util.ListIterator;
+
+import org.eclipse.jpt.core.context.JoinColumn;
+import org.eclipse.jpt.core.context.JoinTable;
+import org.eclipse.jpt.ui.WidgetFactory;
+import org.eclipse.jpt.ui.internal.JpaHelpContextIds;
+import org.eclipse.jpt.ui.internal.details.JoinColumnsComposite.JoinColumnsEditor;
+import org.eclipse.jpt.ui.internal.details.db.CatalogCombo;
+import org.eclipse.jpt.ui.internal.details.db.SchemaCombo;
+import org.eclipse.jpt.ui.internal.details.db.TableCombo;
+import org.eclipse.jpt.ui.internal.widgets.Pane;
+import org.eclipse.jpt.ui.internal.widgets.PostExecution;
+import org.eclipse.jpt.utility.internal.model.value.CachingTransformationPropertyValueModel;
+import org.eclipse.jpt.utility.internal.model.value.ListAspectAdapter;
+import org.eclipse.jpt.utility.internal.model.value.ListPropertyValueModelAdapter;
+import org.eclipse.jpt.utility.internal.model.value.ReadOnlyWritablePropertyValueModelWrapper;
+import org.eclipse.jpt.utility.internal.model.value.ValueListAdapter;
+import org.eclipse.jpt.utility.model.event.StateChangeEvent;
+import org.eclipse.jpt.utility.model.listener.StateChangeListener;
+import org.eclipse.jpt.utility.model.value.ListValueModel;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.jpt.utility.model.value.WritablePropertyValueModel;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Group;
+
+/**
+ * Here the layout of this pane:
+ * <pre>
+ * -----------------------------------------------------------------------------
+ * |         ---------------------------------------------------------------   |
+ * |   Name: |                                                           |v|   |
+ * |         ---------------------------------------------------------------   |
+ * |                                                                           |
+ * | - Join Columns ---------------------------------------------------------- |
+ * | |                                                                       | |
+ * | | x Override Default                                                    | |
+ * | |                                                                       | |
+ * | | --------------------------------------------------------------------- | |
+ * | | |                                                                   | | |
+ * | | | JoinColumnsComposite                                              | | |
+ * | | |                                                                   | | |
+ * | | --------------------------------------------------------------------- | |
+ * | ------------------------------------------------------------------------- |
+ * |                                                                           |
+ * | - Inverse Join Columns -------------------------------------------------- |
+ * | |                                                                       | |
+ * | | x Override Default                                                    | |
+ * | |                                                                       | |
+ * | | --------------------------------------------------------------------- | |
+ * | | |                                                                   | | |
+ * | | | JoinColumnsComposite                                              | | |
+ * | | |                                                                   | | |
+ * | | --------------------------------------------------------------------- | |
+ * | ------------------------------------------------------------------------- |
+ * -----------------------------------------------------------------------------</pre>
+ *
+ * @see {@link JoinTable}
+ * @see {@link JoinTableJoiningStrategyPane}
+ * @see {@link JoinColumnsComposite
+ *
+ * @version 2.1
+ * @since 1.0
+ */
+public class JoinTableComposite extends ReferenceTableComposite<JoinTable>
+{
+	private Button overrideDefaultInverseJoinColumnsCheckBox;
+
+	private JoinColumnsComposite<JoinTable> inverseJoinColumnsComposite;
+	/**
+	 * Creates a new <code>JoinTableComposite</code>.
+	 *
+	 * @param parentPane The parent container of this one
+	 * @param subjectHolder The holder of this pane's subject
+	 * @param parent The parent container
+	 */
+	public JoinTableComposite(
+			Pane<?> parentPane,
+			PropertyValueModel<? extends JoinTable> subjectHolder,
+			Composite parent) {
+
+		super(parentPane, subjectHolder, parent);
+	}
+
+	/**
+	 * Creates a new <code>JoinTableComposite</code>.
+	 *
+	 * @param subjectHolder The holder of the subject <code>IJoinTable</code>
+	 * @param parent The parent container
+	 * @param widgetFactory The factory used to create various common widgets
+	 */
+	public JoinTableComposite(PropertyValueModel<? extends JoinTable> subjectHolder,
+	                          Composite parent,
+	                          WidgetFactory widgetFactory) {
+
+		super(subjectHolder, parent, widgetFactory);
+	}
+
+	@Override
+	protected boolean isParentVirtual(JoinTable joinTable) {
+		return joinTable.getParent().getRelationshipReference().isParentVirtual();
+	}
+	@Override
+	protected void initializeLayout(Composite container) {
+
+		int groupBoxMargin = getGroupBoxMargin();
+
+		// Name widgets
+		TableCombo<JoinTable> tableCombo = addTableCombo(container);
+		Composite tablePane = addPane(container, groupBoxMargin);
+		addLabeledComposite(
+				tablePane,
+			JptUiDetailsMessages.JoinTableComposite_name,
+			tableCombo.getControl(),
+			JpaHelpContextIds.MAPPING_JOIN_TABLE_NAME
+		);
+		
+		// schema widgets
+		SchemaCombo<JoinTable> schemaCombo = addSchemaCombo(container);
+
+		addLabeledComposite(
+			tablePane,
+			JptUiDetailsMessages.JoinTableComposite_schema,
+			schemaCombo.getControl(),
+			JpaHelpContextIds.MAPPING_JOIN_TABLE_SCHEMA
+		);
+		
+		// catalog widgets
+		CatalogCombo<JoinTable> catalogCombo = addCatalogCombo(container);
+
+		addLabeledComposite(
+			tablePane,
+			JptUiDetailsMessages.JoinTableComposite_catalog,
+			catalogCombo.getControl(),
+			JpaHelpContextIds.MAPPING_JOIN_TABLE_CATALOG
+		);
+
+		// Join Columns group pane
+		Group joinColumnGroupPane = addTitledGroup(
+			container,
+			JptUiDetailsMessages.JoinTableComposite_joinColumn
+		);
+
+		// Override Default Join Columns check box
+		this.overrideDefaultJoinColumnsCheckBox = addCheckBox(
+			addSubPane(joinColumnGroupPane, 8),
+			JptUiDetailsMessages.JoinTableComposite_overrideDefaultJoinColumns,
+			buildOverrideDefaultJoinColumnHolder(),
+			null
+		);
+
+		this.joinColumnsComposite = new JoinColumnsComposite<JoinTable>(
+			this,
+			joinColumnGroupPane,
+			buildJoinColumnsEditor()
+		);
+
+		installJoinColumnsPaneEnabler(this.joinColumnsComposite);
+
+		// Inverse Join Columns group pane
+		Group inverseJoinColumnGroupPane = addTitledGroup(
+			container,
+			JptUiDetailsMessages.JoinTableComposite_inverseJoinColumn
+		);
+
+		// Override Default Inverse Join Columns check box
+		this.overrideDefaultInverseJoinColumnsCheckBox = addCheckBox(
+			addSubPane(inverseJoinColumnGroupPane, 8),
+			JptUiDetailsMessages.JoinTableComposite_overrideDefaultInverseJoinColumns,
+			buildOverrideDefaultInverseJoinColumnHolder(),
+			null
+		);
+
+		this.inverseJoinColumnsComposite = new JoinColumnsComposite<JoinTable>(
+			this,
+			inverseJoinColumnGroupPane,
+			buildInverseJoinColumnsEditor()
+		);
+
+		installInverseJoinColumnsPaneEnabler(this.inverseJoinColumnsComposite);
+	}
+
+	private void installInverseJoinColumnsPaneEnabler(JoinColumnsComposite<JoinTable> pane) {
+		pane.installJoinColumnsPaneEnabler(new InverseJoinColumnPaneEnablerHolder());
+	}
+
+	private void addInverseJoinColumn(JoinTable joinTable) {
+
+		InverseJoinColumnInJoinTableDialog dialog =
+			new InverseJoinColumnInJoinTableDialog(getShell(), joinTable, null);
+
+		dialog.openDialog(buildAddInverseJoinColumnPostExecution());
+	}
+
+	private void addInverseJoinColumnFromDialog(InverseJoinColumnInJoinTableStateObject stateObject) {
+
+		JoinTable subject = getSubject();
+		int index = subject.specifiedInverseJoinColumnsSize();
+
+		JoinColumn joinColumn = subject.addSpecifiedInverseJoinColumn(index);
+		stateObject.updateJoinColumn(joinColumn);
+		this.setSelectedInverseJoinColumn(joinColumn);
+	}
+
+	private void setSelectedInverseJoinColumn(JoinColumn joinColumn) {
+		this.inverseJoinColumnsComposite.setSelectedJoinColumn(joinColumn);
+	}
+
+	private PostExecution<InverseJoinColumnInJoinTableDialog> buildAddInverseJoinColumnPostExecution() {
+		return new PostExecution<InverseJoinColumnInJoinTableDialog>() {
+			public void execute(InverseJoinColumnInJoinTableDialog dialog) {
+				if (dialog.wasConfirmed()) {
+					addInverseJoinColumnFromDialog(dialog.getSubject());
+				}
+			}
+		};
+	}
+
+	private PostExecution<InverseJoinColumnInJoinTableDialog> buildEditInverseJoinColumnPostExecution() {
+		return new PostExecution<InverseJoinColumnInJoinTableDialog>() {
+			public void execute(InverseJoinColumnInJoinTableDialog dialog) {
+				if (dialog.wasConfirmed()) {
+					editInverseJoinColumn(dialog.getSubject());
+				}
+			}
+		};
+	}
+
+
+	private InverseJoinColumnsProvider buildInverseJoinColumnsEditor() {
+		return new InverseJoinColumnsProvider();
+	}
+
+	private WritablePropertyValueModel<Boolean> buildOverrideDefaultInverseJoinColumnHolder() {
+		return new OverrideDefaultInverseJoinColumnHolder();
+	}
+	
+	private ListValueModel<JoinColumn> buildSpecifiedInverseJoinColumnsListHolder() {
+		return new ListAspectAdapter<JoinTable, JoinColumn>(getSubjectHolder(), JoinTable.SPECIFIED_INVERSE_JOIN_COLUMNS_LIST) {
+			@Override
+			protected ListIterator<JoinColumn> listIterator_() {
+				return this.subject.specifiedInverseJoinColumns();
+			}
+
+			@Override
+			protected int size_() {
+				return this.subject.specifiedInverseJoinColumnsSize();
+			}
+		};
+	}
+
+
+	private void editInverseJoinColumn(InverseJoinColumnInJoinTableStateObject stateObject) {
+		stateObject.updateJoinColumn(stateObject.getJoinColumn());
+	}
+
+	private void editInverseJoinColumn(JoinColumn joinColumn) {
+
+		InverseJoinColumnInJoinTableDialog dialog =
+			new InverseJoinColumnInJoinTableDialog(getShell(), getSubject(), joinColumn);
+
+		dialog.openDialog(buildEditInverseJoinColumnPostExecution());
+	}
+
+	private void updateInverseJoinColumns() {
+		if (this.isPopulating()) {
+			return;
+		}
+		
+		JoinTable joinTable = this.getSubject();
+		if (joinTable == null) {
+			return;
+		}
+		
+		boolean selected = this.overrideDefaultInverseJoinColumnsCheckBox.getSelection();
+		this.setPopulating(true);
+
+		try {
+			if (selected) {
+				joinTable.convertDefaultToSpecifiedInverseJoinColumn();
+				setSelectedInverseJoinColumn(joinTable.specifiedInverseJoinColumns().next());
+			} else {
+				joinTable.clearSpecifiedInverseJoinColumns();
+			}
+		} finally {
+			this.setPopulating(false);
+		}
+	}
+
+
+
+	private class InverseJoinColumnsProvider implements JoinColumnsEditor<JoinTable> {
+
+		public void addJoinColumn(JoinTable subject) {
+			JoinTableComposite.this.addInverseJoinColumn(subject);
+		}
+
+		public JoinColumn getDefaultJoinColumn(JoinTable subject) {
+			return subject.getDefaultInverseJoinColumn();
+		}
+
+		public String getDefaultPropertyName() {
+			return JoinTable.DEFAULT_INVERSE_JOIN_COLUMN;
+		}
+
+		public void editJoinColumn(JoinTable subject, JoinColumn joinColumn) {
+			JoinTableComposite.this.editInverseJoinColumn(joinColumn);
+		}
+
+		public boolean hasSpecifiedJoinColumns(JoinTable subject) {
+			return subject.hasSpecifiedInverseJoinColumns();
+		}
+
+		public void removeJoinColumns(JoinTable subject, int[] selectedIndices) {
+			for (int index = selectedIndices.length; --index >= 0; ) {
+				subject.removeSpecifiedInverseJoinColumn(selectedIndices[index]);
+			}
+		}
+
+		public ListIterator<JoinColumn> specifiedJoinColumns(JoinTable subject) {
+			return subject.specifiedInverseJoinColumns();
+		}
+
+		public int specifiedJoinColumnsSize(JoinTable subject) {
+			return subject.specifiedInverseJoinColumnsSize();
+		}
+
+		public String getSpecifiedJoinColumnsListPropertyName() {
+			return JoinTable.SPECIFIED_INVERSE_JOIN_COLUMNS_LIST;
+		}
+	}
+	
+	private class OverrideDefaultInverseJoinColumnHolder extends ListPropertyValueModelAdapter<Boolean>
+	    implements WritablePropertyValueModel<Boolean> {
+	
+		public OverrideDefaultInverseJoinColumnHolder() {
+			super(buildSpecifiedInverseJoinColumnsListHolder());
+		}
+	
+		@Override
+		protected Boolean buildValue() {
+			return Boolean.valueOf(this.listHolder.size() > 0);
+		}
+	
+		public void setValue(Boolean value) {
+			updateInverseJoinColumns();
+		}
+	}
+
+	
+	private class InverseJoinColumnPaneEnablerHolder 
+		extends CachingTransformationPropertyValueModel<JoinTable, Boolean>
+	{
+		private StateChangeListener stateChangeListener;
+		
+		
+		public InverseJoinColumnPaneEnablerHolder() {
+			super(
+				new ValueListAdapter<JoinTable>(
+					new ReadOnlyWritablePropertyValueModelWrapper(getSubjectHolder()), 
+					JoinTable.SPECIFIED_INVERSE_JOIN_COLUMNS_LIST));
+			this.stateChangeListener = buildStateChangeListener();
+		}
+		
+		
+		private StateChangeListener buildStateChangeListener() {
+			return new StateChangeListener() {
+				public void stateChanged(StateChangeEvent event) {
+					valueStateChanged(event);
+				}
+			};
+		}
+		
+		private void valueStateChanged(StateChangeEvent event) {
+			Object oldValue = this.cachedValue;
+			Object newValue = transformNew(this.valueHolder.getValue());
+			firePropertyChanged(VALUE, oldValue, newValue);
+		}
+		
+		@Override
+		protected Boolean transform(JoinTable value) {
+			if (value == null) {
+				return false;
+			}
+			return super.transform(value);
+		}
+		
+		@Override
+		protected Boolean transform_(JoinTable value) {
+			boolean virtual = JoinTableComposite.this.isParentVirtual(value);
+			return Boolean.valueOf(! virtual && value.specifiedInverseJoinColumnsSize() > 0);
+		}
+		
+		@Override
+		protected void engageModel() {
+			super.engageModel();
+			this.valueHolder.addStateChangeListener(this.stateChangeListener);
+		}
+		
+		@Override
+		protected void disengageModel() {
+			this.valueHolder.removeStateChangeListener(this.stateChangeListener);
+			super.disengageModel();
+		}
+	}
+}
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/JoinTableJoiningStrategyPane.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/JoinTableJoiningStrategyPane.java
new file mode 100644
index 0000000..36a747d
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/JoinTableJoiningStrategyPane.java
@@ -0,0 +1,109 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2010 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.ui.internal.details;
+
+import org.eclipse.jpt.core.context.JoinTable;
+import org.eclipse.jpt.core.context.JoinTableEnabledRelationshipReference;
+import org.eclipse.jpt.core.context.JoinTableJoiningStrategy;
+import org.eclipse.jpt.core.context.RelationshipReference;
+import org.eclipse.jpt.ui.internal.widgets.Pane;
+import org.eclipse.jpt.utility.internal.model.value.PropertyAspectAdapter;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.jpt.utility.model.value.WritablePropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * Here is the layout of this pane:  
+ * <pre>
+ * -----------------------------------------------------------------------------
+ * | o Join table ____________________________________________________________ |
+ * | | --------------------------------------------------------------------- | |
+ * | | |                                                                   | | |
+ * | | |  JoinTableComposite                                               | | |
+ * | | |                                                                   | | |
+ * | | --------------------------------------------------------------------- | |
+ * | ------------------------------------------------------------------------- |
+ * -----------------------------------------------------------------------------</pre>
+ *
+ * @see {@link JoinTableEnabledRelationshipReference}
+ * @see {@link JoinTableJoiningStrategy}
+ * @see {@link ManyToOneJoiningStrategyPane}
+ * @see {@link ManyToManyJoiningStrategyPane}
+ *
+ * @version 2.3
+ * @since 2.1
+ */
+public class JoinTableJoiningStrategyPane
+	extends AbstractJoiningStrategyPane
+		<JoinTableEnabledRelationshipReference, JoinTableJoiningStrategy>
+{
+	public JoinTableJoiningStrategyPane(
+			Pane<? extends JoinTableEnabledRelationshipReference> parentPane, 
+			Composite parent) {
+		super(parentPane, parent);
+	}
+
+	public JoinTableJoiningStrategyPane(Pane<?> parentPane,
+		PropertyValueModel<? extends JoinTableEnabledRelationshipReference> subjectHolder,
+        Composite parent) {
+
+		super(parentPane, subjectHolder, parent);
+	}
+
+	@Override
+	protected Composite buildStrategyDetailsComposite(Composite parent) {
+		return new JoinTableComposite(this, buildJoinTableHolder(), parent).getControl();
+	}
+
+	@Override
+	protected WritablePropertyValueModel<Boolean> buildUsesStrategyHolder() {
+		return buildUsesJoinTableJoiningStrategyHolder(getSubjectHolder());
+	}
+
+	protected PropertyValueModel<JoinTableJoiningStrategy> buildJoinTableJoiningStrategyHolder() {
+		return new PropertyAspectAdapter
+				<JoinTableEnabledRelationshipReference, JoinTableJoiningStrategy>(
+					getSubjectHolder()) {
+			@Override
+			protected JoinTableJoiningStrategy buildValue_() {
+				return this.subject.getJoinTableJoiningStrategy();
+			}
+		};
+	}
+
+	protected PropertyValueModel<JoinTable> buildJoinTableHolder() {
+		return new PropertyAspectAdapter<JoinTableJoiningStrategy, JoinTable>(
+				this.buildJoinTableJoiningStrategyHolder(), JoinTableJoiningStrategy.JOIN_TABLE_PROPERTY) {
+			@Override
+			protected JoinTable buildValue_() {
+				return this.subject.getJoinTable();
+			}
+		};
+	}
+
+	public static WritablePropertyValueModel<Boolean> buildUsesJoinTableJoiningStrategyHolder(PropertyValueModel<? extends JoinTableEnabledRelationshipReference> subjectHolder) {
+		return new PropertyAspectAdapter<JoinTableEnabledRelationshipReference, Boolean>(
+			subjectHolder, RelationshipReference.PREDOMINANT_JOINING_STRATEGY_PROPERTY) {
+			@Override
+			protected Boolean buildValue() {
+				return (this.subject == null) ? Boolean.FALSE :
+					Boolean.valueOf(this.subject.usesJoinTableJoiningStrategy());
+			}
+			
+			@Override
+			protected void setValue_(Boolean value) {
+				if (value == Boolean.TRUE) {
+					this.subject.setJoinTableJoiningStrategy();
+				}
+				//value == FALSE - selection of another radio button causes this strategy to get unset
+			}
+		};
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/JoiningStrategyJoinColumnsComposite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/JoiningStrategyJoinColumnsComposite.java
new file mode 100644
index 0000000..9451194
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/JoiningStrategyJoinColumnsComposite.java
@@ -0,0 +1,236 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2010 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.ui.internal.details;
+
+import java.util.ListIterator;
+
+import org.eclipse.jpt.core.context.JoinColumn;
+import org.eclipse.jpt.core.context.JoinColumnJoiningStrategy;
+import org.eclipse.jpt.ui.internal.details.JoinColumnsComposite.JoinColumnsEditor;
+import org.eclipse.jpt.ui.internal.widgets.Pane;
+import org.eclipse.jpt.ui.internal.widgets.PostExecution;
+import org.eclipse.jpt.utility.internal.model.value.CachingTransformationPropertyValueModel;
+import org.eclipse.jpt.utility.internal.model.value.ReadOnlyWritablePropertyValueModelWrapper;
+import org.eclipse.jpt.utility.internal.model.value.ValueListAdapter;
+import org.eclipse.jpt.utility.model.event.StateChangeEvent;
+import org.eclipse.jpt.utility.model.listener.StateChangeListener;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * Here is the layout of this pane:
+ * <pre>                                            
+ * ---------------------------------------------------------------------
+ * |                                                                   |
+ * | JoinColumnsComposite                                              |
+ * |                                                                   |
+ * ---------------------------------------------------------------------
+ * -------------------------------------------------------------------------</pre>
+ *
+ * @see JoinColumnEnabledRelationshipReference
+ * @see JoinColumnJoiningStrategy
+ * @see JoinColumnJoiningStrategyPane
+ * @see JoinColumnInJoiningStrategyDialog
+ *
+ * @version 3.0
+ * @since 2.0
+ */
+public class JoiningStrategyJoinColumnsComposite 
+	extends Pane<JoinColumnJoiningStrategy>
+{
+	
+	private JoinColumnsComposite<JoinColumnJoiningStrategy> joinColumnsComposite;
+	
+	public JoiningStrategyJoinColumnsComposite(
+			Pane<?> parentPane,
+			PropertyValueModel<JoinColumnJoiningStrategy> subjectHolder,
+			Composite parent) {
+		super(parentPane, subjectHolder, parent);
+	}
+
+
+	@Override
+	protected void initializeLayout(Composite container) {		
+		this.joinColumnsComposite = new JoinColumnsComposite<JoinColumnJoiningStrategy>(this, container, buildJoinColumnsProvider());
+		this.joinColumnsComposite.installJoinColumnsPaneEnabler(new JoinColumnPaneEnablerHolder());
+	}
+	
+	private JoinColumnsEditor<JoinColumnJoiningStrategy> buildJoinColumnsProvider() {
+		return new JoinColumnsEditor<JoinColumnJoiningStrategy>() {
+
+			public void addJoinColumn(JoinColumnJoiningStrategy subject) {
+				JoiningStrategyJoinColumnsComposite.this.addJoinColumn(subject);
+			}
+
+			public boolean hasSpecifiedJoinColumns(JoinColumnJoiningStrategy subject) {
+				return subject.hasSpecifiedJoinColumns();
+			}
+
+			public void editJoinColumn(JoinColumnJoiningStrategy subject, JoinColumn joinColumn) {
+				JoiningStrategyJoinColumnsComposite.this.editJoinColumn(subject, joinColumn);
+			}
+
+			public JoinColumn getDefaultJoinColumn(JoinColumnJoiningStrategy subject) {
+				return subject.getDefaultJoinColumn();
+			}
+
+			public String getDefaultPropertyName() {
+				return JoinColumnJoiningStrategy.DEFAULT_JOIN_COLUMN_PROPERTY;
+			}
+
+			public String getSpecifiedJoinColumnsListPropertyName() {
+				return JoinColumnJoiningStrategy.SPECIFIED_JOIN_COLUMNS_LIST;
+			}
+
+			public void removeJoinColumns(JoinColumnJoiningStrategy subject, int[] selectedIndices) {
+				for (int index = selectedIndices.length; --index >= 0; ) {
+					subject.removeSpecifiedJoinColumn(selectedIndices[index]);
+				}				
+			}
+
+			public ListIterator<JoinColumn> specifiedJoinColumns(JoinColumnJoiningStrategy subject) {
+				return subject.specifiedJoinColumns();
+			}
+
+			public int specifiedJoinColumnsSize(JoinColumnJoiningStrategy subject) {
+				return subject.specifiedJoinColumnsSize();
+			}
+		};
+	}
+	
+	private void addJoinColumn(JoinColumnJoiningStrategy joiningStrategy) {
+		JoinColumnInJoiningStrategyDialog dialog =
+			new JoinColumnInJoiningStrategyDialog(getShell(), joiningStrategy, null);
+		dialog.openDialog(buildAddJoinColumnPostExecution());
+	}
+	
+	private PostExecution<JoinColumnInJoiningStrategyDialog> buildAddJoinColumnPostExecution() {
+		return new PostExecution<JoinColumnInJoiningStrategyDialog>() {
+			public void execute(JoinColumnInJoiningStrategyDialog dialog) {
+				if (dialog.wasConfirmed()) {
+					addJoinColumn(dialog.getSubject());
+				}
+			}
+		};
+	}
+	
+	private void addJoinColumn(JoinColumnInJoiningStrategyStateObject stateObject) {
+		JoinColumnJoiningStrategy subject = getSubject();
+		int index = subject.specifiedJoinColumnsSize();
+		
+		JoinColumn joinColumn = subject.addSpecifiedJoinColumn(index);
+		stateObject.updateJoinColumn(joinColumn);
+		this.setSelectedJoinColumn(joinColumn);
+	}
+
+	public void setSelectedJoinColumn(JoinColumn joinColumn) {
+		this.joinColumnsComposite.setSelectedJoinColumn(joinColumn);
+	}
+	
+	private void editJoinColumn(JoinColumnJoiningStrategy joiningStrategy, JoinColumn joinColumn) {
+		JoinColumnInJoiningStrategyDialog dialog =
+			new JoinColumnInJoiningStrategyDialog(getShell(), joiningStrategy, joinColumn);
+		dialog.openDialog(buildEditJoinColumnPostExecution());
+	}
+	
+	private PostExecution<JoinColumnInJoiningStrategyDialog> buildEditJoinColumnPostExecution() {
+		return new PostExecution<JoinColumnInJoiningStrategyDialog>() {
+			public void execute(JoinColumnInJoiningStrategyDialog dialog) {
+				if (dialog.wasConfirmed()) {
+					updateJoinColumn(dialog.getSubject());
+				}
+			}
+		};
+	}
+	
+	private void updateJoinColumn(JoinColumnInJoiningStrategyStateObject stateObject) {
+		stateObject.updateJoinColumn(stateObject.getJoinColumn());
+	}
+	
+	protected CachingTransformationPropertyValueModel<JoinColumnJoiningStrategy, Boolean> buildJoinColumnsPaneEnabledHolder() {
+		return new CachingTransformationPropertyValueModel<JoinColumnJoiningStrategy, Boolean>(
+			new ValueListAdapter<JoinColumnJoiningStrategy>(
+				new ReadOnlyWritablePropertyValueModelWrapper<JoinColumnJoiningStrategy>(getSubjectHolder()), 
+				JoinColumnJoiningStrategy.SPECIFIED_JOIN_COLUMNS_LIST)) {
+			
+			@Override
+			protected Boolean transform(JoinColumnJoiningStrategy value) {
+				if (value == null) {
+					return Boolean.FALSE;
+				}
+				return super.transform(value);
+			}
+			
+			@Override
+			protected Boolean transform_(JoinColumnJoiningStrategy value) {
+				boolean virtual = value.getRelationshipReference().getRelationshipMapping().getPersistentAttribute().isVirtual();
+				return Boolean.valueOf(! virtual && value.specifiedJoinColumnsSize() > 0);
+			}
+		};
+
+	}
+	
+	
+	private class JoinColumnPaneEnablerHolder 
+		extends CachingTransformationPropertyValueModel<JoinColumnJoiningStrategy, Boolean>
+	{
+		private StateChangeListener stateChangeListener;
+		
+		
+		public JoinColumnPaneEnablerHolder() {
+			super(
+				new ValueListAdapter<JoinColumnJoiningStrategy>(
+					new ReadOnlyWritablePropertyValueModelWrapper<JoinColumnJoiningStrategy>(getSubjectHolder()), 
+					JoinColumnJoiningStrategy.SPECIFIED_JOIN_COLUMNS_LIST));
+			this.stateChangeListener = buildStateChangeListener();
+		}
+		
+		
+		private StateChangeListener buildStateChangeListener() {
+			return new StateChangeListener() {
+				public void stateChanged(StateChangeEvent event) {
+					valueStateChanged(event);
+				}
+			};
+		}
+		
+		private void valueStateChanged(StateChangeEvent event) {
+			Object oldValue = this.cachedValue;
+			Object newValue = transformNew(this.valueHolder.getValue());
+			firePropertyChanged(VALUE, oldValue, newValue);
+		}
+		
+		@Override
+		protected Boolean transform(JoinColumnJoiningStrategy value) {
+			if (value == null) {
+				return Boolean.FALSE;
+			}
+			return super.transform(value);
+		}
+		
+		@Override
+		protected Boolean transform_(JoinColumnJoiningStrategy value) {
+			boolean virtual = value.getRelationshipReference().isParentVirtual();
+			return Boolean.valueOf(! virtual && value.specifiedJoinColumnsSize() > 0);
+		}
+		
+		@Override
+		protected void engageModel() {
+			super.engageModel();
+			this.valueHolder.addStateChangeListener(this.stateChangeListener);
+		}
+		
+		@Override
+		protected void disengageModel() {
+			this.valueHolder.removeStateChangeListener(this.stateChangeListener);
+			super.disengageModel();
+		}
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/JoiningStrategyJoinColumnsWithOverrideOptionComposite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/JoiningStrategyJoinColumnsWithOverrideOptionComposite.java
new file mode 100644
index 0000000..41775fa
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/JoiningStrategyJoinColumnsWithOverrideOptionComposite.java
@@ -0,0 +1,149 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2010 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.ui.internal.details;
+
+import java.util.ListIterator;
+
+import org.eclipse.jpt.core.context.JoinColumn;
+import org.eclipse.jpt.core.context.JoinColumnJoiningStrategy;
+import org.eclipse.jpt.ui.internal.widgets.Pane;
+import org.eclipse.jpt.utility.internal.model.value.ListAspectAdapter;
+import org.eclipse.jpt.utility.internal.model.value.ListPropertyValueModelAdapter;
+import org.eclipse.jpt.utility.model.value.ListValueModel;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.jpt.utility.model.value.WritablePropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * Here is the layout of this pane:
+ * <pre>
+ * -------------------------------------------------------------------------
+ * x Override Default                                                    
+ * ---------------------------------------------------------------------
+ * |                                                                   |
+ * | JoiningStrategyJoinColumnsComposite                               |
+ * |                                                                   |
+ * ---------------------------------------------------------------------
+ * -------------------------------------------------------------------------</pre>
+ *
+ * @see JoinColumnEnabledRelationshipReference
+ * @see JoinColumnJoiningStrategy
+ * @see JoinColumnJoiningStrategyPane
+ * @see JoinColumnInJoiningStrategyDialog
+ *
+ * @version 3.0
+ * @since 2.0
+ */
+public class JoiningStrategyJoinColumnsWithOverrideOptionComposite 
+	extends Pane<JoinColumnJoiningStrategy>
+{
+	
+	private JoiningStrategyJoinColumnsComposite joiningStrategyComposite;
+	
+	public JoiningStrategyJoinColumnsWithOverrideOptionComposite(
+			Pane<?> parentPane,
+			PropertyValueModel<JoinColumnJoiningStrategy> subjectHolder,
+			Composite parent) {
+		super(parentPane, subjectHolder, parent);
+	}
+
+
+	@Override
+	protected void initializeLayout(Composite container) {
+		// Override Default Join Columns check box
+		addCheckBox(
+			addSubPane(container, 8),
+			JptUiDetailsMessages.JoiningStrategyJoinColumnsComposite_overrideDefaultJoinColumns,
+			buildOverrideDefaultJoinColumnHolder(),
+			null
+		);
+		
+		this.joiningStrategyComposite = new JoiningStrategyJoinColumnsComposite(this, getSubjectHolder(), container);
+	}
+
+	private void setSelectedJoinColumn(JoinColumn joinColumn) {
+		this.joiningStrategyComposite.setSelectedJoinColumn(joinColumn);
+	}
+
+	private WritablePropertyValueModel<Boolean> buildOverrideDefaultJoinColumnHolder() {
+		return new OverrideDefaultJoinColumnHolder();
+	}
+	
+	private ListValueModel<JoinColumn> buildSpecifiedJoinColumnsListHolder() {
+		return new ListAspectAdapter<JoinColumnJoiningStrategy, JoinColumn>(
+				getSubjectHolder(), JoinColumnJoiningStrategy.SPECIFIED_JOIN_COLUMNS_LIST) {
+			@Override
+			protected ListIterator<JoinColumn> listIterator_() {
+				return this.subject.specifiedJoinColumns();
+			}
+
+			@Override
+			protected int size_() {
+				return this.subject.specifiedJoinColumnsSize();
+			}
+		};
+	}
+	
+	private class OverrideDefaultJoinColumnHolder 
+		extends ListPropertyValueModelAdapter<Boolean>
+		implements WritablePropertyValueModel<Boolean> 
+	{
+		public OverrideDefaultJoinColumnHolder() {
+			super(buildSpecifiedJoinColumnsListHolder());
+		}
+		
+		@Override
+		protected Boolean buildValue() {
+			return Boolean.valueOf(this.listHolder.size() > 0);
+		}
+		
+		public void setValue(Boolean value) {
+			updateJoinColumns(value.booleanValue());
+		}
+		
+		private void updateJoinColumns(boolean selected) {
+			if (isPopulating()) {
+				return;
+			}
+			
+			setPopulating(true);
+			
+			try {
+				JoinColumnJoiningStrategy subject = getSubject();
+	
+				// Add a join column by creating a specified one using the default
+				// one if it exists
+				if (selected) {
+					JoinColumn defaultJoinColumn = subject.getDefaultJoinColumn();//TODO could be null, disable override default check box?
+					
+					if (defaultJoinColumn != null) {
+						String columnName = defaultJoinColumn.getDefaultName();
+						String referencedColumnName = defaultJoinColumn.getDefaultReferencedColumnName();
+						
+						JoinColumn joinColumn = subject.addSpecifiedJoinColumn(0);
+						joinColumn.setSpecifiedName(columnName);
+						joinColumn.setSpecifiedReferencedColumnName(referencedColumnName);
+						
+						JoiningStrategyJoinColumnsWithOverrideOptionComposite.this.setSelectedJoinColumn(joinColumn);
+					}
+				}
+				// Remove all the specified join columns
+				else {
+					for (int index = subject.specifiedJoinColumnsSize(); --index >= 0; ) {
+						subject.removeSpecifiedJoinColumn(index);
+					}
+				}
+			}
+			finally {
+				setPopulating(false);
+			}
+		}
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/JptUiDetailsMessages.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/JptUiDetailsMessages.java
new file mode 100644
index 0000000..59f357d
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/JptUiDetailsMessages.java
@@ -0,0 +1,309 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2010 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.ui.internal.details;
+
+import org.eclipse.osgi.util.NLS;
+
+/**
+ * Localized messages used by Dali mapping panes.
+ *
+ * @version 2.3
+ * @since 1.0
+ */
+public class JptUiDetailsMessages {
+
+	public static String AccessTypeCombo_default;
+	public static String AddQueryDialog_name;
+	public static String AddQueryDialog_queryType;
+ 	public static String AddQueryDialog_title;
+	public static String AddQueryDialog_descriptionTitle;
+	public static String AddQueryDialog_description;
+	public static String AddQueryDialog_namedQuery;
+	public static String AddQueryDialog_namedNativeQuery;
+	public static String QueryStateObject_nameMustBeSpecified;
+	public static String QueryStateObject_typeMustBeSpecified;
+	public static String NamedQueryComposite_nameTextLabel;
+
+	public static String OverridesComposite_attributeOverridesGroup;
+	public static String OverridesComposite_attributeOverridesSection;
+	public static String OverridesComposite_overrideDefault;
+	
+	public static String BasicSection_title;
+	public static String EmbeddableSection_title;
+	public static String EmbeddedSection_title;
+	public static String EmbeddedIdSection_title;
+	public static String EntitySection_title;
+	public static String IdSection_title;
+	public static String ManyToManySection_title;
+	public static String ManyToOneSection_title;
+	public static String MappedSuperclassSection_title;
+	public static String OneToManySection_title;
+	public static String OneToOneSection_title;
+	public static String VersionSection_title;
+	
+	public static String BasicGeneralSection_enumeratedLabel;
+	public static String BasicGeneralSection_fetchLabel;
+	public static String BasicGeneralSection_lobLabel;
+	public static String BasicGeneralSection_name;
+	public static String BasicGeneralSection_nameDefault;
+	public static String BasicGeneralSection_optionalLabel;
+	public static String BasicGeneralSection_optionalLabelDefault;
+	public static String BasicGeneralSection_temporalLabel;
+	public static String TypeSection_type;
+	public static String TypeSection_default;
+	public static String TypeSection_lob;
+	public static String TypeSection_temporal;
+	public static String TypeSection_enumerated;
+	public static String Boolean_False;
+	public static String Boolean_True;
+	public static String CascadeComposite_all;
+	public static String CascadeComposite_cascadeTitle;
+	public static String CascadeComposite_merge;
+	public static String CascadeComposite_persist;
+	public static String CascadeComposite_refresh;
+	public static String CascadeComposite_remove;
+	public static String CatalogChooser_label;
+	public static String ColumnComposite_columnDefinition;
+	public static String ColumnComposite_columnSection;
+	public static String ColumnComposite_details;
+	public static String ColumnComposite_insertable;
+	public static String ColumnComposite_insertableWithDefault;
+	public static String ColumnComposite_length;
+	public static String ColumnComposite_name;
+	public static String ColumnComposite_nullable;
+	public static String ColumnComposite_nullableWithDefault;
+	public static String ColumnComposite_precision;
+	public static String ColumnComposite_scale;
+	public static String ColumnComposite_table;
+	public static String ColumnComposite_unique;
+	public static String ColumnComposite_uniqueWithDefault;
+	public static String ColumnComposite_updatable;
+	public static String ColumnComposite_updatableWithDefault;
+	public static String DefaultEmpty;
+	public static String DefaultWithOneParam;
+	public static String ProviderDefault;
+	public static String DiscriminatorColumnComposite_discriminatorType;
+	public static String DiscriminatorColumnComposite_name;
+	public static String DiscriminatorColumnComposite_char;
+	public static String DiscriminatorColumnComposite_integer;
+	public static String DiscriminatorColumnComposite_string;
+	public static String EntityComposite_inheritance;
+	public static String EntityComposite_queries;
+	public static String EntityComposite_tableDefault;
+	public static String EntityComposite_tableNoDefaultSpecified;
+	public static String EntityGeneralSection_name;
+	public static String EntityNameComposite_name;
+	public static String EnumTypeComposite_ordinal;
+	public static String EnumTypeComposite_string;
+	public static String FetchTypeComposite_eager;
+	public static String FetchTypeComposite_lazy;
+	public static String GeneratedValueComposite_auto;
+	public static String GeneratedValueComposite_generatedValue;
+	public static String GeneratedValueComposite_generatorName;
+	public static String GeneratedValueComposite_identity;
+	public static String GeneratedValueComposite_sequence;
+	public static String GeneratedValueComposite_strategy;
+	public static String GeneratedValueComposite_table;
+	public static String GeneratorComposite_allocationSize;
+	public static String GeneratorComposite_initialValue;
+	public static String GeneratorsComposite_sequenceGeneratorCheckBox;
+	public static String GeneratorsComposite_sequenceGeneratorSection;
+	public static String GeneratorsComposite_tableGeneratorCheckBox;
+	public static String GeneratorsComposite_tableGeneratorSection;
+	public static String IdClassComposite_label;
+	public static String IdMappingComposite_pk_generation;
+	public static String IdMappingComposite_primaryKeyGenerationCheckBox;
+	public static String IdMappingComposite_primaryKeyGenerationSection;
+	public static String IdMappingComposite_sequenceGeneratorCheckBox;
+	public static String IdMappingComposite_sequenceGeneratorSection;
+	public static String IdMappingComposite_tableGeneratorCheckBox;
+	public static String IdMappingComposite_tableGeneratorSection;
+	public static String InheritanceComposite_detailsGroupBox;
+	public static String InheritanceComposite_discriminatorColumnGroupBox;
+	public static String InheritanceComposite_discriminatorValue;
+	public static String AbstractInheritanceComposite_joined;
+	public static String AbstractInheritanceComposite_single_table;
+	public static String InheritanceComposite_strategy;
+	public static String AbstractInheritanceComposite_table_per_class;
+	public static String InverseJoinColumnDialog_editInverseJoinColumnTitle;
+	public static String Joining_title;
+	public static String Joining_mappedByLabel;
+	public static String Joining_mappedByAttributeLabel;
+	public static String Joining_joinColumnJoiningLabel;
+	public static String Joining_primaryKeyJoinColumnJoiningLabel;
+	public static String Joining_joinTableJoiningLabel;
+	public static String JoinColumnsComposite_edit;
+	public static String JoinColumnsComposite_mappingBetweenTwoParams;
+	public static String JoinColumnsComposite_mappingBetweenTwoParamsBothDefault;
+	public static String JoinColumnsComposite_mappingBetweenTwoParamsDefault;
+	public static String JoinColumnsComposite_mappingBetweenTwoParamsFirstDefault;
+	public static String JoinColumnsComposite_mappingBetweenTwoParamsSecDefault;
+	public static String JoiningStrategyJoinColumnsComposite_overrideDefaultJoinColumns;
+	public static String JoinColumnDialog_addJoinColumnDescriptionTitle;
+	public static String JoinColumnDialog_addJoinColumnTitle;
+	public static String JoinColumnDialog_description;
+	public static String JoinColumnDialog_editJoinColumnDescriptionTitle;
+	public static String JoinColumnDialog_editJoinColumnTitle;
+	public static String JoinColumnDialog_name;
+	public static String JoinColumnDialog_referencedColumnName;
+	public static String JoinColumnDialogPane_columnDefinition;
+	public static String JoinColumnDialogPane_insertable;
+	public static String JoinColumnDialogPane_insertableWithDefault;
+	public static String JoinColumnDialogPane_nullable;
+	public static String JoinColumnDialogPane_nullableWithDefault;
+	public static String JoinColumnDialogPane_table;
+	public static String JoinColumnDialogPane_unique;
+	public static String JoinColumnDialogPane_uniqueWithDefault;
+	public static String JoinColumnDialogPane_updatable;
+	public static String JoinColumnDialogPane_updatableWithDefault;
+	public static String JoinTableComposite_inverseJoinColumn;
+	public static String JoinTableComposite_joinColumn;
+	public static String JoinTableComposite_name;
+	public static String JoinTableComposite_schema;
+	public static String JoinTableComposite_catalog;
+	public static String JoinTableComposite_overrideDefaultInverseJoinColumns;
+	public static String JoinTableComposite_overrideDefaultJoinColumns;
+	
+	public static String DefaultBasicMappingUiProvider_label;
+	public static String DefaultEmbeddedMappingUiProvider_label;
+	public static String BasicMappingUiProvider_label;
+	public static String EmbeddedIdMappingUiProvider_label;
+	public static String EmbeddedMappingUiProvider_label;
+	public static String IdMappingUiProvider_label;
+	public static String ManyToManyMappingUiProvider_label;
+	public static String ManyToOneMappingUiProvider_label;
+	public static String OneToManyMappingUiProvider_label;
+	public static String OneToOneMappingUiProvider_label;
+	public static String TransientMappingUiProvider_label;
+	public static String VersionMappingUiProvider_label;
+	public static String DefaultBasicMappingUiProvider_linkLabel;
+	public static String DefaultEmbeddedMappingUiProvider_linkLabel;
+	public static String BasicMappingUiProvider_linkLabel;
+	public static String EmbeddedIdMappingUiProvider_linkLabel;
+	public static String EmbeddedMappingUiProvider_linkLabel;
+	public static String IdMappingUiProvider_linkLabel;
+	public static String ManyToManyMappingUiProvider_linkLabel;
+	public static String ManyToOneMappingUiProvider_linkLabel;
+	public static String OneToManyMappingUiProvider_linkLabel;
+	public static String OneToOneMappingUiProvider_linkLabel;
+	public static String TransientMappingUiProvider_linkLabel;
+	public static String VersionMappingUiProvider_linkLabel;
+
+	public static String MapAsComposite_changeMappingType;
+	public static String MapAsComposite_default;
+	public static String MapAsComposite_dialogTitle;
+	public static String MapAsComposite_labelText;
+	public static String MapAsComposite_mappedAttributeText;
+	public static String MapAsComposite_mappedTypeText;
+	public static String MapAsComposite_unmappedAttributeText;
+	public static String MapAsComposite_unmappedTypeText;
+	public static String MapAsComposite_virtualAttributeText;
+	
+	public static String EmbeddableUiProvider_label;
+	public static String EntityUiProvider_label;
+	public static String MappedSuperclassUiProvider_label;
+	public static String EmbeddableUiProvider_linkLabel;
+	public static String EntityUiProvider_linkLabel;
+	public static String MappedSuperclassUiProvider_linkLabel;
+
+	public static String NullTypeMappingUiProvider_label;
+	
+	public static String MetaDataCompleteCombo_Default;
+	public static String MultiRelationshipMappingComposite_cascadeType;
+	public static String MultiRelationshipMappingComposite_fetchType;
+	public static String MultiRelationshipMappingComposite_general;
+	public static String MultiRelationshipMappingComposite_joinTable;
+	public static String MultiRelationshipMappingComposite_mappedBy;
+	public static String MultiRelationshipMappingComposite_targetEntity;
+	public static String NamedNativeQueryPropertyComposite_query;
+	public static String NamedNativeQueryPropertyComposite_queryHintsGroupBox;
+	public static String NamedNativeQueryPropertyComposite_resultClass;
+	public static String NamedQueryPropertyComposite_query;
+	public static String NamedQueryPropertyComposite_queryHintsGroupBox;
+	public static String NewNameStateObject_nameAlreadyExists;
+	public static String NewNameStateObject_nameMustBeSpecified;
+	public static String NoNameSet;
+	public static String NoneSelected;
+	public static String NullAttributeMappingUiProvider_label;
+	public static String OptionalComposite_false;
+	public static String OptionalComposite_true;
+	public static String OrderingComposite_custom;
+	public static String OrderingComposite_none;
+	public static String OrderingComposite_orderingGroup;
+	public static String OrderingComposite_primaryKey;
+	public static String OrmSecondaryTablesComposite_defineInXml;
+	public static String OverridesComposite_association;
+	public static String OverridesComposite_attribute;
+	public static String AssociationOverridesComposite_joinColumn;
+	public static String OverridesComposite_noName;
+	public static String PrimaryKeyJoinColumnDialog_addDescriptionTitle;
+	public static String PrimaryKeyJoinColumnDialog_addTitle;
+	public static String PrimaryKeyJoinColumnDialog_editDescriptionTitle;
+	public static String PrimaryKeyJoinColumnDialog_editTitle;
+	public static String PrimaryKeyJoinColumnInSecondaryTableDialog_addDescriptionTitle;
+	public static String PrimaryKeyJoinColumnInSecondaryTableDialog_addTitle;
+	public static String PrimaryKeyJoinColumnInSecondaryTableDialog_editDescriptionTitle;
+	public static String PrimaryKeyJoinColumnInSecondaryTableDialog_editTitle;
+	public static String PrimaryKeyJoinColumnsComposite_edit;
+	public static String PrimaryKeyJoinColumnsComposite_mappingBetweenTwoParams;
+	public static String PrimaryKeyJoinColumnsComposite_mappingBetweenTwoParamsBothDefault;
+	public static String PrimaryKeyJoinColumnsComposite_mappingBetweenTwoParamsDefault;
+	public static String PrimaryKeyJoinColumnsComposite_mappingBetweenTwoParamsFirstDefault;
+	public static String PrimaryKeyJoinColumnsComposite_mappingBetweenTwoParamsSecDefault;
+	public static String PrimaryKeyJoinColumnsComposite_overrideDefaultPrimaryKeyJoinColumns;
+	public static String PrimaryKeyJoinColumnsComposite_primaryKeyJoinColumn;
+	public static String QueriesComposite_displayString;
+	public static String QueryHintsComposite_nameColumn;
+	public static String QueryHintsComposite_valueColumn;
+	public static String SchemaChooser_label;
+	public static String SecondaryTableDialog_addSecondaryTable;
+	public static String SecondaryTableDialog_catalog;
+	public static String SecondaryTableDialog_defaultCatalog;
+	public static String SecondaryTableDialog_defaultSchema;
+	public static String SecondaryTableDialog_editSecondaryTable;
+	public static String SecondaryTableDialog_name;
+	public static String SecondaryTableDialog_schema;
+	public static String SecondaryTablesComposite_edit;
+	public static String SecondaryTablesComposite_secondaryTables;
+	public static String SequenceGeneratorComposite_catalog;
+	public static String SequenceGeneratorComposite_default;
+	public static String SequenceGeneratorComposite_name;
+	public static String SequenceGeneratorComposite_schema;
+	public static String SequenceGeneratorComposite_sequence;
+	public static String SequenceGeneratorComposite_sequenceGenerator;
+	public static String TableChooser_label;
+	public static String TableComposite_tableSection;
+	public static String TableGeneratorComposite_catalog;
+	public static String TableGeneratorComposite_default;
+	public static String TableGeneratorComposite_name;
+	public static String TableGeneratorComposite_pkColumn;
+	public static String TableGeneratorComposite_pkColumnValue;
+	public static String TableGeneratorComposite_schema;
+	public static String TableGeneratorComposite_table;
+	public static String TableGeneratorComposite_tableGenerator;
+	public static String TableGeneratorComposite_valueColumn;
+	public static String TargetEntityChooser_browse;
+	public static String TargetEntityChooser_label;
+	public static String TargetEntityChooser_selectTypeTitle;
+	public static String TemporalTypeComposite_date;
+	public static String TemporalTypeComposite_time;
+	public static String TemporalTypeComposite_timestamp;
+
+	private static final String BUNDLE_NAME = "jpt_ui_details"; //$NON-NLS-1$
+	private static final Class<?> BUNDLE_CLASS = JptUiDetailsMessages.class;
+	static {
+		NLS.initializeMessages(BUNDLE_NAME, BUNDLE_CLASS);
+	}
+
+	private JptUiDetailsMessages() {
+		throw new UnsupportedOperationException();
+	}
+
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/ManyToManyJoiningStrategyPane.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/ManyToManyJoiningStrategyPane.java
new file mode 100644
index 0000000..6896630
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/ManyToManyJoiningStrategyPane.java
@@ -0,0 +1,124 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2010 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.ui.internal.details;
+
+import org.eclipse.jpt.core.context.JoinTableEnabledRelationshipReference;
+import org.eclipse.jpt.core.context.ManyToManyRelationshipReference;
+import org.eclipse.jpt.core.context.OwnableRelationshipReference;
+import org.eclipse.jpt.core.context.RelationshipReference;
+import org.eclipse.jpt.ui.internal.widgets.Pane;
+import org.eclipse.jpt.utility.internal.model.value.PropertyAspectAdapter;
+import org.eclipse.jpt.utility.internal.model.value.SimplePropertyValueModel;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.jpt.utility.model.value.WritablePropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * Here is the layout of this pane:  
+ * <pre>
+ * -----------------------------------------------------------------------------
+ * | - Joining Strategy ------------------------------------------------------ |
+ * | |                                                                       | |
+ * | | o MappedByJoiningStrategyPane _______________________________________ | |
+ * | | |                                                                   | | |
+ * | | |                                                                   | | |
+ * | | --------------------------------------------------------------------- | |
+ * | | o JoinTableStrategyPane _____________________________________________ | |
+ * | | |                                                                   | | |
+ * | | |                                                                   | | |
+ * | | --------------------------------------------------------------------- | |
+ * | ------------------------------------------------------------------------- |
+ * -----------------------------------------------------------------------------</pre>
+ *
+ * @see {@link ManyToManyMapping}
+ * @see {@link ManyToManyRelationshipReference}
+ * @see {@link ManyToManyMappingComposite}
+ * @see {@link MappedByStrategyPane}
+ * @see {@link JoinTableStrategyPane}
+ *
+ * @version 2.3
+ * @since 2.1
+ */
+public class ManyToManyJoiningStrategyPane 
+	extends Pane<ManyToManyRelationshipReference>
+{
+	public ManyToManyJoiningStrategyPane(
+			Pane<?> parentPane, 
+			PropertyValueModel<? extends ManyToManyRelationshipReference> subjectHolder, 
+			Composite parent) {
+		
+		super(parentPane, subjectHolder, parent);
+	}
+	
+	
+	@Override
+	protected void initializeLayout(Composite container) {
+		Composite composite = addCollapsibleSection(
+				container,
+				JptUiDetailsMessages.Joining_title,
+				new SimplePropertyValueModel<Boolean>(Boolean.TRUE));
+		
+		addRadioButton(
+			composite,
+			JptUiDetailsMessages.Joining_mappedByLabel,
+			MappedByJoiningStrategyPane.buildUsesMappedByJoiningStrategyHolder(getSubjectHolder()),
+			null);
+
+		new MappedByJoiningStrategyPane(this, composite);
+		
+		addRadioButton(
+			composite,
+			JptUiDetailsMessages.Joining_joinTableJoiningLabel,
+			JoinTableJoiningStrategyPane.buildUsesJoinTableJoiningStrategyHolder(getSubjectHolder()),
+			null);
+
+		new JoinTableJoiningStrategyPane(this, composite);
+		
+		addSubPane(composite, 5);
+	}
+
+	protected WritablePropertyValueModel<Boolean> buildUsesMappedByStrategyHolder() {
+		return new PropertyAspectAdapter<OwnableRelationshipReference, Boolean>(
+				this.getSubjectHolder(), RelationshipReference.PREDOMINANT_JOINING_STRATEGY_PROPERTY) {
+			@Override
+			protected Boolean buildValue() {
+				return (this.subject == null) ? Boolean.FALSE :
+					Boolean.valueOf(this.subject.usesMappedByJoiningStrategy());
+			}
+			
+			@Override
+			protected void setValue_(Boolean value) {
+				if (value == Boolean.TRUE) {
+					this.subject.setMappedByJoiningStrategy();
+				}
+				//value == FALSE - selection of another radio button causes this strategy to get unset
+			}
+		};
+	}
+
+	protected WritablePropertyValueModel<Boolean> buildUsesJoinTableStrategyHolder() {
+		return new PropertyAspectAdapter<JoinTableEnabledRelationshipReference, Boolean>(
+				this.getSubjectHolder(), RelationshipReference.PREDOMINANT_JOINING_STRATEGY_PROPERTY) {
+			@Override
+			protected Boolean buildValue() {
+				return (this.subject == null) ? Boolean.FALSE :
+					Boolean.valueOf(this.subject.usesJoinTableJoiningStrategy());
+			}
+			
+			@Override
+			protected void setValue_(Boolean value) {
+				if (value == Boolean.TRUE) {
+					this.subject.setJoinTableJoiningStrategy();
+				}
+				//value == FALSE - selection of another radio button causes this strategy to get unset
+			}
+		};
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/ManyToManyMappingComposite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/ManyToManyMappingComposite.java
new file mode 100644
index 0000000..b4d4edd
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/ManyToManyMappingComposite.java
@@ -0,0 +1,83 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2010 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.ui.internal.details;
+
+import org.eclipse.jpt.core.context.ManyToManyMapping;
+import org.eclipse.jpt.core.context.ManyToManyRelationshipReference;
+import org.eclipse.jpt.ui.WidgetFactory;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * Here the layout of this pane:
+ * <pre>
+ * -----------------------------------------------------------------------------
+ * | ------------------------------------------------------------------------- |
+ * | |                                                                       | |
+ * | | TargetEntityComposite                                                 | |
+ * | |                                                                       | |
+ * | ------------------------------------------------------------------------- |
+ * | ------------------------------------------------------------------------- |
+ * | |                                                                       | |
+ * | | JoiningStrategyComposite                                              | |
+ * | |                                                                       | |
+ * | ------------------------------------------------------------------------- |
+ * | ------------------------------------------------------------------------- |
+ * | |                                                                       | |
+ * | | FetchTypeComposite                                                    | |
+ * | |                                                                       | |
+ * | ------------------------------------------------------------------------- |
+ * | ------------------------------------------------------------------------- |
+ * | |                                                                       | |
+ * | | CascadeComposite                                                      | |
+ * | |                                                                       | |
+ * | ------------------------------------------------------------------------- |
+ * | ------------------------------------------------------------------------- |
+ * | |                                                                       | |
+ * | | OrderingComposite                                                     | |
+ * | |                                                                       | |
+ * | ------------------------------------------------------------------------- |
+ * -----------------------------------------------------------------------------</pre>
+ *
+ * @see {@link ManyToManyMapping}
+ * @see {@link TargetEntityComposite}
+ * @see {@link ManyToManyJoiningStrategyPane}
+ * @see {@link FetchTypeComposite}
+ * @see {@link CascadeComposite}
+ * @see {@link OrderingComposite}
+ *
+ * @version 2.3
+ * @since 1.0
+ */
+public class ManyToManyMappingComposite 
+	extends AbstractManyToManyMappingComposite<ManyToManyMapping, ManyToManyRelationshipReference>
+{
+	/**
+	 * Creates a new <code>ManyToManyMappingComposite</code>.
+	 *
+	 * @param subjectHolder The holder of the subject <code>IManyToManyMapping</code>
+	 * @param parent The parent container
+	 * @param widgetFactory The factory used to create various common widgets
+	 */
+	public ManyToManyMappingComposite(PropertyValueModel<? extends ManyToManyMapping> subjectHolder,
+	                                  Composite parent,
+	                                  WidgetFactory widgetFactory) {
+
+		super(subjectHolder, parent, widgetFactory);
+	}
+
+	@Override
+	protected void initializeManyToManySection(Composite container) {
+		new TargetEntityComposite(this, container);
+		new FetchTypeComposite(this, container);
+		new CascadeComposite(this, buildCascadeHolder(), addSubPane(container, 5));
+	}
+
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/ManyToOneJoiningStrategyPane.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/ManyToOneJoiningStrategyPane.java
new file mode 100644
index 0000000..c9a0146
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/ManyToOneJoiningStrategyPane.java
@@ -0,0 +1,68 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2010 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.ui.internal.details;
+
+import org.eclipse.jpt.core.context.ManyToOneRelationshipReference;
+import org.eclipse.jpt.ui.internal.widgets.Pane;
+import org.eclipse.jpt.utility.internal.model.value.SimplePropertyValueModel;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * Here is the layout of this pane:  
+ * <pre>
+ * -----------------------------------------------------------------------------
+ * | - Joining Strategy ------------------------------------------------------ |
+ * | |                                                                       | |
+ * | | o JoinColumnStrategyPane ____________________________________________ | |
+ * | | |                                                                   | | |
+ * | | |                                                                   | | |
+ * | | --------------------------------------------------------------------- | |
+ * | ------------------------------------------------------------------------- |
+ * -----------------------------------------------------------------------------</pre>
+ *
+ * @see {@link ManyToOneMapping}
+ * @see {@link ManyToOneRelationshipReference}
+ * @see {@link ManyToOneMappingComposite}
+ * @see {@link JoinColumnStrategyPane}
+ *
+ * @version 2.3
+ * @since 2.1
+ */
+public class ManyToOneJoiningStrategyPane extends Pane<ManyToOneRelationshipReference>
+{
+	public ManyToOneJoiningStrategyPane(
+			Pane<?> parentPane, 
+			PropertyValueModel<? extends ManyToOneRelationshipReference> subjectHolder, 
+			Composite parent) {
+		
+		super(parentPane, subjectHolder, parent);
+	}
+	
+	
+	@Override
+	protected void initializeLayout(Composite container) {
+		Composite composite = addCollapsibleSection(
+				container,
+				JptUiDetailsMessages.Joining_title,
+				new SimplePropertyValueModel<Boolean>(Boolean.TRUE));
+		
+		addRadioButton(
+			composite,
+			JptUiDetailsMessages.Joining_joinColumnJoiningLabel,
+			JoinColumnJoiningStrategyPane.buildUsesJoinColumnJoiningStrategyHolder(getSubjectHolder()),
+			null);
+
+		JoinColumnJoiningStrategyPane.
+			buildJoinColumnJoiningStrategyPaneWithIncludeOverrideCheckBox(this, composite);
+		
+		addSubPane(composite, 5);
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/ManyToOneMappingComposite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/ManyToOneMappingComposite.java
new file mode 100644
index 0000000..60cfcb9
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/ManyToOneMappingComposite.java
@@ -0,0 +1,84 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2010 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.ui.internal.details;
+
+import org.eclipse.jpt.core.context.ManyToOneMapping;
+import org.eclipse.jpt.core.context.ManyToOneRelationshipReference;
+import org.eclipse.jpt.ui.WidgetFactory;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * Here the layout of this pane:
+ * <pre>
+ * -----------------------------------------------------------------------------
+ * | ------------------------------------------------------------------------- |
+ * | |                                                                       | |
+ * | | TargetEntityComposite                                                 | |
+ * | |                                                                       | |
+ * | ------------------------------------------------------------------------- |
+ * | ------------------------------------------------------------------------- |
+ * | |                                                                       | |
+ * | | JoiningStrategyComposite                                              | |
+ * | |                                                                       | |
+ * | ------------------------------------------------------------------------- |
+ * | ------------------------------------------------------------------------- |
+ * | |                                                                       | |
+ * | | FetchTypeComposite                                                    | |
+ * | |                                                                       | |
+ * | ------------------------------------------------------------------------- |
+ * | ------------------------------------------------------------------------- |
+ * | |                                                                       | |
+ * | | OptionalComposite                                                     | |
+ * | |                                                                       | |
+ * | ------------------------------------------------------------------------- |
+ * | ------------------------------------------------------------------------- |
+ * | |                                                                       | |
+ * | | CascadeComposite                                                      | |
+ * | |                                                                       | |
+ * | ------------------------------------------------------------------------- |
+ * -----------------------------------------------------------------------------</pre>
+ *
+ * @see {@link ManyToOneMapping}
+ * @see {@link TargetEntityComposite}
+ * @see {@link ManyToOneJoiningStrategyPane}
+ * @see {@link FetchTypeComposite}
+ * @see {@link OptionalComposite}
+ * @see {@link CascadeComposite}
+ *
+ * @version 2.3
+ * @since 1.0
+ */
+public class ManyToOneMappingComposite 
+	extends AbstractManyToOneMappingComposite<ManyToOneMapping, ManyToOneRelationshipReference>
+{
+	/**
+	 * Creates a new <code>ManyToOneMappingComposite</code>.
+	 *
+	 * @param subjectHolder The holder of the subject <code>IManyToOneMapping</code>
+	 * @param parent The parent container
+	 * @param widgetFactory The factory used to create various common widgets
+	 */
+	public ManyToOneMappingComposite(PropertyValueModel<? extends ManyToOneMapping> subjectHolder,
+	                                 Composite parent,
+	                                 WidgetFactory widgetFactory) {
+
+		super(subjectHolder, parent, widgetFactory);
+	}
+
+	@Override
+	protected void initializeManyToOneSection(Composite container) {
+		new TargetEntityComposite(this, container);
+		new FetchTypeComposite(this, container);
+		new OptionalComposite(this, container);
+		new CascadeComposite(this, buildCascadeHolder(),  addSubPane(container, 5));
+	}
+
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/MapAsComposite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/MapAsComposite.java
new file mode 100644
index 0000000..21a83ec
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/MapAsComposite.java
@@ -0,0 +1,638 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2010 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.ui.internal.details;
+
+import java.util.Comparator;
+import java.util.Iterator;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.dialogs.IDialogSettings;
+import org.eclipse.jface.resource.JFaceColors;
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.jpt.core.JpaNode;
+import org.eclipse.jpt.ui.JpaPlatformUi;
+import org.eclipse.jpt.ui.JptUiPlugin;
+import org.eclipse.jpt.ui.details.DefaultMappingUiDefinition;
+import org.eclipse.jpt.ui.details.MappingUiDefinition;
+import org.eclipse.jpt.ui.internal.platform.JpaPlatformUiRegistry;
+import org.eclipse.jpt.ui.internal.util.SWTUtil;
+import org.eclipse.jpt.ui.internal.widgets.Pane;
+import org.eclipse.jpt.ui.internal.widgets.PostExecution;
+import org.eclipse.jpt.utility.internal.CollectionTools;
+import org.eclipse.jpt.utility.internal.StringTools;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.StyleRange;
+import org.eclipse.swt.custom.StyledText;
+import org.eclipse.swt.events.MouseEvent;
+import org.eclipse.swt.events.MouseListener;
+import org.eclipse.swt.events.MouseMoveListener;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Cursor;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.ui.dialogs.FilteredItemsSelectionDialog;
+import com.ibm.icu.text.Collator;
+
+/**
+ * This map as composite simply shows a styled text where the name of the
+ * mapping and its type are displayed. The mapping type can be clicked on to
+ * invoke a dialog in order to change the type.
+ * <p>
+ * Here the layout of this pane:
+ * <pre>
+ * -----------------------------------------------------------------------------
+ * |                                                                           |
+ * | Attribute 'name' is mapped as one to one.                                 |
+ * |                               ¯¯¯¯¯¯¯¯¯¯                                  |
+ * -----------------------------------------------------------------------------</pre>
+ *
+ * @version 2.0
+ * @since 2.0
+ */
+@SuppressWarnings("nls")
+public abstract class MapAsComposite<T extends JpaNode> extends Pane<T> {
+
+	protected boolean dragEvent;
+	protected boolean enabled;
+	protected Cursor handCursor;
+	protected MappingChangeHandler<T> mappingChangeHandler;
+	protected int mappingTypeLength;
+	protected int mappingTypeStart;
+	protected boolean mouseDown;
+	protected int nameLength;
+	protected int nameStart;
+	protected StyledText styledText;
+
+	/**
+	 * The constant ID used to retrieve the dialog settings.
+	 */
+	private static final String DIALOG_SETTINGS = "org.eclipse.jpt.ui.dialogs.MapAsDialog";
+
+	/**
+	 * Creates a new <code>MapAsComposite</code>.
+	 *
+	 * @param parentPane The parent pane of this one
+	 * @param parent The parent container
+	 */
+	public MapAsComposite(Pane<? extends T> parentPane,
+	                      Composite parent) {
+
+		super(parentPane, parent);
+	}
+	
+	/**
+	 * Returns the JPT platform responsble to manage the user interface part of
+	 * the JPT plug-in.
+	 *
+	 * @return The UI platform of the JPT plug-in
+	 */
+	protected JpaPlatformUi getJpaPlatformUi() {
+		String platformId = getSubject().getJpaProject().getJpaPlatform().getId();
+		return JpaPlatformUiRegistry.instance().getJpaPlatformUi(platformId);
+	}
+
+	/**
+	 * Creates the default provider responsible for clearing the mapping type.
+	 * Return null if there is not a default provider
+	 * @return A provider that acts as a default mapping provider
+	 */
+	protected abstract DefaultMappingUiDefinition getDefaultDefinition();
+
+	protected abstract DefaultMappingUiDefinition getDefaultDefinition(String mappingKey);
+	
+	protected MappingUiDefinition getMappingUiDefinition(String mappingKey) {
+		for (MappingUiDefinition<T, ?> provider : CollectionTools.iterable(this.mappingChangeHandler.mappingUiDefinitions())) {
+			if (provider.getKey() == mappingKey) {
+				return provider;
+			}
+		}
+		return null;		
+	}
+	
+	/**
+	 * Creates the handler responsible to give the information required for
+	 * completing the behavior of this pane.
+	 *
+	 * @return A new <code>MappingChangeHandler</code>
+	 */
+	protected abstract MappingChangeHandler buildMappingChangeHandler();
+	
+	private MouseListener buildMouseListener() {
+		return new MouseListener() {
+			public void mouseDoubleClick(MouseEvent e) {
+			}
+			
+			public void mouseDown(MouseEvent e) {
+				if (e.button == 1) {
+					mouseDown = true;
+				}
+			}
+
+			public void mouseUp(MouseEvent e) {
+				mouseDown = false;
+				StyledText text = (StyledText) e.widget;
+				int offset = text.getCaretOffset();
+
+				if (dragEvent) {
+					dragEvent = false;
+
+					if (isOverLink(offset)) {
+						text.setCursor(handCursor);
+					}
+				}
+				else if (isOverLink(offset)) {
+					text.setCursor(handCursor);
+					openMappingSelectionDialog();
+					text.setCursor(null);
+				}
+			}
+		};
+	}
+
+	private MouseMoveListener buildMouseMoveListener() {
+		return new MouseMoveListener() {
+			public void mouseMove(MouseEvent e) {
+				StyledText text = (StyledText) e.widget;
+
+				if (mouseDown) {
+					if (!dragEvent) {
+						text.setCursor(null);
+					}
+
+					dragEvent = true;
+					return;
+				}
+
+				int offset = -1;
+
+				try {
+					offset = text.getOffsetAtLocation(new Point(e.x, e.y));
+				}
+				catch (IllegalArgumentException ex) {
+				}
+
+				if (isOverLink(offset)) {
+					text.setCursor(handCursor);
+				}
+				else {
+					text.setCursor(null);
+				}
+			}
+		};
+	}
+
+	private PostExecution<MappingSelectionDialog> buildPostExecution() {
+
+		return new PostExecution<MappingSelectionDialog>() {
+			public void execute(MappingSelectionDialog dialog) {
+
+				if (dialog.getReturnCode() == IDialogConstants.OK_ID) {
+					MappingUiDefinition definition = (MappingUiDefinition) dialog.getFirstResult();
+					morphMapping(definition);
+				}
+			}
+		};
+	}
+
+	/**
+	 * Creates the full localized string by formatting the label text returned
+	 * by the <code>MappingChangeHandler</code> with the mapping name and the
+	 * mapping type.
+	 *
+	 * @param name The display string of the mapping being edited
+	 * @param mappingType The localized message describing the mapping type
+	 * @return The localized string describing the mapping
+	 */
+	protected String buildText(String name, String mappingType) {
+		return NLS.bind(
+			mappingChangeHandler.getLabelText(),
+			name,
+			mappingType
+		);
+	}
+
+	/**
+	 * Removes any style applied to the styled text.
+	 */
+	protected void clearStyleRange() {
+		styledText.setStyleRange(null);
+	}
+
+	/*
+	 * (non-Javadoc)
+	 */
+	@Override
+	protected void doPopulate() {
+		super.doPopulate();
+		updateDescription();
+	}
+
+	/*
+	 * (non-Javadoc)
+	 */
+	@Override
+	public void enableWidgets(boolean enabled) {
+		this.enabled = enabled;
+		super.enableWidgets(enabled);
+
+		if (!styledText.isDisposed()) {
+			styledText.setEnabled(enabled);
+
+			if (enabled) {
+				updateLinkRange();
+			}
+			else {
+				clearStyleRange();
+			}
+		}
+	}
+
+	/*
+	 * (non-Javadoc)
+	 */
+	@Override
+	protected void initialize() {
+
+		super.initialize();
+
+		this.enabled = true;
+		this.mappingChangeHandler = buildMappingChangeHandler();
+	}
+
+	/*
+	 * (non-Javadoc)
+	 */
+	@Override
+	protected void initializeLayout(Composite container) {
+
+		handCursor = getShell().getDisplay().getSystemCursor(SWT.CURSOR_HAND);
+
+		styledText = new StyledText(container, SWT.WRAP | SWT.READ_ONLY);
+		styledText.addMouseListener(buildMouseListener());
+		styledText.addMouseMoveListener(buildMouseMoveListener());
+		styledText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+	}
+
+	/**
+	 * Retreive the <code>MappingUiDefinition</code> that provides the UI for the
+	 * current mapping.
+	 *
+	 * @return The <code>MappingUiProvider</code> representing the type of the
+	 * mapping being edited
+	 */
+	protected MappingUiDefinition initialSelection() {
+
+		for (Iterator<? extends MappingUiDefinition> iter = this.mappingChangeHandler.mappingUiDefinitions(); iter.hasNext(); ) {
+			MappingUiDefinition definition = iter.next();
+
+			if (getMappingKey() == definition.getKey()) {
+				return definition;
+			}
+		}
+
+		return null;
+	}
+
+	/**
+	 * Determines whether the given location is within the mapping type range.
+	 *
+	 * @param location The mouse location in character coordinate
+	 * @return <code>true</code> if the mouse is over the mapping type text;
+	 * <code>false</code> otherwise
+	 */
+	protected boolean isOverLink(int location) {
+
+		return (location >= mappingTypeStart &&
+		        location <= mappingTypeStart + mappingTypeLength);
+	}
+
+	/**
+	 * Returns the mapping key representing the current mapping object.
+	 *
+	 * @return A non-<code>null</code> unique identifier representing the type
+	 * of the mapping being edited
+	 */
+	protected abstract String getMappingKey();
+
+	/**
+	 * Aks the <code>MappingChangeHandler</code> to change the mapping type using
+	 * the given <code>MappingUiDefinition</code>.
+	 *
+	 * @param provider The provider used to determine the mapping type used for
+	 * morphing the mapping being edited
+	 */
+	protected void morphMapping(MappingUiDefinition definition) {
+		mappingChangeHandler.morphMapping(definition);
+	}
+
+	/**
+	 * Opens the dialog that shows the registered mapping types in order for the
+	 * user to select a provider in order to change the mapping type of the
+	 * mapping being edited.
+	 */
+	protected void openMappingSelectionDialog() {
+
+		MappingSelectionDialog dialog = new MappingSelectionDialog();
+		SWTUtil.show(dialog, buildPostExecution());
+	}
+
+	/**
+	 * Updates the description by recreating the label.
+	 */
+	protected void updateDescription() {
+		if (getSubject() == null) {
+			return;
+		}
+
+		clearStyleRange();
+		updateText();
+
+		if (enabled) {
+			updateLinkRange();
+		}
+	}
+
+	/**
+	 * Updates the colors of the text: (1) the name is shown in bold and (2) the
+	 * mapping type is shown in bold and in hyperlink color.
+	 */
+	protected void updateLinkRange() {
+
+		Color linkColor = JFaceColors.getHyperlinkText(getShell().getDisplay());
+
+		// Make the name bold
+		StyleRange styleRange = new StyleRange(
+			nameStart, nameLength,
+			null, null,
+			SWT.BOLD
+		);
+		styledText.setStyleRange(styleRange);
+
+		// Make the mapping type shown as a hyperlink
+		if (mappingTypeStart > -1) {
+			styleRange = new StyleRange(
+				mappingTypeStart, mappingTypeLength,
+				linkColor, null
+			);
+
+			styleRange.underline      = true;
+			styleRange.underlineColor = linkColor;
+			styleRange.underlineStyle = SWT.UNDERLINE_SINGLE;
+			styledText.setStyleRange(styleRange);
+		}
+	}
+
+	/**
+	 * Updates the styles text's input.
+	 */
+	protected void updateText() {
+
+		String name = mappingChangeHandler.getName();
+
+		if (name == null) {
+			name = JptUiDetailsMessages.NoNameSet;
+		}
+
+		String mappingType = mappingChangeHandler.getMappingText();
+		String text = buildText(name, mappingType);
+
+		mappingTypeStart  = text.lastIndexOf(mappingType);
+		mappingTypeLength = mappingType.length();
+
+		nameStart  = text.indexOf(name);
+		nameLength = name.length();
+
+		styledText.setText(text);
+	}
+
+	@Override
+	public void dispose() {
+		this.styledText.dispose();
+		super.dispose();
+	}
+
+	/**
+	 * This handler is responsible to give the text information and to open the
+	 * mapping dialog if the user clicked on the mapping type.
+	 */
+	protected interface MappingChangeHandler<T> {
+
+		/**
+		 * Returns the entire text describing the mapping (entity or mapping) and
+		 * its type.
+		 *
+		 * @return A localized text with two arguments where the first one should
+		 * be replaced by the name and the second be replaced by the mapping type
+		 */
+		String getLabelText();
+
+		/**
+		 * Returns the displayable text representing the mapping type.
+		 *
+		 * @return A human readable text describing the mapping type
+		 */
+		String getMappingText();
+
+		/**
+		 * Morphes the current mapping into a new type by using the given provider.
+		 *
+		 * @param provider The definition that was selected for changing the mapping
+		 */
+		void morphMapping(MappingUiDefinition<T, ?> definition);
+
+		/**
+		 * Returns the name of the current mapping.
+		 *
+		 * @return The displayable name of the mapping
+		 */
+		String getName();
+
+		/**
+		 * Returns the list of mapping UI definitions that are registered with the JPT plugin.
+		 *
+		 * @return The supported types of mapping
+		 */
+		Iterator<MappingUiDefinition<T, ?>> mappingUiDefinitions();
+	}
+
+	/**
+	 * This dialog shows the list of possible mapping types and lets the user
+	 * the option to filter them using a search field.
+	 */
+	protected class MappingSelectionDialog extends FilteredItemsSelectionDialog 
+	{
+		private MappingUiDefinition defaultDefinition;
+		
+		/**
+		 * Creates a new <code>MappingSelectionDialog</code>.
+		 */
+		private MappingSelectionDialog() {
+			super(MapAsComposite.this.getShell(), false);
+			setMessage(JptUiDetailsMessages.MapAsComposite_labelText);
+			setTitle(JptUiDetailsMessages.MapAsComposite_dialogTitle);
+			setListLabelProvider(buildLabelProvider());
+			setDetailsLabelProvider(buildLabelProvider());
+		}
+
+		private ILabelProvider buildLabelProvider() {
+			return new LabelProvider() {
+
+				@Override
+				public Image getImage(Object element) {
+
+					if (element == null) {
+						return null;
+					}
+
+					MappingUiDefinition definition = (MappingUiDefinition) element;
+					return definition.getImage();
+				}
+
+				@Override
+				public String getText(Object element) {
+					if (element == null) {
+						return "";
+					}
+					
+					MappingUiDefinition definition = (MappingUiDefinition) element;
+					return definition.getLabel();
+				}
+			};
+		}
+
+		@Override
+		protected Control createExtendedContentArea(Composite parent) {
+			return null;
+		}
+
+		@Override
+		protected ItemsFilter createFilter() {
+			return new MappingTypeItemsFilter();
+		}
+
+		@Override
+		protected void fillContentProvider(
+				AbstractContentProvider provider,
+				ItemsFilter itemsFilter,
+				IProgressMonitor monitor) throws CoreException {
+			
+			monitor.beginTask(null, -1);
+
+			try {
+				// Add the default provider
+				defaultDefinition = getDefaultDefinition();
+
+				if (defaultDefinition != null) {
+					provider.add(defaultDefinition, itemsFilter);
+				}
+
+				// Add the registered mapping providers to the dialog
+				for (Iterator<MappingUiDefinition<T, ?>> iter = mappingChangeHandler.mappingUiDefinitions(); iter.hasNext(); ) {
+					MappingUiDefinition mappingDefinition = iter.next();
+					if (mappingDefinition.isEnabledFor(getSubject())) {
+						provider.add(mappingDefinition, itemsFilter);
+					}
+				}
+			}
+			finally {
+				monitor.done();
+			}
+		}
+
+		@Override
+		protected IDialogSettings getDialogSettings() {
+
+			IDialogSettings dialogSettings = JptUiPlugin.instance().getDialogSettings();
+			IDialogSettings settings = dialogSettings.getSection(DIALOG_SETTINGS);
+
+			if (settings == null) {
+				settings = dialogSettings.addNewSection(DIALOG_SETTINGS);
+			}
+
+			return settings;
+		}
+
+		@Override
+		public String getElementName(Object object) {
+			MappingUiDefinition definition = (MappingUiDefinition) object;
+			return definition.getLabel();
+		}
+
+		@Override
+		protected Comparator<MappingUiDefinition> getItemsComparator() {
+			return new Comparator<MappingUiDefinition>() {
+				public int compare(MappingUiDefinition item1, MappingUiDefinition item2) {
+
+					if (item1 == defaultDefinition) {
+						return -1;
+					}
+
+					if (item2 == defaultDefinition) {
+						return 1;
+					}
+
+					String displayString1 = item1.getLabel();
+					String displayString2 = item2.getLabel();
+					return Collator.getInstance().compare(displayString1, displayString2);
+				}
+			};
+		}
+
+		@Override
+		protected IStatus validateItem(Object item) {
+
+			if (item == null) {
+				return new Status(IStatus.ERROR, JptUiPlugin.PLUGIN_ID, IStatus.ERROR, "", null);
+			}
+
+			return Status.OK_STATUS;
+		}
+
+		/**
+		 * Create the filter responsible to remove any mapping type based on the
+		 * pattern entered in the text field.
+		 */
+		private class MappingTypeItemsFilter extends ItemsFilter {
+
+			/**
+			 * Creates a new <code>MappingTypeItemsFilter</code>.
+			 */
+			MappingTypeItemsFilter() {
+
+				super();
+
+				// Make sure that if the pattern is empty, we specify * in order
+				// to show all the mapping types
+				if (StringTools.stringIsEmpty(getPattern())) {
+					patternMatcher.setPattern("*");
+				}
+			}
+
+			@Override
+			public boolean isConsistentItem(Object item) {
+				return true;
+			}
+
+			@Override
+			public boolean matchItem(Object item) {
+				MappingUiDefinition definition = (MappingUiDefinition) item;
+				return matches(definition.getLabel());
+			}
+		}
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/MappedByJoiningStrategyPane.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/MappedByJoiningStrategyPane.java
new file mode 100644
index 0000000..2a83f2e
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/MappedByJoiningStrategyPane.java
@@ -0,0 +1,94 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2010 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.ui.internal.details;
+
+import org.eclipse.jpt.core.context.MappedByJoiningStrategy;
+import org.eclipse.jpt.core.context.OwnableRelationshipReference;
+import org.eclipse.jpt.core.context.RelationshipReference;
+import org.eclipse.jpt.ui.internal.widgets.Pane;
+import org.eclipse.jpt.utility.internal.model.value.PropertyAspectAdapter;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.jpt.utility.model.value.WritablePropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * Here is the layout of this pane:  
+ * <pre>
+ * -----------------------------------------------------------------------------
+ * | o Mapped by _____________________________________________________________ |
+ * | |             ---------------------------------------------  ---------- | |
+ * | |  Attribute: |                                           |  |Browse..| | |
+ * | |             ---------------------------------------------  ---------- | |
+ * | ------------------------------------------------------------------------- |
+ * -----------------------------------------------------------------------------</pre>
+ *
+ * @see {@link OwnableRelationshipReference}
+ * @see {@link MappedByJoiningStrategy}
+ * @see {@link OneToOneJoiningStrategyPane}
+ * @see {@link OneToManyJoiningStrategyPane}
+ * @see {@link ManyToManyJoiningStrategyPane}
+ *
+ * @version 2.3
+ * @since 2.1
+ */
+public class MappedByJoiningStrategyPane 
+	extends AbstractJoiningStrategyPane<OwnableRelationshipReference, MappedByJoiningStrategy>
+{
+	/**
+	 * Creates a new <code>MappedByJoiningStrategyPane</code>.
+	 *
+	 * @param parentPane The parent form pane
+	 * @param parent The parent container
+	 */
+	public MappedByJoiningStrategyPane(
+			Pane<? extends OwnableRelationshipReference> parentPane, 
+			Composite parent) {
+		super(parentPane, parent);
+	}
+
+	@Override
+	protected Composite buildStrategyDetailsComposite(Composite parent) {
+		return new MappedByPane(this, this.buildMappedByJoiningStrategyHolder(), parent).getControl();
+	}	
+
+	@Override
+	protected WritablePropertyValueModel<Boolean> buildUsesStrategyHolder() {
+		return buildUsesMappedByJoiningStrategyHolder(getSubjectHolder());
+	}
+
+	protected PropertyValueModel<MappedByJoiningStrategy> buildMappedByJoiningStrategyHolder() {
+		return new PropertyAspectAdapter<OwnableRelationshipReference, MappedByJoiningStrategy>(
+				getSubjectHolder()) {
+			@Override
+			protected MappedByJoiningStrategy buildValue_() {
+				return this.subject.getMappedByJoiningStrategy();
+			}
+		};
+	}
+
+	public static WritablePropertyValueModel<Boolean> buildUsesMappedByJoiningStrategyHolder(PropertyValueModel<? extends OwnableRelationshipReference> subjectHolder) {
+		return new PropertyAspectAdapter<OwnableRelationshipReference, Boolean>(
+				subjectHolder, RelationshipReference.PREDOMINANT_JOINING_STRATEGY_PROPERTY) {
+			@Override
+			protected Boolean buildValue() {
+				return (this.subject == null) ? Boolean.FALSE :
+					Boolean.valueOf(this.subject.usesMappedByJoiningStrategy());
+			}
+			
+			@Override
+			protected void setValue_(Boolean value) {
+				if (value == Boolean.TRUE) {
+					this.subject.setMappedByJoiningStrategy();
+				}
+				//value == FALSE - selection of another radio button causes this strategy to get unset
+			}
+		};
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/MappedByPane.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/MappedByPane.java
new file mode 100644
index 0000000..7be993c
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/MappedByPane.java
@@ -0,0 +1,100 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 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.ui.internal.details;
+
+import java.util.Iterator;
+
+import org.eclipse.jpt.core.context.MappedByJoiningStrategy;
+import org.eclipse.jpt.ui.internal.JpaHelpContextIds;
+import org.eclipse.jpt.ui.internal.widgets.Pane;
+import org.eclipse.jpt.utility.internal.model.value.CollectionAspectAdapter;
+import org.eclipse.jpt.utility.internal.model.value.PropertyAspectAdapter;
+import org.eclipse.jpt.utility.internal.model.value.SortedListValueModelAdapter;
+import org.eclipse.jpt.utility.model.value.ListValueModel;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.jpt.utility.model.value.WritablePropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+import com.ibm.icu.text.Collator;
+
+/**
+ * Here the layout of this pane:
+ * <pre>
+ * -----------------------------------------------------------------------------
+ * |            -------------------------------------------------------------- |
+ * | Mapped By: |                                                          |v| |
+ * |            -------------------------------------------------------------- |
+ * -----------------------------------------------------------------------------</pre>
+ *
+ * @see NonOwningMapping
+ * @see ManyToManyMappingComposite - A container of this pane
+ * @see OneToManyMappingComposite - A container of this pane
+ * @see OneToOneMappingComposite - A container of this pane
+ *
+ * @version 2.0
+ * @since 1.0
+ */
+public class MappedByPane 
+	extends Pane<MappedByJoiningStrategy>
+{
+	/**
+	 * Creates a new <code>MappedByPane</code>.
+	 *
+	 * @param parentPane The parent form pane
+	 * @param subjectHolder The PVM for the {@link MappedByJoiningStrategy}
+	 * @param parent The parent container
+	 */
+	public MappedByPane(
+			Pane<?> parentPane,
+			PropertyValueModel<MappedByJoiningStrategy> subjectHolder,
+			Composite parent) {
+		super(parentPane, subjectHolder, parent);
+	}
+	
+	
+	@Override
+	protected void initializeLayout(Composite container) {
+		addLabeledEditableCombo(
+			container,
+			JptUiDetailsMessages.Joining_mappedByAttributeLabel,
+			buildCandidateAttributesListValueModel(),
+			buildAttributePropertyValueModel(),
+			JpaHelpContextIds.MAPPING_MAPPED_BY);
+	}
+	
+	@SuppressWarnings("unchecked")
+	protected ListValueModel<String> buildCandidateAttributesListValueModel() {
+		return new SortedListValueModelAdapter<String>(
+			new CollectionAspectAdapter<MappedByJoiningStrategy, String>(
+					getSubjectHolder()) {
+				@Override
+				protected Iterator<String> iterator_() {
+					return this.subject.candidateMappedByAttributeNames();
+				}
+			},
+			Collator.getInstance()
+		);
+	}
+	
+	protected WritablePropertyValueModel<String> buildAttributePropertyValueModel() {
+		return new PropertyAspectAdapter<MappedByJoiningStrategy, String>(
+				getSubjectHolder(), MappedByJoiningStrategy.MAPPED_BY_ATTRIBUTE_PROPERTY) {
+			@Override
+			protected String buildValue_() {
+				return this.subject.getMappedByAttribute();
+			}
+			
+			@Override
+			protected void setValue_(String value) {
+				this.subject.setMappedByAttribute(value);
+			}
+		};
+	}
+}
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/NamedNativeQueryPropertyComposite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/NamedNativeQueryPropertyComposite.java
new file mode 100644
index 0000000..dd9899e
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/NamedNativeQueryPropertyComposite.java
@@ -0,0 +1,182 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2009 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.ui.internal.details;
+
+import org.eclipse.jpt.core.JpaProject;
+import org.eclipse.jpt.core.context.NamedNativeQuery;
+import org.eclipse.jpt.core.context.Query;
+import org.eclipse.jpt.ui.internal.widgets.ClassChooserPane;
+import org.eclipse.jpt.ui.internal.widgets.Pane;
+import org.eclipse.jpt.utility.internal.model.value.PropertyAspectAdapter;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.jpt.utility.model.value.WritablePropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * Here the layout of this pane:
+ * <pre>
+ * -----------------------------------------------------------------------------
+ * |               --------------------------------------------- ------------- |
+ * | Result Class: | I                                         | | Browse... | |
+ * |               --------------------------------------------- ------------- |
+ * |               ---------------------------------------------               |
+ * | Query:        | I                                         |               |
+ * |               |                                           |               |
+ * |               |                                           |               |
+ * |               |                                           |               |
+ * |               ---------------------------------------------               |
+ * |                                                                           |
+ * | - Query Hints ----------------------------------------------------------- |
+ * | | --------------------------------------------------------------------- | |
+ * | | |                                                                   | | |
+ * | | | QueryHintsComposite                                               | | |
+ * | | |                                                                   | | |
+ * | | --------------------------------------------------------------------- | |
+ * | ------------------------------------------------------------------------- |
+ * -----------------------------------------------------------------------------</pre>
+ *
+ * @see NamedNativeQuery
+ * @see NamedNativeQueriesComposite - The parent container
+ * @see ClassChooserPane
+ *
+ * @version 2.0
+ * @since 2.0
+ */
+public class NamedNativeQueryPropertyComposite extends Pane<NamedNativeQuery>
+{
+	private ClassChooserPane<NamedNativeQuery> resultClassChooserPane;
+
+	/**
+	 * Creates a new <code>NamedNativeQueryPropertyComposite</code>.
+	 *
+	 * @param parentPane The parent container of this one
+	 * @param subjectHolder The holder of this pane's subject
+	 * @param parent The parent container
+	 */
+	public NamedNativeQueryPropertyComposite(Pane<?> parentPane,
+	                                         PropertyValueModel<? extends NamedNativeQuery> subjectHolder,
+	                                         Composite parent) {
+
+		super(parentPane, subjectHolder, parent);
+	}
+
+	private ClassChooserPane<NamedNativeQuery> addClassChooser(Composite container) {
+
+		return new ClassChooserPane<NamedNativeQuery>(this, container) {
+
+			@Override
+			protected WritablePropertyValueModel<String> buildTextHolder() {
+				return new PropertyAspectAdapter<NamedNativeQuery, String>(getSubjectHolder(), NamedNativeQuery.RESULT_CLASS_PROPERTY) {
+					@Override
+					protected String buildValue_() {
+						return this.subject.getResultClass();
+					}
+
+					@Override
+					protected void setValue_(String value) {
+						this.subject.setResultClass(value);
+					}
+				};
+			}
+
+			@Override
+			protected String getClassName() {
+				return getSubject().getResultClass();
+			}
+
+			@Override
+			protected String getLabelText() {
+				return JptUiDetailsMessages.NamedNativeQueryPropertyComposite_resultClass;
+			}
+
+			@Override
+			protected JpaProject getJpaProject() {
+				return getSubject().getJpaProject();
+			}
+			
+			@Override
+			protected void setClassName(String className) {
+				getSubject().setResultClass(className);
+			}
+			
+			@Override
+			protected char getEnclosingTypeSeparator() {
+				return getSubject().getResultClassEnclosingTypeSeparator();
+			}
+		};
+	}
+
+	private WritablePropertyValueModel<String> buildQueryHolder() {
+		return new PropertyAspectAdapter<NamedNativeQuery, String>(getSubjectHolder(), Query.QUERY_PROPERTY) {
+			@Override
+			protected String buildValue_() {
+				return this.subject.getQuery();
+			}
+
+			@Override
+			protected void setValue_(String value) {
+				this.subject.setQuery(value);
+			}
+		};
+	}
+
+	@Override
+	public void enableWidgets(boolean enabled) {
+		super.enableWidgets(enabled);
+		this.resultClassChooserPane.enableWidgets(enabled);
+	}
+
+	@Override
+	protected void initializeLayout(Composite container) {
+		
+		addLabeledText(
+			container, 
+			JptUiDetailsMessages.NamedQueryComposite_nameTextLabel, 
+			buildNameTextHolder());
+
+		// Result class chooser
+		this.resultClassChooserPane = addClassChooser(container);
+
+		// Query text area
+		addLabeledMultiLineText(
+			container,
+			JptUiDetailsMessages.NamedNativeQueryPropertyComposite_query,
+			buildQueryHolder(),
+			4,
+			null
+		);
+
+		// Query Hints pane
+		container = addTitledGroup(
+			addSubPane(container, 5),
+			JptUiDetailsMessages.NamedNativeQueryPropertyComposite_queryHintsGroupBox
+		);
+
+		new QueryHintsComposite(this, container);
+	}
+	
+	protected WritablePropertyValueModel<String> buildNameTextHolder() {
+		return new PropertyAspectAdapter<NamedNativeQuery, String>(
+				getSubjectHolder(), Query.NAME_PROPERTY) {
+			@Override
+			protected String buildValue_() {
+				return this.subject.getName();
+			}
+		
+			@Override
+			protected void setValue_(String value) {
+				if (value.length() == 0) {
+					value = null;
+				}
+				this.subject.setName(value);
+			}
+		};
+	}
+}
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/NamedQueryPropertyComposite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/NamedQueryPropertyComposite.java
new file mode 100644
index 0000000..bef74fc
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/NamedQueryPropertyComposite.java
@@ -0,0 +1,119 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2009 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.ui.internal.details;
+
+import org.eclipse.jpt.core.context.NamedQuery;
+import org.eclipse.jpt.core.context.Query;
+import org.eclipse.jpt.ui.internal.widgets.Pane;
+import org.eclipse.jpt.utility.internal.model.value.PropertyAspectAdapter;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.jpt.utility.model.value.WritablePropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * Here the layout of this pane:
+ * <pre>
+ * -----------------------------------------------------------------------------
+ * |        ------------------------------------------------------------------ |
+ * | Query: | I                                                              | |
+ * |        |                                                                | |
+ * |        |                                                                | |
+ * |        ------------------------------------------------------------------ |
+ * |                                                                           |
+ * | - Query Hints ----------------------------------------------------------- |
+ * | | --------------------------------------------------------------------- | |
+ * | | |                                                                   | | |
+ * | | | QueryHintsComposite                                               | | |
+ * | | |                                                                   | | |
+ * | | --------------------------------------------------------------------- | |
+ * | ------------------------------------------------------------------------- |
+ * -----------------------------------------------------------------------------</pre>
+ *
+ * @see NamedQuery
+ * @see NamedQueriesComposite - The parent container
+ * @see QueryHintsComposite
+ *
+ * @version 2.0
+ * @since 2.0
+ */
+public class NamedQueryPropertyComposite<T extends NamedQuery> extends Pane<T>
+{
+	/**
+	 * Creates a new <code>NamedQueryPropertyComposite</code>.
+	 *
+	 * @param parentPane The parent container of this one
+	 * @param subjectHolder The holder of this pane's subject
+	 * @param parent The parent container
+	 */
+	public NamedQueryPropertyComposite(Pane<?> parentPane,
+	                                   PropertyValueModel<T> subjectHolder,
+	                                   Composite parent) {
+
+		super(parentPane, subjectHolder, parent);
+	}
+
+	protected WritablePropertyValueModel<String> buildQueryHolder() {
+		return new PropertyAspectAdapter<NamedQuery, String>(getSubjectHolder(), Query.QUERY_PROPERTY) {
+			@Override
+			protected String buildValue_() {
+				return this.subject.getQuery();
+			}
+
+			@Override
+			protected void setValue_(String value) {
+				this.subject.setQuery(value);
+			}
+		};
+	}
+
+	@Override
+	protected void initializeLayout(Composite container) {
+		
+		addLabeledText(
+			container, 
+			JptUiDetailsMessages.NamedQueryComposite_nameTextLabel, 
+			buildNameTextHolder());
+
+		// Query text area
+		addLabeledMultiLineText(
+			container,
+			JptUiDetailsMessages.NamedQueryPropertyComposite_query,
+			buildQueryHolder(),
+			4,
+			null
+		);
+
+		// Query Hints pane
+		container = addTitledGroup(
+			addSubPane(container, 5),
+			JptUiDetailsMessages.NamedQueryPropertyComposite_queryHintsGroupBox
+		);
+
+		new QueryHintsComposite(this, container);
+	}
+		
+	protected WritablePropertyValueModel<String> buildNameTextHolder() {
+		return new PropertyAspectAdapter<NamedQuery, String>(
+				getSubjectHolder(), Query.NAME_PROPERTY) {
+			@Override
+			protected String buildValue_() {
+				return this.subject.getName();
+			}
+		
+			@Override
+			protected void setValue_(String value) {
+				if (value.length() == 0) {
+					value = null;
+				}
+				this.subject.setName(value);
+			}
+		};
+	}
+}
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/OneToManyJoiningStrategyPane.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/OneToManyJoiningStrategyPane.java
new file mode 100644
index 0000000..e5acc03
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/OneToManyJoiningStrategyPane.java
@@ -0,0 +1,82 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2010 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.ui.internal.details;
+
+import org.eclipse.jpt.core.context.OneToManyRelationshipReference;
+import org.eclipse.jpt.ui.internal.widgets.Pane;
+import org.eclipse.jpt.utility.internal.model.value.SimplePropertyValueModel;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * Here is the layout of this pane:  
+ * <pre>
+ * -----------------------------------------------------------------------------
+ * | - Joining Strategy ------------------------------------------------------ |
+ * | |                                                                       | |
+ * | | o MappedByJoiningStrategyPane _______________________________________ | |
+ * | | |                                                                   | | |
+ * | | |                                                                   | | |
+ * | | --------------------------------------------------------------------- | |
+ * | | o JoinTableStrategyPane _____________________________________________ | |
+ * | | |                                                                   | | |
+ * | | |                                                                   | | |
+ * | | --------------------------------------------------------------------- | |
+ * | ------------------------------------------------------------------------- |
+ * -----------------------------------------------------------------------------</pre>
+ *
+ * @see {@link OneToManyMapping}
+ * @see {@link OneToManyRelationshipReference}
+ * @see {@link OneToManyMappingComposite}
+ * @see {@link MappedByStrategyPane}
+ * @see {@link JoinTableStrategyPane}
+ *
+ * @version 2.3
+ * @since 2.1
+ */
+public class OneToManyJoiningStrategyPane 
+	extends Pane<OneToManyRelationshipReference>
+{
+	public OneToManyJoiningStrategyPane(
+			Pane<?> parentPane, 
+			PropertyValueModel<? extends OneToManyRelationshipReference> subjectHolder, 
+			Composite parent) {
+		
+		super(parentPane, subjectHolder, parent);
+	}
+	
+	
+	@Override
+	protected void initializeLayout(Composite container) {
+		Composite composite = addCollapsibleSection(
+				container,
+				JptUiDetailsMessages.Joining_title,
+				new SimplePropertyValueModel<Boolean>(Boolean.TRUE));
+		
+		addRadioButton(
+			composite,
+			JptUiDetailsMessages.Joining_mappedByLabel,
+			MappedByJoiningStrategyPane.buildUsesMappedByJoiningStrategyHolder(getSubjectHolder()),
+			null);
+
+		new MappedByJoiningStrategyPane(this, composite);
+		
+		
+		addRadioButton(
+			composite,
+			JptUiDetailsMessages.Joining_joinTableJoiningLabel,
+			JoinTableJoiningStrategyPane.buildUsesJoinTableJoiningStrategyHolder(getSubjectHolder()),
+			null);
+
+		new JoinTableJoiningStrategyPane(this, composite);
+		
+		addSubPane(composite, 5);
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/OneToManyMappingComposite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/OneToManyMappingComposite.java
new file mode 100644
index 0000000..bf9c2dd
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/OneToManyMappingComposite.java
@@ -0,0 +1,82 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2010 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.ui.internal.details;
+
+import org.eclipse.jpt.core.context.OneToManyMapping;
+import org.eclipse.jpt.core.context.OneToManyRelationshipReference;
+import org.eclipse.jpt.ui.WidgetFactory;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * Here the layout of this pane:
+ * <pre>
+ * -----------------------------------------------------------------------------
+ * | ------------------------------------------------------------------------- |
+ * | |                                                                       | |
+ * | | TargetEntityComposite                                                 | |
+ * | |                                                                       | |
+ * | ------------------------------------------------------------------------- |
+ * | ------------------------------------------------------------------------- |
+ * | |                                                                       | |
+ * | | JoiningStrategyComposite                                              | |
+ * | |                                                                       | |
+ * | ------------------------------------------------------------------------- |
+ * | ------------------------------------------------------------------------- |
+ * | |                                                                       | |
+ * | | FetchTypeComposite                                                    | |
+ * | |                                                                       | |
+ * | ------------------------------------------------------------------------- |
+ * | ------------------------------------------------------------------------- |
+ * | |                                                                       | |
+ * | | CascadeComposite                                                      | |
+ * | |                                                                       | |
+ * | ------------------------------------------------------------------------- |
+ * | ------------------------------------------------------------------------- |
+ * | |                                                                       | |
+ * | | OrderingComposite                                                     | |
+ * | |                                                                       | |
+ * | ------------------------------------------------------------------------- |
+ * -----------------------------------------------------------------------------</pre>
+ *
+ * @see OneToManyMapping
+ * @see CascadeComposite
+ * @see FetchTypeComposite
+ * @see JoinTableComposite
+ * @see OrderingComposite
+ * @see TargetEntityComposite
+ *
+ * @version 2.3
+ * @since 1.0
+ */
+public class OneToManyMappingComposite 
+	extends AbstractOneToManyMappingComposite<OneToManyMapping, OneToManyRelationshipReference>
+{
+	/**
+	 * Creates a new <code>OneToManyMappingComposite</code>.
+	 *
+	 * @param subjectHolder The holder of the subject <code>IOneToManyMapping</code>
+	 * @param parent The parent container
+	 * @param widgetFactory The factory used to create various common widgets
+	 */
+	public OneToManyMappingComposite(PropertyValueModel<? extends OneToManyMapping> subjectHolder,
+	                                 Composite parent,
+	                                 WidgetFactory widgetFactory) {
+
+		super(subjectHolder, parent, widgetFactory);
+	}
+
+	@Override
+	protected void initializeOneToManySection(Composite container) {
+		new TargetEntityComposite(this, container);
+		new FetchTypeComposite(this, container);
+		new CascadeComposite(this, buildCascadeHolder(), addSubPane(container, 5));
+	}
+}
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/OneToOneJoiningStrategyPane.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/OneToOneJoiningStrategyPane.java
new file mode 100644
index 0000000..d6b693c
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/OneToOneJoiningStrategyPane.java
@@ -0,0 +1,96 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2010 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.ui.internal.details;
+
+import org.eclipse.jpt.core.context.OneToOneRelationshipReference;
+import org.eclipse.jpt.ui.internal.widgets.Pane;
+import org.eclipse.jpt.utility.internal.model.value.SimplePropertyValueModel;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * Here is the layout of this pane:  
+ * <pre>
+ * -----------------------------------------------------------------------------
+ * | - Joining Strategy ------------------------------------------------------ |
+ * | |                                                                       | |
+ * | | o MappedByJoiningStrategyPane _______________________________________ | |
+ * | | |                                                                   | | |
+ * | | |                                                                   | | |
+ * | | --------------------------------------------------------------------- | |
+ * | | o JoinColumnStrategyPane ____________________________________________ | |
+ * | | |                                                                   | | |
+ * | | |                                                                   | | |
+ * | | --------------------------------------------------------------------- | |
+ * | | o PrimaryKeyJoinColumnStrategyPane __________________________________ | |
+ * | | |                                                                   | | |
+ * | | |                                                                   | | |
+ * | | --------------------------------------------------------------------- | |
+ * | ------------------------------------------------------------------------- |
+ * -----------------------------------------------------------------------------</pre>
+ *
+ * @see {@link OneToOneMapping}
+ * @see {@link OneToOneRelationshipReference}
+ * @see {@link OneToOneMappingComposite}
+ * @see {@link MappedByStrategyPane}
+ * @see {@link JoinColumnStrategyPane}
+ * @see {@link PrimaryKeyJoinColumnStrategyPane}
+ *
+ * @version 2.3
+ * @since 2.1
+ */
+public class OneToOneJoiningStrategyPane 
+	extends Pane<OneToOneRelationshipReference>
+{
+	public OneToOneJoiningStrategyPane(
+			Pane<?> parentPane, 
+			PropertyValueModel<? extends OneToOneRelationshipReference> subjectHolder, 
+			Composite parent) {
+		
+		super(parentPane, subjectHolder, parent);
+	}
+	
+	
+	@Override
+	protected void initializeLayout(Composite container) {
+		Composite composite = addCollapsibleSection(
+				container,
+				JptUiDetailsMessages.Joining_title,
+				new SimplePropertyValueModel<Boolean>(Boolean.TRUE));
+		
+		
+		addRadioButton(
+			composite,
+			JptUiDetailsMessages.Joining_mappedByLabel,
+			MappedByJoiningStrategyPane.buildUsesMappedByJoiningStrategyHolder(getSubjectHolder()),
+			null);
+
+		new MappedByJoiningStrategyPane(this, composite);
+		
+		addRadioButton(
+			composite,
+			JptUiDetailsMessages.Joining_primaryKeyJoinColumnJoiningLabel,
+			PrimaryKeyJoinColumnJoiningStrategyPane.buildUsesPrimaryKeyJoinColumnJoiningStrategyHolder(getSubjectHolder()),
+			null);
+
+		new PrimaryKeyJoinColumnJoiningStrategyPane(this, composite);
+		
+		addRadioButton(
+			composite,
+			JptUiDetailsMessages.Joining_joinColumnJoiningLabel,
+			JoinColumnJoiningStrategyPane.buildUsesJoinColumnJoiningStrategyHolder(getSubjectHolder()),
+			null);
+
+		JoinColumnJoiningStrategyPane.
+				buildJoinColumnJoiningStrategyPaneWithIncludeOverrideCheckBox(this, composite);
+		
+		addSubPane(composite, 5);
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/OneToOneMappingComposite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/OneToOneMappingComposite.java
new file mode 100644
index 0000000..4048b81
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/OneToOneMappingComposite.java
@@ -0,0 +1,85 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 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.ui.internal.details;
+
+import org.eclipse.jpt.core.context.OneToOneMapping;
+import org.eclipse.jpt.core.context.OneToOneRelationshipReference;
+import org.eclipse.jpt.ui.WidgetFactory;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * Here the layout of this pane:
+ * <pre>
+ * -----------------------------------------------------------------------------
+ * | ------------------------------------------------------------------------- |
+ * | |                                                                       | |
+ * | | TargetEntityComposite                                                 | |
+ * | |                                                                       | |
+ * | ------------------------------------------------------------------------- |
+ * | ------------------------------------------------------------------------- |
+ * | |                                                                       | |
+ * | | JoiningStrategyComposite                                              | |
+ * | |                                                                       | |
+ * | ------------------------------------------------------------------------- |
+ * | ------------------------------------------------------------------------- |
+ * | |                                                                       | |
+ * | | FetchTypeComposite                                                    | |
+ * | |                                                                       | |
+ * | ------------------------------------------------------------------------- |
+ * | ------------------------------------------------------------------------- |
+ * | |                                                                       | |
+ * | | OptionalComposite                                                     | |
+ * | |                                                                       | |
+ * | ------------------------------------------------------------------------- |
+ * | ------------------------------------------------------------------------- |
+ * | |                                                                       | |
+ * | | CascadeComposite                                                      | |
+ * | |                                                                       | |
+ * | ------------------------------------------------------------------------- |
+ * -----------------------------------------------------------------------------</pre>
+ *
+ * @see OneToOneMapping
+ * @see TargetEntityComposite
+ * @see JoiningStrategyComposite
+ * @see FetchTypeComposite
+ * @see OptionalComposite
+ * @see CascadeComposite
+ *
+ * @version 2.3
+ * @since 1.0
+ */
+public class OneToOneMappingComposite 
+	extends AbstractOneToOneMappingComposite<OneToOneMapping, OneToOneRelationshipReference>
+{
+	/**
+	 * Creates a new <code>OneToOneMappingComposite</code>.
+	 *
+	 * @param subjectHolder The holder of the subject <code>IOneToOneMapping</code>
+	 * @param parent The parent container
+	 * @param widgetFactory The factory used to create various common widgets
+	 */
+	public OneToOneMappingComposite(PropertyValueModel<? extends OneToOneMapping> subjectHolder,
+	                                Composite parent,
+	                                WidgetFactory widgetFactory) {
+
+		super(subjectHolder, parent, widgetFactory);
+	}	
+
+	@Override
+	protected void initializeOneToOneSection(Composite container) {
+		new TargetEntityComposite(this, container);
+		new FetchTypeComposite(this, container);
+		new OptionalComposite(this, container);
+		new CascadeComposite(this, buildCascadeHolder(),  addSubPane(container, 5));
+	}
+
+
+}
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/OptionalComposite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/OptionalComposite.java
new file mode 100644
index 0000000..a4d5ae8
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/OptionalComposite.java
@@ -0,0 +1,101 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2010 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.ui.internal.details;
+
+import org.eclipse.jpt.core.context.Nullable;
+import org.eclipse.jpt.ui.internal.JpaHelpContextIds;
+import org.eclipse.jpt.ui.internal.widgets.Pane;
+import org.eclipse.jpt.utility.internal.model.value.PropertyAspectAdapter;
+import org.eclipse.jpt.utility.internal.model.value.TransformationPropertyValueModel;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.jpt.utility.model.value.WritablePropertyValueModel;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * This composite simply shows a tri-state check box for the Optional option.
+ *
+ * @see BasicMapping
+ * @see BasicMappingComposite - A container of this pane
+ * @see ManyToOneMappingComposite - A container of this pane
+ * @see OneToOneMappingComposite - A container of this pane
+ *
+ * @version 1.0
+ * @since 2.0
+ */
+public class OptionalComposite extends Pane<Nullable>
+{
+	/**
+	 * Creates a new <code>OptionalComposite</code>.
+	 *
+	 * @param parentPane The parent container of this one
+	 * @param parent The parent container
+	 */
+	public OptionalComposite(Pane<? extends Nullable> parentPane,
+	                         Composite parent)
+	{
+		super(parentPane, parent);
+	}
+
+	@Override
+	protected void initializeLayout(Composite container) {
+
+		addTriStateCheckBoxWithDefault(
+			addSubPane(container, 4),
+			JptUiDetailsMessages.BasicGeneralSection_optionalLabel,
+			buildOptionalHolder(),
+			buildOptionalStringHolder(),
+			JpaHelpContextIds.MAPPING_OPTIONAL
+		);
+	}
+	private WritablePropertyValueModel<Boolean> buildOptionalHolder() {
+		return new PropertyAspectAdapter<Nullable, Boolean>(getSubjectHolder(), Nullable.SPECIFIED_OPTIONAL_PROPERTY) {
+			@Override
+			protected Boolean buildValue_() {
+				return this.subject.getSpecifiedOptional();
+			}
+
+			@Override
+			protected void setValue_(Boolean value) {
+				this.subject.setSpecifiedOptional(value);
+			}
+		};
+	}
+
+	private PropertyValueModel<String> buildOptionalStringHolder() {
+		return new TransformationPropertyValueModel<Boolean, String>(buildDefaultOptionalHolder()) {
+			@Override
+			protected String transform(Boolean value) {
+				if (value != null) {
+					String defaultStringValue = value.booleanValue() ? JptUiDetailsMessages.Boolean_True : JptUiDetailsMessages.Boolean_False;
+					return NLS.bind(JptUiDetailsMessages.BasicGeneralSection_optionalLabelDefault, defaultStringValue);
+				}
+				return JptUiDetailsMessages.BasicGeneralSection_optionalLabel;
+			}
+		};
+	}
+	
+	
+	private PropertyValueModel<Boolean> buildDefaultOptionalHolder() {
+		return new PropertyAspectAdapter<Nullable, Boolean>(
+			getSubjectHolder(),
+			Nullable.SPECIFIED_OPTIONAL_PROPERTY,
+			Nullable.DEFAULT_OPTIONAL_PROPERTY)
+		{
+			@Override
+			protected Boolean buildValue_() {
+				if (this.subject.getSpecifiedOptional() != null) {
+					return null;
+				}
+				return Boolean.valueOf(this.subject.isDefaultOptional());
+			}
+		};
+	}
+}
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/OrderingComposite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/OrderingComposite.java
new file mode 100644
index 0000000..24b8e74
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/OrderingComposite.java
@@ -0,0 +1,115 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 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.ui.internal.details;
+
+import org.eclipse.jpt.core.context.CollectionMapping;
+import org.eclipse.jpt.core.context.Orderable;
+import org.eclipse.jpt.ui.WidgetFactory;
+import org.eclipse.jpt.ui.internal.JpaHelpContextIds;
+import org.eclipse.jpt.ui.internal.widgets.Pane;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * Here the layout of this pane:
+ * <pre>
+ * -----------------------------------------------------------------------------
+ * | - Ordering -------------------------------------------------------------- |
+ * | |                                                                       | |
+ * | | o None                                                                | |
+ * | |                                                                       | |
+ * | | o Primary Key                                                         | |
+ * | |                                                                       | |
+ * | | o Custom                                                              | |
+ * | |   ------------------------------------------------------------------- | |
+ * | |   | I                                                               | | |
+ * | |   ------------------------------------------------------------------- | |
+ * | ------------------------------------------------------------------------- |
+ * -----------------------------------------------------------------------------</pre>
+ *
+ * @see CollectionMapping
+ * @see ManyToManyMappingComposite - A container of this pane
+ * @see OneToManyMappingComposite - A container of this pane
+ *
+ * @version 3.0
+ * @since 1.0
+ */
+public class OrderingComposite extends AbstractOrderingComposite
+{
+	/**
+	 * Creates a new <code>OrderingComposite</code>.
+	 *
+	 * @param parentPane The parent container of this one
+	 * @param parent The parent container
+	 */
+	public OrderingComposite(Pane<? extends CollectionMapping> parentPane,
+	                         Composite parent) {
+
+		super(parentPane, parent);
+	}
+
+	/**
+	 * Creates a new <code>OrderingComposite</code>.
+	 *
+	 * @param subjectHolder The holder of the subject <code>IMultiRelationshipMapping</code>
+	 * @param parent The parent container
+	 * @param widgetFactory The factory used to create various common widgets
+	 */
+	public OrderingComposite(PropertyValueModel<? extends CollectionMapping> subjectHolder,
+	                         Composite parent,
+	                         WidgetFactory widgetFactory) {
+
+		super(subjectHolder, parent, widgetFactory);
+	}
+	
+	@Override
+	protected void initializeLayout(Composite container) {
+		PropertyValueModel<Orderable> orderableHolder = buildOrderableHolder();
+		
+		container = addCollapsibleSection(
+			container,
+			JptUiDetailsMessages.OrderingComposite_orderingGroup
+		);
+
+		// No Ordering radio button
+		addRadioButton(
+			container,
+			JptUiDetailsMessages.OrderingComposite_none,
+			buildNoOrderingHolder(orderableHolder),
+			JpaHelpContextIds.MAPPING_ORDER_BY_NO_ORDERING
+		);
+
+		// Order by Primary Key radio button
+		addRadioButton(
+			container,
+			JptUiDetailsMessages.OrderingComposite_primaryKey,
+			buildPrimaryKeyOrderingHolder(orderableHolder),
+			JpaHelpContextIds.MAPPING_ORDER_BY_PRIMARY_KEY_ORDERING
+		);
+
+		// Custom Ordering radio button
+		addRadioButton(
+			container,
+			JptUiDetailsMessages.OrderingComposite_custom,
+			buildCustomOrderingHolder(orderableHolder),
+			JpaHelpContextIds.MAPPING_ORDER_BY_CUSTOM_ORDERING
+		);
+
+		// Custom Ordering text field
+		addText(
+			addSubPane(container, 0, 16),
+			buildSpecifiedOrderByHolder(orderableHolder),
+			JpaHelpContextIds.MAPPING_ORDER_BY,
+			buildCustomOrderingHolder(orderableHolder)
+		);
+	}
+
+
+}
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/PersistentAttributeDetailsPage.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/PersistentAttributeDetailsPage.java
new file mode 100644
index 0000000..f4b953c
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/PersistentAttributeDetailsPage.java
@@ -0,0 +1,180 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2009 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.ui.internal.details;
+
+import java.util.HashMap;
+import java.util.Map;
+import org.eclipse.jpt.core.context.AttributeMapping;
+import org.eclipse.jpt.core.context.PersistentAttribute;
+import org.eclipse.jpt.ui.WidgetFactory;
+import org.eclipse.jpt.ui.details.JpaComposite;
+import org.eclipse.jpt.ui.internal.Tracing;
+import org.eclipse.jpt.ui.internal.util.ControlSwitcher;
+import org.eclipse.jpt.utility.Filter;
+import org.eclipse.jpt.utility.internal.Transformer;
+import org.eclipse.jpt.utility.internal.model.value.FilteringPropertyValueModel;
+import org.eclipse.jpt.utility.internal.model.value.PropertyAspectAdapter;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.jpt.utility.model.value.WritablePropertyValueModel;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.ui.part.PageBook;
+
+/**
+ * The abstract definition of the details page responsible to show the
+ * information for an persistent attribute.
+ *
+ * @see PersistentAttribute
+ *
+ * @version 2.2
+ * @since 1.0
+ */
+public abstract class PersistentAttributeDetailsPage<T extends PersistentAttribute> extends AbstractJpaDetailsPage<T>
+{
+	private Map<String, JpaComposite> mappingComposites;
+	private PageBook mappingPageBook;
+
+	private PropertyValueModel<AttributeMapping> mappingHolder;
+	
+	/**
+	 * Creates a new <code>PersistentAttributeDetailsPage</code>.
+	 *
+	 * @param parent The parent container
+	 * @param widgetFactory The factory used to create various common widgets
+	 */
+	protected PersistentAttributeDetailsPage(
+			Composite parent,
+			WidgetFactory widgetFactory) {
+		
+		super(parent, widgetFactory);
+	}
+	
+	
+	@Override
+	protected void initialize() {
+		super.initialize();
+		this.mappingComposites = new HashMap<String, JpaComposite>();
+	}
+
+	protected PageBook buildMappingPageBook(Composite parent) {
+		this.mappingPageBook = new PageBook(parent, SWT.NONE);
+		this.mappingPageBook.showPage(this.addLabel(this.mappingPageBook, "")); //$NON-NLS-1$
+
+		GridData gridData = new GridData();
+		gridData.horizontalAlignment       = SWT.FILL;
+		gridData.verticalAlignment         = SWT.TOP;
+		gridData.grabExcessHorizontalSpace = true;
+		gridData.grabExcessVerticalSpace   = true;
+
+		this.mappingPageBook.setLayoutData(gridData);
+		
+		this.mappingHolder = this.buildMappingHolder();
+		new ControlSwitcher(this.mappingHolder, this.buildPaneTransformer(), this.mappingPageBook);
+
+		return this.mappingPageBook;
+	}
+	
+	private Transformer<AttributeMapping, Control> buildPaneTransformer() {
+		return new Transformer<AttributeMapping, Control>() {
+			public Control transform(AttributeMapping attributeMapping) {
+				if (attributeMapping == null) {
+					return null;
+				}
+				return getMappingComposite(attributeMapping.getKey()).getControl();
+			}
+		};
+	}
+
+	protected JpaComposite getMappingComposite(String key) {
+		JpaComposite composite = this.mappingComposites.get(key);
+		if (composite != null) {
+			return composite;
+		}
+
+		composite = buildMappingComposite(this.mappingPageBook, key);
+
+		if (composite != null) {
+			this.mappingComposites.put(key, composite);
+		}
+
+		return composite;
+	}
+	
+	protected JpaComposite buildMappingComposite(PageBook pageBook, String key) {
+		return getJpaPlatformUi().buildAttributeMappingComposite(
+				getSubject().getResourceType(),
+				key,
+				pageBook,
+				buildMappingHolder(key),
+				getWidgetFactory());
+	}
+	
+	private PropertyValueModel<AttributeMapping> buildMappingHolder(final String key) {
+		return new FilteringPropertyValueModel<AttributeMapping>(
+			this.mappingHolder,
+			buildMappingFilter(key)
+		);
+	}
+
+	private Filter<AttributeMapping> buildMappingFilter(String mappingKey) {
+		return new MappingFilter(mappingKey);
+	}
+
+
+	private WritablePropertyValueModel<AttributeMapping> buildMappingHolder() {
+		return new PropertyAspectAdapter<T, AttributeMapping>(
+			getSubjectHolder(),
+			PersistentAttribute.DEFAULT_MAPPING_PROPERTY,
+			PersistentAttribute.SPECIFIED_MAPPING_PROPERTY)
+		{
+			@Override
+			protected AttributeMapping buildValue_() {
+				return this.subject.getMapping();
+			}
+		};
+	}
+
+	@Override
+	public void dispose() {
+		log(Tracing.UI_DETAILS_VIEW, "PersistentAttributeDetailsPage.dispose()"); //$NON-NLS-1$
+
+		for (JpaComposite mappingComposite : this.mappingComposites.values()) {
+			mappingComposite.dispose();
+		}
+		this.mappingComposites.clear();
+		super.dispose();
+	}
+
+	@Override
+	protected void log(String flag, String message) {
+		super.log(flag, message);
+
+		if (Tracing.UI_DETAILS_VIEW.equals(flag) &&
+		    Tracing.booleanDebugOption(Tracing.UI_DETAILS_VIEW))
+		{
+			Tracing.log(message);
+		}
+	}
+
+	private class MappingFilter implements Filter<AttributeMapping> {
+		private String mappingKey;
+
+		MappingFilter(String mappingKey) {
+			super();
+			this.mappingKey = mappingKey;
+		}
+
+		public boolean accept(AttributeMapping mapping) {
+			return (mapping == null || this.mappingKey == null) || this.mappingKey.equals(mapping.getKey());
+		}
+	}
+}
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/PersistentAttributeMapAsComposite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/PersistentAttributeMapAsComposite.java
new file mode 100644
index 0000000..6881bc4
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/PersistentAttributeMapAsComposite.java
@@ -0,0 +1,138 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2009 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.ui.internal.details;
+
+import java.util.Collection;
+import java.util.Iterator;
+import org.eclipse.jpt.core.MappingKeys;
+import org.eclipse.jpt.core.context.PersistentAttribute;
+import org.eclipse.jpt.ui.details.DefaultMappingUiDefinition;
+import org.eclipse.jpt.ui.details.MappingUiDefinition;
+import org.eclipse.jpt.ui.internal.details.orm.UnsupportedOrmMappingUiDefinition;
+import org.eclipse.jpt.ui.internal.widgets.Pane;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * This "Map As" composite is responsible for showing the mapping name and
+ * mapping type for an attribute.
+ *
+ * @see JavaPersistentAttributeMapAsComposite
+ * @see OrmPersistentAttributeMapAsComposite
+ */
+public class PersistentAttributeMapAsComposite 
+	extends MapAsComposite<PersistentAttribute>
+{
+	/**
+	 * Creates a new <code>PersistentAttributeMapAsComposite</code>.
+	 *
+	 * @param parentPane The parent pane of this one
+	 * @param parent The parent container
+	 */
+	public PersistentAttributeMapAsComposite(
+			Pane<? extends PersistentAttribute> parentPane,
+            Composite parent) {
+		
+		super(parentPane, parent);
+	}
+	
+	
+	@Override
+	protected String getMappingKey() {
+		return getSubject().getMappingKey();
+	}
+
+	@Override
+	protected MappingChangeHandler buildMappingChangeHandler() {
+		return new MappingChangeHandler() {
+
+			public String getLabelText() {
+				String mappingKey = getMappingKey();
+
+				if (mappingKey != MappingKeys.NULL_ATTRIBUTE_MAPPING_KEY) {
+					return JptUiDetailsMessages.MapAsComposite_mappedAttributeText;
+				}
+				if (getSubject().isVirtual()) {
+					return JptUiDetailsMessages.MapAsComposite_virtualAttributeText;
+				}
+
+				return JptUiDetailsMessages.MapAsComposite_unmappedAttributeText;
+			}
+
+			public String getMappingText() {
+				String mappingKey = getMappingKey();
+
+				if (mappingKey == null) {
+					return JptUiDetailsMessages.MapAsComposite_changeMappingType;
+				}
+
+				if (getSubject().getSpecifiedMapping() == null) {
+					return getDefaultDefinition(getSubject().getDefaultMappingKey()).getLinkLabel();
+				}
+
+				return getMappingUiDefinition(mappingKey).getLinkLabel();
+			}
+			
+			public void morphMapping(MappingUiDefinition definition) {
+				getSubject().setSpecifiedMappingKey(definition.getKey());
+			}
+			
+			public String getName() {
+				return getSubject().getName();
+			}
+			
+			public Iterator<? extends MappingUiDefinition<? extends PersistentAttribute, ?>> mappingUiDefinitions() {
+				return attributeMappingUiDefinitions();
+			}
+		};
+	}
+	
+	protected Iterator<? extends MappingUiDefinition<? extends PersistentAttribute, ?>> attributeMappingUiDefinitions() {
+		return getJpaPlatformUi().attributeMappingUiDefinitions(getSubject().getResourceType());
+	}
+	
+	@Override
+	protected DefaultMappingUiDefinition getDefaultDefinition() {
+		return getDefaultDefinition(getSubject().getDefaultMappingKey());
+	}
+	
+	@Override
+	protected DefaultMappingUiDefinition getDefaultDefinition(String mappingKey) {
+		return getJpaPlatformUi().getDefaultAttributeMappingUiDefinition(getSubject().getResourceType(), mappingKey);
+	}
+
+	@Override
+	protected MappingUiDefinition getMappingUiDefinition(String mappingKey) {
+		MappingUiDefinition definition = super.getMappingUiDefinition(mappingKey);
+		if (definition != null) {
+			return definition;
+		}
+		return UnsupportedOrmMappingUiDefinition.instance();
+	}
+	
+	@Override
+	protected void addPropertyNames(Collection<String> propertyNames) {
+		super.addPropertyNames(propertyNames);
+		propertyNames.add(PersistentAttribute.DEFAULT_MAPPING_PROPERTY);
+		propertyNames.add(PersistentAttribute.SPECIFIED_MAPPING_PROPERTY);
+		propertyNames.add(PersistentAttribute.NAME_PROPERTY);
+	}
+
+	@Override
+	protected void propertyChanged(String propertyName) {
+		super.propertyChanged(propertyName);
+
+		if (propertyName == PersistentAttribute.SPECIFIED_MAPPING_PROPERTY ||
+		    propertyName == PersistentAttribute.DEFAULT_MAPPING_PROPERTY   ||
+		    propertyName == PersistentAttribute.NAME_PROPERTY) {
+
+			updateDescription();
+		}
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/PersistentTypeDetailsPage.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/PersistentTypeDetailsPage.java
new file mode 100644
index 0000000..9bd6b98
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/PersistentTypeDetailsPage.java
@@ -0,0 +1,169 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2009 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.ui.internal.details;
+
+import java.util.HashMap;
+import java.util.Map;
+import org.eclipse.jpt.core.context.PersistentType;
+import org.eclipse.jpt.core.context.TypeMapping;
+import org.eclipse.jpt.ui.WidgetFactory;
+import org.eclipse.jpt.ui.details.JpaComposite;
+import org.eclipse.jpt.ui.internal.Tracing;
+import org.eclipse.jpt.ui.internal.util.ControlSwitcher;
+import org.eclipse.jpt.utility.Filter;
+import org.eclipse.jpt.utility.internal.Transformer;
+import org.eclipse.jpt.utility.internal.model.value.FilteringPropertyValueModel;
+import org.eclipse.jpt.utility.internal.model.value.PropertyAspectAdapter;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.ui.part.PageBook;
+
+/**
+ * The abstract definition of the details page responsible to show the
+ * information for an persistent type.
+ *
+ * @see PersistentType
+ *
+ * @version 2.2
+ * @since 1.0
+ */
+@SuppressWarnings("nls")
+public class PersistentTypeDetailsPage extends AbstractJpaDetailsPage<PersistentType>
+{
+	private Map<String, JpaComposite> mappingComposites;
+	private PageBook mappingPageBook;
+	private PropertyValueModel<TypeMapping> mappingHolder;
+
+	/**
+	 * Creates a new <code>PersistentTypeDetailsPage</code>.
+	 *
+	 * @param parent The parent container
+	 * @param widgetFactory The factory used to create various common widgets
+	 */
+	public PersistentTypeDetailsPage(Composite parent,
+                                    WidgetFactory widgetFactory) {
+
+		super(parent, widgetFactory);
+	}
+
+	@Override
+	protected void initialize() {
+		super.initialize();
+		this.mappingComposites = new HashMap<String, JpaComposite>();
+	}
+	
+	@Override
+	protected void initializeLayout(Composite container) {
+
+		// Map As composite
+		new PersistentTypeMapAsComposite(
+			this,
+			addSubPane(container, 0, 0, 5, 0)
+		);
+
+		// Type properties page
+		buildMappingPageBook(container);
+	}
+
+	protected PageBook buildMappingPageBook(Composite parent) {
+
+		this.mappingPageBook = new PageBook(parent, SWT.NONE);
+		this.mappingPageBook.showPage(this.addLabel(this.mappingPageBook, ""));
+
+		GridData gridData = new GridData();
+		gridData.horizontalAlignment       = SWT.FILL;
+		gridData.verticalAlignment         = SWT.TOP;
+		gridData.grabExcessHorizontalSpace = true;
+		gridData.grabExcessVerticalSpace   = true;
+
+		this.mappingPageBook.setLayoutData(gridData);
+		
+		this.mappingHolder = this.buildMappingHolder();
+		new ControlSwitcher(this.mappingHolder, this.buildPaneTransformer(), this.mappingPageBook);
+
+		return this.mappingPageBook;
+	}
+	
+	private Transformer<TypeMapping, Control> buildPaneTransformer() {
+		return new Transformer<TypeMapping, Control>() {
+			public Control transform(TypeMapping typeMapping) {
+				if (typeMapping == null) {
+					return null;
+				}
+				return getMappingComposite(typeMapping.getKey()).getControl();
+			}
+		};
+	}
+	
+	protected PropertyValueModel<TypeMapping> buildMappingHolder(String key) {
+		return new FilteringPropertyValueModel<TypeMapping>(
+			this.mappingHolder,
+			buildMappingFilter(key)
+		);
+	}
+
+	private PropertyAspectAdapter<PersistentType, TypeMapping> buildMappingHolder() {
+		return new PropertyAspectAdapter<PersistentType, TypeMapping>(getSubjectHolder(), PersistentType.MAPPING_PROPERTY) {
+			@Override
+			protected TypeMapping buildValue_() {
+				return this.subject.getMapping();
+			}
+		};
+	}
+
+	private Filter<TypeMapping> buildMappingFilter(final String key) {
+		return new Filter<TypeMapping>() {
+			public boolean accept(TypeMapping mapping) {
+				return (mapping == null || key == null) || key.equals(mapping.getKey());
+			}
+		};
+	}
+
+	
+	private JpaComposite getMappingComposite(String key) {
+		JpaComposite mappingComposite = this.mappingComposites.get(key);
+		if (mappingComposite != null) {
+			return mappingComposite;
+		}
+
+		mappingComposite = buildMappingComposite(this.mappingPageBook, key);
+
+		if (mappingComposite != null) {
+			this.mappingComposites.put(key, mappingComposite);
+		}
+
+		return mappingComposite;
+	}
+	
+	protected JpaComposite buildMappingComposite(PageBook pageBook, String key) {
+		return getJpaPlatformUi().
+			buildTypeMappingComposite(
+				getSubject().getResourceType(), 
+				key, 
+				pageBook, 
+				buildMappingHolder(key), 
+				getWidgetFactory());
+	}
+
+	@Override
+	public void dispose() {
+		log(Tracing.UI_DETAILS_VIEW, "PersistentTypeDetailsPage.dispose()");
+
+		for (JpaComposite mappingComposite : this.mappingComposites.values()) {
+			mappingComposite.dispose();
+		}
+		this.mappingComposites.clear();
+		super.dispose();
+	}
+
+}
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/PersistentTypeMapAsComposite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/PersistentTypeMapAsComposite.java
new file mode 100644
index 0000000..a877262
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/PersistentTypeMapAsComposite.java
@@ -0,0 +1,128 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2009 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.ui.internal.details;
+
+import java.util.Collection;
+import java.util.Iterator;
+import org.eclipse.jpt.core.context.PersistentType;
+import org.eclipse.jpt.ui.details.DefaultMappingUiDefinition;
+import org.eclipse.jpt.ui.details.MappingUiDefinition;
+import org.eclipse.jpt.ui.internal.widgets.Pane;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * This "Map As" composite is responsible for showing the mapping name and
+ * mapping type for a type.
+ *
+ * @see JavaPersistentTypeMapAsComposite
+ * @see OrmPersistentTypeMapAsComposite
+ *
+ * @version 2.2
+ * @since 2.0
+ */
+public class PersistentTypeMapAsComposite
+	extends MapAsComposite<PersistentType>
+{
+	/**
+	 * Creates a new <code>PersistentTypeMapAsComposite</code>.
+	 *
+	 * @param parentPane The parent pane of this one
+	 * @param parent The parent container
+	 */
+	public PersistentTypeMapAsComposite(
+			Pane<? extends PersistentType> parentPane,
+	        Composite parent) {
+		
+		super(parentPane, parent);
+	}
+	
+	
+	@Override
+	protected String getMappingKey() {
+		return getSubject().getMappingKey();
+	}
+
+	@Override
+	protected MappingChangeHandler buildMappingChangeHandler() {
+		return new MappingChangeHandler() {
+
+			public String getLabelText() {
+				String mappingKey = getMappingKey();
+
+				if (mappingKey != null) {
+					return JptUiDetailsMessages.MapAsComposite_mappedTypeText;
+				}
+
+				return JptUiDetailsMessages.MapAsComposite_unmappedTypeText;
+			}
+
+			public String getMappingText() {
+				String mappingKey = getMappingKey();
+
+				if (mappingKey == null) {
+					return JptUiDetailsMessages.MapAsComposite_changeMappingType;
+				}
+
+				return getMappingUiDefinition(mappingKey).getLinkLabel();
+			}
+
+			public void morphMapping(MappingUiDefinition definition) {
+				getSubject().setMappingKey(definition.getKey());
+			}
+
+			public String getName() {
+				return getSubject().getShortName();
+			}
+			
+			@SuppressWarnings("unchecked")
+			public Iterator<? extends MappingUiDefinition<? extends PersistentType, ?>> mappingUiDefinitions() {
+				return typeMappingUiDefinitions();
+			}
+		};
+	}
+
+	/**
+	 * Retrieves the list of definitions that are registered with the JPT plugin.
+	 *
+	 * @return The supported types of mapping
+	 */
+	protected Iterator<? extends MappingUiDefinition<? extends PersistentType, ?>> typeMappingUiDefinitions() {
+		return getJpaPlatformUi().typeMappingUiDefinitions(getSubject().getResourceType());
+	}
+	
+	@Override
+	protected DefaultMappingUiDefinition getDefaultDefinition() {
+		return getJpaPlatformUi().getDefaultTypeMappingUiDefinition(getSubject().getResourceType());
+	}
+	
+	@Override
+	protected DefaultMappingUiDefinition getDefaultDefinition(String mappingKey) {
+		return getDefaultDefinition();
+	}
+	
+	@Override
+	protected void addPropertyNames(Collection<String> propertyNames) {
+		super.addPropertyNames(propertyNames);
+		propertyNames.add(PersistentType.MAPPING_PROPERTY);
+		propertyNames.add(PersistentType.NAME_PROPERTY);
+	}
+
+	@Override
+	protected void propertyChanged(String propertyName) {
+		super.propertyChanged(propertyName);
+
+		if (propertyName == PersistentType.MAPPING_PROPERTY ||
+		    propertyName == PersistentType.NAME_PROPERTY) {
+
+			updateDescription();
+		}
+	}
+
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/PrimaryKeyJoinColumnDialog.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/PrimaryKeyJoinColumnDialog.java
new file mode 100644
index 0000000..86d631b
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/PrimaryKeyJoinColumnDialog.java
@@ -0,0 +1,108 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2009 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.ui.internal.details;
+
+import org.eclipse.jpt.core.context.Entity;
+import org.eclipse.jpt.core.context.PrimaryKeyJoinColumn;
+import org.eclipse.jpt.ui.internal.widgets.DialogPane;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Shell;
+
+/**
+ * This dialog is used to either create or edit a primary key join column that
+ * is located on an entity.
+ *
+ * @see PrimaryKeyJoinColumn
+ * @see Entity
+ * @see PrimaryKeyJoinColumnStateObject
+ * @see BaseJoinColumnDialogPane
+ *
+ * @version 2.0
+ * @since 2.0
+ */
+public class PrimaryKeyJoinColumnDialog extends BaseJoinColumnDialog<PrimaryKeyJoinColumnStateObject> {
+
+	/**
+	 * Creates a new <code>PrimaryKeyJoinColumnDialog</code>.
+	 *
+	 * @param parent The parent shell
+	 * @param entity The owner of the join column to create or where it is
+	 * located
+	 * @param joinColumn Either the join column to edit or <code>null</code> if
+	 * this state object is used to create a new one
+	 */
+	public PrimaryKeyJoinColumnDialog(Shell parent,
+	                                  Entity entity,
+	                                  PrimaryKeyJoinColumn joinColumn) {
+
+		super(parent, entity, joinColumn);
+	}
+
+	/*
+	 * (non-Javadoc)
+	 */
+	@Override
+	protected DialogPane<PrimaryKeyJoinColumnStateObject> buildLayout(Composite container) {
+		return new BaseJoinColumnDialogPane<PrimaryKeyJoinColumnStateObject>(
+			getSubjectHolder(),
+			container
+		);
+	}
+
+	/*
+	 * (non-Javadoc)
+	 */
+	@Override
+	protected PrimaryKeyJoinColumnStateObject buildStateObject() {
+		return new PrimaryKeyJoinColumnStateObject(getOwner(), getJoinColumn());
+	}
+
+	/*
+	 * (non-Javadoc)
+	 */
+	@Override
+	protected String getDescriptionTitle() {
+
+		if (getJoinColumn() == null) {
+			return JptUiDetailsMessages.PrimaryKeyJoinColumnDialog_addDescriptionTitle;
+		}
+
+		return JptUiDetailsMessages.PrimaryKeyJoinColumnDialog_editDescriptionTitle;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 */
+	@Override
+	public PrimaryKeyJoinColumn getJoinColumn() {
+		return (PrimaryKeyJoinColumn) super.getJoinColumn();
+	}
+
+	/*
+	 * (non-Javadoc)
+	 */
+	@Override
+	protected Entity getOwner() {
+		return (Entity) super.getOwner();
+	}
+
+	/*
+	 * (non-Javadoc)
+	 */
+	@Override
+	protected String getTitle() {
+
+		if (getJoinColumn() == null) {
+			return JptUiDetailsMessages.PrimaryKeyJoinColumnDialog_addTitle;
+		}
+
+		return JptUiDetailsMessages.PrimaryKeyJoinColumnDialog_editTitle;
+	}
+}
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/PrimaryKeyJoinColumnInSecondaryTableDialog.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/PrimaryKeyJoinColumnInSecondaryTableDialog.java
new file mode 100644
index 0000000..948ea62
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/PrimaryKeyJoinColumnInSecondaryTableDialog.java
@@ -0,0 +1,111 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2009 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.ui.internal.details;
+
+import org.eclipse.jpt.core.context.PrimaryKeyJoinColumn;
+import org.eclipse.jpt.core.context.SecondaryTable;
+import org.eclipse.jpt.ui.internal.widgets.DialogPane;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Shell;
+
+/**
+ * This dialog is used to either create or edit a primary key joing column that
+ * is within a secondary table.
+ *
+ * @see PrimaryKeyJoinColumn
+ * @see SecondaryTable
+ * @see BaseJoinColumnDialogPane
+ * @see PrimaryKeyJoinColumnInSecondaryTableStateObject
+ *
+ * @version 2.0
+ * @since 2.0
+ */
+public class PrimaryKeyJoinColumnInSecondaryTableDialog extends BaseJoinColumnDialog<PrimaryKeyJoinColumnInSecondaryTableStateObject> {
+
+	/**
+	 * Creates a new <code>PrimaryKeyJoinColumnInSecondaryTableDialog</code>.
+	 *
+	 * @param parent The parent shell
+	 * @param secondaryTable The owner of the join column to create or where it
+	 * is located
+	 * @param joinColumn Either the join column to edit or <code>null</code> if
+	 * this state object is used to create a new one
+	 */
+	public PrimaryKeyJoinColumnInSecondaryTableDialog(Shell parent,
+	                                                  SecondaryTable secondaryTable,
+	                                                  PrimaryKeyJoinColumn joinColumn) {
+
+		super(parent, secondaryTable, joinColumn);
+	}
+
+	/*
+	 * (non-Javadoc)
+	 */
+	@Override
+	protected DialogPane<PrimaryKeyJoinColumnInSecondaryTableStateObject> buildLayout(Composite container) {
+		return new BaseJoinColumnDialogPane<PrimaryKeyJoinColumnInSecondaryTableStateObject>(
+			getSubjectHolder(),
+			container
+		);
+	}
+
+	/*
+	 * (non-Javadoc)
+	 */
+	@Override
+	protected PrimaryKeyJoinColumnInSecondaryTableStateObject buildStateObject() {
+		return new PrimaryKeyJoinColumnInSecondaryTableStateObject(
+			getOwner(),
+			getJoinColumn()
+		);
+	}
+
+	/*
+	 * (non-Javadoc)
+	 */
+	@Override
+	protected String getDescriptionTitle() {
+
+		if (getJoinColumn() == null) {
+			return JptUiDetailsMessages.PrimaryKeyJoinColumnInSecondaryTableDialog_addDescriptionTitle;
+		}
+
+		return JptUiDetailsMessages.PrimaryKeyJoinColumnInSecondaryTableDialog_editDescriptionTitle;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 */
+	@Override
+	public PrimaryKeyJoinColumn getJoinColumn() {
+		return (PrimaryKeyJoinColumn) super.getJoinColumn();
+	}
+
+	/*
+	 * (non-Javadoc)
+	 */
+	@Override
+	protected SecondaryTable getOwner() {
+		return (SecondaryTable) super.getOwner();
+	}
+
+	/*
+	 * (non-Javadoc)
+	 */
+	@Override
+	protected String getTitle() {
+
+		if (getJoinColumn() == null) {
+			return JptUiDetailsMessages.PrimaryKeyJoinColumnInSecondaryTableDialog_addTitle;
+		}
+
+		return JptUiDetailsMessages.PrimaryKeyJoinColumnInSecondaryTableDialog_editTitle;
+	}
+}
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/PrimaryKeyJoinColumnInSecondaryTableStateObject.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/PrimaryKeyJoinColumnInSecondaryTableStateObject.java
new file mode 100644
index 0000000..025ecc7
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/PrimaryKeyJoinColumnInSecondaryTableStateObject.java
@@ -0,0 +1,99 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2009 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.ui.internal.details;
+
+import java.util.ListIterator;
+import org.eclipse.jpt.core.context.PrimaryKeyJoinColumn;
+import org.eclipse.jpt.core.context.SecondaryTable;
+import org.eclipse.jpt.db.Table;
+import org.eclipse.jpt.utility.internal.iterators.SingleElementListIterator;
+
+/**
+ * The state object used to create or edit a primary key join column on an
+ * secondary table.
+ *
+ * @see PrimaryKeyJoinColumn
+ * @see SecondaryTable
+ * @see PrimaryKeyJoinColumnInSecondaryTableDialog
+ *
+ * @version 2.0
+ * @since 2.0
+ */
+public class PrimaryKeyJoinColumnInSecondaryTableStateObject extends BaseJoinColumnStateObject
+{
+	/**
+	 * Creates a new <code>PrimaryKeyJoinColumnInSecondaryTableStateObject</code>.
+	 *
+	 * @param secondaryTable The owner of the join column to create or where it
+	 * is located
+	 * @param joinColumn The join column to edit or <code>null</code> if it is to
+	 * create a new one
+	 */
+	public PrimaryKeyJoinColumnInSecondaryTableStateObject(SecondaryTable secondaryTable,
+	                                                       PrimaryKeyJoinColumn joinColumn) {
+
+		super(secondaryTable, joinColumn);
+	}
+
+	/*
+	 * (non-Javadoc)
+	 */
+	@Override
+	public String getDefaultTable() {
+		return null;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 */
+	@Override
+	public PrimaryKeyJoinColumn getJoinColumn() {
+		return (PrimaryKeyJoinColumn) super.getJoinColumn();
+	}
+
+	/*
+	 * (non-Javadoc)
+	 */
+	@Override
+	public Table getNameTable() {
+		return getOwner().getDbTable();
+	}
+
+	/*
+	 * (non-Javadoc)
+	 */
+	@Override
+	public SecondaryTable getOwner() {
+		return (SecondaryTable) super.getOwner();
+	}
+
+	/* (non-Javadoc)
+	 */
+	@Override
+	public Table getReferencedNameTable() {
+		return getOwner().getParent().getPrimaryDbTable();
+	}
+
+	/*
+	 * (non-Javadoc)
+	 */
+	@Override
+	protected String getInitialTable() {
+		return getOwner().getName();
+	}
+
+	/*
+	 * (non-Javadoc)
+	 */
+	@Override
+	public ListIterator<String> tables() {
+		return new SingleElementListIterator<String>(getInitialTable());
+	}
+}
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/PrimaryKeyJoinColumnJoiningStrategyPane.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/PrimaryKeyJoinColumnJoiningStrategyPane.java
new file mode 100644
index 0000000..99452f2
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/PrimaryKeyJoinColumnJoiningStrategyPane.java
@@ -0,0 +1,86 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2010 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.ui.internal.details;
+
+import org.eclipse.jpt.core.context.PrimaryKeyJoinColumnEnabledRelationshipReference;
+import org.eclipse.jpt.core.context.PrimaryKeyJoinColumnJoiningStrategy;
+import org.eclipse.jpt.core.context.RelationshipReference;
+import org.eclipse.jpt.ui.internal.widgets.Pane;
+import org.eclipse.jpt.utility.internal.model.value.PropertyAspectAdapter;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.jpt.utility.model.value.WritablePropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * Here is the layout of this pane:  
+ * <pre>
+ * -----------------------------------------------------------------------------
+ * | o Primary key join columns ______________________________________________ |
+ * | |     (no actual content)                                               | |
+ * | ------------------------------------------------------------------------- |
+ * -----------------------------------------------------------------------------</pre>
+ *
+ * @see {@link PrimaryKeyJoinColumnEnabledRelationshipReference}
+ * @see {@link PrimaryKeyJoinColumnJoiningStrategy}
+ * @see {@link OneToOneJoiningStrategyPane}
+ *
+ * @version 2.3
+ * @since 2.1
+ */
+public class PrimaryKeyJoinColumnJoiningStrategyPane 
+	extends AbstractJoiningStrategyPane
+		<PrimaryKeyJoinColumnEnabledRelationshipReference, PrimaryKeyJoinColumnJoiningStrategy>
+{
+	public PrimaryKeyJoinColumnJoiningStrategyPane(
+			Pane<? extends PrimaryKeyJoinColumnEnabledRelationshipReference> parentPane, 
+			Composite parent) {
+		super(parentPane, parent);
+	}
+
+	@Override
+	protected WritablePropertyValueModel<Boolean> buildUsesStrategyHolder() {
+		return buildUsesPrimaryKeyJoinColumnJoiningStrategyHolder(getSubjectHolder());
+	}
+
+	protected PropertyValueModel<PrimaryKeyJoinColumnJoiningStrategy> buildPrimaryKeyJoinColumnJoiningStrategyHolder() {
+		return new PropertyAspectAdapter
+				<PrimaryKeyJoinColumnEnabledRelationshipReference, PrimaryKeyJoinColumnJoiningStrategy>(
+					getSubjectHolder()) {
+			@Override
+			protected PrimaryKeyJoinColumnJoiningStrategy buildValue_() {
+				return this.subject.getPrimaryKeyJoinColumnJoiningStrategy();
+			}
+		};
+	}
+
+	@Override
+	protected Composite buildStrategyDetailsComposite(Composite parent) {
+		return null;
+	}
+
+	public static WritablePropertyValueModel<Boolean> buildUsesPrimaryKeyJoinColumnJoiningStrategyHolder(PropertyValueModel<? extends PrimaryKeyJoinColumnEnabledRelationshipReference> subjectHolder) {
+		return new PropertyAspectAdapter<PrimaryKeyJoinColumnEnabledRelationshipReference, Boolean>(
+				subjectHolder, RelationshipReference.PREDOMINANT_JOINING_STRATEGY_PROPERTY) {
+			@Override
+			protected Boolean buildValue() {
+				return (this.subject == null) ? Boolean.FALSE :
+					Boolean.valueOf(this.subject.usesPrimaryKeyJoinColumnJoiningStrategy());
+			}
+			
+			@Override
+			protected void setValue_(Boolean value) {
+				if (value == Boolean.TRUE) {
+					this.subject.setPrimaryKeyJoinColumnJoiningStrategy();
+				}
+				//value == FALSE - selection of another radio button causes this strategy to get unset
+			}
+		};
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/PrimaryKeyJoinColumnStateObject.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/PrimaryKeyJoinColumnStateObject.java
new file mode 100644
index 0000000..ddebc2c
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/PrimaryKeyJoinColumnStateObject.java
@@ -0,0 +1,101 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2009 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.ui.internal.details;
+
+import java.util.ListIterator;
+import org.eclipse.jpt.core.context.Entity;
+import org.eclipse.jpt.core.context.PrimaryKeyJoinColumn;
+import org.eclipse.jpt.db.Table;
+import org.eclipse.jpt.utility.internal.iterators.SingleElementListIterator;
+
+/**
+ * The state object used to create or edit a primary key join column on an
+ * entity.
+ *
+ * @see PrimaryKeyJoinColumn
+ * @see Entity
+ * @see PrimaryKeyJoinColumnDialog
+ * @see PrimaryKeyJoinColumnDialogPane
+ *
+ * @version 2.0
+ * @since 2.0
+ */
+public class PrimaryKeyJoinColumnStateObject extends BaseJoinColumnStateObject
+{
+	/**
+	 * Creates a new <code>PrimaryKeyJoinColumnStateObject</code>.
+	 *
+	 * @param entity The owner of the join column to create or where it is
+	 * located
+	 * @param joinColumn The join column to edit or <code>null</code> if this is
+	 * used to create a new one
+	 */
+	public PrimaryKeyJoinColumnStateObject(Entity entity,
+	                                       PrimaryKeyJoinColumn joinColumn) {
+		super(entity, joinColumn);
+	}
+
+	/*
+	 * (non-Javadoc)
+	 */
+	@Override
+	public String getDefaultTable() {
+		return null;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 */
+	@Override
+	public PrimaryKeyJoinColumn getJoinColumn() {
+		return (PrimaryKeyJoinColumn) super.getJoinColumn();
+	}
+
+	/*
+	 * (non-Javadoc)
+	 */
+	@Override
+	public Table getNameTable() {
+		return getOwner().getPrimaryDbTable();
+	}
+
+	/*
+	 * (non-Javadoc)
+	 */
+	@Override
+	public Entity getOwner() {
+		return (Entity) super.getOwner();
+	}
+
+	/*
+	 * (non-Javadoc)
+	 */
+	@Override
+	public Table getReferencedNameTable() {
+		Entity parentEntity = getOwner().getParentEntity();
+		return (parentEntity == null) ? getOwner().getPrimaryDbTable() : parentEntity.getPrimaryDbTable();
+	}
+
+	/*
+	 * (non-Javadoc)
+	 */
+	@Override
+	protected String getInitialTable() {
+		return getOwner().getPrimaryTableName();
+	}
+
+	/*
+	 * (non-Javadoc)
+	 */
+	@Override
+	public ListIterator<String> tables() {
+		return new SingleElementListIterator<String>(getInitialTable());
+	}
+}
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/PrimaryKeyJoinColumnsInSecondaryTableComposite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/PrimaryKeyJoinColumnsInSecondaryTableComposite.java
new file mode 100644
index 0000000..0cfaaa1
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/PrimaryKeyJoinColumnsInSecondaryTableComposite.java
@@ -0,0 +1,413 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 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.ui.internal.details;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.ListIterator;
+
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.jpt.core.context.BaseJoinColumn;
+import org.eclipse.jpt.core.context.NamedColumn;
+import org.eclipse.jpt.core.context.PrimaryKeyJoinColumn;
+import org.eclipse.jpt.core.context.SecondaryTable;
+import org.eclipse.jpt.ui.WidgetFactory;
+import org.eclipse.jpt.ui.internal.JpaHelpContextIds;
+import org.eclipse.jpt.ui.internal.util.PaneEnabler;
+import org.eclipse.jpt.ui.internal.utility.swt.SWTTools;
+import org.eclipse.jpt.ui.internal.widgets.AddRemoveListPane;
+import org.eclipse.jpt.ui.internal.widgets.AddRemovePane;
+import org.eclipse.jpt.ui.internal.widgets.Pane;
+import org.eclipse.jpt.ui.internal.widgets.PostExecution;
+import org.eclipse.jpt.utility.internal.model.value.CompositeListValueModel;
+import org.eclipse.jpt.utility.internal.model.value.ItemPropertyListValueModelAdapter;
+import org.eclipse.jpt.utility.internal.model.value.ListAspectAdapter;
+import org.eclipse.jpt.utility.internal.model.value.ListPropertyValueModelAdapter;
+import org.eclipse.jpt.utility.internal.model.value.PropertyAspectAdapter;
+import org.eclipse.jpt.utility.internal.model.value.PropertyListValueModelAdapter;
+import org.eclipse.jpt.utility.internal.model.value.SimplePropertyValueModel;
+import org.eclipse.jpt.utility.internal.model.value.TransformationPropertyValueModel;
+import org.eclipse.jpt.utility.internal.model.value.swing.ObjectListSelectionModel;
+import org.eclipse.jpt.utility.model.value.ListValueModel;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.jpt.utility.model.value.WritablePropertyValueModel;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Group;
+
+/**
+ * Here the layout of this pane:
+ * <pre>
+ * -----------------------------------------------------------------------------
+ * | - Join Columns ---------------------------------------------------------- |
+ * | |                                                                       | |
+ * | | x Override Default                                                    | |
+ * | |                                                                       | |
+ * | | --------------------------------------------------------------------- | |
+ * | | |                                                                   | | |
+ * | | | AddRemoveListPane                                                 | | |
+ * | | |                                                                   | | |
+ * | | --------------------------------------------------------------------- | |
+ * | ------------------------------------------------------------------------- |
+ * -----------------------------------------------------------------------------</pre>
+ *
+ * @see SecondaryTable
+ * @see EntityComposite - The container of this pane
+ * @see AddRemoveListPane
+ *
+ * @version 2.0
+ * @since 1.0
+ */
+public class PrimaryKeyJoinColumnsInSecondaryTableComposite extends Pane<SecondaryTable>
+{
+	private WritablePropertyValueModel<PrimaryKeyJoinColumn> joinColumnHolder;
+
+	/**
+	 * Creates a new <code>PrimaryKeyJoinColumnsInSecondaryTableComposite</code>.
+	 *
+	 * @param parentPane The parent container of this one
+	 * @param subjectHolder The holder of this pane's subject
+	 * @param parent The parent container
+	 */
+	public PrimaryKeyJoinColumnsInSecondaryTableComposite(Pane<?> parentPane,
+	                                                      PropertyValueModel<? extends SecondaryTable> subjectHolder,
+	                                                      Composite parent) {
+
+		super(parentPane, subjectHolder, parent);
+	}
+
+	/**
+	 * Creates a new <code>PrimaryKeyJoinColumnsInSecondaryTableComposite</code>.
+	 *
+	 * @param subjectHolder The holder of the subject <code>ISecondaryTable</code>
+	 * @param parent The parent container
+	 * @param widgetFactory The factory used to create various common widgets
+	 */
+	public PrimaryKeyJoinColumnsInSecondaryTableComposite(PropertyValueModel<? extends SecondaryTable> subjectHolder,
+	                                                      Composite parent,
+	                                                      WidgetFactory widgetFactory) {
+
+		super(subjectHolder, parent, widgetFactory);
+	}
+
+	private void addJoinColumn(PrimaryKeyJoinColumnInSecondaryTableStateObject stateObject) {
+
+		SecondaryTable secondaryTable = stateObject.getOwner();
+		int index = secondaryTable.specifiedPrimaryKeyJoinColumnsSize();
+
+		PrimaryKeyJoinColumn joinColumn = secondaryTable.addSpecifiedPrimaryKeyJoinColumn(index);
+		stateObject.updateJoinColumn(joinColumn);
+	}
+
+	private void addPrimaryKeyJoinColumn() {
+
+		PrimaryKeyJoinColumnInSecondaryTableDialog dialog =
+			new PrimaryKeyJoinColumnInSecondaryTableDialog(getShell(), getSubject(), null);
+
+		dialog.openDialog(buildAddPrimaryKeyJoinColumnPostExecution());
+	}
+
+	private PostExecution<PrimaryKeyJoinColumnInSecondaryTableDialog> buildAddPrimaryKeyJoinColumnPostExecution() {
+		return new PostExecution<PrimaryKeyJoinColumnInSecondaryTableDialog>() {
+			public void execute(PrimaryKeyJoinColumnInSecondaryTableDialog dialog) {
+				if (dialog.wasConfirmed()) {
+					addJoinColumn(dialog.getSubject());
+				}
+			}
+		};
+	}
+
+	private PropertyValueModel<Boolean> buildControlBooleanHolder() {
+		return new TransformationPropertyValueModel<SecondaryTable, Boolean>(getSubjectHolder()) {
+			@Override
+			protected Boolean transform(SecondaryTable value) {
+				if (value == null) {
+					return Boolean.FALSE;
+				}
+				return Boolean.valueOf(!value.isVirtual());
+			}
+		};
+	}
+
+	private PropertyValueModel<PrimaryKeyJoinColumn> buildDefaultJoinColumnHolder() {
+		return new PropertyAspectAdapter<SecondaryTable, PrimaryKeyJoinColumn>(getSubjectHolder(), SecondaryTable.DEFAULT_PRIMARY_KEY_JOIN_COLUMN) {
+			@Override
+			protected PrimaryKeyJoinColumn buildValue_() {
+				return subject.getDefaultPrimaryKeyJoinColumn();
+			}
+		};
+	}
+
+	private ListValueModel<PrimaryKeyJoinColumn> buildDefaultJoinColumnListHolder() {
+		return new PropertyListValueModelAdapter<PrimaryKeyJoinColumn>(
+			buildDefaultJoinColumnHolder()
+		);
+	}
+
+	private PostExecution<PrimaryKeyJoinColumnInSecondaryTableDialog> buildEditPrimaryKeyJoinColumnPostExecution() {
+		return new PostExecution<PrimaryKeyJoinColumnInSecondaryTableDialog>() {
+			public void execute(PrimaryKeyJoinColumnInSecondaryTableDialog dialog) {
+				if (dialog.wasConfirmed()) {
+					editPrimaryKeyJoinColumn(dialog.getSubject());
+				}
+			}
+		};
+	}
+
+	private String buildJoinColumnLabel(PrimaryKeyJoinColumn joinColumn) {
+
+		if (joinColumn.isVirtual()) {
+			return NLS.bind(
+				JptUiDetailsMessages.PrimaryKeyJoinColumnsComposite_mappingBetweenTwoParamsDefault,
+				joinColumn.getName(),
+				joinColumn.getReferencedColumnName()
+			);
+		}
+
+		if (joinColumn.getSpecifiedName() == null) {
+			if (joinColumn.getSpecifiedReferencedColumnName() == null) {
+				return NLS.bind(
+					JptUiDetailsMessages.PrimaryKeyJoinColumnsComposite_mappingBetweenTwoParamsBothDefault,
+					joinColumn.getName(),
+					joinColumn.getReferencedColumnName()
+				);
+			}
+
+			return NLS.bind(
+				JptUiDetailsMessages.PrimaryKeyJoinColumnsComposite_mappingBetweenTwoParamsFirstDefault,
+				joinColumn.getName(),
+				joinColumn.getReferencedColumnName()
+			);
+		}
+
+		if (joinColumn.getSpecifiedReferencedColumnName() == null) {
+			return NLS.bind(
+				JptUiDetailsMessages.PrimaryKeyJoinColumnsComposite_mappingBetweenTwoParamsSecDefault,
+				joinColumn.getName(),
+				joinColumn.getReferencedColumnName()
+			);
+		}
+
+		return NLS.bind(
+			JptUiDetailsMessages.PrimaryKeyJoinColumnsComposite_mappingBetweenTwoParams,
+			joinColumn.getName(),
+			joinColumn.getReferencedColumnName()
+		);
+	}
+
+	private ILabelProvider buildJoinColumnsListLabelProvider() {
+		return new LabelProvider() {
+			@Override
+			public String getText(Object element) {
+				PrimaryKeyJoinColumn joinColumn = (PrimaryKeyJoinColumn) element;
+				return buildJoinColumnLabel(joinColumn);
+			}
+		};
+	}
+
+	private WritablePropertyValueModel<Boolean> buildOverrideDefaultJoinColumnHolder() {
+		return new OverrideDefaultJoinColumnHolder();
+	}
+
+	private AddRemovePane.Adapter buildPrimaryKeyJoinColumnAdapter() {
+		return new AddRemovePane.AbstractAdapter() {
+			public void addNewItem(ObjectListSelectionModel listSelectionModel) {
+				addPrimaryKeyJoinColumn();
+			}
+
+			@Override
+			public boolean hasOptionalButton() {
+				return true;
+			}
+
+			@Override
+			public String optionalButtonText() {
+				return JptUiDetailsMessages.PrimaryKeyJoinColumnsComposite_edit;
+			}
+
+			@Override
+			public void optionOnSelection(ObjectListSelectionModel listSelectionModel) {
+				editPrimaryKeyJoinColumn(listSelectionModel);
+			}
+
+			public void removeSelectedItems(ObjectListSelectionModel listSelectionModel) {
+				removePrimaryKeyJoinColumn(listSelectionModel);
+			}
+		};
+	}
+
+	private WritablePropertyValueModel<PrimaryKeyJoinColumn> buildPrimaryKeyJoinColumnHolder() {
+		return new SimplePropertyValueModel<PrimaryKeyJoinColumn>();
+	}
+
+	private ListValueModel<PrimaryKeyJoinColumn> buildPrimaryKeyJoinColumnsListHolder() {
+		List<ListValueModel<PrimaryKeyJoinColumn>> list = new ArrayList<ListValueModel<PrimaryKeyJoinColumn>>();
+		list.add(buildSpecifiedJoinColumnsListHolder());
+		list.add(buildDefaultJoinColumnListHolder());
+		return new CompositeListValueModel<ListValueModel<PrimaryKeyJoinColumn>, PrimaryKeyJoinColumn>(list);
+	}
+
+	private ListValueModel<PrimaryKeyJoinColumn> buildPrimaryKeyJoinColumnsListModel() {
+		return new ItemPropertyListValueModelAdapter<PrimaryKeyJoinColumn>(
+			buildPrimaryKeyJoinColumnsListHolder(),
+			NamedColumn.SPECIFIED_NAME_PROPERTY,
+			NamedColumn.DEFAULT_NAME_PROPERTY,
+			BaseJoinColumn.SPECIFIED_REFERENCED_COLUMN_NAME_PROPERTY,
+			BaseJoinColumn.DEFAULT_REFERENCED_COLUMN_NAME_PROPERTY
+		);
+	}
+
+	private ListValueModel<PrimaryKeyJoinColumn> buildSpecifiedJoinColumnsListHolder() {
+		return new ListAspectAdapter<SecondaryTable, PrimaryKeyJoinColumn>(getSubjectHolder(), SecondaryTable.SPECIFIED_PRIMARY_KEY_JOIN_COLUMNS_LIST) {
+			@Override
+			protected ListIterator<PrimaryKeyJoinColumn> listIterator_() {
+				return subject.specifiedPrimaryKeyJoinColumns();
+			}
+
+			@Override
+			protected int size_() {
+				return subject.specifiedPrimaryKeyJoinColumnsSize();
+			}
+		};
+	}
+
+	private void editPrimaryKeyJoinColumn(ObjectListSelectionModel listSelectionModel) {
+
+		PrimaryKeyJoinColumn joinColumn = (PrimaryKeyJoinColumn) listSelectionModel.selectedValue();
+
+		PrimaryKeyJoinColumnInSecondaryTableDialog dialog =
+			new PrimaryKeyJoinColumnInSecondaryTableDialog(
+				getShell(),
+				getSubject(),
+				joinColumn
+			);
+
+		dialog.openDialog(buildEditPrimaryKeyJoinColumnPostExecution());
+	}
+
+	private void editPrimaryKeyJoinColumn(PrimaryKeyJoinColumnInSecondaryTableStateObject stateObject) {
+		stateObject.updateJoinColumn(stateObject.getJoinColumn());
+	}
+
+	@Override
+	protected void initialize() {
+		super.initialize();
+		joinColumnHolder = buildPrimaryKeyJoinColumnHolder();
+	}
+
+	@Override
+	protected void initializeLayout(Composite container) {
+
+		// Primary Key Join Columns group pane
+		Group groupPane = addTitledGroup(
+			container,
+			JptUiDetailsMessages.PrimaryKeyJoinColumnsComposite_primaryKeyJoinColumn
+		);
+
+		// Override Default check box
+		addCheckBox(
+			addSubPane(groupPane, 8),
+			JptUiDetailsMessages.PrimaryKeyJoinColumnsComposite_overrideDefaultPrimaryKeyJoinColumns,
+			buildOverrideDefaultJoinColumnHolder(),
+			null,
+			buildControlBooleanHolder()
+		);
+
+		// Primary Key Join Columns list pane
+		AddRemoveListPane<SecondaryTable> joinColumnsPane = new AddRemoveListPane<SecondaryTable>(
+			this,
+			groupPane,
+			buildPrimaryKeyJoinColumnAdapter(),
+			buildPrimaryKeyJoinColumnsListModel(),
+			joinColumnHolder,
+			buildJoinColumnsListLabelProvider(),
+			JpaHelpContextIds.MAPPING_JOIN_TABLE_COLUMNS
+		);
+
+		installPrimaryKeyJoinColumnListPaneEnabler(joinColumnsPane);
+	}
+
+	private void installPrimaryKeyJoinColumnListPaneEnabler(AddRemoveListPane<SecondaryTable> pkJoinColumnListPane) {
+
+		new PaneEnabler(
+			buildOverrideDefaultJoinColumnHolder(),
+			pkJoinColumnListPane
+		);
+	}
+
+	private void removePrimaryKeyJoinColumn(ObjectListSelectionModel listSelectionModel) {
+		int[] selectedIndices = listSelectionModel.selectedIndices();
+
+		for (int index = selectedIndices.length; --index >= 0; ) {
+			getSubject().removeSpecifiedPrimaryKeyJoinColumn(selectedIndices[index]);
+		}
+	}
+
+	private void updateJoinColumns(boolean selected) {
+
+		if (isPopulating()) {
+			return;
+		}
+
+		setPopulating(true);
+
+		try {
+			SecondaryTable secondaryTable = getSubject();
+
+			// Add a join column by creating a specified one using the default
+			// one if it exists
+			if (selected) {
+
+				PrimaryKeyJoinColumn defaultJoinColumn = secondaryTable.getDefaultPrimaryKeyJoinColumn();
+
+				if (defaultJoinColumn != null) {
+					String columnName = defaultJoinColumn.getDefaultName();
+					String referencedColumnName = defaultJoinColumn.getDefaultReferencedColumnName();
+
+					PrimaryKeyJoinColumn pkJoinColumn = secondaryTable.addSpecifiedPrimaryKeyJoinColumn(0);
+					pkJoinColumn.setSpecifiedName(columnName);
+					pkJoinColumn.setSpecifiedReferencedColumnName(referencedColumnName);
+
+					joinColumnHolder.setValue(pkJoinColumn);
+				}
+			}
+			else {
+				for (int index = secondaryTable.specifiedPrimaryKeyJoinColumnsSize(); --index >= 0; ) {
+					secondaryTable.removeSpecifiedPrimaryKeyJoinColumn(index);
+				}
+			}
+		}
+		finally {
+			setPopulating(false);
+		}
+	}
+
+	private class OverrideDefaultJoinColumnHolder extends ListPropertyValueModelAdapter<Boolean>
+	                                              implements WritablePropertyValueModel<Boolean> {
+
+		public OverrideDefaultJoinColumnHolder() {
+			super(buildSpecifiedJoinColumnsListHolder());
+		}
+
+		@Override
+		protected Boolean buildValue() {
+			if (getSubject() == null) {
+				return Boolean.FALSE;
+			}
+			return !getSubject().isVirtual() && listHolder.size() > 0;
+		}
+
+		public void setValue(Boolean value) {
+			updateJoinColumns(value);
+		}
+	}
+}
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/QueriesComposite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/QueriesComposite.java
new file mode 100644
index 0000000..65fe818
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/QueriesComposite.java
@@ -0,0 +1,313 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2010 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.ui.internal.details;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.ListIterator;
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.jface.window.Window;
+import org.eclipse.jpt.core.context.NamedNativeQuery;
+import org.eclipse.jpt.core.context.NamedQuery;
+import org.eclipse.jpt.core.context.Query;
+import org.eclipse.jpt.core.context.QueryContainer;
+import org.eclipse.jpt.ui.internal.JpaHelpContextIds;
+import org.eclipse.jpt.ui.internal.util.ControlSwitcher;
+import org.eclipse.jpt.ui.internal.widgets.AddRemoveListPane;
+import org.eclipse.jpt.ui.internal.widgets.Pane;
+import org.eclipse.jpt.ui.internal.widgets.AddRemovePane.Adapter;
+import org.eclipse.jpt.utility.internal.CollectionTools;
+import org.eclipse.jpt.utility.internal.Transformer;
+import org.eclipse.jpt.utility.internal.model.value.CompositeListValueModel;
+import org.eclipse.jpt.utility.internal.model.value.ItemPropertyListValueModelAdapter;
+import org.eclipse.jpt.utility.internal.model.value.ListAspectAdapter;
+import org.eclipse.jpt.utility.internal.model.value.SimplePropertyValueModel;
+import org.eclipse.jpt.utility.internal.model.value.TransformationPropertyValueModel;
+import org.eclipse.jpt.utility.internal.model.value.swing.ObjectListSelectionModel;
+import org.eclipse.jpt.utility.model.value.ListValueModel;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.jpt.utility.model.value.WritablePropertyValueModel;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.ui.part.PageBook;
+
+/**
+ * This pane shows the list of named queries and named native queries.
+ * <p>
+ * Here the layout of this pane:
+ * <pre>
+ * -----------------------------------------------------------------------------
+ * | ------------------------------------------------------------------------- |
+ * | |                                                                       | |
+ * | | AddRemoveListPane                                                     | |
+ * | |                                                                       | |
+ * | ------------------------------------------------------------------------- |
+ * | ------------------------------------------------------------------------- |
+ * | |                                                                       | |
+ * | | NamedQueryPropertyComposite or NamedNativeQueryPropertyComposite      | |
+ * | |                                                                       | |
+ * | ------------------------------------------------------------------------- |
+ * -----------------------------------------------------------------------------</pre>
+ *
+ * @see Entity
+ * @see Query
+ * @see NamedNativeQuery
+ * @see NamedQuery
+ * @see AbstractEntityComposite - The parent container
+ * @see NamedNativeQueryPropertyComposite
+ * @see NamedQueryPropertyComposite
+ *
+ * @version 2.0
+ * @since 2.0
+ */
+public class QueriesComposite extends Pane<QueryContainer>
+{
+	private AddRemoveListPane<QueryContainer> listPane;
+	private NamedNativeQueryPropertyComposite namedNativeQueryPane;
+	private NamedQueryPropertyComposite<? extends NamedQuery> namedQueryPane;
+	private WritablePropertyValueModel<Query> queryHolder;
+
+
+	public QueriesComposite(
+		Pane<?> parentPane, 
+		PropertyValueModel<? extends QueryContainer> subjectHolder,
+		Composite parent) {
+
+			super(parentPane, subjectHolder, parent, false);
+	}
+	
+	private void addQuery() {
+		addQueryFromDialog(buildAddQueryDialog());
+	}
+	
+	protected AddQueryDialog buildAddQueryDialog() {
+		return new AddQueryDialog(getShell());
+	}
+
+	protected void addQueryFromDialog(AddQueryDialog dialog) {
+		if (dialog.open() != Window.OK) {
+			return;
+		}
+		String queryType = dialog.getQueryType();
+		Query query;
+		if (queryType == Query.NAMED_QUERY) {
+			query = this.getSubject().addNamedQuery(getSubject().namedQueriesSize());
+		}
+		else if (queryType == Query.NAMED_NATIVE_QUERY) {
+			query = this.getSubject().addNamedNativeQuery(getSubject().namedNativeQueriesSize());
+		}
+		else {
+			throw new IllegalArgumentException();
+		}
+		query.setName(dialog.getName());
+		this.getQueryHolder().setValue(query);//so that it gets selected in the List for the user to edit
+	}
+
+	private ListValueModel<Query> buildDisplayableQueriesListHolder() {
+		return new ItemPropertyListValueModelAdapter<Query>(
+			buildQueriesListHolder(),
+			Query.NAME_PROPERTY
+		);
+	}
+	
+	private AddRemoveListPane<QueryContainer> addListPane(Composite container) {
+
+		return new AddRemoveListPane<QueryContainer>(
+			this,
+			container,
+			buildQueriesAdapter(),
+			buildDisplayableQueriesListHolder(),
+			this.getQueryHolder(),
+			buildQueriesListLabelProvider(),
+			JpaHelpContextIds.MAPPING_NAMED_QUERIES
+		);
+	}
+
+	private ListValueModel<NamedNativeQuery> buildNamedNativeQueriesListHolder() {
+		return new ListAspectAdapter<QueryContainer, NamedNativeQuery>(
+			getSubjectHolder(),
+			QueryContainer.NAMED_NATIVE_QUERIES_LIST)
+		{
+			@Override
+			protected ListIterator<NamedNativeQuery> listIterator_() {
+				return this.subject.namedNativeQueries();
+			}
+
+			@Override
+			protected int size_() {
+				return this.subject.namedNativeQueriesSize();
+			}
+		};
+	}
+
+	private PropertyValueModel<NamedNativeQuery> buildNamedNativeQueryHolder() {
+		return new TransformationPropertyValueModel<Query, NamedNativeQuery>(this.getQueryHolder()) {
+			@Override
+			protected NamedNativeQuery transform_(Query value) {
+				return (value instanceof NamedNativeQuery) ? (NamedNativeQuery) value : null;
+			}
+		};
+	}
+
+	private ListValueModel<NamedQuery> buildNamedQueriesListHolder() {
+		return new ListAspectAdapter<QueryContainer, NamedQuery>(
+			getSubjectHolder(),
+			QueryContainer.NAMED_QUERIES_LIST)
+		{
+			@Override
+			protected ListIterator<NamedQuery> listIterator_() {
+				return this.subject.namedQueries();
+			}
+
+			@Override
+			protected int size_() {
+				return this.subject.namedQueriesSize();
+			}
+		};
+	}
+
+	private PropertyValueModel<NamedQuery> buildNamedQueryHolder() {
+		return new TransformationPropertyValueModel<Query, NamedQuery>(this.getQueryHolder()) {
+			@Override
+			protected NamedQuery transform_(Query value) {
+				return (value instanceof NamedQuery) ? (NamedQuery) value : null;
+			}
+		};
+	}
+
+	private Transformer<Query, Control> buildPaneTransformer() {
+		return new Transformer<Query, Control>() {
+			public Control transform(Query query) {
+
+				if (query == null) {
+					return null;
+				}
+
+				if (query instanceof NamedNativeQuery) {
+					return QueriesComposite.this.namedNativeQueryPane.getControl();
+				}
+
+				return QueriesComposite.this.namedQueryPane.getControl();
+			}
+		};
+	}
+	
+	private Adapter buildQueriesAdapter() {
+
+		return new AddRemoveListPane.AbstractAdapter() {
+
+			public void addNewItem(ObjectListSelectionModel listSelectionModel) {
+				addQuery();
+			}
+
+			public void removeSelectedItems(ObjectListSelectionModel listSelectionModel) {
+				for (Object item : listSelectionModel.selectedValues()) {
+					if (item instanceof NamedQuery) {
+						getSubject().removeNamedQuery((NamedQuery) item);
+					}
+					else {
+						getSubject().removeNamedNativeQuery((NamedNativeQuery) item);
+					}
+				}
+			}
+		};
+	}
+
+	private ListValueModel<Query> buildQueriesListHolder() {
+		List<ListValueModel<? extends Query>> list = new ArrayList<ListValueModel<? extends Query>>();
+		list.add(buildNamedQueriesListHolder());
+		list.add(buildNamedNativeQueriesListHolder());
+		return new CompositeListValueModel<ListValueModel<? extends Query>, Query>(list);
+	}
+
+	private ILabelProvider buildQueriesListLabelProvider() {
+		return new LabelProvider() {
+			@Override
+			public String getText(Object element) {
+				Query query = (Query) element;
+				String name = query.getName();
+
+				if (name == null) {
+					int index = -1;
+
+					if (query instanceof NamedQuery) {
+						index = CollectionTools.indexOf(getSubject().namedQueries(), query);
+					}
+					else {
+						index = CollectionTools.indexOf(getSubject().namedNativeQueries(), query);
+					}
+
+					name = NLS.bind(JptUiDetailsMessages.QueriesComposite_displayString, index);
+				}
+
+				return name;
+			}
+		};
+	}
+
+	private WritablePropertyValueModel<Query> buildQueryHolder() {
+		return new SimplePropertyValueModel<Query>();
+	}
+
+	@Override
+	public void enableWidgets(boolean enabled) {
+		super.enableWidgets(enabled);
+		this.listPane.enableWidgets(enabled);
+	}
+
+	@Override
+	protected void initialize() {
+		super.initialize();
+		this.queryHolder = buildQueryHolder();
+	}
+
+	@Override
+	protected void initializeLayout(Composite container) {
+
+		// List pane
+		this.listPane = this.addListPane(container);
+
+		// Property pane
+		PageBook pageBook = new PageBook(container, SWT.NULL);
+		pageBook.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+		// Named Query property pane
+		this.namedQueryPane = this.buildNamedQueryPropertyComposite(pageBook);
+
+		// Named Native Query property pane
+		this.namedNativeQueryPane = new NamedNativeQueryPropertyComposite(
+			this,
+			this.buildNamedNativeQueryHolder(),
+			pageBook
+		);
+
+		installPaneSwitcher(pageBook);
+	}
+	
+	protected NamedQueryPropertyComposite<? extends NamedQuery> buildNamedQueryPropertyComposite(PageBook pageBook) {
+		return new NamedQueryPropertyComposite<NamedQuery>(
+			this,
+			this.buildNamedQueryHolder(),
+			pageBook
+		);
+	}
+
+	private void installPaneSwitcher(PageBook pageBook) {
+		new ControlSwitcher(this.getQueryHolder(), this.buildPaneTransformer(), pageBook);
+	}
+	
+	protected WritablePropertyValueModel<Query> getQueryHolder() {
+		return queryHolder;
+	}
+}
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/QueryHintsComposite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/QueryHintsComposite.java
new file mode 100644
index 0000000..399e7c1
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/QueryHintsComposite.java
@@ -0,0 +1,339 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2009 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.ui.internal.details;
+
+import java.util.ListIterator;
+import org.eclipse.jface.viewers.CellEditor;
+import org.eclipse.jface.viewers.IBaseLabelProvider;
+import org.eclipse.jface.viewers.ICellModifier;
+import org.eclipse.jface.viewers.ITableLabelProvider;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.jface.viewers.TableViewer;
+import org.eclipse.jface.viewers.TextCellEditor;
+import org.eclipse.jpt.core.context.NamedQuery;
+import org.eclipse.jpt.core.context.Query;
+import org.eclipse.jpt.core.context.QueryHint;
+import org.eclipse.jpt.ui.internal.swt.ColumnAdapter;
+import org.eclipse.jpt.ui.internal.util.PaneEnabler;
+import org.eclipse.jpt.ui.internal.widgets.AddRemoveTablePane;
+import org.eclipse.jpt.ui.internal.widgets.Pane;
+import org.eclipse.jpt.ui.internal.widgets.AddRemovePane.Adapter;
+import org.eclipse.jpt.utility.internal.model.value.ListAspectAdapter;
+import org.eclipse.jpt.utility.internal.model.value.PropertyAspectAdapter;
+import org.eclipse.jpt.utility.internal.model.value.SimplePropertyValueModel;
+import org.eclipse.jpt.utility.internal.model.value.TransformationPropertyValueModel;
+import org.eclipse.jpt.utility.internal.model.value.swing.ObjectListSelectionModel;
+import org.eclipse.jpt.utility.model.value.ListValueModel;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.jpt.utility.model.value.WritablePropertyValueModel;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.TableItem;
+
+/**
+ * Here the layout of this pane:
+ * <pre>
+ * -----------------------------------------------------------------------------
+ * |                                                                           |
+ * | AddRemoveTablePane                                                        |
+ * |                                                                           |
+ * -----------------------------------------------------------------------------</pre>
+ *
+ * @see Query
+ * @see QueryHint
+ * @see AddRemoveTablePane
+ *
+ * @version 2.0
+ * @since 2.0
+ */
+@SuppressWarnings("nls")
+public class QueryHintsComposite extends Pane<Query>
+{
+	private WritablePropertyValueModel<QueryHint> queryHintHolder;
+
+	/**
+	 * Creates a new <code>QueryHintsComposite</code>.
+	 *
+	 * @param parentPane The parent pane of this one
+	 * @param parent The parent container
+	 */
+	public QueryHintsComposite(Pane<? extends Query> parentPane,
+	                           Composite container) {
+
+		super(parentPane, container);
+	}
+
+	private PropertyValueModel<Boolean> buildPaneEnableHolder() {
+		return new TransformationPropertyValueModel<Query, Boolean>(getSubjectHolder()) {
+			@Override
+			protected Boolean transform(Query query) {
+				return (query != null);
+			}
+		};
+	}
+
+	private Adapter buildQueryHintAdapter() {
+		return new AddRemoveTablePane.AbstractAdapter() {
+			public void addNewItem(ObjectListSelectionModel listSelectionModel) {
+				QueryHint queryHint = getSubject().addHint(getSubject().hintsSize());
+				queryHintHolder.setValue(queryHint);
+			}
+
+			public void removeSelectedItems(ObjectListSelectionModel listSelectionModel) {
+				for (Object item : listSelectionModel.selectedValues()) {
+					getSubject().removeHint((QueryHint) item);
+				}
+			}
+		};
+	}
+
+	private WritablePropertyValueModel<QueryHint> buildQueryHintHolder() {
+		return new SimplePropertyValueModel<QueryHint>();
+	};
+
+	private ITableLabelProvider buildQueryHintLabelProvider() {
+		return new TableLabelProvider();
+	}
+
+	private ListValueModel<QueryHint> buildQueryHintListHolder() {
+		return new ListAspectAdapter<Query, QueryHint>(getSubjectHolder(), NamedQuery.HINTS_LIST) {
+			@Override
+			protected ListIterator<QueryHint> listIterator_() {
+				return subject.hints();
+			}
+
+			@Override
+			protected int size_() {
+				return subject.hintsSize();
+			}
+		};
+	}
+
+	/*
+	 * (non-Javadoc)
+	 */
+	@Override
+	protected void initialize() {
+		super.initialize();
+		queryHintHolder = buildQueryHintHolder();
+	}
+
+	/*
+	 * (non-Javadoc)
+	 */
+	@Override
+	protected void initializeLayout(Composite container) {
+
+		TablePane tablePane = new TablePane(container);
+		installPaneEnabler(tablePane);
+	}
+
+	private PaneEnabler installPaneEnabler(TablePane tablePane) {
+		return new PaneEnabler(buildPaneEnableHolder(), tablePane);
+	}
+
+	private static class QueryHintColumnAdapter implements ColumnAdapter<QueryHint> {
+
+		static final int COLUMN_COUNT = 2;
+		static final int NAME_COLUMN_INDEX = 0;
+		static final int VALUE_COLUMN_INDEX = 1;
+
+		private WritablePropertyValueModel<String> buildNameHolder(QueryHint subject) {
+			return new PropertyAspectAdapter<QueryHint, String>(QueryHint.NAME_PROPERTY, subject) {
+				@Override
+				protected String buildValue_() {
+					return subject.getName();
+				}
+
+				@Override
+				protected void setValue_(String value) {
+					subject.setName(value);
+				}
+			};
+		}
+
+		private WritablePropertyValueModel<?> buildValueHolder(QueryHint subject) {
+			return new PropertyAspectAdapter<QueryHint, String>(QueryHint.VALUE_PROPERTY, subject) {
+				@Override
+				protected String buildValue_() {
+					return subject.getValue();
+				}
+
+				@Override
+				protected void setValue_(String value) {
+					subject.setValue(value);
+				}
+			};
+		}
+
+		public WritablePropertyValueModel<?>[] cellModels(QueryHint subject) {
+			WritablePropertyValueModel<?>[] models = new WritablePropertyValueModel<?>[COLUMN_COUNT];
+			models[NAME_COLUMN_INDEX]  = buildNameHolder(subject);
+			models[VALUE_COLUMN_INDEX] = buildValueHolder(subject);
+			return models;
+		}
+
+		public int columnCount() {
+			return COLUMN_COUNT;
+		}
+
+		public String columnName(int columnIndex) {
+
+			switch (columnIndex) {
+				case QueryHintColumnAdapter.NAME_COLUMN_INDEX: {
+					return JptUiDetailsMessages.QueryHintsComposite_nameColumn;
+				}
+
+				case QueryHintColumnAdapter.VALUE_COLUMN_INDEX: {
+					return JptUiDetailsMessages.QueryHintsComposite_valueColumn;
+				}
+
+				default: {
+					return null;
+				}
+			}
+		}
+	}
+
+	private class TableLabelProvider extends LabelProvider
+	                                 implements ITableLabelProvider {
+
+		public Image getColumnImage(Object element, int columnIndex) {
+			return null;
+		}
+
+		public String getColumnText(Object element, int columnIndex) {
+
+			QueryHint queryHint = (QueryHint) element;
+			String value = "";
+
+			switch (columnIndex) {
+				case QueryHintColumnAdapter.NAME_COLUMN_INDEX: {
+					value = queryHint.getName();
+					break;
+				}
+
+				case QueryHintColumnAdapter.VALUE_COLUMN_INDEX: {
+					value = queryHint.getValue();
+					break;
+				}
+			}
+
+			if (value == null) {
+				value = "";
+			}
+
+			return value;
+		}
+	}
+
+	private class TablePane extends AddRemoveTablePane<Query> {
+
+		private TablePane(Composite parent) {
+			super(QueryHintsComposite.this,
+			      parent,
+			      buildQueryHintAdapter(),
+			      buildQueryHintListHolder(),
+			      queryHintHolder,
+			      buildQueryHintLabelProvider());
+		}
+
+		private CellEditor[] buildCellEditors(Table table) {
+			return new CellEditor[] {
+				new TextCellEditor(table),
+				new TextCellEditor(table)
+			};
+		}
+
+		private ICellModifier buildCellModifier() {
+			return new ICellModifier() {
+
+				public boolean canModify(Object element, String property) {
+					return true;
+				}
+
+				public Object getValue(Object element, String property) {
+					QueryHint queryHint = (QueryHint) element;
+					String value = "";
+
+					if (property == QueryHint.NAME_PROPERTY) {
+						value = queryHint.getName();
+					}
+					else if (property == QueryHint.VALUE_PROPERTY) {
+						value = queryHint.getValue();
+					}
+
+					if (value == null) {
+						value = "";
+					}
+
+					return value;
+				}
+
+				public void modify(Object element, String property, Object value) {
+					QueryHint queryHint;
+
+					if (element instanceof TableItem) {
+						TableItem tableItem = (TableItem) element;
+						queryHint = (QueryHint) tableItem.getData();
+					}
+					else {
+						queryHint = (QueryHint) element;
+					}
+
+					if (property == QueryHint.NAME_PROPERTY) {
+						 queryHint.setName(value.toString());
+					}
+					else if (property == QueryHint.VALUE_PROPERTY) {
+						 queryHint.setValue(value.toString());
+					}
+				}
+			};
+		}
+
+		@Override
+		protected ColumnAdapter<?> buildColumnAdapter() {
+			return new QueryHintColumnAdapter();
+		}
+
+		private String[] buildColumnProperties() {
+			return new String[] {
+				QueryHint.NAME_PROPERTY,
+				QueryHint.VALUE_PROPERTY
+			};
+		}
+
+		@Override
+		protected void initializeMainComposite(Composite container,
+		                                       Adapter adapter,
+		                                       ListValueModel<?> listHolder,
+		                                       WritablePropertyValueModel<?> selectedItemHolder,
+		                                       IBaseLabelProvider labelProvider,
+		                                       String helpId) {
+
+			super.initializeMainComposite(
+				container,
+				adapter,
+				listHolder,
+				selectedItemHolder,
+				labelProvider,
+				helpId
+			);
+
+			Table table = getMainControl();
+
+			TableViewer tableViewer = new TableViewer(table);
+			tableViewer.setCellEditors(buildCellEditors(table));
+			tableViewer.setCellModifier(buildCellModifier());
+			tableViewer.setColumnProperties(buildColumnProperties());
+		}
+	}
+}
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/ReferenceTableComposite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/ReferenceTableComposite.java
new file mode 100644
index 0000000..5721341
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/ReferenceTableComposite.java
@@ -0,0 +1,424 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2010 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.ui.internal.details;
+
+import java.util.Collection;
+import java.util.ListIterator;
+
+import org.eclipse.jpt.core.context.JoinColumn;
+import org.eclipse.jpt.core.context.ReferenceTable;
+import org.eclipse.jpt.core.context.Table;
+import org.eclipse.jpt.db.Schema;
+import org.eclipse.jpt.db.SchemaContainer;
+import org.eclipse.jpt.ui.WidgetFactory;
+import org.eclipse.jpt.ui.internal.details.JoinColumnsComposite.JoinColumnsEditor;
+import org.eclipse.jpt.ui.internal.details.db.CatalogCombo;
+import org.eclipse.jpt.ui.internal.details.db.SchemaCombo;
+import org.eclipse.jpt.ui.internal.details.db.TableCombo;
+import org.eclipse.jpt.ui.internal.widgets.Pane;
+import org.eclipse.jpt.ui.internal.widgets.PostExecution;
+import org.eclipse.jpt.utility.internal.model.value.CachingTransformationPropertyValueModel;
+import org.eclipse.jpt.utility.internal.model.value.ListAspectAdapter;
+import org.eclipse.jpt.utility.internal.model.value.ListPropertyValueModelAdapter;
+import org.eclipse.jpt.utility.internal.model.value.ReadOnlyWritablePropertyValueModelWrapper;
+import org.eclipse.jpt.utility.internal.model.value.ValueListAdapter;
+import org.eclipse.jpt.utility.model.event.StateChangeEvent;
+import org.eclipse.jpt.utility.model.listener.StateChangeListener;
+import org.eclipse.jpt.utility.model.value.ListValueModel;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.jpt.utility.model.value.WritablePropertyValueModel;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+
+
+public abstract class ReferenceTableComposite<T extends ReferenceTable> extends Pane<T>
+{
+	protected Button overrideDefaultJoinColumnsCheckBox;
+
+	protected JoinColumnsComposite<T> joinColumnsComposite;
+
+	/**
+	 * Creates a new <code>ReferenceTableComposite</code>.
+	 *
+	 * @param parentPane The parent container of this one
+	 * @param subjectHolder The holder of this pane's subject
+	 * @param parent The parent container
+	 */
+	protected ReferenceTableComposite(
+			Pane<?> parentPane,
+			PropertyValueModel<? extends T> subjectHolder,
+			Composite parent) {
+
+		super(parentPane, subjectHolder, parent, false);
+	}
+
+	/**
+	 * Creates a new <code>ReferenceTableComposite</code>.
+	 *
+	 * @param subjectHolder The holder of the subject <code>CollectionTable2_0</code>
+	 * @param parent The parent container
+	 * @param widgetFactory The factory used to create various common widgets
+	 */
+	protected ReferenceTableComposite(PropertyValueModel<? extends T> subjectHolder,
+	                          Composite parent,
+	                          WidgetFactory widgetFactory) {
+
+		super(subjectHolder, parent, widgetFactory);
+	}
+
+
+	protected void installJoinColumnsPaneEnabler(JoinColumnsComposite<T> pane) {
+		pane.installJoinColumnsPaneEnabler(new JoinColumnPaneEnablerHolder());
+	}
+
+	private void addJoinColumn(T referenceTable) {
+
+		JoinColumnInReferenceTableDialog dialog =
+			new JoinColumnInReferenceTableDialog(getShell(), referenceTable, null);
+
+		dialog.openDialog(buildAddJoinColumnPostExecution());
+	}
+
+	private void addJoinColumnFromDialog(JoinColumnInReferenceTableStateObject stateObject) {
+		int index = getSubject().specifiedJoinColumnsSize();
+
+		JoinColumn joinColumn = getSubject().addSpecifiedJoinColumn(index);
+		stateObject.updateJoinColumn(joinColumn);
+		this.setSelectedJoinColumn(joinColumn);
+	}
+
+	private void setSelectedJoinColumn(JoinColumn joinColumn) {
+		this.joinColumnsComposite.setSelectedJoinColumn(joinColumn);
+	}
+
+	private PostExecution<JoinColumnInReferenceTableDialog> buildAddJoinColumnPostExecution() {
+		return new PostExecution<JoinColumnInReferenceTableDialog>() {
+			public void execute(JoinColumnInReferenceTableDialog dialog) {
+				if (dialog.wasConfirmed()) {
+					addJoinColumnFromDialog(dialog.getSubject());
+				}
+			}
+		};
+	}
+
+	private PostExecution<JoinColumnInReferenceTableDialog> buildEditJoinColumnPostExecution() {
+		return new PostExecution<JoinColumnInReferenceTableDialog>() {
+			public void execute(JoinColumnInReferenceTableDialog dialog) {
+				if (dialog.wasConfirmed()) {
+					editJoinColumn(dialog.getSubject());
+				}
+			}
+		};
+	}
+
+	protected JoinColumnsProvider buildJoinColumnsEditor() {
+		return new JoinColumnsProvider();
+	}
+
+	protected WritablePropertyValueModel<Boolean> buildOverrideDefaultJoinColumnHolder() {
+		return new OverrideDefaultJoinColumnHolder();
+	}
+		
+	private ListValueModel<JoinColumn> buildSpecifiedJoinColumnsListHolder() {
+		return new ListAspectAdapter<T, JoinColumn>(getSubjectHolder(), ReferenceTable.SPECIFIED_JOIN_COLUMNS_LIST) {
+			@Override
+			protected ListIterator<JoinColumn> listIterator_() {
+				return this.subject.specifiedJoinColumns();
+			}
+
+			@Override
+			protected int size_() {
+				return this.subject.specifiedJoinColumnsSize();
+			}
+		};
+	}
+
+	protected Composite addPane(Composite container, int groupBoxMargin) {
+		return addSubPane(container, 0, groupBoxMargin, 10, groupBoxMargin);
+	}
+
+	protected TableCombo<T> addTableCombo(Composite container) {
+
+		return new TableCombo<T>(this, container) {
+
+			@Override
+			protected void addPropertyNames(Collection<String> propertyNames) {
+				super.addPropertyNames(propertyNames);
+				propertyNames.add(Table.DEFAULT_NAME_PROPERTY);
+				propertyNames.add(Table.SPECIFIED_NAME_PROPERTY);
+				propertyNames.add(Table.DEFAULT_SCHEMA_PROPERTY);
+				propertyNames.add(Table.SPECIFIED_SCHEMA_PROPERTY);
+				propertyNames.add(Table.DEFAULT_CATALOG_PROPERTY);
+				propertyNames.add(Table.SPECIFIED_CATALOG_PROPERTY);
+			}
+
+			@Override
+			protected void propertyChanged(String propertyName) {
+				super.propertyChanged(propertyName);
+				if (propertyName == Table.DEFAULT_SCHEMA_PROPERTY 
+					|| propertyName == Table.SPECIFIED_SCHEMA_PROPERTY
+					|| propertyName == Table.DEFAULT_CATALOG_PROPERTY
+					|| propertyName == Table.SPECIFIED_CATALOG_PROPERTY ) {
+					repopulate();
+				}
+			}
+
+			@Override
+			protected String getDefaultValue() {
+				return this.getSubject().getDefaultName();
+			}
+
+			@Override
+			protected void setValue(String value) {
+				this.getSubject().setSpecifiedName(value);
+			}
+
+			@Override
+			protected String getValue() {
+				return this.getSubject().getSpecifiedName();
+			}
+
+			@Override
+			protected Schema getDbSchema_() {
+				return this.getSubject().getDbSchema();
+			}
+
+		};
+	}
+	
+	protected SchemaCombo<T> addSchemaCombo(Composite container) {
+
+		return new SchemaCombo<T>(this, container) {
+
+			@Override
+			protected void addPropertyNames(Collection<String> propertyNames) {
+				super.addPropertyNames(propertyNames);
+				propertyNames.add(Table.DEFAULT_SCHEMA_PROPERTY);
+				propertyNames.add(Table.SPECIFIED_SCHEMA_PROPERTY);
+				propertyNames.add(Table.DEFAULT_CATALOG_PROPERTY);
+				propertyNames.add(Table.SPECIFIED_CATALOG_PROPERTY);
+			}
+
+			@Override
+			protected void propertyChanged(String propertyName) {
+				super.propertyChanged(propertyName);
+				if (propertyName == Table.DEFAULT_CATALOG_PROPERTY
+					|| propertyName == Table.SPECIFIED_CATALOG_PROPERTY ) {
+					repopulate();
+				}
+			}
+
+			@Override
+			protected String getDefaultValue() {
+				return this.getSubject().getDefaultSchema();
+			}
+
+			@Override
+			protected void setValue(String value) {
+				this.getSubject().setSpecifiedSchema(value);
+			}
+
+			@Override
+			protected String getValue() {
+				return this.getSubject().getSpecifiedSchema();
+			}
+			
+			@Override
+			protected SchemaContainer getDbSchemaContainer_() {
+				return this.getSubject().getDbSchemaContainer();
+			}
+		};
+	}
+	
+	protected CatalogCombo<T> addCatalogCombo(Composite container) {
+
+		return new CatalogCombo<T>(this, container) {
+
+			@Override
+			protected void addPropertyNames(Collection<String> propertyNames) {
+				super.addPropertyNames(propertyNames);
+				propertyNames.add(Table.DEFAULT_CATALOG_PROPERTY);
+				propertyNames.add(Table.SPECIFIED_CATALOG_PROPERTY);
+			}
+
+			@Override
+			protected String getDefaultValue() {
+				return this.getSubject().getDefaultCatalog();
+			}
+
+			@Override
+			protected void setValue(String value) {
+				this.getSubject().setSpecifiedCatalog(value);
+			}
+
+			@Override
+			protected String getValue() {
+				return this.getSubject().getSpecifiedCatalog();
+			}
+		};
+	}
+
+	private void editJoinColumn(JoinColumn joinColumn) {
+
+		JoinColumnInReferenceTableDialog dialog =
+			new JoinColumnInReferenceTableDialog(getShell(), getSubject(), joinColumn);
+
+		dialog.openDialog(buildEditJoinColumnPostExecution());
+	}
+
+	private void editJoinColumn(JoinColumnInReferenceTableStateObject stateObject) {
+		stateObject.updateJoinColumn(stateObject.getJoinColumn());
+	}
+
+	private void updateJoinColumns() {
+		if (this.isPopulating()) {
+			return;
+		}
+		
+		T referenceTable = this.getSubject();
+		if (referenceTable == null) {
+			return;
+		}
+		
+		boolean selected = this.overrideDefaultJoinColumnsCheckBox.getSelection();
+		this.setPopulating(true);
+
+		try {
+			if (selected) {
+				referenceTable.convertDefaultToSpecifiedJoinColumn();
+				setSelectedJoinColumn(referenceTable.specifiedJoinColumns().next());
+			} else {
+				for (int index = referenceTable.specifiedJoinColumnsSize(); --index >= 0; ) {
+					referenceTable.removeSpecifiedJoinColumn(index);
+				}
+			}
+		} finally {
+			this.setPopulating(false);
+		}
+	}
+
+	private class JoinColumnsProvider implements JoinColumnsEditor<T> {
+
+		public void addJoinColumn(T subject) {
+			ReferenceTableComposite.this.addJoinColumn(subject);
+		}
+
+		public JoinColumn getDefaultJoinColumn(T subject) {
+			return subject.getDefaultJoinColumn();
+		}
+
+		public String getDefaultPropertyName() {
+			return ReferenceTable.DEFAULT_JOIN_COLUMN;
+		}
+
+		public void editJoinColumn(T subject, JoinColumn joinColumn) {
+			ReferenceTableComposite.this.editJoinColumn(joinColumn);
+		}
+
+		public boolean hasSpecifiedJoinColumns(T subject) {
+			return subject.hasSpecifiedJoinColumns();
+		}
+
+		public void removeJoinColumns(T subject, int[] selectedIndices) {
+			for (int index = selectedIndices.length; --index >= 0; ) {
+				subject.removeSpecifiedJoinColumn(selectedIndices[index]);
+			}
+		}
+
+		public ListIterator<JoinColumn> specifiedJoinColumns(T subject) {
+			return subject.specifiedJoinColumns();
+		}
+
+		public int specifiedJoinColumnsSize(T subject) {
+			return subject.specifiedJoinColumnsSize();
+		}
+
+		public String getSpecifiedJoinColumnsListPropertyName() {
+			return ReferenceTable.SPECIFIED_JOIN_COLUMNS_LIST;
+		}
+	}
+	
+	
+	private class OverrideDefaultJoinColumnHolder extends ListPropertyValueModelAdapter<Boolean>
+	    implements WritablePropertyValueModel<Boolean> {
+	
+		public OverrideDefaultJoinColumnHolder() {
+			super(buildSpecifiedJoinColumnsListHolder());
+		}
+	
+		@Override
+		protected Boolean buildValue() {
+			return Boolean.valueOf(this.listHolder.size() > 0);
+		}
+	
+		public void setValue(Boolean value) {
+			updateJoinColumns();
+		}
+	}
+
+	
+	private class JoinColumnPaneEnablerHolder 
+		extends CachingTransformationPropertyValueModel<T, Boolean> 
+	{
+		private StateChangeListener stateChangeListener;
+		
+		
+		public JoinColumnPaneEnablerHolder() {
+			super(
+				new ValueListAdapter<T>(
+					new ReadOnlyWritablePropertyValueModelWrapper(getSubjectHolder()), 
+					ReferenceTable.SPECIFIED_JOIN_COLUMNS_LIST));
+			this.stateChangeListener = buildStateChangeListener();
+		}
+		
+		
+		private StateChangeListener buildStateChangeListener() {
+			return new StateChangeListener() {
+				public void stateChanged(StateChangeEvent event) {
+					valueStateChanged(event);
+				}
+			};
+		}
+		
+		private void valueStateChanged(StateChangeEvent event) {
+			Object oldValue = this.cachedValue;
+			Object newValue = transformNew(this.valueHolder.getValue());
+			firePropertyChanged(VALUE, oldValue, newValue);
+		}
+		
+		@Override
+		protected Boolean transform(T value) {
+			if (value == null) {
+				return Boolean.FALSE;
+			}
+			return super.transform(value);
+		}
+		
+		@Override
+		protected Boolean transform_(T value) {
+			boolean virtual = ReferenceTableComposite.this.isParentVirtual(value);
+			return Boolean.valueOf(! virtual && value.specifiedJoinColumnsSize() > 0);
+		}
+		
+		@Override
+		protected void engageModel() {
+			super.engageModel();
+			this.valueHolder.addStateChangeListener(this.stateChangeListener);
+		}
+		
+		@Override
+		protected void disengageModel() {
+			this.valueHolder.removeStateChangeListener(this.stateChangeListener);
+			super.disengageModel();
+		}
+	}
+	
+	protected abstract boolean isParentVirtual(T referenceTable);
+}
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/SecondaryTableDialog.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/SecondaryTableDialog.java
new file mode 100644
index 0000000..b460f8d
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/SecondaryTableDialog.java
@@ -0,0 +1,450 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2009 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.ui.internal.details;
+
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jpt.core.JpaProject;
+import org.eclipse.jpt.core.context.SecondaryTable;
+import org.eclipse.jpt.db.Database;
+import org.eclipse.jpt.db.Schema;
+import org.eclipse.jpt.db.SchemaContainer;
+import org.eclipse.jpt.utility.internal.StringTools;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Shell;
+
+/**
+ * Clients can use this dialog to prompt the user for SecondaryTable settings.
+ * Use the following once the dialog is closed:
+ *     @see #getSelectedTable()
+ *     @see #getSelectedCatalog()
+ *     @see #getSelectedSchema()
+ */
+public class SecondaryTableDialog extends Dialog {
+
+	private final JpaProject jpaProject;
+
+	/**
+	 * when creating a new SecondaryTable, 'secondaryTable' will be null
+	 */
+	private final SecondaryTable secondaryTable;
+	private final String defaultCatalog;
+	private final String defaultSchema;
+	
+	protected Combo tableCombo;
+	protected Combo catalogCombo;
+	protected Combo schemaCombo;
+
+	// these values are set upon close
+	private String selectedTable;
+	private String selectedSchema;
+	private String selectedCatalog;
+
+
+	// ********** constructors **********
+
+	/**
+	 * Use this constructor to create a new secondary table
+	 */
+	public SecondaryTableDialog(Shell parent, JpaProject jpaProject, String defaultCatalog, String defaultSchema) {
+		this(parent, jpaProject, null, defaultCatalog, defaultSchema);
+	}
+
+	/**
+	 * Use this constructor to edit an existing secondary table
+	 */
+	public SecondaryTableDialog(Shell parent, JpaProject jpaProject, SecondaryTable secondaryTable) {
+		this(parent, jpaProject, secondaryTable, secondaryTable.getDefaultCatalog(), secondaryTable.getDefaultSchema());
+	}
+
+	/**
+	 * internal constructor
+	 */
+	protected SecondaryTableDialog(Shell parent, JpaProject jpaProject, SecondaryTable secondaryTable, String defaultCatalog, String defaultSchema) {
+		super(parent);
+		this.jpaProject = jpaProject;
+		this.secondaryTable = secondaryTable;
+		this.defaultCatalog = defaultCatalog;
+		this.defaultSchema = defaultSchema;
+	}
+
+
+	// ********** open **********
+
+	@Override
+	protected Point getInitialSize() {
+		Point size = super.getInitialSize();
+		size.x = this.convertWidthInCharsToPixels(50);  // ???
+		return size;
+	}
+
+	@Override
+	protected void configureShell(Shell shell) {
+		super.configureShell(shell);
+		shell.setText(this.getTitle());
+	}
+
+	protected String getTitle() {
+		return (this.secondaryTable == null) ?
+						JptUiDetailsMessages.SecondaryTableDialog_addSecondaryTable
+					:
+						JptUiDetailsMessages.SecondaryTableDialog_editSecondaryTable;
+	}
+
+	@Override
+	protected Control createDialogArea(Composite parent) {
+		Composite composite = (Composite) super.createDialogArea(parent);
+		GridLayout gridLayout = (GridLayout) composite.getLayout();
+		gridLayout.numColumns = 2;
+
+		// table
+		Label tableLabel = new Label(composite, SWT.LEFT);
+		tableLabel.setText(JptUiDetailsMessages.SecondaryTableDialog_name);
+		GridData gridData = new GridData();
+		tableLabel.setLayoutData(gridData);
+
+		this.tableCombo = new Combo(composite, SWT.LEFT);
+		gridData = new GridData();
+		gridData.grabExcessHorizontalSpace = true;
+		gridData.horizontalAlignment = SWT.FILL;
+		this.tableCombo.setLayoutData(gridData);
+
+		// catalog
+		Label catalogLabel = new Label(composite, SWT.LEFT);
+		catalogLabel.setText(JptUiDetailsMessages.SecondaryTableDialog_catalog);
+		gridData = new GridData();
+		catalogLabel.setLayoutData(gridData);
+
+		this.catalogCombo = new Combo(composite, SWT.LEFT);
+		gridData = new GridData();
+		gridData.grabExcessHorizontalSpace = true;
+		gridData.horizontalAlignment = SWT.FILL;
+		this.catalogCombo.setLayoutData(gridData);
+
+		// schema
+		Label schemaLabel = new Label(composite, SWT.LEFT);
+		schemaLabel.setText(JptUiDetailsMessages.SecondaryTableDialog_schema);
+		gridData = new GridData();
+		schemaLabel.setLayoutData(gridData);
+
+		this.schemaCombo = new Combo(composite, SWT.LEFT);
+		gridData = new GridData();
+		gridData.grabExcessHorizontalSpace = true;
+		gridData.horizontalAlignment = SWT.FILL;
+		this.schemaCombo.setLayoutData(gridData);
+
+		this.initializeCatalogCombo();
+		this.initializeSchemaCombo();
+		this.initializeTableCombo();
+
+		return composite;
+	}
+
+	@Override
+	protected Control createContents(Composite parent) {
+		Composite composite = (Composite) super.createContents(parent);
+
+		this.tableCombo.addModifyListener(buildTableModifyListener());
+		this.catalogCombo.addSelectionListener(this.buildCatalogSelectionListener());
+		this.schemaCombo.addSelectionListener(this.buildSchemaSelectionListener());
+		this.refreshButtons();
+		return composite;
+	}
+
+	protected void initializeCatalogCombo() {
+		this.populateCatalogCombo();
+
+		if (this.isAddDialog()) {
+			this.catalogCombo.select(0);  // out-of-bounds index is ignored
+		} else {
+			String specifiedCatalog = this.secondaryTable.getSpecifiedCatalog();
+			if (specifiedCatalog == null) {
+				this.catalogCombo.select(0);  // out-of-bounds index is ignored
+			} else {
+				this.catalogCombo.setText(specifiedCatalog);
+			}
+		}
+	}
+
+	protected void populateCatalogCombo() {
+		Database database = this.getDatabase();
+		if ((database != null) && ! database.supportsCatalogs()) {
+			this.catalogCombo.setEnabled(false);
+			return;
+		}
+
+		// add the default catalog first
+		if (this.defaultCatalog != null) {
+			this.catalogCombo.add(NLS.bind(JptUiDetailsMessages.SecondaryTableDialog_defaultCatalog, this.defaultCatalog));
+		}
+
+		if (database != null) {
+			for (String identifier : database.getSortedCatalogIdentifiers()) {
+				this.catalogCombo.add(identifier);
+			}
+		}
+	}
+
+	protected void initializeSchemaCombo() {
+		this.populateSchemaCombo();
+
+		if (this.isAddDialog()) {
+			this.schemaCombo.select(0);  // out-of-bounds index is ignored
+		} else {
+			String specifiedSchema = this.secondaryTable.getSpecifiedSchema();
+			if (specifiedSchema == null) {
+				this.schemaCombo.select(0);  // out-of-bounds index is ignored
+			} else {
+				this.schemaCombo.setText(specifiedSchema);
+			}
+		}
+	}
+
+	// assume the catalog combo has been populated by now
+	protected void populateSchemaCombo() {
+		// add the default schema first
+		if (this.defaultSchema != null) {
+			this.schemaCombo.add(NLS.bind(JptUiDetailsMessages.SecondaryTableDialog_defaultSchema, this.defaultSchema));
+		}
+
+		SchemaContainer sc = this.getCurrentDbSchemaContainer();
+		if (sc != null) {
+			for (String identifier : sc.getSortedSchemaIdentifiers()) {
+				this.schemaCombo.add(identifier);
+			}
+		}
+	}
+
+	protected void initializeTableCombo() {
+		this.populateTableCombo();
+
+		if (this.isEditDialog()) {
+			String specifiedName = this.secondaryTable.getSpecifiedName();
+			if (specifiedName != null) {
+				this.tableCombo.setText(specifiedName);
+			}
+		}
+	}
+
+	// assume the schema combo has been populated by now
+	protected void populateTableCombo() {
+		// we don't need to add a "default" to the table combo
+		Schema dbSchema = this.getCurrentDbSchema();
+		if (dbSchema != null) {
+			for (String identifier : dbSchema.getSortedTableIdentifiers()) {
+				this.tableCombo.add(identifier);
+			}
+		}
+	}
+
+
+	// ********** listeners **********
+
+	protected SelectionListener buildCatalogSelectionListener() {
+		return new SelectionListener() {
+			public void widgetSelected(SelectionEvent event) {
+				SecondaryTableDialog.this.selectedCatalogChanged();
+			}
+			public void widgetDefaultSelected(SelectionEvent e) {
+				SecondaryTableDialog.this.selectedCatalogChanged();
+			}
+			@Override
+			public String toString() {
+				return "catalog selection listener"; //$NON-NLS-1$
+			}
+		};
+	}
+
+	protected void selectedCatalogChanged() {
+		this.refreshSchemaCombo();
+		this.refreshTableCombo();
+	}
+
+	protected void refreshSchemaCombo() {
+		String schema = this.schemaCombo.getText();
+		this.schemaCombo.removeAll();
+		this.populateSchemaCombo();
+		this.schemaCombo.setText(schema);
+	}
+
+	protected SelectionListener buildSchemaSelectionListener() {
+		return new SelectionListener() {
+			public void widgetSelected(SelectionEvent event) {
+				SecondaryTableDialog.this.selectedSchemaChanged();
+			}
+			public void widgetDefaultSelected(SelectionEvent e) {
+				SecondaryTableDialog.this.selectedSchemaChanged();
+			}
+			@Override
+			public String toString() {
+				return "schema selection listener"; //$NON-NLS-1$
+			}
+		};
+	}
+
+	protected void selectedSchemaChanged() {
+		this.refreshTableCombo();
+	}
+
+	protected void refreshTableCombo() {
+		String table = this.tableCombo.getText();
+		this.tableCombo.removeAll();
+		this.populateTableCombo();
+		this.tableCombo.setText(table);
+	}
+
+	protected ModifyListener buildTableModifyListener() {
+		return new ModifyListener() {
+			public void modifyText(ModifyEvent event) {
+				SecondaryTableDialog.this.tableChanged();
+			}
+			@Override
+			public String toString() {
+				return "table modify listener"; //$NON-NLS-1$
+			}
+		};
+	}
+
+	protected void tableChanged() {
+		this.refreshButtons();
+	}
+
+	// ********** convenience methods **********
+
+	protected boolean isAddDialog() {
+		return this.secondaryTable == null;
+	}
+
+	protected boolean isEditDialog() {
+		return ! this.isAddDialog();
+	}
+
+	protected Database getDatabase() {
+		return this.jpaProject.getDataSource().getDatabase();
+	}
+
+	protected SchemaContainer getCurrentDbSchemaContainer() {
+		Database database = this.getDatabase();
+		if (database == null) {
+			return null;
+		}
+		if ( ! database.supportsCatalogs()) {
+			return database;
+		}
+		String catalog = this.getCurrentCatalog();
+		return (catalog == null) ? null : database.getCatalogForIdentifier(catalog);
+	}
+
+	protected String getCurrentCatalog() {
+		if ((this.defaultCatalog != null) && (this.catalogCombo.getSelectionIndex() == 0)) {
+			return this.defaultCatalog;
+		}
+		return convertText(this.catalogCombo);
+	}
+
+	protected Schema getCurrentDbSchema() {
+		String schema = this.getCurrentSchema();
+		if (schema == null) {
+			return null;
+		}
+		SchemaContainer sc = this.getCurrentDbSchemaContainer();
+		return (sc == null) ? null : sc.getSchemaForIdentifier(schema);
+	}
+
+	protected String getCurrentSchema() {
+		if ((this.defaultSchema != null) && (this.schemaCombo.getSelectionIndex() == 0)) {
+			return this.defaultSchema;
+		}
+		return convertText(this.schemaCombo);
+	}
+	
+	protected void refreshButtons() {
+		this.getButton(IDialogConstants.OK_ID).setEnabled(this.validateEntryValues());
+	}
+
+	protected boolean validateEntryValues() {
+		return ! StringTools.stringIsEmpty(this.tableCombo.getText());
+	}
+
+
+	// ********** close **********
+
+	/**
+	 * set all the various values queried by clients once the dialog is closed
+	 */
+	@Override
+	public boolean close() {
+		this.selectedTable = this.tableCombo.getText();
+		this.selectedCatalog = convertText(this.catalogCombo, this.defaultCatalog);
+		this.selectedSchema = convertText(this.schemaCombo, this.defaultSchema);
+		return super.close();
+	}
+
+	/**
+	 * return null if:
+	 *   - the default value is selected
+	 *   - the combo's text is empty
+	 */
+	protected static String convertText(Combo combo, String defaultText) {
+		// if the default text is present, then it will be the combo's first selection
+		if ((defaultText != null) && (combo.getSelectionIndex() == 0)) {
+			return null;
+		}
+		return convertText(combo);
+	}
+
+	/**
+	 * return null if the combo's text is empty
+	 */
+	protected static String convertText(Combo combo) {
+		String text = combo.getText();
+		return (text.length() == 0) ? null : text;
+	}
+
+
+	// ********** public API **********
+
+	/**
+	 * Return the selected table. Return an empty string if nothing
+	 * is selected (since there is no default).
+	 */
+	public String getSelectedTable() {
+		return this.selectedTable;
+	}
+
+	/**
+	 * Return the selected catalog. Return null if either nothing or
+	 * the default catalog is selected.
+	 */
+	public String getSelectedCatalog() {
+		return this.selectedCatalog;
+	}
+
+	/**
+	 * Return the selected schema. Return null if either nothing or
+	 * the default schema is selected.
+	 */
+	public String getSelectedSchema() {
+		return this.selectedSchema;
+	}
+
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/SequenceGeneratorComposite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/SequenceGeneratorComposite.java
new file mode 100644
index 0000000..7879e97
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/SequenceGeneratorComposite.java
@@ -0,0 +1,136 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2009 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.ui.internal.details;
+
+import java.util.Collection;
+import org.eclipse.jpt.core.JpaProject;
+import org.eclipse.jpt.core.context.GeneratorContainer;
+import org.eclipse.jpt.core.context.IdMapping;
+import org.eclipse.jpt.core.context.SequenceGenerator;
+import org.eclipse.jpt.db.Schema;
+import org.eclipse.jpt.ui.internal.JpaHelpContextIds;
+import org.eclipse.jpt.ui.internal.details.db.SequenceCombo;
+import org.eclipse.jpt.ui.internal.widgets.Pane;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * Here the layout of this pane:
+ * <pre>
+ * -----------------------------------------------------------------------------
+ * |                     ----------------------------------------------------- |
+ * | Name:               | I                                                 | |
+ * |                     ----------------------------------------------------- |
+ * |                     ----------------------------------------------------- |
+ * | Sequence Generator: | SequenceCombo                                     | |
+ * |                     ----------------------------------------------------- |
+ * |                     -------------                                         |
+ * | Allocation Size:    | I       |I|                                         |
+ * |                     -------------                                         |
+ * |                     -------------                                         |
+ * | Initial Value:      |         |I|                                         |
+ * |                     -------------                                         |
+ * -----------------------------------------------------------------------------</pre>
+ *
+ * @see IdMapping
+ * @see SequenceGenerator
+ * @see IdMappingGenerationComposite - The parent container
+ * @see SequenceCombo
+ *
+ * @version 2.2
+ * @since 1.0
+ */
+public class SequenceGeneratorComposite extends GeneratorComposite<SequenceGenerator>
+{
+	
+	public SequenceGeneratorComposite(Pane<?> parentPane,
+        							PropertyValueModel<SequenceGenerator> subjectHolder,
+        							Composite parent,
+        							GeneratorBuilder<SequenceGenerator> builder) {
+
+		super(parentPane, subjectHolder, parent, builder);
+	}
+
+	@Override
+	protected String getPropertyName() {
+		return GeneratorContainer.SEQUENCE_GENERATOR_PROPERTY;
+	}
+
+	@Override
+	protected void initializeLayout(Composite container) {
+
+		// Name widgets
+		addLabeledText(
+			container,
+			JptUiDetailsMessages.SequenceGeneratorComposite_name,
+			buildGeneratorNameHolder(),
+			JpaHelpContextIds.MAPPING_SEQUENCE_GENERATOR_NAME
+		);
+
+		// Sequence Generator widgets
+		addLabeledComposite(
+			container,
+			JptUiDetailsMessages.SequenceGeneratorComposite_sequence,
+			buildSequenceNameCombo(container),
+			JpaHelpContextIds.MAPPING_SEQUENCE_GENERATOR_SEQUENCE
+		);
+
+		addAllocationSizeCombo(container);
+		addInitialValueCombo(container);
+	}
+
+	protected SequenceCombo<SequenceGenerator> buildSequenceNameCombo(Composite parent) {
+
+		return new SequenceCombo<SequenceGenerator>(this, getSubjectHolder(), parent) {
+
+			@Override
+			protected void addPropertyNames(Collection<String> propertyNames) {
+				super.addPropertyNames(propertyNames);
+				propertyNames.add(SequenceGenerator.DEFAULT_SEQUENCE_NAME_PROPERTY);
+				propertyNames.add(SequenceGenerator.SPECIFIED_SEQUENCE_NAME_PROPERTY);
+			}
+
+			@Override
+			protected String getDefaultValue() {
+				return this.getSubject().getDefaultSequenceName();
+			}
+
+			@Override
+			protected void setValue(String value) {
+				retrieveGenerator().setSpecifiedSequenceName(value);
+			}
+
+			@Override
+			protected String getValue() {
+				return (getSubject() == null) ? null : getSubject().getSpecifiedSequenceName();
+			}
+
+			@Override
+			protected boolean nullSubjectIsAllowed() {
+				return true;
+			}
+
+			/**
+			 * subject may be null, so delegate to the composite
+			 */
+			@Override
+			protected JpaProject getJpaProject() {
+				return SequenceGeneratorComposite.this.getJpaProject();
+			}
+
+			@Override
+			protected Schema getDbSchema_() {
+				return this.getSubject().getDbSchema();
+			}
+
+		};
+	}
+
+}
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/TableComposite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/TableComposite.java
new file mode 100644
index 0000000..a5d4f8e
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/TableComposite.java
@@ -0,0 +1,239 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 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.ui.internal.details;
+
+import java.util.Collection;
+
+import org.eclipse.jpt.core.context.Entity;
+import org.eclipse.jpt.core.context.Table;
+import org.eclipse.jpt.db.Schema;
+import org.eclipse.jpt.db.SchemaContainer;
+import org.eclipse.jpt.ui.internal.JpaHelpContextIds;
+import org.eclipse.jpt.ui.internal.details.db.CatalogCombo;
+import org.eclipse.jpt.ui.internal.details.db.SchemaCombo;
+import org.eclipse.jpt.ui.internal.details.db.TableCombo;
+import org.eclipse.jpt.ui.internal.util.PaneEnabler;
+import org.eclipse.jpt.ui.internal.widgets.Pane;
+import org.eclipse.jpt.utility.internal.model.value.PropertyAspectAdapter;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.jpt.utility.model.value.WritablePropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Group;
+
+/**
+ * Here the layout of this pane:
+ * <pre>
+ * -----------------------------------------------------------------------------
+ * |                                                                           |
+ * | - Table ----------------------------------------------------------------- |
+ * | |          ------------------------------------------------------------ | |
+ * | | Table:   | TableCombo                                               | | |
+ * | |          ------------------------------------------------------------ | |
+ * | |          ------------------------------------------------------------ | |
+ * | | Catalog: | CatalogCombo                                             | | |
+ * | |          ------------------------------------------------------------ | |
+ * | |          ------------------------------------------------------------ | |
+ * | | Schema:  | SchemaCombo                                              | | |
+ * | |          ------------------------------------------------------------ | |
+ * | ------------------------------------------------------------------------- |
+ * -----------------------------------------------------------------------------</pre>
+ *
+ * @see Table
+ * @see EntityComposite - The parent container
+ * @see TableCombo
+ * @see CatalogCombo
+ * @see SchemaCombo
+ *
+ * @TODO repopulate this panel based on the Entity table changing
+ *
+ * @version 2.0
+ * @since 1.0
+ */
+public class TableComposite extends Pane<Entity>
+{
+	/**
+	 * Creates a new <code>TableComposite</code>.
+	 *
+	 * @param parentPane The parent container of this one
+	 * @param subjectHolder The holder of the subject
+	 * @param parent The parent container
+	 */
+	public TableComposite(Pane<? extends Entity> parentPane,
+	                      Composite parent) {
+
+		super(parentPane, parent, false);
+	}
+
+	@Override
+	protected void initializeLayout(Composite container) {
+
+		// Table group pane
+		Group tableGroupPane = addTitledGroup(
+			container,
+			JptUiDetailsMessages.TableComposite_tableSection
+		);
+
+		PropertyValueModel<Table> subjectHolder = buildTableHolder();
+		// Table widgets
+		addLabeledComposite(
+			tableGroupPane,
+			JptUiDetailsMessages.TableChooser_label,
+			addTableCombo(subjectHolder, tableGroupPane),
+			JpaHelpContextIds.ENTITY_TABLE
+		);
+
+		// Catalog widgets
+		addLabeledComposite(
+			tableGroupPane,
+			JptUiDetailsMessages.CatalogChooser_label,
+			addCatalogCombo(subjectHolder, tableGroupPane),
+			JpaHelpContextIds.ENTITY_CATALOG
+		);
+
+		// Schema widgets
+		addLabeledComposite(
+			tableGroupPane,
+			JptUiDetailsMessages.SchemaChooser_label,
+			addSchemaCombo(subjectHolder, tableGroupPane),
+			JpaHelpContextIds.ENTITY_SCHEMA
+		);
+		
+		new PaneEnabler(buildTableEnabledHolder(), this);
+	}
+	
+	protected WritablePropertyValueModel<Table> buildTableHolder() {
+		
+		return new PropertyAspectAdapter<Entity, Table>(getSubjectHolder(), Entity.TABLE_IS_UNDEFINED_PROPERTY) {
+			@Override
+			protected Table buildValue_() {
+				return this.subject.tableIsUndefined() ? null : this.subject.getTable();
+			}
+		};
+	}
+	
+	protected WritablePropertyValueModel<Boolean> buildTableEnabledHolder() {
+		return new PropertyAspectAdapter<Entity, Boolean>(getSubjectHolder(), Entity.SPECIFIED_TABLE_IS_ALLOWED_PROPERTY) {
+			@Override
+			protected Boolean buildValue_() {
+				return Boolean.valueOf(this.subject.specifiedTableIsAllowed());
+			}
+		};
+	}
+
+	private CatalogCombo<Table> addCatalogCombo(PropertyValueModel<Table> tableHolder, Composite container) {
+
+		return new CatalogCombo<Table>(this, tableHolder, container) {
+
+			@Override
+			protected void addPropertyNames(Collection<String> propertyNames) {
+				super.addPropertyNames(propertyNames);
+				propertyNames.add(Table.DEFAULT_CATALOG_PROPERTY);
+				propertyNames.add(Table.SPECIFIED_CATALOG_PROPERTY);
+			}
+
+			@Override
+			protected String getDefaultValue() {
+				return getSubject().getDefaultCatalog();
+			}
+
+			@Override
+			protected void setValue(String value) {
+				getSubject().setSpecifiedCatalog(value);
+			}
+
+			@Override
+			protected String getValue() {
+				return getSubject().getSpecifiedCatalog();
+			}
+		};
+	}
+
+	private SchemaCombo<Table> addSchemaCombo(PropertyValueModel<Table> subjectHolder, Composite container) {
+
+		return new SchemaCombo<Table>(this, subjectHolder, container) {
+
+			@Override
+			protected void addPropertyNames(Collection<String> propertyNames) {
+				super.addPropertyNames(propertyNames);
+				propertyNames.add(Table.DEFAULT_SCHEMA_PROPERTY);
+				propertyNames.add(Table.SPECIFIED_SCHEMA_PROPERTY);
+			}
+
+			@Override
+			protected String getDefaultValue() {
+				return getSubject().getDefaultSchema();
+			}
+
+			@Override
+			protected void setValue(String value) {
+				getSubject().setSpecifiedSchema(value);
+			}
+
+			@Override
+			protected String getValue() {
+				return getSubject().getSpecifiedSchema();
+			}
+
+			@Override
+			protected SchemaContainer getDbSchemaContainer_() {
+				return this.getSubject().getDbSchemaContainer();
+			}
+		};
+	}
+
+	private TableCombo<Table> addTableCombo(PropertyValueModel<Table> subjectHolder, Composite container) {
+
+		return new TableCombo<Table>(this, subjectHolder, container) {
+
+			@Override
+			protected void addPropertyNames(Collection<String> propertyNames) {
+				super.addPropertyNames(propertyNames);
+				propertyNames.add(Table.DEFAULT_NAME_PROPERTY);
+				propertyNames.add(Table.SPECIFIED_NAME_PROPERTY);
+				propertyNames.add(Table.DEFAULT_SCHEMA_PROPERTY);
+				propertyNames.add(Table.SPECIFIED_SCHEMA_PROPERTY);
+				propertyNames.add(Table.DEFAULT_CATALOG_PROPERTY);
+				propertyNames.add(Table.SPECIFIED_CATALOG_PROPERTY);
+			}
+
+			@Override
+			protected void propertyChanged(String propertyName) {
+				super.propertyChanged(propertyName);
+				if (propertyName == Table.DEFAULT_SCHEMA_PROPERTY 
+					|| propertyName == Table.SPECIFIED_SCHEMA_PROPERTY
+					|| propertyName == Table.DEFAULT_CATALOG_PROPERTY
+					|| propertyName == Table.SPECIFIED_CATALOG_PROPERTY ) {
+					repopulate();
+				}
+			}
+			
+			@Override
+			protected String getDefaultValue() {
+				return this.getSubject().getDefaultName();
+			}
+
+			@Override
+			protected void setValue(String value) {
+				this.getSubject().setSpecifiedName(value);
+			}
+
+			@Override
+			protected String getValue() {
+				return this.getSubject().getSpecifiedName();
+			}
+
+			@Override
+			protected Schema getDbSchema_() {
+				return this.getSubject().getDbSchema();
+			}
+		};
+	}
+
+}
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/TableGeneratorComposite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/TableGeneratorComposite.java
new file mode 100644
index 0000000..1a33eb9
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/TableGeneratorComposite.java
@@ -0,0 +1,499 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2009 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.ui.internal.details;
+
+import java.util.Collection;
+import org.eclipse.jpt.core.JpaProject;
+import org.eclipse.jpt.core.context.GeneratorContainer;
+import org.eclipse.jpt.core.context.IdMapping;
+import org.eclipse.jpt.core.context.TableGenerator;
+import org.eclipse.jpt.db.Schema;
+import org.eclipse.jpt.db.SchemaContainer;
+import org.eclipse.jpt.db.Table;
+import org.eclipse.jpt.ui.internal.JpaHelpContextIds;
+import org.eclipse.jpt.ui.internal.details.db.CatalogCombo;
+import org.eclipse.jpt.ui.internal.details.db.ColumnCombo;
+import org.eclipse.jpt.ui.internal.details.db.SchemaCombo;
+import org.eclipse.jpt.ui.internal.details.db.TableCombo;
+import org.eclipse.jpt.ui.internal.widgets.Pane;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * Here the layout of this pane:
+ * <pre>
+ * -----------------------------------------------------------------------------
+ * |                           ----------------------------------------------- |
+ * | Name:                     | I                                           | |
+ * |                           ----------------------------------------------- |
+ * |                           ----------------------------------------------- |
+ * | Table:                    | TableCombo                                  | |
+ * |                           ----------------------------------------------- |
+ * |                           ----------------------------------------------- |
+ * | Catalog:                  | CatalogCombo                                | |
+ * |                           ----------------------------------------------- |
+ * |                           ----------------------------------------------- |
+ * | Schema:                   | SchemaCombo                                 | |
+ * |                           ----------------------------------------------- |
+ * |                           ----------------------------------------------- |
+ * | Primary Key Column:       | ColumnCombo                                 | |
+ * |                           ----------------------------------------------- |
+ * |                           ----------------------------------------------- |
+ * | Value Column:             | ColumnCombo                                 | |
+ * |                           ----------------------------------------------- |
+ * |                           ----------------------------------------------- |
+ * | Primary Key Column Value: | ColumnCombo                                 | |
+ * |                           ----------------------------------------------- |
+ * |                           -------------                                   |
+ * | Allocation Size:          | I       |I|  Default (XX)                     |
+ * |                           -------------                                   |
+ * |                           -------------                                   |
+ * | Initial Value:            | I       |I|  Default (XX)                     |
+ * |                           -------------                                   |
+ * -----------------------------------------------------------------------------</pre>
+ *
+ * @see IdMapping
+ * @see TableGenerator
+ * @see IdMappingGenerationComposite - The parent container
+ * @see CatalogCombo
+ * @see ColumnCombo
+ * @see SchemaCombo
+ * @see TableCombo
+ *
+ * @version 2.2
+ * @since 1.0
+ */
+public class TableGeneratorComposite extends GeneratorComposite<TableGenerator>
+{
+
+	
+	public TableGeneratorComposite(Pane<?> parentPane,
+        							PropertyValueModel<TableGenerator> subjectHolder,
+        							Composite parent,
+        							GeneratorBuilder<TableGenerator> builder) {
+
+		super(parentPane, subjectHolder, parent, builder);
+	}
+
+	@Override
+	protected String getPropertyName() {
+		return GeneratorContainer.TABLE_GENERATOR_PROPERTY;
+	}
+
+	
+	@Override
+	protected void initializeLayout(Composite container) {
+
+		// Name widgets
+		addLabeledText(
+			container,
+			JptUiDetailsMessages.TableGeneratorComposite_name,
+			buildGeneratorNameHolder(),
+			JpaHelpContextIds.MAPPING_TABLE_GENERATOR_NAME
+		);
+
+		// Table widgets
+		addLabeledComposite(
+			container,
+			JptUiDetailsMessages.TableGeneratorComposite_table,
+			addTableNameCombo(container),
+			JpaHelpContextIds.MAPPING_TABLE_GENERATOR_TABLE
+		);
+
+		// Schema widgets
+		addLabeledComposite(
+			container,
+			JptUiDetailsMessages.TableGeneratorComposite_schema,
+			addSchemaCombo(container),
+			JpaHelpContextIds.MAPPING_TABLE_GENERATOR_SCHEMA
+		);
+
+		// Catalog widgets
+		addLabeledComposite(
+			container,
+			JptUiDetailsMessages.TableGeneratorComposite_catalog,
+			addCatalogCombo(container),
+			JpaHelpContextIds.MAPPING_TABLE_GENERATOR_CATALOG
+		);
+
+		// Primary Key Column widgets
+		addLabeledComposite(
+			container,
+			JptUiDetailsMessages.TableGeneratorComposite_pkColumn,
+			addPkColumnNameCombo(container),
+			JpaHelpContextIds.MAPPING_TABLE_GENERATOR_PRIMARY_KEY_COLUMN
+		);
+
+		// Value Column widgets
+		addLabeledComposite(
+			container,
+			JptUiDetailsMessages.TableGeneratorComposite_valueColumn,
+			addValueColumnCombo(container),
+			JpaHelpContextIds.MAPPING_TABLE_GENERATOR_VALUE_COLUMN
+		);
+
+		// Primary Key Column Value widgets
+		addLabeledComposite(
+			container,
+			JptUiDetailsMessages.TableGeneratorComposite_pkColumnValue,
+			addPkColumnValueCombo(container),
+			JpaHelpContextIds.MAPPING_TABLE_GENERATOR_PRIMARY_KEY_COLUMN_VALUE
+		);
+
+		addAllocationSizeCombo(container);
+		addInitialValueCombo(container);
+	}	
+
+	private CatalogCombo<TableGenerator> addCatalogCombo(Composite container) {
+
+		return new CatalogCombo<TableGenerator>(this, getSubjectHolder(), container) {
+
+			@Override
+			protected void addPropertyNames(Collection<String> propertyNames) {
+				super.addPropertyNames(propertyNames);
+				propertyNames.add(TableGenerator.DEFAULT_CATALOG_PROPERTY);
+				propertyNames.add(TableGenerator.SPECIFIED_CATALOG_PROPERTY);
+			}
+
+			@Override
+			protected String getDefaultValue() {
+				return getSubject().getDefaultCatalog();
+			}
+
+			@Override
+			protected boolean nullSubjectIsAllowed() {
+				return true;
+			}
+
+			/**
+			 * subject may be null, so delegate to the composite
+			 */
+			@Override
+			protected JpaProject getJpaProject() {
+				return TableGeneratorComposite.this.getJpaProject();
+			}
+
+			@Override
+			protected void setValue(String value) {
+				retrieveGenerator().setSpecifiedCatalog(value);
+			}
+
+			@Override
+			protected String getValue() {
+				return getSubject().getSpecifiedCatalog();
+			}
+		};
+	}
+
+	private ColumnCombo<TableGenerator> addPkColumnNameCombo(Composite parent) {
+
+		return new ColumnCombo<TableGenerator>(this, getSubjectHolder(), parent) {
+
+			@Override
+			protected void addPropertyNames(Collection<String> propertyNames) {
+				super.addPropertyNames(propertyNames);
+				propertyNames.add(TableGenerator.DEFAULT_PK_COLUMN_NAME_PROPERTY);
+				propertyNames.add(TableGenerator.SPECIFIED_PK_COLUMN_NAME_PROPERTY);
+				propertyNames.add(TableGenerator.DEFAULT_TABLE_PROPERTY);
+				propertyNames.add(TableGenerator.SPECIFIED_TABLE_PROPERTY);
+			}
+
+			@Override
+			protected void propertyChanged(String propertyName) {
+				if (propertyName == TableGenerator.DEFAULT_TABLE_PROPERTY ||
+				    propertyName == TableGenerator.SPECIFIED_TABLE_PROPERTY) {
+					this.repopulateComboBox();
+				} else {
+					super.propertyChanged(propertyName);
+				}
+			}
+
+			@Override
+			protected String getDefaultValue() {
+				return getSubject().getDefaultPkColumnName();
+			}
+
+			@Override
+			protected boolean nullSubjectIsAllowed() {
+				return true;
+			}
+
+			/**
+			 * subject may be null, so delegate to the composite
+			 */
+			@Override
+			protected JpaProject getJpaProject() {
+				return TableGeneratorComposite.this.getJpaProject();
+			}
+
+			@Override
+			protected void setValue(String value) {
+				retrieveGenerator().setSpecifiedPkColumnName(value);
+			}
+
+			@Override
+			protected Table getDbTable_() {
+				return getSubject().getDbTable();
+			}
+
+			@Override
+			protected String getValue() {
+				return getSubject().getSpecifiedPkColumnName();
+			}
+		};
+	}
+
+	private ColumnCombo<TableGenerator> addPkColumnValueCombo(Composite parent) {
+
+		return new ColumnCombo<TableGenerator>(this, getSubjectHolder(), parent) {
+
+			@Override
+			protected void addPropertyNames(Collection<String> propertyNames) {
+				super.addPropertyNames(propertyNames);
+				propertyNames.add(TableGenerator.DEFAULT_PK_COLUMN_VALUE_PROPERTY);
+				propertyNames.add(TableGenerator.SPECIFIED_PK_COLUMN_VALUE_PROPERTY);
+			}
+
+			@Override
+			protected String getDefaultValue() {
+				return getSubject().getDefaultPkColumnValue();
+			}
+
+			@Override
+			protected boolean nullSubjectIsAllowed() {
+				return true;
+			}
+
+			/**
+			 * subject may be null, so delegate to the composite
+			 */
+			@Override
+			protected JpaProject getJpaProject() {
+				return TableGeneratorComposite.this.getJpaProject();
+			}
+
+			@Override
+			protected void setValue(String value) {
+				retrieveGenerator().setSpecifiedPkColumnValue(value);
+			}
+
+			@Override
+			protected Table getDbTable_() {
+				return getSubject().getDbTable();
+			}
+
+			@Override
+			protected String getValue() {
+				return getSubject().getSpecifiedPkColumnValue();
+			}
+		};
+	}
+
+	private SchemaCombo<TableGenerator> addSchemaCombo(Composite container) {
+
+		return new SchemaCombo<TableGenerator>(this, getSubjectHolder(), container) {
+
+			@Override
+			protected void addPropertyNames(Collection<String> propertyNames) {
+				super.addPropertyNames(propertyNames);
+				propertyNames.add(TableGenerator.DEFAULT_SCHEMA_PROPERTY);
+				propertyNames.add(TableGenerator.SPECIFIED_SCHEMA_PROPERTY);
+				propertyNames.add(TableGenerator.DEFAULT_CATALOG_PROPERTY);
+				propertyNames.add(TableGenerator.SPECIFIED_CATALOG_PROPERTY);
+			}
+
+			@Override
+			protected void propertyChanged(String propertyName) {
+				if (propertyName == TableGenerator.DEFAULT_CATALOG_PROPERTY
+					|| propertyName == TableGenerator.SPECIFIED_CATALOG_PROPERTY ) {
+					repopulateComboBox();
+				}
+				else {
+					super.propertyChanged(propertyName);
+				}
+			}
+
+			@Override
+			protected String getDefaultValue() {
+				return getSubject().getDefaultSchema();
+			}
+
+			@Override
+			protected boolean nullSubjectIsAllowed() {
+				return true;
+			}
+
+			/**
+			 * subject may be null, so delegate to the composite
+			 */
+			@Override
+			protected JpaProject getJpaProject() {
+				return TableGeneratorComposite.this.getJpaProject();
+			}
+
+			@Override
+			protected void setValue(String value) {
+				retrieveGenerator().setSpecifiedSchema(value);
+			}
+
+			@Override
+			protected String getValue() {
+				return getSubject().getSpecifiedSchema();
+			}
+
+			@Override
+			protected SchemaContainer getDbSchemaContainer() {
+				TableGenerator tg = this.getSubject();
+				if (tg != null) {
+					return tg.getDbSchemaContainer();
+				}
+				return TableGeneratorComposite.this.getSubject().getContextDefaultDbSchemaContainer();
+			}
+			
+			@Override
+			protected SchemaContainer getDbSchemaContainer_() {
+				// we overrode #getDbSchemaContainer() instead
+				throw new UnsupportedOperationException();
+			}
+		};
+	}
+
+	private TableCombo<TableGenerator> addTableNameCombo(Composite parent) {
+
+		return new TableCombo<TableGenerator>(this, getSubjectHolder(), parent) {
+
+			@Override
+			protected void addPropertyNames(Collection<String> propertyNames) {
+				super.addPropertyNames(propertyNames);
+				propertyNames.add(TableGenerator.DEFAULT_TABLE_PROPERTY);
+				propertyNames.add(TableGenerator.SPECIFIED_TABLE_PROPERTY);
+				propertyNames.add(TableGenerator.DEFAULT_SCHEMA_PROPERTY);
+				propertyNames.add(TableGenerator.SPECIFIED_SCHEMA_PROPERTY);
+				propertyNames.add(TableGenerator.DEFAULT_CATALOG_PROPERTY);
+				propertyNames.add(TableGenerator.SPECIFIED_CATALOG_PROPERTY);
+			}
+
+			@Override
+			protected void propertyChanged(String propertyName) {
+				if (propertyName == TableGenerator.DEFAULT_SCHEMA_PROPERTY 
+					|| propertyName == TableGenerator.SPECIFIED_SCHEMA_PROPERTY
+					|| propertyName == TableGenerator.DEFAULT_CATALOG_PROPERTY
+					|| propertyName == TableGenerator.SPECIFIED_CATALOG_PROPERTY ) {
+					repopulateComboBox();
+				}
+				else {
+					super.propertyChanged(propertyName);
+				}
+			}
+
+			@Override
+			protected String getDefaultValue() {
+				return this.getSubject().getDefaultTable();
+			}
+
+			@Override
+			protected boolean nullSubjectIsAllowed() {
+				return true;
+			}
+
+			/**
+			 * subject may be null, so delegate to the composite
+			 */
+			@Override
+			protected JpaProject getJpaProject() {
+				return TableGeneratorComposite.this.getJpaProject();
+			}
+
+			@Override
+			protected void setValue(String value) {
+				retrieveGenerator().setSpecifiedTable(value);
+			}
+
+			@Override
+			protected String getValue() {
+				return this.getSubject().getSpecifiedTable();
+			}
+
+			@Override
+			protected Schema getDbSchema() {
+				TableGenerator tg = this.getSubject();
+				if (tg != null) {
+					return tg.getDbSchema();
+				}
+				return TableGeneratorComposite.this.getSubject().getContextDefaultDbSchema();
+			}
+
+			@Override
+			protected Schema getDbSchema_() {
+				// we overrode #getDbSchema() instead
+				throw new UnsupportedOperationException();
+			}
+
+		};
+	}
+
+	private ColumnCombo<TableGenerator> addValueColumnCombo(Composite parent) {
+
+		return new ColumnCombo<TableGenerator>(this, getSubjectHolder(), parent) {
+
+			@Override
+			protected void addPropertyNames(Collection<String> propertyNames) {
+				super.addPropertyNames(propertyNames);
+				propertyNames.add(TableGenerator.DEFAULT_VALUE_COLUMN_NAME_PROPERTY);
+				propertyNames.add(TableGenerator.SPECIFIED_VALUE_COLUMN_NAME_PROPERTY);
+				propertyNames.add(TableGenerator.DEFAULT_TABLE_PROPERTY);
+				propertyNames.add(TableGenerator.SPECIFIED_TABLE_PROPERTY);
+			}
+
+			@Override
+			protected void propertyChanged(String propertyName) {
+				if (propertyName == TableGenerator.DEFAULT_TABLE_PROPERTY ||
+				    propertyName == TableGenerator.SPECIFIED_TABLE_PROPERTY) {
+					this.repopulateComboBox();
+				} else {
+					super.propertyChanged(propertyName);
+				}
+			}
+
+			@Override
+			protected String getDefaultValue() {
+				return getSubject().getDefaultValueColumnName();
+			}
+
+			@Override
+			protected boolean nullSubjectIsAllowed() {
+				return true;
+			}
+
+			/**
+			 * subject may be null, so delegate to the composite
+			 */
+			@Override
+			protected JpaProject getJpaProject() {
+				return TableGeneratorComposite.this.getJpaProject();
+			}
+
+			@Override
+			protected void setValue(String value) {
+				retrieveGenerator().setSpecifiedValueColumnName(value);
+			}
+
+			@Override
+			protected Table getDbTable_() {
+				return getSubject().getDbTable();
+			}
+
+			@Override
+			protected String getValue() {
+				return getSubject().getSpecifiedValueColumnName();
+			}
+		};
+	}
+}
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/TargetEntityComposite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/TargetEntityComposite.java
new file mode 100644
index 0000000..f7d9696
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/TargetEntityComposite.java
@@ -0,0 +1,130 @@
+/*******************************************************************************
+* Copyright (c) 2006, 2010 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.ui.internal.details;
+
+import org.eclipse.jpt.core.JpaProject;
+import org.eclipse.jpt.core.context.RelationshipMapping;
+import org.eclipse.jpt.ui.internal.JpaHelpContextIds;
+import org.eclipse.jpt.ui.internal.widgets.ClassChooserComboPane;
+import org.eclipse.jpt.ui.internal.widgets.Pane;
+import org.eclipse.jpt.utility.internal.model.value.PropertyAspectAdapter;
+import org.eclipse.jpt.utility.internal.model.value.PropertyListValueModelAdapter;
+import org.eclipse.jpt.utility.model.value.ListValueModel;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.jpt.utility.model.value.WritablePropertyValueModel;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ *  target entity hyperlink label, combo and browse button 
+ */
+public class TargetEntityComposite
+	extends ClassChooserComboPane<RelationshipMapping>
+{
+	/**
+	 * Creates a new <code>TargetEntityComposite</code>.
+	 *
+	 * @param parentPane The parent container of this one
+	 * @param parent The parent container
+	 */
+	public TargetEntityComposite(
+			Pane<? extends RelationshipMapping> parentPane,
+	        Composite parent) {
+		
+		super(parentPane, parent);
+	}
+	
+	
+	@Override
+	protected String getClassName() {
+		return getSubject().getTargetEntity();
+	}
+
+	@Override
+	protected void setClassName(String className) {
+		this.getSubject().setSpecifiedTargetEntity(className);
+	}
+
+    @Override
+    protected String getLabelText() {
+    	return JptUiDetailsMessages.TargetEntityChooser_label;
+    }
+   
+    @Override
+    protected String getHelpId() {
+    	return JpaHelpContextIds.MAPPING_TARGET_ENTITY;
+    }
+   
+    @Override
+    protected JpaProject getJpaProject() {
+    	return getSubject().getJpaProject();
+    }
+
+    @Override
+    protected char getEnclosingTypeSeparator() {
+    	return getSubject().getTargetEntityEnclosingTypeSeparator();
+    }
+    
+    @Override
+	protected WritablePropertyValueModel<String> buildTextHolder() {
+		return new PropertyAspectAdapter<RelationshipMapping, String>(this.getSubjectHolder(), RelationshipMapping.SPECIFIED_TARGET_ENTITY_PROPERTY) {
+			@Override
+			protected String buildValue_() {
+
+				String name = this.subject.getSpecifiedTargetEntity();
+				if (name == null) {
+					name = TargetEntityComposite.this.getDefaultValue(this.subject);
+				}
+				return name;
+			}
+
+			@Override
+			protected void setValue_(String value) {
+
+				if (getDefaultValue(this.subject).equals(value)) {
+					value = null;
+				}
+				this.subject.setSpecifiedTargetEntity(value);
+			}
+		};
+    }
+
+	@Override
+	protected ListValueModel<String> buildClassListHolder() {
+		return this.buildDefaultProfilerListHolder();
+	}
+
+	private ListValueModel<String> buildDefaultProfilerListHolder() {
+		return new PropertyListValueModelAdapter<String>(
+			this.buildDefaultProfilerHolder()
+		);
+	}
+
+	private PropertyValueModel<String> buildDefaultProfilerHolder() {
+		return new PropertyAspectAdapter<RelationshipMapping, String>(this.getSubjectHolder(), RelationshipMapping.DEFAULT_TARGET_ENTITY_PROPERTY) {
+			@Override
+			protected String buildValue_() {
+				return TargetEntityComposite.this.getDefaultValue(this.subject);
+			}
+		};
+	}
+
+	private String getDefaultValue(RelationshipMapping subject) {
+		String defaultValue = subject.getDefaultTargetEntity();
+
+		if (defaultValue != null) {
+			return NLS.bind(
+				JptUiDetailsMessages.DefaultWithOneParam,
+				defaultValue
+			);
+		}
+		return JptUiDetailsMessages.DefaultEmpty;
+	}
+}
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/TemporalTypeComposite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/TemporalTypeComposite.java
new file mode 100644
index 0000000..b53f242
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/TemporalTypeComposite.java
@@ -0,0 +1,139 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2010 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.ui.internal.details;
+
+import java.util.Comparator;
+import java.util.List;
+
+import org.eclipse.jpt.core.context.TemporalConverter;
+import org.eclipse.jpt.core.context.TemporalType;
+import org.eclipse.jpt.ui.WidgetFactory;
+import org.eclipse.jpt.ui.internal.util.SWTUtil;
+import org.eclipse.jpt.ui.internal.widgets.Pane;
+import org.eclipse.jpt.utility.internal.CollectionTools;
+import org.eclipse.jpt.utility.internal.StringConverter;
+import org.eclipse.jpt.utility.internal.model.value.PropertyAspectAdapter;
+import org.eclipse.jpt.utility.internal.model.value.SimpleListValueModel;
+import org.eclipse.jpt.utility.internal.model.value.TransformationPropertyValueModel;
+import org.eclipse.jpt.utility.model.value.ListValueModel;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.jpt.utility.model.value.WritablePropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+import com.ibm.icu.text.Collator;
+
+/**
+ * Here the layout of this pane:
+ * <pre>
+ * -----------------------------------------------------------------------------
+ * |           --------------------------------------------------------------- |
+ * | Temporal: |                                                           |v| |
+ * |           --------------------------------------------------------------- |
+ * -----------------------------------------------------------------------------</pre>
+ *
+ * @see ColumnMapping
+ * @see TemporalType
+ * @see BasicMappingComposite - A container of this pane
+ * @see IdMappingComposite - A container of this pane
+ * @see VersionMappingComposite - A container of this pane
+ *
+ * @version 2.0
+ * @since 1.0
+ */
+public class TemporalTypeComposite extends Pane<TemporalConverter> {
+
+	/**
+	 * Creates a new <code>TemporalTypeComposite</code>.
+	 *
+	 * @param parentPane The parent container of this one
+	 * @param parent The parent container
+	 */
+	public TemporalTypeComposite(PropertyValueModel<? extends TemporalConverter> subjectHolder,
+	                             Composite parent,
+	                             WidgetFactory widgetFactory) {
+
+		super(subjectHolder, parent, widgetFactory);
+	}
+
+	@Override
+	protected void initializeLayout(Composite container) {
+
+		this.addCombo(
+			container,
+			buildTemporalTypeListHolder(),
+			buildTemporalTypeHolder(),
+			buildTemporalTypeConverter(),
+			buildBooleanHolder()
+		);
+	}
+
+	private WritablePropertyValueModel<TemporalType> buildTemporalTypeHolder() {
+		return new PropertyAspectAdapter<TemporalConverter, TemporalType>(getSubjectHolder(), TemporalConverter.TEMPORAL_TYPE_PROPERTY) {
+			@Override
+			protected TemporalType buildValue_() {
+				return subject.getTemporalType();
+			}
+
+			@Override
+			protected void setValue_(TemporalType value) {
+				subject.setTemporalType(value);
+			}
+		};
+	}
+
+	private ListValueModel<TemporalType> buildTemporalTypeListHolder() {
+		return new SimpleListValueModel<TemporalType>(
+			buildSortedTemporalTypeList()
+		);
+	}
+	
+	private List<TemporalType> buildSortedTemporalTypeList() {
+		return CollectionTools.sort(CollectionTools.list(TemporalType.values()), this.buildTemporalTypeComparator());
+	}
+
+	private Comparator<TemporalType> buildTemporalTypeComparator() {
+		return new Comparator<TemporalType>() {
+			public int compare(TemporalType type1, TemporalType type2) {
+				String displayString1 = displayString(type1);
+				String displayString2 = displayString(type2);
+				return Collator.getInstance().compare(displayString1, displayString2);
+			}
+		};
+	}
+
+	private StringConverter<TemporalType> buildTemporalTypeConverter() {
+		return new StringConverter<TemporalType>() {
+			public String convertToString(TemporalType value) {
+				return (value == null) ? null : displayString(value);
+			}
+		};
+	}
+
+	String displayString(TemporalType temporalType) {
+		return SWTUtil.buildDisplayString(
+			JptUiDetailsMessages.class,
+			TemporalTypeComposite.this,
+			temporalType.name()
+		);
+	}
+	
+	protected PropertyValueModel<Boolean> buildBooleanHolder() {
+		return new TransformationPropertyValueModel<TemporalConverter, Boolean>(getSubjectHolder()) {
+			@Override
+			protected Boolean transform(TemporalConverter value) {
+				if (getSubject() != null && getSubject().getParent().getPersistentAttribute().isVirtual()) {
+					return Boolean.FALSE;
+				}
+				return Boolean.valueOf(value != null);
+			}
+		};
+	}
+
+}
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/TransientMappingComposite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/TransientMappingComposite.java
new file mode 100644
index 0000000..cb8c728
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/TransientMappingComposite.java
@@ -0,0 +1,50 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 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.ui.internal.details;
+
+import org.eclipse.jpt.core.context.TransientMapping;
+import org.eclipse.jpt.ui.WidgetFactory;
+import org.eclipse.jpt.ui.details.JpaComposite;
+import org.eclipse.jpt.ui.internal.widgets.Pane;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * This pane does not have any widgets.
+ *
+ * @see TransientMapping
+ *
+ * @version 2.0
+ * @since 1.0
+ */
+public class TransientMappingComposite extends Pane<TransientMapping>
+                                       implements JpaComposite
+{
+	/**
+	 * Creates a new <code>TransientMappingComposite</code>.
+	 *
+	 * @param subjectHolder The holder of the subject <code>ITransientMapping</code>
+	 * @param parent The parent container
+	 * @param widgetFactory The factory used to create various common widgets
+	 */
+	public TransientMappingComposite(PropertyValueModel<? extends TransientMapping> subjectHolder,
+	                                 Composite parent,
+	                                 WidgetFactory widgetFactory) {
+
+		super(subjectHolder, parent, widgetFactory);
+	}
+
+	/*
+	 * (non-Javadoc)
+	 */
+	@Override
+	protected void initializeLayout(Composite container) {
+	}
+}
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/VersionMappingComposite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/VersionMappingComposite.java
new file mode 100644
index 0000000..ad6ebf6
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/VersionMappingComposite.java
@@ -0,0 +1,61 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 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.ui.internal.details;
+
+import org.eclipse.jpt.core.context.VersionMapping;
+import org.eclipse.jpt.ui.WidgetFactory;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * Here the layout of this pane:
+ * <pre>
+ * -----------------------------------------------------------------------------
+ * | ------------------------------------------------------------------------- |
+ * | |                                                                       | |
+ * | | ColumnComposite                                                       | |
+ * | |                                                                       | |
+ * | ------------------------------------------------------------------------- |
+ * | ------------------------------------------------------------------------- |
+ * | |                                                                       | |
+ * | | TemporalTypeComposite                                                 | |
+ * | |                                                                       | |
+ * | ------------------------------------------------------------------------- |
+ * -----------------------------------------------------------------------------</pre>
+ *
+ * @see VersionMapping
+ * @see ColumnComposite
+ * @see TemporalTypeComposite
+ *
+ * @version 2.3
+ * @since 1.0
+ */
+public class VersionMappingComposite 
+	extends AbstractVersionMappingComposite<VersionMapping>
+{
+	/**
+	 * Creates a new <code>VersionMappingComposite</code>.
+	 *
+	 * @param subjectHolder The holder of the subject <code>IVersionMapping</code>
+	 * @param parent The parent container
+	 * @param widgetFactory The factory used to create various common widgets
+	 */
+	public VersionMappingComposite(PropertyValueModel<? extends VersionMapping> subjectHolder,
+	                               Composite parent,
+	                               WidgetFactory widgetFactory) {
+
+		super(subjectHolder, parent, widgetFactory);
+	}
+
+	@Override
+	protected void initializeVersionSection(Composite container) {
+		new ColumnComposite(this, buildColumnHolder(), container);
+	}
+}
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/db/CatalogCombo.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/db/CatalogCombo.java
new file mode 100644
index 0000000..4815fe6
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/db/CatalogCombo.java
@@ -0,0 +1,44 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2009 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.ui.internal.details.db;
+
+import org.eclipse.jpt.core.JpaNode;
+import org.eclipse.jpt.ui.internal.widgets.Pane;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * This combo-box displays the database's catalogs.
+ */
+public abstract class CatalogCombo<T extends JpaNode>
+	extends DatabaseObjectCombo<T>
+{
+	public CatalogCombo(
+			Pane<? extends T> parentPane,
+			Composite parent) {
+		
+		super(parentPane, parent);
+	}
+	
+	public CatalogCombo(
+			Pane<?> parentPane,
+			PropertyValueModel<? extends T> subjectHolder,
+			Composite parent) {
+		
+		super(parentPane, subjectHolder, parent);
+	}
+	
+	
+	@Override
+	protected Iterable<String> getValues_() {
+		return this.getDatabase().getSortedCatalogIdentifiers();
+	}
+
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/db/ColumnCombo.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/db/ColumnCombo.java
new file mode 100644
index 0000000..f2b2d23
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/db/ColumnCombo.java
@@ -0,0 +1,63 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2009 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.ui.internal.details.db;
+
+import org.eclipse.jpt.core.JpaNode;
+import org.eclipse.jpt.db.Table;
+import org.eclipse.jpt.ui.internal.widgets.Pane;
+import org.eclipse.jpt.utility.internal.iterables.EmptyIterable;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * This combo-box displays a table's columns.
+ */
+public abstract class ColumnCombo<T extends JpaNode>
+	extends DatabaseObjectCombo<T>
+{
+	public ColumnCombo(
+			Pane<? extends T> parentPane, 
+			Composite parent) {
+		
+		super(parentPane, parent);
+	}
+	
+	public ColumnCombo(
+			Pane<?> parentPane,
+			PropertyValueModel<? extends T> subjectHolder,
+			Composite parent) {
+		
+		super(parentPane, subjectHolder, parent);
+	}
+	
+	
+	@Override
+	protected Iterable<String> getValues_() {
+		Table dbTable = this.getDbTable();
+		return (dbTable != null) ? dbTable.getSortedColumnIdentifiers() : EmptyIterable.<String>instance();
+	}
+	
+	protected Table getDbTable() {
+		return (this.getSubject() == null) ? null : this.getDbTable_();
+	}
+	
+	/**
+	 * Assume the subject is not null.
+	 */
+	protected abstract Table getDbTable_();
+	
+	@Override
+	protected void tableChanged_(Table table) {
+		super.tableChanged_(table);
+		if (this.getDbTable() == table) {
+			this.doPopulate();
+		}
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/db/DatabaseObjectCombo.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/db/DatabaseObjectCombo.java
new file mode 100644
index 0000000..756879e
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/db/DatabaseObjectCombo.java
@@ -0,0 +1,349 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2010 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.ui.internal.details.db;
+
+import org.eclipse.jpt.core.JpaDataSource;
+import org.eclipse.jpt.core.JpaNode;
+import org.eclipse.jpt.core.JpaProject;
+import org.eclipse.jpt.db.Catalog;
+import org.eclipse.jpt.db.Column;
+import org.eclipse.jpt.db.ConnectionListener;
+import org.eclipse.jpt.db.ConnectionProfile;
+import org.eclipse.jpt.db.Database;
+import org.eclipse.jpt.db.ForeignKey;
+import org.eclipse.jpt.db.Schema;
+import org.eclipse.jpt.db.Sequence;
+import org.eclipse.jpt.db.Table;
+import org.eclipse.jpt.ui.internal.Tracing;
+import org.eclipse.jpt.ui.internal.listeners.SWTConnectionListenerWrapper;
+import org.eclipse.jpt.ui.internal.listeners.SWTPropertyChangeListenerWrapper;
+import org.eclipse.jpt.ui.internal.widgets.ComboPane;
+import org.eclipse.jpt.ui.internal.widgets.Pane;
+import org.eclipse.jpt.utility.internal.iterables.EmptyIterable;
+import org.eclipse.jpt.utility.model.event.PropertyChangeEvent;
+import org.eclipse.jpt.utility.model.listener.PropertyChangeListener;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * This abstract pane keeps a combo in sync with the database objects
+ * when a connection is active.
+ *
+ * @see CatalogCombo
+ * @see ColumnCombo
+ * @see SchemaCombo
+ * @see SequenceCombo
+ * @see TableCombo
+ */
+@SuppressWarnings("nls")
+public abstract class DatabaseObjectCombo<T extends JpaNode>
+	extends ComboPane<T>
+{
+	/**
+	 * The listener added to the <code>ConnectionProfile</code>.
+	 * It keeps the combo in sync with the database metadata.
+	 */
+	private ConnectionListener connectionListener;
+	
+	private PropertyChangeListener connectionProfileListener;
+	
+	
+	// ********** constructors **********
+	
+	protected DatabaseObjectCombo(
+			Pane<? extends T> parentPane, 
+			Composite parent) {
+		
+		super(parentPane, parent);
+	}
+	
+	protected DatabaseObjectCombo(
+			Pane<?> parentPane,
+			PropertyValueModel<? extends T> subjectHolder,
+			Composite parent) {
+		
+		super(parentPane, subjectHolder, parent);
+	}
+	
+	
+	// ********** initialization **********
+	
+	@Override
+	protected void initialize() {
+		super.initialize();
+		this.connectionListener = this.buildConnectionListener();
+		this.connectionProfileListener = this.buildConnectionProfileListener();
+	}
+	
+	protected ConnectionListener buildConnectionListener() {
+		return new SWTConnectionListenerWrapper(this.buildConnectionListener_());
+	}
+	
+	protected ConnectionListener buildConnectionListener_() {
+		return new LocalConnectionListener();
+	}
+	
+	protected PropertyChangeListener buildConnectionProfileListener() {
+		return new SWTPropertyChangeListenerWrapper(this.buildConnectionProfileListener_());
+	}
+	
+	protected PropertyChangeListener buildConnectionProfileListener_() {
+		return new PropertyChangeListener(){
+		
+			public void propertyChanged(PropertyChangeEvent event) {
+				connectionProfileChanged(event);
+			}
+		};
+	}
+	
+	protected void connectionProfileChanged(PropertyChangeEvent event) {
+		if (event.getOldValue() != null) {
+			((ConnectionProfile) event.getOldValue()).removeConnectionListener(this.connectionListener);
+		}
+		if (event.getNewValue() != null) {
+			((ConnectionProfile) event.getNewValue()).addConnectionListener(this.connectionListener);			
+		}
+		this.repopulateComboBox();
+	}
+	
+	
+	// ********** overrides **********
+	
+	@Override
+	protected void engageListeners_(T subject) {
+		super.engageListeners_(subject);
+
+		subject.getJpaProject().getDataSource().addPropertyChangeListener(JpaDataSource.CONNECTION_PROFILE_PROPERTY, this.connectionProfileListener);
+		ConnectionProfile cp = subject.getJpaProject().getConnectionProfile();
+		if (cp != null) {
+			cp.addConnectionListener(this.connectionListener);
+		}
+	}
+	
+	@Override
+	protected void disengageListeners_(T subject) {
+		ConnectionProfile cp = subject.getJpaProject().getConnectionProfile();
+		if (cp != null) {
+			cp.removeConnectionListener(this.connectionListener);
+		}
+		subject.getJpaProject().getDataSource().removePropertyChangeListener(JpaDataSource.CONNECTION_PROFILE_PROPERTY, this.connectionProfileListener);
+
+		super.disengageListeners_(subject);
+	}
+	
+	@Override
+	protected final Iterable<String> getValues() {
+		return this.connectionProfileIsActive() ? this.getValues_() : EmptyIterable.<String>instance();
+	}
+	
+	/**
+	 * Called only when connection profile is active
+	 */
+	protected abstract Iterable<String> getValues_();
+	
+	
+	// ********** convenience methods **********
+	
+	/**
+	 * Return the subject's JPA project.
+	 * Allow subclasses to override this method, so we can still get the JPA
+	 * project even when the subject is null.
+	 */
+	protected JpaProject getJpaProject() {
+		T subject = this.getSubject();
+		return (subject == null) ? null : subject.getJpaProject();
+	}
+	
+	/**
+	 * Return the subject's connection profile.
+	 */
+	protected final ConnectionProfile getConnectionProfile() {
+		JpaProject jpaProject = this.getJpaProject();
+		return (jpaProject == null) ? null : jpaProject.getConnectionProfile();
+	}
+	
+	/**
+	 * Return whether the subject's connection profile is active.
+	 */
+	protected final boolean connectionProfileIsActive() {
+		ConnectionProfile cp = this.getConnectionProfile();
+		return (cp != null) && cp.isActive();
+	}
+	
+	/**
+	 * Returns the subject's database.
+	 */
+	protected final Database getDatabase() {
+		ConnectionProfile cp = this.getConnectionProfile();
+		return (cp == null) ? null : cp.getDatabase();
+	}
+	
+	
+	// ********** connection listener callbacks **********
+	
+	protected final void databaseChanged(Database database) {
+		if ( ! this.comboBox.isDisposed()) {
+			this.databaseChanged_(database);
+		}
+	}
+	
+	protected void databaseChanged_(@SuppressWarnings("unused") Database database) {
+		// do nothing by default
+	}
+	
+	protected final void catalogChanged(Catalog catalog) {
+		if ( ! this.comboBox.isDisposed()) {
+			this.catalogChanged_(catalog);
+		}
+	}
+	
+	protected void catalogChanged_(@SuppressWarnings("unused") Catalog catalog) {
+		// do nothing by default
+	}
+	
+	protected final void schemaChanged(Schema schema) {
+		if ( ! this.comboBox.isDisposed()) {
+			this.schemaChanged_(schema);
+		}
+	}
+	
+	protected void schemaChanged_(@SuppressWarnings("unused") Schema schema) {
+		// do nothing by default
+	}
+	
+	protected final void sequenceChanged(Sequence sequence) {
+		if ( ! this.comboBox.isDisposed()) {
+			this.sequenceChanged_(sequence);
+		}
+	}
+	
+	protected void sequenceChanged_(@SuppressWarnings("unused") Sequence sequence) {
+		// do nothing by default
+	}
+	
+	protected final void tableChanged(Table table) {
+		if ( ! this.comboBox.isDisposed()) {
+			this.tableChanged_(table);
+		}
+	}
+	
+	protected void tableChanged_(@SuppressWarnings("unused") Table table) {
+		// do nothing by default
+	}
+	
+	protected final void columnChanged(Column column) {
+		if ( ! this.comboBox.isDisposed()) {
+			this.columnChanged_(column);
+		}
+	}
+	
+	protected void columnChanged_(@SuppressWarnings("unused") Column column) {
+		// do nothing by default
+	}
+	
+	protected final void foreignKeyChanged(ForeignKey foreignKey) {
+		if ( ! this.comboBox.isDisposed()) {
+			this.foreignKeyChanged_(foreignKey);
+		}
+	}
+	
+	protected void foreignKeyChanged_(@SuppressWarnings("unused") ForeignKey foreignKey) {
+		// do nothing by default
+	}
+	
+	@Override
+	protected void log(String flag, String message) {
+		if (flag.equals(Tracing.UI_DB) && Tracing.booleanDebugOption(Tracing.UI_DB)) {
+			this.log(message);
+		} else {
+			super.log(flag, message);
+		}
+	}
+
+	// broaden accessibility a bit
+	@Override
+	protected void repopulateComboBox() {
+		super.repopulateComboBox();
+	}
+	
+	
+	// ********** connection listener **********
+	
+	protected class LocalConnectionListener 
+		implements ConnectionListener 
+	{
+		protected LocalConnectionListener() {
+			super();
+		}
+		
+		public void opened(ConnectionProfile profile) {
+			this.log("opened: " + profile.getName());
+			DatabaseObjectCombo.this.repopulateComboBox();
+		}
+		
+		public void modified(ConnectionProfile profile) {
+			this.log("modified: " + profile.getName());
+			DatabaseObjectCombo.this.repopulateComboBox();
+		}
+		
+		public boolean okToClose(ConnectionProfile profile) {
+			this.log("OK to close: " + profile.getName());
+			return true;
+		}
+		
+		public void aboutToClose(ConnectionProfile profile) {
+			this.log("about to close: " + profile.getName());
+		}
+		
+		public void closed(ConnectionProfile profile) {
+			this.log("closed: " + profile.getName());
+			DatabaseObjectCombo.this.repopulateComboBox();
+		}
+		
+		public void databaseChanged(ConnectionProfile profile, Database database) {
+			this.log("database changed: " + database.getName());
+			DatabaseObjectCombo.this.databaseChanged(database);
+		}
+		
+		public void catalogChanged(ConnectionProfile profile, Catalog catalog) {
+			this.log("catalog changed: " + catalog.getName());
+			DatabaseObjectCombo.this.catalogChanged(catalog);
+		}
+		
+		public void schemaChanged(ConnectionProfile profile, Schema schema) {
+			this.log("schema changed: " + schema.getName());
+			DatabaseObjectCombo.this.schemaChanged(schema);
+		}
+		
+		public void sequenceChanged(ConnectionProfile profile, Sequence sequence) {
+			this.log("sequence changed: " + sequence.getName());
+			DatabaseObjectCombo.this.sequenceChanged(sequence);
+		}
+		
+		public void tableChanged(ConnectionProfile profile, Table table) {
+			this.log("table changed: " + table.getName());
+			DatabaseObjectCombo.this.tableChanged(table);
+		}
+		
+		public void columnChanged(ConnectionProfile profile, Column column) {
+			this.log("column changed: " + column.getName());
+			DatabaseObjectCombo.this.columnChanged(column);
+		}
+		
+		public void foreignKeyChanged(ConnectionProfile profile, ForeignKey foreignKey) {
+			this.log("foreign key changed: " + foreignKey.getName());
+			DatabaseObjectCombo.this.foreignKeyChanged(foreignKey);
+		}
+		
+		protected void log(String message) {
+			DatabaseObjectCombo.this.log(Tracing.UI_DB, message);
+		}
+	}	
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/db/SchemaCombo.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/db/SchemaCombo.java
new file mode 100644
index 0000000..a4966e1
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/db/SchemaCombo.java
@@ -0,0 +1,56 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2009 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.ui.internal.details.db;
+
+import org.eclipse.jpt.core.JpaNode;
+import org.eclipse.jpt.db.SchemaContainer;
+import org.eclipse.jpt.ui.internal.widgets.Pane;
+import org.eclipse.jpt.utility.internal.iterables.EmptyIterable;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * This combo-box displays a schema container's schemata.
+ */
+public abstract class SchemaCombo<T extends JpaNode>
+	extends DatabaseObjectCombo<T>
+{
+	public SchemaCombo(
+			Pane<? extends T> parentPane,
+			Composite parent) {
+		
+		super(parentPane, parent);
+	}
+	
+	public SchemaCombo(
+			Pane<?> parentPane,
+			PropertyValueModel<? extends T> subjectHolder,
+			Composite parent) {
+		
+		super(parentPane, subjectHolder, parent);
+	}
+	
+	
+	@Override
+	protected Iterable<String> getValues_() {
+		SchemaContainer sc = this.getDbSchemaContainer();
+		return (sc != null) ? sc.getSortedSchemaIdentifiers() : EmptyIterable.<String>instance();
+	}
+
+	protected SchemaContainer getDbSchemaContainer() {
+		return (this.getSubject() == null) ? null : this.getDbSchemaContainer_();
+	}
+
+	/**
+	 * Assume the subject is not null.
+	 */
+	protected abstract SchemaContainer getDbSchemaContainer_();
+
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/db/SequenceCombo.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/db/SequenceCombo.java
new file mode 100644
index 0000000..ee77b20
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/db/SequenceCombo.java
@@ -0,0 +1,49 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2009 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.ui.internal.details.db;
+
+import org.eclipse.jpt.core.JpaNode;
+import org.eclipse.jpt.db.Schema;
+import org.eclipse.jpt.ui.internal.widgets.Pane;
+import org.eclipse.jpt.utility.internal.iterables.EmptyIterable;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * This combo-box displays a schema's sequences.
+ */
+public abstract class SequenceCombo<T extends JpaNode>
+	extends DatabaseObjectCombo<T>
+{
+	public SequenceCombo(
+			Pane<?> parentPane,
+			PropertyValueModel<? extends T> subjectHolder,
+			Composite parent) {
+		
+		super(parentPane, subjectHolder, parent);
+	}
+	
+
+	@Override
+	protected Iterable<String> getValues_() {
+		Schema dbSchema = this.getDbSchema();
+		return (dbSchema != null) ? dbSchema.getSortedSequenceIdentifiers() : EmptyIterable.<String>instance();
+	}
+
+	protected Schema getDbSchema() {
+		return (this.getSubject() == null) ? null : this.getDbSchema_();
+	}
+
+	/**
+	 * Assume the subject is not null.
+	 */
+	protected abstract Schema getDbSchema_();
+
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/db/TableCombo.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/db/TableCombo.java
new file mode 100644
index 0000000..7958648
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/db/TableCombo.java
@@ -0,0 +1,56 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2009 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.ui.internal.details.db;
+
+import org.eclipse.jpt.core.JpaNode;
+import org.eclipse.jpt.db.Schema;
+import org.eclipse.jpt.ui.internal.widgets.Pane;
+import org.eclipse.jpt.utility.internal.iterables.EmptyIterable;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * This combo-box displays a schema's tables.
+ */
+public abstract class TableCombo<T extends JpaNode>
+	extends DatabaseObjectCombo<T>
+{
+	public TableCombo(
+			Pane<? extends T> parentPane,
+			Composite parent) {
+		
+		super(parentPane, parent);
+	}
+	
+	public TableCombo(
+			Pane<?> parentPane,
+			PropertyValueModel<? extends T> subjectHolder,
+			Composite parent) {
+		
+		super(parentPane, subjectHolder, parent);
+	}
+	
+	
+	@Override
+	protected Iterable<String> getValues_() {
+		Schema dbSchema = this.getDbSchema();
+		return (dbSchema != null) ? dbSchema.getSortedTableIdentifiers() : EmptyIterable.<String>instance();
+	}
+	
+	protected Schema getDbSchema() {
+		return (this.getSubject() == null) ? null : this.getDbSchema_();
+	}
+
+	/**
+	 * Assume the subject is not null.
+	 */
+	protected abstract Schema getDbSchema_();
+
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/java/AbstractJavaResourceUiDefinition.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/java/AbstractJavaResourceUiDefinition.java
new file mode 100644
index 0000000..c324439
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/java/AbstractJavaResourceUiDefinition.java
@@ -0,0 +1,243 @@
+/*******************************************************************************
+ * Copyright (c) 2009 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.ui.internal.details.java;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+import org.eclipse.jpt.core.JpaResourceType;
+import org.eclipse.jpt.core.JptCorePlugin;
+import org.eclipse.jpt.core.context.AttributeMapping;
+import org.eclipse.jpt.core.context.PersistentAttribute;
+import org.eclipse.jpt.core.context.PersistentType;
+import org.eclipse.jpt.core.context.TypeMapping;
+import org.eclipse.jpt.ui.MappingResourceUiDefinition;
+import org.eclipse.jpt.ui.ResourceUiDefinition;
+import org.eclipse.jpt.ui.WidgetFactory;
+import org.eclipse.jpt.ui.details.JpaComposite;
+import org.eclipse.jpt.ui.details.MappingUiDefinition;
+import org.eclipse.jpt.ui.details.java.DefaultJavaAttributeMappingUiDefinition;
+import org.eclipse.jpt.ui.details.java.DefaultJavaTypeMappingUiDefinition;
+import org.eclipse.jpt.ui.details.java.JavaAttributeMappingUiDefinition;
+import org.eclipse.jpt.ui.details.java.JavaTypeMappingUiDefinition;
+import org.eclipse.jpt.ui.details.java.JavaUiFactory;
+import org.eclipse.jpt.ui.internal.structure.JavaResourceModelStructureProvider;
+import org.eclipse.jpt.ui.structure.JpaStructureProvider;
+import org.eclipse.jpt.utility.internal.Tools;
+import org.eclipse.jpt.utility.internal.iterators.ArrayIterator;
+import org.eclipse.jpt.utility.internal.iterators.ArrayListIterator;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * All the state in the definition should be "static" (i.e. unchanging once it is initialized).
+ */
+public abstract class AbstractJavaResourceUiDefinition
+	implements ResourceUiDefinition, MappingResourceUiDefinition
+{
+	private JavaTypeMappingUiDefinition<? extends TypeMapping>[] specifiedTypeMappingUiDefinitions;
+	
+	private JavaAttributeMappingUiDefinition<? extends AttributeMapping>[] specifiedAttributeMappingUiDefinitions;
+	
+	private DefaultJavaAttributeMappingUiDefinition<?>[] defaultAttributeMappingUiDefinitions;
+	
+	private final JavaUiFactory factory;
+	
+	
+	/**
+	 * zero-argument constructor
+	 */
+	protected AbstractJavaResourceUiDefinition() {
+		super();
+		this.factory = buildJavaUiFactory();
+	}
+	
+	
+	protected abstract JavaUiFactory buildJavaUiFactory();
+	
+	public JavaUiFactory getFactory() {
+		return this.factory;
+	}
+	
+	public boolean providesUi(JpaResourceType resourceType) {
+		return resourceType.equals(JptCorePlugin.JAVA_SOURCE_RESOURCE_TYPE);
+	}
+
+	public JpaStructureProvider getStructureProvider() {
+		return JavaResourceModelStructureProvider.instance();
+	}
+	
+	
+	
+	// ********** type mapping ui definitions **********
+	
+	public JpaComposite buildTypeMappingComposite(
+			String key, 
+			PropertyValueModel<TypeMapping> mappingHolder, 
+			Composite parent, 
+			WidgetFactory widgetFactory) {
+		
+		JavaTypeMappingUiDefinition<TypeMapping> mappingUiDefinition = getJavaTypeMappingUiDefinition(mappingHolder.getValue());
+		return mappingUiDefinition.buildTypeMappingComposite(
+				getFactory(), 
+				mappingHolder,
+				parent,
+				widgetFactory);
+	}
+	
+	@SuppressWarnings("unchecked")
+	protected JavaTypeMappingUiDefinition<TypeMapping> getJavaTypeMappingUiDefinition(TypeMapping typeMapping) {
+		if (typeMapping == null || typeMapping.getKey() == null) {
+			return (JavaTypeMappingUiDefinition<TypeMapping>) getDefaultTypeMappingUiDefinition();
+		}
+		return (JavaTypeMappingUiDefinition<TypeMapping>) getSpecifiedJavaTypeMappingUiDefinition(typeMapping.getKey());
+	}
+	
+	protected JavaTypeMappingUiDefinition<? extends TypeMapping> getSpecifiedJavaTypeMappingUiDefinition(String mappingKey) {
+		for (JavaTypeMappingUiDefinition<? extends TypeMapping> definition : getSpecifiedTypeMappingUiDefinitions()) {
+			if (Tools.valuesAreEqual(definition.getKey(), mappingKey)) {
+				return definition;
+			}
+		}
+		throw new IllegalArgumentException("Illegal type mapping key: " + mappingKey); //$NON-NLS-1$
+	}
+	
+	public Iterator<MappingUiDefinition<PersistentType, ? extends TypeMapping>> typeMappingUiDefinitions() {
+		return new ArrayIterator<MappingUiDefinition<PersistentType, ? extends TypeMapping>>(
+				getSpecifiedTypeMappingUiDefinitions());
+	}
+	
+	protected synchronized JavaTypeMappingUiDefinition<? extends TypeMapping>[] getSpecifiedTypeMappingUiDefinitions() {
+		if (this.specifiedTypeMappingUiDefinitions == null) {
+			this.specifiedTypeMappingUiDefinitions = buildSpecifiedTypeMappingUiDefinitions();
+		}
+		return this.specifiedTypeMappingUiDefinitions;
+	}
+	
+	/**
+	 * Return an array of mapping definitions to use for types in mapping files of this type.  
+	 * The order is unimportant.
+	 */
+	protected JavaTypeMappingUiDefinition<? extends TypeMapping>[] buildSpecifiedTypeMappingUiDefinitions() {
+		ArrayList<JavaTypeMappingUiDefinition<? extends TypeMapping>> definitions = 
+				new ArrayList<JavaTypeMappingUiDefinition<? extends TypeMapping>>();
+		addSpecifiedTypeMappingUiDefinitionsTo(definitions);
+		@SuppressWarnings("unchecked")
+		JavaTypeMappingUiDefinition<? extends TypeMapping>[] definitionArray = 
+				definitions.toArray(new JavaTypeMappingUiDefinition[definitions.size()]);
+		return definitionArray;
+	}
+	
+	protected abstract void addSpecifiedTypeMappingUiDefinitionsTo(
+			List<JavaTypeMappingUiDefinition<? extends TypeMapping>> definitions);
+		
+	public DefaultJavaTypeMappingUiDefinition<? extends TypeMapping> getDefaultTypeMappingUiDefinition() {
+		return NullJavaTypeMappingUiDefinition.instance();
+	}
+	
+	
+	// ********** attributes mapping UI definitions **********
+	
+	public JpaComposite buildAttributeMappingComposite(
+			String key, 
+			PropertyValueModel<AttributeMapping> mappingHolder, 
+			Composite parent, 
+			WidgetFactory widgetFactory) {
+		
+		JavaAttributeMappingUiDefinition<AttributeMapping> mappingUiDefinition = 
+				getAttributeMappingUiDefinition(mappingHolder.getValue());
+		return mappingUiDefinition.buildAttributeMappingComposite(
+				getFactory(), 
+				mappingHolder,
+				parent,
+				widgetFactory);
+	}
+	
+	@SuppressWarnings("unchecked")
+	protected JavaAttributeMappingUiDefinition<AttributeMapping> getAttributeMappingUiDefinition(AttributeMapping attributeMapping) {
+		String key = attributeMapping == null ? null : attributeMapping.getKey();
+		if (attributeMapping == null || attributeMapping.isDefault()) {
+			return (JavaAttributeMappingUiDefinition<AttributeMapping>) getDefaultAttributeMappingUiDefinition(key);
+		}
+		return (JavaAttributeMappingUiDefinition<AttributeMapping>) getSpecifiedAttributeMappingUiDefinition(key);
+	}
+	
+	protected JavaAttributeMappingUiDefinition<? extends AttributeMapping> getSpecifiedAttributeMappingUiDefinition(String mappingKey) {
+		for (JavaAttributeMappingUiDefinition<? extends AttributeMapping> definition : getSpecifiedAttributeMappingUiDefinitions()) {
+			if (Tools.valuesAreEqual(definition.getKey(), mappingKey)) {
+				return definition;
+			}
+		}
+		throw new IllegalArgumentException("Illegal attribute mapping key: " + mappingKey); //$NON-NLS-1$
+	}
+	
+	public ListIterator<MappingUiDefinition<PersistentAttribute, ? extends AttributeMapping>> 
+			attributeMappingUiDefinitions() {
+		
+		return new ArrayListIterator<MappingUiDefinition<PersistentAttribute, ? extends AttributeMapping>>(
+				getSpecifiedAttributeMappingUiDefinitions());
+	}
+	
+	protected synchronized JavaAttributeMappingUiDefinition<? extends AttributeMapping>[] getSpecifiedAttributeMappingUiDefinitions() {
+		if (this.specifiedAttributeMappingUiDefinitions == null) {
+			this.specifiedAttributeMappingUiDefinitions = buildSpecifiedAttributeMappingUiDefinitions();
+		}
+		return this.specifiedAttributeMappingUiDefinitions;
+	}
+	
+	/**
+	 * Return an array of mapping definitions to use for attributes in mapping files of this type.  
+	 * The order is unimportant.
+	 */
+	protected JavaAttributeMappingUiDefinition<? extends AttributeMapping>[] buildSpecifiedAttributeMappingUiDefinitions() {
+		ArrayList<JavaAttributeMappingUiDefinition<? extends AttributeMapping>> definitions = 
+				new ArrayList<JavaAttributeMappingUiDefinition<? extends AttributeMapping>>();
+		addSpecifiedAttributeMappingUiDefinitionsTo(definitions);
+		@SuppressWarnings("unchecked")
+		JavaAttributeMappingUiDefinition<? extends AttributeMapping>[] definitionArray = 
+				definitions.toArray(new JavaAttributeMappingUiDefinition[definitions.size()]);
+		return definitionArray;
+	}
+	
+	protected abstract void addSpecifiedAttributeMappingUiDefinitionsTo(
+			List<JavaAttributeMappingUiDefinition<? extends AttributeMapping>> definitions);
+	
+	
+	// ********** default Java attribute mapping UI providers **********
+	
+	public DefaultJavaAttributeMappingUiDefinition<? extends AttributeMapping> getDefaultAttributeMappingUiDefinition(String key) {
+		for (DefaultJavaAttributeMappingUiDefinition<? extends AttributeMapping> definition : getDefaultAttributeMappingUiDefinitions()) {
+			if (Tools.valuesAreEqual(definition.getDefaultKey(), key)) {
+				return definition;
+			}
+		}
+		throw new IllegalArgumentException("Illegal attribute mapping key: " + key); //$NON-NLS-1$
+	}
+	
+	protected synchronized DefaultJavaAttributeMappingUiDefinition<? extends AttributeMapping>[] getDefaultAttributeMappingUiDefinitions() {
+		if (this.defaultAttributeMappingUiDefinitions == null) {
+			this.defaultAttributeMappingUiDefinitions = this.buildDefaultAttributeMappingUiDefinitions();
+		}
+		return this.defaultAttributeMappingUiDefinitions;
+	}
+	
+	protected DefaultJavaAttributeMappingUiDefinition<?>[] buildDefaultAttributeMappingUiDefinitions() {
+		ArrayList<DefaultJavaAttributeMappingUiDefinition<?>> definitions = 
+				new ArrayList<DefaultJavaAttributeMappingUiDefinition<?>>();
+		addDefaultAttributeMappingUiDefinitionsTo(definitions);
+		DefaultJavaAttributeMappingUiDefinition<?>[] definitionArray = 
+				definitions.toArray(new DefaultJavaAttributeMappingUiDefinition[definitions.size()]);
+		return definitionArray;
+	}
+	
+	protected abstract void addDefaultAttributeMappingUiDefinitionsTo(
+			List<DefaultJavaAttributeMappingUiDefinition<?>> definitions);
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/java/BaseJavaUiFactory.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/java/BaseJavaUiFactory.java
new file mode 100644
index 0000000..271c7cc
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/java/BaseJavaUiFactory.java
@@ -0,0 +1,173 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 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.ui.internal.details.java;
+
+import org.eclipse.jpt.core.context.java.JavaBasicMapping;
+import org.eclipse.jpt.core.context.java.JavaEmbeddable;
+import org.eclipse.jpt.core.context.java.JavaEmbeddedIdMapping;
+import org.eclipse.jpt.core.context.java.JavaEmbeddedMapping;
+import org.eclipse.jpt.core.context.java.JavaEntity;
+import org.eclipse.jpt.core.context.java.JavaIdMapping;
+import org.eclipse.jpt.core.context.java.JavaManyToManyMapping;
+import org.eclipse.jpt.core.context.java.JavaManyToOneMapping;
+import org.eclipse.jpt.core.context.java.JavaMappedSuperclass;
+import org.eclipse.jpt.core.context.java.JavaOneToManyMapping;
+import org.eclipse.jpt.core.context.java.JavaOneToOneMapping;
+import org.eclipse.jpt.core.context.java.JavaTransientMapping;
+import org.eclipse.jpt.core.context.java.JavaVersionMapping;
+import org.eclipse.jpt.core.context.orm.OrmEmbeddable;
+import org.eclipse.jpt.core.context.orm.OrmEntity;
+import org.eclipse.jpt.core.context.orm.OrmMappedSuperclass;
+import org.eclipse.jpt.ui.WidgetFactory;
+import org.eclipse.jpt.ui.details.JpaComposite;
+import org.eclipse.jpt.ui.details.java.JavaUiFactory;
+import org.eclipse.jpt.ui.internal.details.BasicMappingComposite;
+import org.eclipse.jpt.ui.internal.details.EmbeddedIdMappingComposite;
+import org.eclipse.jpt.ui.internal.details.IdMappingComposite;
+import org.eclipse.jpt.ui.internal.details.ManyToManyMappingComposite;
+import org.eclipse.jpt.ui.internal.details.ManyToOneMappingComposite;
+import org.eclipse.jpt.ui.internal.details.OneToManyMappingComposite;
+import org.eclipse.jpt.ui.internal.details.OneToOneMappingComposite;
+import org.eclipse.jpt.ui.internal.details.TransientMappingComposite;
+import org.eclipse.jpt.ui.internal.details.VersionMappingComposite;
+import org.eclipse.jpt.ui.internal.details.orm.OrmEmbeddableComposite;
+import org.eclipse.jpt.ui.internal.details.orm.OrmEntityComposite;
+import org.eclipse.jpt.ui.internal.details.orm.OrmMappedSuperclassComposite;
+import org.eclipse.jpt.ui.internal.jpa2.details.java.JavaEmbeddedMapping2_0Composite;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * The default implementation of the UI factory required to show the information
+ * related to a JPA mapping (type or attribute).
+ */
+public abstract class BaseJavaUiFactory implements JavaUiFactory
+{	
+	
+	// **************** java type mapping composites ***************************
+	
+	public JpaComposite createJavaMappedSuperclassComposite(
+			PropertyValueModel<JavaMappedSuperclass> subjectHolder,
+			Composite parent,
+			WidgetFactory widgetFactory) {
+		return new JavaMappedSuperclassComposite(subjectHolder, parent, widgetFactory);
+	}
+	
+	public JpaComposite createJavaEntityComposite(
+			PropertyValueModel<JavaEntity> subjectHolder,
+			Composite parent,
+			WidgetFactory widgetFactory) {
+		return new JavaEntityComposite(subjectHolder, parent, widgetFactory);
+	}
+	
+	public JpaComposite createJavaEmbeddableComposite(
+			PropertyValueModel<JavaEmbeddable> subjectHolder,
+			Composite parent,
+			WidgetFactory widgetFactory) {
+		return new JavaEmbeddableComposite(subjectHolder, parent, widgetFactory);
+	}
+	
+	
+	// **************** orm type mapping composites ****************************
+	
+	public JpaComposite createOrmMappedSuperclassComposite(
+			PropertyValueModel<OrmMappedSuperclass> subjectHolder,
+			Composite parent,
+			WidgetFactory widgetFactory) {
+		return new OrmMappedSuperclassComposite(subjectHolder, parent, widgetFactory);
+	}
+	
+	public JpaComposite createOrmEntityComposite(
+			PropertyValueModel<OrmEntity> subjectHolder,
+			Composite parent,
+			WidgetFactory widgetFactory) {
+		return new OrmEntityComposite(subjectHolder, parent, widgetFactory);
+	}
+	
+	public JpaComposite createOrmEmbeddableComposite(
+			PropertyValueModel<OrmEmbeddable> subjectHolder,
+			Composite parent,
+			WidgetFactory widgetFactory) {
+		return new OrmEmbeddableComposite(subjectHolder, parent, widgetFactory);
+	}
+	
+	
+	// **************** java attribute mapping composites **********************
+	
+	public JpaComposite createJavaIdMappingComposite(
+			PropertyValueModel<JavaIdMapping> subjectHolder,
+			Composite parent,
+			WidgetFactory widgetFactory) {
+		return new IdMappingComposite(subjectHolder, parent, widgetFactory);
+	}
+	
+	public JpaComposite createJavaEmbeddedIdMappingComposite(
+			PropertyValueModel<JavaEmbeddedIdMapping> subjectHolder,
+			Composite parent,
+			WidgetFactory widgetFactory) {
+		return new EmbeddedIdMappingComposite(subjectHolder, parent, widgetFactory);
+	}
+	
+	public JpaComposite createJavaBasicMappingComposite(
+			PropertyValueModel<JavaBasicMapping> subjectHolder,
+			Composite parent,
+			WidgetFactory widgetFactory) {
+		return new BasicMappingComposite(subjectHolder, parent, widgetFactory);
+	}
+	
+	public JpaComposite createJavaVersionMappingComposite(
+			PropertyValueModel<JavaVersionMapping> subjectHolder,
+			Composite parent,
+			WidgetFactory widgetFactory) {
+		return new VersionMappingComposite(subjectHolder, parent, widgetFactory);
+	}
+	
+	public JpaComposite createJavaManyToOneMappingComposite(
+			PropertyValueModel<JavaManyToOneMapping> subjectHolder,
+			Composite parent,
+			WidgetFactory widgetFactory) {
+		return new ManyToOneMappingComposite(subjectHolder, parent, widgetFactory);
+	}
+	
+	public JpaComposite createJavaOneToManyMappingComposite(
+			PropertyValueModel<JavaOneToManyMapping> subjectHolder,
+			Composite parent,
+			WidgetFactory widgetFactory) {
+		return new OneToManyMappingComposite(subjectHolder, parent, widgetFactory);
+	}
+	
+	public JpaComposite createJavaOneToOneMappingComposite(
+			PropertyValueModel<JavaOneToOneMapping> subjectHolder,
+			Composite parent,
+			WidgetFactory widgetFactory) {
+		return new OneToOneMappingComposite(subjectHolder, parent, widgetFactory);
+	}
+	
+	public JpaComposite createJavaManyToManyMappingComposite(
+			PropertyValueModel<JavaManyToManyMapping> subjectHolder,
+			Composite parent,
+			WidgetFactory widgetFactory) {
+		return new ManyToManyMappingComposite(subjectHolder, parent, widgetFactory);
+	}
+
+	public JpaComposite createJavaEmbeddedMappingComposite(
+			PropertyValueModel<JavaEmbeddedMapping> subjectHolder,
+			Composite parent,
+			WidgetFactory widgetFactory) {
+		return new JavaEmbeddedMapping2_0Composite(subjectHolder, parent, widgetFactory);
+	}
+	
+	public JpaComposite createJavaTransientMappingComposite(
+			PropertyValueModel<JavaTransientMapping> subjectHolder,
+			Composite parent,
+			WidgetFactory widgetFactory) {
+		return new TransientMappingComposite(subjectHolder, parent, widgetFactory);
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/java/DefaultBasicMappingUiDefinition.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/java/DefaultBasicMappingUiDefinition.java
new file mode 100644
index 0000000..903d9e2
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/java/DefaultBasicMappingUiDefinition.java
@@ -0,0 +1,83 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2009 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.ui.internal.details.java;
+
+import org.eclipse.jpt.core.MappingKeys;
+import org.eclipse.jpt.core.context.PersistentAttribute;
+import org.eclipse.jpt.core.context.java.JavaBasicMapping;
+import org.eclipse.jpt.ui.WidgetFactory;
+import org.eclipse.jpt.ui.details.JpaComposite;
+import org.eclipse.jpt.ui.details.java.DefaultJavaAttributeMappingUiDefinition;
+import org.eclipse.jpt.ui.details.java.JavaUiFactory;
+import org.eclipse.jpt.ui.internal.JpaMappingImageHelper;
+import org.eclipse.jpt.ui.internal.details.AbstractBasicMappingUiDefinition;
+import org.eclipse.jpt.ui.internal.details.JptUiDetailsMessages;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Composite;
+
+public class DefaultBasicMappingUiDefinition
+	extends AbstractBasicMappingUiDefinition<PersistentAttribute, JavaBasicMapping>
+	implements DefaultJavaAttributeMappingUiDefinition<JavaBasicMapping>
+{
+	// singleton
+	private static final DefaultBasicMappingUiDefinition INSTANCE = 
+		new DefaultBasicMappingUiDefinition();
+	
+	
+	/**
+	 * Return the singleton.
+	 */
+	public static DefaultJavaAttributeMappingUiDefinition<JavaBasicMapping> instance() {
+		return INSTANCE;
+	}
+	
+	
+	/**
+	 * Ensure single instance.
+	 */
+	private DefaultBasicMappingUiDefinition() {
+		super();
+	}
+	
+	
+	@Override
+	public String getKey() {
+		return null;
+	}
+	
+	public String getDefaultKey() {
+		return MappingKeys.BASIC_ATTRIBUTE_MAPPING_KEY;
+	}
+	
+	@Override
+	public String getLabel() {
+		return JptUiDetailsMessages.DefaultBasicMappingUiProvider_label;
+	}
+
+	@Override
+	public String getLinkLabel() {
+		return JptUiDetailsMessages.DefaultBasicMappingUiProvider_linkLabel;
+	}
+
+	@Override
+	public Image getImage() {
+		return JpaMappingImageHelper.imageForAttributeMapping(getDefaultKey());
+	}
+
+	public JpaComposite buildAttributeMappingComposite(
+				JavaUiFactory factory,
+				PropertyValueModel<JavaBasicMapping> subjectHolder,
+				Composite parent,
+				WidgetFactory widgetFactory) {
+		
+		return factory.createJavaBasicMappingComposite(subjectHolder, parent, widgetFactory);
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/java/DefaultEmbeddedMappingUiDefinition.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/java/DefaultEmbeddedMappingUiDefinition.java
new file mode 100644
index 0000000..7491b93
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/java/DefaultEmbeddedMappingUiDefinition.java
@@ -0,0 +1,83 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2009 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.ui.internal.details.java;
+
+import org.eclipse.jpt.core.MappingKeys;
+import org.eclipse.jpt.core.context.PersistentAttribute;
+import org.eclipse.jpt.core.context.java.JavaEmbeddedMapping;
+import org.eclipse.jpt.ui.WidgetFactory;
+import org.eclipse.jpt.ui.details.JpaComposite;
+import org.eclipse.jpt.ui.details.java.DefaultJavaAttributeMappingUiDefinition;
+import org.eclipse.jpt.ui.details.java.JavaUiFactory;
+import org.eclipse.jpt.ui.internal.JpaMappingImageHelper;
+import org.eclipse.jpt.ui.internal.details.AbstractEmbeddedMappingUiDefinition;
+import org.eclipse.jpt.ui.internal.details.JptUiDetailsMessages;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Composite;
+
+public class DefaultEmbeddedMappingUiDefinition
+	extends AbstractEmbeddedMappingUiDefinition<PersistentAttribute, JavaEmbeddedMapping>
+	implements DefaultJavaAttributeMappingUiDefinition<JavaEmbeddedMapping>
+{
+	// singleton
+	private static final DefaultEmbeddedMappingUiDefinition INSTANCE = 
+			new DefaultEmbeddedMappingUiDefinition();
+	
+	
+	/**
+	 * Return the singleton.
+	 */
+	public static DefaultJavaAttributeMappingUiDefinition<JavaEmbeddedMapping> instance() {
+		return INSTANCE;
+	}
+	
+	
+	/**
+	 * Ensure single instance.
+	 */
+	private DefaultEmbeddedMappingUiDefinition() {
+		super();
+	}
+	
+	
+	@Override
+	public String getKey() {
+		return null;
+	}
+	
+	public String getDefaultKey() {
+		return MappingKeys.EMBEDDED_ATTRIBUTE_MAPPING_KEY;
+	}
+	
+	@Override
+	public String getLabel() {
+		return JptUiDetailsMessages.DefaultEmbeddedMappingUiProvider_label;
+	}
+
+	@Override
+	public String getLinkLabel() {
+		return JptUiDetailsMessages.DefaultEmbeddedMappingUiProvider_linkLabel;
+	}
+
+	@Override
+	public Image getImage() {
+		return JpaMappingImageHelper.imageForAttributeMapping(getDefaultKey());
+	}
+	
+	public JpaComposite buildAttributeMappingComposite(
+			JavaUiFactory factory,
+			PropertyValueModel<JavaEmbeddedMapping> subjectHolder,
+			Composite parent,
+			WidgetFactory widgetFactory) {
+		
+		return factory.createJavaEmbeddedMappingComposite(subjectHolder, parent, widgetFactory);
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/java/GenericJavaResourceUiDefinition.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/java/GenericJavaResourceUiDefinition.java
new file mode 100644
index 0000000..43d7dfc
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/java/GenericJavaResourceUiDefinition.java
@@ -0,0 +1,75 @@
+/*******************************************************************************
+ * Copyright (c) 2009 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.ui.internal.details.java;
+
+import java.util.List;
+import org.eclipse.jpt.core.context.AttributeMapping;
+import org.eclipse.jpt.core.context.TypeMapping;
+import org.eclipse.jpt.ui.ResourceUiDefinition;
+import org.eclipse.jpt.ui.details.java.DefaultJavaAttributeMappingUiDefinition;
+import org.eclipse.jpt.ui.details.java.JavaAttributeMappingUiDefinition;
+import org.eclipse.jpt.ui.details.java.JavaTypeMappingUiDefinition;
+import org.eclipse.jpt.ui.details.java.JavaUiFactory;
+
+public class GenericJavaResourceUiDefinition extends AbstractJavaResourceUiDefinition
+{
+	// singleton
+	private static final ResourceUiDefinition INSTANCE = new GenericJavaResourceUiDefinition();
+
+	/**
+	 * Return the singleton.
+	 */
+	public static ResourceUiDefinition instance() {
+		return INSTANCE;
+	}
+	
+	
+	/**
+	 * zero-argument constructor
+	 */
+	protected GenericJavaResourceUiDefinition() {
+		super();
+	}
+	
+	@Override
+	protected JavaUiFactory buildJavaUiFactory() {
+		return new GenericJavaUiFactory();
+	}
+	
+	@Override
+	protected void addSpecifiedAttributeMappingUiDefinitionsTo(
+			List<JavaAttributeMappingUiDefinition<? extends AttributeMapping>> definitions) {
+		
+		definitions.add(JavaIdMappingUiDefinition.instance());
+		definitions.add(JavaEmbeddedIdMappingUDefinition.instance());
+		definitions.add(JavaBasicMappingUiDefinition.instance());
+		definitions.add(JavaVersionMappingUiDefinition.instance());
+		definitions.add(JavaManyToOneMappingUiDefinition.instance());
+		definitions.add(JavaOneToManyMappingUiDefinition.instance());
+		definitions.add(JavaOneToOneMappingUiDefinition.instance());
+		definitions.add(JavaManyToManyMappingUiDefinition.instance());
+		definitions.add(JavaEmbeddedMappingUiDefinition.instance());
+		definitions.add(JavaTransientMappingUiDefinition.instance());
+	}
+	
+	@Override
+	protected void addDefaultAttributeMappingUiDefinitionsTo(List<DefaultJavaAttributeMappingUiDefinition<?>> definitions) {
+		definitions.add(DefaultBasicMappingUiDefinition.instance());
+		definitions.add(DefaultEmbeddedMappingUiDefinition.instance());
+		definitions.add(NullJavaAttributeMappingUiDefinition.instance());
+	}
+	
+	@Override
+	protected void addSpecifiedTypeMappingUiDefinitionsTo(List<JavaTypeMappingUiDefinition<? extends TypeMapping>> definitions) {
+		definitions.add(JavaEntityUiDefinition.instance());
+		definitions.add(JavaMappedSuperclassUiDefinition.instance());
+		definitions.add(JavaEmbeddableUiDefinition.instance());
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/java/GenericJavaUiFactory.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/java/GenericJavaUiFactory.java
new file mode 100644
index 0000000..cb83ca7
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/java/GenericJavaUiFactory.java
@@ -0,0 +1,23 @@
+/*******************************************************************************
+ * Copyright (c) 2009 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.ui.internal.details.java;
+
+/**
+ * The default implementation of the Java UI factory required to show the information
+ * related to a JPA mapping (type or attribute).
+ *
+ * @see JavaUiFactory
+ *
+ * @version 3.0
+ * @since 3.0
+ */
+public class GenericJavaUiFactory extends BaseJavaUiFactory
+{
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/java/JavaBasicMappingUiDefinition.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/java/JavaBasicMappingUiDefinition.java
new file mode 100644
index 0000000..c491fc0
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/java/JavaBasicMappingUiDefinition.java
@@ -0,0 +1,55 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2009 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.ui.internal.details.java;
+
+import org.eclipse.jpt.core.context.PersistentAttribute;
+import org.eclipse.jpt.core.context.java.JavaBasicMapping;
+import org.eclipse.jpt.ui.WidgetFactory;
+import org.eclipse.jpt.ui.details.JpaComposite;
+import org.eclipse.jpt.ui.details.java.JavaAttributeMappingUiDefinition;
+import org.eclipse.jpt.ui.details.java.JavaUiFactory;
+import org.eclipse.jpt.ui.internal.details.AbstractBasicMappingUiDefinition;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+public class JavaBasicMappingUiDefinition
+	extends AbstractBasicMappingUiDefinition<PersistentAttribute, JavaBasicMapping>
+	implements JavaAttributeMappingUiDefinition<JavaBasicMapping>
+{
+	// singleton
+	private static final JavaBasicMappingUiDefinition INSTANCE = 
+		new JavaBasicMappingUiDefinition();
+	
+	
+	/**
+	 * Return the singleton.
+	 */
+	public static JavaAttributeMappingUiDefinition<JavaBasicMapping> instance() {
+		return INSTANCE;
+	}
+	
+	
+	/**
+	 * Ensure single instance.
+	 */
+	private JavaBasicMappingUiDefinition() {
+		super();
+	}
+	
+	
+	public JpaComposite buildAttributeMappingComposite(
+			JavaUiFactory factory,
+			PropertyValueModel<JavaBasicMapping> subjectHolder,
+			Composite parent,
+			WidgetFactory widgetFactory) {
+		
+		return factory.createJavaBasicMappingComposite(subjectHolder, parent, widgetFactory);
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/java/JavaEmbeddableComposite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/java/JavaEmbeddableComposite.java
new file mode 100644
index 0000000..e899f0e
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/java/JavaEmbeddableComposite.java
@@ -0,0 +1,45 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 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.ui.internal.details.java;
+
+import org.eclipse.jpt.core.context.Embeddable;
+import org.eclipse.jpt.ui.WidgetFactory;
+import org.eclipse.jpt.ui.details.JpaComposite;
+import org.eclipse.jpt.ui.internal.details.AbstractEmbeddableComposite;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * This pane does not have any widgets.
+ *
+ * @see Embeddable
+ * @see EmbeddableUiProvider
+ *
+ * @version 2.3
+ * @since 2.0
+ */
+public class JavaEmbeddableComposite extends AbstractEmbeddableComposite<Embeddable>
+                                 implements JpaComposite
+{
+	/**
+	 * Creates a new <code>EmbeddableComposite</code>.
+	 *
+	 * @param subjectHolder The holder of this pane's subject
+	 * @param parent The parent container
+	 * @param widgetFactory The factory used to create various common widgets
+	 */
+	public JavaEmbeddableComposite(PropertyValueModel<? extends Embeddable> subjectHolder,
+	                           Composite parent,
+	                           WidgetFactory widgetFactory) {
+
+		super(subjectHolder, parent, widgetFactory);
+	}
+
+}
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/java/JavaEmbeddableUiDefinition.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/java/JavaEmbeddableUiDefinition.java
new file mode 100644
index 0000000..f2a640e
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/java/JavaEmbeddableUiDefinition.java
@@ -0,0 +1,54 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2009 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.ui.internal.details.java;
+
+import org.eclipse.jpt.core.context.PersistentType;
+import org.eclipse.jpt.core.context.java.JavaEmbeddable;
+import org.eclipse.jpt.ui.WidgetFactory;
+import org.eclipse.jpt.ui.details.JpaComposite;
+import org.eclipse.jpt.ui.details.java.JavaTypeMappingUiDefinition;
+import org.eclipse.jpt.ui.details.java.JavaUiFactory;
+import org.eclipse.jpt.ui.internal.details.AbstractEmbeddableUiDefinition;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+public class JavaEmbeddableUiDefinition 
+	extends AbstractEmbeddableUiDefinition<PersistentType, JavaEmbeddable>
+	implements JavaTypeMappingUiDefinition<JavaEmbeddable>
+{
+	// singleton
+	private static final JavaEmbeddableUiDefinition INSTANCE = new JavaEmbeddableUiDefinition();
+	
+	
+	/**
+	 * Return the singleton.
+	 */
+	public static JavaTypeMappingUiDefinition<JavaEmbeddable> instance() {
+		return INSTANCE;
+	}
+	
+	
+	/**
+	 * Ensure single instance.
+	 */
+	private JavaEmbeddableUiDefinition() {
+		super();
+	}
+	
+	
+	public JpaComposite buildTypeMappingComposite(
+			JavaUiFactory factory,
+			PropertyValueModel<JavaEmbeddable> subjectHolder,
+			Composite parent,
+			WidgetFactory widgetFactory) {
+		
+		return factory.createJavaEmbeddableComposite(subjectHolder, parent, widgetFactory);
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/java/JavaEmbeddedIdMappingUDefinition.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/java/JavaEmbeddedIdMappingUDefinition.java
new file mode 100644
index 0000000..0c9dd73
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/java/JavaEmbeddedIdMappingUDefinition.java
@@ -0,0 +1,55 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2009 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.ui.internal.details.java;
+
+import org.eclipse.jpt.core.context.PersistentAttribute;
+import org.eclipse.jpt.core.context.java.JavaEmbeddedIdMapping;
+import org.eclipse.jpt.ui.WidgetFactory;
+import org.eclipse.jpt.ui.details.JpaComposite;
+import org.eclipse.jpt.ui.details.java.JavaAttributeMappingUiDefinition;
+import org.eclipse.jpt.ui.details.java.JavaUiFactory;
+import org.eclipse.jpt.ui.internal.details.AbstractEmbeddedIdMappingUiDefinition;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+public class JavaEmbeddedIdMappingUDefinition
+	extends AbstractEmbeddedIdMappingUiDefinition<PersistentAttribute, JavaEmbeddedIdMapping>
+	implements JavaAttributeMappingUiDefinition<JavaEmbeddedIdMapping>
+{
+	// singleton
+	private static final JavaEmbeddedIdMappingUDefinition INSTANCE = 
+			new JavaEmbeddedIdMappingUDefinition();
+	
+	
+	/**
+	 * Return the singleton.
+	 */
+	public static JavaAttributeMappingUiDefinition<JavaEmbeddedIdMapping> instance() {
+		return INSTANCE;
+	}
+	
+	
+	/**
+	 * Ensure single instance.
+	 */
+	private JavaEmbeddedIdMappingUDefinition() {
+		super();
+	}	
+	
+	
+	public JpaComposite buildAttributeMappingComposite(
+			JavaUiFactory factory,
+			PropertyValueModel<JavaEmbeddedIdMapping> subjectHolder,
+			Composite parent,
+			WidgetFactory widgetFactory) {
+		
+		return factory.createJavaEmbeddedIdMappingComposite(subjectHolder, parent, widgetFactory);
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/java/JavaEmbeddedMappingUiDefinition.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/java/JavaEmbeddedMappingUiDefinition.java
new file mode 100644
index 0000000..d237c2d
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/java/JavaEmbeddedMappingUiDefinition.java
@@ -0,0 +1,55 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2009 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.ui.internal.details.java;
+
+import org.eclipse.jpt.core.context.PersistentAttribute;
+import org.eclipse.jpt.core.context.java.JavaEmbeddedMapping;
+import org.eclipse.jpt.ui.WidgetFactory;
+import org.eclipse.jpt.ui.details.JpaComposite;
+import org.eclipse.jpt.ui.details.java.JavaAttributeMappingUiDefinition;
+import org.eclipse.jpt.ui.details.java.JavaUiFactory;
+import org.eclipse.jpt.ui.internal.details.AbstractEmbeddedMappingUiDefinition;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+public class JavaEmbeddedMappingUiDefinition
+	extends AbstractEmbeddedMappingUiDefinition<PersistentAttribute, JavaEmbeddedMapping>
+	implements JavaAttributeMappingUiDefinition<JavaEmbeddedMapping>
+{
+	// singleton
+	private static final JavaEmbeddedMappingUiDefinition INSTANCE = 
+			new JavaEmbeddedMappingUiDefinition();
+	
+	
+	/**
+	 * Return the singleton.
+	 */
+	public static JavaAttributeMappingUiDefinition<JavaEmbeddedMapping> instance() {
+		return INSTANCE;
+	}
+	
+	
+	/**
+	 * Ensure single instance.
+	 */
+	private JavaEmbeddedMappingUiDefinition() {
+		super();
+	}
+	
+	
+	public JpaComposite buildAttributeMappingComposite(
+			JavaUiFactory factory,
+			PropertyValueModel<JavaEmbeddedMapping> subjectHolder,
+			Composite parent,
+			WidgetFactory widgetFactory) {
+		
+		return factory.createJavaEmbeddedMappingComposite(subjectHolder, parent, widgetFactory);
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/java/JavaEntityComposite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/java/JavaEntityComposite.java
new file mode 100644
index 0000000..7b423c3
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/java/JavaEntityComposite.java
@@ -0,0 +1,53 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2010 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.ui.internal.details.java;
+
+import org.eclipse.jpt.core.context.java.JavaEntity;
+import org.eclipse.jpt.ui.WidgetFactory;
+import org.eclipse.jpt.ui.internal.details.AbstractEntityComposite;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * The pane used for a Java entity.
+ *
+ * @see JavaEntity
+ * @see JavaUiFactory - The factory creating this pane
+ * @see JavaSecondaryTablesComposite
+ *
+ * @version 2.3
+ * @since 1.0
+ */
+public class JavaEntityComposite extends AbstractEntityComposite<JavaEntity>
+{
+	/**
+	 * Creates a new <code>JavaEntityComposite</code>.
+	 *
+	 * @param subjectHolder The holder of the subject <code>JavaEntity</code>
+	 * @param parent The parent container
+	 * @param widgetFactory The factory used to create various common widgets
+	 */
+	public JavaEntityComposite(PropertyValueModel<? extends JavaEntity> subjectHolder,
+	                           Composite parent,
+	                           WidgetFactory widgetFactory) {
+
+		super(subjectHolder, parent, widgetFactory);
+	}
+
+	@Override
+	protected void initializeSecondaryTablesSection(Composite container) {
+		new JavaSecondaryTablesComposite(this, container);
+	}
+
+	@Override
+	protected void initializeInheritanceSection(Composite container) {
+		new JavaInheritanceComposite(this, container);
+	}
+}
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/java/JavaEntityUiDefinition.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/java/JavaEntityUiDefinition.java
new file mode 100644
index 0000000..d5ee673
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/java/JavaEntityUiDefinition.java
@@ -0,0 +1,55 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2009 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.ui.internal.details.java;
+
+import org.eclipse.jpt.core.context.PersistentType;
+import org.eclipse.jpt.core.context.java.JavaEntity;
+import org.eclipse.jpt.ui.WidgetFactory;
+import org.eclipse.jpt.ui.details.JpaComposite;
+import org.eclipse.jpt.ui.details.java.JavaTypeMappingUiDefinition;
+import org.eclipse.jpt.ui.details.java.JavaUiFactory;
+import org.eclipse.jpt.ui.internal.details.AbstractEntityUiDefinition;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+public class JavaEntityUiDefinition
+	extends AbstractEntityUiDefinition<PersistentType, JavaEntity>
+	implements JavaTypeMappingUiDefinition<JavaEntity>
+{
+	// singleton
+	private static final JavaEntityUiDefinition INSTANCE = 
+			new JavaEntityUiDefinition();
+	
+	
+	/**
+	 * Return the singleton.
+	 */
+	public static JavaTypeMappingUiDefinition<JavaEntity> instance() {
+		return INSTANCE;
+	}
+	
+	
+	/**
+	 * Ensure single instance.
+	 */
+	private JavaEntityUiDefinition() {
+		super();
+	}
+	
+	
+	public JpaComposite buildTypeMappingComposite(
+			JavaUiFactory factory,
+			PropertyValueModel<JavaEntity> subjectHolder,
+			Composite parent,
+			WidgetFactory widgetFactory) {
+		
+		return factory.createJavaEntityComposite(subjectHolder, parent, widgetFactory);
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/java/JavaIdMappingUiDefinition.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/java/JavaIdMappingUiDefinition.java
new file mode 100644
index 0000000..109badb
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/java/JavaIdMappingUiDefinition.java
@@ -0,0 +1,55 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2009 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.ui.internal.details.java;
+
+import org.eclipse.jpt.core.context.PersistentAttribute;
+import org.eclipse.jpt.core.context.java.JavaIdMapping;
+import org.eclipse.jpt.ui.WidgetFactory;
+import org.eclipse.jpt.ui.details.JpaComposite;
+import org.eclipse.jpt.ui.details.java.JavaAttributeMappingUiDefinition;
+import org.eclipse.jpt.ui.details.java.JavaUiFactory;
+import org.eclipse.jpt.ui.internal.details.AbstractIdMappingUiDefinition;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+public class JavaIdMappingUiDefinition
+	extends AbstractIdMappingUiDefinition<PersistentAttribute, JavaIdMapping>
+	implements JavaAttributeMappingUiDefinition<JavaIdMapping>
+{
+	// singleton
+	private static final JavaIdMappingUiDefinition INSTANCE = 
+			new JavaIdMappingUiDefinition();
+	
+	
+	/**
+	 * Return the singleton.
+	 */
+	public static JavaAttributeMappingUiDefinition<JavaIdMapping> instance() {
+		return INSTANCE;
+	}
+	
+	
+	/**
+	 * Ensure single instance.
+	 */
+	protected JavaIdMappingUiDefinition() {
+		super();
+	}
+	
+	
+	public JpaComposite buildAttributeMappingComposite(
+			JavaUiFactory factory,
+			PropertyValueModel<JavaIdMapping> subjectHolder,
+			Composite parent,
+			WidgetFactory widgetFactory) {
+		
+		return factory.createJavaIdMappingComposite(subjectHolder, parent, widgetFactory);
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/java/JavaInheritanceComposite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/java/JavaInheritanceComposite.java
new file mode 100644
index 0000000..cfc7b6c
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/java/JavaInheritanceComposite.java
@@ -0,0 +1,44 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2010 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.ui.internal.details.java;
+
+import org.eclipse.jpt.core.context.java.JavaEntity;
+import org.eclipse.jpt.ui.internal.details.AbstractInheritanceComposite;
+import org.eclipse.jpt.ui.internal.widgets.Pane;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * The pane used for java inheritance.
+ *
+ * @see JavaEntity
+ * @see JavaPrimaryKeyJoinColumnsComposite
+ *
+ * @version 2.0
+ * @since 1.0
+ */
+public class JavaInheritanceComposite extends AbstractInheritanceComposite<JavaEntity> {
+
+	/**
+	 * Creates a new <code>JavaInheritanceComposite</code>.
+	 *
+	 * @param parentPane The parent container of this one
+	 * @param parent The parent container
+	 */
+	public JavaInheritanceComposite(Pane<? extends JavaEntity> parentPane,
+	                            Composite parent) {
+
+		super(parentPane, parent);
+	}
+
+	@Override
+	protected void addPrimaryKeyJoinColumnsComposite(Composite container) {
+		new JavaPrimaryKeyJoinColumnsComposite(this, container);
+	}
+}
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/java/JavaManyToManyMappingUiDefinition.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/java/JavaManyToManyMappingUiDefinition.java
new file mode 100644
index 0000000..0c7fe0f
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/java/JavaManyToManyMappingUiDefinition.java
@@ -0,0 +1,55 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2009 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.ui.internal.details.java;
+
+import org.eclipse.jpt.core.context.PersistentAttribute;
+import org.eclipse.jpt.core.context.java.JavaManyToManyMapping;
+import org.eclipse.jpt.ui.WidgetFactory;
+import org.eclipse.jpt.ui.details.JpaComposite;
+import org.eclipse.jpt.ui.details.java.JavaAttributeMappingUiDefinition;
+import org.eclipse.jpt.ui.details.java.JavaUiFactory;
+import org.eclipse.jpt.ui.internal.details.AbstractManyToManyMappingUiDefinition;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+public class JavaManyToManyMappingUiDefinition
+	extends AbstractManyToManyMappingUiDefinition<PersistentAttribute, JavaManyToManyMapping>
+	implements JavaAttributeMappingUiDefinition<JavaManyToManyMapping>
+{
+	// singleton
+	private static final JavaManyToManyMappingUiDefinition INSTANCE = 
+			new JavaManyToManyMappingUiDefinition();
+	
+	
+	/**
+	 * Return the singleton.
+	 */
+	public static JavaAttributeMappingUiDefinition<JavaManyToManyMapping> instance() {
+		return INSTANCE;
+	}
+	
+	
+	/**
+	 * Ensure single instance.
+	 */
+	private JavaManyToManyMappingUiDefinition() {
+		super();
+	}
+	
+	
+	public JpaComposite buildAttributeMappingComposite(
+			JavaUiFactory factory,
+			PropertyValueModel<JavaManyToManyMapping> subjectHolder,
+			Composite parent,
+			WidgetFactory widgetFactory) {
+		
+		return factory.createJavaManyToManyMappingComposite(subjectHolder, parent, widgetFactory);
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/java/JavaManyToOneMappingUiDefinition.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/java/JavaManyToOneMappingUiDefinition.java
new file mode 100644
index 0000000..d6fd784
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/java/JavaManyToOneMappingUiDefinition.java
@@ -0,0 +1,55 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2009 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.ui.internal.details.java;
+
+import org.eclipse.jpt.core.context.PersistentAttribute;
+import org.eclipse.jpt.core.context.java.JavaManyToOneMapping;
+import org.eclipse.jpt.ui.WidgetFactory;
+import org.eclipse.jpt.ui.details.JpaComposite;
+import org.eclipse.jpt.ui.details.java.JavaAttributeMappingUiDefinition;
+import org.eclipse.jpt.ui.details.java.JavaUiFactory;
+import org.eclipse.jpt.ui.internal.details.AbstractManyToOneMappingUiDefinition;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+public class JavaManyToOneMappingUiDefinition
+	extends AbstractManyToOneMappingUiDefinition<PersistentAttribute, JavaManyToOneMapping>
+	implements JavaAttributeMappingUiDefinition<JavaManyToOneMapping>
+{
+	// singleton
+	private static final JavaManyToOneMappingUiDefinition INSTANCE = 
+			new JavaManyToOneMappingUiDefinition();
+	
+	
+	/**
+	 * Return the singleton.
+	 */
+	public static JavaAttributeMappingUiDefinition<JavaManyToOneMapping> instance() {
+		return INSTANCE;
+	}
+	
+	
+	/**
+	 * Ensure single instance.
+	 */
+	private JavaManyToOneMappingUiDefinition() {
+		super();
+	}
+	
+	
+	public JpaComposite buildAttributeMappingComposite(
+			JavaUiFactory factory,
+			PropertyValueModel<JavaManyToOneMapping> subjectHolder,
+			Composite parent,
+			WidgetFactory widgetFactory) {
+		
+		return factory.createJavaManyToOneMappingComposite(subjectHolder, parent, widgetFactory);
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/java/JavaMappedSuperclassComposite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/java/JavaMappedSuperclassComposite.java
new file mode 100644
index 0000000..63d7ae5
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/java/JavaMappedSuperclassComposite.java
@@ -0,0 +1,54 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2010 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.ui.internal.details.java;
+
+import org.eclipse.jpt.core.context.MappedSuperclass;
+import org.eclipse.jpt.core.context.java.JavaMappedSuperclass;
+import org.eclipse.jpt.ui.WidgetFactory;
+import org.eclipse.jpt.ui.details.java.JavaUiFactory;
+import org.eclipse.jpt.ui.internal.details.AbstractMappedSuperclassComposite;
+import org.eclipse.jpt.ui.internal.details.IdClassComposite;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * Here the layout of this pane:
+ * <pre>
+ * -----------------------------------------------------------------------------
+ * |                                                                           |
+ * | IdClassComposite                                                          |
+ * |                                                                           |
+ * -----------------------------------------------------------------------------</pre>
+ *
+ * @see MappedSuperclass
+ * @see JavaUiFactory - The factory creating this pane
+ * @see IdClassComposite
+ *
+ * @version 2.3
+ * @since 2.0
+ */
+public class JavaMappedSuperclassComposite
+	extends AbstractMappedSuperclassComposite<JavaMappedSuperclass>
+{
+	/**
+	 * Creates a new <code>MappedSuperclassComposite</code>.
+	 *
+	 * @param subjectHolder The holder of this pane's subject
+	 * @param parent The parent container
+	 * @param widgetFactory The factory used to create various common widgets
+	 */
+	public JavaMappedSuperclassComposite(
+			PropertyValueModel<? extends JavaMappedSuperclass> subjectHolder,
+			Composite parent,
+			WidgetFactory widgetFactory) {
+		
+		super(subjectHolder, parent, widgetFactory);
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/java/JavaMappedSuperclassUiDefinition.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/java/JavaMappedSuperclassUiDefinition.java
new file mode 100644
index 0000000..6738979
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/java/JavaMappedSuperclassUiDefinition.java
@@ -0,0 +1,55 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2009 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.ui.internal.details.java;
+
+import org.eclipse.jpt.core.context.PersistentType;
+import org.eclipse.jpt.core.context.java.JavaMappedSuperclass;
+import org.eclipse.jpt.ui.WidgetFactory;
+import org.eclipse.jpt.ui.details.JpaComposite;
+import org.eclipse.jpt.ui.details.java.JavaTypeMappingUiDefinition;
+import org.eclipse.jpt.ui.details.java.JavaUiFactory;
+import org.eclipse.jpt.ui.internal.details.AbstractMappedSuperclassUiDefinition;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+public class JavaMappedSuperclassUiDefinition
+	extends AbstractMappedSuperclassUiDefinition<PersistentType, JavaMappedSuperclass>
+	implements JavaTypeMappingUiDefinition<JavaMappedSuperclass>
+{
+	// singleton
+	private static final JavaMappedSuperclassUiDefinition INSTANCE = 
+			new JavaMappedSuperclassUiDefinition();
+	
+	
+	/**
+	 * Return the singleton.
+	 */
+	public static JavaTypeMappingUiDefinition<JavaMappedSuperclass> instance() {
+		return INSTANCE;
+	}
+	
+	
+	/**
+	 * Ensure single instance.
+	 */
+	private JavaMappedSuperclassUiDefinition() {
+		super();
+	}
+	
+	
+	public JpaComposite buildTypeMappingComposite(
+			JavaUiFactory factory,
+			PropertyValueModel<JavaMappedSuperclass> subjectHolder,
+			Composite parent,
+			WidgetFactory widgetFactory) {
+		
+		return factory.createJavaMappedSuperclassComposite(subjectHolder, parent, widgetFactory);
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/java/JavaOneToManyMappingUiDefinition.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/java/JavaOneToManyMappingUiDefinition.java
new file mode 100644
index 0000000..1732a9c
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/java/JavaOneToManyMappingUiDefinition.java
@@ -0,0 +1,55 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2009 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.ui.internal.details.java;
+
+import org.eclipse.jpt.core.context.PersistentAttribute;
+import org.eclipse.jpt.core.context.java.JavaOneToManyMapping;
+import org.eclipse.jpt.ui.WidgetFactory;
+import org.eclipse.jpt.ui.details.JpaComposite;
+import org.eclipse.jpt.ui.details.java.JavaAttributeMappingUiDefinition;
+import org.eclipse.jpt.ui.details.java.JavaUiFactory;
+import org.eclipse.jpt.ui.internal.details.AbstractOneToManyMappingUiDefinition;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+public class JavaOneToManyMappingUiDefinition
+	extends AbstractOneToManyMappingUiDefinition<PersistentAttribute, JavaOneToManyMapping>
+	implements JavaAttributeMappingUiDefinition<JavaOneToManyMapping>
+{
+	// singleton
+	private static final JavaOneToManyMappingUiDefinition INSTANCE = 
+			new JavaOneToManyMappingUiDefinition();
+	
+	
+	/**
+	 * Return the singleton.
+	 */
+	public static JavaAttributeMappingUiDefinition<JavaOneToManyMapping> instance() {
+		return INSTANCE;
+	}
+	
+	
+	/**
+	 * Ensure single instance.
+	 */
+	private JavaOneToManyMappingUiDefinition() {
+		super();
+	}
+	
+	
+	public JpaComposite buildAttributeMappingComposite(
+			JavaUiFactory factory,
+			PropertyValueModel<JavaOneToManyMapping> subjectHolder,
+			Composite parent,
+			WidgetFactory widgetFactory) {
+		
+		return factory.createJavaOneToManyMappingComposite(subjectHolder, parent, widgetFactory);
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/java/JavaOneToOneMappingUiDefinition.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/java/JavaOneToOneMappingUiDefinition.java
new file mode 100644
index 0000000..3d9381a
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/java/JavaOneToOneMappingUiDefinition.java
@@ -0,0 +1,55 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2009 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.ui.internal.details.java;
+
+import org.eclipse.jpt.core.context.PersistentAttribute;
+import org.eclipse.jpt.core.context.java.JavaOneToOneMapping;
+import org.eclipse.jpt.ui.WidgetFactory;
+import org.eclipse.jpt.ui.details.JpaComposite;
+import org.eclipse.jpt.ui.details.java.JavaAttributeMappingUiDefinition;
+import org.eclipse.jpt.ui.details.java.JavaUiFactory;
+import org.eclipse.jpt.ui.internal.details.AbstractOneToOneMappingUiDefinition;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+public class JavaOneToOneMappingUiDefinition
+	extends AbstractOneToOneMappingUiDefinition<PersistentAttribute, JavaOneToOneMapping>
+	implements JavaAttributeMappingUiDefinition<JavaOneToOneMapping>
+{
+	// singleton
+	private static final JavaOneToOneMappingUiDefinition INSTANCE = 
+			new JavaOneToOneMappingUiDefinition();
+	
+	
+	/**
+	 * Return the singleton.
+	 */
+	public static JavaAttributeMappingUiDefinition<JavaOneToOneMapping> instance() {
+		return INSTANCE;
+	}
+	
+	
+	/**
+	 * Ensure single instance.
+	 */
+	private JavaOneToOneMappingUiDefinition() {
+		super();
+	}
+	
+	
+	public JpaComposite buildAttributeMappingComposite(
+			JavaUiFactory factory,
+			PropertyValueModel<JavaOneToOneMapping> subjectHolder,
+			Composite parent,
+			WidgetFactory widgetFactory) {
+		
+		return factory.createJavaOneToOneMappingComposite(subjectHolder, parent, widgetFactory);
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/java/JavaPersistentAttributeDetailsPage.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/java/JavaPersistentAttributeDetailsPage.java
new file mode 100644
index 0000000..08eb26b
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/java/JavaPersistentAttributeDetailsPage.java
@@ -0,0 +1,68 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2009 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.ui.internal.details.java;
+
+import org.eclipse.jpt.core.context.java.JavaPersistentAttribute;
+import org.eclipse.jpt.ui.WidgetFactory;
+import org.eclipse.jpt.ui.internal.details.PersistentAttributeDetailsPage;
+import org.eclipse.jpt.ui.internal.details.PersistentAttributeMapAsComposite;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * The default implementation of the details page used for the Java persistent
+ * attribute.
+ * <p>
+ * Here the layout of this pane:
+ * <pre>
+ * -----------------------------------------------------------------------------
+ * | ------------------------------------------------------------------------- |
+ * | |                                                                       | |
+ * | | JavaPersistentAttributeMapAsComposite                                 | |
+ * | |                                                                       | |
+ * | ------------------------------------------------------------------------- |
+ * | ------------------------------------------------------------------------- |
+ * | |                                                                       | |
+ * | | Type mapping pane                                                     | |
+ * | |                                                                       | |
+ * | ------------------------------------------------------------------------- |
+ * -----------------------------------------------------------------------------</pre>
+ *
+ * @see JavaPersistentAttribute
+ * @see JavaPersistentTypeMapAsComposite
+ *
+ * @version 2.2
+ * @since 2.0
+ */
+public class JavaPersistentAttributeDetailsPage extends PersistentAttributeDetailsPage<JavaPersistentAttribute>
+{
+	/**
+	 * Creates a new <code>JavaPersistentAttributeDetailsPage</code>.
+	 *
+	 * @param parent The parent container
+	 * @param widgetFactory The factory used to create various common widgets
+	 */
+	public JavaPersistentAttributeDetailsPage(Composite parent,
+	                                          WidgetFactory widgetFactory) {
+
+		super(parent, widgetFactory);
+	}
+
+	@Override
+	protected void initializeLayout(Composite container) {
+
+		// Map as composite
+		new PersistentAttributeMapAsComposite(
+			this,
+			addSubPane(container, 0, 0, 5, 0)
+		);
+
+		buildMappingPageBook(container);
+	}
+}
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/java/JavaPersistentAttributeDetailsProvider.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/java/JavaPersistentAttributeDetailsProvider.java
new file mode 100644
index 0000000..8db5a44
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/java/JavaPersistentAttributeDetailsProvider.java
@@ -0,0 +1,60 @@
+/*******************************************************************************
+ * Copyright (c) 2009 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.ui.internal.details.java;
+
+import org.eclipse.jpt.core.JpaStructureNode;
+import org.eclipse.jpt.core.JptCorePlugin;
+import org.eclipse.jpt.core.context.java.JavaPersistentAttribute;
+import org.eclipse.jpt.core.context.java.JavaStructureNodes;
+import org.eclipse.jpt.ui.WidgetFactory;
+import org.eclipse.jpt.ui.details.JpaDetailsPage;
+import org.eclipse.jpt.ui.details.JpaDetailsProvider;
+import org.eclipse.jpt.utility.internal.StringTools;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * This provider is responsible for creating the <code>JpaDetailsPage</code>
+ * when the information comes from the Java source file.
+ */
+public class JavaPersistentAttributeDetailsProvider
+	implements JpaDetailsProvider
+{
+	// singleton
+	private static final JpaDetailsProvider INSTANCE = new JavaPersistentAttributeDetailsProvider();
+	
+	
+	/**
+	 * Return the singleton
+	 */
+	public static JpaDetailsProvider instance() {
+		return INSTANCE;
+	}
+	
+	
+	/**
+	 * Enforce singleton usage
+	 */
+	private JavaPersistentAttributeDetailsProvider() {
+		super();
+	}
+	
+	
+	public boolean providesDetails(JpaStructureNode structureNode) {
+			return StringTools.stringsAreEqual(structureNode.getId(), JavaStructureNodes.PERSISTENT_ATTRIBUTE_ID)
+				&& structureNode.getResourceType().getContentType().equals(JptCorePlugin.JAVA_SOURCE_CONTENT_TYPE);
+	}
+	
+	public JpaDetailsPage<JavaPersistentAttribute> buildDetailsPage(
+			Composite parent,
+			WidgetFactory widgetFactory) {
+		
+		return new JavaPersistentAttributeDetailsPage(parent, widgetFactory);
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/java/JavaPersistentTypeDetailsProvider.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/java/JavaPersistentTypeDetailsProvider.java
new file mode 100644
index 0000000..a64b188
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/java/JavaPersistentTypeDetailsProvider.java
@@ -0,0 +1,61 @@
+/*******************************************************************************
+ * Copyright (c) 2009 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.ui.internal.details.java;
+
+import org.eclipse.jpt.core.JpaStructureNode;
+import org.eclipse.jpt.core.JptCorePlugin;
+import org.eclipse.jpt.core.context.PersistentType;
+import org.eclipse.jpt.core.context.java.JavaStructureNodes;
+import org.eclipse.jpt.ui.WidgetFactory;
+import org.eclipse.jpt.ui.details.JpaDetailsPage;
+import org.eclipse.jpt.ui.details.JpaDetailsProvider;
+import org.eclipse.jpt.ui.internal.details.PersistentTypeDetailsPage;
+import org.eclipse.jpt.utility.internal.StringTools;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * This provider is responsible for creating the <code>JpaDetailsPage</code>
+ * when the information comes from the Java source file.
+ */
+public class JavaPersistentTypeDetailsProvider
+	implements JpaDetailsProvider
+{
+	// singleton
+	private static final JpaDetailsProvider INSTANCE = new JavaPersistentTypeDetailsProvider();
+	
+	
+	/**
+	 * Return the singleton
+	 */
+	public static JpaDetailsProvider instance() {
+		return INSTANCE;
+	}
+	
+	
+	/**
+	 * Enforce singleton usage
+	 */
+	private JavaPersistentTypeDetailsProvider() {
+		super();
+	}
+	
+	
+	public boolean providesDetails(JpaStructureNode structureNode) {
+			return StringTools.stringsAreEqual(structureNode.getId(), JavaStructureNodes.PERSISTENT_TYPE_ID)
+				&& structureNode.getResourceType().getContentType().equals(JptCorePlugin.JAVA_SOURCE_CONTENT_TYPE);
+	}
+	
+	public JpaDetailsPage<PersistentType> buildDetailsPage(
+			Composite parent,
+			WidgetFactory widgetFactory) {
+		
+		return new PersistentTypeDetailsPage(parent, widgetFactory);
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/java/JavaPrimaryKeyJoinColumnsComposite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/java/JavaPrimaryKeyJoinColumnsComposite.java
new file mode 100644
index 0000000..b0a9222
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/java/JavaPrimaryKeyJoinColumnsComposite.java
@@ -0,0 +1,75 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2009 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.ui.internal.details.java;
+
+import org.eclipse.jpt.core.context.Entity;
+import org.eclipse.jpt.core.context.PrimaryKeyJoinColumn;
+import org.eclipse.jpt.core.context.java.JavaEntity;
+import org.eclipse.jpt.ui.internal.details.AbstractPrimaryKeyJoinColumnsComposite;
+import org.eclipse.jpt.ui.internal.widgets.Pane;
+import org.eclipse.jpt.utility.internal.model.value.PropertyAspectAdapter;
+import org.eclipse.jpt.utility.internal.model.value.PropertyListValueModelAdapter;
+import org.eclipse.jpt.utility.model.value.ListValueModel;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * @see JavaEntity
+ * @see JavaInheritanceComposite - The container of this pane
+ *
+ * @version 2.0
+ * @since 2.0
+ */
+public class JavaPrimaryKeyJoinColumnsComposite extends AbstractPrimaryKeyJoinColumnsComposite<JavaEntity>
+{
+
+	/**
+	 * Creates a new <code>JavaPrimaryKeyJoinColumnsComposite</code>.
+	 *
+	 * @param parentPane The parent controller of this one
+	 * @param parent The parent container
+	 */
+	public JavaPrimaryKeyJoinColumnsComposite(Pane<? extends JavaEntity> subjectHolder,
+	                                      Composite parent) {
+
+		super(subjectHolder, parent);
+	}
+	
+	@Override
+	protected ListValueModel<PrimaryKeyJoinColumn> buildDefaultJoinColumnsListHolder() {
+		return new PropertyListValueModelAdapter<PrimaryKeyJoinColumn>(buildDefaultJoinColumnHolder());
+	}
+	
+	private PropertyValueModel<PrimaryKeyJoinColumn> buildDefaultJoinColumnHolder() {
+		return new PropertyAspectAdapter<Entity, PrimaryKeyJoinColumn>(getSubjectHolder(), Entity.DEFAULT_PRIMARY_KEY_JOIN_COLUMN) {
+			@Override
+			protected PrimaryKeyJoinColumn buildValue_() {
+				return subject.getDefaultPrimaryKeyJoinColumn();
+			}
+		};
+	}
+	
+	@Override
+	protected void switchDefaultToSpecified() {
+		PrimaryKeyJoinColumn defaultJoinColumn = getSubject().getDefaultPrimaryKeyJoinColumn();
+
+		if (defaultJoinColumn != null) {
+			String columnName = defaultJoinColumn.getDefaultName();
+			String referencedColumnName = defaultJoinColumn.getDefaultReferencedColumnName();
+
+			PrimaryKeyJoinColumn pkJoinColumn = getSubject().addSpecifiedPrimaryKeyJoinColumn(0);
+			pkJoinColumn.setSpecifiedName(columnName);
+			pkJoinColumn.setSpecifiedReferencedColumnName(referencedColumnName);
+
+			this.joinColumnHolder.setValue(pkJoinColumn);
+		}
+	}
+
+}
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/java/JavaSecondaryTablesComposite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/java/JavaSecondaryTablesComposite.java
new file mode 100644
index 0000000..735517e
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/java/JavaSecondaryTablesComposite.java
@@ -0,0 +1,131 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2010 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.ui.internal.details.java;
+
+import java.util.ListIterator;
+
+import org.eclipse.jpt.core.context.Entity;
+import org.eclipse.jpt.core.context.SecondaryTable;
+import org.eclipse.jpt.core.context.Table;
+import org.eclipse.jpt.core.context.java.JavaEntity;
+import org.eclipse.jpt.ui.WidgetFactory;
+import org.eclipse.jpt.ui.internal.JpaHelpContextIds;
+import org.eclipse.jpt.ui.internal.details.AbstractSecondaryTablesComposite;
+import org.eclipse.jpt.ui.internal.details.PrimaryKeyJoinColumnsInSecondaryTableComposite;
+import org.eclipse.jpt.ui.internal.widgets.AddRemoveListPane;
+import org.eclipse.jpt.ui.internal.widgets.Pane;
+import org.eclipse.jpt.utility.internal.model.value.ItemPropertyListValueModelAdapter;
+import org.eclipse.jpt.utility.internal.model.value.ListAspectAdapter;
+import org.eclipse.jpt.utility.model.value.ListValueModel;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.jpt.utility.model.value.WritablePropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * Here the layout of this pane:
+ * <pre>
+ * -----------------------------------------------------------------------------
+ * | ------------------------------------------------------------------------- |
+ * | |                                                                       | |
+ * | | AddRemoveListPane                                                     | |
+ * | |                                                                       | |
+ * | ------------------------------------------------------------------------- |
+ * | ------------------------------------------------------------------------- |
+ * | |                                                                       | |
+ * | | PrimaryKeyJoinColumnsInSecondaryTableComposite                        | |
+ * | |                                                                       | |
+ * | ------------------------------------------------------------------------- |
+ * -----------------------------------------------------------------------------</pre>
+ *
+ * @see Entity
+ * @see EntityComposite - The container of this pane
+ * @see AddRemoveListPane
+ * @see PrimaryKeyJoinColumnsInSecondaryTableComposite
+ *
+ * @version 2.0
+ * @since 1.0
+ */
+public class JavaSecondaryTablesComposite extends AbstractSecondaryTablesComposite<JavaEntity>
+{
+	/**
+	 * Creates a new <code>SecondaryTablesComposite</code>.
+	 *
+	 * @param parentPane The parent container of this one
+	 * @param parent The parent container
+	 */
+	public JavaSecondaryTablesComposite(Pane<? extends JavaEntity> parentPane,
+	                                Composite parent) {
+
+		super(parentPane, parent);
+	}
+
+	/**
+	 * Creates a new <code>SecondaryTablesComposite</code>.
+	 *
+	 * @param subjectHolder The holder of the subject <code>IEntity</code>
+	 * @param parent The parent container
+	 * @param widgetFactory The factory used to create various common widgets
+	 */
+	public JavaSecondaryTablesComposite(PropertyValueModel<? extends JavaEntity> subjectHolder,
+	                                Composite parent,
+	                                WidgetFactory widgetFactory) {
+
+		super(subjectHolder, parent, widgetFactory);
+	}
+
+	private ListValueModel<SecondaryTable> buildSecondaryTablesListModel() {
+		return new ItemPropertyListValueModelAdapter<SecondaryTable>(buildSecondaryTablesListHolder(), 
+			Table.SPECIFIED_NAME_PROPERTY);
+	}	
+
+	private ListValueModel<SecondaryTable> buildSecondaryTablesListHolder() {
+		return new ListAspectAdapter<Entity, SecondaryTable>(getSubjectHolder(), Entity.SPECIFIED_SECONDARY_TABLES_LIST) {
+			@Override
+			protected ListIterator<SecondaryTable> listIterator_() {
+				return subject.specifiedSecondaryTables();
+			}
+
+			@Override
+			protected int size_() {
+				return subject.specifiedSecondaryTablesSize();
+			}
+		};
+	}
+
+	/*
+	 * (non-Javadoc)
+	 */
+	@Override
+	protected void initializeLayout(Composite container) {
+
+		int groupBoxMargin = getGroupBoxMargin();
+
+		WritablePropertyValueModel<SecondaryTable> secondaryTableHolder =
+			buildSecondaryTableHolder();
+
+		// Secondary Tables add/remove list pane
+		new AddRemoveListPane<Entity>(
+			this,
+			addSubPane(container, 0, groupBoxMargin, 0, groupBoxMargin),
+			buildSecondaryTablesAdapter(),
+			buildSecondaryTablesListModel(),
+			secondaryTableHolder,
+			buildSecondaryTableLabelProvider(),
+			JpaHelpContextIds.MAPPING_JOIN_TABLE_COLUMNS//TODO need a help context id for this
+		);
+
+		// Primary Key Join Columns pane
+		new PrimaryKeyJoinColumnsInSecondaryTableComposite(
+			this,
+			secondaryTableHolder,
+			container
+		);
+	}
+}
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/java/JavaTransientMappingUiDefinition.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/java/JavaTransientMappingUiDefinition.java
new file mode 100644
index 0000000..85e07e4
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/java/JavaTransientMappingUiDefinition.java
@@ -0,0 +1,55 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2009 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.ui.internal.details.java;
+
+import org.eclipse.jpt.core.context.PersistentAttribute;
+import org.eclipse.jpt.core.context.java.JavaTransientMapping;
+import org.eclipse.jpt.ui.WidgetFactory;
+import org.eclipse.jpt.ui.details.JpaComposite;
+import org.eclipse.jpt.ui.details.java.JavaAttributeMappingUiDefinition;
+import org.eclipse.jpt.ui.details.java.JavaUiFactory;
+import org.eclipse.jpt.ui.internal.details.AbstractTransientMappingUiDefinition;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+public class JavaTransientMappingUiDefinition
+	extends AbstractTransientMappingUiDefinition<PersistentAttribute, JavaTransientMapping>
+	implements JavaAttributeMappingUiDefinition<JavaTransientMapping>
+{
+	// singleton
+	private static final JavaTransientMappingUiDefinition INSTANCE = 
+			new JavaTransientMappingUiDefinition();
+	
+	
+	/**
+	 * Return the singleton.
+	 */
+	public static JavaAttributeMappingUiDefinition<JavaTransientMapping> instance() {
+		return INSTANCE;
+	}
+	
+	
+	/**
+	 * Ensure single instance.
+	 */
+	private JavaTransientMappingUiDefinition() {
+		super();
+	}
+	
+	
+	public JpaComposite buildAttributeMappingComposite(
+			JavaUiFactory factory,
+			PropertyValueModel<JavaTransientMapping> subjectHolder,
+			Composite parent,
+			WidgetFactory widgetFactory) {
+		
+		return factory.createJavaTransientMappingComposite(subjectHolder, parent, widgetFactory);
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/java/JavaVersionMappingUiDefinition.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/java/JavaVersionMappingUiDefinition.java
new file mode 100644
index 0000000..08d6df4
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/java/JavaVersionMappingUiDefinition.java
@@ -0,0 +1,55 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2009 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.ui.internal.details.java;
+
+import org.eclipse.jpt.core.context.PersistentAttribute;
+import org.eclipse.jpt.core.context.java.JavaVersionMapping;
+import org.eclipse.jpt.ui.WidgetFactory;
+import org.eclipse.jpt.ui.details.JpaComposite;
+import org.eclipse.jpt.ui.details.java.JavaAttributeMappingUiDefinition;
+import org.eclipse.jpt.ui.details.java.JavaUiFactory;
+import org.eclipse.jpt.ui.internal.details.AbstractVersionMappingUiDefinition;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+public class JavaVersionMappingUiDefinition
+	extends AbstractVersionMappingUiDefinition<PersistentAttribute, JavaVersionMapping>
+	implements JavaAttributeMappingUiDefinition<JavaVersionMapping>
+{
+	// singleton
+	private static final JavaVersionMappingUiDefinition INSTANCE = 
+			new JavaVersionMappingUiDefinition();
+	
+	
+	/**
+	 * Return the singleton.
+	 */
+	public static JavaAttributeMappingUiDefinition<JavaVersionMapping> instance() {
+		return INSTANCE;
+	}
+	
+	
+	/**
+	 * Ensure single instance.
+	 */
+	private JavaVersionMappingUiDefinition() {
+		super();
+	}
+	
+	
+	public JpaComposite buildAttributeMappingComposite(
+			JavaUiFactory factory,
+			PropertyValueModel<JavaVersionMapping> subjectHolder,
+			Composite parent,
+			WidgetFactory widgetFactory) {
+		
+		return factory.createJavaVersionMappingComposite(subjectHolder, parent, widgetFactory);
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/java/NullJavaAttributeMappingUiDefinition.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/java/NullJavaAttributeMappingUiDefinition.java
new file mode 100644
index 0000000..d8d1670
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/java/NullJavaAttributeMappingUiDefinition.java
@@ -0,0 +1,92 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2010 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.ui.internal.details.java;
+
+import org.eclipse.jpt.core.MappingKeys;
+import org.eclipse.jpt.core.context.PersistentAttribute;
+import org.eclipse.jpt.core.context.java.JavaAttributeMapping;
+import org.eclipse.jpt.ui.WidgetFactory;
+import org.eclipse.jpt.ui.details.JpaComposite;
+import org.eclipse.jpt.ui.details.java.DefaultJavaAttributeMappingUiDefinition;
+import org.eclipse.jpt.ui.details.java.JavaUiFactory;
+import org.eclipse.jpt.ui.internal.JpaMappingImageHelper;
+import org.eclipse.jpt.ui.internal.details.AbstractMappingUiDefinition;
+import org.eclipse.jpt.ui.internal.details.JptUiDetailsMessages;
+import org.eclipse.jpt.ui.internal.widgets.Pane;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Composite;
+
+public class NullJavaAttributeMappingUiDefinition
+	extends AbstractMappingUiDefinition<PersistentAttribute, JavaAttributeMapping>
+	implements DefaultJavaAttributeMappingUiDefinition<JavaAttributeMapping>
+{
+	// singleton
+	private static final NullJavaAttributeMappingUiDefinition INSTANCE = 
+		new NullJavaAttributeMappingUiDefinition();
+	
+	/**
+	 * Return the singleton.
+	 */
+	public static DefaultJavaAttributeMappingUiDefinition<JavaAttributeMapping> instance() {
+		return INSTANCE;
+	}
+	
+	
+	/**
+	 * Ensure single instance.
+	 */
+	private NullJavaAttributeMappingUiDefinition() {
+		super();
+	}
+
+	public Image getImage() {
+		return JpaMappingImageHelper.imageForAttributeMapping(getKey());
+	}
+	
+	public String getLabel() {
+		return JptUiDetailsMessages.NullAttributeMappingUiProvider_label;
+	}
+	
+	public String getLinkLabel() {
+		return null;
+	}
+	
+	public String getKey() {
+		return null;
+	}
+	
+	public String getDefaultKey() {
+		return MappingKeys.NULL_ATTRIBUTE_MAPPING_KEY;
+	}
+	
+	public JpaComposite buildAttributeMappingComposite(
+			JavaUiFactory factory,
+			PropertyValueModel<JavaAttributeMapping> subjectHolder,
+			Composite parent,
+			WidgetFactory widgetFactory) {
+		return new NullComposite(subjectHolder, parent, widgetFactory);
+	}
+	
+	
+	public static class NullComposite extends Pane<JavaAttributeMapping>
+		implements JpaComposite
+	{
+		NullComposite(
+				PropertyValueModel<JavaAttributeMapping> subjectHolder,
+		        Composite parent,
+		        WidgetFactory widgetFactory) {
+			super(subjectHolder, parent, widgetFactory);
+		}
+		
+		@Override
+		protected void initializeLayout(Composite container) {}
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/java/NullJavaTypeMappingUiDefinition.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/java/NullJavaTypeMappingUiDefinition.java
new file mode 100644
index 0000000..a266baf
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/java/NullJavaTypeMappingUiDefinition.java
@@ -0,0 +1,95 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2010 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.ui.internal.details.java;
+
+import org.eclipse.jpt.core.context.PersistentType;
+import org.eclipse.jpt.core.context.java.JavaTypeMapping;
+import org.eclipse.jpt.ui.WidgetFactory;
+import org.eclipse.jpt.ui.details.JpaComposite;
+import org.eclipse.jpt.ui.details.java.DefaultJavaTypeMappingUiDefinition;
+import org.eclipse.jpt.ui.details.java.JavaUiFactory;
+import org.eclipse.jpt.ui.internal.JpaMappingImageHelper;
+import org.eclipse.jpt.ui.internal.details.AbstractMappingUiDefinition;
+import org.eclipse.jpt.ui.internal.details.JptUiDetailsMessages;
+import org.eclipse.jpt.ui.internal.widgets.Pane;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Composite;
+
+public class NullJavaTypeMappingUiDefinition
+	extends AbstractMappingUiDefinition<PersistentType, JavaTypeMapping>
+	implements DefaultJavaTypeMappingUiDefinition<JavaTypeMapping>
+{
+	// singleton
+	private static final NullJavaTypeMappingUiDefinition INSTANCE = new NullJavaTypeMappingUiDefinition();
+	
+	
+	/**
+	 * Return the singleton.
+	 */
+	public static DefaultJavaTypeMappingUiDefinition<JavaTypeMapping> instance() {
+		return INSTANCE;
+	}
+	
+	
+	/**
+	 * Ensure single instance.
+	 */
+	private NullJavaTypeMappingUiDefinition() {
+		super();
+	}
+	
+	
+	public Image getImage() {
+		return JpaMappingImageHelper.imageForTypeMapping(null);
+	}
+	
+	public String getLabel() {
+		return JptUiDetailsMessages.NullTypeMappingUiProvider_label;
+	}
+	
+	public String getLinkLabel() {
+		return null;
+	}
+	
+	public String getKey() {
+		return null;
+	}
+	
+	public String getDefaultKey() {
+		return null;
+	}
+	
+	public JpaComposite buildTypeMappingComposite(
+			JavaUiFactory factory, 
+			PropertyValueModel<JavaTypeMapping> subjectHolder, 
+			Composite parent, 
+			WidgetFactory widgetFactory) {
+		
+		return new NullComposite(subjectHolder, parent, widgetFactory);
+	}
+	
+	public static class NullComposite 
+		extends Pane<JavaTypeMapping>
+		implements JpaComposite 
+	{
+		NullComposite(
+				PropertyValueModel<JavaTypeMapping> subjectHolder,
+				Composite parent,
+			    WidgetFactory widgetFactory) {
+			
+			super(subjectHolder, parent, widgetFactory);
+		}
+		
+		
+		@Override
+		protected void initializeLayout(Composite container) {}
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/orm/AbstractEntityMappingsDetailsPage.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/orm/AbstractEntityMappingsDetailsPage.java
new file mode 100644
index 0000000..4fa0792
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/orm/AbstractEntityMappingsDetailsPage.java
@@ -0,0 +1,268 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2010 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.ui.internal.details.orm;
+
+import java.util.Collection;
+
+import org.eclipse.jpt.core.context.AccessType;
+import org.eclipse.jpt.core.context.orm.EntityMappings;
+import org.eclipse.jpt.core.context.orm.PersistenceUnitMetadata;
+import org.eclipse.jpt.db.SchemaContainer;
+import org.eclipse.jpt.ui.WidgetFactory;
+import org.eclipse.jpt.ui.internal.JpaHelpContextIds;
+import org.eclipse.jpt.ui.internal.details.AbstractJpaDetailsPage;
+import org.eclipse.jpt.ui.internal.details.db.CatalogCombo;
+import org.eclipse.jpt.ui.internal.details.db.SchemaCombo;
+import org.eclipse.jpt.ui.internal.widgets.EnumFormComboViewer;
+import org.eclipse.jpt.utility.internal.model.value.SimplePropertyValueModel;
+import org.eclipse.jpt.utility.internal.model.value.TransformationPropertyValueModel;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * Here the layout of this pane:
+ * <pre>
+ * -----------------------------------------------------------------------------
+ * | ------------------------------------------------------------------------- |
+ * | |                                                                       | |
+ * | | XmlPackageChooser                                                     | |
+ * | |                                                                       | |
+ * | ------------------------------------------------------------------------- |
+ * |              ------------------------------------------------------------ |
+ * | Schema:      | SchemaCombo                                              | |
+ * |              ------------------------------------------------------------ |
+ * |              ------------------------------------------------------------ |
+ * | Catalog:     | CatalogCombo                                             | |
+ * |              ------------------------------------------------------------ |
+ * |              ------------------------------------------------------------ |
+ * | Access Type: |                                                        |v| |
+ * |              ------------------------------------------------------------ |
+ * |                                                                           |
+ * | ------------------------------------------------------------------------- |
+ * | |                                                                       | |
+ * | | PersistenceUnitMetadataComposite                                      | |
+ * | |                                                                       | |
+ * | ------------------------------------------------------------------------- |
+ * | ------------------------------------------------------------------------- |
+ * | |                                                                       | |
+ * | | OrmGeneratorsComposite                                                | |
+ * | |                                                                       | |
+ * | ------------------------------------------------------------------------- |
+ * | ------------------------------------------------------------------------- |
+ * | |                                                                       | |
+ * | | OrmQueriesComposite                                                   | |
+ * | |                                                                       | |
+ * | ------------------------------------------------------------------------- |
+ * -----------------------------------------------------------------------------</pre>
+ *
+ * @see EntityMappings
+ * @see AbstractEntityMappingsDetailsPage - The parent container
+ * @see CatalogCombo
+ * @see EnumFormComboViewer
+ * @see EntityMappingsGeneratorsComposite
+ * @see OrmPackageChooser
+ * @see OrmQueriesComposite
+ * @see PersistenceUnitMetadataComposite
+ * @see SchemaCombo
+ *
+ * @version 2.3
+ * @since 2.0
+ */
+public abstract class AbstractEntityMappingsDetailsPage extends AbstractJpaDetailsPage<EntityMappings>
+{
+	/**
+	 * Creates a new <code>EntityMappingsDetailsPage</code>.
+	 *
+	 * @param parent The parent container
+	 * @param widgetFactory The factory used to create various common widgets
+	 */
+	protected AbstractEntityMappingsDetailsPage(Composite parent,
+	                                 WidgetFactory widgetFactory) {
+
+		super(parent, widgetFactory);
+	}
+
+	@Override
+	protected void initializeLayout(Composite container) {
+		this.initializeEntityMappingsCollapsibleSection(container);
+		this.initializePersistenceUnitMetadataCollapsibleSection(container);
+		this.initializeGeneratorsCollapsibleSection(container);
+		this.initializeQueriesCollapsibleSection(container);
+	}
+	
+	protected void initializeEntityMappingsCollapsibleSection(Composite container) {
+		container = addCollapsibleSection(
+			container,
+			JptUiDetailsOrmMessages.EntityMappingsSection_title,
+			new SimplePropertyValueModel<Boolean>(Boolean.TRUE)
+		);
+
+		this.initializeEntityMappingsSection(container);
+	}
+	
+	protected void initializeEntityMappingsSection(Composite container) {
+		// Package widgets
+		new OrmPackageChooser(this, container);
+
+		// Schema widgets
+		addLabeledComposite(
+			container,
+			JptUiDetailsOrmMessages.EntityMappingsDetailsPage_schema,
+			addSchemaCombo(container),
+			JpaHelpContextIds.ENTITY_ORM_SCHEMA
+		);
+
+		// Catalog widgets
+		addLabeledComposite(
+			container,
+			JptUiDetailsOrmMessages.EntityMappingsDetailsPage_catalog,
+			addCatalogCombo(container),
+			JpaHelpContextIds.ENTITY_ORM_CATALOG
+		);
+
+		// Access Type widgets
+		addLabeledComposite(
+			container,
+			JptUiDetailsOrmMessages.EntityMappingsDetailsPage_access,
+			addAccessTypeCombo(container),
+			JpaHelpContextIds.ENTITY_ORM_ACCESS
+		);
+	}
+
+	protected void initializePersistenceUnitMetadataCollapsibleSection(Composite container) {
+		new PersistenceUnitMetadataComposite(
+			this,
+			buildPersistentUnitMetadataHolder(),
+			addSubPane(container, 5)
+		);
+	}
+	
+	protected EnumFormComboViewer<EntityMappings, AccessType> addAccessTypeCombo(Composite container) {
+
+		return new EnumFormComboViewer<EntityMappings, AccessType>(this, container) {
+
+			@Override
+			protected void addPropertyNames(Collection<String> propertyNames) {
+				super.addPropertyNames(propertyNames);
+				propertyNames.add(EntityMappings.DEFAULT_ACCESS_PROPERTY);
+				propertyNames.add(EntityMappings.SPECIFIED_ACCESS_PROPERTY);
+			}
+
+			@Override
+			protected AccessType[] getChoices() {
+				return AccessType.values();
+			}
+
+			@Override
+			protected AccessType getDefaultValue() {
+				return getSubject().getDefaultAccess();
+			}
+
+			@Override
+			protected String displayString(AccessType value) {
+				return value == AccessType.FIELD ?
+						JptUiDetailsOrmMessages.EntityMappingsDetailsPage_field :
+						JptUiDetailsOrmMessages.EntityMappingsDetailsPage_property;
+			}
+
+			@Override
+			protected AccessType getValue() {
+				return getSubject().getAccess();
+			}
+
+			@Override
+			protected void setValue(AccessType value) {
+				getSubject().setSpecifiedAccess(value);
+			}
+		};
+	}
+
+	protected CatalogCombo<EntityMappings> addCatalogCombo(Composite container) {
+
+		return new CatalogCombo<EntityMappings>(this, container) {
+
+			@Override
+			protected void addPropertyNames(Collection<String> propertyNames) {
+				super.addPropertyNames(propertyNames);
+				propertyNames.add(EntityMappings.DEFAULT_CATALOG_PROPERTY);
+				propertyNames.add(EntityMappings.SPECIFIED_CATALOG_PROPERTY);
+			}
+
+			@Override
+			protected String getDefaultValue() {
+				return getSubject().getDefaultCatalog();
+			}
+
+			@Override
+			protected void setValue(String value) {
+				getSubject().setSpecifiedCatalog(value);
+			}
+
+			@Override
+			protected String getValue() {
+				return getSubject().getSpecifiedCatalog();
+			}
+		};
+	}
+
+	protected PropertyValueModel<PersistenceUnitMetadata> buildPersistentUnitMetadataHolder() {
+		return new TransformationPropertyValueModel<EntityMappings, PersistenceUnitMetadata>(getSubjectHolder()) {
+			@Override
+			protected PersistenceUnitMetadata transform_(EntityMappings value) {
+				return value.getPersistenceUnitMetadata();
+			}
+		};
+	}
+
+	protected SchemaCombo<EntityMappings> addSchemaCombo(Composite container) {
+
+		return new SchemaCombo<EntityMappings>(this, container) {
+
+			@Override
+			protected void addPropertyNames(Collection<String> propertyNames) {
+				super.addPropertyNames(propertyNames);
+				propertyNames.add(EntityMappings.DEFAULT_SCHEMA_PROPERTY);
+				propertyNames.add(EntityMappings.SPECIFIED_SCHEMA_PROPERTY);
+			}
+
+			@Override
+			protected String getDefaultValue() {
+				return getSubject().getDefaultSchema();
+			}
+
+			@Override
+			protected void setValue(String value) {
+				getSubject().setSpecifiedSchema(value);
+			}
+
+			@Override
+			protected String getValue() {
+				return getSubject().getSpecifiedSchema();
+			}
+
+			@Override
+			protected SchemaContainer getDbSchemaContainer_() {
+				return this.getSubject().getDbSchemaContainer();
+			}
+
+		};
+	}
+
+	protected void initializeGeneratorsCollapsibleSection(Composite container) {
+		new EntityMappingsGeneratorsComposite(
+			this,
+			container
+		);
+	}
+
+	protected void initializeQueriesCollapsibleSection(Composite container) {
+		new OrmQueriesComposite(this, container);
+	}
+}
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/orm/AbstractOrmEntityComposite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/orm/AbstractOrmEntityComposite.java
new file mode 100644
index 0000000..bfa4fba
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/orm/AbstractOrmEntityComposite.java
@@ -0,0 +1,90 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2010 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.ui.internal.details.orm;
+
+import org.eclipse.jpt.core.context.AccessHolder;
+import org.eclipse.jpt.core.context.orm.OrmEntity;
+import org.eclipse.jpt.ui.WidgetFactory;
+import org.eclipse.jpt.ui.internal.details.AbstractEntityComposite;
+import org.eclipse.jpt.ui.internal.details.AccessTypeComposite;
+import org.eclipse.jpt.ui.internal.details.EntityNameComposite;
+import org.eclipse.jpt.ui.internal.details.IdClassComposite;
+import org.eclipse.jpt.ui.internal.details.TableComposite;
+import org.eclipse.jpt.ui.internal.details.java.BaseJavaUiFactory;
+import org.eclipse.jpt.utility.internal.model.value.PropertyAspectAdapter;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * The pane used for an ORM entity.
+ *
+ * @see OrmEntity
+ * @see BaseJavaUiFactory - The factory creating this pane
+ *
+ * @version 2.3
+ * @since 1.0
+ */
+public abstract class AbstractOrmEntityComposite extends AbstractEntityComposite<OrmEntity>
+{
+	/**
+	 * Creates a new <code>OrmEntityComposite</code>.
+	 *
+	 * @param subjectHolder The holder of the subject <code>OrmEntity</code>
+	 * @param parent The parent container
+	 * @param widgetFactory The factory used to create various common widgets
+	 */
+	protected AbstractOrmEntityComposite(
+			PropertyValueModel<? extends OrmEntity> subjectHolder,
+			Composite parent,
+			WidgetFactory widgetFactory) {
+		
+		super(subjectHolder, parent, widgetFactory);
+	}
+	
+	
+	@Override
+	protected void initializeLayout(Composite container) {
+		this.initializeEntityCollapsibleSection(container);
+		this.initializeQueriesCollapsibleSection(container);
+		this.initializeInheritanceCollapsibleSection(container);
+		this.initializeAttributeOverridesCollapsibleSection(container);
+		this.initializeGeneratorsCollapsibleSection(container);
+		this.initializeSecondaryTablesCollapsibleSection(container);
+	}
+
+	@Override
+	protected void initializeEntitySection(Composite container) {
+		new OrmJavaClassChooser(this, getSubjectHolder(), container, false);
+		new TableComposite(this, container);
+		new EntityNameComposite(this, container);
+		new AccessTypeComposite(this, buildAccessHolder(), container);
+		new IdClassComposite(this, buildIdClassReferenceHolder(), container);
+		new MetadataCompleteComposite(this, getSubjectHolder(), container);
+	}
+	
+	protected PropertyValueModel<AccessHolder> buildAccessHolder() {
+		return new PropertyAspectAdapter<OrmEntity, AccessHolder>(getSubjectHolder()){
+			@Override
+			protected AccessHolder buildValue_() {
+				return this.subject.getPersistentType();
+			}
+		};
+	}
+
+	@Override
+	protected void initializeSecondaryTablesSection(Composite container) {
+		new OrmSecondaryTablesComposite(this, container);
+	}
+
+	@Override
+	protected void initializeInheritanceSection(Composite container) {
+		new OrmInheritanceComposite(this, container);
+	}
+}
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/orm/AbstractOrmXmlResourceUiDefinition.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/orm/AbstractOrmXmlResourceUiDefinition.java
new file mode 100644
index 0000000..1ebc77a
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/orm/AbstractOrmXmlResourceUiDefinition.java
@@ -0,0 +1,174 @@
+/*******************************************************************************
+ * Copyright (c) 2009 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.ui.internal.details.orm;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+import org.eclipse.jpt.core.context.AttributeMapping;
+import org.eclipse.jpt.core.context.PersistentAttribute;
+import org.eclipse.jpt.core.context.PersistentType;
+import org.eclipse.jpt.core.context.TypeMapping;
+import org.eclipse.jpt.ui.MappingResourceUiDefinition;
+import org.eclipse.jpt.ui.WidgetFactory;
+import org.eclipse.jpt.ui.details.DefaultMappingUiDefinition;
+import org.eclipse.jpt.ui.details.JpaComposite;
+import org.eclipse.jpt.ui.details.MappingUiDefinition;
+import org.eclipse.jpt.ui.details.orm.OrmAttributeMappingUiDefinition;
+import org.eclipse.jpt.ui.details.orm.OrmTypeMappingUiDefinition;
+import org.eclipse.jpt.ui.details.orm.OrmXmlUiFactory;
+import org.eclipse.jpt.utility.internal.Tools;
+import org.eclipse.jpt.utility.internal.iterators.ArrayIterator;
+import org.eclipse.jpt.utility.internal.iterators.ArrayListIterator;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * All the state in the definition should be "static" (i.e. unchanging once it is initialized).
+ */
+public abstract class AbstractOrmXmlResourceUiDefinition
+	implements MappingResourceUiDefinition
+{
+	
+	private OrmTypeMappingUiDefinition<? extends TypeMapping>[] ormTypeMappingUiDefintions;
+
+	private OrmAttributeMappingUiDefinition<? extends AttributeMapping>[] ormAttributeMappingUiDefintions;
+	
+	private final OrmXmlUiFactory factory;
+	
+	
+	/**
+	 * zero-argument constructor
+	 */
+	protected AbstractOrmXmlResourceUiDefinition() {
+		super();
+		this.factory = buildOrmXmlUiFactory();
+	}
+	
+	
+	protected abstract OrmXmlUiFactory buildOrmXmlUiFactory();
+	
+	public OrmXmlUiFactory getFactory() {
+		return this.factory;
+	}
+	
+	
+	// ********** ORM type mappings **********
+	
+	public JpaComposite buildTypeMappingComposite(String key, PropertyValueModel<TypeMapping> mappingHolder, Composite parent, WidgetFactory widgetFactory) {
+		OrmTypeMappingUiDefinition<TypeMapping> mappingUiDefinition = 
+			(OrmTypeMappingUiDefinition<TypeMapping>) getOrmTypeMappingUiDefinition(key);
+		return mappingUiDefinition.buildTypeMappingComposite(
+			getFactory(), 
+			mappingHolder,
+			parent,
+			widgetFactory
+		);
+	}
+	
+	protected OrmTypeMappingUiDefinition<? extends TypeMapping> getOrmTypeMappingUiDefinition(String mappingKey) {
+		for (OrmTypeMappingUiDefinition<? extends TypeMapping> definition : getOrmTypeMappingUiDefinitions()) {
+			if (Tools.valuesAreEqual(definition.getKey(), mappingKey)) {
+				return definition;
+			}
+		}
+		throw new IllegalArgumentException("Illegal type mapping key: " + mappingKey); //$NON-NLS-1$
+	}
+	
+	public Iterator<MappingUiDefinition<PersistentType, ? extends TypeMapping>> 
+			typeMappingUiDefinitions() {
+		
+		return new ArrayIterator<MappingUiDefinition<PersistentType, ? extends TypeMapping>>(
+				getOrmTypeMappingUiDefinitions());
+	}
+	
+	protected synchronized OrmTypeMappingUiDefinition<? extends TypeMapping>[] getOrmTypeMappingUiDefinitions() {
+		if (this.ormTypeMappingUiDefintions == null) {
+			this.ormTypeMappingUiDefintions = this.buildOrmTypeMappingUiDefinitions();
+		}
+		return this.ormTypeMappingUiDefintions;
+	}
+	
+	
+	/**
+	 * Return an array of mapping definitions to use for types in mapping files of this type.  
+	 * The order is unimportant.
+	 */
+	protected OrmTypeMappingUiDefinition<? extends TypeMapping>[] buildOrmTypeMappingUiDefinitions() {
+		ArrayList<OrmTypeMappingUiDefinition<? extends TypeMapping>> definitions = new ArrayList<OrmTypeMappingUiDefinition<? extends TypeMapping>>();
+		this.addOrmTypeMappingUiDefinitionsTo(definitions);
+		@SuppressWarnings("unchecked")
+		OrmTypeMappingUiDefinition<? extends TypeMapping>[] definitionArray = definitions.toArray(new OrmTypeMappingUiDefinition[definitions.size()]);
+		return definitionArray;
+	}
+	
+	protected abstract void addOrmTypeMappingUiDefinitionsTo(
+			List<OrmTypeMappingUiDefinition<? extends TypeMapping>> definitions);
+	
+	public DefaultMappingUiDefinition<PersistentType, ? extends TypeMapping> getDefaultTypeMappingUiDefinition() {
+		//there is no way to choose an type in the orm.xml that doesn't have a specified mapping so we can return null here
+		return null;
+	}
+	
+	// ********** ORM attribute mappings **********
+	
+	public JpaComposite buildAttributeMappingComposite(String key, PropertyValueModel<AttributeMapping> mappingHolder, Composite parent, WidgetFactory widgetFactory) {
+
+		OrmAttributeMappingUiDefinition<AttributeMapping> mappingUiDefinition = 
+			(OrmAttributeMappingUiDefinition<AttributeMapping>) getOrmAttributeMappingUiDefinition(key);
+		return mappingUiDefinition.buildAttributeMappingComposite(
+			getFactory(), 
+			mappingHolder,
+			parent,
+			widgetFactory
+		);
+	}
+	
+	protected OrmAttributeMappingUiDefinition<? extends AttributeMapping> getOrmAttributeMappingUiDefinition(String mappingKey) {
+		for (OrmAttributeMappingUiDefinition<? extends AttributeMapping> definition : getOrmAttributeMappingUiDefinitions()) {
+			if (Tools.valuesAreEqual(definition.getKey(), mappingKey)) {
+				return definition;
+			}
+		}
+		return UnsupportedOrmMappingUiDefinition.instance();
+	}
+	
+	public ListIterator<MappingUiDefinition<PersistentAttribute, ? extends AttributeMapping>> attributeMappingUiDefinitions() {
+		return new ArrayListIterator<MappingUiDefinition<PersistentAttribute, ? extends AttributeMapping>>(
+				getOrmAttributeMappingUiDefinitions());
+	}
+	
+	protected synchronized OrmAttributeMappingUiDefinition<? extends AttributeMapping>[] getOrmAttributeMappingUiDefinitions() {
+		if (this.ormAttributeMappingUiDefintions == null) {
+			this.ormAttributeMappingUiDefintions = this.buildOrmAttributeMappingUiDefinitions();
+		}
+		return this.ormAttributeMappingUiDefintions;
+	}
+	
+	/**
+	 * Return an array of mapping definitions to use for attributes in mapping files of this type.  
+	 * The order is unimportant.
+	 */
+	protected OrmAttributeMappingUiDefinition<? extends AttributeMapping>[] buildOrmAttributeMappingUiDefinitions() {
+		ArrayList<OrmAttributeMappingUiDefinition<? extends AttributeMapping>> definitions = new ArrayList<OrmAttributeMappingUiDefinition<? extends AttributeMapping>>();
+		this.addOrmAttributeMappingUiDefinitionsTo(definitions);
+		@SuppressWarnings("unchecked")
+		OrmAttributeMappingUiDefinition<? extends AttributeMapping>[] definitionArray = definitions.toArray(new OrmAttributeMappingUiDefinition[definitions.size()]);
+		return definitionArray;
+	}
+	
+	protected abstract void addOrmAttributeMappingUiDefinitionsTo(
+			List<OrmAttributeMappingUiDefinition<? extends AttributeMapping>> definitions);
+	
+	public DefaultMappingUiDefinition<PersistentAttribute, ? extends AttributeMapping> getDefaultAttributeMappingUiDefinition(String key) {
+		return null;
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/orm/AddGeneratorDialog.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/orm/AddGeneratorDialog.java
new file mode 100644
index 0000000..44c56d2
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/orm/AddGeneratorDialog.java
@@ -0,0 +1,187 @@
+/*******************************************************************************
+ * Copyright (c) 2009 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.ui.internal.details.orm;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.jpt.core.context.Generator;
+import org.eclipse.jpt.ui.internal.widgets.DialogPane;
+import org.eclipse.jpt.ui.internal.widgets.ValidatingDialog;
+import org.eclipse.jpt.utility.internal.StringConverter;
+import org.eclipse.jpt.utility.internal.model.value.PropertyAspectAdapter;
+import org.eclipse.jpt.utility.internal.model.value.StaticListValueModel;
+import org.eclipse.jpt.utility.model.value.ListValueModel;
+import org.eclipse.jpt.utility.model.value.WritablePropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Text;
+
+/**
+ * Clients can use this dialog to prompt the user for SecondaryTable settings.
+ * Use the following once the dialog is closed:
+ *     @see #getSelectedTable()
+ *     @see #getSelectedCatalog()
+ *     @see #getSelectedSchema()
+ * @version 2.1
+ * @since 2.1
+ */
+public class AddGeneratorDialog extends ValidatingDialog<AddGeneratorStateObject> {
+
+	
+	// ********** constructors **********
+
+	/**
+	 * Use this constructor to edit an existing conversion value
+	 */
+	public AddGeneratorDialog(Shell parent) {
+		super(parent);
+	}
+
+	@Override
+	protected AddGeneratorStateObject buildStateObject() {
+		return new AddGeneratorStateObject();
+	}
+
+	// ********** open **********
+
+	@Override
+	protected void configureShell(Shell shell) {
+		super.configureShell(shell);
+		shell.setText(this.getTitle());
+	}
+
+	@Override
+	protected String getTitle() {
+		return JptUiDetailsOrmMessages.AddGeneratorDialog_title;
+	}
+
+	@Override
+	protected String getDescriptionTitle() {
+		return JptUiDetailsOrmMessages.AddGeneratorDialog_descriptionTitle;
+	}
+	
+	@Override
+	protected String getDescription() {
+		return JptUiDetailsOrmMessages.AddGeneratorDialog_description;
+	}
+	
+	@Override
+	protected DialogPane<AddGeneratorStateObject> buildLayout(Composite container) {
+		return new GeneratorDialogPane(container);
+	}
+	
+	@Override
+	public void create() {
+		super.create();
+
+		GeneratorDialogPane pane = (GeneratorDialogPane) getPane();
+		pane.selectAll();
+
+		getButton(OK).setEnabled(false);
+	}
+
+
+	// ********** public API **********
+
+	/**
+	 * Return the data value set in the text widget.
+	 */
+	public String getName() {
+		return getSubject().getName();
+	}
+
+	/**
+	 * Return the object value set in the text widget.
+	 */
+	public String getGeneratorType() {
+		return getSubject().getGeneratorType();
+	}
+	
+	private class GeneratorDialogPane extends DialogPane<AddGeneratorStateObject> {
+
+		private Text nameText;
+
+		GeneratorDialogPane(Composite parent) {
+			super(AddGeneratorDialog.this.getSubjectHolder(), parent);
+		}
+
+		@Override
+		protected void initializeLayout(Composite container) {
+			this.nameText = addLabeledText(
+				container,
+				JptUiDetailsOrmMessages.AddGeneratorDialog_name,
+				buildNameHolder()
+			);
+			
+			addLabeledCombo(
+				container, 
+				JptUiDetailsOrmMessages.AddGeneratorDialog_generatorType, 
+				buildGeneratorTypeListHolder(), 
+				buildGeneratorTypeHolder(), 
+				buildStringConverter(),
+				null);
+		}
+
+		protected ListValueModel<String> buildGeneratorTypeListHolder() {
+			List<String> generatorTypes = new ArrayList<String>();
+			generatorTypes.add(Generator.TABLE_GENERATOR);
+			generatorTypes.add(Generator.SEQUENCE_GENERATOR);
+			
+			return new StaticListValueModel<String>(generatorTypes);
+		}
+		
+		private StringConverter<String> buildStringConverter() {
+			return new StringConverter<String>() {
+				public String convertToString(String value) {
+					if (value == Generator.TABLE_GENERATOR) {
+						return JptUiDetailsOrmMessages.AddGeneratorDialog_tableGenerator;
+					}
+					if (value == Generator.SEQUENCE_GENERATOR) {
+						return JptUiDetailsOrmMessages.AddGeneratorDialog_sequenceGenerator;
+					}
+					return value;
+				}
+			};
+		}
+		
+		private WritablePropertyValueModel<String> buildNameHolder() {
+			return new PropertyAspectAdapter<AddGeneratorStateObject, String>(getSubjectHolder(), AddGeneratorStateObject.NAME_PROPERTY) {
+				@Override
+				protected String buildValue_() {
+					return this.subject.getName();
+				}
+
+				@Override
+				protected void setValue_(String value) {
+					this.subject.setName(value);
+				}
+			};
+		}
+
+		private WritablePropertyValueModel<String> buildGeneratorTypeHolder() {
+			return new PropertyAspectAdapter<AddGeneratorStateObject, String>(getSubjectHolder(), AddGeneratorStateObject.GENERATOR_TYPE_PROPERTY) {
+				@Override
+				protected String buildValue_() {
+					return this.subject.getGeneratorType();
+				}
+
+				@Override
+				protected void setValue_(String value) {
+					this.subject.setGeneratorType(value);
+				}
+			};
+		}
+
+		void selectAll() {
+			this.nameText.selectAll();
+		}
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/orm/AddGeneratorStateObject.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/orm/AddGeneratorStateObject.java
new file mode 100644
index 0000000..cd10f5d
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/orm/AddGeneratorStateObject.java
@@ -0,0 +1,123 @@
+/*******************************************************************************
+ * Copyright (c) 2009 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.ui.internal.details.orm;
+
+import java.util.List;
+import org.eclipse.jpt.utility.internal.StringTools;
+import org.eclipse.jpt.utility.internal.node.AbstractNode;
+import org.eclipse.jpt.utility.internal.node.Node;
+import org.eclipse.jpt.utility.internal.node.Problem;
+
+/**
+ * This is the state object used by the <code>AddGeneratorDialog</code>, which stores
+ * the current name and validates it when it is modified.
+ *
+ * @see AddGeneratorDialog
+ *
+ * @version 2.1
+ * @since 2.1
+ */
+final class AddGeneratorStateObject extends AbstractNode
+{
+	/**
+	 * The initial name or <code>null</code>
+	 */
+	private String name;
+
+	/**
+	 * The initial generatorType or <code>null</code>
+	 */
+	private String generatorType;
+
+	/**
+	 * The <code>Validator</code> used to validate this state object.
+	 */
+	private Validator validator;
+
+	/**
+	 * Notifies a change in the data value property.
+	 */
+	static final String NAME_PROPERTY = "nameProperty"; //$NON-NLS-1$
+	
+	/**
+	 * Notifies a change in the generator type property.
+	 */
+	static final String GENERATOR_TYPE_PROPERTY = "generatorTypeProperty"; //$NON-NLS-1$
+
+	/**
+	 * Creates a new <code>NewNameStateObject</code>.
+	 *
+	 * @param name The initial input or <code>null</code> if no initial value can
+	 * be specified
+	 * @param names The collection of names that can't be used or an empty
+	 * collection if none are available
+	 */
+	AddGeneratorStateObject() {
+		super(null);
+	}
+
+	private void addNameProblemsTo(List<Problem> currentProblems) {
+		if (StringTools.stringIsEmpty(this.name)) {
+			currentProblems.add(buildProblem(JptUiDetailsOrmMessages.GeneratorStateObject_nameMustBeSpecified));
+		}
+	}
+
+	private void addGeneratorTypeProblemsTo(List<Problem> currentProblems) {
+		if (StringTools.stringIsEmpty(this.generatorType)) {
+			currentProblems.add(buildProblem(JptUiDetailsOrmMessages.GeneratorStateObject_typeMustBeSpecified));
+		}
+	}
+
+	@Override
+	protected void addProblemsTo(List<Problem> currentProblems) {
+		super.addProblemsTo(currentProblems);
+		addNameProblemsTo(currentProblems);
+		addGeneratorTypeProblemsTo(currentProblems);
+	}
+
+	@Override
+	protected void checkParent(Node parentNode) {
+		//no parent
+	}
+
+	public String displayString() {
+		return null;
+	}
+
+	String getName() {
+		return this.name;
+	}
+
+	String getGeneratorType() {
+		return this.generatorType;
+	}
+
+	public void setName(String newName) {
+		String oldName = this.name;
+		this.name = newName;
+		firePropertyChanged(NAME_PROPERTY, oldName, newName);
+	}
+
+	public void setGeneratorType(String newGeneratorType) {
+		String old = this.generatorType;
+		this.generatorType = newGeneratorType;
+		firePropertyChanged(GENERATOR_TYPE_PROPERTY, old, newGeneratorType);
+	}
+
+	@Override
+	public void setValidator(Validator validator) {
+		this.validator = validator;
+	}
+
+	@Override
+	public Validator getValidator() {
+		return this.validator;
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/orm/BaseOrmXmlUiFactory.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/orm/BaseOrmXmlUiFactory.java
new file mode 100644
index 0000000..a8525b2
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/orm/BaseOrmXmlUiFactory.java
@@ -0,0 +1,134 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 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.ui.internal.details.orm;
+
+import org.eclipse.jpt.core.context.orm.OrmBasicMapping;
+import org.eclipse.jpt.core.context.orm.OrmEmbeddable;
+import org.eclipse.jpt.core.context.orm.OrmEmbeddedIdMapping;
+import org.eclipse.jpt.core.context.orm.OrmEmbeddedMapping;
+import org.eclipse.jpt.core.context.orm.OrmEntity;
+import org.eclipse.jpt.core.context.orm.OrmIdMapping;
+import org.eclipse.jpt.core.context.orm.OrmManyToManyMapping;
+import org.eclipse.jpt.core.context.orm.OrmManyToOneMapping;
+import org.eclipse.jpt.core.context.orm.OrmMappedSuperclass;
+import org.eclipse.jpt.core.context.orm.OrmOneToManyMapping;
+import org.eclipse.jpt.core.context.orm.OrmOneToOneMapping;
+import org.eclipse.jpt.core.context.orm.OrmTransientMapping;
+import org.eclipse.jpt.core.context.orm.OrmVersionMapping;
+import org.eclipse.jpt.ui.WidgetFactory;
+import org.eclipse.jpt.ui.details.JpaComposite;
+import org.eclipse.jpt.ui.details.orm.OrmXmlUiFactory;
+import org.eclipse.jpt.ui.internal.details.TransientMappingComposite;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * The default implementation of the Orm Xml UI factory required to show the information
+ * related to a JPA mapping (type or attribute).
+ */
+public abstract class BaseOrmXmlUiFactory implements OrmXmlUiFactory
+{
+	
+	// **************** orm type mapping composites ****************************
+	
+	public JpaComposite createOrmMappedSuperclassComposite(
+			PropertyValueModel<OrmMappedSuperclass> subjectHolder,
+			Composite parent,
+			WidgetFactory widgetFactory) {
+		return new OrmMappedSuperclassComposite(subjectHolder, parent, widgetFactory);
+	}
+	
+	public JpaComposite createOrmEntityComposite(
+			PropertyValueModel<OrmEntity> subjectHolder,
+			Composite parent,
+			WidgetFactory widgetFactory) {
+		return new OrmEntityComposite(subjectHolder, parent, widgetFactory);
+	}
+	
+	public JpaComposite createOrmEmbeddableComposite(
+			PropertyValueModel<OrmEmbeddable> subjectHolder,
+			Composite parent,
+			WidgetFactory widgetFactory) {
+		return new OrmEmbeddableComposite(subjectHolder, parent, widgetFactory);
+	}
+	
+	
+	// **************** orm attribute mapping composites ***********************
+	
+	public JpaComposite createOrmIdMappingComposite(
+			PropertyValueModel<OrmIdMapping> subjectHolder,
+			Composite parent,
+			WidgetFactory widgetFactory) {
+		return new OrmIdMappingComposite(subjectHolder, parent, widgetFactory);
+	}
+	
+	public JpaComposite createOrmEmbeddedIdMappingComposite(
+			PropertyValueModel<OrmEmbeddedIdMapping> subjectHolder,
+			Composite parent,
+			WidgetFactory widgetFactory) {
+		return new OrmEmbeddedIdMappingComposite(subjectHolder, parent, widgetFactory);
+	}
+	
+	public JpaComposite createOrmBasicMappingComposite(
+			PropertyValueModel<OrmBasicMapping> subjectHolder,
+			Composite parent,
+			WidgetFactory widgetFactory) {
+		return new OrmBasicMappingComposite(subjectHolder, parent, widgetFactory);
+	}
+	
+	public JpaComposite createOrmVersionMappingComposite(
+			PropertyValueModel<OrmVersionMapping> subjectHolder,
+			Composite parent,
+			WidgetFactory widgetFactory) {
+		return new OrmVersionMappingComposite(subjectHolder, parent, widgetFactory);
+	}
+	
+	public JpaComposite createOrmManyToOneMappingComposite(
+			PropertyValueModel<OrmManyToOneMapping> subjectHolder,
+			Composite parent,
+			WidgetFactory widgetFactory) {
+		return new OrmManyToOneMappingComposite(subjectHolder, parent, widgetFactory);
+	}
+	
+	public JpaComposite createOrmOneToManyMappingComposite(
+			PropertyValueModel<OrmOneToManyMapping> subjectHolder,
+			Composite parent,
+			WidgetFactory widgetFactory) {
+		return new OrmOneToManyMappingComposite(subjectHolder, parent, widgetFactory);
+	}
+	
+	public JpaComposite createOrmOneToOneMappingComposite(
+			PropertyValueModel<OrmOneToOneMapping> subjectHolder,
+			Composite parent,
+			WidgetFactory widgetFactory) {
+		return new OrmOneToOneMappingComposite(subjectHolder, parent, widgetFactory);
+	}
+	
+	public JpaComposite createOrmManyToManyMappingComposite(
+			PropertyValueModel<OrmManyToManyMapping> subjectHolder,
+			Composite parent,
+			WidgetFactory widgetFactory) {
+		return new OrmManyToManyMappingComposite(subjectHolder, parent, widgetFactory);
+	}
+	
+	public JpaComposite createOrmEmbeddedMappingComposite(
+			PropertyValueModel<OrmEmbeddedMapping> subjectHolder,
+			Composite parent,
+			WidgetFactory widgetFactory) {
+		return new OrmEmbeddedMappingComposite(subjectHolder, parent, widgetFactory);
+	}
+	
+	public JpaComposite createOrmTransientMappingComposite(
+			PropertyValueModel<OrmTransientMapping> subjectHolder,
+			Composite parent,
+			WidgetFactory widgetFactory) {
+		return new TransientMappingComposite(subjectHolder, parent, widgetFactory);
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/orm/EntityMappingsDetailsPage.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/orm/EntityMappingsDetailsPage.java
new file mode 100644
index 0000000..1181b31
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/orm/EntityMappingsDetailsPage.java
@@ -0,0 +1,82 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2009 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.ui.internal.details.orm;
+
+import org.eclipse.jpt.core.context.orm.EntityMappings;
+import org.eclipse.jpt.ui.WidgetFactory;
+import org.eclipse.jpt.ui.internal.details.db.CatalogCombo;
+import org.eclipse.jpt.ui.internal.details.db.SchemaCombo;
+import org.eclipse.jpt.ui.internal.widgets.EnumFormComboViewer;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * Here the layout of this pane:
+ * <pre>
+ * -----------------------------------------------------------------------------
+ * | ------------------------------------------------------------------------- |
+ * | |                                                                       | |
+ * | | XmlPackageChooser                                                     | |
+ * | |                                                                       | |
+ * | ------------------------------------------------------------------------- |
+ * |              ------------------------------------------------------------ |
+ * | Schema:      | SchemaCombo                                              | |
+ * |              ------------------------------------------------------------ |
+ * |              ------------------------------------------------------------ |
+ * | Catalog:     | CatalogCombo                                             | |
+ * |              ------------------------------------------------------------ |
+ * |              ------------------------------------------------------------ |
+ * | Access Type: |                                                        |v| |
+ * |              ------------------------------------------------------------ |
+ * |                                                                           |
+ * | ------------------------------------------------------------------------- |
+ * | |                                                                       | |
+ * | | PersistenceUnitMetadataComposite                                      | |
+ * | |                                                                       | |
+ * | ------------------------------------------------------------------------- |
+ * | ------------------------------------------------------------------------- |
+ * | |                                                                       | |
+ * | | OrmGeneratorsComposite                                                | |
+ * | |                                                                       | |
+ * | ------------------------------------------------------------------------- |
+ * | ------------------------------------------------------------------------- |
+ * | |                                                                       | |
+ * | | OrmQueriesComposite                                                   | |
+ * | |                                                                       | |
+ * | ------------------------------------------------------------------------- |
+ * -----------------------------------------------------------------------------</pre>
+ *
+ * @see EntityMappings
+ * @see EntityMappingsDetailsPage - The parent container
+ * @see CatalogCombo
+ * @see EnumFormComboViewer
+ * @see EntityMappingsGeneratorsComposite
+ * @see OrmPackageChooser
+ * @see OrmQueriesComposite
+ * @see PersistenceUnitMetadataComposite
+ * @see SchemaCombo
+ *
+ * @version 2.2
+ * @since 2.0
+ */
+public class EntityMappingsDetailsPage extends AbstractEntityMappingsDetailsPage
+{
+	/**
+	 * Creates a new <code>EntityMappingsDetailsPage</code>.
+	 *
+	 * @param parent The parent container
+	 * @param widgetFactory The factory used to create various common widgets
+	 */
+	public EntityMappingsDetailsPage(Composite parent,
+	                                 WidgetFactory widgetFactory) {
+
+		super(parent, widgetFactory);
+	}
+
+}
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/orm/EntityMappingsDetailsProvider.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/orm/EntityMappingsDetailsProvider.java
new file mode 100644
index 0000000..6e9855f
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/orm/EntityMappingsDetailsProvider.java
@@ -0,0 +1,60 @@
+/*******************************************************************************
+ * Copyright (c) 2009 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.ui.internal.details.orm;
+
+import org.eclipse.jpt.core.JpaResourceType;
+import org.eclipse.jpt.core.JptCorePlugin;
+import org.eclipse.jpt.core.context.orm.EntityMappings;
+import org.eclipse.jpt.ui.WidgetFactory;
+import org.eclipse.jpt.ui.details.JpaDetailsPage;
+import org.eclipse.jpt.ui.details.JpaDetailsProvider;
+import org.eclipse.jpt.ui.internal.details.AbstractEntityMappingsDetailsProvider;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * This provider is responsible for creating the {@link JpaDetailsPage}
+ * when the information comes from the XML file (either from the persistence
+ * configuration or from the Mappings Descriptor).
+ */
+public class EntityMappingsDetailsProvider
+	extends AbstractEntityMappingsDetailsProvider
+{
+	// singleton
+	private static final JpaDetailsProvider INSTANCE = new EntityMappingsDetailsProvider();
+	
+	
+	/**
+	 * Return the singleton
+	 */
+	public static JpaDetailsProvider instance() {
+		return INSTANCE;
+	}
+	
+	
+	/**
+	 * Enforce singleton usage
+	 */
+	private EntityMappingsDetailsProvider() {
+		super();
+	}
+	
+	
+	@Override
+	protected boolean providesDetails(JpaResourceType resourceType) {
+		return resourceType.equals(JptCorePlugin.ORM_XML_1_0_RESOURCE_TYPE);
+	}
+	
+	public JpaDetailsPage<EntityMappings> buildDetailsPage(
+			Composite parent,
+			WidgetFactory widgetFactory) {
+		
+		return new EntityMappingsDetailsPage(parent, widgetFactory);
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/orm/EntityMappingsGeneratorsComposite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/orm/EntityMappingsGeneratorsComposite.java
new file mode 100644
index 0000000..63a7d55
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/orm/EntityMappingsGeneratorsComposite.java
@@ -0,0 +1,371 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2010 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.ui.internal.details.orm;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.jface.window.Window;
+import org.eclipse.jpt.core.context.Generator;
+import org.eclipse.jpt.core.context.SequenceGenerator;
+import org.eclipse.jpt.core.context.TableGenerator;
+import org.eclipse.jpt.core.context.orm.EntityMappings;
+import org.eclipse.jpt.core.context.orm.OrmGenerator;
+import org.eclipse.jpt.core.context.orm.OrmSequenceGenerator;
+import org.eclipse.jpt.core.context.orm.OrmTableGenerator;
+import org.eclipse.jpt.ui.internal.details.GeneratorComposite;
+import org.eclipse.jpt.ui.internal.details.SequenceGeneratorComposite;
+import org.eclipse.jpt.ui.internal.details.TableGeneratorComposite;
+import org.eclipse.jpt.ui.internal.details.GeneratorComposite.GeneratorBuilder;
+import org.eclipse.jpt.ui.internal.util.ControlSwitcher;
+import org.eclipse.jpt.ui.internal.util.PaneEnabler;
+import org.eclipse.jpt.ui.internal.widgets.AddRemoveListPane;
+import org.eclipse.jpt.ui.internal.widgets.Pane;
+import org.eclipse.jpt.ui.internal.widgets.AddRemovePane.Adapter;
+import org.eclipse.jpt.utility.internal.CollectionTools;
+import org.eclipse.jpt.utility.internal.Transformer;
+import org.eclipse.jpt.utility.internal.iterables.ListIterable;
+import org.eclipse.jpt.utility.internal.model.value.CompositeListValueModel;
+import org.eclipse.jpt.utility.internal.model.value.ItemPropertyListValueModelAdapter;
+import org.eclipse.jpt.utility.internal.model.value.ListAspectAdapter;
+import org.eclipse.jpt.utility.internal.model.value.SimplePropertyValueModel;
+import org.eclipse.jpt.utility.internal.model.value.TransformationPropertyValueModel;
+import org.eclipse.jpt.utility.internal.model.value.swing.ObjectListSelectionModel;
+import org.eclipse.jpt.utility.model.value.ListValueModel;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.jpt.utility.model.value.WritablePropertyValueModel;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.ui.part.PageBook;
+
+/**
+ * This pane shows the list of named queries and named native queries.
+ * <p>
+ * Here the layout of this pane:
+ * <pre>
+ * -----------------------------------------------------------------------------
+ * | ------------------------------------------------------------------------- |
+ * | |                                                                       | |
+ * | | AddRemoveListPane                                                     | |
+ * | |                                                                       | |
+ * | ------------------------------------------------------------------------- |
+ * | ------------------------------------------------------------------------- |
+ * | |                                                                       | |
+ * | | OrmSequenceGeneratorComposite or OrmTableGeneratorComposite           | |
+ * | |                                                                       | |
+ * | ------------------------------------------------------------------------- |
+ * -----------------------------------------------------------------------------</pre>
+ *
+ * @see EntityMappings
+ * @see OrmGenerator
+ * @see OrmSequenceGenerator
+ * @see OrmTableGenerator
+ * @see EntityComposite - The parent container
+ * @see OrmSequenceGeneratorComposite
+ * @see OrmTableGeneratorComposite
+ *
+ * @version 2.2
+ * @since 2.0
+ */
+public class EntityMappingsGeneratorsComposite extends Pane<EntityMappings>
+{
+	private WritablePropertyValueModel<OrmGenerator> generatorHolder;
+	private GeneratorComposite<SequenceGenerator> sequenceGeneratorPane;
+	private TableGeneratorComposite tableGeneratorPane;
+	private AddRemoveListPane<EntityMappings> listPane;
+
+	/**
+	 * Creates a new <code>EntityMappingsGeneratorsComposite</code>.
+	 *
+	 * @param parentPane The parent container of this one
+	 * @param parent The parent container
+	 */
+	public EntityMappingsGeneratorsComposite(
+						Pane<? extends EntityMappings> parentPane,
+						Composite parent) {
+
+		super(parentPane, parent, false);
+	}
+	
+	private void addGenerator(ObjectListSelectionModel listSelectionModel) {
+		addGeneratorFromDialog(listSelectionModel, buildAddGeneratorDialog());
+	}
+	
+	protected AddGeneratorDialog buildAddGeneratorDialog() {
+		return new AddGeneratorDialog(getShell());
+	}
+
+	protected void addGeneratorFromDialog(ObjectListSelectionModel listSelectionModel, AddGeneratorDialog dialog) {
+		if (dialog.open() != Window.OK) {
+			return;
+		}
+		String generatorType = dialog.getGeneratorType();
+		OrmGenerator generator;
+		if (generatorType == Generator.TABLE_GENERATOR) {
+			generator = this.getSubject().addTableGenerator(getSubject().getTableGeneratorsSize());
+		}
+		else if (generatorType == Generator.SEQUENCE_GENERATOR) {
+			generator = this.getSubject().addSequenceGenerator(getSubject().getSequenceGeneratorsSize());
+		}
+		else {
+			throw new IllegalArgumentException();
+		}
+		generator.setName(dialog.getName());
+		this.generatorHolder.setValue(generator);//so that it gets selected in the List for the user to edit
+		listSelectionModel.setSelectedValue(generator);
+	}
+
+	private ListValueModel<OrmGenerator> buildDisplayableGeneratorListHolder() {
+		return new ItemPropertyListValueModelAdapter<OrmGenerator>(
+			buildGeneratorsListHolder(),
+			Generator.NAME_PROPERTY
+		);
+	}
+
+	private Adapter buildGeneratorAdapter() {
+
+		return new AddRemoveListPane.AbstractAdapter() {
+
+			public void addNewItem(ObjectListSelectionModel listSelectionModel) {
+				addGenerator(listSelectionModel);
+			}
+
+
+			public void removeSelectedItems(ObjectListSelectionModel listSelectionModel) {
+				for (Object item : listSelectionModel.selectedValues()) {
+					if (item instanceof OrmSequenceGenerator) {
+						getSubject().removeSequenceGenerator((OrmSequenceGenerator) item);
+					}
+					else {
+						getSubject().removeTableGenerator((OrmTableGenerator) item);
+					}
+				}
+			}
+		};
+	}
+
+	private WritablePropertyValueModel<OrmGenerator> buildGeneratorHolder() {
+		return new SimplePropertyValueModel<OrmGenerator>();
+	}
+
+	private ILabelProvider buildGeneratorLabelProvider() {
+		return new LabelProvider() {
+			@Override
+			public String getText(Object element) {
+				OrmGenerator generator = (OrmGenerator) element;
+				String name = generator.getName();
+
+				if (name == null) {
+					int index = -1;
+
+					if (generator instanceof OrmSequenceGenerator) {
+						index = CollectionTools.indexOf(getSubject().getSequenceGenerators(), generator);
+					}
+					else {
+						index = CollectionTools.indexOf(getSubject().getTableGenerators(), generator);
+					}
+
+					name = NLS.bind(JptUiDetailsOrmMessages.OrmGeneratorsComposite_displayString, Integer.valueOf(index));
+				}
+
+				return name;
+			}
+		};
+	}
+
+	private ListValueModel<OrmGenerator> buildGeneratorsListHolder() {
+		List<ListValueModel<? extends OrmGenerator>> list = new ArrayList<ListValueModel<? extends OrmGenerator>>();
+		list.add(buildSequenceGeneratorListHolder());
+		list.add(buildTableGeneratorListHolder());
+		return new CompositeListValueModel<ListValueModel<? extends OrmGenerator>, OrmGenerator>(list);
+	}
+
+	private PropertyValueModel<Boolean> buildPaneEnablerHolder() {
+		return new TransformationPropertyValueModel<EntityMappings, Boolean>(getSubjectHolder()) {
+			@Override
+			protected Boolean transform(EntityMappings value) {
+				return Boolean.valueOf(value != null);
+			}
+		};
+	}
+
+	private Transformer<OrmGenerator, Control> buildPaneTransformer() {
+		return new Transformer<OrmGenerator, Control>() {
+			public Control transform(OrmGenerator generator) {
+
+				if (generator == null) {
+					return null;
+				}
+
+				if (generator instanceof OrmSequenceGenerator) {
+					return EntityMappingsGeneratorsComposite.this.sequenceGeneratorPane.getControl();
+				}
+
+				return EntityMappingsGeneratorsComposite.this.tableGeneratorPane.getControl();
+			}
+		};
+	}
+
+	private PropertyValueModel<SequenceGenerator> buildSequenceGeneratorHolder() {
+		return new TransformationPropertyValueModel<OrmGenerator, SequenceGenerator>(this.generatorHolder) {
+			@Override
+			protected SequenceGenerator transform_(OrmGenerator value) {
+				return (value instanceof SequenceGenerator) ? (SequenceGenerator) value : null;
+			}
+		};
+	}
+
+	private ListValueModel<OrmSequenceGenerator> buildSequenceGeneratorListHolder() {
+		return new ListAspectAdapter<EntityMappings, OrmSequenceGenerator>(
+			getSubjectHolder(),
+			EntityMappings.SEQUENCE_GENERATORS_LIST)
+		{
+			@Override
+			protected ListIterable<OrmSequenceGenerator> getListIterable() {
+				return this.subject.getSequenceGenerators();
+			}
+			@Override
+			protected int size_() {
+				return this.subject.getSequenceGeneratorsSize();
+			}
+		};
+	}
+
+	private PropertyValueModel<TableGenerator> buildTableGeneratorHolder() {
+		return new TransformationPropertyValueModel<OrmGenerator, TableGenerator>(this.generatorHolder) {
+			@Override
+			protected TableGenerator transform_(OrmGenerator value) {
+				return (value instanceof TableGenerator) ? (TableGenerator) value : null;
+			}
+		};
+	}
+
+	private ListValueModel<OrmTableGenerator> buildTableGeneratorListHolder() {
+		return new ListAspectAdapter<EntityMappings, OrmTableGenerator>(
+			getSubjectHolder(),
+			EntityMappings.TABLE_GENERATORS_LIST)
+		{
+			@Override
+			protected ListIterable<OrmTableGenerator> getListIterable() {
+				return this.subject.getTableGenerators();
+			}
+			@Override
+			protected int size_() {
+				return this.subject.getTableGeneratorsSize();
+			}
+		};
+	}
+
+
+	@Override
+	protected void initialize() {
+		super.initialize();
+		this.generatorHolder = buildGeneratorHolder();
+	}
+
+	@Override
+	protected void initializeLayout(Composite container) {
+
+		container = addCollapsibleSection(
+			container,
+			JptUiDetailsOrmMessages.OrmGeneratorsComposite_groupBox
+		);
+
+		// List pane
+		this.listPane = addListPane(container);
+		this.installPaneEnabler();
+
+		// Property pane
+		PropertyValueModel<SequenceGenerator> sequenceGeneratorHolder =
+			this.buildSequenceGeneratorHolder();
+		PropertyValueModel<TableGenerator> tableGeneratorHolder =
+			this.buildTableGeneratorHolder();
+
+		PageBook pageBook = new PageBook(container, SWT.NULL);
+		pageBook.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+		// Sequence Generator property pane
+		this.sequenceGeneratorPane = this.buildSequenceGeneratorComposite(
+			pageBook,
+			sequenceGeneratorHolder,
+			this.buildSequenceGeneratorBuilder()
+		);
+
+		// Table Generator property pane
+		this.tableGeneratorPane = new TableGeneratorComposite(
+			this,
+			tableGeneratorHolder,
+			pageBook,
+			this.buildTableGeneratorBuilder()
+		);
+
+		this.addAlignRight(this.sequenceGeneratorPane);
+		this.addAlignRight(this.tableGeneratorPane);
+		this.installPaneSwitcher(pageBook);
+	}
+
+	protected GeneratorComposite<SequenceGenerator> buildSequenceGeneratorComposite(
+			Composite parent,
+			PropertyValueModel<SequenceGenerator> sequenceGeneratorHolder,
+			GeneratorBuilder<SequenceGenerator> generatorBuilder) {
+
+		return new SequenceGeneratorComposite(
+			this,
+			sequenceGeneratorHolder,
+			parent,
+			generatorBuilder
+		);
+	}
+
+	private AddRemoveListPane<EntityMappings> addListPane(Composite container) {
+
+		return new AddRemoveListPane<EntityMappings>(
+			this,
+			container,
+			this.buildGeneratorAdapter(),
+			this.buildDisplayableGeneratorListHolder(),
+			this.generatorHolder,
+			this.buildGeneratorLabelProvider()
+		);
+	}
+
+	private void installPaneEnabler() {
+		new PaneEnabler(
+			this.buildPaneEnablerHolder(),
+			this.listPane
+		);
+	}
+
+	private void installPaneSwitcher(PageBook pageBook) {
+		new ControlSwitcher(this.generatorHolder, this.buildPaneTransformer(), pageBook);
+	}	
+
+	private GeneratorBuilder<SequenceGenerator> buildSequenceGeneratorBuilder() {
+		return new GeneratorBuilder<SequenceGenerator>() {
+			public SequenceGenerator addGenerator() {
+				throw new UnsupportedOperationException("The sequence generator will never be null so we do not need to implement this"); //$NON-NLS-1$
+			}
+		};
+	}
+
+	private GeneratorBuilder<TableGenerator> buildTableGeneratorBuilder() {
+		return new GeneratorBuilder<TableGenerator>() {
+			public TableGenerator addGenerator() {
+				throw new UnsupportedOperationException("The table generator will never be null so we do not need to implement this"); //$NON-NLS-1$
+			}
+		};
+	}
+
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/orm/GenericOrmXmlUiFactory.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/orm/GenericOrmXmlUiFactory.java
new file mode 100644
index 0000000..51a7293
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/orm/GenericOrmXmlUiFactory.java
@@ -0,0 +1,15 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2009 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.ui.internal.details.orm;
+
+public class GenericOrmXmlUiFactory extends BaseOrmXmlUiFactory
+{
+	//nothing
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/orm/JptUiDetailsOrmMessages.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/orm/JptUiDetailsOrmMessages.java
new file mode 100644
index 0000000..88ed634
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/orm/JptUiDetailsOrmMessages.java
@@ -0,0 +1,78 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2010 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.ui.internal.details.orm;
+
+import org.eclipse.osgi.util.NLS;
+
+/**
+ * Localized messages used by Dali ORM widgets.
+ *
+ * @version 2.2
+ * @since 1.0
+ */
+public class JptUiDetailsOrmMessages {
+
+	public static String Boolean_False;
+	public static String Boolean_True;
+
+	public static String EntityMappingsSection_title;
+	public static String EntityMappingsDetailsPage_access;
+	public static String EntityMappingsDetailsPage_catalog;
+	public static String EntityMappingsDetailsPage_field;
+	public static String EntityMappingsDetailsPage_package;
+	public static String EntityMappingsDetailsPage_property;
+	public static String EntityMappingsDetailsPage_schema;
+	public static String EntityMappingsPage_catalogDefault;
+	public static String EntityMappingsPage_catalogNoDefaultSpecified;
+	public static String EntityMappingsPage_schemaDefault;
+	public static String EntityMappingsPage_schemaNoDefaultSpecified;
+	public static String MetadataCompleteComposite_metadataComplete;
+	public static String MetadataCompleteComposite_metadataCompleteWithDefault;
+	public static String OrmGeneratorsComposite_displayString;
+	public static String OrmGeneratorsComposite_groupBox;
+	public static String OrmMappingNameChooser_name;
+	public static String OrmJavaClassChooser_javaClass;
+	public static String OrmQueriesComposite_groupBox;
+	public static String PersistenceUnitMetadataComposite_access;
+	public static String PersistenceUnitMetadataComposite_delimitedIdentifiersCheckBox;
+	public static String PersistenceUnitMetadataComposite_cascadePersistCheckBox;
+	public static String PersistenceUnitMetadataComposite_catalog;
+	public static String PersistenceUnitMetadataComposite_field;
+	public static String PersistenceUnitMetadataComposite_persistenceUnitSection;
+	public static String PersistenceUnitMetadataComposite_property;
+	public static String PersistenceUnitMetadataComposite_schema;
+	public static String PersistenceUnitMetadataComposite_xmlMappingMetadataCompleteCheckBox;
+	public static String PersistenceUnitMetadataSection_catalogDefault;
+	public static String PersistenceUnitMetadataSection_schemaDefault;
+
+	public static String AddGeneratorDialog_name;
+	public static String AddGeneratorDialog_generatorType;
+ 	public static String AddGeneratorDialog_title;
+	public static String AddGeneratorDialog_descriptionTitle;
+	public static String AddGeneratorDialog_description;
+	public static String AddGeneratorDialog_tableGenerator;
+	public static String AddGeneratorDialog_sequenceGenerator;
+	public static String GeneratorStateObject_nameMustBeSpecified;
+	public static String GeneratorStateObject_typeMustBeSpecified;
+	
+	public static String UnsupportedOrmMappingUiProvider_label;
+	public static String UnsupportedOrmMappingUiProvider_linkLabel;
+
+	private static final String BUNDLE_NAME = "jpt_ui_details_orm"; //$NON-NLS-1$
+	private static final Class<?> BUNDLE_CLASS = JptUiDetailsOrmMessages.class;
+	static {
+		NLS.initializeMessages(BUNDLE_NAME, BUNDLE_CLASS);
+	}
+
+	private JptUiDetailsOrmMessages() {
+		throw new UnsupportedOperationException();
+	}
+
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/orm/MetadataCompleteComposite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/orm/MetadataCompleteComposite.java
new file mode 100644
index 0000000..8658e55
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/orm/MetadataCompleteComposite.java
@@ -0,0 +1,86 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2010 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.ui.internal.details.orm;
+
+import org.eclipse.jpt.core.context.orm.OrmTypeMapping;
+import org.eclipse.jpt.ui.internal.widgets.Pane;
+import org.eclipse.jpt.utility.internal.model.value.PropertyAspectAdapter;
+import org.eclipse.jpt.utility.internal.model.value.TransformationPropertyValueModel;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.jpt.utility.model.value.WritablePropertyValueModel;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.swt.widgets.Composite;
+
+public class MetadataCompleteComposite extends Pane<OrmTypeMapping> {
+
+	public MetadataCompleteComposite(Pane<?> parentPane,
+	                           PropertyValueModel<? extends OrmTypeMapping> subjectHolder,
+	                           Composite parent) {
+
+		super(parentPane, subjectHolder, parent);
+	}
+
+	@Override
+	protected void initializeLayout(Composite container) {
+
+		addTriStateCheckBoxWithDefault(
+			container,
+			JptUiDetailsOrmMessages.MetadataCompleteComposite_metadataComplete,
+			buildMetadataCompleteHolder(),
+			buildMetadataCompleteStringHolder(),
+			null
+		);
+	}
+	
+	private WritablePropertyValueModel<Boolean> buildMetadataCompleteHolder() {
+		return new PropertyAspectAdapter<OrmTypeMapping, Boolean>(
+			getSubjectHolder(),
+			OrmTypeMapping.SPECIFIED_METADATA_COMPLETE_PROPERTY)
+		{
+			@Override
+			protected Boolean buildValue_() {
+				return this.subject.getSpecifiedMetadataComplete();
+			}
+
+			@Override
+			protected void setValue_(Boolean value) {
+				this.subject.setSpecifiedMetadataComplete(value);
+			}
+		};
+	}
+
+	private PropertyValueModel<String> buildMetadataCompleteStringHolder() {
+		return new TransformationPropertyValueModel<Boolean, String>(buildDefaultMetadataCompleteHolder()) {
+			@Override
+			protected String transform(Boolean value) {
+				if (value != null) {
+					String defaultStringValue = value.booleanValue() ? JptUiDetailsOrmMessages.Boolean_True : JptUiDetailsOrmMessages.Boolean_False;
+					return NLS.bind(JptUiDetailsOrmMessages.MetadataCompleteComposite_metadataCompleteWithDefault, defaultStringValue);
+				}
+				return JptUiDetailsOrmMessages.MetadataCompleteComposite_metadataComplete;
+			}
+		};
+	}
+	private PropertyValueModel<Boolean> buildDefaultMetadataCompleteHolder() {
+		return new PropertyAspectAdapter<OrmTypeMapping, Boolean>(
+			getSubjectHolder(),
+			OrmTypeMapping.SPECIFIED_METADATA_COMPLETE_PROPERTY,
+			OrmTypeMapping.DEFAULT_METADATA_COMPLETE_PROPERTY)
+		{
+			@Override
+			protected Boolean buildValue_() {
+				if (this.subject.getSpecifiedMetadataComplete() != null) {
+					return null;
+				}
+				return Boolean.valueOf(this.subject.isDefaultMetadataComplete());
+			}
+		};
+	}
+}
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/orm/OrmBasicMappingComposite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/orm/OrmBasicMappingComposite.java
new file mode 100644
index 0000000..3d0b9c0
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/orm/OrmBasicMappingComposite.java
@@ -0,0 +1,46 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2010 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.ui.internal.details.orm;
+
+import org.eclipse.jpt.core.context.orm.OrmBasicMapping;
+import org.eclipse.jpt.ui.WidgetFactory;
+import org.eclipse.jpt.ui.internal.details.AbstractBasicMappingComposite;
+import org.eclipse.jpt.ui.internal.details.ColumnComposite;
+import org.eclipse.jpt.ui.internal.details.FetchTypeComposite;
+import org.eclipse.jpt.ui.internal.details.OptionalComposite;
+import org.eclipse.jpt.ui.internal.details.orm.OrmMappingNameChooser;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+public class OrmBasicMappingComposite extends AbstractBasicMappingComposite<OrmBasicMapping>
+{
+	/**
+	 * Creates a new <code>EclipseLink1_1OrmBasicMappingComposite</code>.
+	 *
+	 * @param subjectHolder The holder of the subject <code>BasicMapping</code>
+	 * @param parent The parent container
+	 * @param widgetFactory The factory used to create various common widgets
+	 */
+	public OrmBasicMappingComposite(PropertyValueModel<? extends OrmBasicMapping> subjectHolder,
+	                               Composite parent,
+	                               WidgetFactory widgetFactory) {
+
+		super(subjectHolder, parent, widgetFactory);
+	}
+
+	@Override
+	protected void initializeBasicSection(Composite container) {
+		new ColumnComposite(this, buildColumnHolder(), container);
+		new OrmMappingNameChooser(this, getSubjectHolder(), container);
+		new FetchTypeComposite(this, container);
+		new OptionalComposite(this, addSubPane(container, 4));
+	}
+
+}
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/orm/OrmBasicMappingUiDefinition.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/orm/OrmBasicMappingUiDefinition.java
new file mode 100644
index 0000000..01939d7
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/orm/OrmBasicMappingUiDefinition.java
@@ -0,0 +1,54 @@
+/*******************************************************************************
+ *  Copyright (c) 2008, 2009  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.ui.internal.details.orm;
+
+import org.eclipse.jpt.core.context.PersistentAttribute;
+import org.eclipse.jpt.core.context.orm.OrmBasicMapping;
+import org.eclipse.jpt.ui.WidgetFactory;
+import org.eclipse.jpt.ui.details.JpaComposite;
+import org.eclipse.jpt.ui.details.orm.OrmAttributeMappingUiDefinition;
+import org.eclipse.jpt.ui.details.orm.OrmXmlUiFactory;
+import org.eclipse.jpt.ui.internal.details.AbstractBasicMappingUiDefinition;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+public class OrmBasicMappingUiDefinition
+	extends AbstractBasicMappingUiDefinition<PersistentAttribute, OrmBasicMapping>
+	implements OrmAttributeMappingUiDefinition<OrmBasicMapping>
+{
+	// singleton
+	private static final OrmBasicMappingUiDefinition INSTANCE = 
+		new OrmBasicMappingUiDefinition();
+	
+	/**
+	 * Return the singleton.
+	 */
+	public static OrmAttributeMappingUiDefinition<OrmBasicMapping> instance() {
+		return INSTANCE;
+	}
+	
+	
+	/**
+	 * Ensure single instance.
+	 */
+	private OrmBasicMappingUiDefinition() {
+		super();
+	}
+	
+	public JpaComposite buildAttributeMappingComposite(
+			OrmXmlUiFactory factory, 
+			PropertyValueModel<OrmBasicMapping> subjectHolder, 
+			Composite parent, 
+			WidgetFactory widgetFactory) {
+		
+		return factory.createOrmBasicMappingComposite(subjectHolder, parent, widgetFactory);
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/orm/OrmEmbeddableComposite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/orm/OrmEmbeddableComposite.java
new file mode 100644
index 0000000..5565d1e
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/orm/OrmEmbeddableComposite.java
@@ -0,0 +1,54 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2010 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.ui.internal.details.orm;
+
+import org.eclipse.jpt.core.context.AccessHolder;
+import org.eclipse.jpt.core.context.orm.OrmEmbeddable;
+import org.eclipse.jpt.ui.WidgetFactory;
+import org.eclipse.jpt.ui.details.JpaComposite;
+import org.eclipse.jpt.ui.internal.details.AbstractEmbeddableComposite;
+import org.eclipse.jpt.ui.internal.details.AccessTypeComposite;
+import org.eclipse.jpt.utility.internal.model.value.PropertyAspectAdapter;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+public class OrmEmbeddableComposite extends AbstractEmbeddableComposite<OrmEmbeddable> implements JpaComposite
+{
+	public OrmEmbeddableComposite(PropertyValueModel<? extends OrmEmbeddable> subjectHolder,
+	                          Composite parent,
+	                          WidgetFactory widgetFactory) {
+
+		super(subjectHolder, parent, widgetFactory);
+	}
+
+	@Override
+	protected void initializeLayout(Composite container) {
+		this.initializeEmbeddableCollapsibleSection(container);
+	}
+
+	@Override
+	protected void initializeEmbeddableSection(Composite container) {
+		new OrmJavaClassChooser(this, getSubjectHolder(), container);
+		new AccessTypeComposite(this, buildAccessHolder(), container);
+		new MetadataCompleteComposite(this, getSubjectHolder(), container);
+	}
+	
+	protected PropertyValueModel<AccessHolder> buildAccessHolder() {
+		return new PropertyAspectAdapter<OrmEmbeddable, AccessHolder>(
+			getSubjectHolder())
+		{
+			@Override
+			protected AccessHolder buildValue_() {
+				return this.subject.getPersistentType();
+			}
+		};
+	}
+
+}
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/orm/OrmEmbeddableUiDefinition.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/orm/OrmEmbeddableUiDefinition.java
new file mode 100644
index 0000000..54ced67
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/orm/OrmEmbeddableUiDefinition.java
@@ -0,0 +1,54 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2009 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.ui.internal.details.orm;
+
+import org.eclipse.jpt.core.context.PersistentType;
+import org.eclipse.jpt.core.context.orm.OrmEmbeddable;
+import org.eclipse.jpt.ui.WidgetFactory;
+import org.eclipse.jpt.ui.details.JpaComposite;
+import org.eclipse.jpt.ui.details.orm.OrmTypeMappingUiDefinition;
+import org.eclipse.jpt.ui.details.orm.OrmXmlUiFactory;
+import org.eclipse.jpt.ui.internal.details.AbstractEmbeddableUiDefinition;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+public class OrmEmbeddableUiDefinition 
+	extends AbstractEmbeddableUiDefinition<PersistentType, OrmEmbeddable>
+	implements OrmTypeMappingUiDefinition<OrmEmbeddable>
+{
+	// singleton
+	private static final OrmEmbeddableUiDefinition INSTANCE = new OrmEmbeddableUiDefinition();
+	
+	
+	/**
+	 * Return the singleton.
+	 */
+	public static OrmTypeMappingUiDefinition<OrmEmbeddable> instance() {
+		return INSTANCE;
+	}
+	
+	
+	/**
+	 * Ensure single instance.
+	 */
+	private OrmEmbeddableUiDefinition() {
+		super();
+	}
+	
+	
+	public JpaComposite buildTypeMappingComposite(
+			OrmXmlUiFactory factory,
+			PropertyValueModel<OrmEmbeddable> subjectHolder,
+			Composite parent,
+			WidgetFactory widgetFactory) {
+		
+		return factory.createOrmEmbeddableComposite(subjectHolder, parent, widgetFactory);
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/orm/OrmEmbeddedIdMappingComposite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/orm/OrmEmbeddedIdMappingComposite.java
new file mode 100644
index 0000000..1c95dfe
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/orm/OrmEmbeddedIdMappingComposite.java
@@ -0,0 +1,41 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2010 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.ui.internal.details.orm;
+
+import org.eclipse.jpt.core.context.orm.OrmEmbeddedIdMapping;
+import org.eclipse.jpt.ui.WidgetFactory;
+import org.eclipse.jpt.ui.details.JpaComposite;
+import org.eclipse.jpt.ui.internal.details.AbstractEmbeddedIdMappingComposite;
+import org.eclipse.jpt.ui.internal.details.EmbeddedMappingOverridesComposite;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+public class OrmEmbeddedIdMappingComposite
+	extends AbstractEmbeddedIdMappingComposite<OrmEmbeddedIdMapping>
+	implements JpaComposite
+{
+	public OrmEmbeddedIdMappingComposite(
+			PropertyValueModel<? extends OrmEmbeddedIdMapping> subjectHolder,
+			Composite parent,
+			WidgetFactory widgetFactory) {
+		
+		super(subjectHolder, parent, widgetFactory);
+	}
+	
+	
+	@Override
+	protected void initializeEmbeddedIdSection(Composite container) {
+		new OrmMappingNameChooser(this, getSubjectHolder(), container);
+
+		new EmbeddedMappingOverridesComposite(
+				this,
+				container);
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/orm/OrmEmbeddedIdMappingUiDefinition.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/orm/OrmEmbeddedIdMappingUiDefinition.java
new file mode 100644
index 0000000..7409fc0
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/orm/OrmEmbeddedIdMappingUiDefinition.java
@@ -0,0 +1,56 @@
+/*******************************************************************************
+ *  Copyright (c) 2008, 2009  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.ui.internal.details.orm;
+
+import org.eclipse.jpt.core.context.PersistentAttribute;
+import org.eclipse.jpt.core.context.orm.OrmEmbeddedIdMapping;
+import org.eclipse.jpt.ui.WidgetFactory;
+import org.eclipse.jpt.ui.details.JpaComposite;
+import org.eclipse.jpt.ui.details.orm.OrmAttributeMappingUiDefinition;
+import org.eclipse.jpt.ui.details.orm.OrmXmlUiFactory;
+import org.eclipse.jpt.ui.internal.details.AbstractEmbeddedIdMappingUiDefinition;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+public class OrmEmbeddedIdMappingUiDefinition
+	extends AbstractEmbeddedIdMappingUiDefinition<PersistentAttribute, OrmEmbeddedIdMapping>
+	implements OrmAttributeMappingUiDefinition<OrmEmbeddedIdMapping>
+{
+	// singleton
+	private static final OrmEmbeddedIdMappingUiDefinition INSTANCE = 
+			new OrmEmbeddedIdMappingUiDefinition();
+	
+	
+	/**
+	 * Return the singleton.
+	 */
+	public static OrmAttributeMappingUiDefinition<OrmEmbeddedIdMapping> instance() {
+		return INSTANCE;
+	}
+	
+	
+	/**
+	 * Ensure single instance.
+	 */
+	private OrmEmbeddedIdMappingUiDefinition() {
+		super();
+	}	
+	
+	
+	public JpaComposite buildAttributeMappingComposite(
+			OrmXmlUiFactory factory,
+			PropertyValueModel<OrmEmbeddedIdMapping> subjectHolder,
+			Composite parent,
+			WidgetFactory widgetFactory) {
+		
+		return factory.createOrmEmbeddedIdMappingComposite(subjectHolder, parent, widgetFactory);
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/orm/OrmEmbeddedMappingComposite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/orm/OrmEmbeddedMappingComposite.java
new file mode 100644
index 0000000..e787b6b
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/orm/OrmEmbeddedMappingComposite.java
@@ -0,0 +1,65 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2010 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.ui.internal.details.orm;
+
+import org.eclipse.jpt.core.context.orm.OrmEmbeddedMapping;
+import org.eclipse.jpt.ui.WidgetFactory;
+import org.eclipse.jpt.ui.details.JpaComposite;
+import org.eclipse.jpt.ui.internal.details.AbstractEmbeddedMappingComposite;
+import org.eclipse.jpt.ui.internal.details.EmbeddedMappingOverridesComposite;
+import org.eclipse.jpt.ui.internal.details.orm.OrmMappingNameChooser;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * Here the layout of this pane:
+ * <pre>
+ * -----------------------------------------------------------------------------
+ * | ------------------------------------------------------------------------- |
+ * | |                                                                       | |
+ * | | EmbeddedAttributeOverridesComposite                                   | |
+ * | |                                                                       | |
+ * | ------------------------------------------------------------------------- |
+ * -----------------------------------------------------------------------------</pre>
+ *
+ * @see EmbeddedMapping
+ * @see BaseJavaUiFactory - The factory creating this pane
+ *
+ * @version 2.3
+ * @since 2.2
+ */
+public class OrmEmbeddedMappingComposite extends AbstractEmbeddedMappingComposite<OrmEmbeddedMapping>
+                                      implements JpaComposite
+{
+	/**
+	 * Creates a new <code>EmbeddedMappingComposite</code>.
+	 *
+	 * @param subjectHolder The holder of the subject <code>EmbeddedMapping</code>
+	 * @param parent The parent container
+	 * @param widgetFactory The factory used to create various common widgets
+	 */
+	public OrmEmbeddedMappingComposite(PropertyValueModel<? extends OrmEmbeddedMapping> subjectHolder,
+	                                Composite parent,
+	                                WidgetFactory widgetFactory) {
+
+		super(subjectHolder, parent, widgetFactory);
+	}
+	
+	@Override
+	protected void initializeEmbeddedSection(Composite container) {
+		new OrmMappingNameChooser(this, getSubjectHolder(), container);
+
+		new EmbeddedMappingOverridesComposite(
+			this,
+			container
+		);
+	}	
+
+}
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/orm/OrmEmbeddedMappingUiDefinition.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/orm/OrmEmbeddedMappingUiDefinition.java
new file mode 100644
index 0000000..b267cb9
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/orm/OrmEmbeddedMappingUiDefinition.java
@@ -0,0 +1,56 @@
+/*******************************************************************************
+ *  Copyright (c) 2008, 2009  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.ui.internal.details.orm;
+
+import org.eclipse.jpt.core.context.PersistentAttribute;
+import org.eclipse.jpt.core.context.orm.OrmEmbeddedMapping;
+import org.eclipse.jpt.ui.WidgetFactory;
+import org.eclipse.jpt.ui.details.JpaComposite;
+import org.eclipse.jpt.ui.details.orm.OrmAttributeMappingUiDefinition;
+import org.eclipse.jpt.ui.details.orm.OrmXmlUiFactory;
+import org.eclipse.jpt.ui.internal.details.AbstractEmbeddedMappingUiDefinition;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+public class OrmEmbeddedMappingUiDefinition
+	extends AbstractEmbeddedMappingUiDefinition<PersistentAttribute, OrmEmbeddedMapping>
+	implements OrmAttributeMappingUiDefinition<OrmEmbeddedMapping>
+{
+	// singleton
+	private static final OrmEmbeddedMappingUiDefinition INSTANCE = 
+			new OrmEmbeddedMappingUiDefinition();
+	
+	
+	/**
+	 * Return the singleton.
+	 */
+	public static OrmAttributeMappingUiDefinition<OrmEmbeddedMapping> instance() {
+		return INSTANCE;
+	}
+	
+	
+	/**
+	 * Ensure single instance.
+	 */
+	private OrmEmbeddedMappingUiDefinition() {
+		super();
+	}
+	
+	
+	public JpaComposite buildAttributeMappingComposite(
+			OrmXmlUiFactory factory,
+			PropertyValueModel<OrmEmbeddedMapping> subjectHolder,
+			Composite parent,
+			WidgetFactory widgetFactory) {
+		
+		return factory.createOrmEmbeddedMappingComposite(subjectHolder, parent, widgetFactory);
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/orm/OrmEntityComposite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/orm/OrmEntityComposite.java
new file mode 100644
index 0000000..8df0695
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/orm/OrmEntityComposite.java
@@ -0,0 +1,43 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2009 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.ui.internal.details.orm;
+
+import org.eclipse.jpt.core.context.orm.OrmEntity;
+import org.eclipse.jpt.ui.WidgetFactory;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * The pane used for an ORM entity.
+ *
+ * @see OrmEntity
+ * @see BaseJavaUiFactory - The factory creating this pane
+ * @see OrmSecondaryTablesComposite
+ *
+ * @version 2.0
+ * @since 1.0
+ */
+public class OrmEntityComposite extends AbstractOrmEntityComposite
+{
+	/**
+	 * Creates a new <code>OrmEntityComposite</code>.
+	 *
+	 * @param subjectHolder The holder of the subject <code>OrmEntity</code>
+	 * @param parent The parent container
+	 * @param widgetFactory The factory used to create various common widgets
+	 */
+	public OrmEntityComposite(PropertyValueModel<? extends OrmEntity> subjectHolder,
+	                          Composite parent,
+	                          WidgetFactory widgetFactory) {
+
+		super(subjectHolder, parent, widgetFactory);
+	}
+	
+}
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/orm/OrmEntityUiDefinition.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/orm/OrmEntityUiDefinition.java
new file mode 100644
index 0000000..2b6967c
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/orm/OrmEntityUiDefinition.java
@@ -0,0 +1,55 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2009 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.ui.internal.details.orm;
+
+import org.eclipse.jpt.core.context.PersistentType;
+import org.eclipse.jpt.core.context.orm.OrmEntity;
+import org.eclipse.jpt.ui.WidgetFactory;
+import org.eclipse.jpt.ui.details.JpaComposite;
+import org.eclipse.jpt.ui.details.orm.OrmTypeMappingUiDefinition;
+import org.eclipse.jpt.ui.details.orm.OrmXmlUiFactory;
+import org.eclipse.jpt.ui.internal.details.AbstractEntityUiDefinition;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+public class OrmEntityUiDefinition
+	extends AbstractEntityUiDefinition<PersistentType, OrmEntity>
+	implements OrmTypeMappingUiDefinition<OrmEntity>
+{
+	// singleton
+	private static final OrmEntityUiDefinition INSTANCE = 
+			new OrmEntityUiDefinition();
+	
+	
+	/**
+	 * Return the singleton.
+	 */
+	public static OrmTypeMappingUiDefinition<OrmEntity> instance() {
+		return INSTANCE;
+	}
+	
+	
+	/**
+	 * Ensure single instance.
+	 */
+	private OrmEntityUiDefinition() {
+		super();
+	}
+	
+	
+	public JpaComposite buildTypeMappingComposite(
+			OrmXmlUiFactory factory,
+			PropertyValueModel<OrmEntity> subjectHolder,
+			Composite parent,
+			WidgetFactory widgetFactory) {
+		
+		return factory.createOrmEntityComposite(subjectHolder, parent, widgetFactory);
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/orm/OrmIdMappingComposite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/orm/OrmIdMappingComposite.java
new file mode 100644
index 0000000..b5216bd
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/orm/OrmIdMappingComposite.java
@@ -0,0 +1,36 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2010 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.ui.internal.details.orm;
+
+import org.eclipse.jpt.core.context.orm.OrmIdMapping;
+import org.eclipse.jpt.ui.WidgetFactory;
+import org.eclipse.jpt.ui.internal.details.AbstractIdMappingComposite;
+import org.eclipse.jpt.ui.internal.details.ColumnComposite;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+public class OrmIdMappingComposite
+	extends AbstractIdMappingComposite<OrmIdMapping>
+{
+	public OrmIdMappingComposite(
+			PropertyValueModel<? extends OrmIdMapping> subjectHolder,
+	        Composite parent,
+	        WidgetFactory widgetFactory) {
+		
+		super(subjectHolder, parent, widgetFactory);
+	}
+	
+	
+	@Override
+	protected void initializeIdSection(Composite container) {
+		new ColumnComposite(this, buildColumnHolder(), container);
+		new OrmMappingNameChooser(this, getSubjectHolder(), container);
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/orm/OrmIdMappingUiDefinition.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/orm/OrmIdMappingUiDefinition.java
new file mode 100644
index 0000000..f58b5f7
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/orm/OrmIdMappingUiDefinition.java
@@ -0,0 +1,56 @@
+/*******************************************************************************
+ *  Copyright (c) 2008, 2009  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.ui.internal.details.orm;
+
+import org.eclipse.jpt.core.context.PersistentAttribute;
+import org.eclipse.jpt.core.context.orm.OrmIdMapping;
+import org.eclipse.jpt.ui.WidgetFactory;
+import org.eclipse.jpt.ui.details.JpaComposite;
+import org.eclipse.jpt.ui.details.orm.OrmAttributeMappingUiDefinition;
+import org.eclipse.jpt.ui.details.orm.OrmXmlUiFactory;
+import org.eclipse.jpt.ui.internal.details.AbstractIdMappingUiDefinition;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+public class OrmIdMappingUiDefinition 
+	extends AbstractIdMappingUiDefinition<PersistentAttribute, OrmIdMapping>
+	implements OrmAttributeMappingUiDefinition<OrmIdMapping>
+{
+	// singleton
+	private static final OrmIdMappingUiDefinition INSTANCE = 
+			new OrmIdMappingUiDefinition();
+	
+	
+	/**
+	 * Return the singleton.
+	 */
+	public static OrmAttributeMappingUiDefinition<OrmIdMapping> instance() {
+		return INSTANCE;
+	}
+	
+	
+	/**
+	 * Ensure single instance.
+	 */
+	private OrmIdMappingUiDefinition() {
+		super();
+	}
+	
+	
+	public JpaComposite buildAttributeMappingComposite(
+			OrmXmlUiFactory factory,
+			PropertyValueModel<OrmIdMapping> subjectHolder,
+			Composite parent,
+			WidgetFactory widgetFactory) {
+		
+		return factory.createOrmIdMappingComposite(subjectHolder, parent, widgetFactory);
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/orm/OrmInheritanceComposite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/orm/OrmInheritanceComposite.java
new file mode 100644
index 0000000..7b563c3
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/orm/OrmInheritanceComposite.java
@@ -0,0 +1,44 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2010 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.ui.internal.details.orm;
+
+import org.eclipse.jpt.core.context.orm.OrmEntity;
+import org.eclipse.jpt.ui.internal.details.AbstractInheritanceComposite;
+import org.eclipse.jpt.ui.internal.widgets.Pane;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * The pane used for java inheritance.
+ *
+ * @see OrmEntity
+ * @see OrmPrimaryKeyJoinColumnsComposite
+ *
+ * @version 2.0
+ * @since 1.0
+ */
+public class OrmInheritanceComposite extends AbstractInheritanceComposite<OrmEntity> {
+
+	/**
+	 * Creates a new <code>OrmInheritanceComposite</code>.
+	 *
+	 * @param parentPane The parent container of this one
+	 * @param parent The parent container
+	 */
+	public OrmInheritanceComposite(Pane<? extends OrmEntity> parentPane,
+	                            Composite parent) {
+
+		super(parentPane, parent);
+	}
+
+	@Override
+	protected void addPrimaryKeyJoinColumnsComposite(Composite container) {
+		new OrmPrimaryKeyJoinColumnsComposite(this, container);
+	}
+}
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/orm/OrmJavaClassChooser.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/orm/OrmJavaClassChooser.java
new file mode 100644
index 0000000..e41afcc
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/orm/OrmJavaClassChooser.java
@@ -0,0 +1,112 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2010 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.ui.internal.details.orm;
+
+import org.eclipse.jpt.core.JpaProject;
+import org.eclipse.jpt.core.context.orm.OrmTypeMapping;
+import org.eclipse.jpt.ui.internal.widgets.ClassChooserPane;
+import org.eclipse.jpt.ui.internal.widgets.Pane;
+import org.eclipse.jpt.utility.internal.model.value.PropertyAspectAdapter;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.jpt.utility.model.value.WritablePropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * Here the layout of this pane:
+ * <pre>
+ * -----------------------------------------------------------------------------
+ * |                                                                           |
+ * | ClassChooserPane                                                          |
+ * |                                                                           |
+ * -----------------------------------------------------------------------------</pre>
+ *
+ * TODO possibly help the user and if they have chosen a package at the
+ * entity-mappings level only insert the class name in the xml file if they
+ * choose a class from the package.
+ * Not sure if this should be driven by the UI or by ui api in the model
+ *
+ * @see OrmTypeMapping
+ * @see OrmPersistentTypeDetailsPage - The parent container
+ * @see ClassChooserPane
+ *
+ * @version 2.0
+ * @since 1.0
+ */
+public class OrmJavaClassChooser extends Pane<OrmTypeMapping> {
+
+	/**
+	 * Creates a new <code>XmlJavaClassChooser</code>.
+	 *
+	 * @param parentPane The parent controller of this one
+	 * @param subjectHolder The holder of this pane's subject
+	 * @param parent The parent container
+	 */
+	public OrmJavaClassChooser(Pane<?> parentPane,
+	                           PropertyValueModel<? extends OrmTypeMapping> subjectHolder,
+	                           Composite parent) {
+
+		super(parentPane, subjectHolder, parent);
+	}
+
+	public OrmJavaClassChooser(Pane<?> parentPane,
+        PropertyValueModel<? extends OrmTypeMapping> subjectHolder,
+        Composite parent,
+        boolean automaticallyAlignWidgets) {
+
+		super(parentPane, subjectHolder, parent, automaticallyAlignWidgets);
+	}
+
+
+	private ClassChooserPane<OrmTypeMapping> addClassChooser(Composite container) {
+
+		return new ClassChooserPane<OrmTypeMapping>(this, container) {
+
+			@Override
+			protected WritablePropertyValueModel<String> buildTextHolder() {
+				return new PropertyAspectAdapter<OrmTypeMapping, String>(getSubjectHolder(), OrmTypeMapping.CLASS_PROPERTY) {
+					@Override
+					protected String buildValue_() {
+						return this.subject.getClass_();
+					}
+
+					@Override
+					protected void setValue_(String value) {
+						this.subject.setClass(value);
+					}
+				};
+			}
+
+			@Override
+			protected String getClassName() {
+				return getSubject().getClass_();
+			}
+
+			@Override
+			protected String getLabelText() {
+				return JptUiDetailsOrmMessages.OrmJavaClassChooser_javaClass;
+			}
+			
+			@Override
+			protected JpaProject getJpaProject() {
+				return getSubject().getJpaProject();
+			}
+			
+			@Override
+			protected void setClassName(String className) {
+				getSubject().setClass(className);
+			}
+		};
+	}
+
+	@Override
+	protected void initializeLayout(Composite container) {
+		addClassChooser(container);
+	}
+}
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/orm/OrmManyToManyMappingComposite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/orm/OrmManyToManyMappingComposite.java
new file mode 100644
index 0000000..c60c5f1
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/orm/OrmManyToManyMappingComposite.java
@@ -0,0 +1,91 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2010 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.ui.internal.details.orm;
+
+import org.eclipse.jpt.core.context.ManyToManyMapping;
+import org.eclipse.jpt.core.context.orm.OrmManyToManyMapping;
+import org.eclipse.jpt.core.context.orm.OrmManyToManyRelationshipReference;
+import org.eclipse.jpt.ui.WidgetFactory;
+import org.eclipse.jpt.ui.internal.details.AbstractManyToManyMappingComposite;
+import org.eclipse.jpt.ui.internal.details.CascadeComposite;
+import org.eclipse.jpt.ui.internal.details.FetchTypeComposite;
+import org.eclipse.jpt.ui.internal.details.ManyToManyJoiningStrategyPane;
+import org.eclipse.jpt.ui.internal.details.OrderingComposite;
+import org.eclipse.jpt.ui.internal.details.TargetEntityComposite;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * Here the layout of this pane:
+ * <pre>
+ * -----------------------------------------------------------------------------
+ * | ------------------------------------------------------------------------- |
+ * | |                                                                       | |
+ * | | TargetEntityComposite                                                 | |
+ * | |                                                                       | |
+ * | ------------------------------------------------------------------------- |
+ * | ------------------------------------------------------------------------- |
+ * | |                                                                       | |
+ * | | JoiningStrategyComposite                                              | |
+ * | |                                                                       | |
+ * | ------------------------------------------------------------------------- |
+ * | ------------------------------------------------------------------------- |
+ * | |                                                                       | |
+ * | | FetchTypeComposite                                                    | |
+ * | |                                                                       | |
+ * | ------------------------------------------------------------------------- |
+ * | ------------------------------------------------------------------------- |
+ * | |                                                                       | |
+ * | | CascadeComposite                                                      | |
+ * | |                                                                       | |
+ * | ------------------------------------------------------------------------- |
+ * | ------------------------------------------------------------------------- |
+ * | |                                                                       | |
+ * | | OrderingComposite                                                     | |
+ * | |                                                                       | |
+ * | ------------------------------------------------------------------------- |
+ * -----------------------------------------------------------------------------</pre>
+ *
+ * @see {@link ManyToManyMapping}
+ * @see {@link TargetEntityComposite}
+ * @see {@link ManyToManyJoiningStrategyPane}
+ * @see {@link FetchTypeComposite}
+ * @see {@link CascadeComposite}
+ * @see {@link OrderingComposite}
+ *
+ * @version 2.3
+ * @since 1.0
+ */
+public class OrmManyToManyMappingComposite 
+	extends AbstractManyToManyMappingComposite<OrmManyToManyMapping, OrmManyToManyRelationshipReference>
+{
+	/**
+	 * Creates a new <code>ManyToManyMappingComposite</code>.
+	 *
+	 * @param subjectHolder The holder of the subject <code>IManyToManyMapping</code>
+	 * @param parent The parent container
+	 * @param widgetFactory The factory used to create various common widgets
+	 */
+	public OrmManyToManyMappingComposite(PropertyValueModel<? extends OrmManyToManyMapping> subjectHolder,
+	                                  Composite parent,
+	                                  WidgetFactory widgetFactory) {
+
+		super(subjectHolder, parent, widgetFactory);
+	}
+
+	@Override
+	protected void initializeManyToManySection(Composite container) {
+		new TargetEntityComposite(this, container);
+		new OrmMappingNameChooser(this, getSubjectHolder(), container);
+		new FetchTypeComposite(this, container);
+		new CascadeComposite(this, buildCascadeHolder(), addSubPane(container, 5));
+	}
+
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/orm/OrmManyToManyMappingUiDefinition.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/orm/OrmManyToManyMappingUiDefinition.java
new file mode 100644
index 0000000..12ab385
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/orm/OrmManyToManyMappingUiDefinition.java
@@ -0,0 +1,56 @@
+/*******************************************************************************
+ *  Copyright (c) 2008, 2009  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.ui.internal.details.orm;
+
+import org.eclipse.jpt.core.context.PersistentAttribute;
+import org.eclipse.jpt.core.context.orm.OrmManyToManyMapping;
+import org.eclipse.jpt.ui.WidgetFactory;
+import org.eclipse.jpt.ui.details.JpaComposite;
+import org.eclipse.jpt.ui.details.orm.OrmAttributeMappingUiDefinition;
+import org.eclipse.jpt.ui.details.orm.OrmXmlUiFactory;
+import org.eclipse.jpt.ui.internal.details.AbstractManyToManyMappingUiDefinition;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+public class OrmManyToManyMappingUiDefinition
+	extends AbstractManyToManyMappingUiDefinition<PersistentAttribute, OrmManyToManyMapping>
+	implements OrmAttributeMappingUiDefinition<OrmManyToManyMapping>
+{
+	// singleton
+	private static final OrmManyToManyMappingUiDefinition INSTANCE = 
+			new OrmManyToManyMappingUiDefinition();
+	
+	
+	/**
+	 * Return the singleton.
+	 */
+	public static OrmAttributeMappingUiDefinition<OrmManyToManyMapping> instance() {
+		return INSTANCE;
+	}
+	
+	
+	/**
+	 * Ensure single instance.
+	 */
+	private OrmManyToManyMappingUiDefinition() {
+		super();
+	}
+	
+	
+	public JpaComposite buildAttributeMappingComposite(
+			OrmXmlUiFactory factory,
+			PropertyValueModel<OrmManyToManyMapping> subjectHolder,
+			Composite parent,
+			WidgetFactory widgetFactory) {
+		
+		return factory.createOrmManyToManyMappingComposite(subjectHolder, parent, widgetFactory);
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/orm/OrmManyToOneMappingComposite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/orm/OrmManyToOneMappingComposite.java
new file mode 100644
index 0000000..115f835
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/orm/OrmManyToOneMappingComposite.java
@@ -0,0 +1,92 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2010 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.ui.internal.details.orm;
+
+import org.eclipse.jpt.core.context.ManyToOneMapping;
+import org.eclipse.jpt.core.context.orm.OrmManyToOneMapping;
+import org.eclipse.jpt.core.context.orm.OrmManyToOneRelationshipReference;
+import org.eclipse.jpt.ui.WidgetFactory;
+import org.eclipse.jpt.ui.internal.details.AbstractManyToOneMappingComposite;
+import org.eclipse.jpt.ui.internal.details.CascadeComposite;
+import org.eclipse.jpt.ui.internal.details.FetchTypeComposite;
+import org.eclipse.jpt.ui.internal.details.ManyToOneJoiningStrategyPane;
+import org.eclipse.jpt.ui.internal.details.OptionalComposite;
+import org.eclipse.jpt.ui.internal.details.TargetEntityComposite;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * Here the layout of this pane:
+ * <pre>
+ * -----------------------------------------------------------------------------
+ * | ------------------------------------------------------------------------- |
+ * | |                                                                       | |
+ * | | TargetEntityComposite                                                 | |
+ * | |                                                                       | |
+ * | ------------------------------------------------------------------------- |
+ * | ------------------------------------------------------------------------- |
+ * | |                                                                       | |
+ * | | JoiningStrategyComposite                                              | |
+ * | |                                                                       | |
+ * | ------------------------------------------------------------------------- |
+ * | ------------------------------------------------------------------------- |
+ * | |                                                                       | |
+ * | | FetchTypeComposite                                                    | |
+ * | |                                                                       | |
+ * | ------------------------------------------------------------------------- |
+ * | ------------------------------------------------------------------------- |
+ * | |                                                                       | |
+ * | | OptionalComposite                                                     | |
+ * | |                                                                       | |
+ * | ------------------------------------------------------------------------- |
+ * | ------------------------------------------------------------------------- |
+ * | |                                                                       | |
+ * | | CascadeComposite                                                      | |
+ * | |                                                                       | |
+ * | ------------------------------------------------------------------------- |
+ * -----------------------------------------------------------------------------</pre>
+ *
+ * @see {@link ManyToOneMapping}
+ * @see {@link TargetEntityComposite}
+ * @see {@link ManyToOneJoiningStrategyPane}
+ * @see {@link FetchTypeComposite}
+ * @see {@link OptionalComposite}
+ * @see {@link CascadeComposite}
+ *
+ * @version 2.3
+ * @since 1.0
+ */
+public class OrmManyToOneMappingComposite 
+	extends AbstractManyToOneMappingComposite<OrmManyToOneMapping, OrmManyToOneRelationshipReference>
+{
+	/**
+	 * Creates a new <code>ManyToOneMappingComposite</code>.
+	 *
+	 * @param subjectHolder The holder of the subject <code>IManyToOneMapping</code>
+	 * @param parent The parent container
+	 * @param widgetFactory The factory used to create various common widgets
+	 */
+	public OrmManyToOneMappingComposite(PropertyValueModel<? extends OrmManyToOneMapping> subjectHolder,
+	                                 Composite parent,
+	                                 WidgetFactory widgetFactory) {
+
+		super(subjectHolder, parent, widgetFactory);
+	}
+
+	@Override
+	protected void initializeManyToOneSection(Composite container) {
+		new TargetEntityComposite(this, container);
+		new OrmMappingNameChooser(this, getSubjectHolder(), container);
+		new FetchTypeComposite(this, container);
+		new OptionalComposite(this, container);
+		new CascadeComposite(this, buildCascadeHolder(),  addSubPane(container, 5));
+	}
+
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/orm/OrmManyToOneMappingUiDefinition.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/orm/OrmManyToOneMappingUiDefinition.java
new file mode 100644
index 0000000..8779152
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/orm/OrmManyToOneMappingUiDefinition.java
@@ -0,0 +1,56 @@
+/*******************************************************************************
+ *  Copyright (c) 2008, 2009  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.ui.internal.details.orm;
+
+import org.eclipse.jpt.core.context.PersistentAttribute;
+import org.eclipse.jpt.core.context.orm.OrmManyToOneMapping;
+import org.eclipse.jpt.ui.WidgetFactory;
+import org.eclipse.jpt.ui.details.JpaComposite;
+import org.eclipse.jpt.ui.details.orm.OrmAttributeMappingUiDefinition;
+import org.eclipse.jpt.ui.details.orm.OrmXmlUiFactory;
+import org.eclipse.jpt.ui.internal.details.AbstractManyToOneMappingUiDefinition;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+public class OrmManyToOneMappingUiDefinition
+	extends AbstractManyToOneMappingUiDefinition<PersistentAttribute, OrmManyToOneMapping>
+	implements OrmAttributeMappingUiDefinition<OrmManyToOneMapping>
+{
+	// singleton
+	private static final OrmManyToOneMappingUiDefinition INSTANCE = 
+			new OrmManyToOneMappingUiDefinition();
+	
+	
+	/**
+	 * Return the singleton.
+	 */
+	public static OrmAttributeMappingUiDefinition<OrmManyToOneMapping> instance() {
+		return INSTANCE;
+	}
+	
+	
+	/**
+	 * Ensure single instance.
+	 */
+	private OrmManyToOneMappingUiDefinition() {
+		super();
+	}
+	
+	
+	public JpaComposite buildAttributeMappingComposite(
+			OrmXmlUiFactory factory,
+			PropertyValueModel<OrmManyToOneMapping> subjectHolder,
+			Composite parent,
+			WidgetFactory widgetFactory) {
+		
+		return factory.createOrmManyToOneMappingComposite(subjectHolder, parent, widgetFactory);
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/orm/OrmMappedSuperclassComposite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/orm/OrmMappedSuperclassComposite.java
new file mode 100644
index 0000000..ae7ed4a
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/orm/OrmMappedSuperclassComposite.java
@@ -0,0 +1,51 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2010 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.ui.internal.details.orm;
+
+import org.eclipse.jpt.core.context.AccessHolder;
+import org.eclipse.jpt.core.context.orm.OrmMappedSuperclass;
+import org.eclipse.jpt.ui.WidgetFactory;
+import org.eclipse.jpt.ui.details.JpaComposite;
+import org.eclipse.jpt.ui.internal.details.AbstractMappedSuperclassComposite;
+import org.eclipse.jpt.ui.internal.details.AccessTypeComposite;
+import org.eclipse.jpt.ui.internal.details.IdClassComposite;
+import org.eclipse.jpt.utility.internal.model.value.PropertyAspectAdapter;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+public class OrmMappedSuperclassComposite
+	extends AbstractMappedSuperclassComposite<OrmMappedSuperclass>
+    implements JpaComposite
+{
+	public OrmMappedSuperclassComposite(
+			PropertyValueModel<? extends OrmMappedSuperclass> subjectHolder,
+			Composite parent,
+			WidgetFactory widgetFactory) {
+		
+		super(subjectHolder, parent, widgetFactory);
+	}
+	
+	@Override
+	protected void initializeMappedSuperclassSection(Composite container) {
+		new OrmJavaClassChooser(this, getSubjectHolder(), container);
+		new AccessTypeComposite(this, buildAccessHolder(), container);
+		new IdClassComposite(this, buildIdClassReferenceHolder(), container);
+		new MetadataCompleteComposite(this, getSubjectHolder(), container);
+	}
+	
+	protected PropertyValueModel<AccessHolder> buildAccessHolder() {
+		return new PropertyAspectAdapter<OrmMappedSuperclass, AccessHolder>(getSubjectHolder()) {
+			@Override
+			protected AccessHolder buildValue_() {
+				return this.subject.getPersistentType();
+			}
+		};
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/orm/OrmMappedSuperclassUiDefinition.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/orm/OrmMappedSuperclassUiDefinition.java
new file mode 100644
index 0000000..23e6df0
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/orm/OrmMappedSuperclassUiDefinition.java
@@ -0,0 +1,55 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2009 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.ui.internal.details.orm;
+
+import org.eclipse.jpt.core.context.PersistentType;
+import org.eclipse.jpt.core.context.orm.OrmMappedSuperclass;
+import org.eclipse.jpt.ui.WidgetFactory;
+import org.eclipse.jpt.ui.details.JpaComposite;
+import org.eclipse.jpt.ui.details.orm.OrmTypeMappingUiDefinition;
+import org.eclipse.jpt.ui.details.orm.OrmXmlUiFactory;
+import org.eclipse.jpt.ui.internal.details.AbstractMappedSuperclassUiDefinition;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+public class OrmMappedSuperclassUiDefinition 
+	extends AbstractMappedSuperclassUiDefinition<PersistentType, OrmMappedSuperclass>
+	implements OrmTypeMappingUiDefinition<OrmMappedSuperclass>
+{
+	// singleton
+	private static final OrmMappedSuperclassUiDefinition INSTANCE = 
+			new OrmMappedSuperclassUiDefinition();
+	
+	
+	/**
+	 * Return the singleton.
+	 */
+	public static OrmTypeMappingUiDefinition<OrmMappedSuperclass> instance() {
+		return INSTANCE;
+	}
+	
+	
+	/**
+	 * Ensure single instance.
+	 */
+	private OrmMappedSuperclassUiDefinition() {
+		super();
+	}
+	
+	
+	public JpaComposite buildTypeMappingComposite(
+			OrmXmlUiFactory factory,
+			PropertyValueModel<OrmMappedSuperclass> subjectHolder,
+			Composite parent,
+			WidgetFactory widgetFactory) {
+		
+		return factory.createOrmMappedSuperclassComposite(subjectHolder, parent, widgetFactory);
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/orm/OrmMappingNameChooser.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/orm/OrmMappingNameChooser.java
new file mode 100644
index 0000000..46e3de6
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/orm/OrmMappingNameChooser.java
@@ -0,0 +1,70 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2010 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.ui.internal.details.orm;
+
+import org.eclipse.jpt.core.context.orm.OrmAttributeMapping;
+import org.eclipse.jpt.ui.internal.widgets.Pane;
+import org.eclipse.jpt.utility.internal.model.value.PropertyAspectAdapter;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.jpt.utility.model.value.WritablePropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Text;
+
+/**
+ * @see OrmPersistentAttributeDetailsPage - The parent container
+ *
+ * @version 2.3
+ * @since 1.0
+ */
+public class OrmMappingNameChooser
+	extends Pane<OrmAttributeMapping>
+{
+	/**
+	 * Creates a new <code>XmlJavaAttributeChooser</code>.
+	 *
+	 * @param parentPane The parent container of this one
+	 * @param subjectHolder The holder of this pane's subject
+	 * @param parent The parent container
+	 */
+	public OrmMappingNameChooser(Pane<?> parentPane,
+	                               PropertyValueModel<? extends OrmAttributeMapping> subjectHolder,
+	                               Composite parent) {
+
+		super(parentPane, subjectHolder, parent);
+	}
+
+	@Override
+	protected void initializeLayout(Composite container) {
+		this.addLabeledText(
+			container,
+			JptUiDetailsOrmMessages.OrmMappingNameChooser_name,
+			buildNameHolder()
+		);
+	}
+	private WritablePropertyValueModel<String> buildNameHolder() {
+		return new PropertyAspectAdapter<OrmAttributeMapping, String>(getSubjectHolder(), OrmAttributeMapping.NAME_PROPERTY) {
+			@Override
+			protected String buildValue_() {
+				return this.subject.getName();
+			}
+
+			@Override
+			protected void setValue_(String value) {
+				if (this.subject.getPersistentAttribute().isVirtual()) {
+					return;
+				}
+				if (value.length() == 0) {
+					value = null;
+				}
+				this.subject.setName(value);
+			}
+		};
+	}
+}
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/orm/OrmOneToManyMappingComposite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/orm/OrmOneToManyMappingComposite.java
new file mode 100644
index 0000000..850cd9e
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/orm/OrmOneToManyMappingComposite.java
@@ -0,0 +1,90 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2010 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.ui.internal.details.orm;
+
+import org.eclipse.jpt.core.context.OneToManyMapping;
+import org.eclipse.jpt.core.context.OneToManyRelationshipReference;
+import org.eclipse.jpt.core.context.orm.OrmOneToManyMapping;
+import org.eclipse.jpt.ui.WidgetFactory;
+import org.eclipse.jpt.ui.internal.details.AbstractOneToManyMappingComposite;
+import org.eclipse.jpt.ui.internal.details.CascadeComposite;
+import org.eclipse.jpt.ui.internal.details.FetchTypeComposite;
+import org.eclipse.jpt.ui.internal.details.JoinTableComposite;
+import org.eclipse.jpt.ui.internal.details.OrderingComposite;
+import org.eclipse.jpt.ui.internal.details.TargetEntityComposite;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * Here the layout of this pane:
+ * <pre>
+ * -----------------------------------------------------------------------------
+ * | ------------------------------------------------------------------------- |
+ * | |                                                                       | |
+ * | | TargetEntityComposite                                                 | |
+ * | |                                                                       | |
+ * | ------------------------------------------------------------------------- |
+ * | ------------------------------------------------------------------------- |
+ * | |                                                                       | |
+ * | | JoiningStrategyComposite                                              | |
+ * | |                                                                       | |
+ * | ------------------------------------------------------------------------- |
+ * | ------------------------------------------------------------------------- |
+ * | |                                                                       | |
+ * | | FetchTypeComposite                                                    | |
+ * | |                                                                       | |
+ * | ------------------------------------------------------------------------- |
+ * | ------------------------------------------------------------------------- |
+ * | |                                                                       | |
+ * | | CascadeComposite                                                      | |
+ * | |                                                                       | |
+ * | ------------------------------------------------------------------------- |
+ * | ------------------------------------------------------------------------- |
+ * | |                                                                       | |
+ * | | OrderingComposite                                                     | |
+ * | |                                                                       | |
+ * | ------------------------------------------------------------------------- |
+ * -----------------------------------------------------------------------------</pre>
+ *
+ * @see OneToManyMapping
+ * @see CascadeComposite
+ * @see FetchTypeComposite
+ * @see JoinTableComposite
+ * @see OrderingComposite
+ * @see TargetEntityComposite
+ *
+ * @version 2.3
+ * @since 1.0
+ */
+public class OrmOneToManyMappingComposite 
+	extends AbstractOneToManyMappingComposite<OrmOneToManyMapping, OneToManyRelationshipReference>
+{
+	/**
+	 * Creates a new <code>OneToManyMappingComposite</code>.
+	 *
+	 * @param subjectHolder The holder of the subject <code>IOneToManyMapping</code>
+	 * @param parent The parent container
+	 * @param widgetFactory The factory used to create various common widgets
+	 */
+	public OrmOneToManyMappingComposite(PropertyValueModel<? extends OrmOneToManyMapping> subjectHolder,
+	                                 Composite parent,
+	                                 WidgetFactory widgetFactory) {
+
+		super(subjectHolder, parent, widgetFactory);
+	}
+
+	@Override
+	protected void initializeOneToManySection(Composite container) {
+		new TargetEntityComposite(this, container);
+		new OrmMappingNameChooser(this, getSubjectHolder(), container);
+		new FetchTypeComposite(this, container);
+		new CascadeComposite(this, buildCascadeHolder(), addSubPane(container, 5));
+	}
+}
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/orm/OrmOneToManyMappingUiDefinition.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/orm/OrmOneToManyMappingUiDefinition.java
new file mode 100644
index 0000000..54b7351
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/orm/OrmOneToManyMappingUiDefinition.java
@@ -0,0 +1,56 @@
+/*******************************************************************************
+ *  Copyright (c) 2008, 2009  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.ui.internal.details.orm;
+
+import org.eclipse.jpt.core.context.PersistentAttribute;
+import org.eclipse.jpt.core.context.orm.OrmOneToManyMapping;
+import org.eclipse.jpt.ui.WidgetFactory;
+import org.eclipse.jpt.ui.details.JpaComposite;
+import org.eclipse.jpt.ui.details.orm.OrmAttributeMappingUiDefinition;
+import org.eclipse.jpt.ui.details.orm.OrmXmlUiFactory;
+import org.eclipse.jpt.ui.internal.details.AbstractOneToManyMappingUiDefinition;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+public class OrmOneToManyMappingUiDefinition
+	extends AbstractOneToManyMappingUiDefinition<PersistentAttribute, OrmOneToManyMapping>
+	implements OrmAttributeMappingUiDefinition<OrmOneToManyMapping>
+{
+	// singleton
+	private static final OrmOneToManyMappingUiDefinition INSTANCE = 
+			new OrmOneToManyMappingUiDefinition();
+	
+	
+	/**
+	 * Return the singleton.
+	 */
+	public static OrmAttributeMappingUiDefinition<OrmOneToManyMapping> instance() {
+		return INSTANCE;
+	}
+	
+	
+	/**
+	 * Ensure single instance.
+	 */
+	private OrmOneToManyMappingUiDefinition() {
+		super();
+	}
+	
+	
+	public JpaComposite buildAttributeMappingComposite(
+			OrmXmlUiFactory factory,
+			PropertyValueModel<OrmOneToManyMapping> subjectHolder,
+			Composite parent,
+			WidgetFactory widgetFactory) {
+		
+		return factory.createOrmOneToManyMappingComposite(subjectHolder, parent, widgetFactory);
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/orm/OrmOneToOneMappingComposite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/orm/OrmOneToOneMappingComposite.java
new file mode 100644
index 0000000..10b423e
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/orm/OrmOneToOneMappingComposite.java
@@ -0,0 +1,92 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 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.ui.internal.details.orm;
+
+import org.eclipse.jpt.core.context.OneToOneMapping;
+import org.eclipse.jpt.core.context.OneToOneRelationshipReference;
+import org.eclipse.jpt.core.context.orm.OrmOneToOneMapping;
+import org.eclipse.jpt.ui.WidgetFactory;
+import org.eclipse.jpt.ui.internal.details.AbstractOneToOneMappingComposite;
+import org.eclipse.jpt.ui.internal.details.CascadeComposite;
+import org.eclipse.jpt.ui.internal.details.FetchTypeComposite;
+import org.eclipse.jpt.ui.internal.details.OptionalComposite;
+import org.eclipse.jpt.ui.internal.details.TargetEntityComposite;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * Here the layout of this pane:
+ * <pre>
+ * -----------------------------------------------------------------------------
+ * | ------------------------------------------------------------------------- |
+ * | |                                                                       | |
+ * | | TargetEntityComposite                                                 | |
+ * | |                                                                       | |
+ * | ------------------------------------------------------------------------- |
+ * | ------------------------------------------------------------------------- |
+ * | |                                                                       | |
+ * | | JoiningStrategyComposite                                              | |
+ * | |                                                                       | |
+ * | ------------------------------------------------------------------------- |
+ * | ------------------------------------------------------------------------- |
+ * | |                                                                       | |
+ * | | FetchTypeComposite                                                    | |
+ * | |                                                                       | |
+ * | ------------------------------------------------------------------------- |
+ * | ------------------------------------------------------------------------- |
+ * | |                                                                       | |
+ * | | OptionalComposite                                                     | |
+ * | |                                                                       | |
+ * | ------------------------------------------------------------------------- |
+ * | ------------------------------------------------------------------------- |
+ * | |                                                                       | |
+ * | | CascadeComposite                                                      | |
+ * | |                                                                       | |
+ * | ------------------------------------------------------------------------- |
+ * -----------------------------------------------------------------------------</pre>
+ *
+ * @see OneToOneMapping
+ * @see TargetEntityComposite
+ * @see JoiningStrategyComposite
+ * @see FetchTypeComposite
+ * @see OptionalComposite
+ * @see CascadeComposite
+ *
+ * @version 2.3
+ * @since 1.0
+ */
+public class OrmOneToOneMappingComposite 
+	extends AbstractOneToOneMappingComposite<OrmOneToOneMapping, OneToOneRelationshipReference>
+{
+	/**
+	 * Creates a new <code>OneToOneMappingComposite</code>.
+	 *
+	 * @param subjectHolder The holder of the subject <code>IOneToOneMapping</code>
+	 * @param parent The parent container
+	 * @param widgetFactory The factory used to create various common widgets
+	 */
+	public OrmOneToOneMappingComposite(PropertyValueModel<? extends OrmOneToOneMapping> subjectHolder,
+	                                Composite parent,
+	                                WidgetFactory widgetFactory) {
+
+		super(subjectHolder, parent, widgetFactory);
+	}	
+
+	@Override
+	protected void initializeOneToOneSection(Composite container) {
+		new TargetEntityComposite(this, container);
+		new OrmMappingNameChooser(this, getSubjectHolder(), container);
+		new FetchTypeComposite(this, container);
+		new OptionalComposite(this, container);
+		new CascadeComposite(this, buildCascadeHolder(),  addSubPane(container, 5));
+	}
+
+
+}
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/orm/OrmOneToOneMappingUiDefinition.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/orm/OrmOneToOneMappingUiDefinition.java
new file mode 100644
index 0000000..7deb029
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/orm/OrmOneToOneMappingUiDefinition.java
@@ -0,0 +1,56 @@
+/*******************************************************************************
+ *  Copyright (c) 2008, 2009  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.ui.internal.details.orm;
+
+import org.eclipse.jpt.core.context.PersistentAttribute;
+import org.eclipse.jpt.core.context.orm.OrmOneToOneMapping;
+import org.eclipse.jpt.ui.WidgetFactory;
+import org.eclipse.jpt.ui.details.JpaComposite;
+import org.eclipse.jpt.ui.details.orm.OrmAttributeMappingUiDefinition;
+import org.eclipse.jpt.ui.details.orm.OrmXmlUiFactory;
+import org.eclipse.jpt.ui.internal.details.AbstractOneToOneMappingUiDefinition;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+public class OrmOneToOneMappingUiDefinition
+	extends AbstractOneToOneMappingUiDefinition<PersistentAttribute, OrmOneToOneMapping>
+	implements OrmAttributeMappingUiDefinition<OrmOneToOneMapping>
+{
+	// singleton
+	private static final OrmOneToOneMappingUiDefinition INSTANCE = 
+			new OrmOneToOneMappingUiDefinition();
+	
+	
+	/**
+	 * Return the singleton.
+	 */
+	public static OrmAttributeMappingUiDefinition<OrmOneToOneMapping> instance() {
+		return INSTANCE;
+	}
+	
+	
+	/**
+	 * Ensure single instance.
+	 */
+	private OrmOneToOneMappingUiDefinition() {
+		super();
+	}
+	
+	
+	public JpaComposite buildAttributeMappingComposite(
+			OrmXmlUiFactory factory,
+			PropertyValueModel<OrmOneToOneMapping> subjectHolder,
+			Composite parent,
+			WidgetFactory widgetFactory) {
+		
+		return factory.createOrmOneToOneMappingComposite(subjectHolder, parent, widgetFactory);
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/orm/OrmPackageChooser.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/orm/OrmPackageChooser.java
new file mode 100644
index 0000000..ffd3970
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/orm/OrmPackageChooser.java
@@ -0,0 +1,98 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2010 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.ui.internal.details.orm;
+
+import org.eclipse.jpt.core.JpaProject;
+import org.eclipse.jpt.core.context.orm.EntityMappings;
+import org.eclipse.jpt.ui.internal.widgets.PackageChooserPane;
+import org.eclipse.jpt.ui.internal.widgets.Pane;
+import org.eclipse.jpt.utility.internal.model.value.PropertyAspectAdapter;
+import org.eclipse.jpt.utility.model.value.WritablePropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * Here the layout of this pane:
+ * <pre>
+ * -----------------------------------------------------------------------------
+ * |                                                                           |
+ * | PackageChooserPane                                                        |
+ * |                                                                           |
+ * -----------------------------------------------------------------------------</pre>
+ *
+ * @see EntityMappings
+ * @see EntityMappingsDetailsPage - The parent container
+ * @see PackageChooserPane
+ *
+ * @version 2.0
+ * @since 2.0
+ */
+public class OrmPackageChooser extends Pane<EntityMappings>
+{
+	/**
+	 * Creates a new <code>XmlPackageChooser</code>.
+	 *
+	 * @param parentPane The parent controller of this one
+	 * @param parent The parent container
+	 */
+	public OrmPackageChooser(Pane<? extends EntityMappings> parentPane,
+	                         Composite parent) {
+
+		super(parentPane, parent);
+	}
+
+	/*
+	 * (non-Javadoc)
+	 */
+	@Override
+	protected void initializeLayout(Composite container) {
+
+		addPackageChooserPane(container);
+	}
+
+	private void addPackageChooserPane(Composite container) {
+
+		new PackageChooserPane<EntityMappings>(this, container) {
+			@Override
+			protected WritablePropertyValueModel<String> buildTextHolder() {
+				return new PropertyAspectAdapter<EntityMappings, String>(getSubjectHolder(), EntityMappings.PACKAGE_PROPERTY) {
+					@Override
+					protected String buildValue_() {
+						return subject.getPackage();
+					}
+
+					@Override
+					protected void setValue_(String value) {
+						subject.setPackage(value == "" ? null : value); //$NON-NLS-1$
+					}
+				};
+			}
+
+			@Override
+			protected String getLabelText() {
+				return JptUiDetailsOrmMessages.EntityMappingsDetailsPage_package;
+			}
+
+			@Override
+			protected JpaProject getJpaProject() {
+				return getSubject().getJpaProject();
+			}
+
+			@Override
+			protected String getPackageName() {
+				return getSubject().getPackage();
+			}
+
+			@Override
+			protected void setPackageName(String packageName) {
+				getSubject().setPackage(packageName);
+			}
+		};
+	}
+}
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/orm/OrmPersistentAttributeDetailsPage.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/orm/OrmPersistentAttributeDetailsPage.java
new file mode 100644
index 0000000..0f3a580
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/orm/OrmPersistentAttributeDetailsPage.java
@@ -0,0 +1,112 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2010 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.ui.internal.details.orm;
+
+import java.util.ArrayList;
+import org.eclipse.jpt.core.context.PersistentAttribute;
+import org.eclipse.jpt.core.context.orm.OrmPersistentAttribute;
+import org.eclipse.jpt.ui.WidgetFactory;
+import org.eclipse.jpt.ui.details.JpaComposite;
+import org.eclipse.jpt.ui.internal.details.PersistentAttributeDetailsPage;
+import org.eclipse.jpt.ui.internal.details.PersistentAttributeMapAsComposite;
+import org.eclipse.jpt.ui.internal.util.PaneEnabler;
+import org.eclipse.jpt.ui.internal.widgets.Pane;
+import org.eclipse.jpt.utility.internal.model.value.TransformationPropertyValueModel;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * The default implementation of the details page used for the XML persistent
+ * attribute.
+ * <p>
+ * Here the layout of this pane:
+ * <pre>
+ * -----------------------------------------------------------------------------
+ * | ------------------------------------------------------------------------- |
+ * | |                                                                       | |
+ * | | OrmPersistentAttributeMapAsComposite                                  | |
+ * | |                                                                       | |
+ * | ------------------------------------------------------------------------- |
+ * | ------------------------------------------------------------------------- |
+ * | |                                                                       | |
+ * | | Attribute mapping pane                                                | |
+ * | |                                                                       | |
+ * | ------------------------------------------------------------------------- |
+ * -----------------------------------------------------------------------------</pre>
+ *
+ * @see OrmPersistentAttribute
+ * @see OrmPersistentAttributeMapAsComposite
+ *
+ * @version 2.3
+ * @since 2.0
+ */
+public class OrmPersistentAttributeDetailsPage extends PersistentAttributeDetailsPage<OrmPersistentAttribute>
+{
+	/**
+	 * Creates a new <code>OrmPersistentAttributeDetailsPage</code>.
+	 *
+	 * @param parent The parent container
+	 * @param widgetFactory The factory used to create various common widgets
+	 */
+	public OrmPersistentAttributeDetailsPage(Composite parent,
+	                                         WidgetFactory widgetFactory) {
+
+		super(parent, widgetFactory);
+	}
+	
+	@Override
+	protected void initializeLayout(Composite container) {
+
+		ArrayList<Pane<?>> panes = new ArrayList<Pane<?>>(2);
+
+		// Map As composite
+		Pane<?> mapAsPane = buildMapAsPane(addSubPane(container, 0, 0, 5, 0));
+		panes.add(mapAsPane);
+
+		buildMappingPageBook(container);
+
+		installPaneEnabler(panes);
+	}
+	
+	protected Pane<PersistentAttribute> buildMapAsPane(Composite parent) {
+		return new PersistentAttributeMapAsComposite(this, parent);		
+	}
+	
+	private void installPaneEnabler(ArrayList<Pane<?>> panes) {
+		new PaneEnabler(buildPaneEnablerHolder(), panes);
+	}
+	
+	private PropertyValueModel<Boolean> buildPaneEnablerHolder() {
+		return new TransformationPropertyValueModel<OrmPersistentAttribute, Boolean>(getSubjectHolder()) {
+			@Override
+			protected Boolean transform_(OrmPersistentAttribute value) {
+				return Boolean.valueOf(!value.isVirtual());
+			}
+		};
+	}
+
+	
+	//TODO this probably needs to change and use a PaneEnabler instead.
+	@Override
+	protected JpaComposite getMappingComposite(String key) {
+		JpaComposite mappingComposite = super.getMappingComposite(key);
+		if (mappingComposite == null) {
+			return null;
+		}
+		boolean enabled = false;
+
+		if (getSubject() != null && getSubject().getParent() != null) {
+			enabled = !getSubject().isVirtual();
+		}
+
+		mappingComposite.enableWidgets(enabled);
+		return mappingComposite;
+	}
+}
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/orm/OrmPersistentAttributeDetailsProvider.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/orm/OrmPersistentAttributeDetailsProvider.java
new file mode 100644
index 0000000..e848ce8
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/orm/OrmPersistentAttributeDetailsProvider.java
@@ -0,0 +1,61 @@
+/*******************************************************************************
+ * Copyright (c) 2009 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.ui.internal.details.orm;
+
+import org.eclipse.jpt.core.JpaStructureNode;
+import org.eclipse.jpt.core.JptCorePlugin;
+import org.eclipse.jpt.core.context.orm.OrmPersistentAttribute;
+import org.eclipse.jpt.core.context.orm.OrmStructureNodes;
+import org.eclipse.jpt.ui.WidgetFactory;
+import org.eclipse.jpt.ui.details.JpaDetailsPage;
+import org.eclipse.jpt.ui.details.JpaDetailsProvider;
+import org.eclipse.jpt.utility.internal.StringTools;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * This provider is responsible for creating the {@link JpaDetailsPage}
+ * when the information comes from the XML file (either from the persistence
+ * configuration or from the Mappings Descriptor).
+ */
+public class OrmPersistentAttributeDetailsProvider
+	implements JpaDetailsProvider
+{
+	// singleton
+	private static final JpaDetailsProvider INSTANCE = new OrmPersistentAttributeDetailsProvider();
+	
+	
+	/**
+	 * Return the singleton
+	 */
+	public static JpaDetailsProvider instance() {
+		return INSTANCE;
+	}
+	
+	
+	/**
+	 * Enforce singleton usage
+	 */
+	private OrmPersistentAttributeDetailsProvider() {
+		super();
+	}
+	
+	
+	public boolean providesDetails(JpaStructureNode structureNode) {
+			return StringTools.stringsAreEqual(structureNode.getId(), OrmStructureNodes.PERSISTENT_ATTRIBUTE_ID)
+				&& structureNode.getResourceType().getContentType().isKindOf(JptCorePlugin.MAPPING_FILE_CONTENT_TYPE);
+	}
+	
+	public JpaDetailsPage<OrmPersistentAttribute> buildDetailsPage(
+			Composite parent,
+			WidgetFactory widgetFactory) {
+		
+		return new OrmPersistentAttributeDetailsPage(parent, widgetFactory);
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/orm/OrmPersistentTypeDetailsProvider.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/orm/OrmPersistentTypeDetailsProvider.java
new file mode 100644
index 0000000..668fd4e
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/orm/OrmPersistentTypeDetailsProvider.java
@@ -0,0 +1,62 @@
+/*******************************************************************************
+ * Copyright (c) 2009 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.ui.internal.details.orm;
+
+import org.eclipse.jpt.core.JpaStructureNode;
+import org.eclipse.jpt.core.JptCorePlugin;
+import org.eclipse.jpt.core.context.PersistentType;
+import org.eclipse.jpt.core.context.orm.OrmStructureNodes;
+import org.eclipse.jpt.ui.WidgetFactory;
+import org.eclipse.jpt.ui.details.JpaDetailsPage;
+import org.eclipse.jpt.ui.details.JpaDetailsProvider;
+import org.eclipse.jpt.ui.internal.details.PersistentTypeDetailsPage;
+import org.eclipse.jpt.utility.internal.StringTools;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * This provider is responsible for creating the {@link JpaDetailsPage}
+ * when the information comes from the XML file (either from the persistence
+ * configuration or from the Mappings Descriptor).
+ */
+public class OrmPersistentTypeDetailsProvider
+	implements JpaDetailsProvider
+{
+	// singleton
+	private static final JpaDetailsProvider INSTANCE = new OrmPersistentTypeDetailsProvider();
+	
+	
+	/**
+	 * Return the singleton
+	 */
+	public static JpaDetailsProvider instance() {
+		return INSTANCE;
+	}
+	
+	
+	/**
+	 * Enforce singleton usage
+	 */
+	private OrmPersistentTypeDetailsProvider() {
+		super();
+	}
+	
+	
+	public boolean providesDetails(JpaStructureNode structureNode) {
+		return StringTools.stringsAreEqual(structureNode.getId(), OrmStructureNodes.PERSISTENT_TYPE_ID)
+				&& structureNode.getResourceType().getContentType().isKindOf(JptCorePlugin.MAPPING_FILE_CONTENT_TYPE);
+	}
+	
+	public JpaDetailsPage<PersistentType> buildDetailsPage(
+			Composite parent,
+			WidgetFactory widgetFactory) {
+		
+		return new PersistentTypeDetailsPage(parent, widgetFactory);
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/orm/OrmPrimaryKeyJoinColumnsComposite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/orm/OrmPrimaryKeyJoinColumnsComposite.java
new file mode 100644
index 0000000..80e25cc
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/orm/OrmPrimaryKeyJoinColumnsComposite.java
@@ -0,0 +1,78 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2009 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.ui.internal.details.orm;
+
+import java.util.ListIterator;
+import org.eclipse.jpt.core.context.PrimaryKeyJoinColumn;
+import org.eclipse.jpt.core.context.orm.OrmEntity;
+import org.eclipse.jpt.core.context.orm.OrmPrimaryKeyJoinColumn;
+import org.eclipse.jpt.ui.internal.details.AbstractPrimaryKeyJoinColumnsComposite;
+import org.eclipse.jpt.ui.internal.widgets.Pane;
+import org.eclipse.jpt.utility.internal.model.value.ListAspectAdapter;
+import org.eclipse.jpt.utility.model.value.ListValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * @see OrmEntity
+ * @see OrmInheritanceComposite - The container of this pane
+ *
+ * @version 2.0
+ * @since 2.0
+ */
+public class OrmPrimaryKeyJoinColumnsComposite extends AbstractPrimaryKeyJoinColumnsComposite<OrmEntity>
+{
+
+	/**
+	 * Creates a new <code>OrmPrimaryKeyJoinColumnsComposite</code>.
+	 *
+	 * @param parentPane The parent controller of this one
+	 * @param parent The parent container
+	 */
+	public OrmPrimaryKeyJoinColumnsComposite(Pane<? extends OrmEntity> subjectHolder,
+	                                      Composite parent) {
+
+		super(subjectHolder, parent);
+	}
+	
+	@Override
+	protected ListValueModel<OrmPrimaryKeyJoinColumn> buildDefaultJoinColumnsListHolder() {
+		return new ListAspectAdapter<OrmEntity, OrmPrimaryKeyJoinColumn>(
+			getSubjectHolder(),
+			OrmEntity.DEFAULT_PRIMARY_KEY_JOIN_COLUMNS_LIST)
+		{
+			@Override
+			protected ListIterator<OrmPrimaryKeyJoinColumn> listIterator_() {
+				return subject.defaultPrimaryKeyJoinColumns();
+			}
+//TODO defaultPrimaryKeyJoinColumnsSize when I can change the API
+//			@Override
+//			protected int size_() {
+//				return subject.defaultPrimaryKeyJoinColumnsSize();
+//			}
+		};
+	}
+	
+	@Override
+	protected void switchDefaultToSpecified() {
+		ListIterator<OrmPrimaryKeyJoinColumn> defaultJoinColumns = getSubject().defaultPrimaryKeyJoinColumns();
+
+		int index = 0;
+		while (defaultJoinColumns.hasNext()) {
+			OrmPrimaryKeyJoinColumn defaultJoinColumn = defaultJoinColumns.next();
+			String columnName = defaultJoinColumn.getName();
+			String referencedColumnName = defaultJoinColumn.getReferencedColumnName();
+
+			PrimaryKeyJoinColumn pkJoinColumn = getSubject().addSpecifiedPrimaryKeyJoinColumn(index++);
+			pkJoinColumn.setSpecifiedName(columnName);
+			pkJoinColumn.setSpecifiedReferencedColumnName(referencedColumnName);
+		}
+	}
+	
+}
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/orm/OrmQueriesComposite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/orm/OrmQueriesComposite.java
new file mode 100644
index 0000000..f8f6b48
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/orm/OrmQueriesComposite.java
@@ -0,0 +1,94 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2009 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.ui.internal.details.orm;
+
+import org.eclipse.jpt.core.context.QueryContainer;
+import org.eclipse.jpt.core.context.orm.EntityMappings;
+import org.eclipse.jpt.ui.internal.details.QueriesComposite;
+import org.eclipse.jpt.ui.internal.util.PaneEnabler;
+import org.eclipse.jpt.ui.internal.widgets.Pane;
+import org.eclipse.jpt.utility.internal.model.value.PropertyAspectAdapter;
+import org.eclipse.jpt.utility.internal.model.value.TransformationPropertyValueModel;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * Here the layout of this pane:
+ * <pre>
+ * -----------------------------------------------------------------------------
+ * | ------------------------------------------------------------------------- |
+ * | |                                                                       | |
+ * | | QueriesComposite                                                      | |
+ * | |                                                                       | |
+ * | ------------------------------------------------------------------------- |
+ * -----------------------------------------------------------------------------</pre>
+ *
+ * @see EntityMappings
+ * @see EntityMappingsDetailsPage - The parent container
+ * @see QueriesComposite
+ *
+ * @version 2.0
+ * @since 2.0
+ */
+public class OrmQueriesComposite extends Pane<EntityMappings> {
+
+	/**
+	 * Creates a new <code>OrmQueriesComposite</code>.
+	 *
+	 * @param parentPane The parent container of this one
+	 * @param parent The parent container
+	 */
+	public OrmQueriesComposite(Pane<? extends EntityMappings> parentPane,
+	                           Composite parent) {
+
+		super(parentPane, parent, false);
+	}
+
+	private PropertyValueModel<Boolean> buildPaneEnablerHolder() {
+		return new TransformationPropertyValueModel<EntityMappings, Boolean>(getSubjectHolder()) {
+			@Override
+			protected Boolean transform(EntityMappings value) {
+				return (value != null);
+			}
+		};
+	}
+
+	@Override
+	protected void initializeLayout(Composite container) {
+
+		container = this.addCollapsibleSection(
+			container,
+			JptUiDetailsOrmMessages.OrmQueriesComposite_groupBox
+		);
+
+		QueriesComposite queriesComposite = this.buildQueriesComposite(container, this.buildQueryContainerHolder());
+
+		this.installPaneEnabler(queriesComposite);
+	}
+
+	protected QueriesComposite buildQueriesComposite(Composite container, PropertyValueModel<QueryContainer> queryContainerHolder) {
+		return new QueriesComposite(this, queryContainerHolder, container);
+	}
+
+	private PropertyValueModel<QueryContainer> buildQueryContainerHolder() {
+		return new PropertyAspectAdapter<EntityMappings, QueryContainer>(getSubjectHolder()) {
+			@Override
+			protected QueryContainer buildValue_() {
+				return this.subject.getQueryContainer();
+			}
+		};
+	}
+	private void installPaneEnabler(QueriesComposite queriesComposite) {
+		new PaneEnabler(
+			buildPaneEnablerHolder(),
+			queriesComposite
+		);
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/orm/OrmSecondaryTablesComposite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/orm/OrmSecondaryTablesComposite.java
new file mode 100644
index 0000000..31c6fee
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/orm/OrmSecondaryTablesComposite.java
@@ -0,0 +1,210 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2010 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.ui.internal.details.orm;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.ListIterator;
+
+import org.eclipse.jpt.core.context.Entity;
+import org.eclipse.jpt.core.context.SecondaryTable;
+import org.eclipse.jpt.core.context.Table;
+import org.eclipse.jpt.core.context.orm.OrmEntity;
+import org.eclipse.jpt.core.context.orm.OrmSecondaryTable;
+import org.eclipse.jpt.ui.WidgetFactory;
+import org.eclipse.jpt.ui.internal.JpaHelpContextIds;
+import org.eclipse.jpt.ui.internal.details.AbstractSecondaryTablesComposite;
+import org.eclipse.jpt.ui.internal.details.JptUiDetailsMessages;
+import org.eclipse.jpt.ui.internal.details.PrimaryKeyJoinColumnsInSecondaryTableComposite;
+import org.eclipse.jpt.ui.internal.details.SecondaryTableDialog;
+import org.eclipse.jpt.ui.internal.util.PaneEnabler;
+import org.eclipse.jpt.ui.internal.widgets.AddRemoveListPane;
+import org.eclipse.jpt.ui.internal.widgets.Pane;
+import org.eclipse.jpt.utility.internal.model.value.CompositeListValueModel;
+import org.eclipse.jpt.utility.internal.model.value.ItemPropertyListValueModelAdapter;
+import org.eclipse.jpt.utility.internal.model.value.ListAspectAdapter;
+import org.eclipse.jpt.utility.internal.model.value.ListPropertyValueModelAdapter;
+import org.eclipse.jpt.utility.model.value.ListValueModel;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.jpt.utility.model.value.WritablePropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * Here the layout of this pane:
+ * <pre>
+ * -----------------------------------------------------------------------------
+ * | ------------------------------------------------------------------------- |
+ * | |                                                                       | |
+ * | | AddRemoveListPane                                                     | |
+ * | |                                                                       | |
+ * | ------------------------------------------------------------------------- |
+ * | ------------------------------------------------------------------------- |
+ * | |                                                                       | |
+ * | | PrimaryKeyJoinColumnsInSecondaryTableComposite                        | |
+ * | |                                                                       | |
+ * | ------------------------------------------------------------------------- |
+ * -----------------------------------------------------------------------------</pre>
+ *
+ * @see OrmEntity
+ * @see OrmEntityComposite - The container of this pane
+ * @see AddRemoveListPane
+ * @see PrimaryKeyJoinColumnsInSecondaryTableComposite
+ *
+ * @version 2.0
+ * @since 1.0
+ */
+public class OrmSecondaryTablesComposite extends AbstractSecondaryTablesComposite<OrmEntity>
+{
+	/**
+	 * Creates a new <code>OrmSecondaryTablesComposite</code>.
+	 *
+	 * @param parentPane The parent container of this one
+	 * @param parent The parent container
+	 */
+	public OrmSecondaryTablesComposite(Pane<? extends OrmEntity> parentPane,
+	                                   Composite parent) {
+
+		super(parentPane, parent);
+	}
+
+	/**
+	 * Creates a new <code>SecondaryTablesComposite</code>.
+	 *
+	 * @param subjectHolder The holder of the subject <code>IEntity</code>
+	 * @param parent The parent container
+	 * @param widgetFactory The factory used to create various common widgets
+	 */
+	public OrmSecondaryTablesComposite(PropertyValueModel<? extends OrmEntity> subjectHolder,
+	                                Composite parent,
+	                                WidgetFactory widgetFactory) {
+
+		super(subjectHolder, parent, widgetFactory);
+	}
+
+	private WritablePropertyValueModel<Boolean> buildDefineInXmlHolder() {
+		return new DefineInXmlHolder();
+	}
+
+	private ListValueModel<OrmSecondaryTable> buildSecondaryTablesListHolder() {
+		List<ListValueModel<OrmSecondaryTable>> list = new ArrayList<ListValueModel<OrmSecondaryTable>>();
+		list.add(buildSpecifiedSecondaryTablesListHolder());
+		list.add(buildVirtualSecondaryTablesListHolder());
+		return new CompositeListValueModel<ListValueModel<OrmSecondaryTable>, OrmSecondaryTable>(list);
+	}
+
+	private ListValueModel<OrmSecondaryTable> buildSecondaryTablesListModel() {
+		return new ItemPropertyListValueModelAdapter<OrmSecondaryTable>(buildSecondaryTablesListHolder(),
+			Table.SPECIFIED_NAME_PROPERTY);
+	}
+
+	private ListValueModel<OrmSecondaryTable> buildSpecifiedSecondaryTablesListHolder() {
+		return new ListAspectAdapter<OrmEntity, OrmSecondaryTable>(getSubjectHolder(), Entity.SPECIFIED_SECONDARY_TABLES_LIST) {
+			@Override
+			protected ListIterator<OrmSecondaryTable> listIterator_() {
+				return subject.specifiedSecondaryTables();
+			}
+
+			@Override
+			protected int size_() {
+				return subject.specifiedSecondaryTablesSize();
+			}
+		};
+	}
+
+	private ListValueModel<OrmSecondaryTable> buildVirtualSecondaryTablesListHolder() {
+		return new ListAspectAdapter<OrmEntity, OrmSecondaryTable>(getSubjectHolder(), OrmEntity.VIRTUAL_SECONDARY_TABLES_LIST) {
+			@Override
+			protected ListIterator<OrmSecondaryTable> listIterator_() {
+				return subject.virtualSecondaryTables();
+			}
+
+			@Override
+			protected int size_() {
+				return subject.virtualSecondaryTablesSize();
+			}
+		};
+	}
+
+	@Override
+	protected void initializeLayout(Composite container) {
+
+		int groupBoxMargin = getGroupBoxMargin();
+
+		WritablePropertyValueModel<SecondaryTable> secondaryTableHolder =
+			buildSecondaryTableHolder();
+
+		WritablePropertyValueModel<Boolean> defineInXmlHolder =
+			buildDefineInXmlHolder();
+
+		// Override Define In XML check box
+		addCheckBox(
+			addSubPane(container, 0, groupBoxMargin),
+			JptUiDetailsMessages.OrmSecondaryTablesComposite_defineInXml,
+			defineInXmlHolder,
+			null
+		);
+
+		// Secondary Tables add/remove list pane
+		AddRemoveListPane<Entity> listPane = new AddRemoveListPane<Entity>(
+			this,
+			addSubPane(container, 0, groupBoxMargin, 0, groupBoxMargin),
+			buildSecondaryTablesAdapter(),
+			buildSecondaryTablesListModel(),
+			secondaryTableHolder,
+			buildSecondaryTableLabelProvider(),
+			JpaHelpContextIds.MAPPING_JOIN_TABLE_COLUMNS//TODO need a help context id for this
+		);
+
+		installListPaneEnabler(defineInXmlHolder, listPane);
+
+		// Primary Key Join Columns pane
+		new PrimaryKeyJoinColumnsInSecondaryTableComposite(
+			this,
+			secondaryTableHolder,
+			container
+		);
+	}
+	
+	private void installListPaneEnabler(WritablePropertyValueModel<Boolean> defineInXmlHolder,
+	                                    AddRemoveListPane<Entity> listPane) {
+
+		new PaneEnabler(defineInXmlHolder, listPane);
+	}
+	
+	@Override
+	protected SecondaryTableDialog buildSecondaryTableDialogForAdd() {
+		// defaultSchema and defaultCatalog should not be taken from the Table in this case.  
+		// The table default schema could be what is the specified schema on the java table.
+		return new SecondaryTableDialog(
+			getShell(), getSubject().getJpaProject(), 
+			getSubject().getMappingFileRoot().getCatalog(), 
+			getSubject().getMappingFileRoot().getSchema());
+	}
+
+	private class DefineInXmlHolder extends ListPropertyValueModelAdapter<Boolean>
+		implements WritablePropertyValueModel<Boolean> {
+
+		public DefineInXmlHolder() {
+			super(buildVirtualSecondaryTablesListHolder());
+		}
+
+		@Override
+		protected Boolean buildValue() {
+			if (getSubject() == null) {
+				return Boolean.FALSE;
+			}
+			return Boolean.valueOf(getSubject().secondaryTablesDefinedInXml());
+		}
+
+		public void setValue(Boolean value) {
+			getSubject().setSecondaryTablesDefinedInXml(value.booleanValue());
+		}
+	}
+}
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/orm/OrmTransientMappingUiDefinition.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/orm/OrmTransientMappingUiDefinition.java
new file mode 100644
index 0000000..a397728
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/orm/OrmTransientMappingUiDefinition.java
@@ -0,0 +1,56 @@
+/*******************************************************************************
+ *  Copyright (c) 2008, 2009  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.ui.internal.details.orm;
+
+import org.eclipse.jpt.core.context.PersistentAttribute;
+import org.eclipse.jpt.core.context.orm.OrmTransientMapping;
+import org.eclipse.jpt.ui.WidgetFactory;
+import org.eclipse.jpt.ui.details.JpaComposite;
+import org.eclipse.jpt.ui.details.orm.OrmAttributeMappingUiDefinition;
+import org.eclipse.jpt.ui.details.orm.OrmXmlUiFactory;
+import org.eclipse.jpt.ui.internal.details.AbstractTransientMappingUiDefinition;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+public class OrmTransientMappingUiDefinition
+	extends AbstractTransientMappingUiDefinition<PersistentAttribute, OrmTransientMapping>
+	implements OrmAttributeMappingUiDefinition<OrmTransientMapping>
+{
+	// singleton
+	private static final OrmTransientMappingUiDefinition INSTANCE = 
+			new OrmTransientMappingUiDefinition();
+	
+	
+	/**
+	 * Return the singleton.
+	 */
+	public static OrmAttributeMappingUiDefinition<OrmTransientMapping> instance() {
+		return INSTANCE;
+	}
+	
+	
+	/**
+	 * Ensure single instance.
+	 */
+	private OrmTransientMappingUiDefinition() {
+		super();
+	}
+	
+	
+	public JpaComposite buildAttributeMappingComposite(
+			OrmXmlUiFactory factory,
+			PropertyValueModel<OrmTransientMapping> subjectHolder,
+			Composite parent,
+			WidgetFactory widgetFactory) {
+		
+		return factory.createOrmTransientMappingComposite(subjectHolder, parent, widgetFactory);
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/orm/OrmVersionMappingComposite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/orm/OrmVersionMappingComposite.java
new file mode 100644
index 0000000..c2ae64a
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/orm/OrmVersionMappingComposite.java
@@ -0,0 +1,41 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2010 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.ui.internal.details.orm;
+
+import org.eclipse.jpt.core.context.orm.OrmVersionMapping;
+import org.eclipse.jpt.ui.WidgetFactory;
+import org.eclipse.jpt.ui.internal.details.AbstractVersionMappingComposite;
+import org.eclipse.jpt.ui.internal.details.ColumnComposite;
+import org.eclipse.jpt.ui.internal.details.orm.OrmMappingNameChooser;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+public class OrmVersionMappingComposite extends AbstractVersionMappingComposite<OrmVersionMapping>
+{
+	/**
+	 * Creates a new <code>EclipseLinkOrmVersionMappingComposite</code>.
+	 *
+	 * @param subjectHolder The holder of the subject <code>VersionMapping</code>
+	 * @param parent The parent container
+	 * @param widgetFactory The factory used to create various common widgets
+	 */
+	public OrmVersionMappingComposite(PropertyValueModel<? extends OrmVersionMapping> subjectHolder,
+	                               Composite parent,
+	                               WidgetFactory widgetFactory) {
+
+		super(subjectHolder, parent, widgetFactory);
+	}
+
+	@Override
+	protected void initializeVersionSection(Composite container) {
+		new ColumnComposite(this, buildColumnHolder(), container);
+		new OrmMappingNameChooser(this, getSubjectHolder(), container);
+	}
+}
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/orm/OrmVersionMappingUiDefinition.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/orm/OrmVersionMappingUiDefinition.java
new file mode 100644
index 0000000..e980711
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/orm/OrmVersionMappingUiDefinition.java
@@ -0,0 +1,56 @@
+/*******************************************************************************
+ *  Copyright (c) 2008, 2009  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.ui.internal.details.orm;
+
+import org.eclipse.jpt.core.context.PersistentAttribute;
+import org.eclipse.jpt.core.context.orm.OrmVersionMapping;
+import org.eclipse.jpt.ui.WidgetFactory;
+import org.eclipse.jpt.ui.details.JpaComposite;
+import org.eclipse.jpt.ui.details.orm.OrmAttributeMappingUiDefinition;
+import org.eclipse.jpt.ui.details.orm.OrmXmlUiFactory;
+import org.eclipse.jpt.ui.internal.details.AbstractVersionMappingUiDefinition;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+public class OrmVersionMappingUiDefinition
+	extends AbstractVersionMappingUiDefinition<PersistentAttribute, OrmVersionMapping>
+	implements OrmAttributeMappingUiDefinition<OrmVersionMapping>
+{
+	// singleton
+	private static final OrmVersionMappingUiDefinition INSTANCE = 
+			new OrmVersionMappingUiDefinition();
+	
+	
+	/**
+	 * Return the singleton.
+	 */
+	public static OrmAttributeMappingUiDefinition<OrmVersionMapping> instance() {
+		return INSTANCE;
+	}
+	
+	
+	/**
+	 * Ensure single instance.
+	 */
+	private OrmVersionMappingUiDefinition() {
+		super();
+	}
+	
+	
+	public JpaComposite buildAttributeMappingComposite(
+			OrmXmlUiFactory factory,
+			PropertyValueModel<OrmVersionMapping> subjectHolder,
+			Composite parent,
+			WidgetFactory widgetFactory) {
+		
+		return factory.createOrmVersionMappingComposite(subjectHolder, parent, widgetFactory);
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/orm/OrmXmlUiDefinition.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/orm/OrmXmlUiDefinition.java
new file mode 100644
index 0000000..d94580c
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/orm/OrmXmlUiDefinition.java
@@ -0,0 +1,84 @@
+/*******************************************************************************
+ *  Copyright (c) 2009  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.ui.internal.details.orm;
+
+import java.util.List;
+import org.eclipse.jpt.core.JpaResourceType;
+import org.eclipse.jpt.core.JptCorePlugin;
+import org.eclipse.jpt.core.context.AttributeMapping;
+import org.eclipse.jpt.core.context.TypeMapping;
+import org.eclipse.jpt.ui.ResourceUiDefinition;
+import org.eclipse.jpt.ui.details.orm.OrmAttributeMappingUiDefinition;
+import org.eclipse.jpt.ui.details.orm.OrmTypeMappingUiDefinition;
+import org.eclipse.jpt.ui.details.orm.OrmXmlUiFactory;
+import org.eclipse.jpt.ui.internal.structure.OrmResourceModelStructureProvider;
+import org.eclipse.jpt.ui.structure.JpaStructureProvider;
+
+public class OrmXmlUiDefinition extends AbstractOrmXmlResourceUiDefinition
+{
+	// singleton
+	private static final ResourceUiDefinition INSTANCE = new OrmXmlUiDefinition();
+	
+	
+	/**
+	 * Return the singleton
+	 */
+	public static ResourceUiDefinition instance() {
+		return INSTANCE;
+	}
+	
+	
+	/**
+	 * Enforce singleton usage
+	 */
+	private OrmXmlUiDefinition() {
+		super();
+	}
+	
+	
+	@Override
+	protected OrmXmlUiFactory buildOrmXmlUiFactory() {
+		return new GenericOrmXmlUiFactory();
+	}
+	
+	public boolean providesUi(JpaResourceType resourceType) {
+		return resourceType.equals(JptCorePlugin.ORM_XML_1_0_RESOURCE_TYPE);
+	}
+	
+	public JpaStructureProvider getStructureProvider() {
+		return OrmResourceModelStructureProvider.instance();
+	}
+	
+	@Override
+	protected void addOrmAttributeMappingUiDefinitionsTo(
+			List<OrmAttributeMappingUiDefinition<? extends AttributeMapping>> definitions) {
+		
+		definitions.add(OrmIdMappingUiDefinition.instance());
+		definitions.add(OrmEmbeddedIdMappingUiDefinition.instance());
+		definitions.add(OrmBasicMappingUiDefinition.instance());
+		definitions.add(OrmVersionMappingUiDefinition.instance());
+		definitions.add(OrmManyToOneMappingUiDefinition.instance());
+		definitions.add(OrmOneToManyMappingUiDefinition.instance());
+		definitions.add(OrmOneToOneMappingUiDefinition.instance());
+		definitions.add(OrmManyToManyMappingUiDefinition.instance());
+		definitions.add(OrmEmbeddedMappingUiDefinition.instance());
+		definitions.add(OrmTransientMappingUiDefinition.instance());
+	}
+	
+	@Override
+	protected void addOrmTypeMappingUiDefinitionsTo(
+			List<OrmTypeMappingUiDefinition<? extends TypeMapping>> definitions) {
+		
+		definitions.add(OrmEntityUiDefinition.instance());
+		definitions.add(OrmMappedSuperclassUiDefinition.instance());
+		definitions.add(OrmEmbeddableUiDefinition.instance());
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/orm/PersistenceUnitMetadataComposite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/orm/PersistenceUnitMetadataComposite.java
new file mode 100644
index 0000000..c2a4f10
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/orm/PersistenceUnitMetadataComposite.java
@@ -0,0 +1,303 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2010 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.ui.internal.details.orm;
+
+import java.util.Collection;
+
+import org.eclipse.jpt.core.JptCorePlugin;
+import org.eclipse.jpt.core.context.AccessType;
+import org.eclipse.jpt.core.context.orm.OrmPersistenceUnitDefaults;
+import org.eclipse.jpt.core.context.orm.PersistenceUnitMetadata;
+import org.eclipse.jpt.core.jpa2.context.orm.OrmPersistenceUnitDefaults2_0;
+import org.eclipse.jpt.db.SchemaContainer;
+import org.eclipse.jpt.ui.internal.JpaHelpContextIds;
+import org.eclipse.jpt.ui.internal.details.db.CatalogCombo;
+import org.eclipse.jpt.ui.internal.details.db.SchemaCombo;
+import org.eclipse.jpt.ui.internal.jpa2.Jpa2_0ProjectFlagModel;
+import org.eclipse.jpt.ui.internal.utility.swt.SWTTools;
+import org.eclipse.jpt.ui.internal.widgets.EnumFormComboViewer;
+import org.eclipse.jpt.ui.internal.widgets.Pane;
+import org.eclipse.jpt.utility.internal.model.value.PropertyAspectAdapter;
+import org.eclipse.jpt.utility.internal.model.value.TransformationPropertyValueModel;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.jpt.utility.model.value.WritablePropertyValueModel;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * Here the layout of this pane:
+ * <pre>
+ * -----------------------------------------------------------------------------
+ * |                                                                           |
+ * | - Persistence Unit ------------------------------------------------------ |
+ * |                                                                           |
+ * | x XML Mapping Metadata Complete                                           |
+ * |                                                                           |
+ * | x Cascade Persist                                                         |
+ * |                                                                           |
+ * |              ------------------------------------------------------------ |
+ * | Schema:      | SchemaCombo                                              | |
+ * |              ------------------------------------------------------------ |
+ * |              ------------------------------------------------------------ |
+ * | Catalog:     | CatalogCombo                                             | |
+ * |              ------------------------------------------------------------ |
+ * |              ------------------------------------------------------------ |
+ * | Access Type: |                                                        |v| |
+ * |              ------------------------------------------------------------ |
+ * -----------------------------------------------------------------------------</pre>
+ *
+ * @see PersistenceUnitMetadata
+ * @see OrmPersistenceUnitDefaults
+ * @see EntityMappingsDetailsPage - The parent container
+ * @see CatalogCombo
+ * @see SchemaCombo
+ * @see EnumFormComboViewer
+ *
+ * @version 2.0
+ * @since 2.0
+ */
+public class PersistenceUnitMetadataComposite extends Pane<PersistenceUnitMetadata>
+{
+	/**
+	 * Creates a new <code>PersistenceUnitMetadataComposite</code>.
+	 *
+	 * @param parentPane The parent container of this one
+	 * @param subjectHolder The holder of this pane's subject
+	 * @param parent The parent container
+	 */
+	public PersistenceUnitMetadataComposite(Pane<?> parentPane,
+	                                        PropertyValueModel<? extends PersistenceUnitMetadata> subjectHolder,
+	                                        Composite parent) {
+
+		super(parentPane, subjectHolder, parent, false);
+	}
+
+	private EnumFormComboViewer<OrmPersistenceUnitDefaults, AccessType> addAccessTypeCombo(Composite container) {
+
+		return new EnumFormComboViewer<OrmPersistenceUnitDefaults, AccessType>(this, buildPersistenceUnitDefaultsHolder(), container) {
+
+			@Override
+			protected void addPropertyNames(Collection<String> propertyNames) {
+				super.addPropertyNames(propertyNames);
+				propertyNames.add(OrmPersistenceUnitDefaults.ACCESS_PROPERTY);
+			}
+
+			@Override
+			protected AccessType[] getChoices() {
+				return AccessType.values();
+			}
+
+			@Override
+			protected AccessType getDefaultValue() {
+				return null;
+			}
+
+			@Override
+			protected String displayString(AccessType value) {
+				return buildDisplayString(
+					JptUiDetailsOrmMessages.class,
+					PersistenceUnitMetadataComposite.this,
+					value
+				);
+			}
+
+			@Override
+			protected AccessType getValue() {
+				return getSubject().getAccess();
+			}
+
+			@Override
+			protected void setValue(AccessType value) {
+				getSubject().setAccess(value);
+			}
+		};
+	}
+
+	private WritablePropertyValueModel<Boolean> buildCascadePersistHolder() {
+		return new PropertyAspectAdapter<OrmPersistenceUnitDefaults, Boolean>(buildPersistenceUnitDefaultsHolder(), OrmPersistenceUnitDefaults.CASCADE_PERSIST_PROPERTY) {
+			@Override
+			protected Boolean buildValue_() {
+				return Boolean.valueOf(this.subject.isCascadePersist());
+			}
+
+			@Override
+			protected void setValue_(Boolean value) {
+				this.subject.setCascadePersist(value.booleanValue());
+			}
+		};
+	}
+
+	private CatalogCombo<OrmPersistenceUnitDefaults> addCatalogCombo(Composite container) {
+
+		return new CatalogCombo<OrmPersistenceUnitDefaults>(this, buildPersistenceUnitDefaultsHolder(), container) {
+
+			@Override
+			protected void addPropertyNames(Collection<String> propertyNames) {
+				super.addPropertyNames(propertyNames);
+				propertyNames.add(OrmPersistenceUnitDefaults.DEFAULT_CATALOG_PROPERTY);
+				propertyNames.add(OrmPersistenceUnitDefaults.SPECIFIED_CATALOG_PROPERTY);
+			}
+
+			@Override
+			protected String getDefaultValue() {
+				return getSubject().getDefaultCatalog();
+			}
+
+			@Override
+			protected void setValue(String value) {
+				getSubject().setSpecifiedCatalog(value);
+			}
+
+			@Override
+			protected String getValue() {
+				return getSubject().getSpecifiedCatalog();
+			}
+		};
+	}
+
+	private PropertyValueModel<OrmPersistenceUnitDefaults> buildPersistenceUnitDefaultsHolder() {
+		return new TransformationPropertyValueModel<PersistenceUnitMetadata, OrmPersistenceUnitDefaults>(getSubjectHolder()) {
+			@Override
+			protected OrmPersistenceUnitDefaults transform_(PersistenceUnitMetadata value) {
+				return value.getPersistenceUnitDefaults();
+			}
+		};
+	}
+
+	private SchemaCombo<OrmPersistenceUnitDefaults> addSchemaCombo(Composite container) {
+
+		return new SchemaCombo<OrmPersistenceUnitDefaults>(this, buildPersistenceUnitDefaultsHolder(), container) {
+
+			@Override
+			protected void addPropertyNames(Collection<String> propertyNames) {
+				super.addPropertyNames(propertyNames);
+				propertyNames.add(OrmPersistenceUnitDefaults.DEFAULT_SCHEMA_PROPERTY);
+				propertyNames.add(OrmPersistenceUnitDefaults.SPECIFIED_SCHEMA_PROPERTY);
+			}
+
+			@Override
+			protected String getDefaultValue() {
+				return getSubject().getDefaultSchema();
+			}
+
+			@Override
+			protected void setValue(String value) {
+				getSubject().setSpecifiedSchema(value);
+			}
+
+			@Override
+			protected String getValue() {
+				return getSubject().getSpecifiedSchema();
+			}
+
+			@Override
+			protected SchemaContainer getDbSchemaContainer_() {
+				return this.getSubject().getDbSchemaContainer();
+			}
+
+		};
+	}
+
+	private WritablePropertyValueModel<Boolean> buildXmlMappingMetadataCompleteHolder() {
+		return new PropertyAspectAdapter<PersistenceUnitMetadata, Boolean>(getSubjectHolder(), PersistenceUnitMetadata.XML_MAPPING_METADATA_COMPLETE_PROPERTY) {
+			@Override
+			protected Boolean buildValue_() {
+				return Boolean.valueOf(this.subject.isXmlMappingMetadataComplete());
+			}
+
+			@Override
+			protected void setValue_(Boolean value) {
+				this.subject.setXmlMappingMetadataComplete(value.booleanValue());
+			}
+		};
+	}
+
+	private WritablePropertyValueModel<Boolean> buildDelimitedIdentifiersHolder() {
+		return new PropertyAspectAdapter<OrmPersistenceUnitDefaults, Boolean>(buildPersistenceUnitDefaultsHolder(), OrmPersistenceUnitDefaults2_0.DELIMITED_IDENTIFIERS_PROPERTY) {
+			@Override
+			protected Boolean buildValue_() {
+				return Boolean.valueOf(this.buildBooleanValue_());
+			}
+
+			protected boolean buildBooleanValue_() {
+				return JptCorePlugin.nodeIsJpa2_0Compatible(this.subject) &&
+						((OrmPersistenceUnitDefaults2_0) this.subject).isDelimitedIdentifiers();
+			}
+
+			@Override
+			protected void setValue_(Boolean value) {
+				if (JptCorePlugin.nodeIsJpa2_0Compatible(this.subject)) {
+					((OrmPersistenceUnitDefaults2_0) this.subject).setDelimitedIdentifiers(value.booleanValue());
+				}
+			}
+		};
+	}
+
+	@Override
+	protected void initializeLayout(Composite container) {
+
+		// Section
+		container = addCollapsibleSection(
+			container,
+			JptUiDetailsOrmMessages.PersistenceUnitMetadataComposite_persistenceUnitSection
+		);
+
+		// XML mapping metadata complete check box
+		addCheckBox(
+			container,
+			JptUiDetailsOrmMessages.PersistenceUnitMetadataComposite_xmlMappingMetadataCompleteCheckBox,
+			buildXmlMappingMetadataCompleteHolder(),
+			JpaHelpContextIds.ENTITY_ORM_XML
+		);
+
+		// Cascade Persist check-box
+		addCheckBox(
+			container,
+			JptUiDetailsOrmMessages.PersistenceUnitMetadataComposite_cascadePersistCheckBox,
+			buildCascadePersistHolder(),
+			JpaHelpContextIds.ENTITY_ORM_CASCADE
+		);
+
+		// Schema widgets
+		addLabeledComposite(
+			container,
+			JptUiDetailsOrmMessages.PersistenceUnitMetadataComposite_schema,
+			addSchemaCombo(container),
+			JpaHelpContextIds.ENTITY_ORM_SCHEMA
+		);
+
+		// Catalog widgets
+		addLabeledComposite(
+			container,
+			JptUiDetailsOrmMessages.PersistenceUnitMetadataComposite_catalog,
+			addCatalogCombo(container),
+			JpaHelpContextIds.ENTITY_ORM_CATALOG
+		);
+
+		// Access Type widgets
+		addLabeledComposite(
+			container,
+			JptUiDetailsOrmMessages.PersistenceUnitMetadataComposite_access,
+			addAccessTypeCombo(container),
+			JpaHelpContextIds.ENTITY_ORM_ACCESS
+		);
+
+		// Delimited Identifiers check-box
+		Button diCheckBox = this.addCheckBox(
+			container,
+			JptUiDetailsOrmMessages.PersistenceUnitMetadataComposite_delimitedIdentifiersCheckBox,
+			this.buildDelimitedIdentifiersHolder(),
+			JpaHelpContextIds.ENTITY_ORM_DELIMITED_IDENTIFIERS
+		);
+		
+		SWTTools.controlVisibleState(new Jpa2_0ProjectFlagModel<PersistenceUnitMetadata>(this.getSubjectHolder()), diCheckBox);
+
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/orm/UnsupportedOrmMappingUiDefinition.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/orm/UnsupportedOrmMappingUiDefinition.java
new file mode 100644
index 0000000..a433477
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/orm/UnsupportedOrmMappingUiDefinition.java
@@ -0,0 +1,89 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2010 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.ui.internal.details.orm;
+
+import org.eclipse.jpt.core.context.java.JavaAttributeMapping;
+import org.eclipse.jpt.ui.WidgetFactory;
+import org.eclipse.jpt.ui.details.JpaComposite;
+import org.eclipse.jpt.ui.details.orm.OrmAttributeMappingUiDefinition;
+import org.eclipse.jpt.ui.details.orm.OrmXmlUiFactory;
+import org.eclipse.jpt.ui.internal.JpaMappingImageHelper;
+import org.eclipse.jpt.ui.internal.details.AbstractMappingUiDefinition;
+import org.eclipse.jpt.ui.internal.widgets.Pane;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Composite;
+
+public class UnsupportedOrmMappingUiDefinition
+	extends AbstractMappingUiDefinition
+	implements OrmAttributeMappingUiDefinition
+{
+	// singleton
+	private static final UnsupportedOrmMappingUiDefinition INSTANCE = 
+			new UnsupportedOrmMappingUiDefinition();
+	
+	
+	/**
+	 * Return the singleton.
+	 */
+	public static OrmAttributeMappingUiDefinition instance() {
+		return INSTANCE;
+	}
+	
+	
+	/**
+	 * Ensure single instance.
+	 */
+	private UnsupportedOrmMappingUiDefinition() {
+		super();
+	}
+	
+	
+	public Image getImage() {
+		return JpaMappingImageHelper.imageForAttributeMapping(getKey());
+	}
+	
+	public String getLabel() {
+		return JptUiDetailsOrmMessages.UnsupportedOrmMappingUiProvider_label;
+	}
+	
+	public String getLinkLabel() {
+		return JptUiDetailsOrmMessages.UnsupportedOrmMappingUiProvider_linkLabel;
+	}
+	
+	public String getKey() {
+		return null;
+	}	
+	
+	public JpaComposite buildAttributeMappingComposite(
+			OrmXmlUiFactory factory,
+			PropertyValueModel subjectHolder,
+			Composite parent,
+			WidgetFactory widgetFactory) {
+		
+		return new NullComposite(subjectHolder, parent, widgetFactory);
+	}
+	
+	public static class NullComposite extends Pane<JavaAttributeMapping>
+		implements JpaComposite
+	{
+		NullComposite(
+				PropertyValueModel<JavaAttributeMapping> subjectHolder,
+		        Composite parent,
+		        WidgetFactory widgetFactory) {
+			
+			super(subjectHolder, parent, widgetFactory);
+		}
+		
+		
+		@Override
+		protected void initializeLayout(Composite container) {}
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/dialogs/AddPersistentAttributeToXmlAndMapDialog.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/dialogs/AddPersistentAttributeToXmlAndMapDialog.java
new file mode 100644
index 0000000..9969d51
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/dialogs/AddPersistentAttributeToXmlAndMapDialog.java
@@ -0,0 +1,197 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2009 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.ui.internal.dialogs;
+
+import java.util.Comparator;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jface.dialogs.StatusDialog;
+import org.eclipse.jface.viewers.ComboViewer;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.IStructuredContentProvider;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jpt.core.context.PersistentAttribute;
+import org.eclipse.jpt.core.context.orm.OrmPersistentAttribute;
+import org.eclipse.jpt.ui.JpaPlatformUi;
+import org.eclipse.jpt.ui.JptUiPlugin;
+import org.eclipse.jpt.ui.details.MappingUiDefinition;
+import org.eclipse.jpt.ui.internal.JptUiMessages;
+import org.eclipse.jpt.utility.internal.ArrayTools;
+import org.eclipse.jpt.utility.internal.CollectionTools;
+import org.eclipse.jpt.utility.internal.iterators.FilteringIterator;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Text;
+import com.ibm.icu.text.Collator;
+
+public class AddPersistentAttributeToXmlAndMapDialog extends StatusDialog
+{
+	private OrmPersistentAttribute unmappedPersistentAttribute;
+	private Text attributeText;
+	private ComboViewer mappingCombo;
+
+	public AddPersistentAttributeToXmlAndMapDialog(Shell parentShell, OrmPersistentAttribute unmappedPersistentAttribute) {
+		super(parentShell);
+		this.unmappedPersistentAttribute = unmappedPersistentAttribute;
+		setTitle(JptUiMessages.AddPersistentAttributeDialog_title);
+	}
+
+	@Override
+	protected Control createDialogArea(Composite parent) {
+		Composite dialogArea = (Composite) super.createDialogArea(parent);
+
+		Composite composite = new Composite(dialogArea, SWT.NULL);
+		composite.setLayoutData(new GridData(GridData.FILL_BOTH));
+		composite.setLayout(new GridLayout());
+
+		createLabel(composite, 1, JptUiMessages.AddPersistentAttributeDialog_attributeLabel);
+
+		attributeText = createText(composite, 1);
+//		attributeText.addModifyListener(
+//				new ModifyListener() {
+//					public void modifyText(ModifyEvent e) {
+//						validate();
+//					}
+//				}
+//			);
+		attributeText.setText(unmappedPersistentAttribute.getName());
+		attributeText.setEditable(false);
+
+		createLabel(composite, 1, JptUiMessages.AddPersistentClassDialog_mappingLabel);
+
+		mappingCombo = new ComboViewer(createCombo(composite, 1));
+		mappingCombo.getCombo().setFocus();
+		mappingCombo.setContentProvider(
+			new IStructuredContentProvider() {
+				public void dispose() {}
+
+				public Object[] getElements(Object inputElement) {
+					return ArrayTools.array(
+						CollectionTools.sort(
+							new FilteringIterator<MappingUiDefinition<PersistentAttribute, ?>>(
+									((JpaPlatformUi) inputElement).attributeMappingUiDefinitions(unmappedPersistentAttribute.getResourceType())) {
+								@Override
+								protected boolean accept(MappingUiDefinition<PersistentAttribute, ?> o) {
+									return o.isEnabledFor(AddPersistentAttributeToXmlAndMapDialog.this.unmappedPersistentAttribute);
+								}
+							},
+							getProvidersComparator()));
+				}
+				
+				public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {}
+			});
+		mappingCombo.setLabelProvider(
+			new LabelProvider() {
+				@Override
+				public String getText(Object element) {
+					return ((MappingUiDefinition) element).getLabel();
+				}
+			});
+		mappingCombo.addSelectionChangedListener(new ISelectionChangedListener() {
+			public void selectionChanged(SelectionChangedEvent event) {
+				validate();
+			}
+		});
+		JpaPlatformUi jpaPlatformUi = JptUiPlugin.instance().getJpaPlatformUi(this.unmappedPersistentAttribute.getJpaProject().getJpaPlatform());
+		mappingCombo.setInput(jpaPlatformUi);
+		mappingCombo.getCombo().select(0);  // select Basic to begin
+
+		// TODO - F1 Help
+		// PlatformUI.getWorkbench().getHelpSystem().setHelp(group, IDaliHelpContextIds.NEW_JPA_PROJECT_CONTENT_PAGE_DATABASE);
+
+		//getButton(IDialogConstants.OK_ID).setEnabled(false);  // disabled to start
+		applyDialogFont(dialogArea);
+
+		validate();
+
+		return dialogArea;
+	}
+	
+	protected Comparator<MappingUiDefinition> getProvidersComparator() {
+		return new Comparator<MappingUiDefinition>() {
+			public int compare(MappingUiDefinition item1, MappingUiDefinition item2) {
+				String displayString1 = item1.getLabel();
+				String displayString2 = item2.getLabel();
+				return Collator.getInstance().compare(displayString1, displayString2);
+			}
+		};
+	}
+
+	private Label createLabel(Composite container, int span, String text) {
+		Label label = new Label(container, SWT.NONE);
+		label.setText(text);
+		GridData gd = new GridData();
+		gd.horizontalSpan = span;
+		label.setLayoutData(gd);
+		return label;
+	}
+
+	private Text createText(Composite container, int span) {
+		Text text = new Text(container, SWT.BORDER | SWT.SINGLE);
+		GridData gd = new GridData(GridData.FILL_HORIZONTAL);
+		gd.horizontalSpan = span;
+		gd.widthHint = 250;
+		text.setLayoutData(gd);
+		return text;
+	}
+
+	private Combo createCombo(Composite container, int span) {
+		Combo combo = new Combo(container, SWT.BORDER | SWT.SINGLE | SWT.READ_ONLY);
+		GridData gd = new GridData(GridData.FILL_HORIZONTAL);
+		gd.horizontalSpan = span;
+		combo.setLayoutData(gd);
+		return combo;
+	}
+
+	public String getAttributeName() {
+		return attributeText.getText();
+	}
+
+	public String getMappingKey() {
+		StructuredSelection selection = (StructuredSelection) mappingCombo.getSelection();
+		return (selection.isEmpty()) ? null : ((MappingUiDefinition) selection.getFirstElement()).getKey();
+	}
+
+	private void validate() {
+//		if (entityMappings.containsPersistentType(type)) {
+//			updateStatus(
+//				new Status(
+//					IStatus.WARNING, JptUiPlugin.PLUGIN_ID,
+//					JptUiMessages.AddPersistentClassDialog_duplicateClassWarning));
+//			return;
+//		}
+//
+		String mappingKey = getMappingKey();
+		if (mappingKey == null) {
+			updateStatus(
+				new Status(
+					IStatus.ERROR, JptUiPlugin.PLUGIN_ID,
+					JptUiMessages.AddPersistentAttributeDialog_noMappingKeyError));
+			return;
+		}
+
+		updateStatus(Status.OK_STATUS);
+	}
+
+	@Override
+	protected void okPressed() {
+		unmappedPersistentAttribute.makeSpecified(getMappingKey());
+		super.okPressed();
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/dialogs/AddPersistentClassDialog.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/dialogs/AddPersistentClassDialog.java
new file mode 100644
index 0000000..7d5a370
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/dialogs/AddPersistentClassDialog.java
@@ -0,0 +1,310 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 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.ui.internal.dialogs;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.IPackageFragmentRoot;
+import org.eclipse.jdt.core.IType;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.core.search.IJavaSearchScope;
+import org.eclipse.jdt.core.search.SearchEngine;
+import org.eclipse.jdt.internal.ui.refactoring.contentassist.ControlContentAssistHelper;
+import org.eclipse.jdt.internal.ui.refactoring.contentassist.JavaTypeCompletionProcessor;
+import org.eclipse.jdt.ui.IJavaElementSearchConstants;
+import org.eclipse.jdt.ui.JavaUI;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.dialogs.StatusDialog;
+import org.eclipse.jface.fieldassist.FieldDecorationRegistry;
+import org.eclipse.jface.viewers.ComboViewer;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.IStructuredContentProvider;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.window.Window;
+import org.eclipse.jpt.core.JpaProject;
+import org.eclipse.jpt.core.context.orm.EntityMappings;
+import org.eclipse.jpt.core.context.orm.OrmPersistentType;
+import org.eclipse.jpt.core.internal.utility.jdt.JDTTools;
+import org.eclipse.jpt.ui.JptUiPlugin;
+import org.eclipse.jpt.ui.details.MappingUiDefinition;
+import org.eclipse.jpt.ui.internal.JptUiMessages;
+import org.eclipse.jpt.ui.internal.details.orm.OrmEmbeddableUiDefinition;
+import org.eclipse.jpt.ui.internal.details.orm.OrmEntityUiDefinition;
+import org.eclipse.jpt.ui.internal.details.orm.OrmMappedSuperclassUiDefinition;
+import org.eclipse.jpt.utility.internal.StringTools;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.dialogs.SelectionDialog;
+import org.eclipse.ui.progress.IProgressService;
+
+public class AddPersistentClassDialog extends StatusDialog
+{
+	private EntityMappings entityMappings;
+	
+	private Text classText;
+	
+	private Button classBrowseButton;
+	
+	private ComboViewer mappingCombo;
+	
+	private OrmPersistentType addedType;
+		
+	
+	public AddPersistentClassDialog(Shell parentShell, EntityMappings entityMappings) {
+		super(parentShell);
+		this.entityMappings = entityMappings;
+		setTitle(JptUiMessages.AddPersistentClassDialog_title);
+	}
+	
+	@Override
+	protected Control createDialogArea(Composite parent) {
+		Composite dialogArea = (Composite) super.createDialogArea(parent);
+		
+		Composite composite = new Composite(dialogArea, SWT.NULL);
+		composite.setLayoutData(new GridData(GridData.FILL_BOTH));
+		composite.setLayout(new GridLayout(3, false));
+		
+		createLabel(composite, JptUiMessages.AddPersistentClassDialog_classLabel);
+			
+		this.classText = createText(composite);
+		this.classText.addModifyListener(
+				new ModifyListener() {
+					public void modifyText(ModifyEvent e) {
+						validate();
+					}
+				}
+			);
+		
+		this.classBrowseButton = createButton(composite, JptUiMessages.General_browse);
+		this.classBrowseButton.addSelectionListener(new SelectionListener() {
+			public void widgetSelected(SelectionEvent e) {
+				IType type = chooseType();
+				if (type != null) {
+					classText.setText(type.getFullyQualifiedName('$'));
+				}
+			}
+			public void widgetDefaultSelected(SelectionEvent e) {
+				widgetSelected(e);
+			}
+		});
+		
+		createLabel(composite, JptUiMessages.AddPersistentClassDialog_mappingLabel);
+		
+		this.mappingCombo = new ComboViewer(createCombo(composite, 2));
+		this.mappingCombo.setContentProvider(
+			new IStructuredContentProvider() {
+				public void dispose() {}
+				
+				public Object[] getElements(Object inputElement) {
+					return new Object[] {
+						OrmMappedSuperclassUiDefinition.instance(), 
+						OrmEntityUiDefinition.instance(), 
+						OrmEmbeddableUiDefinition.instance()
+					};
+				}
+				
+				public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {}
+			});
+		this.mappingCombo.setLabelProvider(
+			new LabelProvider() {
+				@Override
+				public String getText(Object element) {
+					return ((MappingUiDefinition) element).getLabel();
+				}
+			});
+		this.mappingCombo.addSelectionChangedListener(new ISelectionChangedListener() {
+			public void selectionChanged(SelectionChangedEvent event) {
+				validate();
+			}
+		});
+		this.mappingCombo.setInput("FOO");
+		this.mappingCombo.getCombo().select(1);  // select Entity to begin
+		
+		// TODO - F1 Help
+		// PlatformUI.getWorkbench().getHelpSystem().setHelp(group, IDaliHelpContextIds.NEW_JPA_PROJECT_CONTENT_PAGE_DATABASE);
+		
+		//getButton(IDialogConstants.OK_ID).setEnabled(false);  // disabled to start
+		applyDialogFont(dialogArea);		
+		
+		validate();
+		
+		return dialogArea;
+	}
+	
+	private Label createLabel(Composite container, String text) {
+		Label label = new Label(container, SWT.NONE);
+		label.setText(text);
+		return label;
+	}
+	
+	private Text createText(Composite container) {
+		// TODO bug 156185 - when this is fixed there should be api for this
+		JavaTypeCompletionProcessor javaTypeCompletionProcessor = new JavaTypeCompletionProcessor(false, false);
+		IPackageFragmentRoot pfr = getPackageFragmentRoot();
+		if (pfr != null) {
+			javaTypeCompletionProcessor.setPackageFragment(pfr.getPackageFragment(""));
+		}
+		
+		Text text = new Text(container, SWT.BORDER | SWT.SINGLE);
+
+		ControlContentAssistHelper.createTextContentAssistant(
+			text,
+			javaTypeCompletionProcessor
+		);
+		
+		text.setLayoutData(getFieldGridData());
+		return text;
+	}
+	
+	protected GridData getFieldGridData() {
+		int margin = FieldDecorationRegistry.getDefault()
+				.getMaximumDecorationWidth();
+		GridData data = new GridData();
+		data.horizontalAlignment = SWT.FILL;
+		data.widthHint = IDialogConstants.ENTRY_FIELD_WIDTH + margin;
+		data.horizontalIndent = margin;
+		data.grabExcessHorizontalSpace = true;
+		return data;
+	}
+
+	protected IPackageFragmentRoot getPackageFragmentRoot() {
+		return JDTTools.getCodeCompletionContextRoot(getJpaProject().getJavaProject());
+	}
+
+	
+	private Button createButton(Composite container, String text) {
+		Button button = new Button(container, SWT.NONE);
+		button.setText(text);
+		return button;
+	}
+	
+	private Combo createCombo(Composite container, int span) {
+		Combo combo = new Combo(container, SWT.BORDER | SWT.SINGLE | SWT.READ_ONLY);
+		GridData gd = getFieldGridData();
+		gd.horizontalSpan = span;
+		combo.setLayoutData(gd);
+		return combo;
+	}
+	
+	private JpaProject getJpaProject() {
+		return this.entityMappings.getJpaProject();
+	}
+	
+	public String getClassName() {
+		return this.classText.getText();
+	}
+	
+	public String getMappingKey() {
+		StructuredSelection selection = (StructuredSelection) this.mappingCombo.getSelection();
+		return (selection.isEmpty()) ? null : ((MappingUiDefinition) selection.getFirstElement()).getKey();
+	}
+	
+	protected IType chooseType() {
+		IJavaElement[] elements= new IJavaElement[] { getJpaProject().getJavaProject() };
+		IJavaSearchScope scope= SearchEngine.createJavaSearchScope(elements);
+		IProgressService service = PlatformUI.getWorkbench().getProgressService();
+		
+		SelectionDialog typeSelectionDialog;
+		try {
+			typeSelectionDialog = 
+				JavaUI.createTypeDialog(
+						getShell(), service, scope, 
+						IJavaElementSearchConstants.CONSIDER_CLASSES, 
+						false, getClassName());
+		}
+		catch (JavaModelException e) {
+			JptUiPlugin.log(e);
+			throw new RuntimeException(e);
+		}
+		typeSelectionDialog.setTitle(JptUiMessages.AddPersistentClassDialog_classDialog_title); 
+		typeSelectionDialog.setMessage(JptUiMessages.AddPersistentClassDialog_classDialog_message); 
+
+		if (typeSelectionDialog.open() == Window.OK) {
+			return (IType) typeSelectionDialog.getResult()[0];
+		}
+		return null;
+	}
+	
+	private void validate() {
+		String className = getClassName();
+		
+		if (StringTools.stringIsEmpty(className)) {
+			updateStatus(
+				new Status(
+					IStatus.ERROR, JptUiPlugin.PLUGIN_ID, 
+					JptUiMessages.AddPersistentClassDialog_noClassError));
+			return;
+		}
+		className = className.replace('$', '.');
+		
+		IType type;
+		try {
+			type = getJpaProject().getJavaProject().findType(className);
+		}
+		catch (JavaModelException jme) {
+			type = null;
+		}
+		
+		if (type == null) {
+			updateStatus(
+				new Status(
+					IStatus.WARNING, JptUiPlugin.PLUGIN_ID,
+					JptUiMessages.AddPersistentClassDialog_classNotFoundWarning));
+			return;
+		}
+		
+		if (this.entityMappings.containsPersistentType(className)) {
+			updateStatus(
+				new Status(
+					IStatus.WARNING, JptUiPlugin.PLUGIN_ID, 
+					JptUiMessages.AddPersistentClassDialog_duplicateClassWarning));
+			return;
+		}
+		
+		String mappingKey = getMappingKey();
+		if (mappingKey == null) {
+			updateStatus(
+				new Status(
+					IStatus.ERROR, JptUiPlugin.PLUGIN_ID,
+					JptUiMessages.AddPersistentClassDialog_noMappingKeyError));
+			return;
+		}
+		
+		updateStatus(Status.OK_STATUS);
+	}
+	
+	@Override
+	protected void okPressed() {
+		this.addedType = this.entityMappings.addPersistentType(getMappingKey(), getClassName());
+		super.okPressed();
+	}
+	
+	public OrmPersistentType openAndReturnType() {
+		super.open();
+		return addedType;
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/editors/PersistenceContributor.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/editors/PersistenceContributor.java
new file mode 100644
index 0000000..140803a
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/editors/PersistenceContributor.java
@@ -0,0 +1,106 @@
+/*******************************************************************************
+ *  Copyright (c) 2008 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.ui.internal.editors;
+
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.action.IToolBarManager;
+import org.eclipse.ui.IActionBars;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.actions.ActionFactory;
+import org.eclipse.ui.ide.IDEActionFactory;
+import org.eclipse.ui.part.MultiPageEditorActionBarContributor;
+import org.eclipse.ui.texteditor.ITextEditor;
+import org.eclipse.ui.texteditor.ITextEditorActionConstants;
+
+/**
+ *
+ * @version 2.0
+ * @since 2.0
+ */
+public class PersistenceContributor extends MultiPageEditorActionBarContributor {
+
+	private IEditorPart activeEditorPart;
+
+	/**
+	 * Creates a new <code>PersistenceContributor</code>.
+	 */
+	public PersistenceContributor() {
+		super();
+	}
+
+	/*
+	 * (non-Javadoc)
+	 */
+	@Override
+	public void contributeToMenu(IMenuManager manager) {
+	}
+
+	/*
+	 * (non-Javadoc)
+	 */
+	@Override
+	public void contributeToToolBar(IToolBarManager manager) {
+	}
+
+	/**
+	 * Returns the action registed with the given text editor.
+	 * @return IAction or null if editor is null.
+	 */
+	protected IAction getAction(ITextEditor editor, String actionID) {
+		return (editor == null ? null : editor.getAction(actionID));
+	}
+
+	/*
+	 * (non-Javadoc)
+	 */
+	@Override
+	public void setActivePage(IEditorPart part) {
+
+		if (activeEditorPart == part)
+			return;
+
+		activeEditorPart = part;
+
+		IActionBars actionBars = getActionBars();
+		if (actionBars != null) {
+
+			ITextEditor editor = (part instanceof ITextEditor) ? (ITextEditor) part : null;
+
+			actionBars.setGlobalActionHandler(
+				ActionFactory.DELETE.getId(),
+				getAction(editor, ITextEditorActionConstants.DELETE));
+			actionBars.setGlobalActionHandler(
+				ActionFactory.UNDO.getId(),
+				getAction(editor, ITextEditorActionConstants.UNDO));
+			actionBars.setGlobalActionHandler(
+				ActionFactory.REDO.getId(),
+				getAction(editor, ITextEditorActionConstants.REDO));
+			actionBars.setGlobalActionHandler(
+				ActionFactory.CUT.getId(),
+				getAction(editor, ITextEditorActionConstants.CUT));
+			actionBars.setGlobalActionHandler(
+				ActionFactory.COPY.getId(),
+				getAction(editor, ITextEditorActionConstants.COPY));
+			actionBars.setGlobalActionHandler(
+				ActionFactory.PASTE.getId(),
+				getAction(editor, ITextEditorActionConstants.PASTE));
+			actionBars.setGlobalActionHandler(
+				ActionFactory.SELECT_ALL.getId(),
+				getAction(editor, ITextEditorActionConstants.SELECT_ALL));
+			actionBars.setGlobalActionHandler(
+				ActionFactory.FIND.getId(),
+				getAction(editor, ITextEditorActionConstants.FIND));
+			actionBars.setGlobalActionHandler(
+				IDEActionFactory.BOOKMARK.getId(),
+				getAction(editor, IDEActionFactory.BOOKMARK.getId()));
+			actionBars.updateActionBars();
+		}
+	}
+}
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/editors/PersistenceEditor.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/editors/PersistenceEditor.java
new file mode 100644
index 0000000..706a815
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/editors/PersistenceEditor.java
@@ -0,0 +1,436 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2010 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.ui.internal.editors;
+
+import java.util.ListIterator;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.action.IToolBarManager;
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.resource.JFaceResources;
+import org.eclipse.jface.resource.LocalResourceManager;
+import org.eclipse.jface.resource.ResourceManager;
+import org.eclipse.jpt.core.JpaProject;
+import org.eclipse.jpt.core.JpaResourceType;
+import org.eclipse.jpt.core.JptCorePlugin;
+import org.eclipse.jpt.core.context.JpaRootContextNode;
+import org.eclipse.jpt.core.context.persistence.Persistence;
+import org.eclipse.jpt.core.context.persistence.PersistenceUnit;
+import org.eclipse.jpt.core.context.persistence.PersistenceXml;
+import org.eclipse.jpt.ui.JpaPlatformUi;
+import org.eclipse.jpt.ui.PersistenceXmlResourceUiDefinition;
+import org.eclipse.jpt.ui.WidgetFactory;
+import org.eclipse.jpt.ui.details.JpaPageComposite;
+import org.eclipse.jpt.ui.internal.persistence.JptUiPersistenceMessages;
+import org.eclipse.jpt.ui.internal.platform.JpaPlatformUiRegistry;
+import org.eclipse.jpt.ui.internal.widgets.FormWidgetFactory;
+import org.eclipse.jpt.utility.internal.model.value.CachingTransformationPropertyValueModel;
+import org.eclipse.jpt.utility.internal.model.value.ListAspectAdapter;
+import org.eclipse.jpt.utility.internal.model.value.ListPropertyValueModelAdapter;
+import org.eclipse.jpt.utility.internal.model.value.PropertyAspectAdapter;
+import org.eclipse.jpt.utility.internal.model.value.SimplePropertyValueModel;
+import org.eclipse.jpt.utility.internal.model.value.TransformationPropertyValueModel;
+import org.eclipse.jpt.utility.model.value.ListValueModel;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.jpt.utility.model.value.WritablePropertyValueModel;
+import org.eclipse.swt.custom.BusyIndicator;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IEditorSite;
+import org.eclipse.ui.IFileEditorInput;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.forms.IManagedForm;
+import org.eclipse.ui.forms.editor.FormEditor;
+import org.eclipse.ui.forms.editor.FormPage;
+import org.eclipse.ui.forms.widgets.ScrolledForm;
+import org.eclipse.ui.forms.widgets.TableWrapData;
+import org.eclipse.ui.forms.widgets.TableWrapLayout;
+import org.eclipse.ui.views.properties.tabbed.TabbedPropertySheetWidgetFactory;
+import org.eclipse.wst.sse.ui.StructuredTextEditor;
+
+/**
+ * This is the editor for the JPA Persistence Configuration (persistence.xml).
+ * The pages shown before the XML source editor are retrieved from the
+ * <code>JpaUiFactory</code>.
+ *
+ * @see JpaUiFactory
+ *
+ * @version 2.3
+ * @since 2.0
+ */
+@SuppressWarnings("nls")
+public class PersistenceEditor extends FormEditor
+{
+	/**
+	 * The XML text editor.
+	 */
+	private StructuredTextEditor editor;
+
+	/**
+	 * The root of the holders used to retrieve the persistence unit and be
+	 * notified when it changes.
+	 */
+	private WritablePropertyValueModel<IFileEditorInput> editorInputHolder;
+
+	/**
+	 * The factory used to create the various widgets.
+	 */
+	private WidgetFactory widgetFactory;
+
+	private final ResourceManager resourceManager;
+
+	/**
+	 * Creates a new <code>PersistenceEditor</code>.
+	 */
+	public PersistenceEditor() {
+		super();
+		this.resourceManager = new LocalResourceManager(JFaceResources.getResources());
+		initialize();
+	}
+	
+	@Override
+	@SuppressWarnings("unchecked")
+	public Object getAdapter(Class adapterClass) {
+		Object adapter = super.getAdapter(adapterClass);
+		if (adapter == null) {
+			adapter = editor.getAdapter(adapterClass);
+		}
+		return adapter;
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	protected void addPages() {
+		addPersistenceUnitPages();
+		addXMLEditorPage();
+	}
+
+	/**
+	 * Adds the pages that show the properties of the persistence configuration
+	 * or its persistence units.
+	 */
+	private void addPersistenceUnitPages() {
+
+		JpaProject jpaProject = getJpaProject();
+
+		// The project doesn't have JPA
+		if (jpaProject == null) {
+			return;
+		}
+
+		PersistenceXml persistenceXml = jpaProject.getRootContextNode().getPersistenceXml();
+		if (persistenceXml == null) {
+			return;
+		}
+		JpaResourceType resourceType = persistenceXml.getResourceType();
+		if (resourceType == null) {
+			return;  // might not ever get here... (if we have a p.xml, it probably has a resource type...)
+		}
+		String platformId = jpaProject.getJpaPlatform().getId();
+		JpaPlatformUi jpaPlatformUI = JpaPlatformUiRegistry.instance().getJpaPlatformUi(platformId);
+		PersistenceXmlResourceUiDefinition definition = 
+			(PersistenceXmlResourceUiDefinition) jpaPlatformUI.getResourceUiDefinition(resourceType);
+
+		ListIterator<JpaPageComposite> pages = definition.buildPersistenceUnitComposites(
+			buildPersistenceUnitHolder(),
+			getContainer(),
+			this.widgetFactory
+		);
+
+		while (pages.hasNext()) {
+			JpaPageComposite page = pages.next();
+
+			try {
+				FormPage formPage = new Page(page);
+				addPage(formPage);
+			}
+			catch (PartInitException e) {
+				// TODO
+			}
+		}
+	}
+
+	/**
+	 * Adds the page containing the XML editor.
+	 */
+	private void addXMLEditorPage() {
+		try {
+			editor = new StructuredTextEditor();
+			editor.setEditorPart(this);
+			int index = addPage(editor, getEditorInput());
+			setPageText(index, JptUiPersistenceMessages.PersistenceEditor_sourceTab);
+		}
+		catch (PartInitException e) {
+			// TODO
+		}
+	}
+
+	private WritablePropertyValueModel<IFileEditorInput> buildEditorInputHolder() {
+		return new SimplePropertyValueModel<IFileEditorInput>();
+	}
+
+	private PropertyValueModel<JpaProject> buildJpaProjectHolder() {
+		return new CachingTransformationPropertyValueModel<IFileEditorInput, JpaProject>(this.editorInputHolder) {
+			@Override
+			protected JpaProject transform_(IFileEditorInput fileEditorInput) {
+				return JptCorePlugin.getJpaProject(fileEditorInput.getFile().getProject());
+			}
+		};
+	}
+
+	private PropertyValueModel<Persistence> buildPersistenceHolder() {
+		return new PropertyAspectAdapter<PersistenceXml, Persistence>(buildPersistenceXmlHolder(), PersistenceXml.PERSISTENCE_PROPERTY) {
+			@Override
+			protected Persistence buildValue_() {
+				return subject.getPersistence();
+			}
+		};
+	}
+
+	private PropertyValueModel<PersistenceUnit> buildPersistenceUnitHolder() {
+		return new ListPropertyValueModelAdapter<PersistenceUnit>(buildPersistenceUnitListHolder()) {
+			@Override
+			protected PersistenceUnit buildValue() {
+				return listHolder.size() > 0 ? (PersistenceUnit) listHolder.get(0) : null;
+			}
+		};
+	}
+
+	private ListValueModel<PersistenceUnit> buildPersistenceUnitListHolder() {
+		return new ListAspectAdapter<Persistence, PersistenceUnit>(buildPersistenceHolder(), Persistence.PERSISTENCE_UNITS_LIST) {
+			@Override
+			protected ListIterator<PersistenceUnit> listIterator_() {
+				return subject.persistenceUnits();
+			}
+
+			@Override
+			protected int size_() {
+				return subject.persistenceUnitsSize();
+			}
+		};
+	}
+
+	private PropertyValueModel<PersistenceXml> buildPersistenceXmlHolder() {
+		return new PropertyAspectAdapter<JpaRootContextNode, PersistenceXml>(buildRootContextNodeHolder(), JpaRootContextNode.PERSISTENCE_XML_PROPERTY) {
+			@Override
+			protected PersistenceXml buildValue_() {
+				return subject.getPersistenceXml();
+			}
+		};
+	}
+
+	private PropertyValueModel<JpaRootContextNode> buildRootContextNodeHolder() {
+		return new TransformationPropertyValueModel<JpaProject, JpaRootContextNode>(buildJpaProjectHolder()) {
+			@Override
+			protected JpaRootContextNode transform_(JpaProject value) {
+				return value.getRootContextNode();
+			}
+		};
+	}
+
+	private WidgetFactory buildWidgetFactory() {
+		return new FormWidgetFactory(
+			new TabbedPropertySheetWidgetFactory()
+		);
+	}
+
+	@Override
+	public void dispose() {
+		this.editorInputHolder.setValue(null);
+		this.resourceManager.dispose();
+		super.dispose();
+	}
+
+	@Override
+	public void doSave(IProgressMonitor monitor) {
+		getEditor(getPageCount() - 1).doSave(monitor);
+	}
+
+	@Override
+	public void doSaveAs() {
+	}
+
+	@Override
+	public IFileEditorInput getEditorInput() {
+		return (IFileEditorInput) super.getEditorInput();
+	}
+
+	@Override
+	public void init(IEditorSite site, IEditorInput editorInput) throws PartInitException {
+		Assert.isLegal(editorInput instanceof IFileEditorInput, "Invalid Input: Must be IFileEditorInput");
+		super.init(site, editorInput);
+
+		setPartName(editorInput.getName());
+		editorInputHolder.setValue(getEditorInput());
+	}
+
+	/**
+	 * Initializes this multi-page editor.
+	 */
+	private void initialize() {
+
+		widgetFactory      = buildWidgetFactory();
+		editorInputHolder  = buildEditorInputHolder();
+	}
+
+	@Override
+	public boolean isSaveAsAllowed() {
+		return false;
+	}
+
+	/**
+	 * Retrieves the JPA project associated with the project owning the editor
+	 * intput file.
+	 *
+	 * @return The JPA project
+	 */
+	protected JpaProject getJpaProject() {
+		return JptCorePlugin.getJpaProject(getEditorInput().getFile().getProject());
+	}
+
+	/**
+	 * This extension over <code>FormPage</code> simply complete the layout by
+	 * using the <code>JpaPageComposite</code>'s control as its form content.
+	 */
+	private class Page extends FormPage {
+
+		/**
+		 * The wrapped page that actually contains the widgets to show with this
+		 * form page.
+		 */
+		private final JpaPageComposite page;
+
+		private ImageDescriptor imageDescriptor;
+
+		/**
+		 * Creates a new <code>Page</code>.
+		 *
+		 * @param page The wrapped <code>JpaPageComposite</code>
+		 */
+		private Page(JpaPageComposite page) {
+
+			super(PersistenceEditor.this,
+			      page.getClass().getName(),
+			      page.getPageText());
+
+			this.page = page;
+		}
+
+		@Override
+		protected void createFormContent(IManagedForm managedForm) {
+
+			ScrolledForm form = managedForm.getForm();
+			managedForm.getToolkit().decorateFormHeading(form.getForm());
+
+			// Update the text and image
+			updateForm(form);
+
+			// Update the layout
+			updateBody(form);
+
+			// This will finish the initialization of the buttons
+			updateHelpButton();
+			form.updateToolBar();
+		}
+
+		@Override
+		public void dispose() {
+			this.page.dispose();
+			if (this.imageDescriptor != null) {
+				PersistenceEditor.this.resourceManager.destroyImage(this.imageDescriptor);
+			}
+			super.dispose();
+		}
+
+		@Override
+		public void setFocus() {
+			this.page.getControl().setFocus();
+		}
+
+		/**
+		 * Adds the page's control to this page.
+		 *
+		 * @param form The form containing the composite with which the page's
+		 * control is parented
+		 */
+		private void updateBody(ScrolledForm form) {
+
+			Composite body = form.getBody();
+
+			body.setLayout(new TableWrapLayout());
+
+			TableWrapData wrapData = new TableWrapData(
+				TableWrapData.FILL_GRAB,
+				TableWrapData.FILL_GRAB
+			);
+
+			this.page.getControl().setLayoutData(wrapData);
+			this.page.getControl().setParent(body);
+		}
+
+		/**
+		 * Updates the text and image of the form.
+		 *
+		 * @param form The form to have its title bar updated by setting the text
+		 * and image, the image can be <code>null</code>
+		 */
+		private void updateForm(ScrolledForm form) {
+			form.setText(this.page.getPageText());
+
+			this.imageDescriptor = this.page.getPageImageDescriptor();
+			if (this.imageDescriptor != null) {
+				form.setImage(PersistenceEditor.this.resourceManager.createImage(this.imageDescriptor));
+			}
+		}
+
+		/**
+		 * Adds a help button to the page's toolbar if a help ID exists.
+		 */
+		private void updateHelpButton() {
+
+			String helpID = this.page.getHelpID();
+
+			if (helpID != null) {
+				Action helpAction = new HelpAction(helpID);
+
+				ScrolledForm form = getManagedForm().getForm();
+				IToolBarManager manager = form.getToolBarManager();
+				manager.add(helpAction);
+			}
+		}
+
+		private class HelpAction extends Action {
+
+			private final String helpID;
+
+			HelpAction(String helpID) {
+				super(JptUiPersistenceMessages.PersistenceEditor_page_help,
+				      JFaceResources.getImageRegistry().getDescriptor(Dialog.DLG_IMG_HELP));
+
+				this.helpID = helpID;
+			}
+
+			@Override
+			public void run() {
+				BusyIndicator.showWhile(getManagedForm().getForm().getDisplay(), new Runnable() {
+					public void run() {
+						PlatformUI.getWorkbench().getHelpSystem().displayHelp(helpID);
+					}
+				});
+			}
+		}
+	}
+}
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jface/AbstractItemLabelProvider.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jface/AbstractItemLabelProvider.java
new file mode 100644
index 0000000..92ea80c
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jface/AbstractItemLabelProvider.java
@@ -0,0 +1,224 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2009 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.ui.internal.jface;
+
+import org.eclipse.jpt.ui.jface.DelegatingContentAndLabelProvider;
+import org.eclipse.jpt.ui.jface.ItemLabelProvider;
+import org.eclipse.jpt.utility.model.Model;
+import org.eclipse.jpt.utility.model.event.PropertyChangeEvent;
+import org.eclipse.jpt.utility.model.listener.PropertyChangeListener;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.graphics.Image;
+
+/**
+ * Implementation of {@link ItemLabelProvider} that provides updating
+ * label information for a Model object.
+ * 
+ * The typical subclass will override the following methods:
+ * #buildImageModel()
+ * 	   return a {@link PropertyValueModel} that represents the image for the 
+ *     represented model object
+ * #buildTextModel()
+ *     return a {@link PropertyValueModel} that represents the text for the 
+ *     represented model object.
+ * #buildDescriptionModel()
+ * 	   return a {@link PropertyValueModel} that represents the description for 
+ *     the represented model object
+ * 
+ * Other methods may be overridden, but take care to preserve the logic provided 
+ * by this class.
+ */
+public abstract class AbstractItemLabelProvider implements ItemLabelProvider
+{
+	private DelegatingContentAndLabelProvider labelProvider;
+	
+	private Model model;
+	
+	private PropertyValueModel<Image> imageModel;
+	
+	private PropertyValueModel<String> textModel;
+	
+	private PropertyValueModel<String> descriptionModel;
+	
+	private PropertyChangeListener labelChangeListener;
+	
+	
+	protected AbstractItemLabelProvider(
+			Model model, DelegatingContentAndLabelProvider labelProvider) {
+		this.model = model;
+		this.labelProvider = labelProvider;
+		this.labelChangeListener = buildLabelChangeListener();
+	}
+	
+	
+	/**
+	 * Construct a listener to update the viewer (through the label provider)
+	 * if the text or image changes
+	 */
+	protected PropertyChangeListener buildLabelChangeListener() {
+		return new PropertyChangeListener() {
+			public void propertyChanged(PropertyChangeEvent event) {
+				labelProvider().updateLabel(model());
+			}
+		};
+	}
+	
+	/**
+	 * Return the image value model
+	 * (lazy and just-in-time initialized)
+	 */
+	protected synchronized PropertyValueModel<Image> imageModel() {
+		if (imageModel == null) {
+			imageModel = buildImageModel();
+			engageImageModel();
+		}
+		return imageModel;
+	}
+	
+	/**
+	 * Construct an image model
+	 */
+	protected abstract PropertyValueModel<Image> buildImageModel();
+	
+	/** 
+	 * Should only be overridden with a call to super.engageImageModel() before 
+	 * subclass logic 
+	 */
+	protected void engageImageModel() {
+		imageModel.addPropertyChangeListener(PropertyValueModel.VALUE, labelChangeListener);
+	}
+	
+	/** 
+	 * Should only be overridden with a call to super.disengageImageModel() after 
+	 * subclass logic 
+	 */
+	protected void disengageImageModel() {
+		imageModel.removePropertyChangeListener(PropertyValueModel.VALUE, labelChangeListener);
+	}
+	
+	/**
+	 * Return the text value model
+	 * (lazy and just-in-time initialized)
+	 */
+	protected synchronized PropertyValueModel<String> textModel() {
+		if (textModel == null) {
+			textModel = buildTextModel();
+			engageTextModel();
+		}
+		return textModel;
+	}
+	
+	/**
+	 * Construct a text value model
+	 */
+	protected abstract PropertyValueModel<String> buildTextModel();
+	
+	/** 
+	 * Should only be overridden with a call to super.engageTextModel() before 
+	 * subclass logic 
+	 */
+	protected void engageTextModel() {
+		textModel.addPropertyChangeListener(PropertyValueModel.VALUE, labelChangeListener);
+	}
+	
+	/** 
+	 * Should only be overridden with a call to super.disengageTextModel() after 
+	 * subclass logic 
+	 */
+	protected void disengageTextModel() {
+		textModel.removePropertyChangeListener(PropertyValueModel.VALUE, labelChangeListener);
+	}
+	
+	/**
+	 * Return the description value model
+	 * (lazy and just-in-time initialized)
+	 */
+	protected synchronized PropertyValueModel<String> descriptionModel() {
+		if (descriptionModel == null) {
+			descriptionModel = buildDescriptionModel();
+			engageDescriptionModel();
+		}
+		return descriptionModel;
+	}
+	
+	/**
+	 * Construct a description value model
+	 */
+	protected abstract PropertyValueModel<String> buildDescriptionModel();
+	
+	/** 
+	 * Should only be overridden with a call to super.engageDescriptionModel() before 
+	 * subclass logic 
+	 */
+	protected void engageDescriptionModel() {
+		descriptionModel.addPropertyChangeListener(PropertyValueModel.VALUE, labelChangeListener);
+	}
+	
+	/** 
+	 * Should only be overridden with a call to super.disengageDescriptionModel() after 
+	 * subclass logic 
+	 */
+	protected void disengageDescriptionModel() {
+		descriptionModel.removePropertyChangeListener(PropertyValueModel.VALUE, labelChangeListener);
+	}
+	
+	/**
+	 * Return the model object represented by this item
+	 */
+	public Model model() {
+		return model;
+	}
+	
+	/**
+	 * Return the label provider that delegates to this item
+	 */
+	public DelegatingContentAndLabelProvider labelProvider() {
+		return labelProvider;
+	}
+	
+	public Image getImage() {
+		return imageModel().getValue();
+	}
+	
+	public String getText() {
+		return textModel().getValue();
+	}
+	
+	public String getDescription() {
+		return descriptionModel().getValue();
+	}
+	
+	public void dispose() {
+		disposeTextModel();
+		disposeImageModel();
+		disposeDescriptionModel();	
+	}
+	
+	protected synchronized void disposeTextModel() {
+		if (this.textModel != null) {
+			disengageTextModel();
+			this.textModel = null;
+		}
+	}
+	
+	protected synchronized void disposeImageModel() {
+		if (this.imageModel != null) {
+			disengageImageModel();
+			this.imageModel = null;
+		}
+	}
+	
+	protected synchronized void disposeDescriptionModel() {
+		if (this.descriptionModel != null) {
+			disengageDescriptionModel();
+			this.descriptionModel = null;
+		}
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jface/AbstractTreeItemContentProvider.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jface/AbstractTreeItemContentProvider.java
new file mode 100644
index 0000000..f975b8c
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jface/AbstractTreeItemContentProvider.java
@@ -0,0 +1,204 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2009 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.ui.internal.jface;
+
+import java.util.Iterator;
+
+import org.eclipse.jpt.ui.jface.TreeItemContentProvider;
+import org.eclipse.jpt.utility.internal.ArrayTools;
+import org.eclipse.jpt.utility.internal.model.value.ListCollectionValueModelAdapter;
+import org.eclipse.jpt.utility.internal.model.value.NullCollectionValueModel;
+import org.eclipse.jpt.utility.internal.model.value.PropertyListValueModelAdapter;
+import org.eclipse.jpt.utility.model.Model;
+import org.eclipse.jpt.utility.model.event.CollectionAddEvent;
+import org.eclipse.jpt.utility.model.event.CollectionChangeEvent;
+import org.eclipse.jpt.utility.model.event.CollectionClearEvent;
+import org.eclipse.jpt.utility.model.event.CollectionRemoveEvent;
+import org.eclipse.jpt.utility.model.listener.CollectionChangeListener;
+import org.eclipse.jpt.utility.model.value.CollectionValueModel;
+import org.eclipse.jpt.utility.model.value.ListValueModel;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+
+/**
+ * Implementation of {@link TreeItemContentProvider} that provides updating
+ * children information for a Model object.
+ * 
+ * The typical subclass will override the following methods:
+ * #getParent()
+ *     the default behavior for this method is to return null.  there is no 
+ *     property value model for this as this should not be changing for a given
+ *     node.  all such changes will be provided by the parent side of the relationship.
+ * #buildChildrenModel()
+ *     return a {@link ListValueModel} that represents the children for the represented
+ *     model object.  #buildChildrenModel(CollectionValueModel) and 
+ *     #buildChildrenModel(PropertyValueModel) are provided if the children are more
+ *     easily represented as a collection or as a property (single child)
+ *     the default behavior is to return a {@link NullListValueModel}
+ * 
+ * Other methods may be overridden, but take care to preserve the logic provided 
+ * by this class.
+ */
+public abstract class AbstractTreeItemContentProvider<E>
+	implements TreeItemContentProvider
+{
+	private DelegatingTreeContentAndLabelProvider treeContentProvider;
+	
+	private Model model;
+	
+	private CollectionValueModel<E> childrenModel;
+	
+	private CollectionChangeListener childrenListener;
+	
+	
+	protected AbstractTreeItemContentProvider(
+			Model model, DelegatingTreeContentAndLabelProvider treeContentProvider) {
+		this.model = model;
+		this.treeContentProvider = treeContentProvider;
+		this.childrenListener = buildChildrenListener();
+	}
+	
+	/**
+	 * Construct a listener to refresh the tree (through the tree content provider)
+	 * if the children change
+	 */
+	protected CollectionChangeListener buildChildrenListener() {
+		return new CollectionChangeListener() {
+			
+			public void itemsAdded(CollectionAddEvent event) {
+				getTreeContentProvider().updateContent(getModel());
+			}
+			
+			public void itemsRemoved(CollectionRemoveEvent event) {
+				getTreeContentProvider().updateContent(getModel());
+				for (Object item : event.getItems()) {
+					getTreeContentProvider().dispose(item);
+				}
+			}
+			
+			public void collectionChanged(CollectionChangeEvent event) {
+				getTreeContentProvider().updateContent(getModel());
+				// in the case of a list changed event, we don't have 
+				// access to the removed objects, so we can't dispose them.
+				// keep a watch on this to see if this becomes a problem.
+			}
+			
+			public void collectionCleared(CollectionClearEvent event) {
+				getTreeContentProvider().updateContent(getModel());
+				// in the case of a list cleared event, we don't have 
+				// access to the removed objects, so we can't dispose them.
+				// keep a watch on this to see if this becomes a problem.
+			}
+		};
+	}
+	
+	/**
+	 * Return the children model
+	 * (lazy and just-in-time initialized)
+	 */
+	protected synchronized Iterator<E> childrenModel() {
+		if (this.childrenModel == null) {
+			this.childrenModel = buildChildrenModel();
+			engageChildren();
+		}
+		return this.childrenModel.iterator();
+	}
+	
+	/**
+	 * Construct a children model
+	 */
+	protected CollectionValueModel<E> buildChildrenModel() {
+		return new NullCollectionValueModel<E>();
+	}
+	
+	/**
+	 * Utility method that can be used if the children model is better represented
+	 * as a collection.
+	 * This wraps the children collection model and uses it internally as a list
+	 * model.
+	 */
+	protected CollectionValueModel<E> buildChildrenModel(ListValueModel<E> lvm) {
+		return new ListCollectionValueModelAdapter<E>(lvm);
+	}
+	
+	/**
+	 * Utility method that can be used if the children model is better represented
+	 * as a single value property.
+	 * This wraps the children (child) property model and uses it internally as a list
+	 * model.
+	 */
+	protected ListValueModel<E> buildChildrenModel(PropertyValueModel<E> lvm) {
+		return new PropertyListValueModelAdapter<E>(lvm);
+	}
+	
+	/**
+	 * Return the model object represented by this node
+	 */
+	public Model getModel() {
+		return this.model;
+	}
+	
+	/**
+	 * Return the tree content provider that delegates to this node
+	 */
+	public DelegatingTreeContentAndLabelProvider getTreeContentProvider() {
+		return this.treeContentProvider;
+	}
+	
+	public Object getParent() {
+		return null;
+	}
+	
+	public Object[] getElements() {
+		return getChildren();
+	}
+	
+	public Object[] getChildren() {
+		return ArrayTools.array(this.childrenModel());
+	}
+	
+	/**
+	 * Override with potentially more efficient logic
+	 */
+	public boolean hasChildren() {
+		return this.childrenModel().hasNext();
+	}
+	
+	/**
+	 * Should only be overridden with a call to super.dispose()
+	 */
+	public void dispose() {
+		for (Object child : getChildren()) {
+			getTreeContentProvider().dispose(child);
+		}
+		disposeChildrenModel();
+	}
+	
+	/** 
+	 * Should only be overridden with a call to super.engageChildren() before 
+	 * subclass logic 
+	 */
+	protected void engageChildren() {
+		this.childrenModel.addCollectionChangeListener(CollectionValueModel.VALUES, this.childrenListener);
+	}
+	
+	protected synchronized void disposeChildrenModel() {
+		if (this.childrenModel != null) {
+			this.disengageChildrenModel();
+			this.childrenModel = null;
+		}
+	}
+	/** 
+	 * Should only be overridden with a call to super.disengageChildren() after 
+	 * subclass logic 
+	 */
+	protected void disengageChildrenModel() {
+		this.childrenModel.removeCollectionChangeListener(CollectionValueModel.VALUES, this.childrenListener);
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jface/ArchiveFileViewerFilter.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jface/ArchiveFileViewerFilter.java
new file mode 100644
index 0000000..3f66b67
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jface/ArchiveFileViewerFilter.java
@@ -0,0 +1,71 @@
+/*******************************************************************************
+ *  Copyright (c) 2009  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.ui.internal.jface;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerFilter;
+import org.eclipse.jpt.ui.JptUiPlugin;
+
+/**
+ * This filter will deny showing any file that are not JAR files or folders
+ * that don't contain any JAR files in its sub-hierarchy. 
+ */
+public class ArchiveFileViewerFilter 
+	extends ViewerFilter 
+{
+	private static final String[] archiveExtensions= { "jar", "zip" }; //$NON-NLS-1$ 
+	
+	
+	public ArchiveFileViewerFilter() {
+		super();
+	}
+	
+	
+	@Override
+	public boolean select(
+			Viewer viewer, Object parentElement, Object element) {
+		if (element instanceof IFile) {
+			return isArchivePath(((IFile)element).getFullPath());
+		}
+		else if (element instanceof IFolder) {
+			IFolder folder = (IFolder) element;
+			try {
+				for (IResource each : folder.members()) {
+					if (select(viewer, folder, each)) {
+						return true;
+					}
+				}
+			}
+			catch (CoreException ce) {
+				// just skip this one, then
+				JptUiPlugin.log(ce);
+			}
+		}
+		return false;
+	}
+	
+	public static boolean isArchivePath(IPath path) {
+		String ext= path.getFileExtension();
+		if (ext != null && ext.length() != 0) {
+			for (int i= 0; i < archiveExtensions.length; i++) {
+				if (ext.equalsIgnoreCase(archiveExtensions[i])) {
+					return true;
+				}
+			}
+		}
+		return false;
+	}		
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jface/DelegatingTreeContentAndLabelProvider.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jface/DelegatingTreeContentAndLabelProvider.java
new file mode 100644
index 0000000..a99645a
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jface/DelegatingTreeContentAndLabelProvider.java
@@ -0,0 +1,58 @@
+/*******************************************************************************
+ *  Copyright (c) 2007, 2009 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.ui.internal.jface;
+
+import org.eclipse.jface.viewers.ITreeContentProvider;
+import org.eclipse.jpt.ui.jface.DelegatingContentAndLabelProvider;
+import org.eclipse.jpt.ui.jface.ItemLabelProviderFactory;
+import org.eclipse.jpt.ui.jface.TreeItemContentProvider;
+import org.eclipse.jpt.ui.jface.TreeItemContentProviderFactory;
+
+/**
+ * Extension of {@link DelegatingContentAndLabelProvider} that provides an extension
+ * to provide tree content
+ */
+public class DelegatingTreeContentAndLabelProvider 
+	extends DelegatingContentAndLabelProvider
+	implements ITreeContentProvider
+{
+	public DelegatingTreeContentAndLabelProvider(
+			TreeItemContentProviderFactory treeItemContentProviderFactory) {
+		super(treeItemContentProviderFactory);
+	}
+	
+	public DelegatingTreeContentAndLabelProvider(
+			TreeItemContentProviderFactory treeItemContentProviderFactory,
+			ItemLabelProviderFactory itemLabelProviderFactory) {
+		super(treeItemContentProviderFactory, itemLabelProviderFactory);
+	}
+	
+	
+	@Override
+	protected TreeItemContentProvider itemContentProvider(Object item) {
+		return (TreeItemContentProvider) super.itemContentProvider(item);
+	}
+	
+	public Object[] getChildren(Object parentElement) {
+		TreeItemContentProvider provider = itemContentProvider(parentElement);
+		return (provider == null) ? new Object[0] : provider.getChildren();
+	}
+
+	public Object getParent(Object element) {
+		TreeItemContentProvider provider = itemContentProvider(element);
+		return (provider == null) ? null : provider.getParent();
+	}
+	
+	public boolean hasChildren(Object element) {
+		TreeItemContentProvider provider = itemContentProvider(element);
+		return (provider == null) ? false : provider.hasChildren();
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jface/ImageImageDescriptor.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jface/ImageImageDescriptor.java
new file mode 100644
index 0000000..4b69fd2
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jface/ImageImageDescriptor.java
@@ -0,0 +1,47 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jpt.ui.internal.jface;
+
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.ImageData;
+
+/**
+ * Image descriptor for an image.
+ */
+public class ImageImageDescriptor extends ImageDescriptor 
+{
+	
+	private Image fImage;
+	
+	/**
+	 * Constructor for ImagImageDescriptor.
+	 */
+	public ImageImageDescriptor(Image image) {
+		super();
+		this.fImage = image;
+	}
+	
+	@Override
+	public boolean equals(Object obj) {
+		return (obj != null) && getClass().equals(obj.getClass()) && this.fImage.equals(((ImageImageDescriptor) obj).fImage);
+	}
+	
+	@Override
+	public ImageData getImageData() {
+		return this.fImage.getImageData();
+	}
+	
+	@Override
+	public int hashCode() {
+		return this.fImage.hashCode();
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jface/JarFileItemLabelProvider.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jface/JarFileItemLabelProvider.java
new file mode 100644
index 0000000..128f96f
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jface/JarFileItemLabelProvider.java
@@ -0,0 +1,46 @@
+/*******************************************************************************
+ *  Copyright (c) 2009  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.ui.internal.jface;
+
+import org.eclipse.jpt.core.context.java.JarFile;
+import org.eclipse.jpt.ui.JptUiPlugin;
+import org.eclipse.jpt.ui.internal.JptUiIcons;
+import org.eclipse.jpt.ui.jface.DelegatingContentAndLabelProvider;
+import org.eclipse.jpt.utility.internal.model.value.StaticPropertyValueModel;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.graphics.Image;
+
+public class JarFileItemLabelProvider extends AbstractItemLabelProvider
+{
+	public JarFileItemLabelProvider(
+			JarFile jarFile, DelegatingContentAndLabelProvider labelProvider) {
+		super(jarFile, labelProvider);
+	}
+	
+	
+	@Override
+	protected PropertyValueModel<Image> buildImageModel() {
+		return new StaticPropertyValueModel<Image>(JptUiPlugin.getImage(JptUiIcons.JAR_FILE));
+	}
+	
+	@Override
+	protected PropertyValueModel<String> buildTextModel() {
+		return new StaticPropertyValueModel<String>(((JarFile) model()).getResource().getName());
+	}
+	
+	@Override
+	protected PropertyValueModel<String> buildDescriptionModel() {
+		JarFile jarFile = (JarFile) model();
+		return new StaticPropertyValueModel<String>(
+			jarFile.getResource().getName()
+			+ " - " + jarFile.getResource().getParent().getFullPath().makeRelative().toString());
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jface/NullLabelProvider.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jface/NullLabelProvider.java
new file mode 100644
index 0000000..8483d32
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jface/NullLabelProvider.java
@@ -0,0 +1,60 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2008 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.ui.internal.jface;
+
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.jface.viewers.ILabelProviderListener;
+import org.eclipse.swt.graphics.Image;
+
+/**
+ * Null implementation of the ILabelProvider interface.
+ * Implemented as a singleton.
+ */
+public final class NullLabelProvider 
+	implements ILabelProvider 
+{
+	public static final NullLabelProvider INSTANCE = new NullLabelProvider();
+
+	public static ILabelProvider instance() {
+		return INSTANCE;
+	}
+
+	/**
+	 * Ensure a single instance.
+	 */
+	private NullLabelProvider() {
+		super();
+	}
+
+	public Image getImage(Object element) {
+		return null;
+	}
+
+	public String getText(Object element) {
+		return null;
+	}
+
+	public void addListener(ILabelProviderListener listener) {
+		// do nothing
+	}
+
+	public void dispose() {
+		// do nothing
+	}
+
+	public boolean isLabelProperty(Object element, String property) {
+		return false;
+	}
+
+	public void removeListener(ILabelProviderListener listener) {
+		// do nothing
+	}
+
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jface/NullTreeContentProvider.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jface/NullTreeContentProvider.java
new file mode 100644
index 0000000..fdb7e0a
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jface/NullTreeContentProvider.java
@@ -0,0 +1,60 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2008 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.ui.internal.jface;
+
+import org.eclipse.jface.viewers.ITreeContentProvider;
+import org.eclipse.jface.viewers.Viewer;
+
+/**
+ * Null implementation of the ILabelProvider interface.
+ * Implemented as a singleton.
+ */
+public final class NullTreeContentProvider
+	implements ITreeContentProvider 
+{
+	private static final Object[] EMPTY_ARRAY = new Object[0];
+	public static final NullTreeContentProvider INSTANCE = new NullTreeContentProvider();
+
+	public static ITreeContentProvider instance() {
+		return INSTANCE;
+	}
+
+	/**
+	 * Ensure a single instance.
+	 */
+	private NullTreeContentProvider() {
+		super();
+	}
+
+	public Object[] getChildren(Object parentElement) {
+		return EMPTY_ARRAY;
+	}
+
+	public Object getParent(Object element) {
+		return null;
+	}
+
+	public boolean hasChildren(Object element) {
+		return false;
+	}
+
+	public Object[] getElements(Object inputElement) {
+		return EMPTY_ARRAY;
+	}
+
+	public void dispose() {
+		// do nothing
+	}
+
+	public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+		// do nothing
+	}
+
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jface/StructuredContentProviderAdapter.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jface/StructuredContentProviderAdapter.java
new file mode 100644
index 0000000..a10cc2f
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jface/StructuredContentProviderAdapter.java
@@ -0,0 +1,265 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2009 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.ui.internal.jface;
+
+import org.eclipse.jface.viewers.AbstractListViewer;
+import org.eclipse.jface.viewers.IStructuredContentProvider;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jpt.ui.internal.listeners.SWTListChangeListenerWrapper;
+import org.eclipse.jpt.utility.internal.ArrayTools;
+import org.eclipse.jpt.utility.internal.StringTools;
+import org.eclipse.jpt.utility.internal.model.value.CollectionListValueModelAdapter;
+import org.eclipse.jpt.utility.model.event.ListAddEvent;
+import org.eclipse.jpt.utility.model.event.ListChangeEvent;
+import org.eclipse.jpt.utility.model.event.ListClearEvent;
+import org.eclipse.jpt.utility.model.event.ListMoveEvent;
+import org.eclipse.jpt.utility.model.event.ListRemoveEvent;
+import org.eclipse.jpt.utility.model.event.ListReplaceEvent;
+import org.eclipse.jpt.utility.model.listener.ListChangeListener;
+import org.eclipse.jpt.utility.model.value.CollectionValueModel;
+import org.eclipse.jpt.utility.model.value.ListValueModel;
+
+/**
+ * This adapter can be used to keep an AbstractListViewer
+ * (e.g. a ListViewer or ComboViewer) in synch with a ListValueModel
+ * (or a CollectionValueModel).
+ */
+public class StructuredContentProviderAdapter
+	implements IStructuredContentProvider
+{
+	/** The underlying model list. */
+	protected ListValueModel listHolder;
+
+	/** The list viewer we keep in synch with the model list. */
+	protected final AbstractListViewer listViewer;
+
+	/** A listener that allows us to forward changes made to the underlying model list. */
+	protected final ListChangeListener listChangeListener;
+
+
+	// ********** static **********
+
+	/**
+	 * Adapt the specified list viewer to the specified list holder so they
+	 * stay in synch.
+	 */
+	public static StructuredContentProviderAdapter adapt(AbstractListViewer listViewer, ListValueModel listHolder) {
+		// we need only construct the adapter and it will hook up to the list viewer etc.
+		return new StructuredContentProviderAdapter(listViewer, listHolder);
+	}
+
+	/**
+	 * Adapt the specified list viewer to the specified list holder so they
+	 * stay in synch.
+	 */
+	public static StructuredContentProviderAdapter adapt(AbstractListViewer listViewer, CollectionValueModel collectionHolder) {
+		// we need only construct the adapter and it will hook up to the list viewer etc.
+		return new StructuredContentProviderAdapter(listViewer, collectionHolder);
+	}
+
+
+	// ********** constructors **********
+
+	/**
+	 * Constructor.
+	 */
+	protected StructuredContentProviderAdapter(AbstractListViewer listViewer, ListValueModel listHolder) {
+		super();
+		this.listChangeListener = this.buildListChangeListener();
+		this.listViewer = listViewer;
+		this.listViewer.setContentProvider(this);
+		// the list viewer will call back to #inputChanged(Viewer, Object, Object)
+		this.listViewer.setInput(listHolder);
+	}
+
+	/**
+	 * Constructor.
+	 */
+	protected StructuredContentProviderAdapter(AbstractListViewer listViewer, CollectionValueModel collectionHolder) {
+		this(listViewer, new CollectionListValueModelAdapter(collectionHolder));
+	}
+
+
+	// ********** initialization **********
+
+	protected ListChangeListener buildListChangeListener() {
+		return new SWTListChangeListenerWrapper(this.buildListChangeListener_());
+	}
+
+	protected ListChangeListener buildListChangeListener_() {
+		return new ListChangeListener() {
+			public void itemsAdded(ListAddEvent e) {
+				StructuredContentProviderAdapter.this.itemsAdded(e);
+			}
+			public void itemsRemoved(ListRemoveEvent e) {
+				StructuredContentProviderAdapter.this.itemsRemoved(e);
+			}
+			public void itemsReplaced(ListReplaceEvent e) {
+				StructuredContentProviderAdapter.this.itemsReplaced(e);
+			}
+			public void itemsMoved(ListMoveEvent e) {
+				StructuredContentProviderAdapter.this.itemsMoved(e);
+			}
+			public void listCleared(ListClearEvent e) {
+				StructuredContentProviderAdapter.this.listCleared();
+			}
+			public void listChanged(ListChangeEvent e) {
+				StructuredContentProviderAdapter.this.listChanged();
+			}
+			@Override
+			public String toString() {
+				return "list listener";
+			}
+		};
+	}
+
+
+	// ********** IStructuredContentProvider implementation **********
+
+	public Object[] getElements(Object inputElement) {
+		if (inputElement != this.listHolder) {
+			throw new IllegalArgumentException("invalid input element: " + inputElement);
+		}
+		return this.listHolder.toArray();
+	}
+
+	/**
+	 * This is called by the list viewer, so don't update the list viewer here.
+	 */
+	public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+		if (viewer != this.listViewer) {
+			throw new IllegalArgumentException("invalid viewer: " + viewer);
+		}
+		if (oldInput != this.listHolder) {
+			throw new IllegalArgumentException("invalid old input: " + oldInput);
+		}
+		this.modelChanged((ListValueModel) oldInput, (ListValueModel) newInput);
+	}
+
+	public void dispose() {
+		// do nothing - listeners should've already been removed in #inputChanged(Viewer, Object, Object)
+	}
+
+
+	// ********** internal methods **********
+
+	protected void modelChanged(ListValueModel oldModel, ListValueModel newModel) {
+		if (oldModel != null) {
+			this.listHolder.removeListChangeListener(ListValueModel.LIST_VALUES, this.listChangeListener);
+		}
+		this.listHolder = newModel;
+		if (newModel != null) {
+			this.listHolder.addListChangeListener(ListValueModel.LIST_VALUES, this.listChangeListener);
+		}
+	}
+
+
+	// ********** public API **********
+
+	/**
+	 * Return the underlying list model.
+	 */
+	public ListValueModel model() {
+		return this.listHolder;
+	}
+
+	/**
+	 * Set the underlying list model.
+	 */
+	public void setModel(ListValueModel listHolder) {
+		// the list viewer will call back to #inputChanged(Viewer, Object, Object)
+		this.listViewer.setInput(listHolder);
+	}
+
+	/**
+	 * Set the underlying collection model.
+	 */
+	public void setModel(CollectionValueModel collectionHolder) {
+		this.setModel(new CollectionListValueModelAdapter(collectionHolder));
+	}
+
+
+	// ********** list change support **********
+
+	/**
+	 * Items were added to the underlying model list.
+	 * Synchronize the list viewer.
+	 */
+	protected void itemsAdded(ListAddEvent e) {
+		int i = e.getIndex();
+		for (Object item : e.getItems()) {
+			this.listViewer.insert(item, i++);
+		}
+	}
+
+	/**
+	 * Items were removed from the underlying model list.
+	 * Synchronize the list viewer.
+	 */
+	protected void itemsRemoved(ListRemoveEvent e) {
+		this.listViewer.remove(ArrayTools.array(e.getItems(), e.getItemsSize()));
+	}
+
+	/**
+	 * Items were replaced in the underlying model list.
+	 * Synchronize the list viewer.
+	 */
+	protected void itemsReplaced(ListReplaceEvent e) {
+		this.listViewer.remove(ArrayTools.array(e.getOldItems(), e.getItemsSize()));
+		int i = e.getIndex();
+		for (Object item : e.getNewItems()) {
+			this.listViewer.insert(item, i++);
+		}
+	}
+
+	/**
+	 * Items were moved in the underlying model list.
+	 * Synchronize the list viewer.
+	 */
+	protected void itemsMoved(ListMoveEvent e) {
+		int len = e.getLength();
+		Object[] items = new Object[len];
+		int offset = e.getSourceIndex();
+		for (int i = 0; i < len; i++) {
+			items[i] = this.listHolder.get(offset + i);
+		}
+		this.listViewer.remove(items);
+
+		offset = e.getTargetIndex();
+		for (int i = 0; i < len; i++) {
+			this.listViewer.insert(items[i], offset + i);
+		}
+	}
+
+	/**
+	 * The underlying model list was cleared.
+	 * Synchronize the list viewer.
+	 */
+	protected void listCleared() {
+		this.listViewer.refresh();
+	}
+
+	/**
+	 * The underlying model list has changed "dramatically".
+	 * Synchronize the list viewer.
+	 */
+	protected void listChanged() {
+		this.listViewer.refresh();
+	}
+
+
+	// ********** Object overrides **********
+
+	@Override
+	public String toString() {
+		return StringTools.buildToStringFor(this, this.listHolder);
+	}
+
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jface/XmlMappingFileViewerFilter.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jface/XmlMappingFileViewerFilter.java
new file mode 100644
index 0000000..9edf44a
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jface/XmlMappingFileViewerFilter.java
@@ -0,0 +1,88 @@
+/*******************************************************************************
+ * Copyright (c) 2009 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.ui.internal.jface;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.jdt.core.IClasspathEntry;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerFilter;
+import org.eclipse.jpt.core.JpaFile;
+import org.eclipse.jpt.core.JpaProject;
+import org.eclipse.jpt.core.JptCorePlugin;
+import org.eclipse.jpt.ui.JptUiPlugin;
+
+/**
+ * This filter will deny showing any file that are not XML mapping files or folders
+ * that don't contain any XML mapping files in its sub-hierarchy. An XML mapping
+ * file is one that has a corresponding JpaFile in the project with a mapping file
+ * content type.
+ * @see JptCorePlugin.MAPPING_FILE_CONTENT_TYPE
+ */
+public class XmlMappingFileViewerFilter extends ViewerFilter {
+
+	private final IJavaProject javaProject;
+
+	private final JpaProject jpaProject;
+	
+	public XmlMappingFileViewerFilter(JpaProject jpaProject) {
+		super();
+		this.jpaProject = jpaProject;
+		this.javaProject = jpaProject.getJavaProject();
+	}
+
+	/**
+	 * Determines whether the given file (an XML file) is a JPA mapping
+	 * descriptor file. 
+	 */
+	private boolean isMappingFile(IFile file) {
+		JpaFile jpaFile = this.jpaProject.getJpaFile(file);
+		return jpaFile != null ? jpaFile.getContentType().isKindOf(JptCorePlugin.MAPPING_FILE_CONTENT_TYPE): false;
+	}
+
+	@Override
+	public boolean select(Viewer viewer,
+	                      Object parentElement,
+	                      Object element) {
+
+		if (element instanceof IFile) {
+			return isMappingFile((IFile) element);
+		}
+		else if (element instanceof IFolder) {
+			IFolder folder = (IFolder) element;
+
+			try {
+				for (IClasspathEntry entry : this.javaProject.getRawClasspath()) {
+					if (entry.getEntryKind() == IClasspathEntry.CPE_SOURCE) {
+						if (entry.getPath().isPrefixOf(folder.getFullPath().makeRelative())) {
+							for (IResource resource : folder.members()) {
+								if (select(viewer, folder, resource)) {
+									return true;
+								}
+							}
+						}
+					}
+				}
+			}
+			catch (JavaModelException e) {
+				JptUiPlugin.log(e.getStatus());
+			}
+			catch (CoreException e) {
+				JptUiPlugin.log(e.getStatus());
+			}
+		}
+
+		return false;
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/Generic2_0JpaPlatformUiProvider.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/Generic2_0JpaPlatformUiProvider.java
new file mode 100644
index 0000000..fe92b59
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/Generic2_0JpaPlatformUiProvider.java
@@ -0,0 +1,77 @@
+/*******************************************************************************
+ * Copyright (c) 2009 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.ui.internal.jpa2;
+
+import java.util.List;
+import org.eclipse.jpt.ui.JpaPlatformUiProvider;
+import org.eclipse.jpt.ui.ResourceUiDefinition;
+import org.eclipse.jpt.ui.details.JpaDetailsProvider;
+import org.eclipse.jpt.ui.internal.AbstractJpaPlatformUiProvider;
+import org.eclipse.jpt.ui.internal.details.java.JavaPersistentAttributeDetailsProvider;
+import org.eclipse.jpt.ui.internal.details.java.JavaPersistentTypeDetailsProvider;
+import org.eclipse.jpt.ui.internal.details.orm.EntityMappingsDetailsProvider;
+import org.eclipse.jpt.ui.internal.details.orm.OrmXmlUiDefinition;
+import org.eclipse.jpt.ui.internal.details.orm.OrmPersistentAttributeDetailsProvider;
+import org.eclipse.jpt.ui.internal.details.orm.OrmPersistentTypeDetailsProvider;
+import org.eclipse.jpt.ui.internal.jpa2.details.java.Generic2_0JavaResourceUiDefinition;
+import org.eclipse.jpt.ui.internal.jpa2.details.orm.EntityMappings2_0DetailsProvider;
+import org.eclipse.jpt.ui.internal.jpa2.details.orm.OrmXml2_0UiDefinition;
+import org.eclipse.jpt.ui.internal.jpa2.persistence.PersistenceXml2_0UiDefinition;
+import org.eclipse.jpt.ui.internal.persistence.details.PersistenceXmlUiDefinition;
+
+/**
+ * All the state in the JPA platform should be "static" (i.e. unchanging once
+ * it is initialized).
+ */
+public class Generic2_0JpaPlatformUiProvider extends AbstractJpaPlatformUiProvider
+{
+
+	// singleton
+	private static final JpaPlatformUiProvider INSTANCE = new Generic2_0JpaPlatformUiProvider();
+
+	/**
+	 * Return the singleton.
+	 */
+	public static JpaPlatformUiProvider instance() {
+		return INSTANCE;
+	}
+
+	/**
+	 * Ensure single instance.
+	 */
+	private Generic2_0JpaPlatformUiProvider() {
+		super();
+	}
+
+
+	// ********** details providers **********
+	
+	@Override
+	protected void addDetailsProvidersTo(List<JpaDetailsProvider> providers) {
+		providers.add(JavaPersistentTypeDetailsProvider.instance());
+		providers.add(JavaPersistentAttributeDetailsProvider.instance());
+		providers.add(EntityMappingsDetailsProvider.instance());
+		providers.add(OrmPersistentTypeDetailsProvider.instance());
+		providers.add(OrmPersistentAttributeDetailsProvider.instance());
+		providers.add(EntityMappings2_0DetailsProvider.instance());
+	}
+	
+	
+	// ********** resource ui definitions **********
+	
+	@Override
+	protected void addResourceUiDefinitionsTo(List<ResourceUiDefinition> definitions) {
+		definitions.add(Generic2_0JavaResourceUiDefinition.instance());
+		definitions.add(OrmXmlUiDefinition.instance());
+		definitions.add(OrmXml2_0UiDefinition.instance());
+		definitions.add(PersistenceXmlUiDefinition.instance());
+		definitions.add(PersistenceXml2_0UiDefinition.instance());
+	}
+}
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/GenericOrmXml2_0UiFactory.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/GenericOrmXml2_0UiFactory.java
new file mode 100644
index 0000000..0c3d3c8
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/GenericOrmXml2_0UiFactory.java
@@ -0,0 +1,147 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 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.ui.internal.jpa2;
+
+import org.eclipse.jpt.core.context.orm.OrmBasicMapping;
+import org.eclipse.jpt.core.context.orm.OrmEmbeddedIdMapping;
+import org.eclipse.jpt.core.context.orm.OrmEmbeddedMapping;
+import org.eclipse.jpt.core.context.orm.OrmEntity;
+import org.eclipse.jpt.core.context.orm.OrmIdMapping;
+import org.eclipse.jpt.core.context.orm.OrmManyToManyMapping;
+import org.eclipse.jpt.core.context.orm.OrmManyToOneMapping;
+import org.eclipse.jpt.core.context.orm.OrmOneToManyMapping;
+import org.eclipse.jpt.core.context.orm.OrmOneToOneMapping;
+import org.eclipse.jpt.core.context.orm.OrmTransientMapping;
+import org.eclipse.jpt.core.context.orm.OrmVersionMapping;
+import org.eclipse.jpt.core.jpa2.context.orm.OrmElementCollectionMapping2_0;
+import org.eclipse.jpt.ui.WidgetFactory;
+import org.eclipse.jpt.ui.details.JpaComposite;
+import org.eclipse.jpt.ui.internal.details.TransientMappingComposite;
+import org.eclipse.jpt.ui.internal.details.orm.BaseOrmXmlUiFactory;
+import org.eclipse.jpt.ui.internal.jpa2.details.orm.OrmBasicMapping2_0Composite;
+import org.eclipse.jpt.ui.internal.jpa2.details.orm.OrmElementCollectionMapping2_0Composite;
+import org.eclipse.jpt.ui.internal.jpa2.details.orm.OrmEmbeddedIdMapping2_0Composite;
+import org.eclipse.jpt.ui.internal.jpa2.details.orm.OrmEmbeddedMapping2_0Composite;
+import org.eclipse.jpt.ui.internal.jpa2.details.orm.OrmEntity2_0Composite;
+import org.eclipse.jpt.ui.internal.jpa2.details.orm.OrmIdMapping2_0Composite;
+import org.eclipse.jpt.ui.internal.jpa2.details.orm.OrmManyToManyMapping2_0Composite;
+import org.eclipse.jpt.ui.internal.jpa2.details.orm.OrmManyToOneMapping2_0Composite;
+import org.eclipse.jpt.ui.internal.jpa2.details.orm.OrmOneToManyMapping2_0Composite;
+import org.eclipse.jpt.ui.internal.jpa2.details.orm.OrmOneToOneMapping2_0Composite;
+import org.eclipse.jpt.ui.internal.jpa2.details.orm.OrmVersionMapping2_0Composite;
+import org.eclipse.jpt.ui.jpa2.details.orm.OrmXmlUiFactory2_0;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+public class GenericOrmXml2_0UiFactory 
+	extends BaseOrmXmlUiFactory
+	implements OrmXmlUiFactory2_0
+{
+	// **************** orm type mapping composites ****************************
+		
+	@Override
+	public JpaComposite createOrmEntityComposite(
+			PropertyValueModel<OrmEntity> subjectHolder,
+			Composite parent,
+			WidgetFactory widgetFactory) {
+		return new OrmEntity2_0Composite(subjectHolder, parent, widgetFactory);
+	}
+
+	
+	// **************** orm attribute mapping composites ***********************
+	
+	@Override
+	public JpaComposite createOrmIdMappingComposite(
+			PropertyValueModel<OrmIdMapping> subjectHolder,
+			Composite parent,
+			WidgetFactory widgetFactory) {
+		return new OrmIdMapping2_0Composite(subjectHolder, parent, widgetFactory);
+	}
+	
+	@Override
+	public JpaComposite createOrmEmbeddedIdMappingComposite(
+			PropertyValueModel<OrmEmbeddedIdMapping> subjectHolder,
+			Composite parent,
+			WidgetFactory widgetFactory) {
+		return new OrmEmbeddedIdMapping2_0Composite(subjectHolder, parent, widgetFactory);
+	}
+	
+	@Override
+	public JpaComposite createOrmBasicMappingComposite(
+			PropertyValueModel<OrmBasicMapping> subjectHolder,
+			Composite parent,
+			WidgetFactory widgetFactory) {
+		return new OrmBasicMapping2_0Composite(subjectHolder, parent, widgetFactory);
+	}
+	
+	@Override
+	public JpaComposite createOrmVersionMappingComposite(
+			PropertyValueModel<OrmVersionMapping> subjectHolder,
+			Composite parent,
+			WidgetFactory widgetFactory) {
+		return new OrmVersionMapping2_0Composite(subjectHolder, parent, widgetFactory);
+	}
+	
+	@Override
+	public JpaComposite createOrmManyToOneMappingComposite(
+			PropertyValueModel<OrmManyToOneMapping> subjectHolder,
+			Composite parent,
+			WidgetFactory widgetFactory) {
+		return new OrmManyToOneMapping2_0Composite(subjectHolder, parent, widgetFactory);
+	}
+	
+	@Override
+	public JpaComposite createOrmOneToManyMappingComposite(
+			PropertyValueModel<OrmOneToManyMapping> subjectHolder,
+			Composite parent,
+			WidgetFactory widgetFactory) {
+		return new OrmOneToManyMapping2_0Composite(subjectHolder, parent, widgetFactory);
+	}
+	
+	@Override
+	public JpaComposite createOrmOneToOneMappingComposite(
+			PropertyValueModel<OrmOneToOneMapping> subjectHolder,
+			Composite parent,
+			WidgetFactory widgetFactory) {
+		return new OrmOneToOneMapping2_0Composite(subjectHolder, parent, widgetFactory);
+	}
+	
+	@Override
+	public JpaComposite createOrmManyToManyMappingComposite(
+			PropertyValueModel<OrmManyToManyMapping> subjectHolder,
+			Composite parent,
+			WidgetFactory widgetFactory) {
+		return new OrmManyToManyMapping2_0Composite(subjectHolder, parent, widgetFactory);
+	}
+	
+	@Override
+	public JpaComposite createOrmEmbeddedMappingComposite(
+			PropertyValueModel<OrmEmbeddedMapping> subjectHolder,
+			Composite parent,
+			WidgetFactory widgetFactory) {
+		return new OrmEmbeddedMapping2_0Composite(subjectHolder, parent, widgetFactory);
+	}
+	
+	@Override
+	public JpaComposite createOrmTransientMappingComposite(
+			PropertyValueModel<OrmTransientMapping> subjectHolder,
+			Composite parent,
+			WidgetFactory widgetFactory) {
+		return new TransientMappingComposite(subjectHolder, parent, widgetFactory);
+	}
+	
+	public JpaComposite createOrmElementCollectionMapping2_0Composite(
+			PropertyValueModel<OrmElementCollectionMapping2_0> subjectHolder,
+			Composite parent,
+			WidgetFactory widgetFactory) {
+		return new OrmElementCollectionMapping2_0Composite(subjectHolder, parent, widgetFactory);
+	}
+
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/Jpa2_0ProjectFlagModel.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/Jpa2_0ProjectFlagModel.java
new file mode 100644
index 0000000..295a3e7
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/Jpa2_0ProjectFlagModel.java
@@ -0,0 +1,31 @@
+/*******************************************************************************
+ * Copyright (c) 2010 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.ui.internal.jpa2;
+
+import org.eclipse.jpt.core.JpaNode;
+import org.eclipse.jpt.core.JptCorePlugin;
+import org.eclipse.jpt.utility.internal.model.value.TransformationPropertyValueModel;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+
+/**
+ * Flag indicating whether the JPA project supports JPA 2.0.
+ */
+public class Jpa2_0ProjectFlagModel<T extends JpaNode>
+	extends TransformationPropertyValueModel<T, Boolean>
+{
+	public Jpa2_0ProjectFlagModel(PropertyValueModel<T> jpaProjectModel) { 
+		super(jpaProjectModel);
+	}
+
+	@Override
+	protected Boolean transform_(T value) {
+		return Boolean.valueOf(JptCorePlugin.nodeIsJpa2_0Compatible(value));
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/AbstractElementCollectionMapping2_0Composite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/AbstractElementCollectionMapping2_0Composite.java
new file mode 100644
index 0000000..e2f657c
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/AbstractElementCollectionMapping2_0Composite.java
@@ -0,0 +1,376 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2010 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.ui.internal.jpa2.details;
+
+import org.eclipse.jpt.core.context.BasicMapping;
+import org.eclipse.jpt.core.context.Column;
+import org.eclipse.jpt.core.context.Converter;
+import org.eclipse.jpt.core.context.ConvertibleMapping;
+import org.eclipse.jpt.core.context.EnumeratedConverter;
+import org.eclipse.jpt.core.context.TemporalConverter;
+import org.eclipse.jpt.core.jpa2.context.CollectionTable2_0;
+import org.eclipse.jpt.core.jpa2.context.ElementCollectionMapping2_0;
+import org.eclipse.jpt.ui.WidgetFactory;
+import org.eclipse.jpt.ui.details.JpaComposite;
+import org.eclipse.jpt.ui.internal.details.ColumnComposite;
+import org.eclipse.jpt.ui.internal.details.EnumTypeComposite;
+import org.eclipse.jpt.ui.internal.details.FetchTypeComposite;
+import org.eclipse.jpt.ui.internal.details.JptUiDetailsMessages;
+import org.eclipse.jpt.ui.internal.details.TemporalTypeComposite;
+import org.eclipse.jpt.ui.internal.util.ControlSwitcher;
+import org.eclipse.jpt.ui.internal.widgets.Pane;
+import org.eclipse.jpt.utility.internal.Transformer;
+import org.eclipse.jpt.utility.internal.model.value.PropertyAspectAdapter;
+import org.eclipse.jpt.utility.internal.model.value.SimplePropertyValueModel;
+import org.eclipse.jpt.utility.internal.model.value.TransformationPropertyValueModel;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.jpt.utility.model.value.WritablePropertyValueModel;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.ui.part.PageBook;
+
+/**
+ * Here the layout of this pane:
+ * <pre>
+ * -----------------------------------------------------------------------------
+ * | ------------------------------------------------------------------------- |
+ * | |                                                                       | |
+ * | | ColumnComposite                                                       | |
+ * | |                                                                       | |
+ * | ------------------------------------------------------------------------- |
+ * | ------------------------------------------------------------------------- |
+ * | |                                                                       | |
+ * | | FetchTypeComposite                                                    | |
+ * | |                                                                       | |
+ * | ------------------------------------------------------------------------- |
+ * | ------------------------------------------------------------------------- |
+ * | |                                                                       | |
+ * | | TemporalTypeComposite                                                 | |
+ * | |                                                                       | |
+ * | ------------------------------------------------------------------------- |
+ * | ------------------------------------------------------------------------- |
+ * | |                                                                       | |
+ * | | EnumTypeComposite                                                     | |
+ * | |                                                                       | |
+ * | ------------------------------------------------------------------------- |
+ * | ------------------------------------------------------------------------- |
+ * | |                                                                       | |
+ * | | OptionalComposite                                                     | |
+ * | |                                                                       | |
+ * | ------------------------------------------------------------------------- |
+ * | ------------------------------------------------------------------------- |
+ * | |                                                                       | |
+ * | | LobComposite                                                          | |
+ * | |                                                                       | |
+ * | ------------------------------------------------------------------------- |
+ * -----------------------------------------------------------------------------</pre>
+ *
+ * @see BasicMapping
+ * @see OrderColumnComposite
+ * @see EnumTypeComposite
+ * @see FetchTypeComposite
+ * @see LobComposite
+ * @see OptionalComposite
+ * @see TemporalTypeComposite
+ *
+ * @version 2.3
+ * @since 2.3
+ */
+public abstract class AbstractElementCollectionMapping2_0Composite<T extends ElementCollectionMapping2_0> 
+	extends Pane<T>
+	implements JpaComposite
+{
+		
+	private Composite basicValueComposite;
+	
+	private Composite embeddableValueComposite;
+	
+	/**
+	 * Creates a new <code>BasicMappingComposite</code>.
+	 *
+	 * @param subjectHolder The holder of the subject <code>IBasicMapping</code>
+	 * @param parent The parent container
+	 * @param widgetFactory The factory used to create various common widgets
+	 */
+	protected AbstractElementCollectionMapping2_0Composite(PropertyValueModel<? extends T> subjectHolder,
+	                             Composite parent,
+	                             WidgetFactory widgetFactory) {
+
+		super(subjectHolder, parent, widgetFactory);
+	}
+	@Override
+	protected void initializeLayout(Composite container) {
+		initializeElementCollectionCollapsibleSection(container);
+		initializeValueCollapsibleSection(container);
+		initializeKeyCollapsibleSection(container);
+		initializeOrderingCollapsibleSection(container);
+	}
+	
+	protected void initializeElementCollectionCollapsibleSection(Composite container) {
+		container = addCollapsibleSection(
+			container,
+			JptUiDetailsMessages2_0.ElementCollectionSection_title,
+			new SimplePropertyValueModel<Boolean>(Boolean.TRUE)
+		);
+
+		this.initializeElementCollectionSection(container);
+	}
+
+	protected void initializeElementCollectionSection(Composite container) {
+		new TargetClassComposite(this, container);
+		new FetchTypeComposite(this, container);
+		new CollectionTable2_0Composite(this, buildCollectionTableHolder(), container);
+	}
+
+	protected void initializeOrderingCollapsibleSection(Composite container) {
+		new Ordering2_0Composite(this, container);
+	}
+	
+	protected void initializeValueCollapsibleSection(Composite container) {
+		Composite valueSection = addCollapsibleSection(
+			container,
+			JptUiDetailsMessages2_0.AbstractElementCollectionMapping2_0_Composite_valueSectionTitle
+		);
+		initializeValueSection(valueSection);
+	}
+	
+	protected void initializeKeyCollapsibleSection(Composite container) {
+		
+	}
+
+	protected void initializeValueSection(Composite container) {
+		PageBook pageBook = new PageBook(container, SWT.NULL);
+		GridData gd = new GridData(GridData.FILL_HORIZONTAL);
+		gd.horizontalIndent = 5;
+		pageBook.setLayoutData(gd);
+
+		this.initializeBasicValueSection(pageBook);
+		this.initializeEmbeddableValueSection(pageBook);
+		
+		installValueControlSwitcher(pageBook);
+	}
+	
+	protected void initializeBasicValueSection(Composite container) {
+		this.basicValueComposite = addSubPane(container);
+
+		new ColumnComposite(this, buildValueColumnHolder(), this.basicValueComposite);
+
+		// type section
+		Composite converterSection = addCollapsibleSubSection(
+			this.basicValueComposite,
+			JptUiDetailsMessages.TypeSection_type,
+			new SimplePropertyValueModel<Boolean>(Boolean.FALSE)
+		);
+		((GridLayout) converterSection.getLayout()).numColumns = 2;
+
+		// No converter
+		Button noConverterButton = addRadioButton(
+			converterSection, 
+			JptUiDetailsMessages.TypeSection_default, 
+			buildNoConverterHolder(), 
+			null);
+		((GridData) noConverterButton.getLayoutData()).horizontalSpan = 2;
+		
+		// Lob
+		Button lobButton = addRadioButton(
+			converterSection, 
+			JptUiDetailsMessages.TypeSection_lob, 
+			buildLobConverterHolder(), 
+			null);
+		((GridData) lobButton.getLayoutData()).horizontalSpan = 2;
+		
+		
+		PropertyValueModel<Converter> converterHolder = buildConverterHolder();
+		// Temporal
+		addRadioButton(
+			converterSection, 
+			JptUiDetailsMessages.TypeSection_temporal, 
+			buildTemporalBooleanHolder(), 
+			null);
+		registerSubPane(new TemporalTypeComposite(buildTemporalConverterHolder(converterHolder), converterSection, getWidgetFactory()));
+		
+		
+		// Enumerated
+		addRadioButton(
+			converterSection, 
+			JptUiDetailsMessages.TypeSection_enumerated, 
+			buildEnumeratedBooleanHolder(), 
+			null);
+		registerSubPane(new EnumTypeComposite(buildEnumeratedConverterHolder(converterHolder), converterSection, getWidgetFactory()));
+	}
+	
+	protected void initializeEmbeddableValueSection(Composite container) {
+		this.embeddableValueComposite = new ElementCollectionValueOverridesComposite(this, container).getControl();
+	}
+
+	private void installValueControlSwitcher(PageBook pageBook) {
+
+		new ControlSwitcher(
+			buildValueHolder(),
+			buildPaneTransformer(),
+			pageBook
+		);
+	}
+	
+	protected PropertyValueModel<ElementCollectionMapping2_0.Type> buildValueHolder() {
+		return new PropertyAspectAdapter<T, ElementCollectionMapping2_0.Type>(
+				this.getSubjectHolder(), ElementCollectionMapping2_0.VALUE_TYPE_PROPERTY) {
+			@Override
+			protected ElementCollectionMapping2_0.Type buildValue_() {
+				return this.subject.getValueType();
+			}
+		};
+	}
+
+	private Transformer<ElementCollectionMapping2_0.Type, Control> buildPaneTransformer() {
+		return new Transformer<ElementCollectionMapping2_0.Type, Control>() {
+			public Control transform(ElementCollectionMapping2_0.Type type) {
+				return AbstractElementCollectionMapping2_0Composite.this.transformValueType(type);
+			}
+		};
+	}
+
+	/**
+	 * Given the selected override, return the control that will be displayed
+	 */
+	protected Control transformValueType(ElementCollectionMapping2_0.Type type) {
+		if (type == null) {
+			return null;
+		}
+		switch (type) {
+			case BASIC_TYPE :
+				return this.basicValueComposite;
+			case EMBEDDABLE_TYPE :
+				return this.embeddableValueComposite;
+			default :
+				return null;
+		}
+	}
+	
+	protected PropertyValueModel<CollectionTable2_0> buildCollectionTableHolder() {
+		return new PropertyAspectAdapter<ElementCollectionMapping2_0, CollectionTable2_0>(getSubjectHolder()) {
+			@Override
+			protected CollectionTable2_0 buildValue_() {
+				return this.subject.getCollectionTable();
+			}
+		};
+	}
+	
+	protected PropertyValueModel<Column> buildValueColumnHolder() {
+		return new PropertyAspectAdapter<ElementCollectionMapping2_0, Column>(getSubjectHolder()) {
+			@Override
+			protected Column buildValue_() {
+				return this.subject.getValueColumn();
+			}
+		};
+	}
+
+	private WritablePropertyValueModel<Boolean> buildNoConverterHolder() {
+		return new PropertyAspectAdapter<T, Boolean>(getSubjectHolder(), ConvertibleMapping.CONVERTER_PROPERTY) {
+			@Override
+			protected Boolean buildValue_() {
+				return Boolean.valueOf(this.subject.getConverter().getType() == Converter.NO_CONVERTER);
+			}
+
+			@Override
+			protected void setValue_(Boolean value) {
+				if (value.booleanValue()) {
+					this.subject.setConverter(Converter.NO_CONVERTER);
+				}
+			}
+		};
+	}
+	
+	private WritablePropertyValueModel<Boolean> buildLobConverterHolder() {
+		return new PropertyAspectAdapter<T, Boolean>(getSubjectHolder(), ConvertibleMapping.CONVERTER_PROPERTY) {
+			@Override
+			protected Boolean buildValue_() {
+				Converter converter = this.subject.getConverter();
+				return Boolean.valueOf(converter.getType() == Converter.LOB_CONVERTER);
+			}
+
+			@Override
+			protected void setValue_(Boolean value) {
+				if (value.booleanValue()) {
+					this.subject.setConverter(Converter.LOB_CONVERTER);
+				}
+			}
+		};
+	}
+	
+	private PropertyValueModel<Converter> buildConverterHolder() {
+		return new PropertyAspectAdapter<T, Converter>(getSubjectHolder(), ConvertibleMapping.CONVERTER_PROPERTY) {
+			@Override
+			protected Converter buildValue_() {
+				return this.subject.getConverter();
+			}
+		};
+	}
+	
+	private PropertyValueModel<TemporalConverter> buildTemporalConverterHolder(PropertyValueModel<Converter> converterHolder) {
+		return new TransformationPropertyValueModel<Converter, TemporalConverter>(converterHolder) {
+			@Override
+			protected TemporalConverter transform_(Converter converter) {
+				return converter.getType() == Converter.TEMPORAL_CONVERTER ? (TemporalConverter) converter : null;
+			}
+		};
+	}
+	
+	private PropertyValueModel<EnumeratedConverter> buildEnumeratedConverterHolder(PropertyValueModel<Converter> converterHolder) {
+		return new TransformationPropertyValueModel<Converter, EnumeratedConverter>(converterHolder) {
+			@Override
+			protected EnumeratedConverter transform_(Converter converter) {
+				return converter.getType() == Converter.ENUMERATED_CONVERTER ? (EnumeratedConverter) converter : null;
+			}
+		};
+	}
+
+	private WritablePropertyValueModel<Boolean> buildTemporalBooleanHolder() {
+		return new PropertyAspectAdapter<T, Boolean>(getSubjectHolder(), ConvertibleMapping.CONVERTER_PROPERTY) {
+			@Override
+			protected Boolean buildValue_() {
+				Converter converter = this.subject.getConverter();
+				return Boolean.valueOf(converter.getType() == Converter.TEMPORAL_CONVERTER);
+			}
+
+			@Override
+			protected void setValue_(Boolean value) {
+				if (value.booleanValue()) {
+					this.subject.setConverter(Converter.TEMPORAL_CONVERTER);
+				}
+			}
+		};
+	}
+	
+	private WritablePropertyValueModel<Boolean> buildEnumeratedBooleanHolder() {
+		return new PropertyAspectAdapter<T, Boolean>(getSubjectHolder(), ConvertibleMapping.CONVERTER_PROPERTY) {
+			@Override
+			protected Boolean buildValue_() {
+				Converter converter = this.subject.getConverter();
+				return Boolean.valueOf(converter.getType() == Converter.ENUMERATED_CONVERTER);
+			}
+
+			@Override
+			protected void setValue_(Boolean value) {
+				if (value.booleanValue()) {
+					this.subject.setConverter(Converter.ENUMERATED_CONVERTER);
+				}
+			}
+		};
+	}
+	protected Composite addPane(Composite container, int groupBoxMargin) {
+		return addSubPane(container, 0, groupBoxMargin, 0, groupBoxMargin);
+	}
+
+}
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/AbstractElementCollectionMapping2_0UiDefinition.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/AbstractElementCollectionMapping2_0UiDefinition.java
new file mode 100644
index 0000000..49f5ea8
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/AbstractElementCollectionMapping2_0UiDefinition.java
@@ -0,0 +1,42 @@
+/*******************************************************************************
+ *  Copyright (c) 2009  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.ui.internal.jpa2.details;
+
+import org.eclipse.jpt.core.jpa2.MappingKeys2_0;
+import org.eclipse.jpt.core.jpa2.context.ElementCollectionMapping2_0;
+import org.eclipse.jpt.ui.internal.JpaMappingImageHelper;
+import org.eclipse.jpt.ui.internal.details.AbstractMappingUiDefinition;
+import org.eclipse.swt.graphics.Image;
+
+public abstract class AbstractElementCollectionMapping2_0UiDefinition<M, T extends ElementCollectionMapping2_0>
+	extends AbstractMappingUiDefinition<M, T>
+{
+	protected AbstractElementCollectionMapping2_0UiDefinition() {
+		super();
+	}
+	
+	
+	public Image getImage() {
+		return JpaMappingImageHelper.imageForAttributeMapping(getKey());
+	}
+	
+	public String getLabel() {
+		return JptUiDetailsMessages2_0.ElementCollectionMapping2_0_label;
+	}
+	
+	public String getLinkLabel() {
+		return JptUiDetailsMessages2_0.ElementCollectionMapping2_0_linkLabel;
+	}
+	
+	public String getKey() {
+		return MappingKeys2_0.ELEMENT_COLLECTION_ATTRIBUTE_MAPPING_KEY;
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/AbstractManyToOneMapping2_0Composite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/AbstractManyToOneMapping2_0Composite.java
new file mode 100644
index 0000000..dc60043
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/AbstractManyToOneMapping2_0Composite.java
@@ -0,0 +1,58 @@
+/*******************************************************************************
+ *  Copyright (c) 2009, 2010  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.ui.internal.jpa2.details;
+
+import org.eclipse.jpt.core.context.ManyToOneMapping;
+import org.eclipse.jpt.core.jpa2.context.DerivedIdentity2_0;
+import org.eclipse.jpt.core.jpa2.context.ManyToOneMapping2_0;
+import org.eclipse.jpt.core.jpa2.context.ManyToOneRelationshipReference2_0;
+import org.eclipse.jpt.ui.WidgetFactory;
+import org.eclipse.jpt.ui.internal.details.AbstractManyToOneMappingComposite;
+import org.eclipse.jpt.utility.internal.model.value.PropertyAspectAdapter;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+public abstract class AbstractManyToOneMapping2_0Composite<T extends ManyToOneMapping, R extends ManyToOneRelationshipReference2_0>
+	extends AbstractManyToOneMappingComposite<T, R>
+{
+	protected AbstractManyToOneMapping2_0Composite(
+			PropertyValueModel<? extends T> subjectHolder,
+	        Composite parent,
+	        WidgetFactory widgetFactory) {
+
+		super(subjectHolder, parent, widgetFactory);
+	}
+
+	@Override
+	protected void initializeLayout(Composite container) {
+		initializeManyToOneCollapsibleSection(container);
+		initializeDerivedIdentityCollapsibleSection(container);
+		initializeJoiningStrategyCollapsibleSection(container);
+	}
+
+	protected void initializeDerivedIdentityCollapsibleSection(Composite container) {
+		new DerivedIdentity2_0Pane(this, buildDerivedIdentityHolder(), container);
+	}
+
+	@Override
+	protected void initializeJoiningStrategyCollapsibleSection(Composite container) {
+		new ManyToOneJoiningStrategy2_0Pane(this, buildJoiningHolder(), container);
+	}
+
+	protected PropertyValueModel<DerivedIdentity2_0> buildDerivedIdentityHolder() {
+		return new PropertyAspectAdapter<T, DerivedIdentity2_0>(getSubjectHolder()) {
+			@Override
+			protected DerivedIdentity2_0 buildValue_() {
+				return ((ManyToOneMapping2_0) this.subject).getDerivedIdentity();
+			}
+		};
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/AbstractOneToOneMapping2_0Composite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/AbstractOneToOneMapping2_0Composite.java
new file mode 100644
index 0000000..90f5a31
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/AbstractOneToOneMapping2_0Composite.java
@@ -0,0 +1,54 @@
+/*******************************************************************************
+ *  Copyright (c) 2009, 2010  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.ui.internal.jpa2.details;
+
+import org.eclipse.jpt.core.context.OneToOneMapping;
+import org.eclipse.jpt.core.jpa2.context.DerivedIdentity2_0;
+import org.eclipse.jpt.core.jpa2.context.OneToOneMapping2_0;
+import org.eclipse.jpt.core.jpa2.context.OneToOneRelationshipReference2_0;
+import org.eclipse.jpt.ui.WidgetFactory;
+import org.eclipse.jpt.ui.internal.details.AbstractOneToOneMappingComposite;
+import org.eclipse.jpt.utility.internal.model.value.PropertyAspectAdapter;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+public abstract class AbstractOneToOneMapping2_0Composite<T extends OneToOneMapping, R extends OneToOneRelationshipReference2_0>
+	extends AbstractOneToOneMappingComposite<T, R>
+{
+	protected AbstractOneToOneMapping2_0Composite(
+			PropertyValueModel<? extends T> subjectHolder,
+	        Composite parent,
+	        WidgetFactory widgetFactory) {
+
+		super(subjectHolder, parent, widgetFactory);
+	}
+
+	@Override
+	protected void initializeLayout(Composite container) {
+		initializeOneToOneCollapsibleSection(container);
+		initializeDerivedIdentityCollapsibleSection(container);
+		initializeJoiningStrategyCollapsibleSection(container);
+	}
+
+	protected void initializeDerivedIdentityCollapsibleSection(Composite container) {
+		new DerivedIdentity2_0Pane(this, buildDerivedIdentityHolder(), container);
+	}
+	
+	
+	protected PropertyValueModel<DerivedIdentity2_0> buildDerivedIdentityHolder() {
+		return new PropertyAspectAdapter<T, DerivedIdentity2_0>(getSubjectHolder()) {
+			@Override
+			protected DerivedIdentity2_0 buildValue_() {
+				return ((OneToOneMapping2_0) this.subject).getDerivedIdentity();
+			}
+		};
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/AssociationOverride2_0Composite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/AssociationOverride2_0Composite.java
new file mode 100644
index 0000000..8bea9e5
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/AssociationOverride2_0Composite.java
@@ -0,0 +1,82 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 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.ui.internal.jpa2.details;
+
+import org.eclipse.jpt.core.context.AssociationOverride;
+import org.eclipse.jpt.core.jpa2.context.AssociationOverrideRelationshipReference2_0;
+import org.eclipse.jpt.ui.internal.details.AssociationOverrideComposite;
+import org.eclipse.jpt.ui.internal.details.JoinTableJoiningStrategyPane;
+import org.eclipse.jpt.ui.internal.details.JptUiDetailsMessages;
+import org.eclipse.jpt.ui.internal.widgets.Pane;
+import org.eclipse.jpt.utility.internal.model.value.TransformationPropertyValueModel;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * Here the layout of this pane:
+ * <pre>
+ * -----------------------------------------------------------------------------
+ * |                                                                           |
+ * | JoinColumnJoiningStrategyPane                                             |
+ * | JoinTableJoiningStrategyPane                                              |
+ * |                                                                           |
+ * -----------------------------------------------------------------------------</pre>
+ *
+ * @see AssociationOverride
+ * @see EntityOverridesComposite - The parent container
+ * @see JoinColumnsComposite
+ *
+ * @version 2.3
+ * @since 1.0
+ */
+public class AssociationOverride2_0Composite
+	extends AssociationOverrideComposite
+{
+	/**
+	 * Creates a new <code>AssociationOverrideComposite</code>.
+	 *
+	 * @param subjectHolder The holder of the subject <code>AssociationOverride</code>
+	 * @param parent The parent container
+	 * @param widgetFactory The factory used to create various common widgets
+	 */
+	public AssociationOverride2_0Composite(Pane<?> parentPane, 
+			PropertyValueModel<? extends AssociationOverride> subjectHolder,
+			Composite parent) {
+		
+		super(parentPane, subjectHolder, parent);
+	}
+	
+	
+	@Override
+	protected void initializeLayout(Composite container) {
+		Composite composite = addTitledGroup(
+				container,
+				JptUiDetailsMessages.Joining_title);
+		
+		addJoinColumnJoiningStrategyPane(composite);
+		
+		addJoinTableJoiningStrategyPane(composite);
+		
+		addSubPane(composite, 5);
+	}
+	
+	protected void addJoinTableJoiningStrategyPane(Composite container) {
+		new JoinTableJoiningStrategyPane(this, buildRelationshipReferenceHolder(), container);		
+	}
+	
+	private PropertyValueModel<AssociationOverrideRelationshipReference2_0> buildRelationshipReferenceHolder() {
+		return new TransformationPropertyValueModel<AssociationOverride, AssociationOverrideRelationshipReference2_0>(getSubjectHolder()) {
+			@Override
+			protected AssociationOverrideRelationshipReference2_0 transform_(AssociationOverride value) {
+				return (AssociationOverrideRelationshipReference2_0) value.getRelationshipReference();
+			}
+		};
+	}
+}
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/Cacheable2_0Pane.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/Cacheable2_0Pane.java
new file mode 100644
index 0000000..3332721
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/Cacheable2_0Pane.java
@@ -0,0 +1,107 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2010 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.ui.internal.jpa2.details;
+
+import org.eclipse.jpt.core.jpa2.context.Cacheable2_0;
+import org.eclipse.jpt.ui.internal.JpaHelpContextIds;
+import org.eclipse.jpt.ui.internal.details.JptUiDetailsMessages;
+import org.eclipse.jpt.ui.internal.widgets.Pane;
+import org.eclipse.jpt.utility.internal.model.value.PropertyAspectAdapter;
+import org.eclipse.jpt.utility.internal.model.value.TransformationPropertyValueModel;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.jpt.utility.model.value.WritablePropertyValueModel;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * Here the layout of this pane:
+ * <pre>
+ * -----------------------------------------------------------------------------
+ * | [X]  Cacheable (true/false)
+ * -----------------------------------------------------------------------------</pre>
+ *
+ * @see Cacheable2_0
+ * @see JavaEntity2_0Composite - A container of this widget
+ * @see OrmEntity2_0Composite - A container of this widget
+ */
+public class Cacheable2_0Pane 
+	extends Pane<Cacheable2_0>
+{
+	public Cacheable2_0Pane(
+			Pane<?> parentPane,
+			PropertyValueModel<? extends Cacheable2_0> subjectHolder,
+	        Composite parent) {
+		
+		super(parentPane, subjectHolder, parent);
+	}
+	
+	
+	@Override
+	protected void initializeLayout(Composite container) {
+		addTriStateCheckBoxWithDefault(
+			container,
+			JptUiDetailsMessages2_0.Entity_cacheableLabel,
+			buildCacheableBooleanHolder(),
+			buildCacheableStringHolder(),
+			JpaHelpContextIds.ENTITY_CACHEABLE
+		);
+	}
+	
+
+	private WritablePropertyValueModel<Boolean> buildCacheableBooleanHolder() {
+		return new PropertyAspectAdapter<Cacheable2_0, Boolean>(
+			getSubjectHolder(),
+			Cacheable2_0.DEFAULT_CACHEABLE_PROPERTY,
+			Cacheable2_0.SPECIFIED_CACHEABLE_PROPERTY)
+		{
+			@Override
+			protected Boolean buildValue_() {
+				return this.subject.getSpecifiedCacheable();
+			}
+
+			@Override
+			protected void setValue_(Boolean value) {
+				this.subject.setSpecifiedCacheable(value);
+			}
+		};
+	}
+
+	private PropertyValueModel<String> buildCacheableStringHolder() {
+
+		return new TransformationPropertyValueModel<Boolean, String>(buildDefaultCacheableHolder()) {
+
+			@Override
+			protected String transform(Boolean value) {
+				if (value != null) {
+					String defaultStringValue = value.booleanValue() ? JptUiDetailsMessages.Boolean_True : JptUiDetailsMessages.Boolean_False;
+					return NLS.bind(JptUiDetailsMessages2_0.Entity_cacheableWithDefaultLabel, defaultStringValue);
+				}
+				return JptUiDetailsMessages2_0.Entity_cacheableLabel;
+			}
+		};
+	}
+	
+	private PropertyValueModel<Boolean> buildDefaultCacheableHolder() {
+		return new PropertyAspectAdapter<Cacheable2_0, Boolean>(
+			getSubjectHolder(),
+			Cacheable2_0.SPECIFIED_CACHEABLE_PROPERTY,
+			Cacheable2_0.DEFAULT_CACHEABLE_PROPERTY)
+		{
+			@Override
+			protected Boolean buildValue_() {
+				if (this.subject.getSpecifiedCacheable() != null) {
+					return null;
+				}
+				return Boolean.valueOf(this.subject.isDefaultCacheable());
+			}
+		};
+	}
+
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/CascadePane2_0.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/CascadePane2_0.java
new file mode 100644
index 0000000..b1eae50
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/CascadePane2_0.java
@@ -0,0 +1,81 @@
+/*******************************************************************************
+ *  Copyright (c) 2010  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.ui.internal.jpa2.details;
+
+import org.eclipse.jpt.core.context.RelationshipMapping;
+import org.eclipse.jpt.core.jpa2.context.Cascade2_0;
+import org.eclipse.jpt.ui.WidgetFactory;
+import org.eclipse.jpt.ui.internal.details.CascadeComposite;
+import org.eclipse.jpt.ui.internal.widgets.Pane;
+import org.eclipse.jpt.utility.internal.model.value.PropertyAspectAdapter;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.jpt.utility.model.value.WritablePropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Group;
+
+public class CascadePane2_0<T extends Cascade2_0>
+	extends CascadeComposite<T>
+{
+	public CascadePane2_0(
+			Pane<? extends RelationshipMapping> parentPane,
+	        PropertyValueModel<T> subjectHolder,
+	        Composite parent) {
+		
+		super(parentPane, subjectHolder, parent);
+	}
+	
+	public CascadePane2_0(
+			PropertyValueModel<T> subjectHolder,
+			Composite parent,
+		    WidgetFactory widgetFactory) {
+		
+		super(subjectHolder, parent, widgetFactory);
+	}
+	
+	
+	@Override
+	protected void initializeLayout(Composite container) {
+		// Cascade group
+		Group cascadeGroup = addCascadeGroup(container);
+		
+		// Container of the check boxes
+		container = addSubPane(cascadeGroup, 6, 8, 0, 0, 0);
+		
+		addAllCheckBox(container);
+		addPersistCheckBox(container);
+		addMergeCheckBox(container);
+		addRemoveCheckBox(container);
+		addRefreshCheckBox(container);
+		addDetachCheckBox(container);
+	}
+	
+	protected void addDetachCheckBox(Composite container) {
+		addCheckBox(
+				container,
+				JptUiDetailsMessages2_0.CascadePane2_0_detach,
+				buildCascadeTypeDetachHolder(),
+				null);
+	}
+	
+	protected WritablePropertyValueModel<Boolean> buildCascadeTypeDetachHolder() {
+		return new PropertyAspectAdapter<Cascade2_0, Boolean>(getSubjectHolder(), Cascade2_0.DETACH_PROPERTY) {
+			@Override
+			protected Boolean buildValue_() {
+				return subject.isDetach();
+			}
+			
+			@Override
+			protected void setValue_(Boolean value) {
+				subject.setDetach(value);
+			}
+		};
+	}	
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/CollectionTable2_0Composite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/CollectionTable2_0Composite.java
new file mode 100644
index 0000000..f76db54
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/CollectionTable2_0Composite.java
@@ -0,0 +1,155 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2010 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.ui.internal.jpa2.details;
+
+import org.eclipse.jpt.core.jpa2.context.CollectionTable2_0;
+import org.eclipse.jpt.ui.WidgetFactory;
+import org.eclipse.jpt.ui.internal.JpaHelpContextIds;
+import org.eclipse.jpt.ui.internal.details.JoinColumnsComposite;
+import org.eclipse.jpt.ui.internal.details.ReferenceTableComposite;
+import org.eclipse.jpt.ui.internal.details.db.CatalogCombo;
+import org.eclipse.jpt.ui.internal.details.db.SchemaCombo;
+import org.eclipse.jpt.ui.internal.details.db.TableCombo;
+import org.eclipse.jpt.ui.internal.widgets.Pane;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Group;
+
+/**
+ * The layout of this pane:
+ * <pre>
+ * -----------------------------------------------------------------------------
+ * |            ------------------------------------------------------------   |
+ * |   Name:    |                                                        |v|   |
+ * |            ------------------------------------------------------------   |
+ * |            ------------------------------------------------------------   |
+ * |   Schema:  |                                                        |v|   |
+ * |            ------------------------------------------------------------   |
+ * |            ------------------------------------------------------------   |
+ * |   Catalog: |                                                        |v|   |
+ * |            ------------------------------------------------------------   |
+ * |                                                                           |
+ * | - Join Columns ---------------------------------------------------------- |
+ * | |                                                                       | |
+ * | | x Override Default                                                    | |
+ * | |                                                                       | |
+ * | | --------------------------------------------------------------------- | |
+ * | | |                                                                   | | |
+ * | | | JoinColumnsComposite                                              | | |
+ * | | |                                                                   | | |
+ * | | --------------------------------------------------------------------- | |
+ * | ------------------------------------------------------------------------- |
+ * -----------------------------------------------------------------------------</pre>
+ *
+ * @see {@link CollectionTable2_0}
+ * @see {@link JoinColumnsComposite
+ *
+ * @version 3.0
+ * @since 3.0
+ */
+public class CollectionTable2_0Composite extends ReferenceTableComposite<CollectionTable2_0>
+{
+	/**
+	 * Creates a new <code>CollectionTable2_0Composite</code>.
+	 *
+	 * @param parentPane The parent container of this one
+	 * @param subjectHolder The holder of this pane's subject
+	 * @param parent The parent container
+	 */
+	public CollectionTable2_0Composite(
+			Pane<?> parentPane,
+			PropertyValueModel<? extends CollectionTable2_0> subjectHolder,
+			Composite parent) {
+
+		super(parentPane, subjectHolder, parent);
+	}
+
+	/**
+	 * Creates a new <code>CollectionTable2_0Composite</code>.
+	 *
+	 * @param subjectHolder The holder of the subject <code>CollectionTable2_0</code>
+	 * @param parent The parent container
+	 * @param widgetFactory The factory used to create various common widgets
+	 */
+	public CollectionTable2_0Composite(PropertyValueModel<? extends CollectionTable2_0> subjectHolder,
+	                          Composite parent,
+	                          WidgetFactory widgetFactory) {
+
+		super(subjectHolder, parent, widgetFactory);
+	}
+
+	@Override
+	protected void initializeLayout(Composite container) {
+		// collection table group pane
+		container = addTitledGroup(
+			container,
+			JptUiDetailsMessages2_0.CollectionTable2_0Composite_title
+		);
+
+		int groupBoxMargin = getGroupBoxMargin();
+
+		// Name widgets
+		TableCombo<CollectionTable2_0> tableCombo = addTableCombo(container);
+		Composite tablePane = addPane(container, groupBoxMargin);
+		addLabeledComposite(
+				tablePane,
+			JptUiDetailsMessages2_0.CollectionTable2_0Composite_name,
+			tableCombo.getControl(),
+			JpaHelpContextIds.MAPPING_COLLECTION_TABLE_NAME
+		);
+		
+		// schema widgets
+		SchemaCombo<CollectionTable2_0> schemaCombo = addSchemaCombo(container);
+
+		addLabeledComposite(
+			tablePane,
+			JptUiDetailsMessages2_0.CollectionTable2_0Composite_schema,
+			schemaCombo.getControl(),
+			JpaHelpContextIds.MAPPING_COLLECTION_TABLE_SCHEMA
+		);
+		
+		// catalog widgets
+		CatalogCombo<CollectionTable2_0> catalogCombo = addCatalogCombo(container);
+
+		addLabeledComposite(
+			tablePane,
+			JptUiDetailsMessages2_0.CollectionTable2_0Composite_catalog,
+			catalogCombo.getControl(),
+			JpaHelpContextIds.MAPPING_COLLECTION_TABLE_CATALOG
+		);
+
+		// Join Columns group pane
+		Group joinColumnGroupPane = addTitledGroup(
+			container,
+			JptUiDetailsMessages2_0.CollectionTable2_0Composite_joinColumn
+		);
+
+		// Override Default Join Columns check box
+		this.overrideDefaultJoinColumnsCheckBox = addCheckBox(
+			addSubPane(joinColumnGroupPane, 8),
+			JptUiDetailsMessages2_0.CollectionTable2_0Composite_overrideDefaultJoinColumns,
+			buildOverrideDefaultJoinColumnHolder(),
+			null
+		);
+
+		this.joinColumnsComposite = new JoinColumnsComposite<CollectionTable2_0>(
+			this,
+			joinColumnGroupPane,
+			buildJoinColumnsEditor()
+		);
+
+		installJoinColumnsPaneEnabler(this.joinColumnsComposite);
+	}
+	
+	@Override
+	protected boolean isParentVirtual(CollectionTable2_0 collectionTable) {
+		return collectionTable.getPersistentAttribute().isVirtual();
+	}
+}
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/DerivedIdentity2_0Pane.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/DerivedIdentity2_0Pane.java
new file mode 100644
index 0000000..2b6c0ee
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/DerivedIdentity2_0Pane.java
@@ -0,0 +1,200 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2010 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.ui.internal.jpa2.details;
+
+import java.util.Collection;
+import org.eclipse.jpt.core.jpa2.context.DerivedIdentity2_0;
+import org.eclipse.jpt.core.jpa2.context.MapsIdDerivedIdentityStrategy2_0;
+import org.eclipse.jpt.ui.internal.widgets.ComboPane;
+import org.eclipse.jpt.ui.internal.widgets.Pane;
+import org.eclipse.jpt.utility.internal.iterables.EmptyIterable;
+import org.eclipse.jpt.utility.internal.model.value.PropertyAspectAdapter;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.jpt.utility.model.value.WritablePropertyValueModel;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+
+public class DerivedIdentity2_0Pane
+	extends Pane<DerivedIdentity2_0>
+{
+	public DerivedIdentity2_0Pane(
+			Pane<?> parentPane, 
+			PropertyValueModel<? extends DerivedIdentity2_0> subjectHolder, 
+			Composite parent) {
+		
+		super(parentPane, subjectHolder, parent);
+	}
+	
+	
+	@Override
+	protected void initializeLayout(Composite container) {
+		Composite composite = addCollapsibleSection(
+				container,
+				JptUiDetailsMessages2_0.DerivedIdentity_title);
+		((GridLayout) composite.getLayout()).numColumns = 2;
+		
+		addNullDerivedIdentityPane(composite);
+		addIdDerivedIdentityPane(composite);
+		addMapsIdDerivedIdentityPane(composite);
+	}
+	
+	protected void addNullDerivedIdentityPane(Composite parent) {
+		Button button = addRadioButton(
+				parent,
+				JptUiDetailsMessages2_0.DerivedIdentity_nullDerivedIdentity,
+				buildUsesNullDerivedIdentityStrategyHolder(),
+				null);
+		((GridData) button.getLayoutData()).horizontalSpan = 2;
+	}
+	
+	protected WritablePropertyValueModel<Boolean> buildUsesNullDerivedIdentityStrategyHolder() {
+		return new PropertyAspectAdapter<DerivedIdentity2_0, Boolean>(
+				getSubjectHolder(), DerivedIdentity2_0.PREDOMINANT_DERIVED_IDENTITY_STRATEGY_PROPERTY) {
+			
+			@Override
+			protected Boolean buildValue_() {
+				return this.subject.usesNullDerivedIdentityStrategy();
+			}
+			
+			@Override
+			protected void setValue_(Boolean value) {
+				// radio button - should only have true values here
+				if (value) {
+					this.subject.setNullDerivedIdentityStrategy();
+				}
+			}
+		};
+	}
+	
+	protected void addIdDerivedIdentityPane(Composite parent) {
+		Button button = addRadioButton(
+				parent,
+				JptUiDetailsMessages2_0.DerivedIdentity_idDerivedIdentity,
+				buildUsesIdDerivedIdentityStrategyHolder(),
+				null);
+		((GridData) button.getLayoutData()).horizontalSpan = 2;
+	}
+	
+	protected WritablePropertyValueModel<Boolean> buildUsesIdDerivedIdentityStrategyHolder() {
+		return new PropertyAspectAdapter<DerivedIdentity2_0, Boolean>(
+				getSubjectHolder(), DerivedIdentity2_0.PREDOMINANT_DERIVED_IDENTITY_STRATEGY_PROPERTY) {
+			
+			@Override
+			protected Boolean buildValue_() {
+				return this.subject.usesIdDerivedIdentityStrategy();
+			}
+			
+			@Override
+			protected void setValue_(Boolean value) {
+				// radio button - should only have true values here
+				if (value) {
+					this.subject.setIdDerivedIdentityStrategy();
+				}
+			}
+		};
+	}
+	
+	protected void addMapsIdDerivedIdentityPane(Composite parent) {
+		WritablePropertyValueModel<Boolean> usesMapsIdModel = buildUsesMapsIdDerivedIdentityStrategyHolder();
+		addRadioButton(
+			parent,
+			JptUiDetailsMessages2_0.DerivedIdentity_mapsIdDerivedIdentity,
+			usesMapsIdModel,
+			null);
+
+		buildMapsIdValueComboPane(parent, usesMapsIdModel);
+	}
+	
+	protected WritablePropertyValueModel<Boolean> buildUsesMapsIdDerivedIdentityStrategyHolder() {
+		return new PropertyAspectAdapter<DerivedIdentity2_0, Boolean>(
+				getSubjectHolder(), DerivedIdentity2_0.PREDOMINANT_DERIVED_IDENTITY_STRATEGY_PROPERTY) {
+			
+			@Override
+			protected Boolean buildValue() {
+				return (this.subject == null) ? Boolean.FALSE : this.subject.usesMapsIdDerivedIdentityStrategy();
+			}
+			
+			@Override
+			protected void setValue_(Boolean value) {
+				// radio button - should only have true values here
+				if (value) {
+					this.subject.setMapsIdDerivedIdentityStrategy();
+				}
+			}
+		};
+	}
+	
+	protected ComboPane buildMapsIdValueComboPane(Composite parent, PropertyValueModel<Boolean> usesMapsIdModel) {
+		return new MapsIdValueComboPane(this, buildMapsIdStrategyHolder(), parent, usesMapsIdModel);
+	}
+	
+	protected PropertyValueModel<MapsIdDerivedIdentityStrategy2_0> buildMapsIdStrategyHolder() {
+		return new PropertyAspectAdapter<DerivedIdentity2_0, MapsIdDerivedIdentityStrategy2_0>(getSubjectHolder()) {
+			@Override
+			protected MapsIdDerivedIdentityStrategy2_0 buildValue_() {
+				return this.subject.getMapsIdDerivedIdentityStrategy();
+			}
+		};
+	}
+	
+	
+	private class MapsIdValueComboPane
+		extends ComboPane<MapsIdDerivedIdentityStrategy2_0>
+	{
+		public MapsIdValueComboPane(
+				Pane<?> parentPane,
+				PropertyValueModel<? extends MapsIdDerivedIdentityStrategy2_0> subjectHolder,
+				Composite parent,
+				PropertyValueModel<Boolean> enabledModel) {
+			
+			super(parentPane, subjectHolder, parent, enabledModel);
+		}
+		
+		
+		@Override
+		protected void addPropertyNames(Collection<String> propertyNames) {
+			super.addPropertyNames(propertyNames);
+			propertyNames.add(MapsIdDerivedIdentityStrategy2_0.DEFAULT_VALUE_PROPERTY);
+			propertyNames.add(MapsIdDerivedIdentityStrategy2_0.SPECIFIED_VALUE_PROPERTY);
+		}
+		
+		@Override
+		protected String getValue() {
+			return (getSubject() == null) ? null : getSubject().getSpecifiedValue();
+		}
+		
+		@Override
+		protected void setValue(String value) {
+			if (getSubject() != null) getSubject().setSpecifiedValue(value);
+		}
+		
+		@Override
+		protected boolean usesDefaultValue() {
+			return (getSubject() == null) ? true : getSubject().usesDefaultValue();
+		}
+		
+		@Override
+		protected String getDefaultValue() {
+			return (getSubject() == null) ? null : getSubject().getDefaultValue();
+		}
+		
+		@Override
+		protected Iterable<String> getValues() {
+			return (getSubject() == null) ? EmptyIterable.<String>instance() : getSubject().getSortedValueChoices();
+		}
+		
+		@Override
+		protected String buildNullDefaultValueEntry() {
+			return buildNonNullDefaultValueEntry(JptUiDetailsMessages2_0.DerivedIdentity_mapsIdUnspecifiedValue);
+		}
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/ElementCollectionMapping2_0Composite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/ElementCollectionMapping2_0Composite.java
new file mode 100644
index 0000000..e9c93cb
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/ElementCollectionMapping2_0Composite.java
@@ -0,0 +1,81 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2010 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.ui.internal.jpa2.details;
+
+import org.eclipse.jpt.core.context.BasicMapping;
+import org.eclipse.jpt.core.jpa2.context.ElementCollectionMapping2_0;
+import org.eclipse.jpt.ui.WidgetFactory;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * Here the layout of this pane:
+ * <pre>
+ * -----------------------------------------------------------------------------
+ * | ------------------------------------------------------------------------- |
+ * | |                                                                       | |
+ * | | TargetClassComposite                                                  | |
+ * | |                                                                       | |
+ * | ------------------------------------------------------------------------- |
+ * | ------------------------------------------------------------------------- |
+ * | |                                                                       | |
+ * | | FetchTypeComposite                                                    | |
+ * | |                                                                       | |
+ * | ------------------------------------------------------------------------- |
+ * | ------------------------------------------------------------------------- |
+ * | |                                                                       | |
+ * | | CollectionTableComposite                                              | |
+ * | |                                                                       | |
+ * | ------------------------------------------------------------------------- |
+ * | ------------------------------------------------------------------------- |
+ * | |                                                                       | |
+ * | | ColumnComposite                                                       | |
+ * | |                                                                       | |
+ * | ------------------------------------------------------------------------- |
+ * | ------------------------------------------------------------------------- |
+ * | |                                                                       | |
+ * | | OptionalComposite                                                     | |
+ * | |                                                                       | |
+ * | ------------------------------------------------------------------------- |
+ * | ------------------------------------------------------------------------- |
+ * | |                                                                       | |
+ * | | LobComposite                                                          | |
+ * | |                                                                       | |
+ * | ------------------------------------------------------------------------- |
+ * -----------------------------------------------------------------------------</pre>
+ *
+ * @see BasicMapping
+ * @see OrderColumnComposite
+ * @see EnumTypeComposite
+ * @see FetchTypeComposite
+ * @see LobComposite
+ * @see OptionalComposite
+ * @see TemporalTypeComposite
+ *
+ * @version 2.3
+ * @since 2.3
+ */
+public class ElementCollectionMapping2_0Composite extends AbstractElementCollectionMapping2_0Composite<ElementCollectionMapping2_0>
+{
+	/**
+	 * Creates a new <code>BasicMappingComposite</code>.
+	 *
+	 * @param subjectHolder The holder of the subject <code>IBasicMapping</code>
+	 * @param parent The parent container
+	 * @param widgetFactory The factory used to create various common widgets
+	 */
+	public ElementCollectionMapping2_0Composite(PropertyValueModel<? extends ElementCollectionMapping2_0> subjectHolder,
+	                             Composite parent,
+	                             WidgetFactory widgetFactory) {
+
+		super(subjectHolder, parent, widgetFactory);
+	}
+
+}
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/ElementCollectionValueOverridesComposite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/ElementCollectionValueOverridesComposite.java
new file mode 100644
index 0000000..3bb04de
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/ElementCollectionValueOverridesComposite.java
@@ -0,0 +1,64 @@
+/*******************************************************************************
+ * Copyright (c) 2010 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.ui.internal.jpa2.details;
+
+import org.eclipse.jpt.core.context.AssociationOverride;
+import org.eclipse.jpt.core.context.AssociationOverrideContainer;
+import org.eclipse.jpt.core.context.AttributeOverrideContainer;
+import org.eclipse.jpt.core.jpa2.context.ElementCollectionMapping2_0;
+import org.eclipse.jpt.ui.internal.details.AbstractOverridesComposite;
+import org.eclipse.jpt.ui.internal.details.AssociationOverrideComposite;
+import org.eclipse.jpt.ui.internal.widgets.Pane;
+import org.eclipse.jpt.utility.internal.model.value.PropertyAspectAdapter;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.ui.part.PageBook;
+
+public final class ElementCollectionValueOverridesComposite
+	extends AbstractOverridesComposite<ElementCollectionMapping2_0>
+{
+	public ElementCollectionValueOverridesComposite(
+			Pane<? extends ElementCollectionMapping2_0> parentPane,
+			Composite parent) {
+		
+		super(parentPane, parent);
+	}
+	
+	
+	@Override
+	protected boolean supportsAssociationOverrides() {
+		return true;
+	}
+	
+	@Override
+	protected Pane<AssociationOverride> buildAssociationOverridePane(PageBook pageBook, PropertyValueModel<AssociationOverride> associationOverrideHolder) {
+		return new AssociationOverrideComposite(this, associationOverrideHolder, pageBook);
+	}
+	
+	@Override
+	protected PropertyValueModel<AttributeOverrideContainer> buildAttributeOverrideContainerHolder() {
+		return new PropertyAspectAdapter<ElementCollectionMapping2_0, AttributeOverrideContainer>(getSubjectHolder()) {
+			@Override
+			protected AttributeOverrideContainer buildValue_() {
+				return this.subject.getValueAttributeOverrideContainer();
+			}
+		};
+	}
+	
+	@Override
+	protected PropertyValueModel<AssociationOverrideContainer> buildAssociationOverrideContainerHolder() {
+		return new PropertyAspectAdapter<ElementCollectionMapping2_0, AssociationOverrideContainer>(getSubjectHolder()) {
+			@Override
+			protected AssociationOverrideContainer buildValue_() {
+				return this.subject.getValueAssociationOverrideContainer();
+			}
+		};
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/EmbeddedIdMapping2_0Composite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/EmbeddedIdMapping2_0Composite.java
new file mode 100644
index 0000000..cffa632
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/EmbeddedIdMapping2_0Composite.java
@@ -0,0 +1,37 @@
+/*******************************************************************************
+ *  Copyright (c) 2010  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.ui.internal.jpa2.details;
+
+import org.eclipse.jpt.core.context.EmbeddedIdMapping;
+import org.eclipse.jpt.ui.WidgetFactory;
+import org.eclipse.jpt.ui.internal.details.AbstractEmbeddedIdMappingComposite;
+import org.eclipse.jpt.ui.internal.details.EmbeddedMappingOverridesComposite;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+public class EmbeddedIdMapping2_0Composite
+	extends AbstractEmbeddedIdMappingComposite<EmbeddedIdMapping>
+{
+	public EmbeddedIdMapping2_0Composite(
+			PropertyValueModel<? extends EmbeddedIdMapping> subjectHolder,
+			Composite parent,
+			WidgetFactory widgetFactory) {
+		
+		super(subjectHolder, parent, widgetFactory);
+	}
+	
+	
+	@Override
+	protected void initializeEmbeddedIdSection(Composite container) {
+		new EmbeddedIdMapping2_0MappedByRelationshipPane(this, getSubjectHolder(), container);
+		new EmbeddedMappingOverridesComposite(this, container);
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/EmbeddedIdMapping2_0MappedByRelationshipPane.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/EmbeddedIdMapping2_0MappedByRelationshipPane.java
new file mode 100644
index 0000000..a37eddb
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/EmbeddedIdMapping2_0MappedByRelationshipPane.java
@@ -0,0 +1,69 @@
+/*******************************************************************************
+ *  Copyright (c) 2010  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.ui.internal.jpa2.details;
+
+import org.eclipse.jpt.core.jpa2.context.EmbeddedIdMapping2_0;
+import org.eclipse.jpt.ui.internal.util.ControlSwitcher;
+import org.eclipse.jpt.ui.internal.widgets.Pane;
+import org.eclipse.jpt.utility.internal.Transformer;
+import org.eclipse.jpt.utility.internal.model.value.PropertyAspectAdapter;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.jpt.utility.model.value.WritablePropertyValueModel;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.ui.part.PageBook;
+
+public class EmbeddedIdMapping2_0MappedByRelationshipPane<T extends EmbeddedIdMapping2_0>
+	extends Pane<T>
+{
+	private Label mappedByRelationshipLabel;
+
+	public EmbeddedIdMapping2_0MappedByRelationshipPane(
+			Pane<?> parentPane,
+			PropertyValueModel<T> subjectHolder,
+			Composite parent) {
+		
+		super(parentPane, subjectHolder, parent);
+	}
+
+	@Override
+	protected void initializeLayout(Composite container) {
+		PageBook pageBook = new PageBook(container, SWT.NULL);
+		pageBook.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+		this.mappedByRelationshipLabel = addLabel(pageBook, JptUiDetailsMessages2_0.EmbeddedIdMapping2_0MappedByRelationshipPane_label);
+
+		new ControlSwitcher(buildIsMappedByRelationshipHolder(), buildPaneTransformer(), pageBook);
+	}
+
+	protected WritablePropertyValueModel<Boolean> buildIsMappedByRelationshipHolder() {
+		return new PropertyAspectAdapter<T, Boolean>(getSubjectHolder(), EmbeddedIdMapping2_0.MAPPED_BY_RELATIONSHIP_PROPERTY) {
+			@Override
+			protected Boolean buildValue_() {
+				return Boolean.valueOf(this.subject.isMappedByRelationship());
+			}
+		};
+	}
+
+	private Transformer<Boolean, Control> buildPaneTransformer() {
+		return new Transformer<Boolean, Control>() {
+			public Control transform(Boolean converter) {
+				if (converter == null || converter == Boolean.FALSE) {
+					return null;
+				}
+				return EmbeddedIdMapping2_0MappedByRelationshipPane.this.mappedByRelationshipLabel; 
+			}
+		};
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/EmbeddedMapping2_0OverridesComposite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/EmbeddedMapping2_0OverridesComposite.java
new file mode 100644
index 0000000..4cc0d3c
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/EmbeddedMapping2_0OverridesComposite.java
@@ -0,0 +1,64 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2010 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.ui.internal.jpa2.details;
+
+import org.eclipse.jpt.core.context.AssociationOverride;
+import org.eclipse.jpt.core.context.AssociationOverrideContainer;
+import org.eclipse.jpt.core.context.AttributeOverrideContainer;
+import org.eclipse.jpt.core.context.EmbeddedMapping;
+import org.eclipse.jpt.core.jpa2.context.EmbeddedMapping2_0;
+import org.eclipse.jpt.ui.internal.details.AbstractEmbeddedMappingOverridesComposite;
+import org.eclipse.jpt.ui.internal.widgets.Pane;
+import org.eclipse.jpt.utility.internal.model.value.PropertyAspectAdapter;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.ui.part.PageBook;
+
+public class EmbeddedMapping2_0OverridesComposite
+	extends AbstractEmbeddedMappingOverridesComposite<EmbeddedMapping>
+{
+	public EmbeddedMapping2_0OverridesComposite(
+			Pane<? extends EmbeddedMapping> parentPane,
+			Composite parent) {
+		
+		super(parentPane, parent);
+	}
+	
+	
+	@Override
+	protected boolean supportsAssociationOverrides() {
+		return true;
+	}	
+	
+	@Override
+	protected PropertyValueModel<AttributeOverrideContainer> buildAttributeOverrideContainerHolder() {
+		return new PropertyAspectAdapter<EmbeddedMapping, AttributeOverrideContainer>(getSubjectHolder()) {
+			@Override
+			protected AttributeOverrideContainer buildValue_() {
+				return this.subject.getAttributeOverrideContainer();
+			}
+		};
+	}
+	
+	@Override
+	protected Pane<AssociationOverride> buildAssociationOverridePane(PageBook pageBook, PropertyValueModel<AssociationOverride> associationOverrideHolder) {
+		return new AssociationOverride2_0Composite(this, associationOverrideHolder, pageBook);
+	}
+	
+	@Override
+	protected PropertyValueModel<AssociationOverrideContainer> buildAssociationOverrideContainerHolder() {
+		return new PropertyAspectAdapter<EmbeddedMapping, AssociationOverrideContainer>(getSubjectHolder()) {
+			@Override
+			protected AssociationOverrideContainer buildValue_() {
+				return ((EmbeddedMapping2_0) this.subject).getAssociationOverrideContainer();
+			}
+		};
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/Entity2_0OverridesComposite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/Entity2_0OverridesComposite.java
new file mode 100644
index 0000000..00026ef
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/Entity2_0OverridesComposite.java
@@ -0,0 +1,35 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 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.ui.internal.jpa2.details;
+
+import org.eclipse.jpt.core.context.AssociationOverride;
+import org.eclipse.jpt.core.context.Entity;
+import org.eclipse.jpt.ui.internal.details.AbstractEntityOverridesComposite;
+import org.eclipse.jpt.ui.internal.widgets.Pane;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.ui.part.PageBook;
+
+public class Entity2_0OverridesComposite
+	extends AbstractEntityOverridesComposite
+{
+	public Entity2_0OverridesComposite(
+			Pane<? extends Entity> parentPane,
+			Composite parent) {
+		
+		super(parentPane, parent);
+	}
+	
+	
+	@Override
+	protected Pane<AssociationOverride> buildAssociationOverridePane(PageBook pageBook, PropertyValueModel<AssociationOverride> associationOverrideHolder) {
+		return new AssociationOverride2_0Composite(this, associationOverrideHolder, pageBook);
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/Generation2_0Composite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/Generation2_0Composite.java
new file mode 100644
index 0000000..442e1ba
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/Generation2_0Composite.java
@@ -0,0 +1,42 @@
+/*******************************************************************************
+* Copyright (c) 2009 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.ui.internal.jpa2.details;
+
+import org.eclipse.jpt.core.context.GeneratorContainer;
+import org.eclipse.jpt.ui.internal.details.GenerationComposite;
+import org.eclipse.jpt.ui.internal.widgets.Pane;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ *  Generation2_0Composite
+ */
+public class Generation2_0Composite extends GenerationComposite
+{
+	
+	public Generation2_0Composite(
+		Pane<?> parentPane, 
+		PropertyValueModel<? extends GeneratorContainer> subjectHolder,
+		Composite parent) {
+
+			super(parentPane, subjectHolder, parent);
+	}
+
+	@Override
+	protected void addSequenceGeneratorComposite(Composite container, int topMargin, int leftMargin) {
+		new SequenceGenerator2_0Composite(
+			this,
+			this.buildSequenceGeneratorHolder(),
+			this.addSubPane(container, topMargin, leftMargin),
+			this.buildSequenceGeneratorBuilder()
+		);
+	}
+
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/IdMapping2_0MappedByRelationshipPane.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/IdMapping2_0MappedByRelationshipPane.java
new file mode 100644
index 0000000..3e1fbdf
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/IdMapping2_0MappedByRelationshipPane.java
@@ -0,0 +1,71 @@
+/*******************************************************************************
+ *  Copyright (c) 2010  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.ui.internal.jpa2.details;
+
+import org.eclipse.jpt.core.jpa2.context.IdMapping2_0;
+import org.eclipse.jpt.ui.internal.util.ControlSwitcher;
+import org.eclipse.jpt.ui.internal.widgets.Pane;
+import org.eclipse.jpt.utility.internal.Transformer;
+import org.eclipse.jpt.utility.internal.model.value.PropertyAspectAdapter;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.jpt.utility.model.value.WritablePropertyValueModel;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.ui.part.PageBook;
+
+
+public class IdMapping2_0MappedByRelationshipPane<T extends IdMapping2_0>
+	extends Pane<T>
+{
+
+	private Label mappedByRelationshipLabel;
+
+	public IdMapping2_0MappedByRelationshipPane(
+			Pane<?> parentPane,
+			PropertyValueModel<T> subjectHolder,
+			Composite parent) {
+		
+		super(parentPane, subjectHolder, parent);
+	}
+
+	@Override
+	protected void initializeLayout(Composite container) {
+		PageBook pageBook = new PageBook(container, SWT.NULL);
+		pageBook.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+		this.mappedByRelationshipLabel = addLabel(pageBook, JptUiDetailsMessages2_0.IdMapping2_0MappedByRelationshipPane_label);
+
+		new ControlSwitcher(buildIsMappedByRelationshipHolder(), buildPaneTransformer(), pageBook);
+	}
+
+	protected WritablePropertyValueModel<Boolean> buildIsMappedByRelationshipHolder() {
+		return new PropertyAspectAdapter<T, Boolean>(getSubjectHolder(), IdMapping2_0.MAPPED_BY_RELATIONSHIP_PROPERTY) {
+			@Override
+			protected Boolean buildValue_() {
+				return Boolean.valueOf(this.subject.isMappedByRelationship());
+			}
+		};
+	}
+
+	private Transformer<Boolean, Control> buildPaneTransformer() {
+		return new Transformer<Boolean, Control>() {
+			public Control transform(Boolean converter) {
+				if (converter == null || converter == Boolean.FALSE) {
+					return null;
+				}
+				return IdMapping2_0MappedByRelationshipPane.this.mappedByRelationshipLabel; 
+			}
+		};
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/IdMappingGeneration2_0Composite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/IdMappingGeneration2_0Composite.java
new file mode 100644
index 0000000..381ae4a
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/IdMappingGeneration2_0Composite.java
@@ -0,0 +1,48 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2010 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.ui.internal.jpa2.details;
+
+import org.eclipse.jpt.core.context.IdMapping;
+import org.eclipse.jpt.core.context.SequenceGenerator;
+import org.eclipse.jpt.ui.internal.details.IdMappingGenerationComposite;
+import org.eclipse.jpt.ui.internal.details.SequenceGeneratorComposite;
+import org.eclipse.jpt.ui.internal.details.GeneratorComposite.GeneratorBuilder;
+import org.eclipse.jpt.ui.internal.widgets.Pane;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ *  IdMappingGeneration2_0Composite
+ */
+public class IdMappingGeneration2_0Composite extends IdMappingGenerationComposite
+{
+
+	public IdMappingGeneration2_0Composite(Pane<? extends IdMapping> parentPane, Composite parent) {
+		super(parentPane, parent);
+	}
+
+	@Override
+	protected SequenceGeneratorComposite buildSequenceGeneratorComposite(
+		Composite container, 
+		PropertyValueModel<SequenceGenerator> sequenceGeneratorHolder,
+		GeneratorBuilder<SequenceGenerator> sequenceGeneratorBuilder,
+		int topMargin,
+		int leftMargin) {
+
+		return new SequenceGenerator2_0Composite(
+			this,
+			sequenceGeneratorHolder,
+			this.addSubPane(container, topMargin, leftMargin),
+			sequenceGeneratorBuilder
+		);
+	}
+	
+	
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/JptUiDetailsMessages2_0.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/JptUiDetailsMessages2_0.java
new file mode 100644
index 0000000..a9044e1
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/JptUiDetailsMessages2_0.java
@@ -0,0 +1,78 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2010 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.ui.internal.jpa2.details;
+
+import org.eclipse.osgi.util.NLS;
+
+/**
+ * Localized messages used by Dali mapping panes.
+ *
+ * @version 2.3
+ * @since 2.3
+ */
+public class JptUiDetailsMessages2_0 
+{
+	public static String CascadePane2_0_detach;
+	
+	public static String CollectionTable2_0Composite_title;
+	public static String CollectionTable2_0Composite_joinColumn;
+	public static String CollectionTable2_0Composite_name;
+	public static String CollectionTable2_0Composite_schema;
+	public static String CollectionTable2_0Composite_catalog;
+	public static String CollectionTable2_0Composite_overrideDefaultJoinColumns;
+	
+	public static String DerivedIdentity_title;
+	public static String DerivedIdentity_nullDerivedIdentity;
+	public static String DerivedIdentity_idDerivedIdentity;
+	public static String DerivedIdentity_mapsIdDerivedIdentity;
+	public static String DerivedIdentity_mapsIdUnspecifiedValue;
+	
+	public static String ElementCollectionMapping2_0_label;
+	public static String ElementCollectionMapping2_0_linkLabel;
+	
+	public static String ElementCollectionSection_title;
+	public static String AbstractElementCollectionMapping2_0_Composite_valueSectionTitle;
+	
+	public static String Entity_cacheableLabel;
+	public static String Entity_cacheableWithDefaultLabel;
+	
+	public static String EmbeddedIdMapping2_0MappedByRelationshipPane_label;
+	
+	public static String IdMapping2_0MappedByRelationshipPane_label;
+	
+	public static String OrderingComposite_orderColumn;
+	
+	public static String OrphanRemoval2_0Composite_orphanRemovalLabel;
+	public static String OrphanRemoval2_0Composite_orphanRemovalLabelDefault;
+	
+	public static String LockModeComposite_lockModeLabel;
+
+	public static String LockModeComposite_read;
+	public static String LockModeComposite_write;
+	public static String LockModeComposite_optimistic;
+	public static String LockModeComposite_optimistic_force_increment;
+	public static String LockModeComposite_pessimistic_read;
+	public static String LockModeComposite_pessimistic_write;
+	public static String LockModeComposite_pessimistic_force_increment;
+	public static String LockModeComposite_none;
+
+	public static String TargetClassComposite_label;
+	
+	private static final String BUNDLE_NAME = "jpt_ui_details2_0"; //$NON-NLS-1$
+	private static final Class<?> BUNDLE_CLASS = JptUiDetailsMessages2_0.class;
+	static {
+		NLS.initializeMessages(BUNDLE_NAME, BUNDLE_CLASS);
+	}
+
+	private JptUiDetailsMessages2_0() {
+		throw new UnsupportedOperationException();
+	}
+
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/LockModeComposite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/LockModeComposite.java
new file mode 100644
index 0000000..be37fc7
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/LockModeComposite.java
@@ -0,0 +1,89 @@
+/*******************************************************************************
+* Copyright (c) 2009, 2010 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.ui.internal.jpa2.details;
+
+import java.util.Collection;
+
+import org.eclipse.jpt.core.jpa2.context.LockModeType2_0;
+import org.eclipse.jpt.core.jpa2.context.NamedQuery2_0;
+import org.eclipse.jpt.ui.internal.widgets.EnumFormComboViewer;
+import org.eclipse.jpt.ui.internal.widgets.Pane;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ *  LockModeComposite
+ */
+public class LockModeComposite extends Pane<NamedQuery2_0>
+{
+	/**
+	 * Creates a new <code>LockModeComposite</code>.
+	 *
+	 * @param parentPane The parent container of this one
+	 * @param parent The parent container
+	 */
+	public LockModeComposite(Pane<? extends NamedQuery2_0> parentPane,
+	                          Composite parent) {
+
+		super(parentPane, parent);
+	}
+
+	@Override
+	protected void initializeLayout(Composite container) {
+
+		this.addLabeledComposite(
+			container,
+			JptUiDetailsMessages2_0.LockModeComposite_lockModeLabel,
+			this.addLockModeTypeCombo(container),
+			null		// TODO
+		);
+	}
+
+	private EnumFormComboViewer<NamedQuery2_0, LockModeType2_0> addLockModeTypeCombo(Composite container) {
+
+		return new EnumFormComboViewer<NamedQuery2_0, LockModeType2_0>(this, container) {
+
+			@Override
+			protected void addPropertyNames(Collection<String> propertyNames) {
+				super.addPropertyNames(propertyNames);
+				propertyNames.add(NamedQuery2_0.DEFAULT_LOCK_MODE_PROPERTY);
+				propertyNames.add(NamedQuery2_0.SPECIFIED_LOCK_MODE_PROPERTY);
+			}
+
+			@Override
+			protected LockModeType2_0[] getChoices() {
+				return LockModeType2_0.values();
+			}
+
+			@Override
+			protected LockModeType2_0 getDefaultValue() {
+				return this.getSubject().getDefaultLockMode();
+			}
+
+			@Override
+			protected String displayString(LockModeType2_0 value) {
+				return this.buildDisplayString(
+					JptUiDetailsMessages2_0.class,
+					LockModeComposite.this,
+					value
+				);
+			}
+
+			@Override
+			protected LockModeType2_0 getValue() {
+				return this.getSubject().getSpecifiedLockMode();
+			}
+
+			@Override
+			protected void setValue(LockModeType2_0 value) {
+				this.getSubject().setSpecifiedLockMode(value);
+			}
+		};
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/ManyToOneJoiningStrategy2_0Pane.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/ManyToOneJoiningStrategy2_0Pane.java
new file mode 100644
index 0000000..5413aae
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/ManyToOneJoiningStrategy2_0Pane.java
@@ -0,0 +1,84 @@
+/*******************************************************************************
+ * Copyright (c) 2010 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.ui.internal.jpa2.details;
+
+import org.eclipse.jpt.core.context.ManyToOneRelationshipReference;
+import org.eclipse.jpt.core.jpa2.context.ManyToOneRelationshipReference2_0;
+import org.eclipse.jpt.ui.internal.details.JoinColumnJoiningStrategyPane;
+import org.eclipse.jpt.ui.internal.details.JoinTableJoiningStrategyPane;
+import org.eclipse.jpt.ui.internal.details.JptUiDetailsMessages;
+import org.eclipse.jpt.ui.internal.widgets.Pane;
+import org.eclipse.jpt.utility.internal.model.value.SimplePropertyValueModel;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * Here is the layout of this pane:  
+ * <pre>
+ * -----------------------------------------------------------------------------
+ * | - Joining Strategy ------------------------------------------------------ |
+ * | |                                                                       | |
+ * | | o JoinColumnStrategyPane ____________________________________________ | |
+ * | | |                                                                   | | |
+ * | | |                                                                   | | |
+ * | | --------------------------------------------------------------------- | |
+ * | | o JoinTableJoiningStrategyPane_______________________________________ | |
+ * | | |                                                                   | | |
+ * | | |                                                                   | | |
+ * | | --------------------------------------------------------------------- | |
+ * | ------------------------------------------------------------------------- |
+ * -----------------------------------------------------------------------------</pre>
+ *
+ * @see {@link ManyToOneMapping}
+ * @see {@link ManyToOneRelationshipReference}
+ * @see {@link OrmManyToOneMappingComposite}
+ * @see {@link JoinColumnStrategyPane}
+ *
+ * @version 2.3
+ * @since 2.1
+ */
+public class ManyToOneJoiningStrategy2_0Pane extends Pane<ManyToOneRelationshipReference2_0>
+{
+	public ManyToOneJoiningStrategy2_0Pane(
+			Pane<?> parentPane, 
+			PropertyValueModel<? extends ManyToOneRelationshipReference2_0> subjectHolder, 
+			Composite parent) {
+		
+		super(parentPane, subjectHolder, parent);
+	}
+	
+	
+	@Override
+	protected void initializeLayout(Composite container) {
+		Composite composite = addCollapsibleSection(
+				container,
+				JptUiDetailsMessages.Joining_title,
+				new SimplePropertyValueModel<Boolean>(Boolean.TRUE));
+		
+		addRadioButton(
+			composite,
+			JptUiDetailsMessages.Joining_joinColumnJoiningLabel,
+			JoinColumnJoiningStrategyPane.buildUsesJoinColumnJoiningStrategyHolder(getSubjectHolder()),
+			null);
+
+		JoinColumnJoiningStrategyPane.
+			buildJoinColumnJoiningStrategyPaneWithIncludeOverrideCheckBox(this, composite);
+		
+		addRadioButton(
+			composite,
+			JptUiDetailsMessages.Joining_joinTableJoiningLabel,
+			JoinTableJoiningStrategyPane.buildUsesJoinTableJoiningStrategyHolder(getSubjectHolder()),
+			null);
+
+		new JoinTableJoiningStrategyPane(this, composite);
+
+		addSubPane(composite, 5);
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/NamedQueryProperty2_0Composite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/NamedQueryProperty2_0Composite.java
new file mode 100644
index 0000000..a673a5b
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/NamedQueryProperty2_0Composite.java
@@ -0,0 +1,67 @@
+/*******************************************************************************
+* Copyright (c) 2009 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.ui.internal.jpa2.details;
+
+import org.eclipse.jpt.core.jpa2.context.NamedQuery2_0;
+import org.eclipse.jpt.ui.internal.details.JptUiDetailsMessages;
+import org.eclipse.jpt.ui.internal.details.NamedQueryPropertyComposite;
+import org.eclipse.jpt.ui.internal.details.QueryHintsComposite;
+import org.eclipse.jpt.ui.internal.widgets.Pane;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ *  NamedQueryProperty2_0Composite
+ */
+public class NamedQueryProperty2_0Composite extends NamedQueryPropertyComposite<NamedQuery2_0>
+{
+	/**
+	 * Creates a new <code>NamedQueryProperty2_0Composite</code>.
+	 *
+	 * @param parentPane The parent container of this one
+	 * @param subjectHolder The holder of this pane's subject
+	 * @param parent The parent container
+	 */
+	public NamedQueryProperty2_0Composite(Pane<?> parentPane,
+	                                   PropertyValueModel<NamedQuery2_0> subjectHolder,
+	                                   Composite parent) {
+
+		super(parentPane, subjectHolder, parent);
+	}
+
+	@Override
+	protected void initializeLayout(Composite container) {
+		
+		this.addLabeledText(
+			container, 
+			JptUiDetailsMessages.NamedQueryComposite_nameTextLabel, 
+			this.buildNameTextHolder());
+
+		// Query text area
+		this.addLabeledMultiLineText(
+			container,
+			JptUiDetailsMessages.NamedQueryPropertyComposite_query,
+			this.buildQueryHolder(),
+			4,
+			null
+		);
+
+		new LockModeComposite(this, container);
+			
+		// Query Hints pane
+		container = this.addTitledGroup(
+			this.addSubPane(container, 5),
+			JptUiDetailsMessages.NamedQueryPropertyComposite_queryHintsGroupBox
+		);
+
+		new QueryHintsComposite(this, container);
+	}
+	
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/OneToManyJoiningStrategy2_0Pane.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/OneToManyJoiningStrategy2_0Pane.java
new file mode 100644
index 0000000..4ff6b24
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/OneToManyJoiningStrategy2_0Pane.java
@@ -0,0 +1,95 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2010 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.ui.internal.jpa2.details;
+
+import org.eclipse.jpt.core.context.OneToManyRelationshipReference;
+import org.eclipse.jpt.core.jpa2.context.OneToManyRelationshipReference2_0;
+import org.eclipse.jpt.ui.internal.details.JoinColumnJoiningStrategyPane;
+import org.eclipse.jpt.ui.internal.details.JoinTableJoiningStrategyPane;
+import org.eclipse.jpt.ui.internal.details.JptUiDetailsMessages;
+import org.eclipse.jpt.ui.internal.details.MappedByJoiningStrategyPane;
+import org.eclipse.jpt.ui.internal.widgets.Pane;
+import org.eclipse.jpt.utility.internal.model.value.SimplePropertyValueModel;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * Here is the layout of this pane:  
+ * <pre>
+ * -----------------------------------------------------------------------------
+ * | - Joining Strategy ------------------------------------------------------ |
+ * | |                                                                       | |
+ * | | o MappedByJoiningStrategyPane _______________________________________ | |
+ * | | |                                                                   | | |
+ * | | |                                                                   | | |
+ * | | --------------------------------------------------------------------- | |
+ * | | o JoinTableStrategyPane _____________________________________________ | |
+ * | | |                                                                   | | |
+ * | | |                                                                   | | |
+ * | | --------------------------------------------------------------------- | |
+ * | ------------------------------------------------------------------------- |
+ * -----------------------------------------------------------------------------</pre>
+ *
+ * @see {@link OneToManyMapping}
+ * @see {@link OneToManyRelationshipReference}
+ * @see {@link OrmOneToManyMappingComposite}
+ * @see {@link MappedByStrategyPane}
+ * @see {@link JoinTableStrategyPane}
+ *
+ * @version 2.3
+ * @since 2.1
+ */
+public class OneToManyJoiningStrategy2_0Pane 
+	extends Pane<OneToManyRelationshipReference2_0>
+{
+	public OneToManyJoiningStrategy2_0Pane(
+			Pane<?> parentPane, 
+			PropertyValueModel<? extends OneToManyRelationshipReference2_0> subjectHolder, 
+			Composite parent) {
+		
+		super(parentPane, subjectHolder, parent);
+	}
+	
+	
+	@Override
+	protected void initializeLayout(Composite container) {
+		Composite composite = addCollapsibleSection(
+			container,
+			JptUiDetailsMessages.Joining_title,
+			new SimplePropertyValueModel<Boolean>(Boolean.TRUE));
+	
+		addRadioButton(
+			composite,
+			JptUiDetailsMessages.Joining_mappedByLabel,
+			MappedByJoiningStrategyPane.buildUsesMappedByJoiningStrategyHolder(getSubjectHolder()),
+			null);
+
+		new MappedByJoiningStrategyPane(this, composite);
+		
+		addRadioButton(
+			composite,
+			JptUiDetailsMessages.Joining_joinColumnJoiningLabel,
+			JoinColumnJoiningStrategyPane.buildUsesJoinColumnJoiningStrategyHolder(getSubjectHolder()),
+			null);
+
+		JoinColumnJoiningStrategyPane.
+			buildJoinColumnJoiningStrategyPaneWithIncludeOverrideCheckBox(this, composite);
+		
+		addRadioButton(
+			composite,
+			JptUiDetailsMessages.Joining_joinTableJoiningLabel,
+			JoinTableJoiningStrategyPane.buildUsesJoinTableJoiningStrategyHolder(getSubjectHolder()),
+			null);
+
+		new JoinTableJoiningStrategyPane(this, composite);
+		
+		addSubPane(composite, 5);
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/OneToOneJoiningStrategy2_0Pane.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/OneToOneJoiningStrategy2_0Pane.java
new file mode 100644
index 0000000..dea1b9b
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/OneToOneJoiningStrategy2_0Pane.java
@@ -0,0 +1,115 @@
+/*******************************************************************************
+ * Copyright (c) 2010 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.ui.internal.jpa2.details;
+
+import org.eclipse.jpt.core.context.OneToOneMapping;
+import org.eclipse.jpt.core.context.OneToOneRelationshipReference;
+import org.eclipse.jpt.core.jpa2.context.OneToOneRelationshipReference2_0;
+import org.eclipse.jpt.ui.internal.details.JoinColumnJoiningStrategyPane;
+import org.eclipse.jpt.ui.internal.details.JoinTableJoiningStrategyPane;
+import org.eclipse.jpt.ui.internal.details.JptUiDetailsMessages;
+import org.eclipse.jpt.ui.internal.details.MappedByJoiningStrategyPane;
+import org.eclipse.jpt.ui.internal.details.OneToOneMappingComposite;
+import org.eclipse.jpt.ui.internal.details.PrimaryKeyJoinColumnJoiningStrategyPane;
+import org.eclipse.jpt.ui.internal.widgets.Pane;
+import org.eclipse.jpt.utility.internal.model.value.SimplePropertyValueModel;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * Here is the layout of this pane:  
+ * <pre>
+ * -----------------------------------------------------------------------------
+ * | - Joining Strategy ------------------------------------------------------ |
+ * | |                                                                       | |
+ * | | o MappedByJoiningStrategyPane _______________________________________ | |
+ * | | |                                                                   | | |
+ * | | |                                                                   | | |
+ * | | --------------------------------------------------------------------- | |
+ * | | o JoinColumnStrategyPane ____________________________________________ | |
+ * | | |                                                                   | | |
+ * | | |                                                                   | | |
+ * | | --------------------------------------------------------------------- | |
+ * | | o JoinTableJoiningStrategyPane_______________________________________ | |
+ * | | |                                                                   | | |
+ * | | |                                                                   | | |
+ * | | --------------------------------------------------------------------- | |
+ * | | o PrimaryKeyJoinColumnStrategyPane __________________________________ | |
+ * | | |                                                                   | | |
+ * | | |                                                                   | | |
+ * | | --------------------------------------------------------------------- | |
+ * | ------------------------------------------------------------------------- |
+ * -----------------------------------------------------------------------------</pre>
+ *
+ * @see {@link OneToOneMapping}
+ * @see {@link OneToOneRelationshipReference}
+ * @see {@link OneToOneMappingComposite}
+ * @see {@link MappedByStrategyPane}
+ * @see {@link JoinColumnStrategyPane}
+ * @see {@link PrimaryKeyJoinColumnStrategyPane}
+ *
+ * @version 2.3
+ * @since 2.1
+ */
+public class OneToOneJoiningStrategy2_0Pane 
+	extends Pane<OneToOneRelationshipReference2_0>
+{
+	public OneToOneJoiningStrategy2_0Pane(
+			Pane<?> parentPane, 
+			PropertyValueModel<? extends OneToOneRelationshipReference2_0> subjectHolder, 
+			Composite parent) {
+		
+		super(parentPane, subjectHolder, parent);
+	}
+	
+	
+	@Override
+	protected void initializeLayout(Composite container) {
+		Composite composite = addCollapsibleSection(
+				container,
+				JptUiDetailsMessages.Joining_title,
+				new SimplePropertyValueModel<Boolean>(Boolean.TRUE));
+		
+		addRadioButton(
+			composite,
+			JptUiDetailsMessages.Joining_mappedByLabel,
+			MappedByJoiningStrategyPane.buildUsesMappedByJoiningStrategyHolder(getSubjectHolder()),
+			null);
+
+		new MappedByJoiningStrategyPane(this, composite);
+		
+		addRadioButton(
+			composite,
+			JptUiDetailsMessages.Joining_primaryKeyJoinColumnJoiningLabel,
+			PrimaryKeyJoinColumnJoiningStrategyPane.buildUsesPrimaryKeyJoinColumnJoiningStrategyHolder(getSubjectHolder()),
+			null);
+
+		new PrimaryKeyJoinColumnJoiningStrategyPane(this, composite);
+		
+		addRadioButton(
+			composite,
+			JptUiDetailsMessages.Joining_joinColumnJoiningLabel,
+			JoinColumnJoiningStrategyPane.buildUsesJoinColumnJoiningStrategyHolder(getSubjectHolder()),
+			null);
+
+		JoinColumnJoiningStrategyPane.
+				buildJoinColumnJoiningStrategyPaneWithIncludeOverrideCheckBox(this, composite);
+		
+		addRadioButton(
+			composite,
+			JptUiDetailsMessages.Joining_joinTableJoiningLabel,
+			JoinTableJoiningStrategyPane.buildUsesJoinTableJoiningStrategyHolder(getSubjectHolder()),
+			null);
+
+		new JoinTableJoiningStrategyPane(this, composite);
+
+		addSubPane(composite, 5);
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/OrderColumnComposite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/OrderColumnComposite.java
new file mode 100644
index 0000000..98213a7
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/OrderColumnComposite.java
@@ -0,0 +1,369 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 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.ui.internal.jpa2.details;
+
+import java.util.Collection;
+
+import org.eclipse.jpt.core.context.BaseColumn;
+import org.eclipse.jpt.core.context.NamedColumn;
+import org.eclipse.jpt.core.jpa2.context.OrderColumn2_0;
+import org.eclipse.jpt.db.Table;
+import org.eclipse.jpt.ui.internal.JpaHelpContextIds;
+import org.eclipse.jpt.ui.internal.details.JptUiDetailsMessages;
+import org.eclipse.jpt.ui.internal.details.db.ColumnCombo;
+import org.eclipse.jpt.ui.internal.widgets.Pane;
+import org.eclipse.jpt.utility.internal.model.value.PropertyAspectAdapter;
+import org.eclipse.jpt.utility.internal.model.value.SimplePropertyValueModel;
+import org.eclipse.jpt.utility.internal.model.value.TransformationPropertyValueModel;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.jpt.utility.model.value.WritablePropertyValueModel;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * Here the layout of this pane:
+ * <pre>
+ * -----------------------------------------------------------------------------
+ * | ------------------------------------------------------------------------- |
+ * | |                                                                       | |
+ * | | ColumnCombo                                                           | |
+ * | |                                                                       | |
+ * | ------------------------------------------------------------------------- |
+ * |                                                                           |
+ * | > Details                                                                 |
+ * |                                                                           |
+ * |   x Insertable                                                            |
+ * |                                                                           |
+ * |   x Updatable                                                             |
+ * |                                                                           |
+ * |   x Nullable                                                              |
+ * |                                                                           |
+ * |                      ---------------------------------------------------- |
+ * |   Column Definition: | I                                                | |
+ * |                      ---------------------------------------------------- |
+ * -----------------------------------------------------------------------------</pre>
+ * *
+ * @version 3.0
+ * @since 3.0
+ */
+public class OrderColumnComposite extends Pane<OrderColumn2_0> {
+
+	/**
+	 * Creates a new <code>ColumnComposite</code>.
+	 *
+	 * @param parentPane The parent container of this one
+	 * @param subjectHolder The holder of the subject <code>IColumn</code>
+	 * @param parent The parent container
+	 */
+	public OrderColumnComposite(Pane<?> parentPane,
+	                       PropertyValueModel<? extends OrderColumn2_0> subjectHolder,
+	                       Composite parent) {
+
+		super(parentPane, subjectHolder, parent, false);
+	}
+
+	/**
+	 * Creates a new <code>ColumnComposite</code>.
+	 *
+	 * @param parentPane The parent container of this one
+	 * @param subjectHolder The holder of the subject <code>IColumn</code>
+	 * @param parent The parent container
+	 * @param automaticallyAlignWidgets <code>true</code> to make the widgets
+	 * this pane aligned with the widgets of the given parent controller;
+	 * <code>false</code> to not align them
+	 */
+	public OrderColumnComposite(Pane<?> parentPane,
+	                       PropertyValueModel<? extends OrderColumn2_0> subjectHolder,
+	                       Composite parent,
+	                       boolean automaticallyAlignWidgets) {
+
+		super(parentPane, subjectHolder, parent, automaticallyAlignWidgets);
+	}
+	
+	/**
+	 * Creates a new <code>ColumnComposite</code>.
+	 *
+	 * @param parentPane The parent container of this one
+	 * @param subjectHolder The holder of the subject <code>IColumn</code>
+	 * @param parent The parent container
+	 * @param automaticallyAlignWidgets <code>true</code> to make the widgets
+	 * this pane aligned with the widgets of the given parent controller;
+	 * <code>false</code> to not align them
+	 */
+	public OrderColumnComposite(Pane<?> parentPane,
+	                       PropertyValueModel<? extends OrderColumn2_0> subjectHolder,
+	                       Composite parent,
+	                       boolean automaticallyAlignWidgets,
+	                       boolean parentManagePane) {
+
+		super(parentPane, subjectHolder, parent, automaticallyAlignWidgets, parentManagePane);
+	}
+
+	private ColumnCombo<OrderColumn2_0> addColumnCombo(Composite container) {
+
+		return new ColumnCombo<OrderColumn2_0>(this, container) {
+
+			@Override
+			protected void addPropertyNames(Collection<String> propertyNames) {
+				super.addPropertyNames(propertyNames);
+				propertyNames.add(NamedColumn.DEFAULT_NAME_PROPERTY);
+				propertyNames.add(NamedColumn.SPECIFIED_NAME_PROPERTY);
+			}
+
+			@Override
+			protected String getDefaultValue() {
+				return getSubject().getDefaultName();
+			}
+
+			@Override
+			protected void setValue(String value) {
+				getSubject().setSpecifiedName(value);
+			}
+
+			@Override
+			protected Table getDbTable_() {
+				return getSubject().getDbTable();
+			}
+
+			@Override
+			protected String getValue() {
+				return getSubject().getSpecifiedName();
+			}
+			@Override
+			public String toString() {
+				return "OrderColumnComposite.columnCombo"; //$NON-NLS-1$
+			}
+		};
+	}
+
+	private WritablePropertyValueModel<String> buildColumnDefinitionHolder() {
+		return new PropertyAspectAdapter<OrderColumn2_0, String>(getSubjectHolder(), NamedColumn.COLUMN_DEFINITION_PROPERTY) {
+			@Override
+			protected String buildValue_() {
+				return this.subject.getColumnDefinition();
+			}
+
+			@Override
+			protected void setValue_(String value) {
+				if (value.length() == 0) {
+					value = null;
+				}
+				this.subject.setColumnDefinition(value);
+			}
+		};
+	}
+	
+	private WritablePropertyValueModel<Boolean> buildInsertableHolder() {
+		return new PropertyAspectAdapter<OrderColumn2_0, Boolean>(getSubjectHolder(), BaseColumn.SPECIFIED_INSERTABLE_PROPERTY) {
+			@Override
+			protected Boolean buildValue_() {
+				return this.subject.getSpecifiedInsertable();
+			}
+
+			@Override
+			protected void setValue_(Boolean value) {
+				this.subject.setSpecifiedInsertable(value);
+			}
+		};
+	}
+
+	private PropertyValueModel<String> buildInsertableStringHolder() {
+		return new TransformationPropertyValueModel<Boolean, String>(buildDefaultInsertableHolder()) {
+			@Override
+			protected String transform(Boolean value) {
+				if (value != null) {
+					String defaultStringValue = value.booleanValue() ? JptUiDetailsMessages.Boolean_True : JptUiDetailsMessages.Boolean_False;
+					return NLS.bind(JptUiDetailsMessages.ColumnComposite_insertableWithDefault, defaultStringValue);
+				}
+				return JptUiDetailsMessages.ColumnComposite_insertable;
+			}
+		};
+	}
+	
+	private PropertyValueModel<Boolean> buildDefaultInsertableHolder() {
+		return new PropertyAspectAdapter<OrderColumn2_0, Boolean>(
+			getSubjectHolder(),
+			BaseColumn.SPECIFIED_INSERTABLE_PROPERTY,
+			BaseColumn.DEFAULT_INSERTABLE_PROPERTY)
+		{
+			@Override
+			protected Boolean buildValue_() {
+				if (this.subject.getSpecifiedInsertable() != null) {
+					return null;
+				}
+				return Boolean.valueOf(this.subject.isDefaultInsertable());
+			}
+		};
+	}
+
+	private WritablePropertyValueModel<Boolean> buildNullableHolder() {
+		return new PropertyAspectAdapter<OrderColumn2_0, Boolean>(
+			getSubjectHolder(),
+			BaseColumn.SPECIFIED_NULLABLE_PROPERTY)
+		{
+			@Override
+			protected Boolean buildValue_() {
+				return this.subject.getSpecifiedNullable();
+			}
+
+			@Override
+			protected void setValue_(Boolean value) {
+				this.subject.setSpecifiedNullable(value);
+			}
+		};
+	}
+
+	private PropertyValueModel<String> buildNullableStringHolder() {
+		return new TransformationPropertyValueModel<Boolean, String>(buildDefaultNullableHolder()) {
+			@Override
+			protected String transform(Boolean value) {
+				if (value != null) {
+					String defaultStringValue = value.booleanValue() ? JptUiDetailsMessages.Boolean_True : JptUiDetailsMessages.Boolean_False;
+					return NLS.bind(JptUiDetailsMessages.ColumnComposite_nullableWithDefault, defaultStringValue);
+				}
+				return JptUiDetailsMessages.ColumnComposite_nullable;
+			}
+		};
+	}
+	
+	private PropertyValueModel<Boolean> buildDefaultNullableHolder() {
+		return new PropertyAspectAdapter<OrderColumn2_0, Boolean>(
+			getSubjectHolder(),
+			BaseColumn.SPECIFIED_NULLABLE_PROPERTY,
+			BaseColumn.DEFAULT_NULLABLE_PROPERTY)
+		{
+			@Override
+			protected Boolean buildValue_() {
+				if (this.subject.getSpecifiedNullable() != null) {
+					return null;
+				}
+				return Boolean.valueOf(this.subject.isDefaultNullable());
+			}
+		};
+	}
+
+
+	private WritablePropertyValueModel<Boolean> buildUpdatableHolder() {
+		return new PropertyAspectAdapter<OrderColumn2_0, Boolean>(
+			getSubjectHolder(),
+			BaseColumn.DEFAULT_UPDATABLE_PROPERTY,
+			BaseColumn.SPECIFIED_UPDATABLE_PROPERTY)
+		{
+			@Override
+			protected Boolean buildValue_() {
+				return this.subject.getSpecifiedUpdatable();
+			}
+
+			@Override
+			protected void setValue_(Boolean value) {
+				this.subject.setSpecifiedUpdatable(value);
+			}
+		};
+	}
+
+	private PropertyValueModel<String> buildUpdatableStringHolder() {
+
+		return new TransformationPropertyValueModel<Boolean, String>(buildDefaultUpdatableHolder()) {
+
+			@Override
+			protected String transform(Boolean value) {
+				if (value != null) {
+					String defaultStringValue = value.booleanValue() ? JptUiDetailsMessages.Boolean_True : JptUiDetailsMessages.Boolean_False;
+					return NLS.bind(JptUiDetailsMessages.ColumnComposite_updatableWithDefault, defaultStringValue);
+				}
+				return JptUiDetailsMessages.ColumnComposite_updatable;
+			}
+		};
+	}
+	
+	private PropertyValueModel<Boolean> buildDefaultUpdatableHolder() {
+		return new PropertyAspectAdapter<OrderColumn2_0, Boolean>(
+			getSubjectHolder(),
+			BaseColumn.SPECIFIED_UPDATABLE_PROPERTY,
+			BaseColumn.DEFAULT_UPDATABLE_PROPERTY)
+		{
+			@Override
+			protected Boolean buildValue_() {
+				if (this.subject.getSpecifiedUpdatable() != null) {
+					return null;
+				}
+				return Boolean.valueOf(this.subject.isDefaultUpdatable());
+			}
+		};
+	}
+
+	@Override
+	protected void initializeLayout(Composite container) {
+		// Column widgets
+		addLabeledComposite(
+			container,
+			JptUiDetailsMessages.ColumnComposite_name,
+			addColumnCombo(container),
+			JpaHelpContextIds.MAPPING_ORDER_COLUMN_ORDERING_COLUMN
+		);
+
+		// Details sub-pane
+		container = addCollapsibleSubSection(
+			container,
+			JptUiDetailsMessages.ColumnComposite_details,
+			new SimplePropertyValueModel<Boolean>(Boolean.FALSE)
+		);
+
+		new DetailsComposite(this, getSubjectHolder(), addSubPane(container, 0, 16));
+	}
+
+	protected class DetailsComposite extends Pane<OrderColumn2_0> {
+				
+		public DetailsComposite(Pane<?> parentPane,
+            PropertyValueModel<? extends OrderColumn2_0> subjectHolder,
+            Composite parent) {
+
+			super(parentPane, subjectHolder, parent, false);
+		}
+
+		@Override
+		protected void initializeLayout(Composite container) {
+
+			// Insertable tri-state check box
+			addTriStateCheckBoxWithDefault(
+				addSubPane(container, 4),
+				JptUiDetailsMessages.ColumnComposite_insertable,
+				buildInsertableHolder(),
+				buildInsertableStringHolder(),
+				JpaHelpContextIds.MAPPING_COLUMN_INSERTABLE
+			);
+
+			// Updatable tri-state check box
+			addTriStateCheckBoxWithDefault(
+				container,
+				JptUiDetailsMessages.ColumnComposite_updatable,
+				buildUpdatableHolder(),
+				buildUpdatableStringHolder(),
+				JpaHelpContextIds.MAPPING_COLUMN_UPDATABLE
+			);
+
+			// Nullable tri-state check box
+			addTriStateCheckBoxWithDefault(
+				container,
+				JptUiDetailsMessages.ColumnComposite_nullable,
+				buildNullableHolder(),
+				buildNullableStringHolder(),
+				JpaHelpContextIds.MAPPING_COLUMN_NULLABLE
+			);
+
+			// Column Definition widgets
+			addLabeledText(
+				container,
+				JptUiDetailsMessages.ColumnComposite_columnDefinition,
+				buildColumnDefinitionHolder()
+			);
+		}
+	}
+}
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/Ordering2_0Composite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/Ordering2_0Composite.java
new file mode 100644
index 0000000..e1616b5
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/Ordering2_0Composite.java
@@ -0,0 +1,168 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2010 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.ui.internal.jpa2.details;
+
+import org.eclipse.jpt.core.context.CollectionMapping;
+import org.eclipse.jpt.core.context.Orderable;
+import org.eclipse.jpt.core.jpa2.context.OrderColumn2_0;
+import org.eclipse.jpt.core.jpa2.context.Orderable2_0;
+import org.eclipse.jpt.ui.WidgetFactory;
+import org.eclipse.jpt.ui.internal.JpaHelpContextIds;
+import org.eclipse.jpt.ui.internal.details.AbstractOrderingComposite;
+import org.eclipse.jpt.ui.internal.details.JptUiDetailsMessages;
+import org.eclipse.jpt.ui.internal.util.PaneEnabler;
+import org.eclipse.jpt.ui.internal.widgets.Pane;
+import org.eclipse.jpt.utility.internal.model.value.PropertyAspectAdapter;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.jpt.utility.model.value.WritablePropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * Here the layout of this pane:
+ * <pre>
+ * -----------------------------------------------------------------------------
+ * | - Ordering -------------------------------------------------------------- |
+ * | |                                                                       | |
+ * | | o None                                                                | |
+ * | |                                                                       | |
+ * | | o Primary Key                                                         | |
+ * | |                                                                       | |
+ * | | o Custom                                                              | |
+ * | |   ------------------------------------------------------------------- | |
+ * | |   | I                                                               | | |
+ * | |   ------------------------------------------------------------------- | |
+ * | ------------------------------------------------------------------------- |
+ * -----------------------------------------------------------------------------</pre>
+ *
+ * @see CollectionMapping
+ * @see OrmManyToManyMappingComposite - A container of this pane
+ * @see OrmOneToManyMappingComposite - A container of this pane
+ *
+ * @version 2.3
+ * @since 1.0
+ */
+public class Ordering2_0Composite extends AbstractOrderingComposite
+{
+	/**
+	 * Creates a new <code>OrderingComposite</code>.
+	 *
+	 * @param parentPane The parent container of this one
+	 * @param parent The parent container
+	 */
+	public Ordering2_0Composite(Pane<? extends CollectionMapping> parentPane,
+	                         Composite parent) {
+
+		super(parentPane, parent);
+	}
+
+	/**
+	 * Creates a new <code>OrderingComposite</code>.
+	 *
+	 * @param subjectHolder The holder of the subject <code>IMultiRelationshipMapping</code>
+	 * @param parent The parent container
+	 * @param widgetFactory The factory used to create various common widgets
+	 */
+	public Ordering2_0Composite(PropertyValueModel<? extends CollectionMapping> subjectHolder,
+	                         Composite parent,
+	                         WidgetFactory widgetFactory) {
+
+		super(subjectHolder, parent, widgetFactory);
+	}
+	
+	@Override
+	protected void initializeLayout(Composite container) {
+		PropertyValueModel<Orderable> orderableHolder = buildOrderableHolder();
+
+		container = addCollapsibleSection(
+			container,
+			JptUiDetailsMessages.OrderingComposite_orderingGroup
+		);
+
+		// No Ordering radio button
+		addRadioButton(
+			container,
+			JptUiDetailsMessages.OrderingComposite_none,
+			buildNoOrderingHolder(orderableHolder),
+			JpaHelpContextIds.MAPPING_ORDER_BY_NO_ORDERING
+		);
+
+		// Order by Primary Key radio button
+		addRadioButton(
+			container,
+			JptUiDetailsMessages.OrderingComposite_primaryKey,
+			buildPrimaryKeyOrderingHolder(orderableHolder),
+			JpaHelpContextIds.MAPPING_ORDER_BY_PRIMARY_KEY_ORDERING
+		);
+
+		// Custom Ordering radio button
+		addRadioButton(
+			container,
+			JptUiDetailsMessages.OrderingComposite_custom,
+			buildCustomOrderingHolder(orderableHolder),
+			JpaHelpContextIds.MAPPING_ORDER_BY_CUSTOM_ORDERING
+		);
+
+		// Custom Ordering text field
+		addText(
+			addSubPane(container, 0, 16),
+			buildSpecifiedOrderByHolder(orderableHolder),
+			JpaHelpContextIds.MAPPING_ORDER_BY,
+			buildCustomOrderingHolder(orderableHolder)
+		);
+
+		
+		// Order Column Ordering radio button
+		addRadioButton(
+			container,
+			JptUiDetailsMessages2_0.OrderingComposite_orderColumn,
+			buildOrderColumnOrderingHolder(orderableHolder),
+			JpaHelpContextIds.MAPPING_ORDER_COLUMN_ORDERING
+		);
+
+		OrderColumnComposite orderColumnComposite = new OrderColumnComposite(
+			this,
+			buildOrderColumnHolder(orderableHolder), 
+			addSubPane(container, 0, 16));
+
+		installOrderColumnCompositeEnabler(orderableHolder, orderColumnComposite);
+	}
+	
+	protected void installOrderColumnCompositeEnabler(PropertyValueModel<Orderable> orderableHolder, OrderColumnComposite pane) {
+		new PaneEnabler(buildPaneEnablerHolder(orderableHolder), pane);
+	}
+	
+	private PropertyValueModel<Boolean> buildPaneEnablerHolder(PropertyValueModel<Orderable> orderableHolder) {
+		return buildOrderColumnOrderingHolder(orderableHolder);
+	}
+
+
+	protected WritablePropertyValueModel<Boolean> buildOrderColumnOrderingHolder(PropertyValueModel<Orderable> orderableHolder) {
+		return new PropertyAspectAdapter<Orderable, Boolean>(orderableHolder, Orderable2_0.ORDER_COLUMN_ORDERING_PROPERTY) {
+			@Override
+			protected Boolean buildValue_() {
+				return Boolean.valueOf(((Orderable2_0) this.subject).isOrderColumnOrdering());
+			}
+
+			@Override
+			protected void setValue_(Boolean value) {
+				((Orderable2_0) this.subject).setOrderColumnOrdering(value.booleanValue());
+			}
+		};
+	}
+	
+	protected PropertyValueModel<OrderColumn2_0> buildOrderColumnHolder(PropertyValueModel<Orderable> orderableHolder) {
+		return new PropertyAspectAdapter<Orderable, OrderColumn2_0>(orderableHolder) {
+			@Override
+			protected OrderColumn2_0 buildValue_() {
+				return ((Orderable2_0) this.subject).getOrderColumn();
+			}
+		};
+	}
+}
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/OrphanRemoval2_0Composite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/OrphanRemoval2_0Composite.java
new file mode 100644
index 0000000..58a4dc2
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/OrphanRemoval2_0Composite.java
@@ -0,0 +1,111 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2010 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.ui.internal.jpa2.details;
+
+import org.eclipse.jpt.core.context.RelationshipMapping;
+import org.eclipse.jpt.core.jpa2.context.OrphanRemovable2_0;
+import org.eclipse.jpt.ui.internal.details.JptUiDetailsMessages;
+import org.eclipse.jpt.ui.internal.widgets.Pane;
+import org.eclipse.jpt.utility.internal.model.value.PropertyAspectAdapter;
+import org.eclipse.jpt.utility.internal.model.value.TransformationPropertyValueModel;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.jpt.utility.model.value.WritablePropertyValueModel;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * Here the layout of this pane:
+ * <pre>
+ * -----------------------------------------------------------------------------
+ * | ------------------------------------------------------------------------- |
+ * | |                                                                       | |
+ * | | [X]  Orphan removal (true/false)                                    | |
+ * | |                                                                       | |
+ * | ------------------------------------------------------------------------- |
+ * -----------------------------------------------------------------------------</pre>
+ *
+ * @see {@link OrphanRemovable2_0}
+ * @see {@link JavaOneToOneMapping2_0Composite} - A container of this widget
+ * @see {@link OrmOneToOneMapping2_0Composite} - A container of this widget
+ */
+public class OrphanRemoval2_0Composite extends Pane<OrphanRemovable2_0>
+{
+	/**
+	 * Creates a new <code>OrphanRemoval2_0Composite</code>.
+	 *
+	 * @param parentPane The parent container of this one
+	 * @param parent The parent container
+	 */
+	public OrphanRemoval2_0Composite(
+							Pane<? extends RelationshipMapping> parentPane,
+							PropertyValueModel<? extends OrphanRemovable2_0> subjectHolder,
+							Composite parent) {
+		super(parentPane, subjectHolder, parent);
+	}
+
+	@Override
+	protected void initializeLayout(Composite container) {
+
+		this.addTriStateCheckBoxWithDefault(
+			container,
+			JptUiDetailsMessages2_0.OrphanRemoval2_0Composite_orphanRemovalLabel,
+			this.buildOrphanRemovalHolder(),
+			this.buildOrphanRemovalStringHolder(),
+			null		// TODO
+		);
+	}
+	private WritablePropertyValueModel<Boolean> buildOrphanRemovalHolder() {
+		return new PropertyAspectAdapter<OrphanRemovable2_0, Boolean>(
+				this.getSubjectHolder(), 
+				OrphanRemovable2_0.DEFAULT_ORPHAN_REMOVAL_PROPERTY,
+				OrphanRemovable2_0.SPECIFIED_ORPHAN_REMOVAL_PROPERTY) {
+			@Override
+			protected Boolean buildValue_() {
+				return this.subject.getSpecifiedOrphanRemoval();
+			}
+
+			@Override
+			protected void setValue_(Boolean value) {
+				this.subject.setSpecifiedOrphanRemoval(value);
+			}
+		};
+	}
+
+	private PropertyValueModel<String> buildOrphanRemovalStringHolder() {
+		
+		return new TransformationPropertyValueModel<Boolean, String>(this.buildDefaultOrphanRemovalHolder()) {
+			@Override
+			protected String transform(Boolean value) {
+				if (value != null) {
+					String defaultStringValue = value.booleanValue() ? JptUiDetailsMessages.Boolean_True : JptUiDetailsMessages.Boolean_False;
+					return NLS.bind(JptUiDetailsMessages2_0.OrphanRemoval2_0Composite_orphanRemovalLabelDefault, defaultStringValue);
+				}
+				return JptUiDetailsMessages2_0.OrphanRemoval2_0Composite_orphanRemovalLabel;
+			}
+		};
+	}
+	
+	private PropertyValueModel<Boolean> buildDefaultOrphanRemovalHolder() {
+		return new PropertyAspectAdapter<OrphanRemovable2_0, Boolean>(
+			this.getSubjectHolder(),
+			OrphanRemovable2_0.SPECIFIED_ORPHAN_REMOVAL_PROPERTY,
+			OrphanRemovable2_0.DEFAULT_ORPHAN_REMOVAL_PROPERTY)
+		{
+			@Override
+			protected Boolean buildValue_() {
+				if (this.subject.getSpecifiedOrphanRemoval() != null) {
+					return null;
+				}
+				return Boolean.valueOf(this.subject.isDefaultOrphanRemoval());
+			}
+		};
+	}
+
+}
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/Queries2_0Composite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/Queries2_0Composite.java
new file mode 100644
index 0000000..59a4c67
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/Queries2_0Composite.java
@@ -0,0 +1,55 @@
+/*******************************************************************************
+* Copyright (c) 2009 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.ui.internal.jpa2.details;
+
+import org.eclipse.jpt.core.context.NamedQuery;
+import org.eclipse.jpt.core.context.Query;
+import org.eclipse.jpt.core.context.QueryContainer;
+import org.eclipse.jpt.core.jpa2.context.NamedQuery2_0;
+import org.eclipse.jpt.ui.internal.details.NamedQueryPropertyComposite;
+import org.eclipse.jpt.ui.internal.details.QueriesComposite;
+import org.eclipse.jpt.ui.internal.widgets.Pane;
+import org.eclipse.jpt.utility.internal.model.value.TransformationPropertyValueModel;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.ui.part.PageBook;
+
+/**
+ *  Queries2_0Composite
+ */
+public class Queries2_0Composite
+	extends QueriesComposite
+{
+	public Queries2_0Composite(
+			Pane<?> parentPane, 
+			PropertyValueModel<? extends QueryContainer> subjectHolder,
+			Composite parent) {
+		
+		super(parentPane, subjectHolder, parent);
+	}
+	
+	
+	@Override
+	protected NamedQueryPropertyComposite<NamedQuery2_0> buildNamedQueryPropertyComposite(PageBook pageBook) {
+		return new NamedQueryProperty2_0Composite(
+			this,
+			this.buildNamedQuery2_0Holder(),
+			pageBook);
+	}
+	
+	protected PropertyValueModel<NamedQuery2_0> buildNamedQuery2_0Holder() {
+		return new TransformationPropertyValueModel<Query, NamedQuery2_0>(this.getQueryHolder()) {
+			@Override
+			protected NamedQuery2_0 transform_(Query value) {
+				return (value instanceof NamedQuery) ? (NamedQuery2_0) value : null;
+			}
+		};
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/SequenceGenerator2_0Composite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/SequenceGenerator2_0Composite.java
new file mode 100644
index 0000000..5f1b2fe
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/SequenceGenerator2_0Composite.java
@@ -0,0 +1,190 @@
+/*******************************************************************************
+* Copyright (c) 2009 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.ui.internal.jpa2.details;
+
+import java.util.Collection;
+
+import org.eclipse.jpt.core.JpaProject;
+import org.eclipse.jpt.core.context.SequenceGenerator;
+import org.eclipse.jpt.core.jpa2.context.SequenceGenerator2_0;
+import org.eclipse.jpt.db.SchemaContainer;
+import org.eclipse.jpt.ui.internal.JpaHelpContextIds;
+import org.eclipse.jpt.ui.internal.details.JptUiDetailsMessages;
+import org.eclipse.jpt.ui.internal.details.SequenceGeneratorComposite;
+import org.eclipse.jpt.ui.internal.details.db.CatalogCombo;
+import org.eclipse.jpt.ui.internal.details.db.SchemaCombo;
+import org.eclipse.jpt.ui.internal.widgets.Pane;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ *  JavaSequenceGenerator2_0Composite
+ */
+public class SequenceGenerator2_0Composite extends SequenceGeneratorComposite
+{
+
+	public SequenceGenerator2_0Composite(Pane<?> parentPane,
+		PropertyValueModel<SequenceGenerator> subjectHolder,
+		Composite parent,
+		GeneratorBuilder<SequenceGenerator> builder) {
+
+		super(parentPane, subjectHolder, parent, builder);
+	}
+
+	@Override
+	protected void initializeLayout(Composite container) {
+
+		// Name widgets
+		this.addLabeledText(
+			container,
+			JptUiDetailsMessages.SequenceGeneratorComposite_name,
+			this.buildGeneratorNameHolder(),
+			JpaHelpContextIds.MAPPING_SEQUENCE_GENERATOR_NAME
+		);
+
+		// Sequence Generator widgets
+		this.addLabeledComposite(
+			container,
+			JptUiDetailsMessages.SequenceGeneratorComposite_sequence,
+			this.buildSequenceNameCombo(container),
+			JpaHelpContextIds.MAPPING_SEQUENCE_GENERATOR_SEQUENCE
+		);
+
+		// Schema widgets
+		this.addLabeledComposite(
+			container,
+			JptUiDetailsMessages.SequenceGeneratorComposite_schema,
+			this.addSchemaCombo(container),
+			null	// JpaHelpContextIds.MAPPING_SEQUENCE_GENERATOR_SCHEMA
+		);
+
+		// Catalog widgets
+		this.addLabeledComposite(
+			container,
+			JptUiDetailsMessages.SequenceGeneratorComposite_catalog,
+			this.addCatalogCombo(container),
+			null	// JpaHelpContextIds.MAPPING_SEQUENCE_GENERATOR_CATALOG
+		);
+
+		this.addAllocationSizeCombo(container);
+		this.addInitialValueCombo(container);
+	}
+
+	private SchemaCombo<SequenceGenerator> addSchemaCombo(Composite container) {
+
+		return new SchemaCombo<SequenceGenerator>(this, getSubjectHolder(), container) {
+
+			@Override
+			protected void addPropertyNames(Collection<String> propertyNames) {
+				super.addPropertyNames(propertyNames);
+				propertyNames.add(SequenceGenerator2_0.DEFAULT_SCHEMA_PROPERTY);
+				propertyNames.add(SequenceGenerator2_0.SPECIFIED_SCHEMA_PROPERTY);
+				propertyNames.add(SequenceGenerator2_0.DEFAULT_CATALOG_PROPERTY);
+				propertyNames.add(SequenceGenerator2_0.SPECIFIED_CATALOG_PROPERTY);
+			}
+
+			@Override
+			protected void propertyChanged(String propertyName) {
+				if (propertyName == SequenceGenerator2_0.DEFAULT_CATALOG_PROPERTY
+					|| propertyName == SequenceGenerator2_0.SPECIFIED_CATALOG_PROPERTY ) {
+					repopulateComboBox();
+				}
+				else {
+					super.propertyChanged(propertyName);
+				}
+			}
+
+			@Override
+			protected String getDefaultValue() {
+				return ((SequenceGenerator2_0) getSubject()).getDefaultSchema();
+			}
+
+			@Override
+			protected boolean nullSubjectIsAllowed() {
+				return true;
+			}
+
+			/**
+			 * subject may be null, so delegate to the composite
+			 */
+			@Override
+			protected JpaProject getJpaProject() {
+				return SequenceGenerator2_0Composite.this.getJpaProject();
+			}
+
+			@Override
+			protected void setValue(String value) {
+				((SequenceGenerator2_0) SequenceGenerator2_0Composite.this.retrieveGenerator()).setSpecifiedSchema(value);
+			}
+
+			@Override
+			protected String getValue() {
+				return ((SequenceGenerator2_0) getSubject()).getSpecifiedSchema();
+			}
+
+			@Override
+			protected SchemaContainer getDbSchemaContainer() {
+				SequenceGenerator2_0 tg = (SequenceGenerator2_0) this.getSubject();
+				if (tg != null) {
+					return tg.getDbSchemaContainer();
+				}
+				return SequenceGenerator2_0Composite.this.getSubject().getContextDefaultDbSchemaContainer();
+			}
+			
+			@Override
+			protected SchemaContainer getDbSchemaContainer_() {
+				// we overrode #getDbSchemaContainer() instead
+				throw new UnsupportedOperationException();
+			}
+		};
+	}
+
+	private CatalogCombo<SequenceGenerator> addCatalogCombo(Composite container) {
+
+		return new CatalogCombo<SequenceGenerator>(this, getSubjectHolder(), container) {
+
+			@Override
+			protected void addPropertyNames(Collection<String> propertyNames) {
+				super.addPropertyNames(propertyNames);
+				propertyNames.add(SequenceGenerator2_0.DEFAULT_CATALOG_PROPERTY);
+				propertyNames.add(SequenceGenerator2_0.SPECIFIED_CATALOG_PROPERTY);
+			}
+
+			@Override
+			protected String getDefaultValue() {
+				return ((SequenceGenerator2_0) getSubject()).getDefaultCatalog();
+			}
+
+			@Override
+			protected boolean nullSubjectIsAllowed() {
+				return true;
+			}
+
+			/**
+			 * subject may be null, so delegate to the composite
+			 */
+			@Override
+			protected JpaProject getJpaProject() {
+				return SequenceGenerator2_0Composite.this.getJpaProject();
+			}
+
+			@Override
+			protected void setValue(String value) {
+				((SequenceGenerator2_0) SequenceGenerator2_0Composite.this.retrieveGenerator()).setSpecifiedCatalog(value);
+			}
+
+			@Override
+			protected String getValue() {
+				return ((SequenceGenerator2_0) getSubject()).getSpecifiedCatalog();
+			}
+		};
+	}
+	
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/TargetClassComposite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/TargetClassComposite.java
new file mode 100644
index 0000000..a39f006
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/TargetClassComposite.java
@@ -0,0 +1,130 @@
+/*******************************************************************************
+* Copyright (c) 2009 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.ui.internal.jpa2.details;
+
+import org.eclipse.jpt.core.JpaProject;
+import org.eclipse.jpt.core.jpa2.context.ElementCollectionMapping2_0;
+import org.eclipse.jpt.ui.internal.JpaHelpContextIds;
+import org.eclipse.jpt.ui.internal.details.JptUiDetailsMessages;
+import org.eclipse.jpt.ui.internal.widgets.ClassChooserComboPane;
+import org.eclipse.jpt.ui.internal.widgets.Pane;
+import org.eclipse.jpt.utility.internal.model.value.PropertyAspectAdapter;
+import org.eclipse.jpt.utility.internal.model.value.PropertyListValueModelAdapter;
+import org.eclipse.jpt.utility.model.value.ListValueModel;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.jpt.utility.model.value.WritablePropertyValueModel;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ *  target entity hyperlink label, combo and browse button 
+ */
+public class TargetClassComposite extends ClassChooserComboPane<ElementCollectionMapping2_0>
+{
+
+	/**
+	 * Creates a new <code>TargetEntityComposite</code>.
+	 *
+	 * @param parentPane The parent container of this one
+	 * @param parent The parent container
+	 */
+	public TargetClassComposite(
+								Pane<? extends ElementCollectionMapping2_0> parentPane,
+	                           Composite parent) {
+
+		super(parentPane, parent);
+	}
+
+	@Override
+	protected String getClassName() {
+		return getSubject().getTargetClass();
+	}
+
+	@Override
+	protected void setClassName(String className) {
+		this.getSubject().setSpecifiedTargetClass(className);
+	}
+
+	@Override
+	protected char getEnclosingTypeSeparator() {
+		return getSubject().getTargetClassEnclosingTypeSeparator();
+	}
+	
+    @Override
+    protected String getLabelText() {
+    	return JptUiDetailsMessages2_0.TargetClassComposite_label;
+    }
+   
+    @Override
+    protected String getHelpId() {
+    	return JpaHelpContextIds.MAPPING_ELEMENT_COLLECTION_TARGET_CLASS;
+    }
+   
+    @Override
+    protected JpaProject getJpaProject() {
+    	return getSubject().getJpaProject();
+    }
+
+    @Override
+	protected WritablePropertyValueModel<String> buildTextHolder() {
+		return new PropertyAspectAdapter<ElementCollectionMapping2_0, String>(this.getSubjectHolder(), ElementCollectionMapping2_0.SPECIFIED_TARGET_CLASS_PROPERTY) {
+			@Override
+			protected String buildValue_() {
+
+				String name = this.subject.getSpecifiedTargetClass();
+				if (name == null) {
+					name = TargetClassComposite.this.getDefaultValue(this.subject);
+				}
+				return name;
+			}
+
+			@Override
+			protected void setValue_(String value) {
+
+				if (getDefaultValue(this.subject).equals(value)) {
+					value = null;
+				}
+				this.subject.setSpecifiedTargetClass(value);
+			}
+		};
+    }
+
+	@Override
+	protected ListValueModel<String> buildClassListHolder() {
+		return this.buildDefaultProfilerListHolder();
+	}
+
+	private ListValueModel<String> buildDefaultProfilerListHolder() {
+		return new PropertyListValueModelAdapter<String>(
+			this.buildDefaultProfilerHolder()
+		);
+	}
+
+	private PropertyValueModel<String> buildDefaultProfilerHolder() {
+		return new PropertyAspectAdapter<ElementCollectionMapping2_0, String>(this.getSubjectHolder(), ElementCollectionMapping2_0.DEFAULT_TARGET_CLASS_PROPERTY) {
+			@Override
+			protected String buildValue_() {
+				return TargetClassComposite.this.getDefaultValue(this.subject);
+			}
+		};
+	}
+
+	private String getDefaultValue(ElementCollectionMapping2_0 subject) {
+		String defaultValue = subject.getDefaultTargetClass();
+
+		if (defaultValue != null) {
+			return NLS.bind(
+				JptUiDetailsMessages.DefaultWithOneParam,
+				defaultValue
+			);
+		}
+		return JptUiDetailsMessages.DefaultEmpty;
+	}
+}
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/java/Generic2_0JavaResourceUiDefinition.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/java/Generic2_0JavaResourceUiDefinition.java
new file mode 100644
index 0000000..bec9e7e
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/java/Generic2_0JavaResourceUiDefinition.java
@@ -0,0 +1,91 @@
+/*******************************************************************************
+ * Copyright (c) 2009 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.ui.internal.jpa2.details.java;
+
+import java.util.List;
+import org.eclipse.jpt.core.context.AttributeMapping;
+import org.eclipse.jpt.core.context.TypeMapping;
+import org.eclipse.jpt.ui.ResourceUiDefinition;
+import org.eclipse.jpt.ui.details.java.DefaultJavaAttributeMappingUiDefinition;
+import org.eclipse.jpt.ui.details.java.JavaAttributeMappingUiDefinition;
+import org.eclipse.jpt.ui.details.java.JavaTypeMappingUiDefinition;
+import org.eclipse.jpt.ui.details.java.JavaUiFactory;
+import org.eclipse.jpt.ui.internal.details.java.AbstractJavaResourceUiDefinition;
+import org.eclipse.jpt.ui.internal.details.java.DefaultBasicMappingUiDefinition;
+import org.eclipse.jpt.ui.internal.details.java.DefaultEmbeddedMappingUiDefinition;
+import org.eclipse.jpt.ui.internal.details.java.JavaBasicMappingUiDefinition;
+import org.eclipse.jpt.ui.internal.details.java.JavaEmbeddableUiDefinition;
+import org.eclipse.jpt.ui.internal.details.java.JavaEmbeddedIdMappingUDefinition;
+import org.eclipse.jpt.ui.internal.details.java.JavaEmbeddedMappingUiDefinition;
+import org.eclipse.jpt.ui.internal.details.java.JavaEntityUiDefinition;
+import org.eclipse.jpt.ui.internal.details.java.JavaIdMappingUiDefinition;
+import org.eclipse.jpt.ui.internal.details.java.JavaManyToManyMappingUiDefinition;
+import org.eclipse.jpt.ui.internal.details.java.JavaManyToOneMappingUiDefinition;
+import org.eclipse.jpt.ui.internal.details.java.JavaMappedSuperclassUiDefinition;
+import org.eclipse.jpt.ui.internal.details.java.JavaOneToManyMappingUiDefinition;
+import org.eclipse.jpt.ui.internal.details.java.JavaOneToOneMappingUiDefinition;
+import org.eclipse.jpt.ui.internal.details.java.JavaTransientMappingUiDefinition;
+import org.eclipse.jpt.ui.internal.details.java.JavaVersionMappingUiDefinition;
+import org.eclipse.jpt.ui.internal.details.java.NullJavaAttributeMappingUiDefinition;
+
+public class Generic2_0JavaResourceUiDefinition extends AbstractJavaResourceUiDefinition
+{
+	// singleton
+	private static final ResourceUiDefinition INSTANCE = new Generic2_0JavaResourceUiDefinition();
+
+	/**
+	 * Return the singleton.
+	 */
+	public static ResourceUiDefinition instance() {
+		return INSTANCE;
+	}
+	
+	
+	/**
+	 * zero-argument constructor
+	 */
+	protected Generic2_0JavaResourceUiDefinition() {
+		super();
+	}
+	
+	@Override
+	protected JavaUiFactory buildJavaUiFactory() {
+		return new Generic2_0JavaUiFactory();
+	}
+	
+	@Override
+	protected void addSpecifiedAttributeMappingUiDefinitionsTo(List<JavaAttributeMappingUiDefinition<? extends AttributeMapping>> definitions) {
+		definitions.add(JavaElementCollectionMapping2_0UiDefinition.instance());
+		definitions.add(JavaIdMappingUiDefinition.instance());
+		definitions.add(JavaEmbeddedIdMappingUDefinition.instance());
+		definitions.add(JavaBasicMappingUiDefinition.instance());
+		definitions.add(JavaVersionMappingUiDefinition.instance());
+		definitions.add(JavaManyToOneMappingUiDefinition.instance());
+		definitions.add(JavaOneToManyMappingUiDefinition.instance());
+		definitions.add(JavaOneToOneMappingUiDefinition.instance());
+		definitions.add(JavaManyToManyMappingUiDefinition.instance());
+		definitions.add(JavaEmbeddedMappingUiDefinition.instance());
+		definitions.add(JavaTransientMappingUiDefinition.instance());
+	}
+	
+	@Override
+	protected void addDefaultAttributeMappingUiDefinitionsTo(List<DefaultJavaAttributeMappingUiDefinition<?>> definitions) {
+		definitions.add(DefaultBasicMappingUiDefinition.instance());
+		definitions.add(DefaultEmbeddedMappingUiDefinition.instance());
+		definitions.add(NullJavaAttributeMappingUiDefinition.instance());
+	}
+	
+	@Override
+	protected void addSpecifiedTypeMappingUiDefinitionsTo(List<JavaTypeMappingUiDefinition<? extends TypeMapping>> definitions) {
+		definitions.add(JavaEntityUiDefinition.instance());
+		definitions.add(JavaMappedSuperclassUiDefinition.instance());
+		definitions.add(JavaEmbeddableUiDefinition.instance());
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/java/Generic2_0JavaUiFactory.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/java/Generic2_0JavaUiFactory.java
new file mode 100644
index 0000000..ebb6911
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/java/Generic2_0JavaUiFactory.java
@@ -0,0 +1,134 @@
+/*******************************************************************************
+ * Copyright (c) 2009 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.ui.internal.jpa2.details.java;
+
+import org.eclipse.jpt.core.context.java.JavaEmbeddable;
+import org.eclipse.jpt.core.context.java.JavaEmbeddedIdMapping;
+import org.eclipse.jpt.core.context.java.JavaEmbeddedMapping;
+import org.eclipse.jpt.core.context.java.JavaEntity;
+import org.eclipse.jpt.core.context.java.JavaIdMapping;
+import org.eclipse.jpt.core.context.java.JavaManyToManyMapping;
+import org.eclipse.jpt.core.context.java.JavaManyToOneMapping;
+import org.eclipse.jpt.core.context.java.JavaMappedSuperclass;
+import org.eclipse.jpt.core.context.java.JavaOneToManyMapping;
+import org.eclipse.jpt.core.context.java.JavaOneToOneMapping;
+import org.eclipse.jpt.core.jpa2.context.java.JavaElementCollectionMapping2_0;
+import org.eclipse.jpt.ui.WidgetFactory;
+import org.eclipse.jpt.ui.details.JpaComposite;
+import org.eclipse.jpt.ui.internal.details.java.BaseJavaUiFactory;
+import org.eclipse.jpt.ui.internal.jpa2.details.ElementCollectionMapping2_0Composite;
+import org.eclipse.jpt.ui.internal.jpa2.details.EmbeddedIdMapping2_0Composite;
+import org.eclipse.jpt.ui.internal.persistence.details.GenericPersistenceXmlUiFactory;
+import org.eclipse.jpt.ui.jpa2.details.java.JavaUiFactory2_0;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * The default implementation of the UI factory required to show the information
+ * related to a JPA mapping (type or attribute).
+ *
+ * @see GenericPersistenceXmlUiFactory
+ *
+ * @version 1.0
+ * @since 1.0
+ */
+public class Generic2_0JavaUiFactory
+	extends BaseJavaUiFactory
+	implements JavaUiFactory2_0
+{
+	// **************** java type mapping composites ***************************
+	
+	@Override
+	public JpaComposite createJavaMappedSuperclassComposite(
+			PropertyValueModel<JavaMappedSuperclass> subjectHolder,
+			Composite parent, WidgetFactory widgetFactory) {
+		return new JavaMappedSuperclass2_0Composite(subjectHolder, parent, widgetFactory);
+	}
+	
+	@Override
+	public JpaComposite createJavaEntityComposite(
+			PropertyValueModel<JavaEntity> subjectHolder,
+			Composite parent, WidgetFactory widgetFactory) {
+		return new JavaEntity2_0Composite(subjectHolder, parent, widgetFactory);
+	}
+	
+	@Override
+	public JpaComposite createJavaEmbeddableComposite(
+			PropertyValueModel<JavaEmbeddable> subjectHolder,
+			Composite parent, WidgetFactory widgetFactory) {
+		return new JavaEmbeddable2_0Composite(subjectHolder, parent, widgetFactory);
+	}
+	
+	
+	// **************** java attribute mapping composites **********************
+	
+	@Override
+	public JpaComposite createJavaIdMappingComposite(
+			PropertyValueModel<JavaIdMapping> subjectHolder,
+			Composite parent,
+			WidgetFactory widgetFactory) {
+		return new JavaIdMapping2_0Composite(subjectHolder, parent, widgetFactory);
+	}
+
+	@Override
+	public JpaComposite createJavaEmbeddedIdMappingComposite(
+			PropertyValueModel<JavaEmbeddedIdMapping> subjectHolder, 
+			Composite parent, 
+			WidgetFactory widgetFactory) {
+		return new EmbeddedIdMapping2_0Composite(subjectHolder, parent, widgetFactory);
+	}
+	
+	@Override
+	public JpaComposite createJavaEmbeddedMappingComposite(
+			PropertyValueModel<JavaEmbeddedMapping> subjectHolder,
+			Composite parent,
+			WidgetFactory widgetFactory) {
+		return new JavaEmbeddedMapping2_0Composite(subjectHolder, parent, widgetFactory);
+	}
+	
+	@Override
+	public JpaComposite createJavaManyToManyMappingComposite(
+			PropertyValueModel<JavaManyToManyMapping> subjectHolder, 
+			Composite parent, 
+			WidgetFactory widgetFactory) {
+		return new JavaManyToManyMapping2_0Composite(subjectHolder, parent, widgetFactory);
+	}
+	
+	@Override
+	public JpaComposite createJavaManyToOneMappingComposite(
+			PropertyValueModel<JavaManyToOneMapping> subjectHolder, 
+			Composite parent, 
+			WidgetFactory widgetFactory) {
+		return new JavaManyToOneMapping2_0Composite(subjectHolder, parent, widgetFactory);
+	}
+
+	@Override
+	public JpaComposite createJavaOneToManyMappingComposite(
+			PropertyValueModel<JavaOneToManyMapping> subjectHolder,
+			Composite parent,
+			WidgetFactory widgetFactory) {
+		return new JavaOneToManyMapping2_0Composite(subjectHolder, parent, widgetFactory);
+	}
+	
+	@Override
+	public JpaComposite createJavaOneToOneMappingComposite(
+			PropertyValueModel<JavaOneToOneMapping> subjectHolder, 
+			Composite parent, 
+			WidgetFactory widgetFactory) {
+		return new JavaOneToOneMapping2_0Composite(subjectHolder, parent, widgetFactory);
+	}
+	
+	public JpaComposite createJavaElementCollectionMapping2_0Composite(
+			PropertyValueModel<JavaElementCollectionMapping2_0> subjectHolder,
+			Composite parent,
+			WidgetFactory widgetFactory) {
+		return new ElementCollectionMapping2_0Composite(subjectHolder, parent, widgetFactory);
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/java/JavaElementCollectionMapping2_0UiDefinition.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/java/JavaElementCollectionMapping2_0UiDefinition.java
new file mode 100644
index 0000000..44129b8
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/java/JavaElementCollectionMapping2_0UiDefinition.java
@@ -0,0 +1,56 @@
+/*******************************************************************************
+ * Copyright (c) 2009 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.ui.internal.jpa2.details.java;
+
+import org.eclipse.jpt.core.context.PersistentAttribute;
+import org.eclipse.jpt.core.jpa2.context.java.JavaElementCollectionMapping2_0;
+import org.eclipse.jpt.ui.WidgetFactory;
+import org.eclipse.jpt.ui.details.JpaComposite;
+import org.eclipse.jpt.ui.details.java.JavaAttributeMappingUiDefinition;
+import org.eclipse.jpt.ui.details.java.JavaUiFactory;
+import org.eclipse.jpt.ui.internal.jpa2.details.AbstractElementCollectionMapping2_0UiDefinition;
+import org.eclipse.jpt.ui.jpa2.details.java.JavaUiFactory2_0;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+public class JavaElementCollectionMapping2_0UiDefinition
+	extends AbstractElementCollectionMapping2_0UiDefinition<PersistentAttribute, JavaElementCollectionMapping2_0>
+	implements JavaAttributeMappingUiDefinition<JavaElementCollectionMapping2_0>
+{
+	// singleton
+	private static final JavaElementCollectionMapping2_0UiDefinition INSTANCE = 
+			new JavaElementCollectionMapping2_0UiDefinition();
+	
+	
+	/**
+	 * Return the singleton.
+	 */
+	public static JavaAttributeMappingUiDefinition<JavaElementCollectionMapping2_0> instance() {
+		return INSTANCE;
+	}
+	
+	
+	/**
+	 * Ensure single instance.
+	 */
+	private JavaElementCollectionMapping2_0UiDefinition() {
+		super();
+	}
+	
+	
+	public JpaComposite buildAttributeMappingComposite(
+			JavaUiFactory factory,
+			PropertyValueModel<JavaElementCollectionMapping2_0> subjectHolder,
+			Composite parent,
+			WidgetFactory widgetFactory) {
+		
+		return ((JavaUiFactory2_0) factory).createJavaElementCollectionMapping2_0Composite(subjectHolder, parent, widgetFactory);
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/java/JavaEmbeddable2_0Composite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/java/JavaEmbeddable2_0Composite.java
new file mode 100644
index 0000000..36010bf
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/java/JavaEmbeddable2_0Composite.java
@@ -0,0 +1,69 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 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.ui.internal.jpa2.details.java;
+
+import org.eclipse.jpt.core.context.AccessHolder;
+import org.eclipse.jpt.core.context.java.JavaEmbeddable;
+import org.eclipse.jpt.ui.WidgetFactory;
+import org.eclipse.jpt.ui.details.JpaComposite;
+import org.eclipse.jpt.ui.internal.details.AbstractEmbeddableComposite;
+import org.eclipse.jpt.ui.internal.details.AccessTypeComposite;
+import org.eclipse.jpt.utility.internal.model.value.PropertyAspectAdapter;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * This pane does not have any widgets.
+ *
+ * @see Embeddable
+ * @see EmbeddableUiProvider
+ *
+ * @version 2.3
+ * @since 2.0
+ */
+public class JavaEmbeddable2_0Composite extends AbstractEmbeddableComposite<JavaEmbeddable>
+                                 implements JpaComposite
+{
+	/**
+	 * Creates a new <code>EmbeddableComposite</code>.
+	 *
+	 * @param subjectHolder The holder of this pane's subject
+	 * @param parent The parent container
+	 * @param widgetFactory The factory used to create various common widgets
+	 */
+	public JavaEmbeddable2_0Composite(PropertyValueModel<? extends JavaEmbeddable> subjectHolder,
+	                           Composite parent,
+	                           WidgetFactory widgetFactory) {
+
+		super(subjectHolder, parent, widgetFactory);
+	}
+
+	@Override
+	protected void initializeLayout(Composite container) {
+		this.initializeEmbeddableCollapsibleSection(container);
+	}
+
+	@Override
+	protected void initializeEmbeddableSection(Composite container) {
+		new AccessTypeComposite(this, buildAccessHolder(), container);	
+	}
+
+	protected PropertyValueModel<AccessHolder> buildAccessHolder() {
+		return new PropertyAspectAdapter<JavaEmbeddable, AccessHolder>(
+			getSubjectHolder())
+		{
+			@Override
+			protected AccessHolder buildValue_() {
+				return this.subject.getPersistentType();
+			}
+		};
+	}
+
+}
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/java/JavaEmbeddedMapping2_0Composite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/java/JavaEmbeddedMapping2_0Composite.java
new file mode 100644
index 0000000..3b8d28d
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/java/JavaEmbeddedMapping2_0Composite.java
@@ -0,0 +1,60 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 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.ui.internal.jpa2.details.java;
+
+import org.eclipse.jpt.core.context.java.JavaEmbeddedMapping;
+import org.eclipse.jpt.ui.WidgetFactory;
+import org.eclipse.jpt.ui.details.JpaComposite;
+import org.eclipse.jpt.ui.internal.details.AbstractEmbeddedMappingComposite;
+import org.eclipse.jpt.ui.internal.jpa2.details.EmbeddedMapping2_0OverridesComposite;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * Here the layout of this pane:
+ * <pre>
+ * -----------------------------------------------------------------------------
+ * | ------------------------------------------------------------------------- |
+ * | |                                                                       | |
+ * | | EmbeddedAttributeOverridesComposite                                   | |
+ * | |                                                                       | |
+ * | ------------------------------------------------------------------------- |
+ * -----------------------------------------------------------------------------</pre>
+ *
+ * @see EmbeddedMapping
+ *
+ * @version 2.3
+ * @since 1.0
+ */
+public class JavaEmbeddedMapping2_0Composite extends AbstractEmbeddedMappingComposite<JavaEmbeddedMapping>
+                                      implements JpaComposite
+{
+	/**
+	 * Creates a new <code>EmbeddedMappingComposite</code>.
+	 *
+	 * @param subjectHolder The holder of the subject <code>EmbeddedMapping</code>
+	 * @param parent The parent container
+	 * @param widgetFactory The factory used to create various common widgets
+	 */
+	public JavaEmbeddedMapping2_0Composite(PropertyValueModel<? extends JavaEmbeddedMapping> subjectHolder,
+	                                Composite parent,
+	                                WidgetFactory widgetFactory) {
+
+		super(subjectHolder, parent, widgetFactory);
+	}
+	
+	@Override
+	protected void initializeEmbeddedSection(Composite container) {
+		new EmbeddedMapping2_0OverridesComposite(
+			this,
+			container
+		);
+	}
+}
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/java/JavaEntity2_0Composite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/java/JavaEntity2_0Composite.java
new file mode 100644
index 0000000..43d711f
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/java/JavaEntity2_0Composite.java
@@ -0,0 +1,105 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2010 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.ui.internal.jpa2.details.java;
+
+import org.eclipse.jpt.core.context.AccessHolder;
+import org.eclipse.jpt.core.context.QueryContainer;
+import org.eclipse.jpt.core.context.java.JavaEntity;
+import org.eclipse.jpt.core.jpa2.context.Cacheable2_0;
+import org.eclipse.jpt.core.jpa2.context.CacheableHolder2_0;
+import org.eclipse.jpt.ui.WidgetFactory;
+import org.eclipse.jpt.ui.internal.details.AbstractEntityComposite;
+import org.eclipse.jpt.ui.internal.details.AccessTypeComposite;
+import org.eclipse.jpt.ui.internal.details.EntityNameComposite;
+import org.eclipse.jpt.ui.internal.details.IdClassComposite;
+import org.eclipse.jpt.ui.internal.details.TableComposite;
+import org.eclipse.jpt.ui.internal.details.java.JavaInheritanceComposite;
+import org.eclipse.jpt.ui.internal.details.java.JavaSecondaryTablesComposite;
+import org.eclipse.jpt.ui.internal.jpa2.details.Cacheable2_0Pane;
+import org.eclipse.jpt.ui.internal.jpa2.details.Entity2_0OverridesComposite;
+import org.eclipse.jpt.ui.internal.jpa2.details.Queries2_0Composite;
+import org.eclipse.jpt.utility.internal.model.value.PropertyAspectAdapter;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * The pane used for a Java entity.
+ *
+ * @see JavaEntity
+ * @see JavaSecondaryTablesComposite
+ *
+ * @version 2.3
+ * @since 1.0
+ */
+public class JavaEntity2_0Composite
+	extends AbstractEntityComposite<JavaEntity>
+{
+	/**
+	 * Creates a new <code>JavaEntityComposite</code>.
+	 *
+	 * @param subjectHolder The holder of the subject <code>JavaEntity</code>
+	 * @param parent The parent container
+	 * @param widgetFactory The factory used to create various common widgets
+	 */
+	public JavaEntity2_0Composite(
+			PropertyValueModel<? extends JavaEntity> subjectHolder,
+			Composite parent,
+			WidgetFactory widgetFactory) {
+		
+		super(subjectHolder, parent, widgetFactory);
+	}
+	
+	@Override
+	protected void initializeEntitySection(Composite container) {
+		new TableComposite(this, container);
+		new EntityNameComposite(this, container);
+		new AccessTypeComposite(this, buildAccessHolder(), container);	
+		new IdClassComposite(this, buildIdClassReferenceHolder(), container);
+		new Cacheable2_0Pane(this, buildCacheableHolder(), container);
+	}
+	
+	protected PropertyValueModel<AccessHolder> buildAccessHolder() {
+		return new PropertyAspectAdapter<JavaEntity, AccessHolder>(getSubjectHolder()) {
+			@Override
+			protected AccessHolder buildValue_() {
+				return this.subject.getPersistentType();
+			}
+		};
+	}
+	
+	protected PropertyValueModel<Cacheable2_0> buildCacheableHolder() {
+		return new PropertyAspectAdapter<JavaEntity, Cacheable2_0>(getSubjectHolder()) {
+			@Override
+			protected Cacheable2_0 buildValue_() {
+				return ((CacheableHolder2_0) this.subject).getCacheable();
+			}
+		};
+	}
+
+	@Override
+	protected void initializeSecondaryTablesSection(Composite container) {
+		new JavaSecondaryTablesComposite(this, container);
+	}
+
+	@Override
+	protected void initializeInheritanceSection(Composite container) {
+		new JavaInheritanceComposite(this, container);
+	}
+
+	@Override
+	protected void initializeAttributeOverridesSection(Composite container) {
+		new Entity2_0OverridesComposite(this, container);
+	}
+
+	@Override
+	protected void initializeQueriesSection(Composite container, PropertyValueModel<QueryContainer> queryContainerHolder) {
+		new Queries2_0Composite(this, queryContainerHolder, container);
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/java/JavaIdMapping2_0Composite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/java/JavaIdMapping2_0Composite.java
new file mode 100644
index 0000000..47c5d41
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/java/JavaIdMapping2_0Composite.java
@@ -0,0 +1,43 @@
+/*******************************************************************************
+* Copyright (c) 2009, 2010 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.ui.internal.jpa2.details.java;
+
+import org.eclipse.jpt.core.context.IdMapping;
+import org.eclipse.jpt.ui.WidgetFactory;
+import org.eclipse.jpt.ui.internal.details.AbstractIdMappingComposite;
+import org.eclipse.jpt.ui.internal.details.ColumnComposite;
+import org.eclipse.jpt.ui.internal.jpa2.details.IdMapping2_0MappedByRelationshipPane;
+import org.eclipse.jpt.ui.internal.jpa2.details.IdMappingGeneration2_0Composite;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+public class JavaIdMapping2_0Composite
+	extends AbstractIdMappingComposite<IdMapping>
+{
+	public JavaIdMapping2_0Composite(
+			PropertyValueModel<? extends IdMapping> subjectHolder,
+			Composite parent,
+			WidgetFactory widgetFactory) {
+		
+		super(subjectHolder, parent, widgetFactory);
+	}
+	
+	
+	@Override
+	protected void initializeIdSection(Composite container) {
+		new IdMapping2_0MappedByRelationshipPane(this, getSubjectHolder(), container);
+		new ColumnComposite(this, buildColumnHolder(), container);
+	}
+	
+	@Override
+	protected void initializeGenerationCollapsibleSection(Composite container) {
+		new IdMappingGeneration2_0Composite(this, container);
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/java/JavaManyToManyMapping2_0Composite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/java/JavaManyToManyMapping2_0Composite.java
new file mode 100644
index 0000000..89e5824
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/java/JavaManyToManyMapping2_0Composite.java
@@ -0,0 +1,46 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2010 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.ui.internal.jpa2.details.java;
+
+import org.eclipse.jpt.core.context.java.JavaManyToManyMapping;
+import org.eclipse.jpt.core.context.java.JavaManyToManyRelationshipReference;
+import org.eclipse.jpt.ui.WidgetFactory;
+import org.eclipse.jpt.ui.internal.details.AbstractManyToManyMappingComposite;
+import org.eclipse.jpt.ui.internal.details.FetchTypeComposite;
+import org.eclipse.jpt.ui.internal.details.TargetEntityComposite;
+import org.eclipse.jpt.ui.internal.jpa2.details.CascadePane2_0;
+import org.eclipse.jpt.ui.internal.jpa2.details.Ordering2_0Composite;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+public class JavaManyToManyMapping2_0Composite
+	extends AbstractManyToManyMappingComposite<JavaManyToManyMapping, JavaManyToManyRelationshipReference>
+{
+	public JavaManyToManyMapping2_0Composite(
+			PropertyValueModel<? extends JavaManyToManyMapping> subjectHolder,
+	        Composite parent,
+	        WidgetFactory widgetFactory) {
+		
+		super(subjectHolder, parent, widgetFactory);
+	}
+	
+	
+	@Override
+	protected void initializeManyToManySection(Composite container) {
+		new TargetEntityComposite(this, container);
+		new FetchTypeComposite(this, container);
+		new CascadePane2_0(this, buildCascadeHolder(), addSubPane(container, 5));
+	}
+	
+	@Override
+	protected void initializeOrderingCollapsibleSection(Composite container) {
+		new Ordering2_0Composite(this, container);
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/java/JavaManyToOneMapping2_0Composite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/java/JavaManyToOneMapping2_0Composite.java
new file mode 100644
index 0000000..34f7c0e
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/java/JavaManyToOneMapping2_0Composite.java
@@ -0,0 +1,43 @@
+/*******************************************************************************
+ *  Copyright (c) 2009, 2010  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.ui.internal.jpa2.details.java;
+
+import org.eclipse.jpt.core.context.java.JavaManyToOneMapping;
+import org.eclipse.jpt.core.jpa2.context.java.JavaManyToOneRelationshipReference2_0;
+import org.eclipse.jpt.ui.WidgetFactory;
+import org.eclipse.jpt.ui.internal.details.FetchTypeComposite;
+import org.eclipse.jpt.ui.internal.details.OptionalComposite;
+import org.eclipse.jpt.ui.internal.details.TargetEntityComposite;
+import org.eclipse.jpt.ui.internal.jpa2.details.AbstractManyToOneMapping2_0Composite;
+import org.eclipse.jpt.ui.internal.jpa2.details.CascadePane2_0;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+public class JavaManyToOneMapping2_0Composite
+	extends AbstractManyToOneMapping2_0Composite<JavaManyToOneMapping, JavaManyToOneRelationshipReference2_0>
+{
+	public JavaManyToOneMapping2_0Composite(
+			PropertyValueModel<? extends JavaManyToOneMapping> subjectHolder,
+			Composite parent,
+	        WidgetFactory widgetFactory) {
+		
+		super(subjectHolder, parent, widgetFactory);
+	}
+	
+	
+	@Override
+	protected void initializeManyToOneSection(Composite container) {
+		new TargetEntityComposite(this, container);
+		new FetchTypeComposite(this, container);
+		new OptionalComposite(this, container);
+		new CascadePane2_0(this, buildCascadeHolder(),  addSubPane(container, 5));
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/java/JavaManyToOneMapping2_0Pane.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/java/JavaManyToOneMapping2_0Pane.java
new file mode 100644
index 0000000..04170cc
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/java/JavaManyToOneMapping2_0Pane.java
@@ -0,0 +1,14 @@
+/*******************************************************************************
+ *  Copyright (c) 2010  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.ui.internal.jpa2.details.java;
+
+public class JavaManyToOneMapping2_0Pane
+{}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/java/JavaMappedSuperclass2_0Composite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/java/JavaMappedSuperclass2_0Composite.java
new file mode 100644
index 0000000..638268d
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/java/JavaMappedSuperclass2_0Composite.java
@@ -0,0 +1,74 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2010 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.ui.internal.jpa2.details.java;
+
+import org.eclipse.jpt.core.context.AccessHolder;
+import org.eclipse.jpt.core.context.MappedSuperclass;
+import org.eclipse.jpt.core.context.java.JavaMappedSuperclass;
+import org.eclipse.jpt.ui.WidgetFactory;
+import org.eclipse.jpt.ui.details.JpaComposite;
+import org.eclipse.jpt.ui.internal.details.AbstractMappedSuperclassComposite;
+import org.eclipse.jpt.ui.internal.details.AccessTypeComposite;
+import org.eclipse.jpt.ui.internal.details.IdClassComposite;
+import org.eclipse.jpt.ui.internal.details.java.BaseJavaUiFactory;
+import org.eclipse.jpt.utility.internal.model.value.PropertyAspectAdapter;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * Here the layout of this pane:
+ * <pre>
+ * -----------------------------------------------------------------------------
+ * |                                                                           |
+ * | IdClassComposite                                                          |
+ * |                                                                           |
+ * -----------------------------------------------------------------------------</pre>
+ *
+ * @see MappedSuperclass
+ * @see BaseJavaUiFactory - The factory creating this pane
+ * @see IdClassComposite
+ *
+ * @version 2.3
+ * @since 2.0
+ */
+public class JavaMappedSuperclass2_0Composite
+	extends AbstractMappedSuperclassComposite<JavaMappedSuperclass>
+    implements JpaComposite
+{
+	/**
+	 * Creates a new <code>MappedSuperclassComposite</code>.
+	 *
+	 * @param subjectHolder The holder of this pane's subject
+	 * @param parent The parent container
+	 * @param widgetFactory The factory used to create various common widgets
+	 */
+	public JavaMappedSuperclass2_0Composite(
+			PropertyValueModel<? extends JavaMappedSuperclass> subjectHolder,
+			Composite parent,
+			WidgetFactory widgetFactory) {
+		
+		super(subjectHolder, parent, widgetFactory);
+	}
+	
+	@Override
+	protected void initializeMappedSuperclassSection(Composite container) {
+		new AccessTypeComposite(this, buildAccessHolder(), container);	
+		new IdClassComposite(this, buildIdClassReferenceHolder(), container);
+	}
+	
+	protected PropertyValueModel<AccessHolder> buildAccessHolder() {
+		return new PropertyAspectAdapter<JavaMappedSuperclass, AccessHolder>(getSubjectHolder()) {
+			@Override
+			protected AccessHolder buildValue_() {
+				return this.subject.getPersistentType();
+			}
+		};
+	}
+}
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/java/JavaOneToManyMapping2_0Composite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/java/JavaOneToManyMapping2_0Composite.java
new file mode 100644
index 0000000..a783b61
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/java/JavaOneToManyMapping2_0Composite.java
@@ -0,0 +1,66 @@
+/*******************************************************************************
+* Copyright (c) 2009, 2010 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.ui.internal.jpa2.details.java;
+
+import org.eclipse.jpt.core.context.java.JavaOneToManyMapping;
+import org.eclipse.jpt.core.jpa2.context.OrphanRemovable2_0;
+import org.eclipse.jpt.core.jpa2.context.OrphanRemovalHolder2_0;
+import org.eclipse.jpt.core.jpa2.context.java.JavaOneToManyRelationshipReference2_0;
+import org.eclipse.jpt.ui.WidgetFactory;
+import org.eclipse.jpt.ui.internal.details.AbstractOneToManyMappingComposite;
+import org.eclipse.jpt.ui.internal.details.FetchTypeComposite;
+import org.eclipse.jpt.ui.internal.details.TargetEntityComposite;
+import org.eclipse.jpt.ui.internal.jpa2.details.CascadePane2_0;
+import org.eclipse.jpt.ui.internal.jpa2.details.OneToManyJoiningStrategy2_0Pane;
+import org.eclipse.jpt.ui.internal.jpa2.details.Ordering2_0Composite;
+import org.eclipse.jpt.ui.internal.jpa2.details.OrphanRemoval2_0Composite;
+import org.eclipse.jpt.utility.internal.model.value.PropertyAspectAdapter;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+public class JavaOneToManyMapping2_0Composite
+	extends AbstractOneToManyMappingComposite<JavaOneToManyMapping, JavaOneToManyRelationshipReference2_0>
+{
+	public JavaOneToManyMapping2_0Composite(
+			PropertyValueModel<? extends JavaOneToManyMapping> subjectHolder,
+	        Composite parent,
+	        WidgetFactory widgetFactory) {
+		
+		super(subjectHolder, parent, widgetFactory);
+	}
+	
+	
+	@Override
+	protected void initializeOneToManySection(Composite container) {
+		new TargetEntityComposite(this, container);
+		new FetchTypeComposite(this, container);
+		new OrphanRemoval2_0Composite(this, this.buildOrphanRemovableHolder(), container);
+		new CascadePane2_0(this, this.buildCascadeHolder(), this.addSubPane(container, 5));
+	}
+	
+	@Override
+	protected void initializeJoiningStrategyCollapsibleSection(Composite container) {
+		new OneToManyJoiningStrategy2_0Pane(this, this.buildJoiningHolder(), container);
+	}
+
+	@Override
+	protected void initializeOrderingCollapsibleSection(Composite container) {
+		new Ordering2_0Composite(this, container);
+	}
+
+	protected PropertyValueModel<OrphanRemovable2_0> buildOrphanRemovableHolder() {
+		return new PropertyAspectAdapter<JavaOneToManyMapping, OrphanRemovable2_0>(this.getSubjectHolder()) {
+			@Override
+			protected OrphanRemovable2_0 buildValue_() {
+				return ((OrphanRemovalHolder2_0) this.subject).getOrphanRemoval();
+			}
+		};
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/java/JavaOneToOneMapping2_0Composite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/java/JavaOneToOneMapping2_0Composite.java
new file mode 100644
index 0000000..91c7628
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/java/JavaOneToOneMapping2_0Composite.java
@@ -0,0 +1,63 @@
+/*******************************************************************************
+ *  Copyright (c) 2009, 2010  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.ui.internal.jpa2.details.java;
+
+import org.eclipse.jpt.core.context.java.JavaOneToOneMapping;
+import org.eclipse.jpt.core.jpa2.context.OrphanRemovable2_0;
+import org.eclipse.jpt.core.jpa2.context.OrphanRemovalHolder2_0;
+import org.eclipse.jpt.core.jpa2.context.java.JavaOneToOneRelationshipReference2_0;
+import org.eclipse.jpt.ui.WidgetFactory;
+import org.eclipse.jpt.ui.internal.details.FetchTypeComposite;
+import org.eclipse.jpt.ui.internal.details.OptionalComposite;
+import org.eclipse.jpt.ui.internal.details.TargetEntityComposite;
+import org.eclipse.jpt.ui.internal.jpa2.details.AbstractOneToOneMapping2_0Composite;
+import org.eclipse.jpt.ui.internal.jpa2.details.CascadePane2_0;
+import org.eclipse.jpt.ui.internal.jpa2.details.OneToOneJoiningStrategy2_0Pane;
+import org.eclipse.jpt.ui.internal.jpa2.details.OrphanRemoval2_0Composite;
+import org.eclipse.jpt.utility.internal.model.value.PropertyAspectAdapter;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+public class JavaOneToOneMapping2_0Composite
+	extends AbstractOneToOneMapping2_0Composite<JavaOneToOneMapping, JavaOneToOneRelationshipReference2_0>
+{
+	public JavaOneToOneMapping2_0Composite(
+			PropertyValueModel<? extends JavaOneToOneMapping> subjectHolder,
+			Composite parent,
+			WidgetFactory widgetFactory) {
+		
+		super(subjectHolder, parent, widgetFactory);
+	}
+	
+	
+	@Override
+	protected void initializeOneToOneSection(Composite container) {
+		new TargetEntityComposite(this, container);
+		new FetchTypeComposite(this, container);
+		new OptionalComposite(this, container);
+		new OrphanRemoval2_0Composite(this, buildOrphanRemovableHolder(), container);
+		new CascadePane2_0(this, buildCascadeHolder(),  addSubPane(container, 5));
+	}
+	
+	@Override
+	protected void initializeJoiningStrategyCollapsibleSection(Composite container) {
+		new OneToOneJoiningStrategy2_0Pane(this, buildJoiningHolder(), container);
+	}
+	
+	protected PropertyValueModel<OrphanRemovable2_0> buildOrphanRemovableHolder() {
+		return new PropertyAspectAdapter<JavaOneToOneMapping, OrphanRemovable2_0>(getSubjectHolder()) {
+			@Override
+			protected OrphanRemovable2_0 buildValue_() {
+				return ((OrphanRemovalHolder2_0) this.subject).getOrphanRemoval();
+			}
+		};
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/orm/EntityMappings2_0DetailsPage.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/orm/EntityMappings2_0DetailsPage.java
new file mode 100644
index 0000000..c22ef74
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/orm/EntityMappings2_0DetailsPage.java
@@ -0,0 +1,43 @@
+/*******************************************************************************
+* Copyright (c) 2009, 2010 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.ui.internal.jpa2.details.orm;
+
+import org.eclipse.jpt.ui.WidgetFactory;
+import org.eclipse.jpt.ui.internal.details.orm.AbstractEntityMappingsDetailsPage;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ *  EntityMappings2_0DetailsPage
+ */
+public class EntityMappings2_0DetailsPage extends AbstractEntityMappingsDetailsPage
+{
+	/**
+	 * Creates a new <code>EntityMappings2_0DetailsPage</code>.
+	 *
+	 * @param parent The parent container
+	 * @param widgetFactory The factory used to create various common widgets
+	 */
+	public EntityMappings2_0DetailsPage(Composite parent,
+	                                 WidgetFactory widgetFactory) {
+
+		super(parent, widgetFactory);
+	}
+
+	@Override
+	protected void initializeGeneratorsCollapsibleSection(Composite container) {
+		new EntityMappingsGenerators2_0Composite(this, container);
+	}
+
+	@Override
+	protected void initializeQueriesCollapsibleSection(Composite container) {
+		new OrmQueries2_0Composite(this, container);
+	}
+
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/orm/EntityMappings2_0DetailsProvider.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/orm/EntityMappings2_0DetailsProvider.java
new file mode 100644
index 0000000..89b9d0b
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/orm/EntityMappings2_0DetailsProvider.java
@@ -0,0 +1,58 @@
+/*******************************************************************************
+* Copyright (c) 2009 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.ui.internal.jpa2.details.orm;
+
+import org.eclipse.jpt.core.JpaResourceType;
+import org.eclipse.jpt.core.JptCorePlugin;
+import org.eclipse.jpt.core.context.orm.EntityMappings;
+import org.eclipse.jpt.ui.WidgetFactory;
+import org.eclipse.jpt.ui.details.JpaDetailsPage;
+import org.eclipse.jpt.ui.details.JpaDetailsProvider;
+import org.eclipse.jpt.ui.internal.details.AbstractEntityMappingsDetailsProvider;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ *  EntityMappings2_0DetailsProvider
+ */
+public class EntityMappings2_0DetailsProvider
+	extends AbstractEntityMappingsDetailsProvider
+{
+	// singleton
+	private static final JpaDetailsProvider INSTANCE = new EntityMappings2_0DetailsProvider();
+	
+	
+	/**
+	 * Return the singleton
+	 */
+	public static JpaDetailsProvider instance() {
+		return INSTANCE;
+	}
+	
+	
+	/**
+	 * Enforce singleton usage
+	 */
+	private EntityMappings2_0DetailsProvider() {
+		super();
+	}
+	
+	
+	@Override
+	protected boolean providesDetails(JpaResourceType resourceType) {
+		return resourceType.equals(JptCorePlugin.ORM_XML_2_0_RESOURCE_TYPE);
+	}
+	
+	public JpaDetailsPage<EntityMappings> buildDetailsPage(
+			Composite parent,
+			WidgetFactory widgetFactory) {
+		
+		return new EntityMappings2_0DetailsPage(parent, widgetFactory);
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/orm/EntityMappingsGenerators2_0Composite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/orm/EntityMappingsGenerators2_0Composite.java
new file mode 100644
index 0000000..ecf89b6
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/orm/EntityMappingsGenerators2_0Composite.java
@@ -0,0 +1,53 @@
+/*******************************************************************************
+* Copyright (c) 2009 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.ui.internal.jpa2.details.orm;
+
+import org.eclipse.jpt.core.context.SequenceGenerator;
+import org.eclipse.jpt.core.context.orm.EntityMappings;
+import org.eclipse.jpt.ui.internal.details.GeneratorComposite;
+import org.eclipse.jpt.ui.internal.details.GeneratorComposite.GeneratorBuilder;
+import org.eclipse.jpt.ui.internal.details.orm.EntityMappingsGeneratorsComposite;
+import org.eclipse.jpt.ui.internal.jpa2.details.SequenceGenerator2_0Composite;
+import org.eclipse.jpt.ui.internal.widgets.Pane;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ *  EntityMappingsGenerators2_0Composite
+ */
+public class EntityMappingsGenerators2_0Composite extends EntityMappingsGeneratorsComposite
+{
+	/**
+	 * Creates a new <code>EntityMappingsGenerators2_0Composite</code>.
+	 *
+	 * @param parentPane The parent container of this one
+	 * @param parent The parent container
+	 */
+	public EntityMappingsGenerators2_0Composite(
+						Pane<? extends EntityMappings> parentPane,
+						Composite parent) {
+	
+		super(parentPane, parent);
+	}
+
+	@Override
+	protected GeneratorComposite<SequenceGenerator> buildSequenceGeneratorComposite(
+			Composite parent,
+			PropertyValueModel<SequenceGenerator> sequenceGeneratorHolder,
+			GeneratorBuilder<SequenceGenerator> generatorBuilder) {
+
+		return new SequenceGenerator2_0Composite(
+			this,
+			sequenceGeneratorHolder,
+			parent,
+			generatorBuilder
+		);
+	}
+}
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/orm/OrmBasicMapping2_0Composite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/orm/OrmBasicMapping2_0Composite.java
new file mode 100644
index 0000000..36a731a
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/orm/OrmBasicMapping2_0Composite.java
@@ -0,0 +1,58 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2010 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.ui.internal.jpa2.details.orm;
+
+import org.eclipse.jpt.core.context.AccessHolder;
+import org.eclipse.jpt.core.context.orm.OrmBasicMapping;
+import org.eclipse.jpt.ui.WidgetFactory;
+import org.eclipse.jpt.ui.internal.details.AbstractBasicMappingComposite;
+import org.eclipse.jpt.ui.internal.details.AccessTypeComposite;
+import org.eclipse.jpt.ui.internal.details.ColumnComposite;
+import org.eclipse.jpt.ui.internal.details.FetchTypeComposite;
+import org.eclipse.jpt.ui.internal.details.OptionalComposite;
+import org.eclipse.jpt.ui.internal.details.orm.OrmMappingNameChooser;
+import org.eclipse.jpt.utility.internal.model.value.PropertyAspectAdapter;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+public class OrmBasicMapping2_0Composite extends AbstractBasicMappingComposite<OrmBasicMapping>
+{
+	/**
+	 * Creates a new <code>EclipseLink1_1OrmBasicMappingComposite</code>.
+	 *
+	 * @param subjectHolder The holder of the subject <code>BasicMapping</code>
+	 * @param parent The parent container
+	 * @param widgetFactory The factory used to create various common widgets
+	 */
+	public OrmBasicMapping2_0Composite(PropertyValueModel<? extends OrmBasicMapping> subjectHolder,
+	                               Composite parent,
+	                               WidgetFactory widgetFactory) {
+
+		super(subjectHolder, parent, widgetFactory);
+	}
+
+	@Override
+	protected void initializeBasicSection(Composite container) {
+		new ColumnComposite(this, buildColumnHolder(), container);
+		new OrmMappingNameChooser(this, getSubjectHolder(), container);
+		new AccessTypeComposite(this, buildAccessHolderHolder(), container);
+		new FetchTypeComposite(this, container);
+		new OptionalComposite(this, addSubPane(container, 4));
+	}
+	
+	protected PropertyValueModel<AccessHolder> buildAccessHolderHolder() {
+		return new PropertyAspectAdapter<OrmBasicMapping, AccessHolder>(getSubjectHolder()) {
+			@Override
+			protected AccessHolder buildValue_() {
+				return this.subject.getPersistentAttribute();
+			}
+		};
+	}
+}
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/orm/OrmElementCollectionMapping2_0Composite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/orm/OrmElementCollectionMapping2_0Composite.java
new file mode 100644
index 0000000..7aec834
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/orm/OrmElementCollectionMapping2_0Composite.java
@@ -0,0 +1,58 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2010 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.ui.internal.jpa2.details.orm;
+
+import org.eclipse.jpt.core.context.AccessHolder;
+import org.eclipse.jpt.core.jpa2.context.orm.OrmElementCollectionMapping2_0;
+import org.eclipse.jpt.ui.WidgetFactory;
+import org.eclipse.jpt.ui.internal.details.AccessTypeComposite;
+import org.eclipse.jpt.ui.internal.details.FetchTypeComposite;
+import org.eclipse.jpt.ui.internal.details.orm.OrmMappingNameChooser;
+import org.eclipse.jpt.ui.internal.jpa2.details.AbstractElementCollectionMapping2_0Composite;
+import org.eclipse.jpt.ui.internal.jpa2.details.CollectionTable2_0Composite;
+import org.eclipse.jpt.ui.internal.jpa2.details.TargetClassComposite;
+import org.eclipse.jpt.utility.internal.model.value.PropertyAspectAdapter;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+public class OrmElementCollectionMapping2_0Composite extends AbstractElementCollectionMapping2_0Composite<OrmElementCollectionMapping2_0>
+{
+	/**
+	 * Creates a new <code>EclipseLink1_1OrmBasicMappingComposite</code>.
+	 *
+	 * @param subjectHolder The holder of the subject <code>BasicMapping</code>
+	 * @param parent The parent container
+	 * @param widgetFactory The factory used to create various common widgets
+	 */
+	public OrmElementCollectionMapping2_0Composite(PropertyValueModel<? extends OrmElementCollectionMapping2_0> subjectHolder,
+	                               Composite parent,
+	                               WidgetFactory widgetFactory) {
+
+		super(subjectHolder, parent, widgetFactory);
+	}
+
+	@Override
+	protected void initializeElementCollectionSection(Composite container) {
+		new TargetClassComposite(this, container);
+		new OrmMappingNameChooser(this, getSubjectHolder(), container);
+		new AccessTypeComposite(this, buildAccessHolderHolder(), container);
+		new FetchTypeComposite(this, container);
+		new CollectionTable2_0Composite(this, buildCollectionTableHolder(), container);
+	}
+	
+	protected PropertyValueModel<AccessHolder> buildAccessHolderHolder() {
+		return new PropertyAspectAdapter<OrmElementCollectionMapping2_0, AccessHolder>(getSubjectHolder()) {
+			@Override
+			protected AccessHolder buildValue_() {
+				return this.subject.getPersistentAttribute();
+			}
+		};
+	}
+}
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/orm/OrmElementCollectionMapping2_0UiDefinition.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/orm/OrmElementCollectionMapping2_0UiDefinition.java
new file mode 100644
index 0000000..e98a853
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/orm/OrmElementCollectionMapping2_0UiDefinition.java
@@ -0,0 +1,56 @@
+/*******************************************************************************
+ *  Copyright (c) 2009  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.ui.internal.jpa2.details.orm;
+
+import org.eclipse.jpt.core.context.PersistentAttribute;
+import org.eclipse.jpt.core.jpa2.context.orm.OrmElementCollectionMapping2_0;
+import org.eclipse.jpt.ui.WidgetFactory;
+import org.eclipse.jpt.ui.details.JpaComposite;
+import org.eclipse.jpt.ui.details.orm.OrmAttributeMappingUiDefinition;
+import org.eclipse.jpt.ui.details.orm.OrmXmlUiFactory;
+import org.eclipse.jpt.ui.internal.jpa2.details.AbstractElementCollectionMapping2_0UiDefinition;
+import org.eclipse.jpt.ui.jpa2.details.orm.OrmXmlUiFactory2_0;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+public class OrmElementCollectionMapping2_0UiDefinition
+	extends AbstractElementCollectionMapping2_0UiDefinition<PersistentAttribute, OrmElementCollectionMapping2_0>
+	implements OrmAttributeMappingUiDefinition<OrmElementCollectionMapping2_0>
+{
+	// singleton
+	private static final OrmElementCollectionMapping2_0UiDefinition INSTANCE = 
+		new OrmElementCollectionMapping2_0UiDefinition();
+	
+	
+	/**
+	 * Return the singleton.
+	 */
+	public static OrmAttributeMappingUiDefinition<OrmElementCollectionMapping2_0> instance() {
+		return INSTANCE;
+	}
+	
+	
+	/**
+	 * Ensure single instance.
+	 */
+	private OrmElementCollectionMapping2_0UiDefinition() {
+		super();
+	}
+	
+	public JpaComposite buildAttributeMappingComposite(
+			OrmXmlUiFactory factory, 
+			PropertyValueModel<OrmElementCollectionMapping2_0> subjectHolder, 
+			Composite parent, 
+			WidgetFactory widgetFactory) {
+		
+		return ((OrmXmlUiFactory2_0) factory).createOrmElementCollectionMapping2_0Composite(subjectHolder, parent, widgetFactory);
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/orm/OrmEmbeddedIdMapping2_0Composite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/orm/OrmEmbeddedIdMapping2_0Composite.java
new file mode 100644
index 0000000..69046d3
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/orm/OrmEmbeddedIdMapping2_0Composite.java
@@ -0,0 +1,55 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2010 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.ui.internal.jpa2.details.orm;
+
+import org.eclipse.jpt.core.context.AccessHolder;
+import org.eclipse.jpt.core.context.orm.OrmEmbeddedIdMapping;
+import org.eclipse.jpt.ui.WidgetFactory;
+import org.eclipse.jpt.ui.details.JpaComposite;
+import org.eclipse.jpt.ui.internal.details.AbstractEmbeddedIdMappingComposite;
+import org.eclipse.jpt.ui.internal.details.AccessTypeComposite;
+import org.eclipse.jpt.ui.internal.details.EmbeddedMappingOverridesComposite;
+import org.eclipse.jpt.ui.internal.details.orm.OrmMappingNameChooser;
+import org.eclipse.jpt.ui.internal.jpa2.details.EmbeddedIdMapping2_0MappedByRelationshipPane;
+import org.eclipse.jpt.utility.internal.model.value.PropertyAspectAdapter;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+public class OrmEmbeddedIdMapping2_0Composite
+	extends AbstractEmbeddedIdMappingComposite<OrmEmbeddedIdMapping>
+	implements JpaComposite
+{
+	public OrmEmbeddedIdMapping2_0Composite(
+			PropertyValueModel<? extends OrmEmbeddedIdMapping> subjectHolder,
+			Composite parent,
+			WidgetFactory widgetFactory) {
+		
+		super(subjectHolder, parent, widgetFactory);
+	}
+	
+	
+	@Override
+	protected void initializeEmbeddedIdSection(Composite container) {
+		new OrmMappingNameChooser(this, getSubjectHolder(), container);
+		new AccessTypeComposite(this, buildAccessHolderHolder(), container);
+		
+		new EmbeddedIdMapping2_0MappedByRelationshipPane(this, getSubjectHolder(), container);
+		new EmbeddedMappingOverridesComposite(this, container);
+	}	
+	
+	protected PropertyValueModel<AccessHolder> buildAccessHolderHolder() {
+		return new PropertyAspectAdapter<OrmEmbeddedIdMapping, AccessHolder>(getSubjectHolder()) {
+			@Override
+			protected AccessHolder buildValue_() {
+				return this.subject.getPersistentAttribute();
+			}
+		};
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/orm/OrmEmbeddedMapping2_0Composite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/orm/OrmEmbeddedMapping2_0Composite.java
new file mode 100644
index 0000000..1dbb88b
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/orm/OrmEmbeddedMapping2_0Composite.java
@@ -0,0 +1,77 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2010 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.ui.internal.jpa2.details.orm;
+
+import org.eclipse.jpt.core.context.AccessHolder;
+import org.eclipse.jpt.core.context.orm.OrmEmbeddedMapping;
+import org.eclipse.jpt.ui.WidgetFactory;
+import org.eclipse.jpt.ui.details.JpaComposite;
+import org.eclipse.jpt.ui.internal.details.AbstractEmbeddedMappingComposite;
+import org.eclipse.jpt.ui.internal.details.AccessTypeComposite;
+import org.eclipse.jpt.ui.internal.details.orm.OrmMappingNameChooser;
+import org.eclipse.jpt.ui.internal.jpa2.details.EmbeddedMapping2_0OverridesComposite;
+import org.eclipse.jpt.utility.internal.model.value.PropertyAspectAdapter;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * Here the layout of this pane:
+ * <pre>
+ * -----------------------------------------------------------------------------
+ * | ------------------------------------------------------------------------- |
+ * | |                                                                       | |
+ * | | EmbeddedAttributeOverridesComposite                                   | |
+ * | |                                                                       | |
+ * | ------------------------------------------------------------------------- |
+ * -----------------------------------------------------------------------------</pre>
+ *
+ * @see EmbeddedMapping
+ * @see BaseJavaUiFactory - The factory creating this pane
+ *
+ * @version 2.3
+ * @since 2.2
+ */
+public class OrmEmbeddedMapping2_0Composite extends AbstractEmbeddedMappingComposite<OrmEmbeddedMapping>
+                                      implements JpaComposite
+{
+	/**
+	 * Creates a new <code>EmbeddedMappingComposite</code>.
+	 *
+	 * @param subjectHolder The holder of the subject <code>EmbeddedMapping</code>
+	 * @param parent The parent container
+	 * @param widgetFactory The factory used to create various common widgets
+	 */
+	public OrmEmbeddedMapping2_0Composite(PropertyValueModel<? extends OrmEmbeddedMapping> subjectHolder,
+	                                Composite parent,
+	                                WidgetFactory widgetFactory) {
+
+		super(subjectHolder, parent, widgetFactory);
+	}
+	
+	@Override
+	protected void initializeEmbeddedSection(Composite container) {
+		new OrmMappingNameChooser(this, getSubjectHolder(), container);
+		new AccessTypeComposite(this, buildAccessHolderHolder(), container);
+
+		new EmbeddedMapping2_0OverridesComposite(
+			this,
+			container
+		);
+	}	
+	
+	protected PropertyValueModel<AccessHolder> buildAccessHolderHolder() {
+		return new PropertyAspectAdapter<OrmEmbeddedMapping, AccessHolder>(getSubjectHolder()) {
+			@Override
+			protected AccessHolder buildValue_() {
+				return this.subject.getPersistentAttribute();
+			}
+		};
+	}
+}
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/orm/OrmEntity2_0Composite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/orm/OrmEntity2_0Composite.java
new file mode 100644
index 0000000..5044e79
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/orm/OrmEntity2_0Composite.java
@@ -0,0 +1,91 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2010 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.ui.internal.jpa2.details.orm;
+
+import org.eclipse.jpt.core.context.GeneratorContainer;
+import org.eclipse.jpt.core.context.QueryContainer;
+import org.eclipse.jpt.core.context.orm.OrmEntity;
+import org.eclipse.jpt.core.jpa2.context.Cacheable2_0;
+import org.eclipse.jpt.core.jpa2.context.CacheableHolder2_0;
+import org.eclipse.jpt.ui.WidgetFactory;
+import org.eclipse.jpt.ui.internal.details.AccessTypeComposite;
+import org.eclipse.jpt.ui.internal.details.EntityNameComposite;
+import org.eclipse.jpt.ui.internal.details.IdClassComposite;
+import org.eclipse.jpt.ui.internal.details.TableComposite;
+import org.eclipse.jpt.ui.internal.details.orm.AbstractOrmEntityComposite;
+import org.eclipse.jpt.ui.internal.details.orm.MetadataCompleteComposite;
+import org.eclipse.jpt.ui.internal.details.orm.OrmJavaClassChooser;
+import org.eclipse.jpt.ui.internal.jpa2.details.Cacheable2_0Pane;
+import org.eclipse.jpt.ui.internal.jpa2.details.Entity2_0OverridesComposite;
+import org.eclipse.jpt.ui.internal.jpa2.details.Generation2_0Composite;
+import org.eclipse.jpt.ui.internal.jpa2.details.Queries2_0Composite;
+import org.eclipse.jpt.utility.internal.model.value.PropertyAspectAdapter;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * The pane used for an ORM entity 2.0.
+ *
+ * @see OrmEntity
+ * @see Entity2_0OverridesComposite
+ */
+public class OrmEntity2_0Composite
+	extends AbstractOrmEntityComposite
+{
+	/**
+	 * Creates a new <code>OrmEntityComposite</code>.
+	 *
+	 * @param subjectHolder The holder of the subject <code>OrmEntity</code>
+	 * @param parent The parent container
+	 * @param widgetFactory The factory used to create various common widgets
+	 */
+	public OrmEntity2_0Composite(
+			PropertyValueModel<? extends OrmEntity> subjectHolder,
+			Composite parent,
+			WidgetFactory widgetFactory) {
+		
+		super(subjectHolder, parent, widgetFactory);
+	}
+	
+	@Override
+	protected void initializeEntitySection(Composite container) {
+		new OrmJavaClassChooser(this, getSubjectHolder(), container, false);
+		new TableComposite(this, container);
+		new EntityNameComposite(this, container);
+		new AccessTypeComposite(this, buildAccessHolder(), container);
+		new IdClassComposite(this, buildIdClassReferenceHolder(), container);
+		new Cacheable2_0Pane(this, buildCacheableHolder(), container);
+		new MetadataCompleteComposite(this, getSubjectHolder(), container);
+	}
+	
+	protected PropertyValueModel<Cacheable2_0> buildCacheableHolder() {
+		return new PropertyAspectAdapter<OrmEntity, Cacheable2_0>(getSubjectHolder()) {
+			@Override
+			protected Cacheable2_0 buildValue_() {
+				return ((CacheableHolder2_0) this.subject).getCacheable();
+			}
+		};
+	}
+
+	@Override
+	protected void initializeAttributeOverridesSection(Composite container) {
+		new Entity2_0OverridesComposite(this, container);
+	}
+
+	@Override
+	protected void initializeGeneratorsSection(Composite container, PropertyValueModel<GeneratorContainer> generatorContainerHolder) {
+		new Generation2_0Composite(this, generatorContainerHolder, container);
+	}
+
+	@Override
+	protected void initializeQueriesSection(Composite container, PropertyValueModel<QueryContainer> queryContainerHolder) {
+		new Queries2_0Composite(this, queryContainerHolder, container);
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/orm/OrmIdMapping2_0Composite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/orm/OrmIdMapping2_0Composite.java
new file mode 100644
index 0000000..1d81e9c
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/orm/OrmIdMapping2_0Composite.java
@@ -0,0 +1,58 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2010 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.ui.internal.jpa2.details.orm;
+
+import org.eclipse.jpt.core.context.AccessHolder;
+import org.eclipse.jpt.core.context.orm.OrmIdMapping;
+import org.eclipse.jpt.ui.WidgetFactory;
+import org.eclipse.jpt.ui.internal.details.AbstractIdMappingComposite;
+import org.eclipse.jpt.ui.internal.details.AccessTypeComposite;
+import org.eclipse.jpt.ui.internal.details.ColumnComposite;
+import org.eclipse.jpt.ui.internal.details.orm.OrmMappingNameChooser;
+import org.eclipse.jpt.ui.internal.jpa2.details.IdMapping2_0MappedByRelationshipPane;
+import org.eclipse.jpt.ui.internal.jpa2.details.IdMappingGeneration2_0Composite;
+import org.eclipse.jpt.utility.internal.model.value.PropertyAspectAdapter;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+public class OrmIdMapping2_0Composite
+	extends AbstractIdMappingComposite<OrmIdMapping>
+{
+	public OrmIdMapping2_0Composite(
+			PropertyValueModel<? extends OrmIdMapping> subjectHolder,
+	        Composite parent,
+	        WidgetFactory widgetFactory) {
+		
+		super(subjectHolder, parent, widgetFactory);
+	}
+	
+	
+	@Override
+	protected void initializeIdSection(Composite container) {
+		new IdMapping2_0MappedByRelationshipPane(this, getSubjectHolder(), container);
+		new ColumnComposite(this, buildColumnHolder(), container);
+		new OrmMappingNameChooser(this, getSubjectHolder(), container);
+		new AccessTypeComposite(this, buildAccessHolderHolder(), container);
+	}
+	
+	@Override
+	protected void initializeGenerationCollapsibleSection(Composite container) {
+		new IdMappingGeneration2_0Composite(this, container);
+	}
+	
+	protected PropertyValueModel<AccessHolder> buildAccessHolderHolder() {
+		return new PropertyAspectAdapter<OrmIdMapping, AccessHolder>(getSubjectHolder()) {
+			@Override
+			protected AccessHolder buildValue_() {
+				return this.subject.getPersistentAttribute();
+			}
+		};
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/orm/OrmManyToManyMapping2_0Composite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/orm/OrmManyToManyMapping2_0Composite.java
new file mode 100644
index 0000000..d39134e
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/orm/OrmManyToManyMapping2_0Composite.java
@@ -0,0 +1,57 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2010 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.ui.internal.jpa2.details.orm;
+
+import org.eclipse.jpt.core.context.orm.OrmManyToManyMapping;
+import org.eclipse.jpt.core.context.orm.OrmManyToManyRelationshipReference;
+import org.eclipse.jpt.ui.WidgetFactory;
+import org.eclipse.jpt.ui.internal.details.AbstractManyToManyMappingComposite;
+import org.eclipse.jpt.ui.internal.details.AccessTypeComposite;
+import org.eclipse.jpt.ui.internal.details.FetchTypeComposite;
+import org.eclipse.jpt.ui.internal.details.TargetEntityComposite;
+import org.eclipse.jpt.ui.internal.details.orm.OrmMappingNameChooser;
+import org.eclipse.jpt.ui.internal.jpa2.details.CascadePane2_0;
+import org.eclipse.jpt.ui.internal.jpa2.details.Ordering2_0Composite;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+public class OrmManyToManyMapping2_0Composite
+	extends AbstractManyToManyMappingComposite<OrmManyToManyMapping, OrmManyToManyRelationshipReference>
+{
+	/**
+	 * Creates a new <code>ManyToManyMappingComposite</code>.
+	 *
+	 * @param subjectHolder The holder of the subject <code>IManyToManyMapping</code>
+	 * @param parent The parent container
+	 * @param widgetFactory The factory used to create various common widgets
+	 */
+	public OrmManyToManyMapping2_0Composite(
+			PropertyValueModel<? extends OrmManyToManyMapping> subjectHolder,
+	        Composite parent,
+	        WidgetFactory widgetFactory) {
+		
+		super(subjectHolder, parent, widgetFactory);
+	}
+	
+	
+	@Override
+	protected void initializeManyToManySection(Composite container) {
+		new TargetEntityComposite(this, container);
+		new OrmMappingNameChooser(this, getSubjectHolder(), container);
+		new AccessTypeComposite(this, buildAccessHolderHolder(), container);
+		new FetchTypeComposite(this, container);
+		new CascadePane2_0(this, buildCascadeHolder(), addSubPane(container, 5));
+	}
+	
+	@Override
+	protected void initializeOrderingCollapsibleSection(Composite container) {
+		new Ordering2_0Composite(this, container);
+	}
+}
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/orm/OrmManyToOneMapping2_0Composite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/orm/OrmManyToOneMapping2_0Composite.java
new file mode 100644
index 0000000..3b5f7e0
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/orm/OrmManyToOneMapping2_0Composite.java
@@ -0,0 +1,57 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2010 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.ui.internal.jpa2.details.orm;
+
+import org.eclipse.jpt.core.context.AccessHolder;
+import org.eclipse.jpt.core.context.orm.OrmManyToOneMapping;
+import org.eclipse.jpt.core.jpa2.context.orm.OrmManyToOneRelationshipReference2_0;
+import org.eclipse.jpt.ui.WidgetFactory;
+import org.eclipse.jpt.ui.internal.details.AccessTypeComposite;
+import org.eclipse.jpt.ui.internal.details.FetchTypeComposite;
+import org.eclipse.jpt.ui.internal.details.OptionalComposite;
+import org.eclipse.jpt.ui.internal.details.TargetEntityComposite;
+import org.eclipse.jpt.ui.internal.details.orm.OrmMappingNameChooser;
+import org.eclipse.jpt.ui.internal.jpa2.details.AbstractManyToOneMapping2_0Composite;
+import org.eclipse.jpt.ui.internal.jpa2.details.CascadePane2_0;
+import org.eclipse.jpt.utility.internal.model.value.PropertyAspectAdapter;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+public class OrmManyToOneMapping2_0Composite
+	extends AbstractManyToOneMapping2_0Composite<OrmManyToOneMapping, OrmManyToOneRelationshipReference2_0>
+{
+	public OrmManyToOneMapping2_0Composite(
+			PropertyValueModel<? extends OrmManyToOneMapping> subjectHolder,
+			Composite parent,
+	        WidgetFactory widgetFactory) {
+		
+		super(subjectHolder, parent, widgetFactory);
+	}
+	
+	
+	@Override
+	protected void initializeManyToOneSection(Composite container) {
+		new TargetEntityComposite(this, container);
+		new OrmMappingNameChooser(this, getSubjectHolder(), container);
+		new AccessTypeComposite(this, buildAccessHolderHolder(), container);
+		new FetchTypeComposite(this, container);
+		new OptionalComposite(this, container);
+		new CascadePane2_0(this, buildCascadeHolder(),  addSubPane(container, 5));
+	}
+	
+	protected PropertyValueModel<AccessHolder> buildAccessHolderHolder() {
+		return new PropertyAspectAdapter<OrmManyToOneMapping, AccessHolder>(getSubjectHolder()) {
+			@Override
+			protected AccessHolder buildValue_() {
+				return this.subject.getPersistentAttribute();
+			}
+		};
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/orm/OrmOneToManyMapping2_0Composite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/orm/OrmOneToManyMapping2_0Composite.java
new file mode 100644
index 0000000..10a9b05
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/orm/OrmOneToManyMapping2_0Composite.java
@@ -0,0 +1,80 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2010 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.ui.internal.jpa2.details.orm;
+
+import org.eclipse.jpt.core.context.AccessHolder;
+import org.eclipse.jpt.core.context.orm.OrmOneToManyMapping;
+import org.eclipse.jpt.core.jpa2.context.OrphanRemovable2_0;
+import org.eclipse.jpt.core.jpa2.context.OrphanRemovalHolder2_0;
+import org.eclipse.jpt.core.jpa2.context.orm.OrmOneToManyRelationshipReference2_0;
+import org.eclipse.jpt.ui.WidgetFactory;
+import org.eclipse.jpt.ui.internal.details.AbstractOneToManyMappingComposite;
+import org.eclipse.jpt.ui.internal.details.AccessTypeComposite;
+import org.eclipse.jpt.ui.internal.details.FetchTypeComposite;
+import org.eclipse.jpt.ui.internal.details.TargetEntityComposite;
+import org.eclipse.jpt.ui.internal.details.orm.OrmMappingNameChooser;
+import org.eclipse.jpt.ui.internal.jpa2.details.CascadePane2_0;
+import org.eclipse.jpt.ui.internal.jpa2.details.OneToManyJoiningStrategy2_0Pane;
+import org.eclipse.jpt.ui.internal.jpa2.details.Ordering2_0Composite;
+import org.eclipse.jpt.ui.internal.jpa2.details.OrphanRemoval2_0Composite;
+import org.eclipse.jpt.utility.internal.model.value.PropertyAspectAdapter;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+public class OrmOneToManyMapping2_0Composite
+	extends AbstractOneToManyMappingComposite<OrmOneToManyMapping, OrmOneToManyRelationshipReference2_0>
+{
+	public OrmOneToManyMapping2_0Composite(
+			PropertyValueModel<? extends OrmOneToManyMapping> subjectHolder,
+			Composite parent,
+			WidgetFactory widgetFactory) {
+		
+		super(subjectHolder, parent, widgetFactory);
+	}
+	
+	
+	@Override
+	protected void initializeOneToManySection(Composite container) {
+		new TargetEntityComposite(this, container);
+		new OrmMappingNameChooser(this, getSubjectHolder(), container);
+		new AccessTypeComposite(this, this.buildAccessHolderHolder(), container);
+		new FetchTypeComposite(this, container);
+		new OrphanRemoval2_0Composite(this, this.buildOrphanRemovableHolder(), container);
+		new CascadePane2_0(this, this.buildCascadeHolder(), this.addSubPane(container, 5));
+	}
+
+	@Override
+	protected void initializeJoiningStrategyCollapsibleSection(Composite container) {
+		new OneToManyJoiningStrategy2_0Pane(this, this.buildJoiningHolder(), container);
+	}
+
+	@Override
+	protected void initializeOrderingCollapsibleSection(Composite container) {
+		new Ordering2_0Composite(this, container);
+	}
+
+	protected PropertyValueModel<AccessHolder> buildAccessHolderHolder() {
+		return new PropertyAspectAdapter<OrmOneToManyMapping, AccessHolder>(this.getSubjectHolder()) {
+			@Override
+			protected AccessHolder buildValue_() {
+				return this.subject.getPersistentAttribute();
+			}
+		};
+	}
+	
+	protected PropertyValueModel<OrphanRemovable2_0> buildOrphanRemovableHolder() {
+		return new PropertyAspectAdapter<OrmOneToManyMapping, OrphanRemovable2_0>(this.getSubjectHolder()) {
+			@Override
+			protected OrphanRemovable2_0 buildValue_() {
+				return ((OrphanRemovalHolder2_0) this.subject).getOrphanRemoval();
+			}
+		};
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/orm/OrmOneToOneMapping2_0Composite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/orm/OrmOneToOneMapping2_0Composite.java
new file mode 100644
index 0000000..15bfee3
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/orm/OrmOneToOneMapping2_0Composite.java
@@ -0,0 +1,76 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2010 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.ui.internal.jpa2.details.orm;
+
+import org.eclipse.jpt.core.context.AccessHolder;
+import org.eclipse.jpt.core.context.orm.OrmOneToOneMapping;
+import org.eclipse.jpt.core.jpa2.context.OrphanRemovable2_0;
+import org.eclipse.jpt.core.jpa2.context.OrphanRemovalHolder2_0;
+import org.eclipse.jpt.core.jpa2.context.orm.OrmOneToOneRelationshipReference2_0;
+import org.eclipse.jpt.ui.WidgetFactory;
+import org.eclipse.jpt.ui.internal.details.AccessTypeComposite;
+import org.eclipse.jpt.ui.internal.details.FetchTypeComposite;
+import org.eclipse.jpt.ui.internal.details.OptionalComposite;
+import org.eclipse.jpt.ui.internal.details.TargetEntityComposite;
+import org.eclipse.jpt.ui.internal.details.orm.OrmMappingNameChooser;
+import org.eclipse.jpt.ui.internal.jpa2.details.AbstractOneToOneMapping2_0Composite;
+import org.eclipse.jpt.ui.internal.jpa2.details.CascadePane2_0;
+import org.eclipse.jpt.ui.internal.jpa2.details.OneToOneJoiningStrategy2_0Pane;
+import org.eclipse.jpt.ui.internal.jpa2.details.OrphanRemoval2_0Composite;
+import org.eclipse.jpt.utility.internal.model.value.PropertyAspectAdapter;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+public class OrmOneToOneMapping2_0Composite
+	extends AbstractOneToOneMapping2_0Composite<OrmOneToOneMapping, OrmOneToOneRelationshipReference2_0>
+{
+	public OrmOneToOneMapping2_0Composite(
+			PropertyValueModel<? extends OrmOneToOneMapping> subjectHolder,
+			Composite parent,
+			WidgetFactory widgetFactory) {
+		
+		super(subjectHolder, parent, widgetFactory);
+	}
+	
+	
+	@Override
+	protected void initializeOneToOneSection(Composite container) {
+		new TargetEntityComposite(this, container);
+		new OrmMappingNameChooser(this, getSubjectHolder(), container);
+		new AccessTypeComposite(this, buildAccessHolderHolder(), container);
+		new FetchTypeComposite(this, container);
+		new OptionalComposite(this, container);
+		new OrphanRemoval2_0Composite(this, buildOrphanRemovableHolder(), container);
+		new CascadePane2_0(this, buildCascadeHolder(),  addSubPane(container, 5));
+	}
+
+	@Override
+	protected void initializeJoiningStrategyCollapsibleSection(Composite container) {
+		new OneToOneJoiningStrategy2_0Pane(this, buildJoiningHolder(), container);
+	}
+
+	protected PropertyValueModel<AccessHolder> buildAccessHolderHolder() {
+		return new PropertyAspectAdapter<OrmOneToOneMapping, AccessHolder>(getSubjectHolder()) {
+			@Override
+			protected AccessHolder buildValue_() {
+				return this.subject.getPersistentAttribute();
+			}
+		};
+	}
+	
+	protected PropertyValueModel<OrphanRemovable2_0> buildOrphanRemovableHolder() {
+		return new PropertyAspectAdapter<OrmOneToOneMapping, OrphanRemovable2_0>(getSubjectHolder()) {
+			@Override
+			protected OrphanRemovable2_0 buildValue_() {
+				return ((OrphanRemovalHolder2_0) this.subject).getOrphanRemoval();
+			}
+		};
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/orm/OrmQueries2_0Composite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/orm/OrmQueries2_0Composite.java
new file mode 100644
index 0000000..7fce6a0
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/orm/OrmQueries2_0Composite.java
@@ -0,0 +1,43 @@
+/*******************************************************************************
+* Copyright (c) 2009 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.ui.internal.jpa2.details.orm;
+
+import org.eclipse.jpt.core.context.QueryContainer;
+import org.eclipse.jpt.core.context.orm.EntityMappings;
+import org.eclipse.jpt.ui.internal.details.QueriesComposite;
+import org.eclipse.jpt.ui.internal.details.orm.OrmQueriesComposite;
+import org.eclipse.jpt.ui.internal.jpa2.details.Queries2_0Composite;
+import org.eclipse.jpt.ui.internal.widgets.Pane;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ *  OrmQueries2_0Composite
+ */
+public class OrmQueries2_0Composite extends OrmQueriesComposite {
+
+	/**
+	 * Creates a new <code>OrmQueries2_0Composite</code>.
+	 *
+	 * @param parentPane The parent container of this one
+	 * @param parent The parent container
+	 */
+	public OrmQueries2_0Composite(Pane<? extends EntityMappings> parentPane,
+	                           Composite parent) {
+
+		super(parentPane, parent);
+	}
+
+	@Override
+	protected QueriesComposite buildQueriesComposite(Composite container, PropertyValueModel<QueryContainer> queryContainerHolder) {
+		return new Queries2_0Composite(this, queryContainerHolder, container);
+	}
+	
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/orm/OrmVersionMapping2_0Composite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/orm/OrmVersionMapping2_0Composite.java
new file mode 100644
index 0000000..f31197d
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/orm/OrmVersionMapping2_0Composite.java
@@ -0,0 +1,54 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2010 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.ui.internal.jpa2.details.orm;
+
+import org.eclipse.jpt.core.context.AccessHolder;
+import org.eclipse.jpt.core.context.orm.OrmVersionMapping;
+import org.eclipse.jpt.ui.WidgetFactory;
+import org.eclipse.jpt.ui.internal.details.AbstractVersionMappingComposite;
+import org.eclipse.jpt.ui.internal.details.AccessTypeComposite;
+import org.eclipse.jpt.ui.internal.details.ColumnComposite;
+import org.eclipse.jpt.ui.internal.details.orm.OrmMappingNameChooser;
+import org.eclipse.jpt.utility.internal.model.value.PropertyAspectAdapter;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+public class OrmVersionMapping2_0Composite extends AbstractVersionMappingComposite<OrmVersionMapping>
+{
+	/**
+	 * Creates a new <code>EclipseLinkOrmVersionMappingComposite</code>.
+	 *
+	 * @param subjectHolder The holder of the subject <code>VersionMapping</code>
+	 * @param parent The parent container
+	 * @param widgetFactory The factory used to create various common widgets
+	 */
+	public OrmVersionMapping2_0Composite(PropertyValueModel<? extends OrmVersionMapping> subjectHolder,
+	                               Composite parent,
+	                               WidgetFactory widgetFactory) {
+
+		super(subjectHolder, parent, widgetFactory);
+	}
+
+	@Override
+	protected void initializeVersionSection(Composite container) {
+		new ColumnComposite(this, buildColumnHolder(), container);
+		new OrmMappingNameChooser(this, getSubjectHolder(), container);
+		new AccessTypeComposite(this, buildAccessHolderHolder(), container);
+	}
+
+	protected PropertyValueModel<AccessHolder> buildAccessHolderHolder() {
+		return new PropertyAspectAdapter<OrmVersionMapping, AccessHolder>(getSubjectHolder()) {
+			@Override
+			protected AccessHolder buildValue_() {
+				return this.subject.getPersistentAttribute();
+			}
+		};
+	}
+}
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/orm/OrmXml2_0UiDefinition.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/orm/OrmXml2_0UiDefinition.java
new file mode 100644
index 0000000..5ab8499
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/details/orm/OrmXml2_0UiDefinition.java
@@ -0,0 +1,96 @@
+/*******************************************************************************
+ * Copyright (c) 2009 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.ui.internal.jpa2.details.orm;
+
+import java.util.List;
+import org.eclipse.jpt.core.JpaResourceType;
+import org.eclipse.jpt.core.JptCorePlugin;
+import org.eclipse.jpt.core.context.AttributeMapping;
+import org.eclipse.jpt.core.context.TypeMapping;
+import org.eclipse.jpt.ui.ResourceUiDefinition;
+import org.eclipse.jpt.ui.details.orm.OrmAttributeMappingUiDefinition;
+import org.eclipse.jpt.ui.details.orm.OrmTypeMappingUiDefinition;
+import org.eclipse.jpt.ui.details.orm.OrmXmlUiFactory;
+import org.eclipse.jpt.ui.internal.details.orm.AbstractOrmXmlResourceUiDefinition;
+import org.eclipse.jpt.ui.internal.details.orm.OrmBasicMappingUiDefinition;
+import org.eclipse.jpt.ui.internal.details.orm.OrmEmbeddableUiDefinition;
+import org.eclipse.jpt.ui.internal.details.orm.OrmEmbeddedIdMappingUiDefinition;
+import org.eclipse.jpt.ui.internal.details.orm.OrmEmbeddedMappingUiDefinition;
+import org.eclipse.jpt.ui.internal.details.orm.OrmEntityUiDefinition;
+import org.eclipse.jpt.ui.internal.details.orm.OrmIdMappingUiDefinition;
+import org.eclipse.jpt.ui.internal.details.orm.OrmManyToManyMappingUiDefinition;
+import org.eclipse.jpt.ui.internal.details.orm.OrmManyToOneMappingUiDefinition;
+import org.eclipse.jpt.ui.internal.details.orm.OrmMappedSuperclassUiDefinition;
+import org.eclipse.jpt.ui.internal.details.orm.OrmOneToManyMappingUiDefinition;
+import org.eclipse.jpt.ui.internal.details.orm.OrmOneToOneMappingUiDefinition;
+import org.eclipse.jpt.ui.internal.details.orm.OrmTransientMappingUiDefinition;
+import org.eclipse.jpt.ui.internal.details.orm.OrmVersionMappingUiDefinition;
+import org.eclipse.jpt.ui.internal.jpa2.GenericOrmXml2_0UiFactory;
+import org.eclipse.jpt.ui.internal.structure.OrmResourceModelStructureProvider;
+import org.eclipse.jpt.ui.structure.JpaStructureProvider;
+
+public class OrmXml2_0UiDefinition extends AbstractOrmXmlResourceUiDefinition
+{
+	// singleton
+	private static final ResourceUiDefinition INSTANCE = new OrmXml2_0UiDefinition();
+	
+	
+	/**
+	 * Return the singleton
+	 */
+	public static ResourceUiDefinition instance() {
+		return INSTANCE;
+	}
+	
+	
+	/**
+	 * Enforce singleton usage
+	 */
+	private OrmXml2_0UiDefinition() {
+		super();
+	}
+	
+	
+	@Override
+	protected OrmXmlUiFactory buildOrmXmlUiFactory() {
+		return new GenericOrmXml2_0UiFactory();
+	}
+	
+	public boolean providesUi(JpaResourceType resourceType) {
+		return resourceType.equals(JptCorePlugin.ORM_XML_2_0_RESOURCE_TYPE);
+	}
+	
+	public JpaStructureProvider getStructureProvider() {
+		return OrmResourceModelStructureProvider.instance();
+	}
+	
+	@Override
+	protected void addOrmAttributeMappingUiDefinitionsTo(List<OrmAttributeMappingUiDefinition<? extends AttributeMapping>> definitions) {
+		definitions.add(OrmIdMappingUiDefinition.instance());
+		definitions.add(OrmEmbeddedIdMappingUiDefinition.instance());
+		definitions.add(OrmBasicMappingUiDefinition.instance());
+		definitions.add(OrmVersionMappingUiDefinition.instance());
+		definitions.add(OrmManyToOneMappingUiDefinition.instance());
+		definitions.add(OrmOneToManyMappingUiDefinition.instance());
+		definitions.add(OrmOneToOneMappingUiDefinition.instance());
+		definitions.add(OrmManyToManyMappingUiDefinition.instance());
+		definitions.add(OrmEmbeddedMappingUiDefinition.instance());
+		definitions.add(OrmTransientMappingUiDefinition.instance());
+		
+		definitions.add(OrmElementCollectionMapping2_0UiDefinition.instance());
+	}
+	
+	@Override
+	protected void addOrmTypeMappingUiDefinitionsTo(List<OrmTypeMappingUiDefinition<? extends TypeMapping>> definitions) {
+		definitions.add(OrmEntityUiDefinition.instance());
+		definitions.add(OrmMappedSuperclassUiDefinition.instance());
+		definitions.add(OrmEmbeddableUiDefinition.instance());
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/persistence/Generic2_0PersistenceXmlUiFactory.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/persistence/Generic2_0PersistenceXmlUiFactory.java
new file mode 100644
index 0000000..c03c932
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/persistence/Generic2_0PersistenceXmlUiFactory.java
@@ -0,0 +1,83 @@
+/*******************************************************************************
+ * Copyright (c) 2009 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.ui.internal.jpa2.persistence;
+
+import java.util.ArrayList;
+import java.util.ListIterator;
+import org.eclipse.jpt.core.context.persistence.PersistenceUnit;
+import org.eclipse.jpt.core.jpa2.context.persistence.PersistenceUnit2_0;
+import org.eclipse.jpt.core.jpa2.context.persistence.connection.JpaConnection2_0;
+import org.eclipse.jpt.core.jpa2.context.persistence.options.JpaOptions2_0;
+import org.eclipse.jpt.ui.WidgetFactory;
+import org.eclipse.jpt.ui.details.JpaPageComposite;
+import org.eclipse.jpt.ui.internal.jpa2.persistence.connection.GenericPersistenceUnit2_0ConnectionTab;
+import org.eclipse.jpt.ui.internal.jpa2.persistence.options.GenericPersistenceUnit2_0OptionsTab;
+import org.eclipse.jpt.ui.internal.persistence.details.GenericPersistenceUnitGeneralComposite;
+import org.eclipse.jpt.ui.internal.persistence.details.PersistenceUnitPropertiesComposite;
+import org.eclipse.jpt.ui.internal.persistence.details.PersistenceXmlUiFactory;
+import org.eclipse.jpt.utility.internal.model.value.TransformationPropertyValueModel;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * The default implementation of the UI factory required to show the information
+ * related to a JPA mapping (type or attribute).
+ *
+ * @see GenericPersistenceXmlUiFactory
+ *
+ * @version 1.0
+ * @since 1.0
+ */
+public class Generic2_0PersistenceXmlUiFactory implements PersistenceXmlUiFactory
+{
+	
+	// **************** persistence unit composites ****************************
+	public ListIterator<JpaPageComposite> createPersistenceUnitComposites(
+		PropertyValueModel<PersistenceUnit> subjectHolder,
+		Composite parent,
+		WidgetFactory widgetFactory) {
+
+		ArrayList<JpaPageComposite> pages = new ArrayList<JpaPageComposite>(4);
+		
+		PropertyValueModel<JpaConnection2_0> connection2_0Holder = 
+			this.buildJpaConnection2_0Holder(subjectHolder);
+		PropertyValueModel<JpaOptions2_0> options2_0Holder = 
+			this.buildJpaOptions2_0Holder(subjectHolder);
+		
+		pages.add(new GenericPersistenceUnitGeneralComposite(subjectHolder, parent, widgetFactory));
+		pages.add(new GenericPersistenceUnit2_0ConnectionTab(connection2_0Holder, parent, widgetFactory));
+		pages.add(new GenericPersistenceUnit2_0OptionsTab(options2_0Holder, parent, widgetFactory));
+		pages.add(new PersistenceUnitPropertiesComposite(subjectHolder, parent, widgetFactory));
+
+		return pages.listIterator();
+	}
+
+	// ********** private methods **********
+	
+	private PropertyValueModel<JpaConnection2_0> buildJpaConnection2_0Holder(
+				PropertyValueModel<PersistenceUnit> subjectHolder) {
+		return new TransformationPropertyValueModel<PersistenceUnit, JpaConnection2_0>(subjectHolder) {
+			@Override
+			protected JpaConnection2_0 transform_(PersistenceUnit value) {
+				return (JpaConnection2_0) ((PersistenceUnit2_0) value).getConnection();
+			}
+		};
+	}
+	
+	private PropertyValueModel<JpaOptions2_0> buildJpaOptions2_0Holder(
+				PropertyValueModel<PersistenceUnit> subjectHolder) {
+		return new TransformationPropertyValueModel<PersistenceUnit, JpaOptions2_0>(subjectHolder) {
+			@Override
+			protected JpaOptions2_0 transform_(PersistenceUnit value) {
+				return (JpaOptions2_0) ((PersistenceUnit2_0) value).getOptions();
+			}
+		};
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/persistence/JptUiPersistence2_0Messages.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/persistence/JptUiPersistence2_0Messages.java
new file mode 100644
index 0000000..351aaa6
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/persistence/JptUiPersistence2_0Messages.java
@@ -0,0 +1,81 @@
+/*******************************************************************************
+* Copyright (c) 2009, 2010 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.ui.internal.jpa2.persistence;
+
+import org.eclipse.osgi.util.NLS;
+
+/**
+ *  JptUiPersistence2_0Messages
+ */
+public class JptUiPersistence2_0Messages
+{
+	// Connection
+	public static String ConnectionPropertiesComposite_Database_GroupBox;
+
+	public static String DataSourcePropertiesComposite_jtaDataSourceLabel;
+	public static String DataSourcePropertiesComposite_nonJtaDataSourceLabel;
+	
+	public static String GenericPersistenceUnit2_0ConnectionComposite_sectionTitle;
+	public static String GenericPersistenceUnit2_0ConnectionComposite_sectionDescription;
+	public static String GenericPersistenceUnit2_0ConnectionTab_title;
+	
+	public static String GenericPersistenceUnit2_0OptionsComposite_miscellaneousSectionTitle;
+	public static String GenericPersistenceUnit2_0OptionsComposite_miscellaneousSectionDescription;
+	public static String GenericPersistenceUnit2_0OptionsTab_title;
+
+	public static String JdbcConnectionPropertiesComposite_ConnectionDialog_Message;
+	public static String JdbcConnectionPropertiesComposite_ConnectionDialog_Title;
+
+	public static String JdbcConnectionPropertiesComposite_populateFromConnectionHyperLink;
+	public static String JdbcConnectionPropertiesComposite_driverLabel;
+	public static String JdbcConnectionPropertiesComposite_urlLabel;
+	public static String JdbcConnectionPropertiesComposite_userLabel;
+	public static String JdbcConnectionPropertiesComposite_passwordLabel;
+
+	public static String JdbcPropertiesComposite_JdbcConnectionProperties_GroupBox;
+
+	public static String LockingConfigurationComposite_lockTimeoutLabel;
+	public static String QueryConfigurationComposite_queryTimeoutLabel;
+	
+	public static String TransactionTypeComposite_transactionTypeLabel;
+
+	public static String TransactionTypeComposite_jta;
+	public static String TransactionTypeComposite_resource_local;
+	
+	public static String SharedCacheModeComposite_sharedCacheModeLabel;
+
+	public static String SharedCacheModeComposite_all;
+	public static String SharedCacheModeComposite_none;
+	public static String SharedCacheModeComposite_enable_selective;
+	public static String SharedCacheModeComposite_disable_selective;
+	public static String SharedCacheModeComposite_unspecified;
+	
+	public static String ValidationModeComposite_validationModeLabel;
+	
+	public static String ValidationModeComposite_auto;
+	public static String ValidationModeComposite_callback;
+	public static String ValidationModeComposite_none;
+
+	public static String ValidationConfigurationComposite_groupPrePersistLabel;
+	public static String ValidationConfigurationComposite_groupPreUpdateLabel;
+	public static String ValidationConfigurationComposite_groupPreRemoveLabel;
+
+	
+	private static final String BUNDLE_NAME = "jpt_ui_persistence2_0"; //$NON-NLS-1$
+	private static final Class<?> BUNDLE_CLASS = JptUiPersistence2_0Messages.class;
+	static {
+		NLS.initializeMessages(BUNDLE_NAME, BUNDLE_CLASS);
+	}
+
+	private JptUiPersistence2_0Messages() {
+		throw new UnsupportedOperationException();
+	}
+
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/persistence/PersistenceXml2_0UiDefinition.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/persistence/PersistenceXml2_0UiDefinition.java
new file mode 100644
index 0000000..5608157
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/persistence/PersistenceXml2_0UiDefinition.java
@@ -0,0 +1,55 @@
+/*******************************************************************************
+ *  Copyright (c) 2009  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.ui.internal.jpa2.persistence;
+
+import org.eclipse.jpt.core.JpaResourceType;
+import org.eclipse.jpt.core.JptCorePlugin;
+import org.eclipse.jpt.ui.ResourceUiDefinition;
+import org.eclipse.jpt.ui.internal.persistence.details.AbstractPersistenceXmlResourceUiDefinition;
+import org.eclipse.jpt.ui.internal.persistence.details.PersistenceXmlUiFactory;
+import org.eclipse.jpt.ui.internal.structure.PersistenceResourceModelStructureProvider;
+import org.eclipse.jpt.ui.structure.JpaStructureProvider;
+
+public class PersistenceXml2_0UiDefinition extends AbstractPersistenceXmlResourceUiDefinition
+{
+	// singleton
+	private static final ResourceUiDefinition INSTANCE = new PersistenceXml2_0UiDefinition();
+	
+	
+	/**
+	 * Return the singleton
+	 */
+	public static ResourceUiDefinition instance() {
+		return INSTANCE;
+	}
+	
+	
+	/**
+	 * Enforce singleton usage
+	 */
+	private PersistenceXml2_0UiDefinition() {
+		super();
+	}
+	
+	
+	@Override
+	protected PersistenceXmlUiFactory buildPersistenceXmlUiFactory() {
+		return new Generic2_0PersistenceXmlUiFactory();
+	}
+	
+	public boolean providesUi(JpaResourceType resourceType) {
+		return resourceType.equals(JptCorePlugin.PERSISTENCE_XML_2_0_RESOURCE_TYPE);
+	}
+	
+	public JpaStructureProvider getStructureProvider() {
+		return PersistenceResourceModelStructureProvider.instance();
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/persistence/connection/ConnectionPropertiesComposite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/persistence/connection/ConnectionPropertiesComposite.java
new file mode 100644
index 0000000..7a17b4e
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/persistence/connection/ConnectionPropertiesComposite.java
@@ -0,0 +1,38 @@
+/*******************************************************************************
+* Copyright (c) 2009, 2010 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.ui.internal.jpa2.persistence.connection;
+
+import org.eclipse.jpt.core.jpa2.context.persistence.connection.JpaConnection2_0;
+import org.eclipse.jpt.ui.internal.jpa2.persistence.JptUiPersistence2_0Messages;
+import org.eclipse.jpt.ui.internal.widgets.Pane;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ *  ConnectionPropertiesComposite
+ */
+public class ConnectionPropertiesComposite extends Pane<JpaConnection2_0>
+{
+	public ConnectionPropertiesComposite(Pane<JpaConnection2_0> parentComposite, Composite parent) {
+
+		super(parentComposite, parent);
+	}
+
+	@Override
+	protected void initializeLayout(Composite container) {
+
+		container = addTitledGroup(
+			container,
+			JptUiPersistence2_0Messages.ConnectionPropertiesComposite_Database_GroupBox
+		);
+
+		new DataSourcePropertiesComposite(this, container);
+		new JdbcPropertiesComposite(this, container);
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/persistence/connection/DataSourcePropertiesComposite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/persistence/connection/DataSourcePropertiesComposite.java
new file mode 100644
index 0000000..b5afe19
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/persistence/connection/DataSourcePropertiesComposite.java
@@ -0,0 +1,142 @@
+/*******************************************************************************
+* Copyright (c) 2009, 2010 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.ui.internal.jpa2.persistence.connection;
+
+import org.eclipse.jpt.core.context.persistence.PersistenceUnit;
+import org.eclipse.jpt.core.context.persistence.PersistenceUnitTransactionType;
+import org.eclipse.jpt.core.jpa2.context.persistence.connection.JpaConnection2_0;
+import org.eclipse.jpt.ui.internal.JpaHelpContextIds;
+import org.eclipse.jpt.ui.internal.jpa2.persistence.JptUiPersistence2_0Messages;
+import org.eclipse.jpt.ui.internal.widgets.Pane;
+import org.eclipse.jpt.utility.internal.model.value.PropertyAspectAdapter;
+import org.eclipse.jpt.utility.internal.model.value.TransformationPropertyValueModel;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.jpt.utility.model.value.WritablePropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Text;
+
+/**
+ *  DataSourcePropertiesComposite
+ */
+public class DataSourcePropertiesComposite extends Pane<JpaConnection2_0>
+{
+	/**
+	 * Creates a new <code>DataSourcePropertiesComposite</code>.
+	 *
+	 * @param parentPane The parent container of this one
+	 * @param parent The parent container
+	 */
+	public DataSourcePropertiesComposite(Pane<JpaConnection2_0> parentComposite,
+	                                      Composite parent) {
+
+		super(parentComposite, parent);
+	}
+
+	private WritablePropertyValueModel<String> buildJtaDataSourceHolder() {
+		return new PropertyAspectAdapter<PersistenceUnit, String>(this.buildPersistenceUnitHolder(), PersistenceUnit.JTA_DATA_SOURCE_PROPERTY) {
+			@Override
+			protected String buildValue_() {
+				return this.subject.getJtaDataSource();
+			}
+
+			@Override
+			protected void setValue_(String value) {
+				if (value.length() == 0) {
+					value = null;
+				}
+				this.subject.setJtaDataSource(value);
+			}
+		};
+	}
+
+	private PropertyValueModel<Boolean> buildJTADataSourceHolder() {
+		return new TransformationPropertyValueModel<PersistenceUnitTransactionType, Boolean>(buildTransactionTypeHolder()) {
+			@Override
+			protected Boolean transform(PersistenceUnitTransactionType value) {
+				return Boolean.valueOf(this.transform2(value));
+			}
+			private boolean transform2(PersistenceUnitTransactionType value) {
+				return value == null || value == PersistenceUnitTransactionType.JTA;
+			}
+		};
+	}
+
+	private WritablePropertyValueModel<String> buildNonJtaDataSourceHolder() {
+		return new PropertyAspectAdapter<PersistenceUnit, String>(buildPersistenceUnitHolder(), PersistenceUnit.NON_JTA_DATA_SOURCE_PROPERTY) {
+			@Override
+			protected String buildValue_() {
+				return this.subject.getNonJtaDataSource();
+			}
+
+			@Override
+			protected void setValue_(String value) {
+				if (value.length() == 0) {
+					value = null;
+				}
+				this.subject.setNonJtaDataSource(value);
+			}
+		};
+	}
+
+	private PropertyValueModel<Boolean> buildNonJTADataSourceHolder() {
+		return new TransformationPropertyValueModel<PersistenceUnitTransactionType, Boolean>(buildTransactionTypeHolder()) {
+			@Override
+			protected Boolean transform(PersistenceUnitTransactionType value) {
+				return Boolean.valueOf(value == PersistenceUnitTransactionType.RESOURCE_LOCAL);
+			}
+		};
+	}
+
+	private PropertyValueModel<PersistenceUnitTransactionType> buildTransactionTypeHolder() {
+		return new PropertyAspectAdapter<PersistenceUnit, PersistenceUnitTransactionType>(
+				buildPersistenceUnitHolder(), 
+				PersistenceUnit.SPECIFIED_TRANSACTION_TYPE_PROPERTY, 
+				PersistenceUnit.DEFAULT_TRANSACTION_TYPE_PROPERTY) {
+			@Override
+			protected PersistenceUnitTransactionType buildValue_() {
+				return this.subject.getTransactionType();
+			}
+		};
+	}
+
+	private PropertyValueModel<PersistenceUnit> buildPersistenceUnitHolder() {
+		return new PropertyAspectAdapter<JpaConnection2_0, PersistenceUnit>(getSubjectHolder()) {
+			@Override
+			protected PersistenceUnit buildValue_() {
+				return this.subject.getPersistenceUnit();
+			}
+		};
+	}
+	
+	@Override
+	protected void initializeLayout(Composite container) {
+
+		int groupBoxMargin = this.getGroupBoxMargin();
+
+		container = this.addSubPane(container, 0, groupBoxMargin, 0, groupBoxMargin);
+
+		// JTA Data Source
+		PropertyValueModel<Boolean> jtaEnabled = this.buildJTADataSourceHolder();
+		Label jtaLabel = this.addLabel(container, JptUiPersistence2_0Messages.DataSourcePropertiesComposite_jtaDataSourceLabel, jtaEnabled);
+		Text jtaText = this.addText(container, this.buildJtaDataSourceHolder(), this.getHelpID(), jtaEnabled);
+		this.addLabeledComposite(container, jtaLabel, jtaText, this.getHelpID());
+
+		// Non-JTA Data Source
+		PropertyValueModel<Boolean> nonJTAEnabled = this.buildNonJTADataSourceHolder();
+		Label nonJtaLabel = this.addLabel(container, JptUiPersistence2_0Messages.DataSourcePropertiesComposite_nonJtaDataSourceLabel, nonJTAEnabled);
+		Text nonJtaText = this.addText(container, this.buildNonJtaDataSourceHolder(), this.getHelpID(), nonJTAEnabled);
+		this.addLabeledComposite(container, nonJtaLabel, nonJtaText, this.getHelpID());
+	}
+
+	public String getHelpID() {
+		return JpaHelpContextIds.PERSISTENCE_XML_CONNECTION;	// TODO - Review for JPA 2.0
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/persistence/connection/GenericPersistenceUnit2_0ConnectionComposite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/persistence/connection/GenericPersistenceUnit2_0ConnectionComposite.java
new file mode 100644
index 0000000..6d188b1
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/persistence/connection/GenericPersistenceUnit2_0ConnectionComposite.java
@@ -0,0 +1,49 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2010 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.ui.internal.jpa2.persistence.connection;
+
+import org.eclipse.jpt.core.jpa2.context.persistence.connection.JpaConnection2_0;
+import org.eclipse.jpt.ui.internal.jpa2.persistence.JptUiPersistence2_0Messages;
+import org.eclipse.jpt.ui.internal.widgets.Pane;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ *  GenericPersistenceUnit2_0ConnectionComposite
+ */
+public class GenericPersistenceUnit2_0ConnectionComposite extends Pane<JpaConnection2_0>
+{
+	public GenericPersistenceUnit2_0ConnectionComposite(
+															Pane<JpaConnection2_0> subjectHolder,
+															Composite container) {
+		super(subjectHolder, container, false);
+	}
+
+	@Override
+	protected void initializeLayout(Composite container) {
+
+		int groupBoxMargin = this.getGroupBoxMargin() * 2;
+
+		container = this.addSection(
+			container,
+			JptUiPersistence2_0Messages.GenericPersistenceUnit2_0ConnectionComposite_sectionTitle,
+			JptUiPersistence2_0Messages.GenericPersistenceUnit2_0ConnectionComposite_sectionDescription
+		);
+
+		Composite subPane = this.addSubPane(
+			container,
+			0, groupBoxMargin, 10, groupBoxMargin
+		);
+
+		new TransactionTypeComposite(this, subPane);
+
+		new ConnectionPropertiesComposite(this, container);
+	}
+	
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/persistence/connection/GenericPersistenceUnit2_0ConnectionTab.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/persistence/connection/GenericPersistenceUnit2_0ConnectionTab.java
new file mode 100644
index 0000000..01fe7af
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/persistence/connection/GenericPersistenceUnit2_0ConnectionTab.java
@@ -0,0 +1,90 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2010 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.ui.internal.jpa2.persistence.connection;
+
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jpt.core.jpa2.context.persistence.connection.JpaConnection2_0;
+import org.eclipse.jpt.ui.WidgetFactory;
+import org.eclipse.jpt.ui.details.JpaPageComposite;
+import org.eclipse.jpt.ui.internal.JpaHelpContextIds;
+import org.eclipse.jpt.ui.internal.jpa2.persistence.JptUiPersistence2_0Messages;
+import org.eclipse.jpt.ui.internal.widgets.Pane;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ *  GenericPersistenceUnit2_0ConnectionTab
+ */
+public class GenericPersistenceUnit2_0ConnectionTab extends Pane<JpaConnection2_0>
+	implements JpaPageComposite
+{
+	// ********** constructors/initialization **********
+	/**
+	 * Creates a new <code>GenericPersistenceUnit2_0ConnectionTab</code>.
+	 *
+	 * @param subjectHolder The holder of this pane's subject
+	 * @param parent The parent container
+	 * @param widgetFactory The factory used to create various common widgets
+	 */
+	public GenericPersistenceUnit2_0ConnectionTab(
+											PropertyValueModel<JpaConnection2_0> subjectHolder,
+	                                        Composite parent,
+	                                        WidgetFactory widgetFactory) {
+
+		super(subjectHolder, parent, widgetFactory);
+	}
+
+	@Override
+	protected void initializeLayout(Composite container) {
+		new GenericPersistenceUnit2_0ConnectionComposite(this, container);
+	}
+
+	// ********** Layout **********
+	@Override
+	protected Composite addContainer(Composite parent) {
+		GridLayout layout = new GridLayout(1, true);
+		layout.marginHeight = 0;
+		layout.marginWidth = 0;
+		layout.marginTop = 0;
+		layout.marginLeft = 0;
+		layout.marginBottom = 0;
+		layout.marginRight = 0;
+		layout.verticalSpacing = 15;
+		Composite container = this.addPane(parent, layout);
+		updateGridData(container);
+		return container;
+	}
+
+	private void updateGridData(Composite container) {
+		GridData gridData = new GridData();
+		gridData.grabExcessHorizontalSpace = true;
+		gridData.grabExcessVerticalSpace = true;
+		gridData.horizontalAlignment = SWT.FILL;
+		gridData.verticalAlignment = SWT.FILL;
+		container.setLayoutData(gridData);
+	}
+
+	// ********** JpaPageComposite implementation **********
+
+	public String getHelpID() {
+		return JpaHelpContextIds.PERSISTENCE_XML_CONNECTION;	// TODO - Review for JPA 2.0
+	}
+	
+	public ImageDescriptor getPageImageDescriptor() {
+		return null;
+	}
+
+	public String getPageText() {
+		return JptUiPersistence2_0Messages.GenericPersistenceUnit2_0ConnectionTab_title;
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/persistence/connection/JdbcConnectionPropertiesComposite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/persistence/connection/JdbcConnectionPropertiesComposite.java
new file mode 100644
index 0000000..ee5cf1c
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/persistence/connection/JdbcConnectionPropertiesComposite.java
@@ -0,0 +1,314 @@
+/*******************************************************************************
+* Copyright (c) 2009, 2010 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.ui.internal.jpa2.persistence.connection;
+
+import java.util.Comparator;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.dialogs.IDialogSettings;
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.jpt.core.jpa2.context.persistence.connection.JpaConnection2_0;
+import org.eclipse.jpt.db.ConnectionProfile;
+import org.eclipse.jpt.db.ConnectionProfileFactory;
+import org.eclipse.jpt.db.JptDbPlugin;
+import org.eclipse.jpt.ui.JptUiPlugin;
+import org.eclipse.jpt.ui.internal.jpa2.persistence.JptUiPersistence2_0Messages;
+import org.eclipse.jpt.ui.internal.widgets.Pane;
+import org.eclipse.jpt.utility.internal.StringTools;
+import org.eclipse.jpt.utility.internal.model.value.PropertyAspectAdapter;
+import org.eclipse.jpt.utility.model.value.WritablePropertyValueModel;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.dialogs.FilteredItemsSelectionDialog;
+
+/**
+ *  JdbcConnectionPropertiesComposite
+ */
+@SuppressWarnings("nls")
+public class JdbcConnectionPropertiesComposite extends Pane<JpaConnection2_0>
+{
+	/**
+	 * The constant ID used to retrieve the dialog settings.
+	 */
+	private static final String DIALOG_SETTINGS = "org.eclipse.jpt.ui.internal.jpa2.dialogs.ConnectionDialog";
+
+	public JdbcConnectionPropertiesComposite(Pane<JpaConnection2_0> parentComposite, Composite parent) {
+
+		super(parentComposite, parent);
+	}
+
+	private WritablePropertyValueModel<String> buildPasswordHolder() {
+		return new PropertyAspectAdapter<JpaConnection2_0, String>(this.getSubjectHolder(), JpaConnection2_0.PASSWORD_PROPERTY) {
+			@Override
+			protected String buildValue_() {
+				return this.subject.getPassword();
+			}
+
+			@Override
+			protected void setValue_(String value) {
+				if (value.length() == 0) {
+					value = null;
+				}
+				this.subject.setPassword(value);
+			}
+		};
+	}
+
+	private Runnable buildPopulateFromConnectionAction() {
+		return new Runnable() {
+			public void run() {
+				promptConnection();
+			}
+		};
+	}
+
+	private WritablePropertyValueModel<String> buildUrlHolder() {
+		return new PropertyAspectAdapter<JpaConnection2_0, String>(this.getSubjectHolder(), JpaConnection2_0.URL_PROPERTY) {
+			@Override
+			protected String buildValue_() {
+				return this.subject.getUrl();
+			}
+
+			@Override
+			protected void setValue_(String value) {
+				if (value.length() == 0) {
+					value = null;
+				}
+				this.subject.setUrl(value);
+			}
+		};
+	}
+
+	private WritablePropertyValueModel<String> buildUserHolder() {
+		return new PropertyAspectAdapter<JpaConnection2_0, String>(this.getSubjectHolder(), JpaConnection2_0.USER_PROPERTY) {
+			@Override
+			protected String buildValue_() {
+				return this.subject.getUser();
+			}
+
+			@Override
+			protected void setValue_(String value) {
+				if (value.length() == 0) {
+					value = null;
+				}
+				this.subject.setUser(value);
+			}
+		};
+	}
+
+	@Override
+	protected void initializeLayout(Composite container) {
+
+		// Populate from Connection hyperlink
+		this.addHyperlink(
+			container,
+			JptUiPersistence2_0Messages.JdbcConnectionPropertiesComposite_populateFromConnectionHyperLink,
+			this.buildPopulateFromConnectionAction()
+		);
+
+		// Driver
+		new JdbcDriverComposite(this, container);
+
+		// Url
+		this.addLabeledText(
+			container,
+			JptUiPersistence2_0Messages.JdbcConnectionPropertiesComposite_urlLabel,
+			this.buildUrlHolder()
+		);
+
+		// User
+		this.addLabeledText(
+			container,
+			JptUiPersistence2_0Messages.JdbcConnectionPropertiesComposite_userLabel,
+			this.buildUserHolder()
+		);
+
+		// Password
+		this.addLabeledPasswordText(
+			container,
+			JptUiPersistence2_0Messages.JdbcConnectionPropertiesComposite_passwordLabel,
+			this.buildPasswordHolder()
+		);
+	}
+
+	void promptConnection() {
+
+		ConnectionSelectionDialog dialog = new ConnectionSelectionDialog();
+
+		if (dialog.open() != IDialogConstants.OK_ID) {
+			return;
+		}
+
+		String name = (String) dialog.getResult()[0];
+		ConnectionProfile cp = this.getConnectionProfileFactory().buildConnectionProfile(name);
+
+		JpaConnection2_0 connection = getSubject();
+		connection.setUrl((cp == null) ? "" : cp.getURL());
+		connection.setUser((cp == null) ? "" : cp.getUserName());
+		connection.setPassword((cp == null) ? "" : cp.getUserPassword());
+		connection.setDriver((cp == null) ? "" : cp.getDriverClassName());
+	}
+
+	ConnectionProfileFactory getConnectionProfileFactory() {
+		// we allow the user to select any connection profile and simply
+		// take the settings from it (user, password, etc.) and give them
+		// to the persistence connection, so we go
+		// to the db plug-in directly to get the factory
+		return JptDbPlugin.instance().getConnectionProfileFactory();
+	}
+
+	// broaden access a bit
+	Shell getShell_() {
+		return this.getShell();
+	}
+
+	/**
+	 * This dialog shows the list of possible connection names and lets the user
+	 * the option to filter them using a search field.
+	 */
+	protected class ConnectionSelectionDialog extends FilteredItemsSelectionDialog {
+
+		/**
+		 * Creates a new <code>MappingSelectionDialog</code>.
+		 */
+		protected ConnectionSelectionDialog() {
+			super(JdbcConnectionPropertiesComposite.this.getShell_(), false);
+			this.setMessage(JptUiPersistence2_0Messages.JdbcConnectionPropertiesComposite_ConnectionDialog_Message);
+			this.setTitle(JptUiPersistence2_0Messages.JdbcConnectionPropertiesComposite_ConnectionDialog_Title);
+			this.setListLabelProvider(this.buildLabelProvider());
+			this.setDetailsLabelProvider(this.buildLabelProvider());
+		}
+
+		protected ILabelProvider buildLabelProvider() {
+			return new LabelProvider() {
+				@Override
+				public Image getImage(Object element) {
+					return null;
+				}
+
+				@Override
+				public String getText(Object element) {
+					return (element == null) ? "" : element.toString();
+				}
+			};
+		}
+
+		@Override
+		protected Control createExtendedContentArea(Composite parent) {
+			return null;
+		}
+
+		@Override
+		protected ItemsFilter createFilter() {
+			return new ConnectionItemsFilter();
+		}
+
+		@Override
+		protected void fillContentProvider(AbstractContentProvider provider,
+		                                   ItemsFilter itemsFilter,
+		                                   IProgressMonitor monitor) throws CoreException {
+
+			monitor.beginTask(null, -1);
+
+			try {
+				// Add the connection names to the dialog
+				for (String name : this.getConnectionProfileNames()) {
+					provider.add(name, itemsFilter);
+				}
+			}
+			finally {
+				monitor.done();
+			}
+		}
+
+		private Iterable<String> getConnectionProfileNames() {
+			return JdbcConnectionPropertiesComposite.this.getConnectionProfileFactory().getConnectionProfileNames();
+		}
+
+		@Override
+		protected IDialogSettings getDialogSettings() {
+
+			IDialogSettings dialogSettings = JptUiPlugin.instance().getDialogSettings();
+			IDialogSettings settings = dialogSettings.getSection(DIALOG_SETTINGS);
+
+			if (settings == null) {
+				settings = dialogSettings.addNewSection(DIALOG_SETTINGS);
+			}
+			return settings;
+		}
+
+		@Override
+		public String getElementName(Object object) {
+			return object.toString();
+		}
+
+		@Override
+		protected Comparator<String> getItemsComparator() {
+			return new Comparator<String>() {
+				public int compare(String item1, String item2) {
+					return item1.compareTo(item2);
+				}
+			};
+		}
+
+		@Override
+		protected IStatus validateItem(Object item) {
+
+			if (item == null) {
+				return new Status(IStatus.ERROR, JptUiPlugin.PLUGIN_ID, IStatus.ERROR, "", null);
+			}
+			return Status.OK_STATUS;
+		}
+
+		/**
+		 * Create the filter responsible to remove any connection name based on
+		 * the pattern entered in the text field.
+		 */
+		private class ConnectionItemsFilter extends ItemsFilter {
+
+			/**
+			 * Creates a new <code>ConnectionItemsFilter</code>.
+			 */
+			ConnectionItemsFilter() {
+
+				super();
+
+				// Make sure that if the pattern is empty, we specify * in order
+				// to show all the mapping types
+				if (StringTools.stringIsEmpty(getPattern())) {
+					patternMatcher.setPattern("*");
+				}
+			}
+
+			/*
+			 * (non-Javadoc)
+			 */
+			@Override
+			public boolean isConsistentItem(Object item) {
+				return true;
+			}
+
+			/*
+			 * (non-Javadoc)
+			 */
+			@Override
+			public boolean matchItem(Object item) {
+				return matches(item.toString());
+			}
+		}
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/persistence/connection/JdbcDriverComposite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/persistence/connection/JdbcDriverComposite.java
new file mode 100644
index 0000000..ffeadfe
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/persistence/connection/JdbcDriverComposite.java
@@ -0,0 +1,93 @@
+/*******************************************************************************
+* Copyright (c) 2009, 2010 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.ui.internal.jpa2.persistence.connection;
+
+import org.eclipse.jpt.core.JpaProject;
+import org.eclipse.jpt.core.jpa2.context.persistence.connection.JpaConnection2_0;
+import org.eclipse.jpt.ui.internal.jpa2.persistence.JptUiPersistence2_0Messages;
+import org.eclipse.jpt.ui.internal.widgets.ClassChooserPane;
+import org.eclipse.jpt.ui.internal.widgets.Pane;
+import org.eclipse.jpt.utility.internal.model.value.PropertyAspectAdapter;
+import org.eclipse.jpt.utility.model.value.WritablePropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ *  JdbcDriverComposite
+ */
+public class JdbcDriverComposite extends Pane<JpaConnection2_0>
+{
+	/**
+	 * Creates a new <code>JdbcDriverComposite</code>.
+	 *
+	 * @param parentPane The parent pane of this one
+	 * @param parent The parent container
+	 */
+	public JdbcDriverComposite(Pane<? extends JpaConnection2_0> parentPane,
+                           Composite parent) {
+
+		super(parentPane, parent);
+	}
+
+	private ClassChooserPane<JpaConnection2_0> initializeClassChooser(Composite container) {
+
+		return new ClassChooserPane<JpaConnection2_0>(this, container) {
+
+			@Override
+			protected WritablePropertyValueModel<String> buildTextHolder() {
+				return new PropertyAspectAdapter<JpaConnection2_0, String>(
+							this.getSubjectHolder(), JpaConnection2_0.DRIVER_PROPERTY) {
+					@Override
+					protected String buildValue_() {
+						return this.subject.getDriver();
+					}
+
+					@Override
+					protected void setValue_(String value) {
+
+						if (value.length() == 0) {
+							value = null;
+						}
+						this.subject.setDriver(value);
+					}
+				};
+			}
+
+			@Override
+			protected String getClassName() {
+				return this.getSubject().getDriver();
+			}
+
+			@Override
+			protected String getLabelText() {
+				return JptUiPersistence2_0Messages.JdbcConnectionPropertiesComposite_driverLabel;
+			}
+			
+			@Override
+			protected JpaProject getJpaProject() {
+				return this.getSubject().getJpaProject();
+			}
+			@Override
+			protected void setClassName(String className) {
+				this.getSubject().setDriver(className);				
+			}
+			
+			@Override
+			protected boolean allowTypeCreation() {
+				//Does not make sense to allow the user to create a new Driver class
+				return false;
+			}
+		};
+	}
+
+	@Override
+	protected void initializeLayout(Composite container) {
+		this.initializeClassChooser(container);
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/persistence/connection/JdbcPropertiesComposite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/persistence/connection/JdbcPropertiesComposite.java
new file mode 100644
index 0000000..2318630
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/persistence/connection/JdbcPropertiesComposite.java
@@ -0,0 +1,79 @@
+/*******************************************************************************
+* Copyright (c) 2009, 2010 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.ui.internal.jpa2.persistence.connection;
+
+import org.eclipse.jpt.core.context.persistence.PersistenceUnit;
+import org.eclipse.jpt.core.context.persistence.PersistenceUnitTransactionType;
+import org.eclipse.jpt.core.jpa2.context.persistence.connection.JpaConnection2_0;
+import org.eclipse.jpt.ui.internal.jpa2.persistence.JptUiPersistence2_0Messages;
+import org.eclipse.jpt.ui.internal.util.PaneEnabler;
+import org.eclipse.jpt.ui.internal.widgets.Pane;
+import org.eclipse.jpt.utility.internal.model.value.PropertyAspectAdapter;
+import org.eclipse.jpt.utility.internal.model.value.TransformationPropertyValueModel;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ *  JdbcPropertiesComposite
+ */
+public class JdbcPropertiesComposite extends Pane<JpaConnection2_0>
+{
+	public JdbcPropertiesComposite(Pane<JpaConnection2_0> parentComposite, Composite parent) {
+
+		super(parentComposite, parent);
+	}
+
+	private PropertyValueModel<Boolean> buildPaneEnablerHolder() {
+		return new TransformationPropertyValueModel<PersistenceUnitTransactionType, Boolean>(buildTransactionTypeHolder()) {
+			@Override
+			protected Boolean transform(PersistenceUnitTransactionType value) {
+				return value == PersistenceUnitTransactionType.RESOURCE_LOCAL;
+			}
+		};
+	}
+
+	private PropertyValueModel<PersistenceUnitTransactionType> buildTransactionTypeHolder() {
+		return new PropertyAspectAdapter<PersistenceUnit, PersistenceUnitTransactionType>(
+			buildPersistenceUnitHolder(), 
+			PersistenceUnit.SPECIFIED_TRANSACTION_TYPE_PROPERTY, 
+			PersistenceUnit.DEFAULT_TRANSACTION_TYPE_PROPERTY) {
+			@Override
+			protected PersistenceUnitTransactionType buildValue_() {
+				return this.subject.getTransactionType();
+			}
+		};
+	}
+
+	private PropertyValueModel<PersistenceUnit> buildPersistenceUnitHolder() {
+		return new PropertyAspectAdapter<JpaConnection2_0, PersistenceUnit>(getSubjectHolder()) {
+			@Override
+			protected PersistenceUnit buildValue_() {
+				return this.subject.getPersistenceUnit();
+			}
+		};
+	}
+
+	@Override
+	protected void initializeLayout(Composite container) {
+
+		container = addTitledGroup(
+			addSubPane(container, 10),
+			JptUiPersistence2_0Messages.JdbcPropertiesComposite_JdbcConnectionProperties_GroupBox
+		);
+
+		new JdbcConnectionPropertiesComposite(this, container);
+
+		this.installPaneEnabler();
+	}
+
+	private void installPaneEnabler() {
+		new PaneEnabler(buildPaneEnablerHolder(), this);
+	}
+}
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/persistence/connection/TransactionTypeComposite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/persistence/connection/TransactionTypeComposite.java
new file mode 100644
index 0000000..9eefaa4
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/persistence/connection/TransactionTypeComposite.java
@@ -0,0 +1,123 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2010 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.ui.internal.jpa2.persistence.connection;
+
+import java.util.Collection;
+
+import org.eclipse.jpt.core.context.persistence.PersistenceUnit;
+import org.eclipse.jpt.core.context.persistence.PersistenceUnitTransactionType;
+import org.eclipse.jpt.core.jpa2.context.persistence.connection.JpaConnection2_0;
+import org.eclipse.jpt.ui.internal.JpaHelpContextIds;
+import org.eclipse.jpt.ui.internal.jpa2.persistence.JptUiPersistence2_0Messages;
+import org.eclipse.jpt.ui.internal.widgets.EnumFormComboViewer;
+import org.eclipse.jpt.ui.internal.widgets.Pane;
+import org.eclipse.jpt.utility.internal.model.value.PropertyAspectAdapter;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ *  TransactionTypeComposite
+ */
+public class TransactionTypeComposite extends Pane<JpaConnection2_0>
+{
+	/**
+	 * Creates a new <code>TransactionTypeComposite</code>.
+	 *
+	 * @param parentController
+	 *            The parent container of this one
+	 * @param parent
+	 *            The parent container
+	 */
+	public TransactionTypeComposite(
+					Pane<? extends JpaConnection2_0> parentComposite,
+					Composite parent) {
+
+		super( parentComposite, parent);
+	}
+
+	private EnumFormComboViewer<PersistenceUnit, PersistenceUnitTransactionType> buildTransactionTypeCombo(Composite container) {
+
+		return new EnumFormComboViewer<PersistenceUnit, PersistenceUnitTransactionType>(this, 
+											this.buildPersistenceUnitHolder(), 
+											container) {
+			@Override
+			protected void addPropertyNames(Collection<String> propertyNames) {
+				super.addPropertyNames(propertyNames);
+				propertyNames.add(PersistenceUnit.SPECIFIED_TRANSACTION_TYPE_PROPERTY);
+				propertyNames.add(PersistenceUnit.DEFAULT_TRANSACTION_TYPE_PROPERTY);
+			}
+
+			@Override
+			protected PersistenceUnitTransactionType[] getChoices() {
+				return PersistenceUnitTransactionType.values();
+			}
+
+			@Override
+			protected PersistenceUnitTransactionType getDefaultValue() {
+				return this.getSubject().getDefaultTransactionType();
+			}
+
+			@Override
+			protected String displayString(PersistenceUnitTransactionType value) {
+				return this.buildDisplayString(JptUiPersistence2_0Messages.class, TransactionTypeComposite.this, value);
+			}
+
+			@Override
+			protected PersistenceUnitTransactionType getValue() {
+				return this.getSubject().getSpecifiedTransactionType();
+			}
+
+			@Override
+			protected void setValue(PersistenceUnitTransactionType value) {
+				this.getSubject().setSpecifiedTransactionType(value);
+
+				if (value == PersistenceUnitTransactionType.RESOURCE_LOCAL) {
+					clearJTAProperties();
+				}
+				else {
+					clearResourceLocalProperties();
+				}
+			}
+		};
+	}
+
+	private PropertyValueModel<PersistenceUnit> buildPersistenceUnitHolder() {
+		return new PropertyAspectAdapter<JpaConnection2_0, PersistenceUnit>(this.getSubjectHolder()) {
+			@Override
+			protected PersistenceUnit buildValue_() {
+				return this.subject.getPersistenceUnit();
+			}
+		};
+	}
+
+	private void clearJTAProperties() {
+		this.getSubject().getPersistenceUnit().setJtaDataSource(null);
+	}
+
+	private void clearResourceLocalProperties() {
+		JpaConnection2_0 connection = this.getSubject();
+		connection.getPersistenceUnit().setNonJtaDataSource(null);
+		connection.setDriver(null);
+		connection.setUrl(null);
+		connection.setUser(null);
+		connection.setPassword(null);
+	}
+
+	@Override
+	protected void initializeLayout( Composite container) {
+
+		this.addLabeledComposite(
+			container,
+			JptUiPersistence2_0Messages.TransactionTypeComposite_transactionTypeLabel,
+			this.buildTransactionTypeCombo( container),
+			JpaHelpContextIds.PERSISTENCE_XML_CONNECTION	// TODO - Review for JPA 2.0
+		);
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/persistence/options/GenericPersistenceUnit2_0OptionsComposite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/persistence/options/GenericPersistenceUnit2_0OptionsComposite.java
new file mode 100644
index 0000000..5d3cf11
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/persistence/options/GenericPersistenceUnit2_0OptionsComposite.java
@@ -0,0 +1,63 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2010 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.ui.internal.jpa2.persistence.options;
+
+import org.eclipse.jpt.core.jpa2.context.persistence.options.JpaOptions2_0;
+import org.eclipse.jpt.ui.internal.jpa2.persistence.JptUiPersistence2_0Messages;
+import org.eclipse.jpt.ui.internal.widgets.Pane;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ *  GenericPersistenceUnit2_0OptionsComposite
+ */
+public class GenericPersistenceUnit2_0OptionsComposite extends Pane<JpaOptions2_0>
+{
+	public GenericPersistenceUnit2_0OptionsComposite(
+					Pane<JpaOptions2_0> subjectHolder,
+					Composite parent) {
+					
+		super(subjectHolder, parent, false);
+	}
+
+	@Override
+	protected void initializeLayout(Composite parent) {
+		this.initializeMiscellaneousPane(parent);
+	}
+
+	private void initializeMiscellaneousPane(Composite container) {	
+		
+		this.updateGridData(container);
+		this.updateGridData(container.getParent());
+		
+		Composite composite = this.addSection(container, 
+			JptUiPersistence2_0Messages.GenericPersistenceUnit2_0OptionsComposite_miscellaneousSectionTitle,
+			JptUiPersistence2_0Messages.GenericPersistenceUnit2_0OptionsComposite_miscellaneousSectionDescription);
+		
+		this.updateGridData(composite);
+		this.updateGridData(composite.getParent());
+
+		new LockingConfigurationComposite(this, composite);
+		new QueryConfigurationComposite(this, composite);
+		new ValidationConfigurationComposite(this, composite);
+
+	}
+
+	private void updateGridData(Composite container) {
+		GridData gridData = new GridData();
+		gridData.grabExcessHorizontalSpace = true;
+		gridData.grabExcessVerticalSpace = true;
+		gridData.horizontalAlignment = SWT.FILL;
+		gridData.verticalAlignment = SWT.FILL;
+		container.setLayoutData(gridData);
+	}
+
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/persistence/options/GenericPersistenceUnit2_0OptionsTab.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/persistence/options/GenericPersistenceUnit2_0OptionsTab.java
new file mode 100644
index 0000000..59f24a9
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/persistence/options/GenericPersistenceUnit2_0OptionsTab.java
@@ -0,0 +1,90 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2010 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.ui.internal.jpa2.persistence.options;
+
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jpt.core.jpa2.context.persistence.options.JpaOptions2_0;
+import org.eclipse.jpt.ui.WidgetFactory;
+import org.eclipse.jpt.ui.details.JpaPageComposite;
+import org.eclipse.jpt.ui.internal.jpa2.persistence.JptUiPersistence2_0Messages;
+import org.eclipse.jpt.ui.internal.widgets.Pane;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ *  GenericPersistenceUnit2_0OptionsTab
+ */
+public class GenericPersistenceUnit2_0OptionsTab extends Pane<JpaOptions2_0>
+	implements JpaPageComposite
+{
+	// ********** constructors/initialization **********
+	/**
+	 * Creates a new <code>GenericPersistenceUnit2_0OptionsTab</code>.
+	 *
+	 * @param subjectHolder The holder of this pane's subject
+	 * @param parent The parent container
+	 * @param widgetFactory The factory used to create various common widgets
+	 */
+	public GenericPersistenceUnit2_0OptionsTab(
+											PropertyValueModel<JpaOptions2_0> subjectHolder,
+	                                        Composite parent,
+	                                        WidgetFactory widgetFactory) {
+
+		super(subjectHolder, parent, widgetFactory);
+	}
+
+	@Override
+	protected void initializeLayout(Composite parent) {
+		new GenericPersistenceUnit2_0OptionsComposite(this, parent);
+
+	}
+
+	// ********** Layout **********
+	@Override
+	protected Composite addContainer(Composite parent) {
+		GridLayout layout = new GridLayout(1, true);
+		layout.marginHeight = 0;
+		layout.marginWidth = 0;
+		layout.marginTop = 0;
+		layout.marginLeft = 0;
+		layout.marginBottom = 0;
+		layout.marginRight = 0;
+		layout.verticalSpacing = 15;
+		Composite container = this.addPane(parent, layout);
+		updateGridData(container);
+		return container;
+	}
+
+	private void updateGridData(Composite container) {
+		GridData gridData = new GridData();
+		gridData.grabExcessHorizontalSpace = true;
+		gridData.grabExcessVerticalSpace = true;
+		gridData.horizontalAlignment = SWT.FILL;
+		gridData.verticalAlignment = SWT.FILL;
+		container.setLayoutData(gridData);
+	}
+
+	// ********** JpaPageComposite implementation **********
+
+	public String getHelpID() {
+		return null;						// TODO - Review for JPA 2.0
+	}
+	
+	public ImageDescriptor getPageImageDescriptor() {
+		return null;
+	}
+
+	public String getPageText() {
+		return JptUiPersistence2_0Messages.GenericPersistenceUnit2_0OptionsTab_title;
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/persistence/options/LockingConfigurationComposite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/persistence/options/LockingConfigurationComposite.java
new file mode 100644
index 0000000..9c39925
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/persistence/options/LockingConfigurationComposite.java
@@ -0,0 +1,85 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2010 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.ui.internal.jpa2.persistence.options;
+
+import org.eclipse.jpt.core.jpa2.context.persistence.options.JpaOptions2_0;
+import org.eclipse.jpt.ui.internal.jpa2.persistence.JptUiPersistence2_0Messages;
+import org.eclipse.jpt.ui.internal.widgets.IntegerCombo;
+import org.eclipse.jpt.ui.internal.widgets.Pane;
+import org.eclipse.jpt.utility.internal.model.value.PropertyAspectAdapter;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.jpt.utility.model.value.WritablePropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ *  LockingConfigurationComposite
+ */
+public class LockingConfigurationComposite extends Pane<JpaOptions2_0>
+{
+	/**
+	 * Creates a new <code>LockingConfigurationComposite</code>.
+	 *
+	 * @param parentController
+	 *            The parent container of this one
+	 * @param parent
+	 *            The parent container
+	 */
+	public LockingConfigurationComposite(
+					Pane<? extends JpaOptions2_0> parentComposite,
+					Composite parent) {
+
+		super(parentComposite, parent);
+	}
+
+	@Override
+	protected void initializeLayout(Composite parent) {
+		this.addLockTimeoutCombo(parent);
+	}
+	
+	private void addLockTimeoutCombo(Composite parent) {
+		new IntegerCombo<JpaOptions2_0>(this, parent) {
+			
+			@Override
+			protected String getLabelText() {
+				return JptUiPersistence2_0Messages.LockingConfigurationComposite_lockTimeoutLabel;
+			}
+		
+			@Override
+			protected String getHelpId() {
+				return null;		// TODO
+			}
+			
+			@Override
+			protected PropertyValueModel<Integer> buildDefaultHolder() {
+				return new PropertyAspectAdapter<JpaOptions2_0, Integer>(this.getSubjectHolder()) {
+					@Override
+					protected Integer buildValue_() {
+						return this.subject.getDefaultLockTimeout();
+					}
+				};
+			}
+			
+			@Override
+			protected WritablePropertyValueModel<Integer> buildSelectedItemHolder() {
+				return new PropertyAspectAdapter<JpaOptions2_0, Integer>(this.getSubjectHolder(), JpaOptions2_0.LOCK_TIMEOUT_PROPERTY) {
+					@Override
+					protected Integer buildValue_() {
+						return this.subject.getLockTimeout();
+					}
+
+					@Override
+					protected void setValue_(Integer value) {
+						this.subject.setLockTimeout(value);
+					}
+				};
+			}
+		};
+	}
+}
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/persistence/options/QueryConfigurationComposite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/persistence/options/QueryConfigurationComposite.java
new file mode 100644
index 0000000..b3398c6
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/persistence/options/QueryConfigurationComposite.java
@@ -0,0 +1,85 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2010 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.ui.internal.jpa2.persistence.options;
+
+import org.eclipse.jpt.core.jpa2.context.persistence.options.JpaOptions2_0;
+import org.eclipse.jpt.ui.internal.jpa2.persistence.JptUiPersistence2_0Messages;
+import org.eclipse.jpt.ui.internal.widgets.IntegerCombo;
+import org.eclipse.jpt.ui.internal.widgets.Pane;
+import org.eclipse.jpt.utility.internal.model.value.PropertyAspectAdapter;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.jpt.utility.model.value.WritablePropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ *  QueryConfigurationComposite
+ */
+public class QueryConfigurationComposite extends Pane<JpaOptions2_0>
+{
+	/**
+	 * Creates a new <code>QueryConfigurationComposite</code>.
+	 *
+	 * @param parentController
+	 *            The parent container of this one
+	 * @param parent
+	 *            The parent container
+	 */
+	public QueryConfigurationComposite(
+					Pane<? extends JpaOptions2_0> parentComposite,
+					Composite parent) {
+
+		super(parentComposite, parent);
+	}
+
+	@Override
+	protected void initializeLayout(Composite parent) {
+		this.addQueryTimeoutCombo(parent);
+	}
+	
+	private void addQueryTimeoutCombo(Composite parent) {
+		new IntegerCombo<JpaOptions2_0>(this, parent) {
+			
+			@Override
+			protected String getLabelText() {
+				return JptUiPersistence2_0Messages.QueryConfigurationComposite_queryTimeoutLabel;
+			}
+		
+			@Override
+			protected String getHelpId() {
+				return null;		// TODO
+			}
+			
+			@Override
+			protected PropertyValueModel<Integer> buildDefaultHolder() {
+				return new PropertyAspectAdapter<JpaOptions2_0, Integer>(this.getSubjectHolder()) {
+					@Override
+					protected Integer buildValue_() {
+						return this.subject.getDefaultQueryTimeout();
+					}
+				};
+			}
+			
+			@Override
+			protected WritablePropertyValueModel<Integer> buildSelectedItemHolder() {
+				return new PropertyAspectAdapter<JpaOptions2_0, Integer>(this.getSubjectHolder(), JpaOptions2_0.QUERY_TIMEOUT_PROPERTY) {
+					@Override
+					protected Integer buildValue_() {
+						return this.subject.getQueryTimeout();
+					}
+
+					@Override
+					protected void setValue_(Integer value) {
+						this.subject.setQueryTimeout(value);
+					}
+				};
+			}
+		};
+	}
+}
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/persistence/options/SharedCacheModeComposite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/persistence/options/SharedCacheModeComposite.java
new file mode 100644
index 0000000..6520a0c
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/persistence/options/SharedCacheModeComposite.java
@@ -0,0 +1,94 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2010 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.ui.internal.jpa2.persistence.options;
+
+import java.util.Collection;
+
+import org.eclipse.jpt.core.jpa2.context.persistence.PersistenceUnit2_0;
+import org.eclipse.jpt.core.jpa2.context.persistence.options.SharedCacheMode;
+import org.eclipse.jpt.ui.internal.jpa2.persistence.JptUiPersistence2_0Messages;
+import org.eclipse.jpt.ui.internal.widgets.EnumFormComboViewer;
+import org.eclipse.jpt.ui.internal.widgets.Pane;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ *  SharedCacheModeComposite
+ */
+public class SharedCacheModeComposite extends Pane<PersistenceUnit2_0>
+{
+	/**
+	 * Creates a new <code>SharedCacheModeComposite</code>.
+	 * 
+	 * @param parentController
+	 *            The parent container of this one
+	 * @param parent
+	 *            The parent container
+	 */
+	public SharedCacheModeComposite(
+					Pane<?> parentPane,
+			        PropertyValueModel<? extends PersistenceUnit2_0> subjectHolder,
+			        Composite parent) {
+
+	super(parentPane, subjectHolder, parent);
+	}
+
+	@Override
+	protected void initializeLayout(Composite parent) {
+		
+		this.addLabeledComposite(
+			parent,
+			JptUiPersistence2_0Messages.SharedCacheModeComposite_sharedCacheModeLabel,
+			this.addSharedCacheModeCombo(parent),
+			null			// TODO
+		);
+	}
+	
+	private EnumFormComboViewer<PersistenceUnit2_0, SharedCacheMode> addSharedCacheModeCombo(Composite parent) {
+		
+		return new EnumFormComboViewer<PersistenceUnit2_0, SharedCacheMode>(this, this.getSubjectHolder(), parent) {
+			@Override
+			protected void addPropertyNames(Collection<String> propertyNames) {
+				super.addPropertyNames(propertyNames);
+				propertyNames.add(PersistenceUnit2_0.SPECIFIED_SHARED_CACHE_MODE_PROPERTY);
+			}
+			
+			@Override
+			protected SharedCacheMode[] getChoices() {
+				return SharedCacheMode.values();
+			}
+			
+			@Override
+			protected boolean sortChoices() {
+				return false;
+			}
+			
+			@Override
+			protected SharedCacheMode getDefaultValue() {
+				return this.getSubject().getDefaultSharedCacheMode();
+			}
+
+			@Override
+			protected String displayString(SharedCacheMode value) {
+				return this.buildDisplayString(JptUiPersistence2_0Messages.class, SharedCacheModeComposite.this, value);
+			}
+
+			@Override
+			protected SharedCacheMode getValue() {
+				return this.getSubject().getSpecifiedSharedCacheMode();
+			}
+
+			@Override
+			protected void setValue(SharedCacheMode value) {
+				this.getSubject().setSpecifiedSharedCacheMode(value);
+			}
+		};
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/persistence/options/ValidationConfigurationComposite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/persistence/options/ValidationConfigurationComposite.java
new file mode 100644
index 0000000..3e944bd
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/persistence/options/ValidationConfigurationComposite.java
@@ -0,0 +1,131 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2010 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.ui.internal.jpa2.persistence.options;
+
+import org.eclipse.jpt.core.jpa2.context.persistence.PersistenceUnit2_0;
+import org.eclipse.jpt.core.jpa2.context.persistence.options.JpaOptions2_0;
+import org.eclipse.jpt.ui.internal.jpa2.persistence.JptUiPersistence2_0Messages;
+import org.eclipse.jpt.ui.internal.widgets.Pane;
+import org.eclipse.jpt.utility.internal.model.value.PropertyAspectAdapter;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.jpt.utility.model.value.WritablePropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ *  ValidationConfigurationComposite
+ */
+public class ValidationConfigurationComposite extends Pane<JpaOptions2_0>
+{
+	/**
+	 * Creates a new <code>ValidationGroupComposite</code>.
+	 *
+	 * @param parentController
+	 *            The parent container of this one
+	 * @param parent
+	 *            The parent container
+	 */
+	public ValidationConfigurationComposite(
+					Pane<? extends JpaOptions2_0> parentComposite,
+					Composite parent) {
+
+		super(parentComposite, parent);
+	}
+
+	@Override
+	protected void initializeLayout(Composite parent) {
+
+		// SharedCacheMode
+		new SharedCacheModeComposite(this, this.buildPersistenceUnit2_0Holder(), parent);
+
+		// ValidationMode
+		new ValidationModeComposite(this, this.buildPersistenceUnit2_0Holder(), parent);
+		
+		// GroupPrePersist
+		this.addLabeledText(
+			parent,
+			JptUiPersistence2_0Messages.ValidationConfigurationComposite_groupPrePersistLabel,
+			this.buildValidationGroupPrePersistHolder()
+		);
+
+		// ValidationGroupPreUpdate
+		this.addLabeledText(
+			parent,
+			JptUiPersistence2_0Messages.ValidationConfigurationComposite_groupPreUpdateLabel,
+			this.buildValidationGroupPreUpdateHolder()
+		);
+
+		// ValidationGroupPreRemove
+		this.addLabeledText(
+			parent,
+			JptUiPersistence2_0Messages.ValidationConfigurationComposite_groupPreRemoveLabel,
+			this.buildValidationGroupPreRemoveHolder()
+		);
+	}
+	
+	private PropertyValueModel<PersistenceUnit2_0> buildPersistenceUnit2_0Holder() {
+		return new PropertyAspectAdapter<JpaOptions2_0, PersistenceUnit2_0>(this.getSubjectHolder()) {
+			@Override
+			protected PersistenceUnit2_0 buildValue_() {
+				return (PersistenceUnit2_0) this.subject.getPersistenceUnit();
+			}
+		};
+	}
+
+	private WritablePropertyValueModel<String> buildValidationGroupPrePersistHolder() {
+		return new PropertyAspectAdapter<JpaOptions2_0, String>(this.getSubjectHolder(), JpaOptions2_0.VALIDATION_GROUP_PRE_PERSIST_PROPERTY) {
+			@Override
+			protected String buildValue_() {
+				return this.subject.getValidationGroupPrePersist();
+			}
+
+			@Override
+			protected void setValue_(String value) {
+				if (value.length() == 0) {
+					value = null;
+				}
+				this.subject.setValidationGroupPrePersist(value);
+			}
+		};
+	}
+
+	private WritablePropertyValueModel<String> buildValidationGroupPreUpdateHolder() {
+		return new PropertyAspectAdapter<JpaOptions2_0, String>(this.getSubjectHolder(), JpaOptions2_0.VALIDATION_GROUP_PRE_UPDATE_PROPERTY) {
+			@Override
+			protected String buildValue_() {
+				return this.subject.getValidationGroupPreUpdate();
+			}
+
+			@Override
+			protected void setValue_(String value) {
+				if (value.length() == 0) {
+					value = null;
+				}
+				this.subject.setValidationGroupPreUpdate(value);
+			}
+		};
+	}
+
+	private WritablePropertyValueModel<String> buildValidationGroupPreRemoveHolder() {
+		return new PropertyAspectAdapter<JpaOptions2_0, String>(this.getSubjectHolder(), JpaOptions2_0.VALIDATION_GROUP_PRE_REMOVE_PROPERTY) {
+			@Override
+			protected String buildValue_() {
+				return this.subject.getValidationGroupPreRemove();
+			}
+
+			@Override
+			protected void setValue_(String value) {
+				if (value.length() == 0) {
+					value = null;
+				}
+				this.subject.setValidationGroupPreRemove(value);
+			}
+		};
+	}
+}
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/persistence/options/ValidationModeComposite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/persistence/options/ValidationModeComposite.java
new file mode 100644
index 0000000..ab8e792
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/persistence/options/ValidationModeComposite.java
@@ -0,0 +1,94 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2010 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.ui.internal.jpa2.persistence.options;
+
+import java.util.Collection;
+
+import org.eclipse.jpt.core.jpa2.context.persistence.PersistenceUnit2_0;
+import org.eclipse.jpt.core.jpa2.context.persistence.options.ValidationMode;
+import org.eclipse.jpt.ui.internal.jpa2.persistence.JptUiPersistence2_0Messages;
+import org.eclipse.jpt.ui.internal.widgets.EnumFormComboViewer;
+import org.eclipse.jpt.ui.internal.widgets.Pane;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ *  ValidationModeComposite
+ */
+public class ValidationModeComposite extends Pane<PersistenceUnit2_0>
+{
+	/**
+	 * Creates a new <code>ValidationModeComposite</code>.
+	 * 
+	 * @param parentController
+	 *            The parent container of this one
+	 * @param parent
+	 *            The parent container
+	 */
+	public ValidationModeComposite(
+					Pane<?> parentPane,
+			        PropertyValueModel<? extends PersistenceUnit2_0> subjectHolder,
+			        Composite parent) {
+
+	super(parentPane, subjectHolder, parent);
+	}
+
+	@Override
+	protected void initializeLayout(Composite parent) {
+		
+		this.addLabeledComposite(
+			parent,
+			JptUiPersistence2_0Messages.ValidationModeComposite_validationModeLabel,
+			this.addValidationModeCombo(parent),
+			null			// TODO
+		);
+	}
+	
+	private EnumFormComboViewer<PersistenceUnit2_0, ValidationMode> addValidationModeCombo(Composite parent) {
+		
+		return new EnumFormComboViewer<PersistenceUnit2_0, ValidationMode>(this, this.getSubjectHolder(), parent) {
+			@Override
+			protected void addPropertyNames(Collection<String> propertyNames) {
+				super.addPropertyNames(propertyNames);
+				propertyNames.add(PersistenceUnit2_0.SPECIFIED_VALIDATION_MODE_PROPERTY);
+			}
+			
+			@Override
+			protected ValidationMode[] getChoices() {
+				return ValidationMode.values();
+			}
+			
+			@Override
+			protected boolean sortChoices() {
+				return false;
+			}
+			
+			@Override
+			protected ValidationMode getDefaultValue() {
+				return this.getSubject().getDefaultValidationMode();
+			}
+
+			@Override
+			protected String displayString(ValidationMode value) {
+				return this.buildDisplayString(JptUiPersistence2_0Messages.class, ValidationModeComposite.this, value);
+			}
+
+			@Override
+			protected ValidationMode getValue() {
+				return this.getSubject().getSpecifiedValidationMode();
+			}
+
+			@Override
+			protected void setValue(ValidationMode value) {
+				this.getSubject().setSpecifiedValidationMode(value);
+			}
+		};
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/platform/generic/Generic2_0JpaPlatformUiFactory.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/platform/generic/Generic2_0JpaPlatformUiFactory.java
new file mode 100644
index 0000000..4525ce0
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/jpa2/platform/generic/Generic2_0JpaPlatformUiFactory.java
@@ -0,0 +1,34 @@
+/*******************************************************************************
+ * Copyright (c) 2009 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.ui.internal.jpa2.platform.generic;
+
+import org.eclipse.jpt.ui.JpaPlatformUi;
+import org.eclipse.jpt.ui.JpaPlatformUiFactory;
+import org.eclipse.jpt.ui.internal.jpa2.Generic2_0JpaPlatformUiProvider;
+import org.eclipse.jpt.ui.internal.platform.generic.GenericJpaPlatformUi;
+import org.eclipse.jpt.ui.internal.platform.generic.GenericNavigatorProvider;
+
+public class Generic2_0JpaPlatformUiFactory implements JpaPlatformUiFactory
+{
+
+	/**
+	 * Zero arg constructor for extension point
+	 */
+	public Generic2_0JpaPlatformUiFactory() {
+		super();
+	}
+
+	public JpaPlatformUi buildJpaPlatformUi() {
+		return new GenericJpaPlatformUi(
+			new GenericNavigatorProvider(),
+			Generic2_0JpaPlatformUiProvider.instance()
+		);
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/listeners/SWTCollectionChangeListenerWrapper.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/listeners/SWTCollectionChangeListenerWrapper.java
new file mode 100644
index 0000000..048c9f2
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/listeners/SWTCollectionChangeListenerWrapper.java
@@ -0,0 +1,154 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 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.ui.internal.listeners;
+
+import org.eclipse.jpt.utility.model.event.CollectionAddEvent;
+import org.eclipse.jpt.utility.model.event.CollectionChangeEvent;
+import org.eclipse.jpt.utility.model.event.CollectionClearEvent;
+import org.eclipse.jpt.utility.model.event.CollectionRemoveEvent;
+import org.eclipse.jpt.utility.model.listener.CollectionChangeListener;
+import org.eclipse.swt.widgets.Display;
+
+/**
+ * Wrap another collection change listener and forward events to it on the SWT
+ * UI thread, asynchronously if necessary. If the event arrived on the UI
+ * thread that is probably because it was initiated by a UI widget; as a
+ * result, we want to loop back synchronously so the events can be
+ * short-circuited.
+ */
+public class SWTCollectionChangeListenerWrapper
+	implements CollectionChangeListener
+{
+	private final CollectionChangeListener listener;
+
+	public SWTCollectionChangeListenerWrapper(CollectionChangeListener listener) {
+		super();
+		if (listener == null) {
+			throw new NullPointerException();
+		}
+		this.listener = listener;
+	}
+
+	public void itemsAdded(CollectionAddEvent event) {
+		if (this.isExecutingOnUIThread()) {
+			this.itemsAdded_(event);
+		} else {
+			this.executeOnUIThread(this.buildItemsAddedRunnable(event));
+		}
+	}
+
+	public void itemsRemoved(CollectionRemoveEvent event) {
+		if (this.isExecutingOnUIThread()) {
+			this.itemsRemoved_(event);
+		} else {
+			this.executeOnUIThread(this.buildItemsRemovedRunnable(event));
+		}
+	}
+
+	public void collectionCleared(CollectionClearEvent event) {
+		if (this.isExecutingOnUIThread()) {
+			this.collectionCleared_(event);
+		} else {
+			this.executeOnUIThread(this.buildCollectionClearedRunnable(event));
+		}
+	}
+
+	public void collectionChanged(CollectionChangeEvent event) {
+		if (this.isExecutingOnUIThread()) {
+			this.collectionChanged_(event);
+		} else {
+			this.executeOnUIThread(this.buildCollectionChangedRunnable(event));
+		}
+	}
+
+	private Runnable buildItemsAddedRunnable(final CollectionAddEvent event) {
+		return new Runnable() {
+			public void run() {
+				SWTCollectionChangeListenerWrapper.this.itemsAdded_(event);
+			}
+			@Override
+			public String toString() {
+				return "items added"; //$NON-NLS-1$
+			}
+		};
+	}
+
+	private Runnable buildItemsRemovedRunnable(final CollectionRemoveEvent event) {
+		return new Runnable() {
+			public void run() {
+				SWTCollectionChangeListenerWrapper.this.itemsRemoved_(event);
+			}
+			@Override
+			public String toString() {
+				return "items removed"; //$NON-NLS-1$
+			}
+		};
+	}
+
+	private Runnable buildCollectionClearedRunnable(final CollectionClearEvent event) {
+		return new Runnable() {
+			public void run() {
+				SWTCollectionChangeListenerWrapper.this.collectionCleared_(event);
+			}
+			@Override
+			public String toString() {
+				return "collection cleared"; //$NON-NLS-1$
+			}
+		};
+	}
+
+	private Runnable buildCollectionChangedRunnable(final CollectionChangeEvent event) {
+		return new Runnable() {
+			public void run() {
+				SWTCollectionChangeListenerWrapper.this.collectionChanged_(event);
+			}
+			@Override
+			public String toString() {
+				return "collection changed"; //$NON-NLS-1$
+			}
+		};
+	}
+
+	private boolean isExecutingOnUIThread() {
+		return Display.getCurrent() != null;
+	}
+
+	/**
+	 * {@link Display#asyncExec(Runnable)} seems to work OK;
+	 * but using {@link Display#syncExec(Runnable)} can somtimes make things
+	 * more predictable when debugging, at the risk of deadlocks.
+	 */
+	private void executeOnUIThread(Runnable r) {
+		Display.getDefault().asyncExec(r);
+//		Display.getDefault().syncExec(r);
+	}
+
+	void itemsAdded_(CollectionAddEvent event) {
+		this.listener.itemsAdded(event);
+	}
+
+	void itemsRemoved_(CollectionRemoveEvent event) {
+		this.listener.itemsRemoved(event);
+	}
+
+	void collectionCleared_(CollectionClearEvent event) {
+		this.listener.collectionCleared(event);
+	}
+
+	void collectionChanged_(CollectionChangeEvent event) {
+		this.listener.collectionChanged(event);
+	}
+
+	@Override
+	public String toString() {
+		return "SWT(" + this.listener.toString() + ')'; //$NON-NLS-1$
+	}
+
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/listeners/SWTConnectionListenerWrapper.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/listeners/SWTConnectionListenerWrapper.java
new file mode 100644
index 0000000..6022355
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/listeners/SWTConnectionListenerWrapper.java
@@ -0,0 +1,351 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2010 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.ui.internal.listeners;
+
+import org.eclipse.jpt.db.Catalog;
+import org.eclipse.jpt.db.Column;
+import org.eclipse.jpt.db.ConnectionListener;
+import org.eclipse.jpt.db.ConnectionProfile;
+import org.eclipse.jpt.db.Database;
+import org.eclipse.jpt.db.ForeignKey;
+import org.eclipse.jpt.db.Schema;
+import org.eclipse.jpt.db.Sequence;
+import org.eclipse.jpt.db.Table;
+import org.eclipse.swt.widgets.Display;
+
+/**
+ * Wrap another connection listener and forward events to it on the SWT
+ * UI thread, asynchronously if necessary. If the event arrived on the UI
+ * thread that is probably because it was initiated by a UI widget; as a
+ * result, we want to loop back synchronously so the events can be
+ * short-circuited.
+ */
+public class SWTConnectionListenerWrapper
+	implements ConnectionListener
+{
+
+	private final ConnectionListener listener;
+
+	public SWTConnectionListenerWrapper(ConnectionListener listener) {
+		super();
+		if (listener == null) {
+			throw new NullPointerException();
+		}
+		this.listener = listener;
+	}
+
+	public void opened(ConnectionProfile profile) {
+		if (this.isExecutingOnUIThread()) {
+			this.opened_(profile);
+		} else {
+			this.executeOnUIThread(this.buildOpenedRunnable(profile));
+		}
+	}
+
+	public void modified(ConnectionProfile profile) {
+		if (this.isExecutingOnUIThread()) {
+			this.modified_(profile);
+		} else {
+			this.executeOnUIThread(this.buildModifiedRunnable(profile));
+		}
+	}
+
+	public boolean okToClose(ConnectionProfile profile) {
+		if (this.isExecutingOnUIThread()) {
+			return this.okToClose_(profile);
+		}
+		this.executeOnUIThread(this.buildOkToCloseRunnable(profile));
+		return true;
+	}
+
+	public void aboutToClose(ConnectionProfile profile) {
+		if (this.isExecutingOnUIThread()) {
+			this.aboutToClose_(profile);
+		} else {
+			this.executeOnUIThread(this.buildAboutToCloseRunnable(profile));
+		}
+	}
+
+	public void closed(ConnectionProfile profile) {
+		if (this.isExecutingOnUIThread()) {
+			this.closed_(profile);
+		} else {
+			this.executeOnUIThread(this.buildClosedRunnable(profile));
+		}
+	}
+
+	public void databaseChanged(ConnectionProfile profile, Database database) {
+		if (this.isExecutingOnUIThread()) {
+			this.databaseChanged_(profile, database);
+		} else {
+			this.executeOnUIThread(this.buildDatabaseChangedRunnable(profile, database));
+		}
+	}
+
+	public void catalogChanged(ConnectionProfile profile, Catalog catalog) {
+		if (this.isExecutingOnUIThread()) {
+			this.catalogChanged_(profile, catalog);
+		} else {
+			this.executeOnUIThread(this.buildCatalogChangedRunnable(profile, catalog));
+		}
+	}
+
+	public void schemaChanged(ConnectionProfile profile, Schema schema) {
+		if (this.isExecutingOnUIThread()) {
+			this.schemaChanged_(profile, schema);
+		} else {
+			this.executeOnUIThread(this.buildSchemaChangedRunnable(profile, schema));
+		}
+	}
+
+	public void sequenceChanged(ConnectionProfile profile, Sequence sequence) {
+		if (this.isExecutingOnUIThread()) {
+			this.sequenceChanged_(profile, sequence);
+		} else {
+			this.executeOnUIThread(this.buildSequenceChangedRunnable(profile, sequence));
+		}
+	}
+
+	public void tableChanged(ConnectionProfile profile, Table table) {
+		if (this.isExecutingOnUIThread()) {
+			this.tableChanged_(profile, table);
+		} else {
+			this.executeOnUIThread(this.buildTableChangedRunnable(profile, table));
+		}
+	}
+
+	public void columnChanged(ConnectionProfile profile, Column column) {
+		if (this.isExecutingOnUIThread()) {
+			this.columnChanged_(profile, column);
+		} else {
+			this.executeOnUIThread(this.buildColumnChangedRunnable(profile, column));
+		}
+	}
+
+	public void foreignKeyChanged(ConnectionProfile profile, ForeignKey foreignKey) {
+		if (this.isExecutingOnUIThread()) {
+			this.foreignKeyChanged_(profile, foreignKey);
+		} else {
+			this.executeOnUIThread(this.buildForeignKeyChangedRunnable(profile, foreignKey));
+		}
+	}
+
+	private Runnable buildOpenedRunnable(final ConnectionProfile profile) {
+		return new Runnable() {
+			public void run() {
+				SWTConnectionListenerWrapper.this.opened_(profile);
+			}
+			@Override
+			public String toString() {
+				return "opened"; //$NON-NLS-1$
+			}
+		};
+	}
+
+	private Runnable buildModifiedRunnable(final ConnectionProfile profile) {
+		return new Runnable() {
+			public void run() {
+				SWTConnectionListenerWrapper.this.modified_(profile);
+			}
+			@Override
+			public String toString() {
+				return "modified"; //$NON-NLS-1$
+			}
+		};
+	}
+
+	private Runnable buildOkToCloseRunnable(final ConnectionProfile profile) {
+		return new Runnable() {
+			public void run() {
+				SWTConnectionListenerWrapper.this.okToClose_(profile);
+			}
+			@Override
+			public String toString() {
+				return "OK to close"; //$NON-NLS-1$
+			}
+		};
+	}
+
+	private Runnable buildAboutToCloseRunnable(final ConnectionProfile profile) {
+		return new Runnable() {
+			public void run() {
+				SWTConnectionListenerWrapper.this.aboutToClose_(profile);
+			}
+			@Override
+			public String toString() {
+				return "about to close"; //$NON-NLS-1$
+			}
+		};
+	}
+
+	private Runnable buildClosedRunnable(final ConnectionProfile profile) {
+		return new Runnable() {
+			public void run() {
+				SWTConnectionListenerWrapper.this.closed_(profile);
+			}
+			@Override
+			public String toString() {
+				return "closed"; //$NON-NLS-1$
+			}
+		};
+	}
+
+	private Runnable buildDatabaseChangedRunnable(final ConnectionProfile profile, final Database database) {
+		return new Runnable() {
+			public void run() {
+				SWTConnectionListenerWrapper.this.databaseChanged_(profile, database);
+			}
+			@Override
+			public String toString() {
+				return "database changed"; //$NON-NLS-1$
+			}
+		};
+	}
+
+	private Runnable buildCatalogChangedRunnable(final ConnectionProfile profile, final Catalog catalog) {
+		return new Runnable() {
+			public void run() {
+				SWTConnectionListenerWrapper.this.catalogChanged_(profile, catalog);
+			}
+			@Override
+			public String toString() {
+				return "catalog changed"; //$NON-NLS-1$
+			}
+		};
+	}
+
+	private Runnable buildSchemaChangedRunnable(final ConnectionProfile profile, final Schema schema) {
+		return new Runnable() {
+			public void run() {
+				SWTConnectionListenerWrapper.this.schemaChanged_(profile, schema);
+			}
+			@Override
+			public String toString() {
+				return "schema changed"; //$NON-NLS-1$
+			}
+		};
+	}
+
+	private Runnable buildSequenceChangedRunnable(final ConnectionProfile profile, final Sequence sequence) {
+		return new Runnable() {
+			public void run() {
+				SWTConnectionListenerWrapper.this.sequenceChanged_(profile, sequence);
+			}
+			@Override
+			public String toString() {
+				return "sequence changed"; //$NON-NLS-1$
+			}
+		};
+	}
+
+	private Runnable buildTableChangedRunnable(final ConnectionProfile profile, final Table table) {
+		return new Runnable() {
+			public void run() {
+				SWTConnectionListenerWrapper.this.tableChanged_(profile, table);
+			}
+			@Override
+			public String toString() {
+				return "table changed"; //$NON-NLS-1$
+			}
+		};
+	}
+
+	private Runnable buildColumnChangedRunnable(final ConnectionProfile profile, final Column column) {
+		return new Runnable() {
+			public void run() {
+				SWTConnectionListenerWrapper.this.columnChanged_(profile, column);
+			}
+			@Override
+			public String toString() {
+				return "column changed"; //$NON-NLS-1$
+			}
+		};
+	}
+
+	private Runnable buildForeignKeyChangedRunnable(final ConnectionProfile profile, final ForeignKey foreignKey) {
+		return new Runnable() {
+			public void run() {
+				SWTConnectionListenerWrapper.this.foreignKeyChanged_(profile, foreignKey);
+			}
+			@Override
+			public String toString() {
+				return "foreign key changed"; //$NON-NLS-1$
+			}
+		};
+	}
+
+	private boolean isExecutingOnUIThread() {
+		return Display.getCurrent() != null;
+	}
+
+	/**
+	 * {@link Display#asyncExec(Runnable)} seems to work OK;
+	 * but using {@link Display#syncExec(Runnable)} can somtimes make things
+	 * more predictable when debugging, at the risk of deadlocks.
+	 */
+	private void executeOnUIThread(Runnable r) {
+		Display.getDefault().asyncExec(r);
+//		Display.getDefault().syncExec(r);
+	}
+
+	void opened_(ConnectionProfile profile) {
+		this.listener.opened(profile);
+	}
+
+	void modified_(ConnectionProfile profile) {
+		this.listener.modified(profile);
+	}
+
+	boolean okToClose_(ConnectionProfile profile) {
+		return this.listener.okToClose(profile);
+	}
+
+	void aboutToClose_(ConnectionProfile profile) {
+		this.listener.aboutToClose(profile);
+	}
+
+	void closed_(ConnectionProfile profile) {
+		this.listener.closed(profile);
+	}
+
+	void databaseChanged_(ConnectionProfile profile, Database database) {
+		this.listener.databaseChanged(profile, database);
+	}
+
+	void catalogChanged_(ConnectionProfile profile, Catalog catalog) {
+		this.listener.catalogChanged(profile, catalog);
+	}
+
+	void schemaChanged_(ConnectionProfile profile, Schema schema) {
+		this.listener.schemaChanged(profile, schema);
+	}
+
+	void sequenceChanged_(ConnectionProfile profile, Sequence sequence) {
+		this.listener.sequenceChanged(profile, sequence);
+	}
+
+	void tableChanged_(ConnectionProfile profile, Table table) {
+		this.listener.tableChanged(profile, table);
+	}
+
+	void columnChanged_(ConnectionProfile profile, Column column) {
+		this.listener.columnChanged(profile, column);
+	}
+
+	void foreignKeyChanged_(ConnectionProfile profile, ForeignKey foreignKey) {
+		this.listener.foreignKeyChanged(profile, foreignKey);
+	}
+
+	@Override
+	public String toString() {
+		return "SWT(" + this.listener.toString() + ')'; //$NON-NLS-1$
+	}
+
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/listeners/SWTListChangeListenerWrapper.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/listeners/SWTListChangeListenerWrapper.java
new file mode 100644
index 0000000..c70b1d2
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/listeners/SWTListChangeListenerWrapper.java
@@ -0,0 +1,204 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 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.ui.internal.listeners;
+
+import org.eclipse.jpt.utility.model.event.ListAddEvent;
+import org.eclipse.jpt.utility.model.event.ListChangeEvent;
+import org.eclipse.jpt.utility.model.event.ListClearEvent;
+import org.eclipse.jpt.utility.model.event.ListMoveEvent;
+import org.eclipse.jpt.utility.model.event.ListRemoveEvent;
+import org.eclipse.jpt.utility.model.event.ListReplaceEvent;
+import org.eclipse.jpt.utility.model.listener.ListChangeListener;
+import org.eclipse.swt.widgets.Display;
+
+/**
+ * Wrap another list change listener and forward events to it on the SWT
+ * UI thread, asynchronously if necessary. If the event arrived on the UI
+ * thread that is probably because it was initiated by a UI widget; as a
+ * result, we want to loop back synchronously so the events can be
+ * short-circuited.
+ */
+public class SWTListChangeListenerWrapper
+	implements ListChangeListener
+{
+	private final ListChangeListener listener;
+
+	public SWTListChangeListenerWrapper(ListChangeListener listener) {
+		super();
+		if (listener == null) {
+			throw new NullPointerException();
+		}
+		this.listener = listener;
+	}
+
+	public void itemsAdded(ListAddEvent event) {
+		if (this.isExecutingOnUIThread()) {
+			this.itemsAdded_(event);
+		} else {
+			this.executeOnUIThread(this.buildItemsAddedRunnable(event));
+		}
+	}
+
+	public void itemsRemoved(ListRemoveEvent event) {
+		if (this.isExecutingOnUIThread()) {
+			this.itemsRemoved_(event);
+		} else {
+			this.executeOnUIThread(this.buildItemsRemovedRunnable(event));
+		}
+	}
+
+	public void itemsMoved(ListMoveEvent event) {
+		if (this.isExecutingOnUIThread()) {
+			this.itemsMoved_(event);
+		} else {
+			this.executeOnUIThread(this.buildItemsMovedRunnable(event));
+		}
+	}
+
+	public void itemsReplaced(ListReplaceEvent event) {
+		if (this.isExecutingOnUIThread()) {
+			this.itemsReplaced_(event);
+		} else {
+			this.executeOnUIThread(this.buildItemsReplacedRunnable(event));
+		}
+	}
+
+	public void listCleared(ListClearEvent event) {
+		if (this.isExecutingOnUIThread()) {
+			this.listCleared_(event);
+		} else {
+			this.executeOnUIThread(this.buildListClearedRunnable(event));
+		}
+	}
+
+	public void listChanged(ListChangeEvent event) {
+		if (this.isExecutingOnUIThread()) {
+			this.listChanged_(event);
+		} else {
+			this.executeOnUIThread(this.buildListChangedRunnable(event));
+		}
+	}
+
+	private Runnable buildItemsAddedRunnable(final ListAddEvent event) {
+		return new Runnable() {
+			public void run() {
+				SWTListChangeListenerWrapper.this.itemsAdded_(event);
+			}
+			@Override
+			public String toString() {
+				return "items added"; //$NON-NLS-1$
+			}
+		};
+	}
+
+	private Runnable buildItemsRemovedRunnable(final ListRemoveEvent event) {
+		return new Runnable() {
+			public void run() {
+				SWTListChangeListenerWrapper.this.itemsRemoved_(event);
+			}
+			@Override
+			public String toString() {
+				return "items removed"; //$NON-NLS-1$
+			}
+		};
+	}
+
+	private Runnable buildItemsMovedRunnable(final ListMoveEvent event) {
+		return new Runnable() {
+			public void run() {
+				SWTListChangeListenerWrapper.this.itemsMoved_(event);
+			}
+			@Override
+			public String toString() {
+				return "items moved"; //$NON-NLS-1$
+			}
+		};
+	}
+
+	private Runnable buildItemsReplacedRunnable(final ListReplaceEvent event) {
+		return new Runnable() {
+			public void run() {
+				SWTListChangeListenerWrapper.this.itemsReplaced_(event);
+			}
+			@Override
+			public String toString() {
+				return "items replaced"; //$NON-NLS-1$
+			}
+		};
+	}
+
+	private Runnable buildListClearedRunnable(final ListClearEvent event) {
+		return new Runnable() {
+			public void run() {
+				SWTListChangeListenerWrapper.this.listCleared_(event);
+			}
+			@Override
+			public String toString() {
+				return "list cleared"; //$NON-NLS-1$
+			}
+		};
+	}
+
+	private Runnable buildListChangedRunnable(final ListChangeEvent event) {
+		return new Runnable() {
+			public void run() {
+				SWTListChangeListenerWrapper.this.listChanged_(event);
+			}
+			@Override
+			public String toString() {
+				return "list changed"; //$NON-NLS-1$
+			}
+		};
+	}
+
+	private boolean isExecutingOnUIThread() {
+		return Display.getCurrent() != null;
+	}
+
+	/**
+	 * {@link Display#asyncExec(Runnable)} seems to work OK;
+	 * but using {@link Display#syncExec(Runnable)} can somtimes make things
+	 * more predictable when debugging, at the risk of deadlocks.
+	 */
+	private void executeOnUIThread(Runnable r) {
+		Display.getDefault().asyncExec(r);
+//		Display.getDefault().syncExec(r);
+	}
+
+	void itemsAdded_(ListAddEvent event) {
+		this.listener.itemsAdded(event);
+	}
+
+	void itemsRemoved_(ListRemoveEvent event) {
+		this.listener.itemsRemoved(event);
+	}
+
+	void itemsMoved_(ListMoveEvent event) {
+		this.listener.itemsMoved(event);
+	}
+
+	void itemsReplaced_(ListReplaceEvent event) {
+		this.listener.itemsReplaced(event);
+	}
+
+	void listCleared_(ListClearEvent event) {
+		this.listener.listCleared(event);
+	}
+
+	void listChanged_(ListChangeEvent event) {
+		this.listener.listChanged(event);
+	}
+
+	@Override
+	public String toString() {
+		return "SWT(" + this.listener.toString() + ')'; //$NON-NLS-1$
+	}
+
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/listeners/SWTPropertyChangeListenerWrapper.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/listeners/SWTPropertyChangeListenerWrapper.java
new file mode 100644
index 0000000..9a3221f
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/listeners/SWTPropertyChangeListenerWrapper.java
@@ -0,0 +1,75 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 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.ui.internal.listeners;
+
+import org.eclipse.jpt.utility.model.event.PropertyChangeEvent;
+import org.eclipse.jpt.utility.model.listener.PropertyChangeListener;
+import org.eclipse.swt.widgets.Display;
+
+/**
+ * Wrap another property change listener and forward events to it on the SWT
+ * UI thread, asynchronously if necessary. If the event arrived on the UI
+ * thread that is probably because it was initiated by a UI widget; as a
+ * result, we want to loop back synchronously so the events can be
+ * short-circuited.
+ */
+public class SWTPropertyChangeListenerWrapper
+	implements PropertyChangeListener
+{
+	private final PropertyChangeListener listener;
+
+	public SWTPropertyChangeListenerWrapper(PropertyChangeListener listener) {
+		super();
+		if (listener == null) {
+			throw new NullPointerException();
+		}
+		this.listener = listener;
+	}
+
+	public void propertyChanged(PropertyChangeEvent event) {
+		if (this.isExecutingOnUIThread()) {
+			this.propertyChanged_(event);
+		} else {
+			this.executeOnUIThread(this.buildPropertyChangedRunnable(event));
+		}
+	}
+
+	private Runnable buildPropertyChangedRunnable(final PropertyChangeEvent event) {
+		return new Runnable() {
+			public void run() {
+				SWTPropertyChangeListenerWrapper.this.propertyChanged_(event);
+			}
+		};
+	}
+
+	private boolean isExecutingOnUIThread() {
+		return Display.getCurrent() != null;
+	}
+
+	/**
+	 * {@link Display#asyncExec(Runnable)} seems to work OK;
+	 * but using {@link Display#syncExec(Runnable)} can somtimes make things
+	 * more predictable when debugging, at the risk of deadlocks.
+	 */
+	private void executeOnUIThread(Runnable r) {
+		Display.getDefault().asyncExec(r);
+//		Display.getDefault().syncExec(r);
+	}
+
+	void propertyChanged_(PropertyChangeEvent event) {
+		this.listener.propertyChanged(event);
+	}
+
+	@Override
+	public String toString() {
+		return "SWT(" + this.listener.toString() + ')'; //$NON-NLS-1$
+	}
+
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/listeners/SWTStateChangeListenerWrapper.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/listeners/SWTStateChangeListenerWrapper.java
new file mode 100644
index 0000000..122a410
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/listeners/SWTStateChangeListenerWrapper.java
@@ -0,0 +1,75 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 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.ui.internal.listeners;
+
+import org.eclipse.jpt.utility.model.event.StateChangeEvent;
+import org.eclipse.jpt.utility.model.listener.StateChangeListener;
+import org.eclipse.swt.widgets.Display;
+
+/**
+ * Wrap another state change listener and forward events to it on the SWT
+ * UI thread, asynchronously if necessary. If the event arrived on the UI
+ * thread that is probably because it was initiated by a UI widget; as a
+ * result, we want to loop back synchronously so the events can be
+ * short-circuited.
+ */
+public class SWTStateChangeListenerWrapper
+	implements StateChangeListener
+{
+	private final StateChangeListener listener;
+
+	public SWTStateChangeListenerWrapper(StateChangeListener listener) {
+		super();
+		if (listener == null) {
+			throw new NullPointerException();
+		}
+		this.listener = listener;
+	}
+
+	public void stateChanged(StateChangeEvent event) {
+		if (this.isExecutingOnUIThread()) {
+			this.stateChanged_(event);
+		} else {
+			this.executeOnUIThread(this.buildStateChangedRunnable(event));
+		}
+	}
+
+	private Runnable buildStateChangedRunnable(final StateChangeEvent event) {
+		return new Runnable() {
+			public void run() {
+				SWTStateChangeListenerWrapper.this.stateChanged_(event);
+			}
+		};
+	}
+
+	private boolean isExecutingOnUIThread() {
+		return Display.getCurrent() != null;
+	}
+
+	/**
+	 * {@link Display#asyncExec(Runnable)} seems to work OK;
+	 * but using {@link Display#syncExec(Runnable)} can somtimes make things
+	 * more predictable when debugging, at the risk of deadlocks.
+	 */
+	private void executeOnUIThread(Runnable r) {
+		Display.getDefault().asyncExec(r);
+//		Display.getDefault().syncExec(r);
+	}
+
+	void stateChanged_(StateChangeEvent event) {
+		this.listener.stateChanged(event);
+	}
+
+	@Override
+	public String toString() {
+		return "SWT(" + this.listener.toString() + ')'; //$NON-NLS-1$
+	}
+
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/listeners/SWTTreeChangeListenerWrapper.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/listeners/SWTTreeChangeListenerWrapper.java
new file mode 100644
index 0000000..29462e9
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/listeners/SWTTreeChangeListenerWrapper.java
@@ -0,0 +1,154 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 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.ui.internal.listeners;
+
+import org.eclipse.jpt.utility.model.event.TreeAddEvent;
+import org.eclipse.jpt.utility.model.event.TreeChangeEvent;
+import org.eclipse.jpt.utility.model.event.TreeClearEvent;
+import org.eclipse.jpt.utility.model.event.TreeRemoveEvent;
+import org.eclipse.jpt.utility.model.listener.TreeChangeListener;
+import org.eclipse.swt.widgets.Display;
+
+/**
+ * Wrap another tree change listener and forward events to it on the SWT
+ * UI thread, asynchronously if necessary. If the event arrived on the UI
+ * thread that is probably because it was initiated by a UI widget; as a
+ * result, we want to loop back synchronously so the events can be
+ * short-circuited.
+ */
+public class SWTTreeChangeListenerWrapper
+	implements TreeChangeListener
+{
+	private final TreeChangeListener listener;
+
+	public SWTTreeChangeListenerWrapper(TreeChangeListener listener) {
+		super();
+		if (listener == null) {
+			throw new NullPointerException();
+		}
+		this.listener = listener;
+	}
+
+	public void nodeAdded(TreeAddEvent event) {
+		if (this.isExecutingOnUIThread()) {
+			this.nodeAdded_(event);
+		} else {
+			this.executeOnUIThread(this.buildNodeAddedRunnable(event));
+		}
+	}
+
+	public void nodeRemoved(TreeRemoveEvent event) {
+		if (this.isExecutingOnUIThread()) {
+			this.nodeRemoved_(event);
+		} else {
+			this.executeOnUIThread(this.buildNodeRemovedRunnable(event));
+		}
+	}
+
+	public void treeCleared(TreeClearEvent event) {
+		if (this.isExecutingOnUIThread()) {
+			this.treeCleared_(event);
+		} else {
+			this.executeOnUIThread(this.buildTreeClearedRunnable(event));
+		}
+	}
+
+	public void treeChanged(TreeChangeEvent event) {
+		if (this.isExecutingOnUIThread()) {
+			this.treeChanged_(event);
+		} else {
+			this.executeOnUIThread(this.buildTreeChangedRunnable(event));
+		}
+	}
+
+	private Runnable buildNodeAddedRunnable(final TreeAddEvent event) {
+		return new Runnable() {
+			public void run() {
+				SWTTreeChangeListenerWrapper.this.nodeAdded_(event);
+			}
+			@Override
+			public String toString() {
+				return "node added"; //$NON-NLS-1$
+			}
+		};
+	}
+
+	private Runnable buildNodeRemovedRunnable(final TreeRemoveEvent event) {
+		return new Runnable() {
+			public void run() {
+				SWTTreeChangeListenerWrapper.this.nodeRemoved_(event);
+			}
+			@Override
+			public String toString() {
+				return "node removed"; //$NON-NLS-1$
+			}
+		};
+	}
+
+	private Runnable buildTreeClearedRunnable(final TreeClearEvent event) {
+		return new Runnable() {
+			public void run() {
+				SWTTreeChangeListenerWrapper.this.treeCleared_(event);
+			}
+			@Override
+			public String toString() {
+				return "tree cleared"; //$NON-NLS-1$
+			}
+		};
+	}
+
+	private Runnable buildTreeChangedRunnable(final TreeChangeEvent event) {
+		return new Runnable() {
+			public void run() {
+				SWTTreeChangeListenerWrapper.this.treeChanged_(event);
+			}
+			@Override
+			public String toString() {
+				return "tree changed"; //$NON-NLS-1$
+			}
+		};
+	}
+
+	private boolean isExecutingOnUIThread() {
+		return Display.getCurrent() != null;
+	}
+
+	/**
+	 * {@link Display#asyncExec(Runnable)} seems to work OK;
+	 * but using {@link Display#syncExec(Runnable)} can somtimes make things
+	 * more predictable when debugging, at the risk of deadlocks.
+	 */
+	private void executeOnUIThread(Runnable r) {
+		Display.getDefault().asyncExec(r);
+//		Display.getDefault().syncExec(r);
+	}
+
+	void nodeAdded_(TreeAddEvent event) {
+		this.listener.nodeAdded(event);
+	}
+
+	void nodeRemoved_(TreeRemoveEvent event) {
+		this.listener.nodeRemoved(event);
+	}
+
+	void treeCleared_(TreeClearEvent event) {
+		this.listener.treeCleared(event);
+	}
+
+	void treeChanged_(TreeChangeEvent event) {
+		this.listener.treeChanged(event);
+	}
+
+	@Override
+	public String toString() {
+		return "SWT(" + this.listener.toString() + ')'; //$NON-NLS-1$
+	}
+
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/menus/MapAsContribution.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/menus/MapAsContribution.java
new file mode 100644
index 0000000..8d23218
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/menus/MapAsContribution.java
@@ -0,0 +1,204 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2009 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.ui.internal.menus;
+
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import org.eclipse.jface.action.IContributionItem;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jpt.core.JpaPlatform;
+import org.eclipse.jpt.core.JpaResourceType;
+import org.eclipse.jpt.core.JpaStructureNode;
+import org.eclipse.jpt.ui.JpaPlatformUi;
+import org.eclipse.jpt.ui.JptUiPlugin;
+import org.eclipse.jpt.ui.details.DefaultMappingUiDefinition;
+import org.eclipse.jpt.ui.details.MappingUiDefinition;
+import org.eclipse.jpt.ui.internal.jface.ImageImageDescriptor;
+import org.eclipse.jpt.utility.internal.ArrayTools;
+import org.eclipse.jpt.utility.internal.CollectionTools;
+import org.eclipse.jpt.utility.internal.iterators.CompositeIterator;
+import org.eclipse.jpt.utility.internal.iterators.FilteringIterator;
+import org.eclipse.jpt.utility.internal.iterators.TransformationIterator;
+import org.eclipse.ui.ISources;
+import org.eclipse.ui.actions.CompoundContributionItem;
+import org.eclipse.ui.handlers.IHandlerService;
+import org.eclipse.ui.menus.CommandContributionItem;
+import org.eclipse.ui.menus.CommandContributionItemParameter;
+import org.eclipse.ui.menus.IWorkbenchContribution;
+import org.eclipse.ui.services.IServiceLocator;
+import com.ibm.icu.text.Collator;
+
+/**
+ * This menu contribution is responsible to populate the Map As menu with the
+ * registered mapping types defined in the <code>JptPlatformUi</code>.
+ *
+ * @see JpaPlatform
+ * @see JpaPlatformUi
+ *
+ * @version 2.0
+ * @since 2.0
+ */
+@SuppressWarnings("nls")
+public abstract class MapAsContribution<T extends JpaStructureNode>
+	extends CompoundContributionItem
+	implements IWorkbenchContribution
+{
+	/**
+	 * Keeps track of the <code>IServiceLocator</code> which is used to retrieve
+	 * various services required for invoking the <code>PersistentAttributeMapAsHandler</code>.
+	 */
+	private IServiceLocator serviceLocator;
+	
+	
+	/**
+	 * Creates a new <code>PersistentAttributeMapAsContribution</code>.
+	 */
+	public MapAsContribution() {
+		super();
+	}
+	
+	
+	public void initialize(IServiceLocator serviceLocator) {
+		this.serviceLocator = serviceLocator;
+	}
+		
+	@Override
+	protected IContributionItem[] getContributionItems() {
+		// Retrieve the selection from the handler service
+		// which should be an IStructuredSelection of JpaStructureNodes
+		IHandlerService handlerService = 
+			(IHandlerService) this.serviceLocator.getService(IHandlerService.class);
+		IStructuredSelection currentSelection = 
+			(IStructuredSelection) handlerService.getCurrentState().getVariable(ISources.ACTIVE_CURRENT_SELECTION_NAME);
+		
+		// Assume that all nodes are in the same project (which is very safe)
+		// and retrieve the mapping UI providers just from the first item
+		T node = (T) currentSelection.getFirstElement();
+		
+		return 
+			ArrayTools.array(
+				new TransformationIterator<MappingUiDefinition<T, ?>, IContributionItem>(mappingUiDefinitions(node)) {
+					@Override
+					protected IContributionItem transform(MappingUiDefinition<T, ?> next) {
+						return createContributionItem(next);
+					}
+				},
+				new IContributionItem[0]);
+	}
+	
+
+	protected Comparator<MappingUiDefinition<T, ?>> getDefinitionsComparator() {
+		return new Comparator<MappingUiDefinition<T, ?>>() {
+			public int compare(MappingUiDefinition<T, ?> item1, MappingUiDefinition<T, ?> item2) {
+				String displayString1 = item1.getLabel();
+				String displayString2 = item2.getLabel();
+				return Collator.getInstance().compare(displayString1, displayString2);
+			}
+		};
+	}
+
+	/**
+	 * Retrieves the registered {@link MappingUiDefinition}s from the given node, 
+	 * using its {@link JpaPlatformUi}.
+	 *
+	 * @param node A test node to determine the {@link JpaPlatformUi} and type 
+	 * of providers to return
+	 * @return The list of registered {@link MappingUiDefinition}s
+	 */
+	protected <U extends T> Iterator<? extends MappingUiDefinition<T, ?>> mappingUiDefinitions(final T node) {
+		JpaPlatform jpaPlatform = node.getJpaProject().getJpaPlatform();
+		JpaPlatformUi jpaPlatformUi = JptUiPlugin.instance().getJpaPlatformUi(jpaPlatform);
+		
+		Iterator<? extends MappingUiDefinition<T, ?>> sortedMappingUiDefinitions = 
+				CollectionTools.sort(
+					new FilteringIterator<MappingUiDefinition<T, ?>>(
+							mappingUiDefinitions(jpaPlatformUi, node.getResourceType())) {
+						 @Override
+						protected boolean accept(MappingUiDefinition<T, ?> o) {
+							return o.isEnabledFor(node);
+						}
+					},
+					getDefinitionsComparator());
+		
+		DefaultMappingUiDefinition<T, ?> defaultDefinition = getDefaultMappingUiDefinition(jpaPlatformUi, node);
+		if (defaultDefinition != null) {
+			return new CompositeIterator<MappingUiDefinition<T, ?>>(defaultDefinition, sortedMappingUiDefinitions);
+		}
+		return sortedMappingUiDefinitions;
+	}
+
+	/**
+	* Retrieves the registered {@link MappingUiDefinition}s from the given 
+	* {@link JpaPlatformUi} and {@link JpaStructureNode} (to determine type of 
+	* mapping providers to retrieve).
+	*
+	* @param jpaPlatformUi The active {@link JpaPlatformUi} from where the
+	* provider can be retrieved
+	* @param node A test node to determine type of providers to return
+	* @return The list of registered {@link MappingUiDefinition}s
+	*/
+	protected abstract Iterator<? extends MappingUiDefinition<T, ?>> 
+		mappingUiDefinitions(JpaPlatformUi platformUi, JpaResourceType resourceType);
+	
+	/**
+	* Creates the default provider responsible for clearing the mapping type.
+	* If not default provider, then return null
+	*
+	* @return A provider that acts as a default mapping provider
+	*/
+	protected abstract DefaultMappingUiDefinition<T, ?> getDefaultMappingUiDefinition(JpaPlatformUi platformUi, T node);
+			
+	protected IContributionItem createContributionItem(MappingUiDefinition<T, ?> mappingUiProvider) {
+		return new CommandContributionItem(createParameter(mappingUiProvider));
+	}
+	
+	protected CommandContributionItemParameter createParameter(MappingUiDefinition<T, ?> mappingUiDefinition) {
+		CommandContributionItemParameter parameter =
+			new CommandContributionItemParameter(
+					this.serviceLocator, 
+					createCommandContributionItemId(mappingUiDefinition),
+					getCommandId(),
+					CommandContributionItem.STYLE_CHECK);
+		parameter.label = mappingUiDefinition.getLabel();
+		Map<String, String> parameters = new HashMap<String, String>();
+		parameters.put(getCommandParameterId(), mappingUiDefinition.getKey());
+		parameter.parameters = parameters;
+		parameter.icon = new ImageImageDescriptor(mappingUiDefinition.getImage());
+		parameter.visibleEnabled = true;
+		return parameter;
+	}
+	
+	/**
+	 * Retrieves the unique identifier of the command that will be invoked for
+	 * changing the mapping type of the selected nodes.
+	 *
+	 * @return The unique identifier of the "map as" command
+	 */
+	protected abstract String getCommandId();
+	
+	/**
+	 * Retrieves the unique identifier of the mapping key command parameter that 
+	 * will be used for the new mapping type of the selected nodes.
+	 *
+	 * @return The unique identifier of the "map as" command parameter
+	 */
+	protected abstract String getCommandParameterId();
+	
+	/**
+	 * Returns an id for a {@link CommandContributionItem} in the form of 
+	 * "<commandId>.<mappingKey>"  
+	 * (for example "org.eclipse.jpt.core.ui.persistentTypeMapAs.entity")
+	 */
+	protected String createCommandContributionItemId(MappingUiDefinition<T, ?> mappingUiDefinition) {
+		return getCommandId() + "." + mappingUiDefinition.getKey();
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/menus/PersistentAttributeMapAsContribution.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/menus/PersistentAttributeMapAsContribution.java
new file mode 100644
index 0000000..5ccb60e
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/menus/PersistentAttributeMapAsContribution.java
@@ -0,0 +1,85 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2009 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.ui.internal.menus;
+
+import java.util.Iterator;
+import org.eclipse.jpt.core.JpaResourceType;
+import org.eclipse.jpt.core.context.PersistentAttribute;
+import org.eclipse.jpt.ui.JpaPlatformUi;
+import org.eclipse.jpt.ui.details.DefaultMappingUiDefinition;
+import org.eclipse.jpt.ui.details.MappingUiDefinition;
+import org.eclipse.jpt.ui.internal.commands.PersistentAttributeMapAsHandler;
+import org.eclipse.ui.menus.CommandContributionItemParameter;
+
+/**
+ * This menu contribution is responsible to populate the Map As menu with the
+ * registered attribute mapping types defined in the <code>JptPlatformUi</code>
+ * for <code>PersistentAttribute</code> objects.
+ *
+ * @see PersistentAttributeMapAsHandler
+ * @see PersistentAttribute
+ *
+ * @version 2.2
+ * @since 2.0
+ */
+public class PersistentAttributeMapAsContribution
+	extends MapAsContribution<PersistentAttribute>
+{
+	/**
+	 * Creates a new <code>PersistentAttributeMapAsContribution</code>.
+	 */
+	public PersistentAttributeMapAsContribution() {
+		super();
+	}
+
+	@Override
+	protected String getCommandId() {
+		return PersistentAttributeMapAsHandler.COMMAND_ID;
+	}
+	
+	@Override
+	protected String getCommandParameterId() {
+		return PersistentAttributeMapAsHandler.SPECIFIED_MAPPING_COMMAND_PARAMETER_ID;
+	}
+	
+	@Override
+	protected CommandContributionItemParameter createParameter(MappingUiDefinition<PersistentAttribute, ?> mappingUiProvider) {
+		CommandContributionItemParameter parameter = super.createParameter(mappingUiProvider);
+		String defaultKey = null;
+		if (mappingUiProvider instanceof DefaultMappingUiDefinition<?, ?>) {
+			defaultKey = ((DefaultMappingUiDefinition<? extends PersistentAttribute, ?>) mappingUiProvider).getDefaultKey();
+		}
+		parameter.parameters.put(PersistentAttributeMapAsHandler.DEFAULT_MAPPING_COMMAND_PARAMETER_ID, defaultKey);
+		return parameter;
+	}
+	
+	@Override
+	protected Iterator<? extends MappingUiDefinition<PersistentAttribute, ?>> mappingUiDefinitions(
+			JpaPlatformUi jpaPlatformUi, JpaResourceType resourceType) {
+		
+		return jpaPlatformUi.attributeMappingUiDefinitions(resourceType);
+	}
+	
+	@Override
+	protected DefaultMappingUiDefinition<PersistentAttribute, ?> getDefaultMappingUiDefinition(
+			JpaPlatformUi jpaPlatformUi, PersistentAttribute node) {
+		
+		return getDefaultMappingUiDefinition(
+				jpaPlatformUi, 
+				((PersistentAttribute) node).getDefaultMappingKey(), 
+				node.getResourceType());
+	}
+	
+	protected DefaultMappingUiDefinition<PersistentAttribute, ?> getDefaultMappingUiDefinition(
+			JpaPlatformUi jpaPlatformUi, String defaultMappingKey, JpaResourceType resourceType) {
+		
+		return jpaPlatformUi.getDefaultAttributeMappingUiDefinition(resourceType, defaultMappingKey);
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/menus/PersistentTypeMapAsContribution.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/menus/PersistentTypeMapAsContribution.java
new file mode 100644
index 0000000..f46726d
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/menus/PersistentTypeMapAsContribution.java
@@ -0,0 +1,64 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2009 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.ui.internal.menus;
+
+import java.util.Iterator;
+import org.eclipse.jpt.core.JpaPlatform;
+import org.eclipse.jpt.core.JpaResourceType;
+import org.eclipse.jpt.core.context.PersistentType;
+import org.eclipse.jpt.ui.JpaPlatformUi;
+import org.eclipse.jpt.ui.details.DefaultMappingUiDefinition;
+import org.eclipse.jpt.ui.details.MappingUiDefinition;
+import org.eclipse.jpt.ui.internal.commands.PersistentTypeMapAsHandler;
+
+/**
+ * This menu contribution is responsible to populate the Map As menu with the
+ * registered mapping types defined in the <code>JptPlatformUi</code> for
+ * <code>PersistentType</code> objects.
+ *
+ * @see JpaPlatform
+ * @see JpaPlatformUi
+ * @see PersistentType
+ */
+public class PersistentTypeMapAsContribution
+	extends MapAsContribution<PersistentType>
+{
+	/**
+	 * Creates a new <code>PersistentTypeMapAsContribution</code>.
+	 */
+	public PersistentTypeMapAsContribution() {
+		super();
+	}
+	
+	
+	@Override
+	protected String getCommandId() {
+		return PersistentTypeMapAsHandler.COMMAND_ID;
+	}
+	
+	@Override
+	protected String getCommandParameterId() {
+		return PersistentTypeMapAsHandler.COMMAND_PARAMETER_ID;
+	}
+	
+	@Override
+	protected Iterator<? extends MappingUiDefinition<PersistentType, ?>> mappingUiDefinitions(
+			JpaPlatformUi jpaPlatformUi, JpaResourceType resourceType) {
+		
+		return jpaPlatformUi.typeMappingUiDefinitions(resourceType);
+	}
+	
+	@Override
+	protected DefaultMappingUiDefinition<PersistentType, ?> getDefaultMappingUiDefinition(
+			JpaPlatformUi jpaPlatformUi, PersistentType node) {
+		
+		return jpaPlatformUi.getDefaultTypeMappingUiDefinition(node.getResourceType());
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/navigator/JpaNavigatorActionProvider.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/navigator/JpaNavigatorActionProvider.java
new file mode 100644
index 0000000..35c0ab3
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/navigator/JpaNavigatorActionProvider.java
@@ -0,0 +1,59 @@
+/*******************************************************************************
+ *  Copyright (c) 2008  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.ui.internal.navigator;
+
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jpt.ui.internal.actions.OpenJpaResourceAction;
+import org.eclipse.ui.IActionBars;
+import org.eclipse.ui.actions.ActionContext;
+import org.eclipse.ui.navigator.CommonActionProvider;
+import org.eclipse.ui.navigator.ICommonActionConstants;
+import org.eclipse.ui.navigator.ICommonActionExtensionSite;
+import org.eclipse.ui.navigator.ICommonMenuConstants;
+
+public class JpaNavigatorActionProvider extends CommonActionProvider
+{
+	private OpenJpaResourceAction openAction;
+	
+	public JpaNavigatorActionProvider() {
+		super();
+	}
+	
+	public void init(ICommonActionExtensionSite aConfig) {
+		openAction = new OpenJpaResourceAction();
+	}
+	
+	public void setContext(ActionContext aContext) {
+		if (aContext != null && aContext.getSelection() instanceof IStructuredSelection) {
+			IStructuredSelection selection = (IStructuredSelection) aContext.getSelection();
+			openAction.selectionChanged(selection);
+		}
+		
+		super.setContext(aContext);
+	}
+	
+	public void fillActionBars(IActionBars theActionBars) {
+		if (openAction.isEnabled()) {
+			theActionBars.setGlobalActionHandler(ICommonActionConstants.OPEN, openAction);
+		}
+	}
+	
+	public void fillContextMenu(IMenuManager aMenu) {
+		if (getContext() == null || getContext().getSelection().isEmpty()) {
+			return;
+		}
+		
+		if (openAction.isEnabled()) {
+			aMenu.insertAfter(ICommonMenuConstants.GROUP_OPEN, openAction);
+		}
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/navigator/JpaNavigatorContentAndLabelProvider.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/navigator/JpaNavigatorContentAndLabelProvider.java
new file mode 100644
index 0000000..6bda2b3
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/navigator/JpaNavigatorContentAndLabelProvider.java
@@ -0,0 +1,20 @@
+/*******************************************************************************
+ *  Copyright (c) 2008  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.ui.internal.navigator;
+
+import org.eclipse.jpt.ui.internal.jface.DelegatingTreeContentAndLabelProvider;
+
+public class JpaNavigatorContentAndLabelProvider extends DelegatingTreeContentAndLabelProvider
+{
+	public JpaNavigatorContentAndLabelProvider() {
+		super(new JpaNavigatorTreeItemContentProviderFactory(), new JpaNavigatorItemLabelProviderFactory());
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/navigator/JpaNavigatorContentProvider.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/navigator/JpaNavigatorContentProvider.java
new file mode 100644
index 0000000..3caba4d
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/navigator/JpaNavigatorContentProvider.java
@@ -0,0 +1,217 @@
+/*******************************************************************************
+ *  Copyright (c) 2007, 2009 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.ui.internal.navigator;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.jobs.Job;
+import org.eclipse.jface.viewers.StructuredViewer;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jpt.core.JpaProject;
+import org.eclipse.jpt.core.JptCorePlugin;
+import org.eclipse.jpt.ui.JpaPlatformUi;
+import org.eclipse.jpt.ui.JptUiPlugin;
+import org.eclipse.ui.IMemento;
+import org.eclipse.ui.navigator.ICommonContentExtensionSite;
+import org.eclipse.ui.navigator.ICommonContentProvider;
+import org.eclipse.wst.common.project.facet.core.FacetedProjectFramework;
+import org.eclipse.wst.common.project.facet.core.ProjectFacetsManager;
+import org.eclipse.wst.common.project.facet.core.events.IFacetedProjectEvent;
+import org.eclipse.wst.common.project.facet.core.events.IFacetedProjectListener;
+import org.eclipse.wst.common.project.facet.core.events.IProjectFacetActionEvent;
+
+/**
+ * This extension of navigator content provider delegates to the platform UI
+ * (see the org.eclipse.jpt.ui.jpaPlatform extension point) for navigator content.
+ * 
+ * If there is a platform UI for the given project, this content provider will
+ * provide a root "JPA Content" node (child of the project), otherwise there
+ * will be no content.  For children of the "JPA Content" node (or for any other
+ * sub-node), this provider will delegate to the content provider returned by the 
+ * platform UI implementation.
+ */
+public class JpaNavigatorContentProvider
+	implements ICommonContentProvider
+{
+	private JpaNavigatorContentAndLabelProvider delegate;
+	
+	private IFacetedProjectListener facetListener;
+	
+	private StructuredViewer viewer;
+	
+	
+	public JpaNavigatorContentProvider() {
+		super();
+		facetListener = new FacetListener();
+		FacetedProjectFramework.addListener(
+				facetListener, 
+				IFacetedProjectEvent.Type.POST_INSTALL,
+				IFacetedProjectEvent.Type.POST_UNINSTALL,
+				IFacetedProjectEvent.Type.PROJECT_MODIFIED);
+	}
+	
+	
+	public JpaNavigatorContentAndLabelProvider delegate() {
+		return delegate;
+	}
+	
+	
+	// **************** IContentProvider implementation ************************
+	
+	public void dispose() {
+		FacetedProjectFramework.removeListener(facetListener);
+		if (delegate != null) {
+			delegate.dispose();
+		}
+	}
+	
+	public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+		if (delegate != null) {
+			delegate.inputChanged(viewer, oldInput, newInput);
+		}
+		this.viewer = (StructuredViewer) viewer;
+	}
+	
+	
+	// **************** IStructuredContentProvider implementation **************
+	
+	public Object[] getElements(Object inputElement) {
+		return getChildren(inputElement);
+	}
+	
+	
+	// **************** ITreeContentProvider implementation ********************
+	
+	public Object getParent(Object element) {
+		if (delegate != null) {
+			return delegate.getParent(element);
+		}
+		
+		return null;
+	}
+	
+	public boolean hasChildren(Object element) {
+		if (element instanceof IAdaptable) {
+			IProject project = (IProject) ((IAdaptable) element).getAdapter(IProject.class);
+			
+			if (project != null) {
+				JpaProject jpaProject = JptCorePlugin.getJpaProject(project);
+				if (jpaProject != null) {
+					JpaPlatformUi platformUi = JptUiPlugin.instance().getJpaPlatformUi(jpaProject.getJpaPlatform());
+					
+					return platformUi != null;
+				}	
+			}
+		}
+		
+		if (delegate != null) {
+			return delegate.hasChildren(element);
+		}
+		
+		return false;
+	}
+	
+	public Object[] getChildren(Object parentElement) {
+		if (parentElement instanceof IAdaptable) {
+			IProject project = (IProject) ((IAdaptable) parentElement).getAdapter(IProject.class);
+			
+			if (project != null) {
+				JpaProject jpaProject = JptCorePlugin.getJpaProject(project);
+				if (jpaProject != null) {
+					JpaPlatformUi platformUi = JptUiPlugin.instance().getJpaPlatformUi(jpaProject.getJpaPlatform());
+					
+					if (platformUi != null) {
+						return new Object[] {jpaProject.getRootContextNode()};
+					}
+				}	
+			}
+		}
+		
+		if (delegate != null) {
+			return delegate.getChildren(parentElement);
+		}
+			
+		return new Object[0];
+	}
+	
+	
+	// **************** IMementoAware implementation ***************************
+	
+	public void saveState(IMemento memento) {
+		// no op
+	}
+	
+	public void restoreState(IMemento memento) {
+		// no op
+	}
+	
+	
+	// **************** ICommonContentProvider implementation ******************
+	
+	public void init(ICommonContentExtensionSite config) {
+		if (delegate == null) {
+			JpaNavigatorLabelProvider labelProvider = (JpaNavigatorLabelProvider) config.getExtension().getLabelProvider();
+			if (labelProvider != null && labelProvider.delegate() != null) {
+				delegate = labelProvider.delegate();
+			}
+			else {
+				delegate = new JpaNavigatorContentAndLabelProvider();
+			}
+		}
+	}
+	
+	
+	// **************** member classes *****************************************
+	
+	private class FacetListener
+		implements IFacetedProjectListener
+	{
+		public void handleEvent(IFacetedProjectEvent event) {
+			if (event.getType() == IFacetedProjectEvent.Type.PROJECT_MODIFIED) {
+				refreshViewer(event.getProject().getProject());
+			}
+			else if (event.getType() == IFacetedProjectEvent.Type.POST_INSTALL
+					|| event.getType() == IFacetedProjectEvent.Type.POST_UNINSTALL) {
+				IProjectFacetActionEvent ipaEvent = (IProjectFacetActionEvent) event;
+				if (ipaEvent.getProjectFacet().equals(
+						ProjectFacetsManager.getProjectFacet(JptCorePlugin.FACET_ID))) {
+					refreshViewer(ipaEvent.getProject().getProject());
+				}
+			}
+		}
+		
+		private void refreshViewer(final IProject project) {
+			if (viewer != null 
+					&& viewer.getControl() != null 
+					&& !viewer.getControl().isDisposed()) {
+				// Using job here so that project model update (which also uses
+				//  a job) will complete first
+				Job refreshJob = new Job("Refresh viewer") {
+					@Override
+					protected IStatus run(IProgressMonitor monitor) {
+						// Using runnable here so that refresh will go on correct thread
+						viewer.getControl().getDisplay().asyncExec(new Runnable() {
+							public void run() {
+								viewer.refresh(project);
+							}
+						});
+						return Status.OK_STATUS;
+					}
+				};
+				refreshJob.setRule(project);
+				refreshJob.schedule();
+			}
+		}
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/navigator/JpaNavigatorItemLabelProviderFactory.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/navigator/JpaNavigatorItemLabelProviderFactory.java
new file mode 100644
index 0000000..95eff0e
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/navigator/JpaNavigatorItemLabelProviderFactory.java
@@ -0,0 +1,75 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2009 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.ui.internal.navigator;
+
+import java.util.HashMap;
+import java.util.Map;
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.jpt.core.JpaPlatform;
+import org.eclipse.jpt.core.context.JpaContextNode;
+import org.eclipse.jpt.ui.JptUiPlugin;
+import org.eclipse.jpt.ui.jface.DelegatingContentAndLabelProvider;
+import org.eclipse.jpt.ui.jface.ItemLabelProvider;
+import org.eclipse.jpt.ui.jface.ItemLabelProviderFactory;
+import org.eclipse.jpt.ui.navigator.JpaNavigatorProvider;
+
+public class JpaNavigatorItemLabelProviderFactory
+	implements ItemLabelProviderFactory
+{
+	/**
+	 * Exactly *one* of these factories is created for each view that utilizes it.  
+	 * Therefore, as we delegate to the platform UI for each project, we should 
+	 * maintain the same multiplicity.  That is, if there is a delegate for each 
+	 * platform UI, we should maintain *one* delegate for each view.
+	 * 
+	 * Key: platform id,  Value: delegate content provider factory
+	 */
+	private final Map<String, ItemLabelProviderFactory> delegates;
+	
+	
+	public JpaNavigatorItemLabelProviderFactory() {
+		super();
+		this.delegates = new HashMap<String, ItemLabelProviderFactory>();
+	}
+	
+	public ItemLabelProvider buildItemLabelProvider(Object item, DelegatingContentAndLabelProvider contentAndLabelProvider) {
+		ItemLabelProviderFactory delegate = getDelegate(item);
+		if (delegate != null) {
+			return delegate.buildItemLabelProvider(item, contentAndLabelProvider);
+		}
+		return null;
+	}
+	
+	
+	private ItemLabelProviderFactory getDelegate(Object element) {
+		if (! (element instanceof IAdaptable)) {
+			return null;
+		}
+		
+		JpaContextNode contextNode = (JpaContextNode) ((IAdaptable) element).getAdapter(JpaContextNode.class);
+		
+		if (contextNode == null) {
+			return null;
+		}
+		
+		JpaPlatform platform = contextNode.getJpaProject().getJpaPlatform();
+		String platformId = platform.getId();
+		if (delegates.containsKey(platformId)) {
+			return delegates.get(platformId);
+		}
+		JpaNavigatorProvider navigatorProvider = JptUiPlugin.instance().getJpaNavigatorProvider(platform);
+		ItemLabelProviderFactory delegate = null;
+		if (navigatorProvider != null) {
+			delegate = navigatorProvider.getItemLabelProviderFactory();
+		}
+		delegates.put(platformId, delegate);
+		return delegate;
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/navigator/JpaNavigatorLabelProvider.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/navigator/JpaNavigatorLabelProvider.java
new file mode 100644
index 0000000..5e3b976
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/navigator/JpaNavigatorLabelProvider.java
@@ -0,0 +1,137 @@
+/*******************************************************************************
+ *  Copyright (c) 2007, 2009 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.ui.internal.navigator;
+
+import org.eclipse.jface.viewers.ILabelProviderListener;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.ui.IMemento;
+import org.eclipse.ui.navigator.ICommonContentExtensionSite;
+import org.eclipse.ui.navigator.ICommonLabelProvider;
+
+/**
+ * This extension of navigator label provider delegates to the platform UI
+ * (see the org.eclipse.jpt.ui.jpaPlatform extension point) for navigator labels.
+ * 
+ * This label provider provides a label for the root "JPA Content" node provided
+ * by the content provider (see {@link JpaNavigatorContentProvider}) and delegates
+ * to the label provider returned by the platform UI implementation for labels
+ * for children of the "JPA Content" node (or for any other sub-node).
+ */
+public class JpaNavigatorLabelProvider extends LabelProvider
+	implements ICommonLabelProvider
+{
+	private JpaNavigatorContentAndLabelProvider delegate;
+	
+	
+	public JpaNavigatorLabelProvider() {
+		super();
+	}
+	
+	
+	public JpaNavigatorContentAndLabelProvider delegate() {
+		return delegate;
+	}
+	
+	
+	// **************** IBaseLabelProvider implementation **********************
+	
+	@Override
+	public void addListener(ILabelProviderListener listener) {
+		if (delegate != null) {
+			delegate.addListener(listener);
+		}
+		super.addListener(listener);
+	}
+	
+	@Override
+	public void removeListener(ILabelProviderListener listener) {
+		super.removeListener(listener);
+		if (delegate != null) {
+			delegate.removeListener(listener);
+		}
+	}
+	
+	@Override
+	public boolean isLabelProperty(Object element, String property) {
+		if (delegate != null) {
+			return delegate.isLabelProperty(element, property);
+		}
+		
+		return super.isLabelProperty(element, property);
+	}
+	
+	@Override
+	public void dispose() {
+		if (delegate != null) {
+			delegate.dispose();
+		}
+		super.dispose();
+	}
+	
+	
+	// **************** ILabelProvider implementation **************************
+	
+	@Override
+	public Image getImage(Object element) {
+		if (delegate != null) {
+			return delegate.getImage(element);
+		}
+		
+		return super.getImage(element);
+	}
+	
+	@Override
+	public String getText(Object element) {
+		if (delegate != null) {
+			return delegate.getText(element);
+		}
+		
+		return super.getText(element);
+	}
+	
+	
+	// **************** IDescriptionProvider implementation ********************
+	
+	public String getDescription(Object element) {
+		if (delegate != null) {
+			return delegate.getDescription(element);
+		}
+		
+		return super.getText(element);
+	}
+	
+	
+	// **************** IMementoAware implementation ***************************
+	
+	public void saveState(IMemento memento) {
+		// no op
+	}
+	
+	public void restoreState(IMemento memento) {
+		// no op
+	}
+	
+	
+	// **************** ICommonLabelProvider implementation ********************
+	
+	public void init(ICommonContentExtensionSite config) {
+		if (delegate == null) {
+			JpaNavigatorContentProvider contentProvider = (JpaNavigatorContentProvider) config.getExtension().getContentProvider();
+			if (contentProvider != null && contentProvider.delegate() != null) {
+				delegate = contentProvider.delegate();
+			}
+			else {
+				delegate = new JpaNavigatorContentAndLabelProvider();
+			}
+		}
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/navigator/JpaNavigatorTreeItemContentProviderFactory.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/navigator/JpaNavigatorTreeItemContentProviderFactory.java
new file mode 100644
index 0000000..3851fc2
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/navigator/JpaNavigatorTreeItemContentProviderFactory.java
@@ -0,0 +1,75 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2009 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.ui.internal.navigator;
+
+import java.util.HashMap;
+import java.util.Map;
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.jpt.core.JpaPlatform;
+import org.eclipse.jpt.core.context.JpaContextNode;
+import org.eclipse.jpt.ui.JptUiPlugin;
+import org.eclipse.jpt.ui.jface.DelegatingContentAndLabelProvider;
+import org.eclipse.jpt.ui.jface.TreeItemContentProvider;
+import org.eclipse.jpt.ui.jface.TreeItemContentProviderFactory;
+import org.eclipse.jpt.ui.navigator.JpaNavigatorProvider;
+
+public class JpaNavigatorTreeItemContentProviderFactory
+	implements TreeItemContentProviderFactory
+{
+	/**
+	 * Exactly *one* of these factories is created for each view that utilizes it.  
+	 * Therefore, as we delegate to the platform UI for each project, we should 
+	 * maintain the same multiplicity.  That is, if there is a delegate for each 
+	 * platform UI, we should maintain *one* delegate for each view.
+	 * 
+	 * Key: platform id,  Value: delegate content provider factory
+	 */
+	private Map<String, TreeItemContentProviderFactory> delegates;
+	
+	
+	public JpaNavigatorTreeItemContentProviderFactory() {
+		super();
+		this.delegates = new HashMap<String, TreeItemContentProviderFactory>();
+	}
+	
+	public TreeItemContentProvider buildItemContentProvider(Object item, DelegatingContentAndLabelProvider contentAndLabelProvider) {
+		TreeItemContentProviderFactory delegate = getDelegate(item);
+		if (delegate != null) {
+			return delegate.buildItemContentProvider(item, contentAndLabelProvider);
+		}
+		return null;
+	}
+	
+	
+	private TreeItemContentProviderFactory getDelegate(Object element) {
+		if (! (element instanceof IAdaptable)) {
+			return null;
+		}
+		
+		JpaContextNode contextNode = (JpaContextNode) ((IAdaptable) element).getAdapter(JpaContextNode.class);
+		
+		if (contextNode == null) {
+			return null;
+		}
+		
+		JpaPlatform platform = contextNode.getJpaProject().getJpaPlatform();
+		String platformId = platform.getId();
+		if (delegates.containsKey(platformId)) {
+			return delegates.get(platformId);
+		}
+		JpaNavigatorProvider navigatorProvider = JptUiPlugin.instance().getJpaNavigatorProvider(platform);
+		TreeItemContentProviderFactory delegate = null;
+		if (navigatorProvider != null) {
+			delegate = navigatorProvider.getTreeItemContentProviderFactory();
+		}
+		delegates.put(platformId, delegate);
+		return delegate;
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/persistence/JptUiPersistenceMessages.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/persistence/JptUiPersistenceMessages.java
new file mode 100644
index 0000000..3caaf5d
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/persistence/JptUiPersistenceMessages.java
@@ -0,0 +1,81 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2009 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.ui.internal.persistence;
+
+import org.eclipse.osgi.util.NLS;
+
+/**
+ * Localized messages used by Dali persistence editor.
+ *
+ * @version 2.0
+ * @since 2.0
+ */
+public class JptUiPersistenceMessages {
+
+	public static String Boolean_False;
+	public static String Boolean_True;
+	
+	public static String ArchiveFileSelectionDialog_jarPathHelpLabel;
+	public static String ArchiveFileSelectionDialog_jarPathLabel;
+
+	public static String PersistenceEditor_page_help;
+	public static String PersistenceEditor_sourceTab;
+
+	public static String PersistenceUnitClassesComposite_description;
+	public static String PersistenceUnitClassesComposite_excludeUnlistedMappedClasses;
+	public static String PersistenceUnitClassesComposite_excludeUnlistedMappedClassesWithDefault;
+	public static String PersistenceUnitClassesComposite_mappedClassesNoName;
+	public static String PersistenceUnitClassesComposite_open;
+
+	public static String PersistenceUnitConnectionComposite_connection;
+	public static String PersistenceUnitConnectionComposite_database;
+	public static String PersistenceUnitConnectionComposite_general;
+
+	public static String PersistenceUnitConnectionDatabaseComposite_jtaDatasourceName;
+	public static String PersistenceUnitConnectionDatabaseComposite_nonJtaDatasourceName;
+
+	public static String PersistenceUnitConnectionGeneralComposite_default;
+	public static String PersistenceUnitConnectionGeneralComposite_jta;
+	public static String PersistenceUnitConnectionGeneralComposite_resource_local;
+	public static String PersistenceUnitConnectionGeneralComposite_transactionType;
+
+	public static String PersistenceUnitGeneralComposite_general;
+	public static String PersistenceUnitGeneralComposite_jarFiles;
+	public static String PersistenceUnitGeneralComposite_jpaMappingDescriptors;
+	public static String PersistenceUnitGeneralComposite_jpaMappingDescriptors_description;
+	public static String PersistenceUnitGeneralComposite_mappedClasses;
+	public static String PersistenceUnitGeneralComposite_name;
+	public static String PersistenceUnitGeneralComposite_persistenceProvider;
+	public static String PersistenceUnitGeneralComposite_description;
+	
+	public static String PersistenceUnitJarFilesComposite_noFileName;
+	public static String PersistenceUnitMappingFilesComposite_jarFileDialog_title;
+	public static String PersistenceUnitMappingFilesComposite_jarFileDialog_message;
+	
+	public static String PersistenceUnitMappingFilesComposite_mappingFileDialog_message;
+	public static String PersistenceUnitMappingFilesComposite_mappingFileDialog_title;
+	public static String PersistenceUnitMappingFilesComposite_ormNoName;
+
+	public static String PersistenceUnitPropertiesComposite_nameColumn;
+	public static String PersistenceUnitPropertiesComposite_properties;
+	public static String PersistenceUnitPropertiesComposite_properties_description;
+	public static String PersistenceUnitPropertiesComposite_valueColumn;
+
+	private static final String BUNDLE_NAME = "jpt_ui_persistence"; //$NON-NLS-1$
+	private static final Class<?> BUNDLE_CLASS = JptUiPersistenceMessages.class;
+	static {
+		NLS.initializeMessages(BUNDLE_NAME, BUNDLE_CLASS);
+	}
+
+	private JptUiPersistenceMessages() {
+		throw new UnsupportedOperationException();
+	}
+
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/persistence/details/AbstractPersistenceXmlResourceUiDefinition.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/persistence/details/AbstractPersistenceXmlResourceUiDefinition.java
new file mode 100644
index 0000000..03c80d3
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/persistence/details/AbstractPersistenceXmlResourceUiDefinition.java
@@ -0,0 +1,50 @@
+/*******************************************************************************
+ * Copyright (c) 2009 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.ui.internal.persistence.details;
+
+import java.util.ListIterator;
+import org.eclipse.jpt.core.context.persistence.PersistenceUnit;
+import org.eclipse.jpt.ui.ResourceUiDefinition;
+import org.eclipse.jpt.ui.PersistenceXmlResourceUiDefinition;
+import org.eclipse.jpt.ui.WidgetFactory;
+import org.eclipse.jpt.ui.details.JpaPageComposite;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * All the state in the definition should be "static" (i.e. unchanging once it is initialized).
+ */
+public abstract class AbstractPersistenceXmlResourceUiDefinition
+	implements ResourceUiDefinition, PersistenceXmlResourceUiDefinition
+{
+	
+	
+	private final PersistenceXmlUiFactory factory;
+	
+	
+	/**
+	 * zero-argument constructor
+	 */
+	protected AbstractPersistenceXmlResourceUiDefinition() {
+		super();
+		this.factory = buildPersistenceXmlUiFactory();
+	}
+	
+	
+	protected abstract PersistenceXmlUiFactory buildPersistenceXmlUiFactory();
+	
+	public PersistenceXmlUiFactory getFactory() {
+		return this.factory;
+	}
+	
+	public ListIterator<JpaPageComposite> buildPersistenceUnitComposites(PropertyValueModel<PersistenceUnit> subjectHolder, Composite parent, WidgetFactory widgetFactory) {
+		return this.factory.createPersistenceUnitComposites(subjectHolder, parent, widgetFactory);
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/persistence/details/ArchiveFileSelectionDialog.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/persistence/details/ArchiveFileSelectionDialog.java
new file mode 100644
index 0000000..1061c2d
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/persistence/details/ArchiveFileSelectionDialog.java
@@ -0,0 +1,225 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2010 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.ui.internal.persistence.details;
+
+import java.util.Collections;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.jpt.core.JptCorePlugin;
+import org.eclipse.jpt.ui.JptUiPlugin;
+import org.eclipse.jpt.ui.internal.jface.ArchiveFileViewerFilter;
+import org.eclipse.jpt.ui.internal.persistence.JptUiPersistenceMessages;
+import org.eclipse.jpt.ui.internal.utility.swt.SWTTools;
+import org.eclipse.jpt.utility.internal.model.value.SimplePropertyValueModel;
+import org.eclipse.jpt.utility.model.value.WritablePropertyValueModel;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.ui.dialogs.ElementTreeSelectionDialog;
+import org.eclipse.ui.dialogs.ISelectionStatusValidator;
+import org.eclipse.ui.model.WorkbenchContentProvider;
+import org.eclipse.ui.model.WorkbenchLabelProvider;
+import org.eclipse.ui.views.navigator.ResourceComparator;
+import org.eclipse.wst.common.componentcore.ComponentCore;
+import org.eclipse.wst.common.componentcore.resources.IVirtualComponent;
+import org.eclipse.wst.common.componentcore.resources.IVirtualContainer;
+import org.eclipse.wst.common.componentcore.resources.IVirtualFile;
+import org.eclipse.wst.common.componentcore.resources.IVirtualFolder;
+import org.eclipse.wst.common.componentcore.resources.IVirtualResource;
+
+public class ArchiveFileSelectionDialog 
+	extends ElementTreeSelectionDialog
+{
+	private final WritablePropertyValueModel<String> jarPathModel;
+	
+	private DeploymentPathCalculator pathCalculator;
+	
+	
+	public ArchiveFileSelectionDialog(Shell parent) {
+		this(parent, new SimpleDeploymentPathCalculator());
+	}
+	
+	public ArchiveFileSelectionDialog(Shell parent, DeploymentPathCalculator pathCalculator) {
+		super(parent, new WorkbenchLabelProvider(), new WorkbenchContentProvider());
+		this.pathCalculator = pathCalculator;
+		setComparator(new ResourceComparator(ResourceComparator.NAME));
+		addFilter(new ArchiveFileViewerFilter());
+		setValidator(new ArchiveFileSelectionValidator());
+		this.jarPathModel = new SimplePropertyValueModel<String>();
+	}
+	
+	
+	@Override
+	protected Control createDialogArea(Composite parent) {
+		Composite composite = (Composite) super.createDialogArea(parent);
+		
+		Label helpLabel = new Label(composite, SWT.WRAP);
+		helpLabel.setText(JptUiPersistenceMessages.ArchiveFileSelectionDialog_jarPathHelpLabel);
+		GridData gd = new GridData(GridData.FILL_HORIZONTAL);
+		gd.widthHint = 400;
+		helpLabel.setLayoutData(gd);
+		
+		Composite subComposite = new Composite(composite, SWT.NONE);
+		subComposite.setLayout(new GridLayout(2, false));
+		subComposite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+		
+		Label jarPathLabel = new Label(subComposite, SWT.NONE);
+		jarPathLabel.setFont(composite.getFont());
+		jarPathLabel.setText(JptUiPersistenceMessages.ArchiveFileSelectionDialog_jarPathLabel);
+		
+		Text jarPathText = new Text(subComposite, SWT.BORDER);
+		jarPathText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+		SWTTools.bind(jarPathModel, jarPathText);
+		
+		return composite;
+	}
+	
+	@Override
+	protected TreeViewer doCreateTreeViewer(Composite parent, int style) {
+		TreeViewer treeViewer = super.doCreateTreeViewer(parent, style);
+		
+		treeViewer.addSelectionChangedListener(
+			new ISelectionChangedListener() {
+				public void selectionChanged(SelectionChangedEvent event) {
+					updateJarPathModel(event.getSelection());
+				}
+			});
+		
+		return treeViewer;
+	}
+	
+	protected void updateJarPathModel(ISelection selection) {
+		Object selectedObj = ((IStructuredSelection) selection).getFirstElement();
+		if (selectedObj instanceof IFile) {
+			this.jarPathModel.setValue(calculateDeployPath((IFile) selectedObj));
+		}
+		else {
+			this.jarPathModel.setValue("");
+		}
+	}
+	
+	protected String calculateDeployPath(IFile archiveFile) {
+		return this.pathCalculator.calculateDeploymentPath(archiveFile);
+	}
+	
+	@Override
+	protected void computeResult() {
+		setResult(Collections.singletonList(this.jarPathModel.getValue()));
+	}
+	
+	
+	private static class ArchiveFileSelectionValidator 
+		implements ISelectionStatusValidator 
+	{
+		public ArchiveFileSelectionValidator() {
+			super();
+		}
+		
+		
+		public IStatus validate(Object[] selection) {
+			int nSelected= selection.length;
+			if (nSelected == 0 || (nSelected > 1)) {
+				return new Status(IStatus.ERROR, JptUiPlugin.PLUGIN_ID, "");  //$NON-NLS-1$
+			}
+			for (int i= 0; i < selection.length; i++) {
+				Object curr= selection[i];
+				if (curr instanceof IFile) {
+					return new Status(IStatus.OK, JptUiPlugin.PLUGIN_ID, "");  //$NON-NLS-1$
+				}
+			}
+			return new Status(IStatus.ERROR, JptUiPlugin.PLUGIN_ID, "");  //$NON-NLS-1$
+		}
+	}	
+	
+	
+	public static interface DeploymentPathCalculator
+	{
+		String calculateDeploymentPath(IFile file);
+	}
+	
+	
+	public static class SimpleDeploymentPathCalculator
+		implements DeploymentPathCalculator
+	{
+		public String calculateDeploymentPath(IFile file) {
+			return file.getName();
+		}
+	}
+	
+	
+	public static class ModuleDeploymentPathCalculator
+		extends SimpleDeploymentPathCalculator
+	{
+		@Override
+		public String calculateDeploymentPath(IFile file) {
+			// first look for virtual component that matches this file, returning
+			// the path to that virtual component
+			IVirtualComponent vComponent = ComponentCore.createComponent(file.getProject());
+			if (vComponent != null) {
+				IVirtualFolder vFolder = vComponent.getRootFolder();
+				IVirtualFile vFile = findVirtualFile(vFolder, file);
+				if (vFile != null) {
+					return calculatePersistenceRootRelativePath(vFile);
+				}
+			}
+			
+			// then default to simple behavior
+			return super.calculateDeploymentPath(file);
+		}
+		
+		protected IVirtualFile findVirtualFile(IVirtualContainer vContainer, IFile realFile) {
+			try { 
+				for (IVirtualResource vResource : vContainer.members()) {
+					if (vResource.getType() == IVirtualResource.FILE) {
+						IVirtualFile vFile = (IVirtualFile) vResource;
+						if (realFile.equals(vFile.getUnderlyingFile())) {
+							return vFile;
+						}
+					}
+					else {
+						IVirtualFile vFile = findVirtualFile((IVirtualContainer) vResource, realFile);
+						if (vFile != null) {
+							return vFile;
+						}
+					}
+				}
+			}
+			catch (CoreException ce) {
+				JptUiPlugin.log(ce);
+			}
+			
+			return null;
+		}
+		
+		protected String calculatePersistenceRootRelativePath(IVirtualFile vFile) {
+			IProject project = vFile.getProject();
+			IPath puRootPath = JptCorePlugin.getJarDeploymentRootPath(project);
+			
+			IPath path = vFile.getRuntimePath().makeRelativeTo(puRootPath);
+			
+			return path.toString();
+		}
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/persistence/details/GenericPersistenceUnitGeneralComposite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/persistence/details/GenericPersistenceUnitGeneralComposite.java
new file mode 100644
index 0000000..6e0437e
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/persistence/details/GenericPersistenceUnitGeneralComposite.java
@@ -0,0 +1,116 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2009 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.ui.internal.persistence.details;
+
+import org.eclipse.jpt.core.context.persistence.PersistenceUnit;
+import org.eclipse.jpt.ui.WidgetFactory;
+import org.eclipse.jpt.ui.details.JpaPageComposite;
+import org.eclipse.jpt.ui.internal.persistence.JptUiPersistenceMessages;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * Here the layout of this pane:
+ * <pre>
+ * -----------------------------------------------------------------------------
+ * |                                                                           |
+ * | - General --------------------------------------------------------------- |
+ * |                         ------------------------------------------------- |
+ * |   Name:                 | I                                             | |
+ * |                         ------------------------------------------------- |
+ * |                         ------------------------------------------------- |
+ * |   Persistence Provider: |                                             |v| |
+ * |                         ------------------------------------------------- |
+ * |                                                                           |
+ * |                                                                           |
+ * | - Mapped Classes -------------------------------------------------------- |
+ * |                                                                           |
+ * |   Description                                                             |
+ * |                                                                           |
+ * |   ----------------------------------------------------------------------- |
+ * |   |                                                                     | |
+ * |   | PersistenceUnitMappedClassesComposite                               | |
+ * |   |                                                                     | |
+ * |   ----------------------------------------------------------------------- |
+ * |                                                                           |
+ * |                                                                           |
+ * | - XML Mapping Files ----------------------------------------------------- |
+ * |                                                                           |
+ * |   Description                                                             |
+ * |                                                                           |
+ * |   ----------------------------------------------------------------------- |
+ * |   |                                                                     | |
+ * |   | PersistenceUnitMappingFilesComposite                                | |
+ * |   |                                                                     | |
+ * |   ----------------------------------------------------------------------- |
+ * -----------------------------------------------------------------------------</pre>
+ *
+ * @see PersistenceUnit
+ * @see PersistenceUnitJarFilesComposite
+ * @see PersistenceUnitMappedClassesComposite
+ * @see PersistenceUnitMappingFilesComposite
+ *
+ * @version 2.0
+ * @since 2.0
+ */
+public class GenericPersistenceUnitGeneralComposite extends PersistenceUnitGeneralComposite
+                                             implements JpaPageComposite
+{
+	/**
+	 * Creates a new <code>PersistenceUnitGeneralComposite</code>.
+	 *
+	 * @param subjectHolder The holder of this pane's subject
+	 * @param parent The parent container
+	 * @param widgetFactory The factory used to create various common widgets
+	 */
+	public GenericPersistenceUnitGeneralComposite(PropertyValueModel<PersistenceUnit> subjectHolder,
+	                                       Composite container,
+	                                       WidgetFactory widgetFactory) {
+
+		super(subjectHolder, container, widgetFactory);
+	}
+	
+	@Override
+	protected void initializeLayout(Composite container) {
+
+		initializeGeneralPane(container);
+		initializeMappedClassesPane(container);
+		initializeJPAMappingDescriptorsPane(container);
+		initializeJarFilesPane(container);
+	}
+	
+
+	protected void initializeJPAMappingDescriptorsPane(Composite container) {
+
+		container = addCollapsibleSection(
+			container,
+			JptUiPersistenceMessages.PersistenceUnitGeneralComposite_jpaMappingDescriptors,
+			JptUiPersistenceMessages.PersistenceUnitGeneralComposite_jpaMappingDescriptors_description
+		);
+
+		updateGridData(container);
+		updateGridData(container.getParent());
+
+		new GenericPersistenceUnitMappingFilesComposite(this, container);
+	}
+	
+	protected void initializeJarFilesPane(Composite container) {
+
+		container = addCollapsibleSection(
+			container,
+			JptUiPersistenceMessages.PersistenceUnitGeneralComposite_jarFiles
+		);
+		
+		updateGridData(container);
+		updateGridData(container.getParent());
+		
+		new GenericPersistenceUnitJarFilesComposite(this, container);
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/persistence/details/GenericPersistenceUnitJarFilesComposite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/persistence/details/GenericPersistenceUnitJarFilesComposite.java
new file mode 100644
index 0000000..f695596
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/persistence/details/GenericPersistenceUnitJarFilesComposite.java
@@ -0,0 +1,26 @@
+/*******************************************************************************
+ *  Copyright (c) 2009  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.ui.internal.persistence.details;
+
+import org.eclipse.jpt.core.context.persistence.PersistenceUnit;
+import org.eclipse.jpt.ui.internal.widgets.Pane;
+import org.eclipse.swt.widgets.Composite;
+
+public class GenericPersistenceUnitJarFilesComposite
+	extends PersistenceUnitJarFilesComposite
+{
+	public GenericPersistenceUnitJarFilesComposite(
+			Pane<? extends PersistenceUnit> parentPane,
+			Composite parent) {
+
+		super(parentPane, parent);
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/persistence/details/GenericPersistenceUnitMappingFilesComposite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/persistence/details/GenericPersistenceUnitMappingFilesComposite.java
new file mode 100644
index 0000000..7b0c103
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/persistence/details/GenericPersistenceUnitMappingFilesComposite.java
@@ -0,0 +1,52 @@
+/*******************************************************************************
+ * Copyright (c) 2008 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.ui.internal.persistence.details;
+
+import org.eclipse.jpt.core.context.persistence.PersistenceUnit;
+import org.eclipse.jpt.ui.internal.widgets.Pane;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * Here the layout of this pane:
+ * <pre>
+ * -----------------------------------------------------------------------------
+ * | ------------------------------------------------------------------------- |
+ * | |                                                                       | |
+ * | | AddRemoveListPane                                                     | |
+ * | |                                                                       | |
+ * | ------------------------------------------------------------------------- |
+ * -----------------------------------------------------------------------------</pre>
+ *
+ * @see PersistenceUnit
+ * @see PersistenceUnitGeneralComposite - The parent container
+ * @see AddRemoveListPane
+ *
+ * @version 2.0
+ * @since 2.0
+ */
+public class GenericPersistenceUnitMappingFilesComposite extends PersistenceUnitMappingFilesComposite
+{
+	/**
+	 * Creates a new <code>PersistenceUnitMappingFilesComposite</code>.
+	 *
+	 * @param parentPane The parent pane of this one
+	 * @param parent The parent container
+	 */
+	public GenericPersistenceUnitMappingFilesComposite(Pane<? extends PersistenceUnit> parentPane,
+	                                            Composite parent) {
+
+		super(parentPane, parent);
+	}
+
+	@Override
+	protected void initializeLayout(Composite container) {
+		addMappingFilesList(container);
+	}
+}
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/persistence/details/GenericPersistenceXmlUiFactory.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/persistence/details/GenericPersistenceXmlUiFactory.java
new file mode 100644
index 0000000..c1d03e8
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/persistence/details/GenericPersistenceXmlUiFactory.java
@@ -0,0 +1,38 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2009 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.ui.internal.persistence.details;
+
+import java.util.ArrayList;
+import java.util.ListIterator;
+import org.eclipse.jpt.core.context.persistence.PersistenceUnit;
+import org.eclipse.jpt.ui.WidgetFactory;
+import org.eclipse.jpt.ui.details.JpaPageComposite;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+public class GenericPersistenceXmlUiFactory implements PersistenceXmlUiFactory
+{
+	// **************** persistence unit composites ****************************
+	
+	public ListIterator<JpaPageComposite> createPersistenceUnitComposites(
+		PropertyValueModel<PersistenceUnit> subjectHolder,
+		Composite parent,
+		WidgetFactory widgetFactory) {
+
+		ArrayList<JpaPageComposite> pages = new ArrayList<JpaPageComposite>(3);
+
+		pages.add(new GenericPersistenceUnitGeneralComposite(subjectHolder, parent, widgetFactory));
+		pages.add(new PersistenceUnitConnectionComposite(subjectHolder, parent, widgetFactory));
+		pages.add(new PersistenceUnitPropertiesComposite(subjectHolder, parent, widgetFactory));
+
+		return pages.listIterator();
+	}
+
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/persistence/details/PersistenceUnitClassesComposite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/persistence/details/PersistenceUnitClassesComposite.java
new file mode 100644
index 0000000..6f7b693
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/persistence/details/PersistenceUnitClassesComposite.java
@@ -0,0 +1,378 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2010 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.ui.internal.persistence.details;
+
+import java.util.ListIterator;
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.IType;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.core.search.IJavaSearchScope;
+import org.eclipse.jdt.core.search.SearchEngine;
+import org.eclipse.jdt.ui.IJavaElementSearchConstants;
+import org.eclipse.jdt.ui.JavaUI;
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.jface.window.Window;
+import org.eclipse.jpt.core.context.java.JavaPersistentType;
+import org.eclipse.jpt.core.context.persistence.ClassRef;
+import org.eclipse.jpt.core.context.persistence.PersistenceUnit;
+import org.eclipse.jpt.ui.JptUiPlugin;
+import org.eclipse.jpt.ui.internal.JpaHelpContextIds;
+import org.eclipse.jpt.ui.internal.JpaMappingImageHelper;
+import org.eclipse.jpt.ui.internal.JptUiIcons;
+import org.eclipse.jpt.ui.internal.JptUiMessages;
+import org.eclipse.jpt.ui.internal.details.JptUiDetailsMessages;
+import org.eclipse.jpt.ui.internal.persistence.JptUiPersistenceMessages;
+import org.eclipse.jpt.ui.internal.widgets.AddRemoveListPane;
+import org.eclipse.jpt.ui.internal.widgets.Pane;
+import org.eclipse.jpt.ui.internal.widgets.AddRemovePane.Adapter;
+import org.eclipse.jpt.utility.internal.model.value.ItemPropertyListValueModelAdapter;
+import org.eclipse.jpt.utility.internal.model.value.ListAspectAdapter;
+import org.eclipse.jpt.utility.internal.model.value.PropertyAspectAdapter;
+import org.eclipse.jpt.utility.internal.model.value.SimplePropertyValueModel;
+import org.eclipse.jpt.utility.internal.model.value.TransformationPropertyValueModel;
+import org.eclipse.jpt.utility.internal.model.value.swing.ObjectListSelectionModel;
+import org.eclipse.jpt.utility.model.value.ListValueModel;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.jpt.utility.model.value.WritablePropertyValueModel;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.dialogs.SelectionDialog;
+import org.eclipse.ui.progress.IProgressService;
+
+/**
+ * Here the layout of this pane:
+ * <pre>
+ * -----------------------------------------------------------------------------
+ * |                                                                           |
+ * | Description                                                               |
+ * |                                                                           |
+ * | ------------------------------------------------------------------------- |
+ * | |                                                                       | |
+ * | | AddRemoveListPane                                                     | |
+ * | |                                                                       | |
+ * | ------------------------------------------------------------------------- |
+ * |                                                                           |
+ * | x Exclude Unlisted Mapped Classes                                         |
+ * |                                                                           |
+ * -----------------------------------------------------------------------------</pre>
+ *
+ * @see PersistenceUnit
+ * @see PersistenceUnitGeneralComposite - The parent container
+ * @see AddRemoveListPane
+ *
+ * @version 2.3
+ * @since 2.0
+ */
+@SuppressWarnings("nls")
+public class PersistenceUnitClassesComposite extends Pane<PersistenceUnit>
+{
+	/**
+	 * Creates a new <code>PersistenceUnitMappedClassesComposite</code>.
+	 *
+	 * @param parentPane The parent pane of this one
+	 * @param parent The parent container
+	 */
+	public PersistenceUnitClassesComposite(Pane<? extends PersistenceUnit> parentPane,
+	                                             Composite parent) {
+
+		super(parentPane, parent);
+	}
+
+	private void addMappedClass(ObjectListSelectionModel listSelectionModel) {
+
+		IType type = chooseType();
+
+		if (type != null) {
+			String className = type.getFullyQualifiedName('$');
+			if(classRefExists(className)) {
+				return;
+			}
+			ClassRef classRef = getSubject().addSpecifiedClassRef();
+			classRef.setClassName(className);
+			listSelectionModel.setSelectedValue(classRef);
+		}
+	}
+	
+	private boolean classRefExists(String className) {
+		for ( ListIterator<ClassRef> i = getSubject().specifiedClassRefs(); i.hasNext(); ) {
+			ClassRef classRef = i.next();
+			if( classRef.getClassName().equals(className)) {
+				return true;
+			}
+		}
+		return false;
+	}
+
+	private Adapter buildAdapter() {
+		return new AddRemoveListPane.AbstractAdapter() {
+			public void addNewItem(ObjectListSelectionModel listSelectionModel) {
+				addMappedClass(listSelectionModel);
+			}
+
+			@Override
+			public boolean enableOptionOnSelectionChange(ObjectListSelectionModel listSelectionModel) {
+				if (!super.enableOptionOnSelectionChange(listSelectionModel)) {
+					return false;
+				}
+
+				return findType((ClassRef) listSelectionModel.selectedValue()) != null;
+			}
+
+			@Override
+			public boolean hasOptionalButton() {
+				return true;
+			}
+
+			@Override
+			public String optionalButtonText() {
+				return JptUiPersistenceMessages.PersistenceUnitClassesComposite_open;
+			}
+
+			@Override
+			public void optionOnSelection(ObjectListSelectionModel listSelectionModel) {
+				openMappedClass((ClassRef) listSelectionModel.selectedValue());
+			}
+
+			public void removeSelectedItems(ObjectListSelectionModel listSelectionModel) {
+				for (Object item : listSelectionModel.selectedValues()) {
+					getSubject().removeSpecifiedClassRef((ClassRef) item);
+				}
+			}
+		};
+	}
+
+	private WritablePropertyValueModel<Boolean> buildExcludeUnlistedMappedClassesHolder() {
+		return new PropertyAspectAdapter<PersistenceUnit, Boolean>(
+			getSubjectHolder(),
+			PersistenceUnit.SPECIFIED_EXCLUDE_UNLISTED_CLASSES_PROPERTY)
+		{
+			@Override
+			protected Boolean buildValue_() {
+				return this.subject.getSpecifiedExcludeUnlistedClasses();
+			}
+
+			@Override
+			protected void setValue_(Boolean value) {
+				this.subject.setSpecifiedExcludeUnlistedClasses(value);
+			}
+		};
+	}
+
+	private PropertyValueModel<String> buildExcludeUnlistedMappedClassesStringHolder() {
+		return new TransformationPropertyValueModel<Boolean, String>(buildDefaultExcludeUnlistedMappedClassesHolder()) {
+			@Override
+			protected String transform(Boolean value) {
+				if (value != null) {
+					String defaultStringValue = value.booleanValue() ? JptUiDetailsMessages.Boolean_True : JptUiDetailsMessages.Boolean_False;
+					return NLS.bind(JptUiPersistenceMessages.PersistenceUnitClassesComposite_excludeUnlistedMappedClassesWithDefault, defaultStringValue);
+				}
+				return JptUiPersistenceMessages.PersistenceUnitClassesComposite_excludeUnlistedMappedClasses;
+			}
+		};
+	}
+	
+	private PropertyValueModel<Boolean> buildDefaultExcludeUnlistedMappedClassesHolder() {
+		return new PropertyAspectAdapter<PersistenceUnit, Boolean>(
+			getSubjectHolder(),
+			PersistenceUnit.SPECIFIED_EXCLUDE_UNLISTED_CLASSES_PROPERTY,
+			PersistenceUnit.DEFAULT_EXCLUDE_UNLISTED_CLASSES_PROPERTY)
+		{
+			@Override
+			protected Boolean buildValue_() {
+				if (this.subject.getSpecifiedExcludeUnlistedClasses() != null) {
+					return null;
+				}
+				return Boolean.valueOf(this.subject.getDefaultExcludeUnlistedClasses());
+			}
+		};
+	}
+	private ILabelProvider buildLabelProvider() {
+		return new LabelProvider() {
+			@Override
+			public Image getImage(Object element) {
+				ClassRef classRef = (ClassRef) element;
+				JavaPersistentType persistentType = classRef.getJavaPersistentType();
+				Image image = null;
+
+				if (persistentType != null) {
+					image = JpaMappingImageHelper.imageForTypeMapping(persistentType.getMappingKey());
+				}
+
+				if (image != null) {
+					return image;
+				}
+
+				return JptUiPlugin.getImage(JptUiIcons.WARNING);
+			}
+
+			@Override
+			public String getText(Object element) {
+				ClassRef classRef = (ClassRef) element;
+				String name = classRef.getClassName();
+
+				if (name == null) {
+					name = JptUiPersistenceMessages.PersistenceUnitClassesComposite_mappedClassesNoName;
+				}
+
+				return name;
+			}
+		};
+	}
+
+	private ListValueModel<ClassRef> buildItemListHolder() {
+		return new ItemPropertyListValueModelAdapter<ClassRef>(
+			buildListHolder(),
+			ClassRef.JAVA_PERSISTENT_TYPE_PROPERTY,
+			ClassRef.CLASS_NAME_PROPERTY
+		);
+	}
+
+	private ListValueModel<ClassRef> buildListHolder() {
+		return new ListAspectAdapter<PersistenceUnit, ClassRef>(getSubjectHolder(), PersistenceUnit.SPECIFIED_CLASS_REFS_LIST) {
+			@Override
+			protected ListIterator<ClassRef> listIterator_() {
+				return subject.specifiedClassRefs();
+			}
+
+			@Override
+			protected int size_() {
+				return subject.specifiedClassRefsSize();
+			}
+		};
+	}
+
+	private WritablePropertyValueModel<ClassRef> buildSelectedItemHolder() {
+		return new SimplePropertyValueModel<ClassRef>();
+	}
+
+	/**
+	 * Prompts the user the Open Type dialog.
+	 *
+	 * @return Either the selected type or <code>null</code> if the user
+	 * canceled the dialog
+	 */
+	private IType chooseType() {
+		IJavaProject javaProject = getJavaProject();
+		IJavaElement[] elements = new IJavaElement[] { javaProject };
+		IJavaSearchScope scope = SearchEngine.createJavaSearchScope(elements);
+		IProgressService service = PlatformUI.getWorkbench().getProgressService();
+		SelectionDialog typeSelectionDialog;
+
+		try {
+			typeSelectionDialog = JavaUI.createTypeDialog(
+				getShell(),
+				service,
+				scope,
+				IJavaElementSearchConstants.CONSIDER_CLASSES,
+				false,
+				""
+			);
+		}
+		catch (JavaModelException e) {
+			JptUiPlugin.log(e);
+			return null;
+		}
+
+		typeSelectionDialog.setTitle(JptUiMessages.ClassChooserPane_dialogTitle);
+		typeSelectionDialog.setMessage(JptUiMessages.ClassChooserPane_dialogMessage);
+
+		if (typeSelectionDialog.open() == Window.OK) {
+			return (IType) typeSelectionDialog.getResult()[0];
+		}
+
+		return null;
+	}
+
+	private IType findType(ClassRef classRef) {
+		String className = classRef.getClassName();
+
+		if (className != null) {
+			try {
+				return getSubject().getJpaProject().getJavaProject().findType(className.replace('$', '.'));
+			}
+			catch (JavaModelException e) {
+				JptUiPlugin.log(e);
+			}
+		}
+
+		return null;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 */
+	@Override
+	protected void initializeLayout(Composite container) {
+
+		// Description
+		addMultiLineLabel(
+			container,
+			JptUiPersistenceMessages.PersistenceUnitClassesComposite_description
+		);
+
+		// List pane
+		new AddRemoveListPane<PersistenceUnit>(
+			this,
+			container,
+			this.buildAdapter(),
+			this.buildItemListHolder(),
+			this.buildSelectedItemHolder(),
+			this.buildLabelProvider(),
+			JpaHelpContextIds.PERSISTENCE_XML_GENERAL
+		)
+		{
+			@Override
+			protected void initializeTable(Table table) {
+				super.initializeTable(table);
+
+				Composite container = table.getParent();
+				GridData gridData   = (GridData) container.getLayoutData();
+				gridData.heightHint = 75;
+			}
+		};
+
+		this.addTriStateCheckBoxWithDefault(
+			container,
+			JptUiPersistenceMessages.PersistenceUnitClassesComposite_excludeUnlistedMappedClasses,
+			buildExcludeUnlistedMappedClassesHolder(),
+			buildExcludeUnlistedMappedClassesStringHolder(),
+			JpaHelpContextIds.PERSISTENCE_XML_GENERAL
+		);
+	}
+
+	private void openMappedClass(ClassRef classRef) {
+
+		IType type = findType(classRef);
+
+		if (type != null) {
+			try {
+				IJavaElement javaElement = type.getParent();
+				JavaUI.openInEditor(javaElement, true, true);
+			}
+			catch (PartInitException e) {
+				JptUiPlugin.log(e);
+			}
+			catch (JavaModelException e) {
+				JptUiPlugin.log(e);
+			}
+		}
+	}
+
+	private IJavaProject getJavaProject() {
+		return getSubject().getJpaProject().getJavaProject();
+	}
+}
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/persistence/details/PersistenceUnitConnectionComposite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/persistence/details/PersistenceUnitConnectionComposite.java
new file mode 100644
index 0000000..022b85a
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/persistence/details/PersistenceUnitConnectionComposite.java
@@ -0,0 +1,144 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2010 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.ui.internal.persistence.details;
+
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jpt.core.context.persistence.PersistenceUnit;
+import org.eclipse.jpt.ui.WidgetFactory;
+import org.eclipse.jpt.ui.details.JpaPageComposite;
+import org.eclipse.jpt.ui.internal.JpaHelpContextIds;
+import org.eclipse.jpt.ui.internal.persistence.JptUiPersistenceMessages;
+import org.eclipse.jpt.ui.internal.widgets.Pane;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * Here the layout of this pane:
+ * <pre>
+ * -----------------------------------------------------------------------------
+ * |                                                                           |
+ * | - General --------------------------------------------------------------- |
+ * | ------------------------------------------------------------------------- |
+ * | |                                                                       | |
+ * | | PersistenceUnitConnectionGeneralComposite                             | |
+ * | |                                                                       | |
+ * | ------------------------------------------------------------------------- |
+ * |                                                                           |
+ * | - Database -------------------------------------------------------------- |
+ * | ------------------------------------------------------------------------- |
+ * | |                                                                       | |
+ * | | PersistenceUnitConnectionDatabaseComposite                            | |
+ * | |                                                                       | |
+ * | ------------------------------------------------------------------------- |
+ * -----------------------------------------------------------------------------</pre>
+ *
+ * @see PersistenceUnit
+ * @see PersistenceUnitConnectionGeneralComposite
+ * @see PersistenceUnitConnectionDatabaseComposite
+ *
+ * @version 2.0
+ * @since 2.0
+ */
+public class PersistenceUnitConnectionComposite extends Pane<PersistenceUnit>
+                                                implements JpaPageComposite
+{
+	/**
+	 * Creates a new <code>PersistenceUnitConnectionComposite</code>.
+	 *
+	 * @param subjectHolder The holder of this pane's subject
+	 * @param parent The parent container
+	 * @param widgetFactory The factory used to create various common widgets
+	 */
+	public PersistenceUnitConnectionComposite(PropertyValueModel<PersistenceUnit> subjectHolder,
+	                                          Composite container,
+	                                          WidgetFactory widgetFactory) {
+
+		super(subjectHolder, container, widgetFactory);
+	}
+
+	/*
+	 * (non-Javadoc)
+	 */
+	@Override
+	protected Composite addContainer(Composite parent) {
+
+		GridLayout layout = new GridLayout(1, true);
+		layout.marginHeight    = 0;
+		layout.marginWidth     = 0;
+		layout.marginTop       = 0;
+		layout.marginLeft      = 0;
+		layout.marginBottom    = 0;
+		layout.marginRight     = 0;
+		layout.verticalSpacing = 15;
+
+		Composite container = addPane(parent, layout);
+		updateGridData(container);
+
+		return container;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 */
+	public String getHelpID() {
+		return JpaHelpContextIds.PERSISTENCE_XML_CONNECTION;
+	}
+
+	private void initializeDatabasePane(Composite container) {
+
+		container = addSection(
+			container,
+			JptUiPersistenceMessages.PersistenceUnitConnectionComposite_database
+		);
+
+		new PersistenceUnitConnectionDatabaseComposite(this, container);
+	}
+
+	private void initializeGeneralPane(Composite container) {
+
+		container = addSection(
+			container,
+			JptUiPersistenceMessages.PersistenceUnitConnectionComposite_general
+		);
+
+		new PersistenceUnitConnectionGeneralComposite(this, container);
+	}
+
+	/*
+	 * (non-Javadoc)
+	 */
+	@Override
+	protected void initializeLayout(Composite container) {
+
+		initializeGeneralPane(container);
+		initializeDatabasePane(container);
+	}
+
+	public ImageDescriptor getPageImageDescriptor() {
+		return null;
+	}
+
+	public String getPageText() {
+		return JptUiPersistenceMessages.PersistenceUnitConnectionComposite_connection;
+	}
+
+	private void updateGridData(Composite container) {
+
+		GridData gridData = new GridData();
+		gridData.grabExcessHorizontalSpace = true;
+		gridData.grabExcessVerticalSpace   = true;
+		gridData.horizontalAlignment       = SWT.FILL;
+		gridData.verticalAlignment         = SWT.FILL;
+		container.setLayoutData(gridData);
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/persistence/details/PersistenceUnitConnectionDatabaseComposite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/persistence/details/PersistenceUnitConnectionDatabaseComposite.java
new file mode 100644
index 0000000..aca6c6e
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/persistence/details/PersistenceUnitConnectionDatabaseComposite.java
@@ -0,0 +1,159 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2010 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.ui.internal.persistence.details;
+
+import org.eclipse.jpt.core.context.persistence.PersistenceUnit;
+import org.eclipse.jpt.core.context.persistence.PersistenceUnitTransactionType;
+import org.eclipse.jpt.ui.internal.JpaHelpContextIds;
+import org.eclipse.jpt.ui.internal.persistence.JptUiPersistenceMessages;
+import org.eclipse.jpt.ui.internal.widgets.Pane;
+import org.eclipse.jpt.utility.internal.model.value.PropertyAspectAdapter;
+import org.eclipse.jpt.utility.internal.model.value.TransformationPropertyValueModel;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.jpt.utility.model.value.WritablePropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Text;
+
+/**
+ * Here the layout of this pane:
+ * <pre>
+ * -----------------------------------------------------------------------------
+ * |                          ------------------------------------------------ |
+ * | JTA Datasource Name:     | I                                            | |
+ * |                          ------------------------------------------------ |
+ * |                          ------------------------------------------------ |
+ * | Non-JTA Datasource Name: | I                                            | |
+ * |                          ------------------------------------------------ |
+ * -----------------------------------------------------------------------------</pre>
+ *
+ * @see PersistenceUnit
+ * @see PersistenceUnitConnectionComposite - The parent container
+ *
+ * @version 2.0
+ * @since 2.0
+ */
+public class PersistenceUnitConnectionDatabaseComposite extends Pane<PersistenceUnit>
+{
+	/**
+	 * Creates a new <code>PersistenceUnitConnectionDatabaseComposite</code>.
+	 *
+	 * @param parentPane The parent pane of this one
+	 * @param parent The parent container
+	 */
+	public PersistenceUnitConnectionDatabaseComposite(Pane<PersistenceUnit> subjectHolder,
+	                                                  Composite container) {
+
+		super(subjectHolder, container);
+	}
+
+	private PropertyValueModel<Boolean> buildJTADatasourceNameBooleanHolder() {
+		return new TransformationPropertyValueModel<PersistenceUnitTransactionType, Boolean>(buildTransactionTypeHolder()) {
+			@Override
+			protected Boolean transform_(PersistenceUnitTransactionType value) {
+				return Boolean.valueOf(value == PersistenceUnitTransactionType.JTA);
+			}
+		};
+	}
+
+	private WritablePropertyValueModel<String> buildJTADatasourceNameHolder() {
+		return new PropertyAspectAdapter<PersistenceUnit, String>(getSubjectHolder(), PersistenceUnit.JTA_DATA_SOURCE_PROPERTY) {
+			@Override
+			protected String buildValue_() {
+				return subject.getJtaDataSource();
+			}
+
+			@Override
+			protected void setValue_(String value) {
+				if (value.length() == 0) {
+					value = null;
+				}
+				subject.setJtaDataSource(value);
+			}
+		};
+	}
+
+	private PropertyValueModel<Boolean> buildNonJTADatasourceNameBooleanHolder() {
+		return new TransformationPropertyValueModel<PersistenceUnitTransactionType, Boolean>(buildTransactionTypeHolder()) {
+			@Override
+			protected Boolean transform_(PersistenceUnitTransactionType value) {
+				return Boolean.valueOf(value == PersistenceUnitTransactionType.RESOURCE_LOCAL);
+			}
+		};
+	}
+
+	private WritablePropertyValueModel<String> buildNonJTADatasourceNameHolder() {
+		return new PropertyAspectAdapter<PersistenceUnit, String>(getSubjectHolder(), PersistenceUnit.NON_JTA_DATA_SOURCE_PROPERTY) {
+			@Override
+			protected String buildValue_() {
+				return subject.getNonJtaDataSource();
+			}
+
+			@Override
+			protected void setValue_(String value) {
+				if (value.length() == 0) {
+					value = null;
+				}
+				subject.setNonJtaDataSource(value);
+			}
+		};
+	}
+
+	private PropertyValueModel<PersistenceUnitTransactionType> buildTransactionTypeHolder() {
+		return new PropertyAspectAdapter<PersistenceUnit, PersistenceUnitTransactionType>(
+			getSubjectHolder(),
+			PersistenceUnit.DEFAULT_TRANSACTION_TYPE_PROPERTY,
+			PersistenceUnit.SPECIFIED_TRANSACTION_TYPE_PROPERTY)
+		{
+			@Override
+			protected PersistenceUnitTransactionType buildValue_() {
+				return subject.getTransactionType();
+			}
+		};
+	}
+
+	/*
+	 * (non-Javadoc)
+	 */
+	@Override
+	protected void initializeLayout(Composite container) {
+
+		// JTA Datasource Name widgets
+		PropertyValueModel<Boolean> enabled = this.buildJTADatasourceNameBooleanHolder();
+		Label label = addLabel(
+			container, 
+			JptUiPersistenceMessages.PersistenceUnitConnectionDatabaseComposite_jtaDatasourceName,
+			enabled
+		);
+		Text text = addText(
+			container,
+			buildJTADatasourceNameHolder(),
+			JpaHelpContextIds.PERSISTENCE_XML_CONNECTION,
+			enabled
+		);
+		addLabeledComposite(container, label, text, JpaHelpContextIds.PERSISTENCE_XML_CONNECTION);
+		
+		
+		// Non-JTA Datasource Name widgets
+		enabled = this.buildNonJTADatasourceNameBooleanHolder();
+		label = addLabel(
+			container, 
+			JptUiPersistenceMessages.PersistenceUnitConnectionDatabaseComposite_nonJtaDatasourceName,
+			enabled
+		);
+		text = addText(
+			container,
+			buildNonJTADatasourceNameHolder(),
+			JpaHelpContextIds.PERSISTENCE_XML_CONNECTION,
+			enabled
+		);
+		addLabeledComposite(container, label, text, JpaHelpContextIds.PERSISTENCE_XML_CONNECTION);
+	}
+}
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/persistence/details/PersistenceUnitConnectionGeneralComposite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/persistence/details/PersistenceUnitConnectionGeneralComposite.java
new file mode 100644
index 0000000..a4293e4
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/persistence/details/PersistenceUnitConnectionGeneralComposite.java
@@ -0,0 +1,106 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2009 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.ui.internal.persistence.details;
+
+import java.util.Collection;
+import org.eclipse.jpt.core.context.persistence.PersistenceUnit;
+import org.eclipse.jpt.core.context.persistence.PersistenceUnitTransactionType;
+import org.eclipse.jpt.ui.internal.JpaHelpContextIds;
+import org.eclipse.jpt.ui.internal.persistence.JptUiPersistenceMessages;
+import org.eclipse.jpt.ui.internal.widgets.Pane;
+import org.eclipse.jpt.ui.internal.widgets.EnumFormComboViewer;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * Here the layout of this pane:
+ * <pre>
+ * -----------------------------------------------------------------------------
+ * |                    ------------------------------------------------------ |
+ * | Transaction Type:  |                                                  |v| |
+ * |                    ------------------------------------------------------ |
+ * -----------------------------------------------------------------------------</pre>
+ *
+ * @see PersistenceUnit
+ * @see PersistenceUnitConnectionComposite - The parent container
+ *
+ * @version 2.0
+ * @since 2.0
+ */
+public class PersistenceUnitConnectionGeneralComposite extends Pane<PersistenceUnit>
+{
+	/**
+	 * Creates a new <code>PersistenceUnitConnectionGeneralComposite</code>.
+	 *
+	 * @param parentPane The parent pane of this one
+	 * @param parent The parent container
+	 */
+	public PersistenceUnitConnectionGeneralComposite(Pane<PersistenceUnit> subjectHolder,
+	                                                 Composite container) {
+
+		super(subjectHolder, container);
+	}
+
+	private EnumFormComboViewer<PersistenceUnit, PersistenceUnitTransactionType> buildTransactionTypeCombo(Composite container) {
+
+		return new EnumFormComboViewer<PersistenceUnit, PersistenceUnitTransactionType>(this, container) {
+
+			@Override
+			protected void addPropertyNames(Collection<String> propertyNames) {
+				super.addPropertyNames(propertyNames);
+				propertyNames.add(PersistenceUnit.SPECIFIED_TRANSACTION_TYPE_PROPERTY);
+				propertyNames.add(PersistenceUnit.DEFAULT_TRANSACTION_TYPE_PROPERTY);
+			}
+
+			@Override
+			protected PersistenceUnitTransactionType[] getChoices() {
+				return PersistenceUnitTransactionType.values();
+			}
+
+			@Override
+			protected PersistenceUnitTransactionType getDefaultValue() {
+				return getSubject().getDefaultTransactionType();
+			}
+
+			@Override
+			protected String displayString(PersistenceUnitTransactionType value) {
+				return buildDisplayString(
+					JptUiPersistenceMessages.class,
+					PersistenceUnitConnectionGeneralComposite.this,
+					value
+				);
+			}
+
+			@Override
+			protected PersistenceUnitTransactionType getValue() {
+				return getSubject().getSpecifiedTransactionType();
+			}
+
+			@Override
+			protected void setValue(PersistenceUnitTransactionType value) {
+				getSubject().setSpecifiedTransactionType(value);
+			}
+		};
+	}
+
+	/*
+	 * (non-Javadoc)
+	 */
+	@Override
+	protected void initializeLayout(Composite container) {
+
+		// Transaction Type widgets
+		addLabeledComposite(
+			container,
+			JptUiPersistenceMessages.PersistenceUnitConnectionGeneralComposite_transactionType,
+			buildTransactionTypeCombo(container).getControl(),
+			JpaHelpContextIds.PERSISTENCE_XML_CONNECTION
+		);
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/persistence/details/PersistenceUnitGeneralComposite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/persistence/details/PersistenceUnitGeneralComposite.java
new file mode 100644
index 0000000..b9f1403
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/persistence/details/PersistenceUnitGeneralComposite.java
@@ -0,0 +1,230 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2010 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.ui.internal.persistence.details;
+
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jpt.core.context.persistence.PersistenceUnit;
+import org.eclipse.jpt.ui.WidgetFactory;
+import org.eclipse.jpt.ui.details.JpaPageComposite;
+import org.eclipse.jpt.ui.internal.JpaHelpContextIds;
+import org.eclipse.jpt.ui.internal.persistence.JptUiPersistenceMessages;
+import org.eclipse.jpt.ui.internal.widgets.Pane;
+import org.eclipse.jpt.utility.internal.model.value.PropertyAspectAdapter;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.jpt.utility.model.value.WritablePropertyValueModel;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * Here the layout of this pane:
+ * <pre>
+ * -----------------------------------------------------------------------------
+ * |                                                                           |
+ * | - General --------------------------------------------------------------- |
+ * |                         ------------------------------------------------- |
+ * |   Name:                 | I                                             | |
+ * |                         ------------------------------------------------- |
+ * |                         ------------------------------------------------- |
+ * |   Persistence Provider: |                                             |v| |
+ * |                         ------------------------------------------------- |
+ * |                                                                           |
+ * |                                                                           |
+ * | - Mapped Classes -------------------------------------------------------- |
+ * |                                                                           |
+ * |   Description                                                             |
+ * |                                                                           |
+ * |   ----------------------------------------------------------------------- |
+ * |   |                                                                     | |
+ * |   | PersistenceUnitMappedClassesComposite                               | |
+ * |   |                                                                     | |
+ * |   ----------------------------------------------------------------------- |
+ * |                                                                           |
+ * |                                                                           |
+ * | - XML Mapping Files ----------------------------------------------------- |
+ * |                                                                           |
+ * |   Description                                                             |
+ * |                                                                           |
+ * |   ----------------------------------------------------------------------- |
+ * |   |                                                                     | |
+ * |   | PersistenceUnitMappingFilesComposite                                | |
+ * |   |                                                                     | |
+ * |   ----------------------------------------------------------------------- |
+ * |                                                                           |
+ * |                                                                           |
+ * | - JAR Files ------------------------------------------------------------- |
+ * |                                                                           |
+ * |   Description                                                             |
+ * |                                                                           |
+ * |   ----------------------------------------------------------------------- |
+ * |   |                                                                     | |
+ * |   | PersistenceUnitJarFilesComposite                                    | |
+ * |   |                                                                     | |
+ * |   ----------------------------------------------------------------------- |
+ * -----------------------------------------------------------------------------</pre>
+ *
+ * @see PersistenceUnit
+ * @see PersistenceUnitMappedClassesComposite
+ * @see PersistenceUnitMappingFilesComposite
+ * @see PersistenceUnitJarFilesComposite
+ *
+ * @version 2.0
+ * @since 2.0
+ */
+public abstract class PersistenceUnitGeneralComposite extends Pane<PersistenceUnit>
+                                             implements JpaPageComposite
+{
+	/**
+	 * Creates a new <code>PersistenceUnitGeneralComposite</code>.
+	 *
+	 * @param subjectHolder The holder of this pane's subject
+	 * @param parent The parent container
+	 * @param widgetFactory The factory used to create various common widgets
+	 */
+	public PersistenceUnitGeneralComposite(PropertyValueModel<? extends PersistenceUnit> subjectHolder,
+	                                       Composite container,
+	                                       WidgetFactory widgetFactory) {
+
+		super(subjectHolder, container, widgetFactory);
+	}
+	
+
+	/*
+	 * (non-Javadoc)
+	 */
+	@Override
+	protected Composite addContainer(Composite parent) {
+		Composite container = addSubPane(parent);
+		updateGridData(container);
+
+		return container;
+	}
+
+	private WritablePropertyValueModel<String> buildPersistenceProviderHolder() {
+		return new PropertyAspectAdapter<PersistenceUnit, String>(getSubjectHolder(), PersistenceUnit.PROVIDER_PROPERTY) {
+			@Override
+			protected String buildValue_() {
+				return subject.getProvider();
+			}
+
+			@Override
+			protected void setValue_(String value) {
+				if (value.length() == 0) {
+					value = null;
+				}
+				subject.setProvider(value);
+			}
+		};
+	}
+
+	private WritablePropertyValueModel<String> buildPersistenceUnitNameHolder() {
+		return new PropertyAspectAdapter<PersistenceUnit, String>(getSubjectHolder(), PersistenceUnit.NAME_PROPERTY) {
+			@Override
+			protected String buildValue_() {
+				return subject.getName();
+			}
+
+			@Override
+			protected void setValue_(String value) {
+				subject.setName(value);
+			}
+		};
+	}
+
+	private WritablePropertyValueModel<String> buildPersistenceUnitDescriptionHolder() {
+		return new PropertyAspectAdapter<PersistenceUnit, String>(getSubjectHolder(), PersistenceUnit.DESCRIPTION_PROPERTY) {
+			@Override
+			protected String buildValue_() {
+				return subject.getDescription();
+			}
+			
+			@Override
+			protected void setValue_(String value) {
+				if (value.length() == 0) {
+					value = null;
+				}
+				subject.setDescription(value);
+			}
+		};
+	}
+
+	/*
+	 * (non-Javadoc)
+	 */
+	public String getHelpID() {
+		return JpaHelpContextIds.PERSISTENCE_XML_GENERAL;
+	}
+
+	public ImageDescriptor getPageImageDescriptor() {
+		return null;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 */
+	public String getPageText() {
+		return JptUiPersistenceMessages.PersistenceUnitGeneralComposite_general;
+	}
+
+	protected void initializeGeneralPane(Composite container) {
+
+		container = this.addSection(
+			container,
+			JptUiPersistenceMessages.PersistenceUnitGeneralComposite_general
+		);
+
+		// Name widgets
+		this.addLabeledText(
+			container,
+			JptUiPersistenceMessages.PersistenceUnitGeneralComposite_name,
+			this.buildPersistenceUnitNameHolder(),
+			this.getHelpID()
+		);
+
+		// Persistence Provider widgets
+		this.addLabeledText(
+			container,
+			JptUiPersistenceMessages.PersistenceUnitGeneralComposite_persistenceProvider,
+			this.buildPersistenceProviderHolder(),
+			this.getHelpID()
+		);
+
+		// Description widgets
+		this.addLabeledText(
+			container,
+			JptUiPersistenceMessages.PersistenceUnitGeneralComposite_description,
+			this.buildPersistenceUnitDescriptionHolder(),
+			this.getHelpID()
+		);
+	}
+
+	protected void initializeMappedClassesPane(Composite container) {
+
+		container = addCollapsibleSection(
+			container,
+			JptUiPersistenceMessages.PersistenceUnitGeneralComposite_mappedClasses
+		);
+
+		updateGridData(container);
+		updateGridData(container.getParent());
+
+		new PersistenceUnitClassesComposite(this, container);
+	}
+	
+	protected void updateGridData(Composite container) {
+
+		GridData gridData = new GridData();
+		gridData.grabExcessHorizontalSpace = true;
+		gridData.grabExcessVerticalSpace   = true;
+		gridData.horizontalAlignment       = SWT.FILL;
+		gridData.verticalAlignment         = SWT.FILL;
+		container.setLayoutData(gridData);
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/persistence/details/PersistenceUnitJarFilesComposite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/persistence/details/PersistenceUnitJarFilesComposite.java
new file mode 100644
index 0000000..9e94d9b
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/persistence/details/PersistenceUnitJarFilesComposite.java
@@ -0,0 +1,231 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2009 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.ui.internal.persistence.details;
+
+import java.util.ListIterator;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.jpt.core.context.persistence.JarFileRef;
+import org.eclipse.jpt.core.context.persistence.PersistenceUnit;
+import org.eclipse.jpt.ui.JptUiPlugin;
+import org.eclipse.jpt.ui.internal.JpaHelpContextIds;
+import org.eclipse.jpt.ui.internal.JptUiIcons;
+import org.eclipse.jpt.ui.internal.persistence.JptUiPersistenceMessages;
+import org.eclipse.jpt.ui.internal.util.SWTUtil;
+import org.eclipse.jpt.ui.internal.widgets.AddRemoveListPane;
+import org.eclipse.jpt.ui.internal.widgets.Pane;
+import org.eclipse.jpt.ui.internal.widgets.PostExecution;
+import org.eclipse.jpt.ui.internal.widgets.AddRemovePane.Adapter;
+import org.eclipse.jpt.utility.internal.CollectionTools;
+import org.eclipse.jpt.utility.internal.model.value.ItemPropertyListValueModelAdapter;
+import org.eclipse.jpt.utility.internal.model.value.ListAspectAdapter;
+import org.eclipse.jpt.utility.internal.model.value.SimplePropertyValueModel;
+import org.eclipse.jpt.utility.internal.model.value.swing.ObjectListSelectionModel;
+import org.eclipse.jpt.utility.model.value.ListValueModel;
+import org.eclipse.jpt.utility.model.value.WritablePropertyValueModel;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.ui.dialogs.ElementTreeSelectionDialog;
+
+/**
+ * Here the layout of this pane:
+ * <pre>
+ * -----------------------------------------------------------------------------
+ * |                                                                           |
+ * | Description                                                               |
+ * |                                                                           |
+ * | ------------------------------------------------------------------------- |
+ * | |                                                                       | |
+ * | | AddRemoveListPane                                                     | |
+ * | |                                                                       | |
+ * | ------------------------------------------------------------------------- |
+ * -----------------------------------------------------------------------------</pre>
+ *
+ * @see PersistenceUnit
+ * @see PersistenceUnitGeneralComposite - The parent container
+ * @see AddRemoveListPane
+ *
+ * @version 2.0
+ * @since 2.0
+ */
+public abstract class PersistenceUnitJarFilesComposite 
+	extends Pane<PersistenceUnit>
+{
+	/**
+	 * Creates a new <code>PersistenceUnitJPAMappingDescriptorsComposite</code>.
+	 *
+	 * @param parentPane The parent pane of this one
+	 * @param parent The parent container
+	 */
+	public PersistenceUnitJarFilesComposite(
+			Pane<? extends PersistenceUnit> parentPane,
+			Composite parent) {
+
+		super(parentPane, parent, false);
+	}
+
+	
+	
+	@Override
+	protected void initializeLayout(Composite container) {
+		addJarFilesList(container);
+	}
+	
+	protected void addJarFilesList(Composite container) {
+		// List pane
+		new AddRemoveListPane<PersistenceUnit>(
+			this,
+			container,
+			this.buildAdapter(),
+			this.buildItemListHolder(),
+			this.buildSelectedItemHolder(),
+			this.buildLabelProvider(),
+			JpaHelpContextIds.PERSISTENCE_XML_GENERAL
+		) {
+			@Override
+			protected Composite addContainer(Composite parent) {
+				parent = super.addContainer(parent);
+				updateGridData(parent);
+				return parent;
+			}
+	
+			@Override
+			protected void initializeLayout(Composite container) {
+				super.initializeLayout(container);
+				updateGridData(getContainer());
+			}
+		};
+	}
+	
+	private void updateGridData(Composite container) {
+		GridData gridData = new GridData();
+		gridData.grabExcessHorizontalSpace = true;
+		gridData.grabExcessVerticalSpace   = true;
+		gridData.horizontalAlignment       = SWT.FILL;
+		gridData.verticalAlignment         = SWT.FILL;
+		container.setLayoutData(gridData);
+	}
+	
+	private Adapter buildAdapter() {
+		return new AddRemoveListPane.AbstractAdapter() {
+			public void addNewItem(ObjectListSelectionModel listSelectionModel) {
+				addJarFileRef(listSelectionModel);
+			}
+			
+			public void removeSelectedItems(ObjectListSelectionModel listSelectionModel) {
+				for (Object item : listSelectionModel.selectedValues()) {
+					getSubject().removeJarFileRef((JarFileRef) item);
+				}
+			}
+		};
+	}
+	
+	private ListValueModel<JarFileRef> buildItemListHolder() {
+		return new ItemPropertyListValueModelAdapter<JarFileRef>(
+			buildListHolder(),
+			JarFileRef.FILE_NAME_PROPERTY
+		);
+	}
+	
+	private ListValueModel<JarFileRef> buildListHolder() {
+		return new ListAspectAdapter<PersistenceUnit, JarFileRef>(getSubjectHolder(), PersistenceUnit.JAR_FILE_REFS_LIST) {
+			@Override
+			protected ListIterator<JarFileRef> listIterator_() {
+				return this.subject.jarFileRefs();
+			}
+			
+			@Override
+			protected int size_() {
+				return this.subject.jarFileRefsSize();
+			}
+		};
+	}
+	
+	private WritablePropertyValueModel<JarFileRef> buildSelectedItemHolder() {
+		return new SimplePropertyValueModel<JarFileRef>();
+	}
+	
+	private ILabelProvider buildLabelProvider() {
+		return new LabelProvider() {
+			@Override
+			public Image getImage(Object element) {
+				return JptUiPlugin.getImage(JptUiIcons.JAR_FILE_REF);
+			}
+			
+			@Override
+			public String getText(Object element) {
+				JarFileRef jarFileRef = (JarFileRef) element;
+				String name = jarFileRef.getFileName();
+				
+				if (name == null) {
+					name = JptUiPersistenceMessages.PersistenceUnitJarFilesComposite_noFileName;
+				}
+				
+				return name;
+			}
+		};
+	}
+	
+	private void addJarFileRef(ObjectListSelectionModel listSelectionModel) {
+		IProject project = getSubject().getJpaProject().getProject();
+
+		ElementTreeSelectionDialog dialog = new ArchiveFileSelectionDialog(
+			getShell(), buildJarFileDeploymentPathCalculator());
+		
+		dialog.setHelpAvailable(false);
+		dialog.setTitle(JptUiPersistenceMessages.PersistenceUnitMappingFilesComposite_jarFileDialog_title);
+		dialog.setMessage(JptUiPersistenceMessages.PersistenceUnitMappingFilesComposite_jarFileDialog_message);
+		dialog.setInput(project);
+		
+		SWTUtil.show(
+			dialog,
+			buildSelectionDialogPostExecution(listSelectionModel)
+		);
+	}
+	
+	protected ArchiveFileSelectionDialog.DeploymentPathCalculator buildJarFileDeploymentPathCalculator() {
+		return new ArchiveFileSelectionDialog.ModuleDeploymentPathCalculator();
+	}
+	
+	private PostExecution<ElementTreeSelectionDialog> buildSelectionDialogPostExecution(
+			final ObjectListSelectionModel listSelectionModel) {
+		return new PostExecution<ElementTreeSelectionDialog>() {
+			public void execute(ElementTreeSelectionDialog dialog) {
+				if (dialog.getReturnCode() == IDialogConstants.CANCEL_ID) {
+					return;
+				}
+				
+				for (Object result : dialog.getResult()) {
+					String filePath = (String) result;
+					if (jarFileRefExists(filePath)) {
+						continue;
+					}
+					JarFileRef jarFileRef = getSubject().addJarFileRef();
+					jarFileRef.setFileName(filePath);
+
+					listSelectionModel.addSelectedValue(jarFileRef);
+				}
+			}
+		};
+	}
+	
+	private boolean jarFileRefExists(String fileName) {
+		for (JarFileRef each : CollectionTools.iterable(getSubject().jarFileRefs())) {
+			if (each.getFileName().equals(fileName)) {
+				return true;
+			}
+		}
+		return false;
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/persistence/details/PersistenceUnitMappingFilesComposite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/persistence/details/PersistenceUnitMappingFilesComposite.java
new file mode 100644
index 0000000..4688118
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/persistence/details/PersistenceUnitMappingFilesComposite.java
@@ -0,0 +1,362 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2009 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.ui.internal.persistence.details;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.util.ListIterator;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jdt.core.IClasspathEntry;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.jpt.core.context.persistence.MappingFileRef;
+import org.eclipse.jpt.core.context.persistence.PersistenceUnit;
+import org.eclipse.jpt.ui.JptUiPlugin;
+import org.eclipse.jpt.ui.internal.JpaHelpContextIds;
+import org.eclipse.jpt.ui.internal.JptUiIcons;
+import org.eclipse.jpt.ui.internal.jface.XmlMappingFileViewerFilter;
+import org.eclipse.jpt.ui.internal.persistence.JptUiPersistenceMessages;
+import org.eclipse.jpt.ui.internal.util.SWTUtil;
+import org.eclipse.jpt.ui.internal.widgets.AddRemoveListPane;
+import org.eclipse.jpt.ui.internal.widgets.Pane;
+import org.eclipse.jpt.ui.internal.widgets.PostExecution;
+import org.eclipse.jpt.ui.internal.widgets.AddRemovePane.Adapter;
+import org.eclipse.jpt.utility.internal.model.value.ItemPropertyListValueModelAdapter;
+import org.eclipse.jpt.utility.internal.model.value.ListAspectAdapter;
+import org.eclipse.jpt.utility.internal.model.value.SimplePropertyValueModel;
+import org.eclipse.jpt.utility.internal.model.value.swing.ObjectListSelectionModel;
+import org.eclipse.jpt.utility.model.value.ListValueModel;
+import org.eclipse.jpt.utility.model.value.WritablePropertyValueModel;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.ui.dialogs.ElementTreeSelectionDialog;
+import org.eclipse.ui.dialogs.ISelectionStatusValidator;
+import org.eclipse.ui.model.WorkbenchContentProvider;
+import org.eclipse.ui.model.WorkbenchLabelProvider;
+import org.eclipse.ui.views.navigator.ResourceComparator;
+import org.xml.sax.Attributes;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+import org.xml.sax.helpers.DefaultHandler;
+
+/**
+ * Here the layout of this pane:
+ * <pre>
+ * -----------------------------------------------------------------------------
+ * | ------------------------------------------------------------------------- |
+ * | |                                                                       | |
+ * | | AddRemoveListPane                                                     | |
+ * | |                                                                       | |
+ * | ------------------------------------------------------------------------- |
+ * -----------------------------------------------------------------------------</pre>
+ *
+ * @see PersistenceUnit
+ * @see PersistenceUnitGeneralComposite - The parent container
+ * @see AddRemoveListPane
+ *
+ * @version 2.0
+ * @since 2.0
+ */
+@SuppressWarnings("nls")
+public abstract class PersistenceUnitMappingFilesComposite extends Pane<PersistenceUnit>
+{
+	/**
+	 * Creates a new <code>PersistenceUnitMappingFilesComposite</code>.
+	 *
+	 * @param parentPane The parent pane of this one
+	 * @param parent The parent container
+	 */
+	public PersistenceUnitMappingFilesComposite(Pane<? extends PersistenceUnit> parentPane,
+	                                            Composite parent) {
+
+		super(parentPane, parent);
+	}
+	
+	protected void addMappingFilesList(Composite container) {
+		// List pane
+		new AddRemoveListPane<PersistenceUnit>(
+			this,
+			container,
+			buildAdapter(),
+			buildItemListHolder(),
+			buildSelectedItemHolder(),
+			buildLabelProvider(),
+			JpaHelpContextIds.PERSISTENCE_XML_GENERAL
+		) {
+			@Override
+			protected Composite addContainer(Composite parent) {
+				parent = super.addContainer(parent);
+				updateGridData(parent);
+				return parent;
+			}
+	
+			@Override
+			protected void initializeLayout(Composite container) {
+				super.initializeLayout(container);
+				updateGridData(getContainer());
+			}
+		};
+	}
+
+	/**
+	 * Prompts a dialog showing a tree structure of the source paths where the
+	 * only files shown are JPA mapping descriptors file. The XML file has to be
+	 * an XML file with the root tag: {@code <entity-mappings>}.
+	 *
+	 * @param listSelectionModel The selection model used to select the new files
+	 */
+	private void addJPAMappingDescriptor(ObjectListSelectionModel listSelectionModel) {
+
+		IProject project = getSubject().getJpaProject().getProject();
+
+		ElementTreeSelectionDialog dialog = new ElementTreeSelectionDialog(
+			getShell(),
+			new WorkbenchLabelProvider(),
+			new WorkbenchContentProvider()
+		);
+
+		dialog.setHelpAvailable(false);
+		dialog.setValidator(buildValidator());
+		dialog.setTitle(JptUiPersistenceMessages.PersistenceUnitMappingFilesComposite_mappingFileDialog_title);
+		dialog.setMessage(JptUiPersistenceMessages.PersistenceUnitMappingFilesComposite_mappingFileDialog_message);
+		dialog.addFilter(new XmlMappingFileViewerFilter(getSubject().getJpaProject()));
+		dialog.setInput(project);
+		dialog.setComparator(new ResourceComparator(ResourceComparator.NAME));
+
+		SWTUtil.show(
+			dialog,
+			buildSelectionDialogPostExecution(listSelectionModel)
+		);
+	}
+
+	private Adapter buildAdapter() {
+		return new AddRemoveListPane.AbstractAdapter() {
+			public void addNewItem(ObjectListSelectionModel listSelectionModel) {
+				addJPAMappingDescriptor(listSelectionModel);
+			}
+
+			public void removeSelectedItems(ObjectListSelectionModel listSelectionModel) {
+				for (Object item : listSelectionModel.selectedValues()) {
+					getSubject().removeSpecifiedMappingFileRef((MappingFileRef) item);
+				}
+			}
+		};
+	}
+
+	/*
+	 * (non-Javadoc)
+	 */
+	@Override
+	protected Composite addContainer(Composite parent) {
+
+		GridLayout layout = new GridLayout(1, true);
+		layout.marginHeight = 0;
+		layout.marginWidth  = 0;
+		layout.marginTop    = 0;
+		layout.marginLeft   = 0;
+		layout.marginBottom = 0;
+		layout.marginRight  = 0;
+
+		Composite container = addPane(parent, layout);
+		updateGridData(container);
+
+		return container;
+	}
+
+	private ListValueModel<MappingFileRef> buildItemListHolder() {
+		return new ItemPropertyListValueModelAdapter<MappingFileRef>(
+			buildListHolder(),
+			MappingFileRef.FILE_NAME_PROPERTY
+		);
+	}
+
+	private ILabelProvider buildLabelProvider() {
+		return new LabelProvider() {
+			@Override
+			public Image getImage(Object element) {
+				return JptUiPlugin.getImage(JptUiIcons.MAPPING_FILE_REF);
+			}
+
+			@Override
+			public String getText(Object element) {
+				MappingFileRef mappingFileRef = (MappingFileRef) element;
+				String name = mappingFileRef.getFileName();
+
+				if (name == null) {
+					name = JptUiPersistenceMessages.PersistenceUnitMappingFilesComposite_ormNoName;
+				}
+
+				return name;
+			}
+		};
+	}
+
+	private ListValueModel<MappingFileRef> buildListHolder() {
+		return new ListAspectAdapter<PersistenceUnit, MappingFileRef>(getSubjectHolder(), PersistenceUnit.SPECIFIED_MAPPING_FILE_REFS_LIST) {
+			@Override
+			protected ListIterator<MappingFileRef> listIterator_() {
+				return this.subject.specifiedMappingFileRefs();
+			}
+
+			@Override
+			protected int size_() {
+				return this.subject.specifiedMappingFileRefsSize();
+			}
+		};
+	}
+
+	private WritablePropertyValueModel<MappingFileRef> buildSelectedItemHolder() {
+		return new SimplePropertyValueModel<MappingFileRef>();
+	}
+
+	private PostExecution<ElementTreeSelectionDialog> buildSelectionDialogPostExecution(final ObjectListSelectionModel listSelectionModel) {
+		return new PostExecution<ElementTreeSelectionDialog>() {
+			public void execute(ElementTreeSelectionDialog dialog) {
+
+				if (dialog.getReturnCode() == IDialogConstants.CANCEL_ID) {
+					return;
+				}
+
+				for (Object result : dialog.getResult()) {
+					IFile file = (IFile) result;
+					IPath filePath = removeSourcePath(file);
+					String fileName = filePath.toPortableString();
+					if(mappingFileRefExists(fileName)) {
+						continue;
+					}
+					MappingFileRef mappingFileRef = getSubject().addSpecifiedMappingFileRef();
+					mappingFileRef.setFileName(fileName);
+
+					listSelectionModel.addSelectedValue(mappingFileRef);
+				}
+			}
+		};
+	}
+	
+	private boolean mappingFileRefExists(String fileName) {
+		for ( ListIterator<MappingFileRef> i = getSubject().specifiedMappingFileRefs(); i.hasNext(); ) {
+			MappingFileRef mappingFileRef = i.next();
+			if( mappingFileRef.getFileName().equals(fileName)) {
+				return true;
+			}
+		}
+		return false;
+	}
+
+	private ISelectionStatusValidator buildValidator() {
+		return new ISelectionStatusValidator() {
+			public IStatus validate(Object[] selection) {
+
+				if (selection.length == 0) {
+					return new Status(IStatus.ERROR, JptUiPlugin.PLUGIN_ID, "");
+				}
+
+				for (Object item : selection) {
+					if (item instanceof IFolder) {
+						return new Status(IStatus.ERROR, JptUiPlugin.PLUGIN_ID, "");
+					}
+				}
+
+				return new Status(IStatus.OK, JptUiPlugin.PLUGIN_ID, "");
+			}
+		};
+	}
+
+	/**
+	 * Returns the path of the given file excluding the source folder.
+	 *
+	 * @param file The file to retrieve its path minus the source folder
+	 * @return The relative path of the given path, the path is relative to the
+	 * source path
+	 */
+	private IPath removeSourcePath(IFile file) {
+		IJavaProject javaProject = getSubject().getJpaProject().getJavaProject();
+		IPath filePath = file.getProjectRelativePath();
+
+		try {
+			for (IClasspathEntry entry : javaProject.getRawClasspath()) {
+
+				// Only check for source paths
+				if (entry.getEntryKind() == IClasspathEntry.CPE_SOURCE) {
+
+					// Retrieve the source path relative to the project
+					IPath sourcePath = entry.getPath().removeFirstSegments(1);
+
+					// Check to see if the file path starts with the source path
+					if (sourcePath.isPrefixOf(filePath)) {
+						int count = sourcePath.segmentCount();
+						filePath = filePath.removeFirstSegments(count);
+						break;
+					}
+				}
+			}
+		}
+		catch (JavaModelException e) {
+			JptUiPlugin.log(e.getStatus());
+		}
+
+		return filePath;
+	}
+
+	private void updateGridData(Composite container) {
+
+		GridData gridData = new GridData();
+		gridData.grabExcessHorizontalSpace = true;
+		gridData.grabExcessVerticalSpace   = true;
+		gridData.horizontalAlignment       = SWT.FILL;
+		gridData.verticalAlignment         = SWT.FILL;
+		container.setLayoutData(gridData);
+	}
+
+	//TODO might we want to do this with content-types instead?  is there
+	//the potential that an extender could hae a mapping file that doesn't have
+	//entity-mappings as the root node??
+	/**
+	 * This handler is responsible to parse the root tag (local name) only.
+	 */
+	private static class SAXHandler extends DefaultHandler {
+
+		private String rootTagName;
+
+		public String getRootTagName() {
+			return this.rootTagName;
+		}
+
+		@Override
+		public InputSource resolveEntity(String publicId,
+		                                 String systemId) throws IOException, SAXException {
+
+			InputSource inputSource = new InputSource();
+			inputSource.setByteStream(new ByteArrayInputStream(new byte[0]));
+			return inputSource;
+		}
+
+		@Override
+		public void startElement(String uri,
+		                         String localName,
+		                         String name,
+		                         Attributes attributes) throws SAXException {
+
+			this.rootTagName = name;
+			throw new SAXException();
+		}
+	}
+}
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/persistence/details/PersistenceUnitPropertiesComposite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/persistence/details/PersistenceUnitPropertiesComposite.java
new file mode 100644
index 0000000..ecf5424
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/persistence/details/PersistenceUnitPropertiesComposite.java
@@ -0,0 +1,419 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2010 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.ui.internal.persistence.details;
+
+import java.util.ListIterator;
+
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.viewers.CellEditor;
+import org.eclipse.jface.viewers.IBaseLabelProvider;
+import org.eclipse.jface.viewers.ICellModifier;
+import org.eclipse.jface.viewers.ITableLabelProvider;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.jface.viewers.TableViewer;
+import org.eclipse.jface.viewers.TextCellEditor;
+import org.eclipse.jpt.core.context.persistence.PersistenceUnit;
+import org.eclipse.jpt.ui.WidgetFactory;
+import org.eclipse.jpt.ui.details.JpaPageComposite;
+import org.eclipse.jpt.ui.internal.JpaHelpContextIds;
+import org.eclipse.jpt.ui.internal.details.java.BaseJavaUiFactory;
+import org.eclipse.jpt.ui.internal.persistence.JptUiPersistenceMessages;
+import org.eclipse.jpt.ui.internal.swt.ColumnAdapter;
+import org.eclipse.jpt.ui.internal.util.SWTUtil;
+import org.eclipse.jpt.ui.internal.widgets.AddRemoveTablePane;
+import org.eclipse.jpt.ui.internal.widgets.Pane;
+import org.eclipse.jpt.utility.internal.model.value.ListAspectAdapter;
+import org.eclipse.jpt.utility.internal.model.value.PropertyAspectAdapter;
+import org.eclipse.jpt.utility.internal.model.value.SimplePropertyValueModel;
+import org.eclipse.jpt.utility.internal.model.value.swing.ObjectListSelectionModel;
+import org.eclipse.jpt.utility.model.event.ListAddEvent;
+import org.eclipse.jpt.utility.model.event.ListChangeEvent;
+import org.eclipse.jpt.utility.model.event.ListRemoveEvent;
+import org.eclipse.jpt.utility.model.value.ListValueModel;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.jpt.utility.model.value.WritablePropertyValueModel;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.TableColumn;
+import org.eclipse.swt.widgets.TableItem;
+
+/**
+ * Here the layout of this pane:
+ * <pre>
+ * -----------------------------------------------------------------------------
+ * | - Properties ------------------------------------------------------------ |
+ * |                                                                           |
+ * |   Description                                                             |
+ * |                                                                           |
+ * |   ----------------------------------------------------------------------- |
+ * |   |                                                                     | |
+ * |   | AddRemoveTablePane                                                  | |
+ * |   |                                                                     | |
+ * |   ----------------------------------------------------------------------- |
+ * -----------------------------------------------------------------------------</pre>
+ *
+ * @see PersistenceUnit
+ * @see BaseJavaUiFactory - The invoker
+ * @see AddRemoveTablePane
+ *
+ * @version 2.3
+ * @since 2.0
+ */
+@SuppressWarnings("nls")
+public class PersistenceUnitPropertiesComposite extends Pane<PersistenceUnit>
+                                                implements JpaPageComposite
+{
+	private WritablePropertyValueModel<PersistenceUnit.Property> propertyHolder;
+	private TablePane tablePane;
+
+	/**
+	 * Creates a new <code>PersistenceUnitPropertiesComposite</code>.
+	 *
+	 * @param subjectHolder The holder of this pane's subject
+	 * @param parent The parent container
+	 * @param widgetFactory The factory used to create various common widgets
+	 */
+	public PersistenceUnitPropertiesComposite(PropertyValueModel<PersistenceUnit> subjectHolder,
+	                                          Composite container,
+	                                          WidgetFactory widgetFactory) {
+
+		super(subjectHolder, container, widgetFactory);
+	}
+
+	private ListValueModel<PersistenceUnit.Property> buildPropertiesListHolder() {
+		return new ListAspectAdapter<PersistenceUnit, PersistenceUnit.Property>(getSubjectHolder(), PersistenceUnit.PROPERTIES_LIST) {
+			@Override
+			protected ListIterator<PersistenceUnit.Property> listIterator_() {
+				return subject.properties();
+			}
+
+			@Override
+			protected int size_() {
+				return subject.propertiesSize();
+			}
+		};
+	}
+
+	private ITableLabelProvider buildPropertyLabelProvider() {
+		return new TableLabelProvider();
+	}
+
+	private AddRemoveTablePane.Adapter buildTableAdapter() {
+		return new AddRemoveTablePane.AbstractAdapter() {
+
+			public void addNewItem(ObjectListSelectionModel listSelectionModel) {
+
+				PersistenceUnit.Property property = getSubject().addProperty();
+				propertyHolder.setValue(property);
+
+				tablePane.getTableViewer().editElement(
+					property,
+					PropertyColumnAdapter.NAME_COLUMN
+				);
+			}
+
+			public void removeSelectedItems(ObjectListSelectionModel listSelectionModel) {
+				for (Object item : listSelectionModel.selectedValues()) {
+					getSubject().removeProperty((PersistenceUnit.Property) item);
+				}
+			}
+		};
+	}
+
+	public String getHelpID() {
+		return JpaHelpContextIds.PERSISTENCE_XML_PROPERTIES;
+	}
+
+	public ImageDescriptor getPageImageDescriptor() {
+		return null;
+	}
+
+	public String getPageText() {
+		return JptUiPersistenceMessages.PersistenceUnitPropertiesComposite_properties;
+	}
+
+	@Override
+	protected void initialize() {
+		super.initialize();
+		propertyHolder = new SimplePropertyValueModel<PersistenceUnit.Property>();
+	}
+
+	@Override
+	protected void initializeLayout(Composite container) {
+
+		addLabel(
+			container,
+			JptUiPersistenceMessages.PersistenceUnitPropertiesComposite_properties_description
+		);
+
+		tablePane = new TablePane(container);
+		container.setLayoutData(new GridData(GridData.FILL_BOTH));
+	}
+
+	private static class PropertyColumnAdapter implements ColumnAdapter<PersistenceUnit.Property> {
+
+		public static final int COLUMN_COUNT = 3;
+		public static final int NAME_COLUMN = 1;
+		public static final int SELECTION_COLUMN = 0;
+		public static final int VALUE_COLUMN = 2;
+
+		private WritablePropertyValueModel<String> buildNameHolder(PersistenceUnit.Property subject) {
+			return new PropertyAspectAdapter<PersistenceUnit.Property, String>(PersistenceUnit.Property.NAME_PROPERTY, subject) {
+				@Override
+				protected String buildValue_() {
+					return subject.getName();
+				}
+
+				@Override
+				protected void setValue_(String value) {
+					subject.setName(value);
+				}
+			};
+		}
+
+		private WritablePropertyValueModel<String> buildValueHolder(PersistenceUnit.Property subject) {
+			return new PropertyAspectAdapter<PersistenceUnit.Property, String>(PersistenceUnit.Property.VALUE_PROPERTY, subject) {
+				@Override
+				protected String buildValue_() {
+					return subject.getValue();
+				}
+
+				@Override
+				protected void setValue_(String value) {
+					subject.setValue(value);
+				}
+			};
+		}
+
+		public WritablePropertyValueModel<?>[] cellModels(PersistenceUnit.Property subject) {
+			WritablePropertyValueModel<?>[] holders = new WritablePropertyValueModel<?>[COLUMN_COUNT];
+			holders[SELECTION_COLUMN] = new SimplePropertyValueModel<Object>();
+			holders[NAME_COLUMN]      = buildNameHolder(subject);
+			holders[VALUE_COLUMN]     = buildValueHolder(subject);
+			return holders;
+		}
+
+		public int columnCount() {
+			return COLUMN_COUNT;
+		}
+
+		public String columnName(int columnIndex) {
+
+			switch (columnIndex) {
+				case PropertyColumnAdapter.NAME_COLUMN: {
+					return JptUiPersistenceMessages.PersistenceUnitPropertiesComposite_nameColumn;
+				}
+
+				case PropertyColumnAdapter.VALUE_COLUMN: {
+					return JptUiPersistenceMessages.PersistenceUnitPropertiesComposite_valueColumn;
+				}
+
+				default: {
+					return null;
+				}
+			}
+		}
+	}
+
+	private class TableLabelProvider extends LabelProvider
+	                                 implements ITableLabelProvider {
+
+		public Image getColumnImage(Object element, int columnIndex) {
+			return null;
+		}
+
+		public String getColumnText(Object element, int columnIndex) {
+
+			PersistenceUnit.Property property = (PersistenceUnit.Property) element;
+			String value = null;
+
+			switch (columnIndex) {
+				case PropertyColumnAdapter.NAME_COLUMN: {
+					value = property.getName();
+					break;
+				}
+
+				case PropertyColumnAdapter.VALUE_COLUMN: {
+					value = property.getValue();
+					break;
+				}
+			}
+
+			if (value == null) {
+				value = "";
+			}
+
+			return value;
+		}
+	}
+
+	private class TablePane extends AddRemoveTablePane<PersistenceUnit> {
+
+		private final String SELECTION_COLUMN = "selection";
+
+		private TableViewer tableViewer;
+
+		private TablePane(Composite parent) {
+			super(PersistenceUnitPropertiesComposite.this,
+			      parent,
+					buildTableAdapter(),
+					buildPropertiesListHolder(),
+					propertyHolder,
+					buildPropertyLabelProvider());
+		}
+
+		@Override
+		protected Composite addContainer(Composite parent) {
+			Composite container = super.addContainer(parent);
+			container.setLayoutData(new GridData(GridData.FILL_BOTH));
+			return container;
+		}
+
+		private CellEditor[] buildCellEditors(Table table) {
+			return new CellEditor[] {
+				null,
+				new TextCellEditor(table),
+				new TextCellEditor(table)
+			};
+		}
+
+		private ICellModifier buildCellModifier() {
+			return new ICellModifier() {
+
+				public boolean canModify(Object element, String property) {
+					return !SELECTION_COLUMN.equals(property);
+				}
+
+				public Object getValue(Object element, String property) {
+					PersistenceUnit.Property propertyModel = (PersistenceUnit.Property) element;
+					String value = null;
+
+					if (property == PersistenceUnit.Property.NAME_PROPERTY) {
+						value = propertyModel.getName();
+					}
+					else if (property == PersistenceUnit.Property.VALUE_PROPERTY) {
+						value = propertyModel.getValue();
+					}
+
+					if (value == null) {
+						value = "";
+					}
+
+					return value;
+				}
+
+				public void modify(Object element, String property, Object value) {
+					PersistenceUnit.Property propertyModel;
+
+					if (element instanceof TableItem) {
+						TableItem tableItem = (TableItem) element;
+						propertyModel = (PersistenceUnit.Property) tableItem.getData();
+					}
+					else {
+						propertyModel = (PersistenceUnit.Property) element;
+					}
+
+					if (property == PersistenceUnit.Property.NAME_PROPERTY) {
+						propertyModel.setName(value.toString());
+					}
+					else if (property == PersistenceUnit.Property.VALUE_PROPERTY) {
+						propertyModel.setValue(value.toString());
+					}
+				}
+			};
+		}
+
+		@Override
+		protected ColumnAdapter<?> buildColumnAdapter() {
+			return new PropertyColumnAdapter();
+		}
+
+		private String[] buildColumnProperties() {
+			return new String[] {
+				SELECTION_COLUMN,
+				PersistenceUnit.Property.NAME_PROPERTY,
+				PersistenceUnit.Property.VALUE_PROPERTY
+			};
+		}
+
+		TableViewer getTableViewer() {
+			return tableViewer;
+		}
+
+		@Override
+		protected void initializeMainComposite(Composite container,
+		                                       Adapter adapter,
+		                                       ListValueModel<?> listHolder,
+		                                       WritablePropertyValueModel<?> selectedItemHolder,
+		                                       IBaseLabelProvider labelProvider,
+		                                       String helpId) {
+
+			super.initializeMainComposite(
+				container,
+				adapter,
+				listHolder,
+				selectedItemHolder,
+				labelProvider,
+				helpId
+			);
+
+			Table table = getMainControl();
+			table.setLayoutData(new GridData(GridData.FILL_BOTH));
+
+			// Make the selection column non-resizable since it's only used to
+			// ease the selection of rows
+			TableColumn selectionColumn = table.getColumn(PropertyColumnAdapter.SELECTION_COLUMN);
+			selectionColumn.setResizable(false);
+			selectionColumn.setWidth(20);
+
+			// Install the editors
+			tableViewer = new TableViewer(table);
+			tableViewer.setCellEditors(buildCellEditors(table));
+			tableViewer.setCellModifier(buildCellModifier());
+			tableViewer.setColumnProperties(buildColumnProperties());
+		}
+
+		@Override
+		protected void itemsAdded(ListAddEvent e) {
+			super.itemsAdded(e);
+			revalidateLayout();
+		}
+
+		@Override
+		protected void itemsRemoved(ListRemoveEvent e) {
+			super.itemsRemoved(e);
+			revalidateLayout();
+		}
+
+		@Override
+		protected void listChanged(ListChangeEvent e) {
+			super.listChanged(e);
+			revalidateLayout();
+		}
+
+		/**
+		 * Revalidates the table layout after the list of items has changed. The
+		 * layout has to be done in a new UI thread because our listener might be
+		 * notified before the table has been updated (table column added or removed).
+		 */
+		private void revalidateLayout() {
+			SWTUtil.asyncExec(new Runnable() { public void run() {
+				Table table = getMainControl();
+				if (!table.isDisposed()) {
+					// We have to do a total relayout of the tab otherwise the
+					// table might become cut off at the bottom
+					SWTUtil.reflow(table);
+				}
+			}});
+		}
+	}
+}
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/persistence/details/PersistenceXmlUiDefinition.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/persistence/details/PersistenceXmlUiDefinition.java
new file mode 100644
index 0000000..b21f630
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/persistence/details/PersistenceXmlUiDefinition.java
@@ -0,0 +1,53 @@
+/*******************************************************************************
+ *  Copyright (c) 2009  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.ui.internal.persistence.details;
+
+import org.eclipse.jpt.core.JpaResourceType;
+import org.eclipse.jpt.core.JptCorePlugin;
+import org.eclipse.jpt.ui.ResourceUiDefinition;
+import org.eclipse.jpt.ui.internal.structure.PersistenceResourceModelStructureProvider;
+import org.eclipse.jpt.ui.structure.JpaStructureProvider;
+
+public class PersistenceXmlUiDefinition extends AbstractPersistenceXmlResourceUiDefinition
+{
+	// singleton
+	private static final ResourceUiDefinition INSTANCE = new PersistenceXmlUiDefinition();
+	
+	
+	/**
+	 * Return the singleton
+	 */
+	public static ResourceUiDefinition instance() {
+		return INSTANCE;
+	}
+	
+	
+	/**
+	 * Enforce singleton usage
+	 */
+	private PersistenceXmlUiDefinition() {
+		super();
+	}
+	
+	
+	@Override
+	protected PersistenceXmlUiFactory buildPersistenceXmlUiFactory() {
+		return new GenericPersistenceXmlUiFactory();
+	}
+	
+	public boolean providesUi(JpaResourceType resourceType) {
+		return resourceType.equals(JptCorePlugin.PERSISTENCE_XML_1_0_RESOURCE_TYPE);
+	}
+	
+	public JpaStructureProvider getStructureProvider() {
+		return PersistenceResourceModelStructureProvider.instance();
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/persistence/details/PersistenceXmlUiFactory.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/persistence/details/PersistenceXmlUiFactory.java
new file mode 100644
index 0000000..f8d0376
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/persistence/details/PersistenceXmlUiFactory.java
@@ -0,0 +1,38 @@
+/*******************************************************************************
+ * Copyright (c) 2009 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.ui.internal.persistence.details;
+
+import java.util.ListIterator;
+import org.eclipse.jpt.core.context.persistence.PersistenceUnit;
+import org.eclipse.jpt.ui.WidgetFactory;
+import org.eclipse.jpt.ui.details.JpaPageComposite;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+public interface PersistenceXmlUiFactory
+{
+	// **************** persistence unit composites ****************************
+	
+	/**
+	 * Creates the list of <code>JpaComposite</code>s used to edit a
+	 * <code>PersistenceUnit</code>. The properties can be regrouped into
+	 * sections that will be shown in the editor as pages.
+	 *
+	 * @param subjectHolder The holder of the pertistence unit
+	 * @param parent The parent container
+	 * @param widgetFactory The factory used to create the widgets
+	 * @return A new <code>JpaComposite</code>
+	 */
+	ListIterator<JpaPageComposite> createPersistenceUnitComposites(
+		PropertyValueModel<PersistenceUnit> subjectHolder,
+		Composite parent,
+		WidgetFactory widgetFactory);
+
+}
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/perspective/JpaPerspectiveFactory.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/perspective/JpaPerspectiveFactory.java
new file mode 100644
index 0000000..263f9ef
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/perspective/JpaPerspectiveFactory.java
@@ -0,0 +1,51 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2008 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.ui.internal.perspective;
+
+import org.eclipse.jdt.ui.JavaUI;
+import org.eclipse.ui.IFolderLayout;
+import org.eclipse.ui.IPageLayout;
+import org.eclipse.ui.IPerspectiveFactory;
+import org.eclipse.ui.navigator.resources.ProjectExplorer;
+import org.eclipse.ui.progress.IProgressConstants;
+
+public class JpaPerspectiveFactory implements IPerspectiveFactory {
+
+	public void createInitialLayout(IPageLayout layout) {
+		String editorArea = layout.getEditorArea();
+
+		//Package area
+		IFolderLayout folder = layout.createFolder(
+				"left", IPageLayout.LEFT, (float) 0.25, editorArea); //$NON-NLS-1$
+		folder.addView(ProjectExplorer.VIEW_ID);
+		folder.addPlaceholder(JavaUI.ID_TYPE_HIERARCHY);
+		folder.addPlaceholder(IPageLayout.ID_RES_NAV);
+
+		//Database Explorer area
+		layout.addView("org.eclipse.datatools.connectivity.DataSourceExplorerNavigator", //$NON-NLS-1$
+			IPageLayout.BOTTOM, (float) 0.60, ProjectExplorer.VIEW_ID);
+
+		//Problems/Console area
+		IFolderLayout outputFolder = layout.createFolder(
+				"bottom", IPageLayout.BOTTOM, (float) 0.60, editorArea); //$NON-NLS-1$
+		outputFolder.addView(IPageLayout.ID_PROBLEM_VIEW);
+		outputFolder.addPlaceholder(IPageLayout.ID_BOOKMARKS);
+		outputFolder.addPlaceholder(IProgressConstants.PROGRESS_VIEW_ID);
+
+		//JPA Details (Split with Problems/Console area)
+		layout.addView("org.eclipse.jpt.ui.jpaDetailsView", //$NON-NLS-1$
+				IPageLayout.RIGHT, (float) .60, "bottom"); //$NON-NLS-1$
+		
+		//JPA Structure area
+		IFolderLayout outlineFolder = layout.createFolder(
+				"right", IPageLayout.RIGHT, (float) 0.75, editorArea); //$NON-NLS-1$
+		outlineFolder.addView("org.eclipse.jpt.ui.jpaStructureView"); //$NON-NLS-1$
+		outlineFolder.addView(IPageLayout.ID_OUTLINE);
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/platform/JpaPlatformUiRegistry.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/platform/JpaPlatformUiRegistry.java
new file mode 100644
index 0000000..255ac2d
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/platform/JpaPlatformUiRegistry.java
@@ -0,0 +1,190 @@
+/*******************************************************************************
+ *  Copyright (c) 2006, 2009 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.ui.internal.platform;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IExtension;
+import org.eclipse.core.runtime.IExtensionPoint;
+import org.eclipse.core.runtime.IExtensionRegistry;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.jpt.ui.JpaPlatformUi;
+import org.eclipse.jpt.ui.JpaPlatformUiFactory;
+import org.eclipse.jpt.ui.JptUiPlugin;
+import org.eclipse.jpt.utility.internal.CollectionTools;
+import org.eclipse.jpt.utility.internal.iterators.CompositeIterator;
+import org.eclipse.jpt.utility.internal.iterators.TransformationIterator;
+
+public class JpaPlatformUiRegistry 
+{
+	// singleton
+	private static final JpaPlatformUiRegistry INSTANCE = new JpaPlatformUiRegistry();
+
+	/**
+	 * Return the singleton.
+	 */
+	public static JpaPlatformUiRegistry instance() {
+		return INSTANCE;
+	}
+
+	private static final String EXTENSION_ID = 
+		"jpaPlatformUis"; //$NON-NLS-1$
+	
+	private static final String EL_PLATFORM_UI =
+		"jpaPlatformUi"; //$NON-NLS-1$	
+
+	private static final String AT_ID =
+		"id"; //$NON-NLS-1$	
+	
+	private static final String AT_JPA_PLATFORM =
+		"jpaPlatform"; //$NON-NLS-1$	
+
+	private static final String AT_FACTORY_CLASS =
+		"factoryClass"; //$NON-NLS-1$	
+		
+	// key: String id  value: IConfigurationElement class descriptor
+	private Map<String, IConfigurationElement> jpaPlatformUiConfigElements;
+	
+	//cache the jpaPlatformUis when they are built
+	//key: jpa platform id  value: JpaPlaformUi
+	private Map<String, JpaPlatformUi> jpaPlatformUis;
+	
+	/* (non Java doc)
+	 * restrict access
+	 */
+	private JpaPlatformUiRegistry() {
+		buildJpaPlatformUiConfigElements();
+		this.jpaPlatformUis = new HashMap<String, JpaPlatformUi>();
+	}
+	
+	
+	private void buildJpaPlatformUiConfigElements() {
+		this.jpaPlatformUiConfigElements = new HashMap<String, IConfigurationElement>();
+		
+		for (Iterator<IConfigurationElement> stream = allConfigElements(); stream.hasNext(); ) {
+			buildJpaPlatformUi(stream.next());
+		}
+	}
+	
+	private void buildJpaPlatformUi(IConfigurationElement configElement) {
+		if (! configElement.getName().equals(EL_PLATFORM_UI)) {
+			return;
+		}
+		
+		String platformUiId = configElement.getAttribute(AT_ID);
+		String platform = configElement.getAttribute(AT_JPA_PLATFORM);
+		String platformUiFactoryClass = configElement.getAttribute(AT_FACTORY_CLASS);
+		
+		if ((platformUiId == null) || (platformUiFactoryClass == null)) {
+			if (platformUiId == null) {
+				reportMissingAttribute(configElement, AT_ID);
+			}
+			if (platform == null) {
+				reportMissingAttribute(configElement, AT_JPA_PLATFORM);
+			}
+			if (platformUiFactoryClass == null) {
+				reportMissingAttribute(configElement, AT_FACTORY_CLASS);
+			}
+			return;
+		}
+		
+		if (this.jpaPlatformUiConfigElements.containsKey(platformUiId)) {
+			IConfigurationElement otherConfigElement = this.jpaPlatformUiConfigElements.get(platform);
+			reportDuplicatePlatformUi(configElement, otherConfigElement);
+		}
+		
+		this.jpaPlatformUiConfigElements.put(platformUiId, configElement);
+	}
+	
+	public JpaPlatformUi getJpaPlatformUi(String platformId) {
+		if (this.jpaPlatformUis.containsKey(platformId)) {
+			return this.jpaPlatformUis.get(platformId);
+		}
+		IConfigurationElement registeredConfigElement = null;
+		for (IConfigurationElement configurationElement : this.jpaPlatformUiConfigElements.values()) {
+			if (configurationElement.getAttribute(AT_JPA_PLATFORM).equals(platformId)) {
+				registeredConfigElement = configurationElement;
+				break;
+			}
+		}
+		
+		if (registeredConfigElement == null) {
+			return null;
+		}
+		JpaPlatformUiFactory jpaPlatformUiFactory;
+		try {
+			jpaPlatformUiFactory = (JpaPlatformUiFactory) registeredConfigElement.createExecutableExtension(AT_FACTORY_CLASS);
+		}
+		catch (CoreException ce) {
+			reportFailedInstantiation(registeredConfigElement);
+			throw new IllegalArgumentException(platformId);
+		}
+		JpaPlatformUi platformUi = jpaPlatformUiFactory.buildJpaPlatformUi();
+		this.jpaPlatformUis.put(platformId, platformUi);
+		return platformUi;
+	}
+	
+	private Iterator<IConfigurationElement> allConfigElements() {
+		IExtensionRegistry registry = Platform.getExtensionRegistry();
+		IExtensionPoint extensionPoint = 
+			registry.getExtensionPoint(JptUiPlugin.PLUGIN_ID, EXTENSION_ID);
+		IExtension[] extensions = extensionPoint.getExtensions();
+		
+		return new CompositeIterator<IConfigurationElement>(
+				new TransformationIterator<IExtension, Iterator<IConfigurationElement>>(CollectionTools.iterator(extensions)) {
+					@Override
+					protected Iterator<IConfigurationElement> transform(IExtension extension) {
+						return CollectionTools.iterator(extension.getConfigurationElements());
+					}
+				}
+			);
+	}
+	
+	// TODO externalize strings
+	private void reportMissingAttribute(IConfigurationElement configElement, String attributeName) {
+		String message = 
+			"An extension element \""
+			+ configElement.getName()
+			+ "\" in plugin \""
+			+ configElement.getContributor().getName()
+			+ "\" is missing a required attribute \""
+			+ attributeName
+			+ "\".";
+		JptUiPlugin.log(message);
+	}
+	
+	// TODO externalize strings
+	private void reportDuplicatePlatformUi(
+			IConfigurationElement oneConfigElement, IConfigurationElement otherConfigElement) {
+		String message =
+			"The plugins \""
+			+ oneConfigElement.getContributor().getName()
+			+ "\" and \""
+			+ otherConfigElement.getContributor().getName()
+			+ "\" have registered a duplicate attribute \"id\" "
+			+ "for the extension element \"jpaPlatformUi\".";
+		JptUiPlugin.log(message);
+	}
+		
+	// TODO externalize strings
+	private void reportFailedInstantiation(IConfigurationElement configElement) {
+		String message =
+			"Could not instantiate the class \""
+			+ configElement.getAttribute(AT_FACTORY_CLASS)
+			+ "\" for the extension element \""
+			+ configElement.getName()
+			+ "\" in the plugin \""
+			+ configElement.getContributor().getName()
+			+ "\".";
+		JptUiPlugin.log(message);
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/platform/base/BaseJpaPlatformUi.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/platform/base/BaseJpaPlatformUi.java
new file mode 100644
index 0000000..d08d7af
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/platform/base/BaseJpaPlatformUi.java
@@ -0,0 +1,191 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 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.ui.internal.platform.base;
+
+import java.util.Iterator;
+import java.util.ListIterator;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jpt.core.JpaFile;
+import org.eclipse.jpt.core.JpaProject;
+import org.eclipse.jpt.core.JpaResourceType;
+import org.eclipse.jpt.core.JpaStructureNode;
+import org.eclipse.jpt.core.context.AttributeMapping;
+import org.eclipse.jpt.core.context.PersistentAttribute;
+import org.eclipse.jpt.core.context.PersistentType;
+import org.eclipse.jpt.core.context.TypeMapping;
+import org.eclipse.jpt.ui.JpaPlatformUi;
+import org.eclipse.jpt.ui.JpaPlatformUiProvider;
+import org.eclipse.jpt.ui.JptUiPlugin;
+import org.eclipse.jpt.ui.MappingResourceUiDefinition;
+import org.eclipse.jpt.ui.ResourceUiDefinition;
+import org.eclipse.jpt.ui.WidgetFactory;
+import org.eclipse.jpt.ui.details.DefaultMappingUiDefinition;
+import org.eclipse.jpt.ui.details.JpaComposite;
+import org.eclipse.jpt.ui.details.JpaDetailsPage;
+import org.eclipse.jpt.ui.details.JpaDetailsProvider;
+import org.eclipse.jpt.ui.details.MappingUiDefinition;
+import org.eclipse.jpt.ui.navigator.JpaNavigatorProvider;
+import org.eclipse.jpt.ui.structure.JpaStructureProvider;
+import org.eclipse.jpt.utility.internal.CollectionTools;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Shell;
+
+public abstract class BaseJpaPlatformUi
+	implements JpaPlatformUi
+{
+	private final JpaNavigatorProvider navigatorProvider;
+	
+	private final JpaPlatformUiProvider platformUiProvider;
+	
+	
+	protected BaseJpaPlatformUi(
+			JpaNavigatorProvider navigatorProvider, JpaPlatformUiProvider platformUiProvider) {
+		
+		super();
+		this.navigatorProvider = navigatorProvider;
+		this.platformUiProvider = platformUiProvider;
+	}
+	
+	
+	// ********** navigator provider **********
+	
+	public JpaNavigatorProvider getNavigatorProvider() {
+		return this.navigatorProvider;
+	}
+	
+	
+	// ********** structure providers **********
+	
+	public JpaStructureProvider getStructureProvider(JpaFile jpaFile) {
+		JpaResourceType resourceType = jpaFile.getResourceModel().getResourceType();
+		return (resourceType == null) ? null : this.getStructureProvider(resourceType);
+	}
+	
+	protected JpaStructureProvider getStructureProvider(JpaResourceType resourceType) {
+		ResourceUiDefinition definition;
+		try {
+			definition = getResourceUiDefinition(resourceType);
+		}
+		catch (IllegalArgumentException iae) {
+			JptUiPlugin.log(iae);
+			return null;
+		}
+		return definition.getStructureProvider();
+	}
+	
+	
+	// ********** details providers **********
+	
+	public JpaDetailsPage<? extends JpaStructureNode> buildJpaDetailsPage(
+			Composite parent, JpaStructureNode structureNode, WidgetFactory widgetFactory) {
+		
+		JpaDetailsProvider jpaDetailsProvider = getDetailsProvider(structureNode);
+		return jpaDetailsProvider == null ? null : jpaDetailsProvider.buildDetailsPage(parent, widgetFactory);
+	}
+	
+	protected JpaDetailsProvider getDetailsProvider(JpaStructureNode structureNode) {
+		for (JpaDetailsProvider provider : CollectionTools.iterable(this.detailsProviders())) {
+			if (provider.providesDetails(structureNode)) {
+				return provider;
+			}
+		}
+		return null;//return null, some structure nodes do not have a details page
+	}
+	
+	protected ListIterator<JpaDetailsProvider> detailsProviders() {
+		return this.platformUiProvider.detailsProviders();
+	}
+	
+	
+	// ********** mapping ui definitions **********
+	
+	public JpaComposite buildTypeMappingComposite(
+			JpaResourceType resourceType, 
+			String mappingKey, 
+			Composite parent, 
+			PropertyValueModel<TypeMapping> mappingHolder, 
+			WidgetFactory widgetFactory) {
+		
+		return getMappingResourceUiDefinition(resourceType).buildTypeMappingComposite(
+				mappingKey, mappingHolder, parent, widgetFactory);
+	}
+	
+	public JpaComposite buildAttributeMappingComposite(
+			JpaResourceType resourceType, 
+			String mappingKey, 
+			Composite parent, 
+			PropertyValueModel<AttributeMapping> mappingHolder, 
+			WidgetFactory widgetFactory) {
+		
+		return getMappingResourceUiDefinition(resourceType).buildAttributeMappingComposite(
+				mappingKey, mappingHolder, parent, widgetFactory);
+	}
+	
+	public DefaultMappingUiDefinition<PersistentAttribute, ? extends AttributeMapping> getDefaultAttributeMappingUiDefinition(JpaResourceType resourceType, String mappingKey) {
+		return getMappingResourceUiDefinition(resourceType).getDefaultAttributeMappingUiDefinition(mappingKey);
+	}
+	
+	public Iterator<MappingUiDefinition<PersistentAttribute, ? extends AttributeMapping>> attributeMappingUiDefinitions(JpaResourceType resourceType) {
+		return getMappingResourceUiDefinition(resourceType).attributeMappingUiDefinitions();
+	}
+	
+	public DefaultMappingUiDefinition<PersistentType, ? extends TypeMapping> getDefaultTypeMappingUiDefinition(JpaResourceType resourceType) {
+		return getMappingResourceUiDefinition(resourceType).getDefaultTypeMappingUiDefinition();
+	}
+	
+	public Iterator<MappingUiDefinition<PersistentType, ? extends TypeMapping>> typeMappingUiDefinitions(JpaResourceType resourceType) {
+		return getMappingResourceUiDefinition(resourceType).typeMappingUiDefinitions();
+	}
+	
+	
+	// ********** resource ui definitions **********
+	
+	protected ListIterator<ResourceUiDefinition> resourceUiDefinitions() {
+		return this.platformUiProvider.resourceUiDefinitions();
+	}
+	
+	public ResourceUiDefinition getResourceUiDefinition(JpaResourceType resourceType) {
+		for (ResourceUiDefinition definition : CollectionTools.iterable(this.resourceUiDefinitions())) {
+			if (definition.providesUi(resourceType)) {
+				return definition;
+			}
+		}
+		// TODO (bug 313632) - return a null resource ui definition?
+		throw new IllegalArgumentException("No resource UI definition for the resource type: " + resourceType); //$NON-NLS-1$
+	}
+	
+	public MappingResourceUiDefinition getMappingResourceUiDefinition(JpaResourceType resourceType) {
+		try {
+			return (MappingResourceUiDefinition) getResourceUiDefinition(resourceType);
+		}
+		catch (ClassCastException cce) {
+			// TODO (bug 313632) - return a null resource ui definition?
+			throw new IllegalArgumentException("No mapping resource UI definition for the resource type: " + resourceType, cce); //$NON-NLS-1$
+		}
+	}
+	
+	
+	// ********** entity generation **********
+	
+	public void generateEntities(JpaProject project, IStructuredSelection selection) {
+		EntitiesGenerator.generate(project, selection);
+	}
+	
+	
+	// ********** convenience methods **********
+	
+	protected void displayMessage(String title, String message) {
+	    Shell currentShell = Display.getCurrent().getActiveShell();
+	    MessageDialog.openInformation(currentShell, title, message);
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/platform/base/EntitiesGenerator.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/platform/base/EntitiesGenerator.java
new file mode 100644
index 0000000..1fb02a6
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/platform/base/EntitiesGenerator.java
@@ -0,0 +1,66 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 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.ui.internal.platform.base;
+
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.window.Window;
+import org.eclipse.jface.wizard.WizardDialog;
+import org.eclipse.jpt.core.JpaProject;
+import org.eclipse.jpt.ui.internal.wizards.gen.GenerateEntitiesFromSchemaWizard;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Shell;
+
+/**
+ *  EntitiesGenerator
+ */
+public class EntitiesGenerator {
+	private JpaProject project;
+	private IStructuredSelection selection;
+
+	public static void generate(JpaProject project, IStructuredSelection selection) {
+		new EntitiesGenerator(project, selection).generate();
+	}
+	
+	private EntitiesGenerator(JpaProject project, IStructuredSelection selection) {
+		super();
+		if (project == null) {
+			throw new NullPointerException();
+		}
+		this.project = project;
+		this.selection = selection;
+	}
+
+
+	// ********** generate **********
+
+	/**
+	 * prompt the user with a wizard;
+	 * schedule a job to generate the entities;
+	 * optionally schedule a job to synchronize persistence.xml to
+	 * run afterwards
+	 */
+	protected void generate() {
+		GenerateEntitiesFromSchemaWizard wizard = new GenerateEntitiesFromSchemaWizard(this.project, this.selection);
+		WizardDialog dialog = new WizardDialog(this.getCurrentShell(), wizard);
+		dialog.create();
+		int returnCode = dialog.open();
+		if (returnCode != Window.OK) {
+			return;
+		}
+		//Entities generation happens in the GenerateEntitiesFromSchemaWizard.performFinish()
+		//method
+	}
+	
+	private Shell getCurrentShell() {
+	    return Display.getCurrent().getActiveShell();
+	}
+
+
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/platform/generic/ClassRefItemLabelProvider.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/platform/generic/ClassRefItemLabelProvider.java
new file mode 100644
index 0000000..63d5bef
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/platform/generic/ClassRefItemLabelProvider.java
@@ -0,0 +1,64 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2010 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.ui.internal.platform.generic;
+
+import org.eclipse.jpt.core.context.persistence.ClassRef;
+import org.eclipse.jpt.ui.JptUiPlugin;
+import org.eclipse.jpt.ui.internal.JptUiIcons;
+import org.eclipse.jpt.ui.internal.jface.AbstractItemLabelProvider;
+import org.eclipse.jpt.ui.jface.DelegatingContentAndLabelProvider;
+import org.eclipse.jpt.utility.internal.model.value.PropertyAspectAdapter;
+import org.eclipse.jpt.utility.internal.model.value.StaticPropertyValueModel;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.graphics.Image;
+
+public class ClassRefItemLabelProvider extends AbstractItemLabelProvider
+{
+	public ClassRefItemLabelProvider(
+			ClassRef classRef, DelegatingContentAndLabelProvider labelProvider) {
+		super(classRef, labelProvider);
+	}
+	
+	
+	@Override
+	protected PropertyValueModel<Image> buildImageModel() {
+		Image image;
+		if (((ClassRef) model()).isVirtual()) {
+			image = JptUiIcons.ghost(JptUiIcons.CLASS_REF);
+		}
+		else {
+			 image = JptUiPlugin.getImage(JptUiIcons.CLASS_REF);
+		}
+		return new StaticPropertyValueModel<Image>(image);
+	}
+	
+	@Override
+	protected PropertyValueModel<String> buildTextModel() {
+		return new PropertyAspectAdapter<ClassRef, String>(ClassRef.CLASS_NAME_PROPERTY, (ClassRef) model()) {
+			 @Override
+			protected String buildValue_() {
+				return subject.getClassName();
+			}
+		};
+	}
+	
+	@Override
+	protected PropertyValueModel<String> buildDescriptionModel() {
+		//TODO also need to listen to the PersistenceUnit name property since this value depends on it
+		return new PropertyAspectAdapter<ClassRef, String>(ClassRef.CLASS_NAME_PROPERTY, (ClassRef) model()) {
+			@Override
+			protected String buildValue_() {
+				return subject.getPersistenceUnit().getName() 
+				+ "/\"" + subject.getClassName()
+				+ "\" - " + subject.getResource().getFullPath().makeRelative();
+			}
+		};
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/platform/generic/EntityMappingsItemLabelProvider.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/platform/generic/EntityMappingsItemLabelProvider.java
new file mode 100644
index 0000000..110a11a
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/platform/generic/EntityMappingsItemLabelProvider.java
@@ -0,0 +1,48 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2009 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.ui.internal.platform.generic;
+
+import org.eclipse.jpt.core.context.orm.EntityMappings;
+import org.eclipse.jpt.ui.JptUiPlugin;
+import org.eclipse.jpt.ui.internal.JptUiIcons;
+import org.eclipse.jpt.ui.internal.JptUiMessages;
+import org.eclipse.jpt.ui.internal.jface.AbstractItemLabelProvider;
+import org.eclipse.jpt.ui.jface.DelegatingContentAndLabelProvider;
+import org.eclipse.jpt.utility.internal.model.value.StaticPropertyValueModel;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.graphics.Image;
+
+public class EntityMappingsItemLabelProvider extends AbstractItemLabelProvider
+{
+	public EntityMappingsItemLabelProvider(
+			EntityMappings entityMappings, DelegatingContentAndLabelProvider labelProvider) {
+		super(entityMappings, labelProvider);
+	}
+	
+	
+	@Override
+	protected PropertyValueModel<Image> buildImageModel() {
+		return new StaticPropertyValueModel<Image>(
+			JptUiPlugin.getImage(JptUiIcons.ENTITY_MAPPINGS));
+	}
+	
+	@Override
+	protected PropertyValueModel<String> buildTextModel() {
+		return new StaticPropertyValueModel<String>(
+			JptUiMessages.OrmItemLabelProviderFactory_entityMappingsLabel);
+	}
+	
+	@Override
+	protected PropertyValueModel<String> buildDescriptionModel() {
+		return new StaticPropertyValueModel<String>(
+			JptUiMessages.OrmItemLabelProviderFactory_entityMappingsLabel
+				+ " - " + ((EntityMappings) model()).getResource().getFullPath().makeRelative());
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/platform/generic/GenericJpaPlatformUi.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/platform/generic/GenericJpaPlatformUi.java
new file mode 100644
index 0000000..dd2503a
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/platform/generic/GenericJpaPlatformUi.java
@@ -0,0 +1,34 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2009 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.ui.internal.platform.generic;
+
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jpt.core.JpaProject;
+import org.eclipse.jpt.ui.JpaPlatformUiProvider;
+import org.eclipse.jpt.ui.internal.JptUiMessages;
+import org.eclipse.jpt.ui.internal.platform.base.BaseJpaPlatformUi;
+import org.eclipse.jpt.ui.navigator.JpaNavigatorProvider;
+
+public class GenericJpaPlatformUi
+	extends BaseJpaPlatformUi
+{
+	public GenericJpaPlatformUi(
+			JpaNavigatorProvider navigatorProvider, JpaPlatformUiProvider platformUiProvider) {
+		
+		super(navigatorProvider, platformUiProvider);
+	}
+	
+	
+	// ********** DDL generation **********
+	
+	public void generateDDL(JpaProject project, IStructuredSelection selection) {
+		this.displayMessage(JptUiMessages.GenericPlatformUiDialog_notSupportedMessageTitle, JptUiMessages.GenericPlatformUiDialog_notSupportedMessageText);
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/platform/generic/GenericJpaPlatformUiFactory.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/platform/generic/GenericJpaPlatformUiFactory.java
new file mode 100644
index 0000000..238901d
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/platform/generic/GenericJpaPlatformUiFactory.java
@@ -0,0 +1,32 @@
+/*******************************************************************************
+ * Copyright (c) 2009 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.ui.internal.platform.generic;
+
+import org.eclipse.jpt.ui.JpaPlatformUi;
+import org.eclipse.jpt.ui.JpaPlatformUiFactory;
+import org.eclipse.jpt.ui.internal.GenericJpaPlatformUiProvider;
+
+public class GenericJpaPlatformUiFactory implements JpaPlatformUiFactory
+{
+
+	/**
+	 * Zero arg constructor for extension point
+	 */
+	public GenericJpaPlatformUiFactory() {
+		super();
+	}
+
+	public JpaPlatformUi buildJpaPlatformUi() {
+		return new GenericJpaPlatformUi(
+			new GenericNavigatorProvider(),
+			GenericJpaPlatformUiProvider.instance()
+		);
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/platform/generic/GenericNavigatorItemContentProviderFactory.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/platform/generic/GenericNavigatorItemContentProviderFactory.java
new file mode 100644
index 0000000..2160b76
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/platform/generic/GenericNavigatorItemContentProviderFactory.java
@@ -0,0 +1,255 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2010 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.ui.internal.platform.generic;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+
+import org.eclipse.jpt.core.context.JpaContextNode;
+import org.eclipse.jpt.core.context.JpaRootContextNode;
+import org.eclipse.jpt.core.context.MappingFile;
+import org.eclipse.jpt.core.context.PersistentAttribute;
+import org.eclipse.jpt.core.context.PersistentType;
+import org.eclipse.jpt.core.context.java.JarFile;
+import org.eclipse.jpt.core.context.java.JavaPersistentType;
+import org.eclipse.jpt.core.context.orm.OrmPersistentType;
+import org.eclipse.jpt.core.context.orm.OrmXml;
+import org.eclipse.jpt.core.context.persistence.ClassRef;
+import org.eclipse.jpt.core.context.persistence.JarFileRef;
+import org.eclipse.jpt.core.context.persistence.MappingFileRef;
+import org.eclipse.jpt.core.context.persistence.PersistenceUnit;
+import org.eclipse.jpt.core.context.persistence.PersistenceXml;
+import org.eclipse.jpt.ui.internal.jface.AbstractTreeItemContentProvider;
+import org.eclipse.jpt.ui.internal.jface.DelegatingTreeContentAndLabelProvider;
+import org.eclipse.jpt.ui.jface.DelegatingContentAndLabelProvider;
+import org.eclipse.jpt.ui.jface.TreeItemContentProvider;
+import org.eclipse.jpt.ui.jface.TreeItemContentProviderFactory;
+import org.eclipse.jpt.utility.internal.iterables.FilteringIterable;
+import org.eclipse.jpt.utility.internal.model.value.CollectionAspectAdapter;
+import org.eclipse.jpt.utility.internal.model.value.CompositeCollectionValueModel;
+import org.eclipse.jpt.utility.internal.model.value.FilteringCollectionValueModel;
+import org.eclipse.jpt.utility.internal.model.value.ItemPropertyListValueModelAdapter;
+import org.eclipse.jpt.utility.internal.model.value.ListAspectAdapter;
+import org.eclipse.jpt.utility.internal.model.value.ListCollectionValueModelAdapter;
+import org.eclipse.jpt.utility.internal.model.value.PropertyAspectAdapter;
+import org.eclipse.jpt.utility.internal.model.value.PropertyCollectionValueModelAdapter;
+import org.eclipse.jpt.utility.internal.model.value.TransformationListValueModelAdapter;
+import org.eclipse.jpt.utility.model.value.CollectionValueModel;
+
+public class GenericNavigatorItemContentProviderFactory
+	implements TreeItemContentProviderFactory
+{
+	public TreeItemContentProvider buildItemContentProvider(Object item, DelegatingContentAndLabelProvider contentAndLabelProvider) {
+		DelegatingTreeContentAndLabelProvider treeContentAndLabelProvider = (DelegatingTreeContentAndLabelProvider) contentAndLabelProvider;
+		
+		if (item instanceof JpaRootContextNode) {
+			return new RootContextItemContentProvider((JpaRootContextNode) item, treeContentAndLabelProvider);
+		}
+		else if (item instanceof PersistenceXml) {
+			return new PersistenceXmlItemContentProvider((PersistenceXml) item, treeContentAndLabelProvider);	
+		}
+		else if (item instanceof PersistenceUnit) {
+			return new PersistenceUnitItemContentProvider((PersistenceUnit) item, treeContentAndLabelProvider);	
+		}
+		else if (item instanceof OrmXml) {
+			return new OrmXmlItemContentProvider((OrmXml) item, treeContentAndLabelProvider);	
+		}
+		else if (item instanceof OrmPersistentType) {
+			return new OrmPersistentTypeItemContentProvider((OrmPersistentType) item, treeContentAndLabelProvider);	
+		}
+		else if (item instanceof JavaPersistentType) {
+			return new JavaPersistentTypeItemContentProvider((JavaPersistentType) item, treeContentAndLabelProvider);	
+		}
+		else if (item instanceof PersistentAttribute) {
+			return new PersistentAttributeItemContentProvider((PersistentAttribute) item, treeContentAndLabelProvider);	
+		}
+		return null;
+	}
+	
+	
+	public static class PersistenceUnitItemContentProvider extends AbstractTreeItemContentProvider<JpaContextNode>
+	{
+		public PersistenceUnitItemContentProvider(
+				PersistenceUnit persistenceUnit, DelegatingTreeContentAndLabelProvider contentProvider) {
+			super(persistenceUnit, contentProvider);
+		}
+		
+		@Override
+		public PersistenceUnit getModel() {
+			return (PersistenceUnit) super.getModel();
+		}
+		
+		@Override
+		public PersistenceXml getParent() {
+			return getModel().getParent().getParent();
+		}
+	
+		@Override
+		protected CollectionValueModel<JpaContextNode> buildChildrenModel() {
+			List<CollectionValueModel<? extends JpaContextNode>> list = new ArrayList<CollectionValueModel<? extends JpaContextNode>>();
+			list.add(buildSpecifiedOrmXmlCvm());
+			list.add(buildImpliedMappingFileCvm());
+			list.add(buildPersistentTypeCvm());
+			list.add(buildJarFileCvm());
+			return new CompositeCollectionValueModel<CollectionValueModel<? extends JpaContextNode>, JpaContextNode>(list);
+		}
+		
+		protected CollectionValueModel<JpaContextNode> buildSpecifiedOrmXmlCvm() {
+			return new FilteringCollectionValueModel<JpaContextNode>(
+					new ListCollectionValueModelAdapter<MappingFile>(
+						new TransformationListValueModelAdapter<MappingFileRef, MappingFile>(
+							new ItemPropertyListValueModelAdapter<MappingFileRef>(
+								new ListAspectAdapter<PersistenceUnit, MappingFileRef>(
+										PersistenceUnit.SPECIFIED_MAPPING_FILE_REFS_LIST,
+										getModel()) {
+									@Override
+									protected ListIterator<MappingFileRef> listIterator_() {
+										return subject.specifiedMappingFileRefs();
+									}
+									@Override
+									protected int size_() {
+										return subject.specifiedMappingFileRefsSize();
+									}
+								}, MappingFileRef.MAPPING_FILE_PROPERTY)) {
+							@Override
+							protected MappingFile transformItem(MappingFileRef item) {
+								return item.getMappingFile();
+							}
+						})) {
+					@Override
+					protected Iterable<JpaContextNode> filter(Iterable<? extends JpaContextNode> items) {
+						return new FilteringIterable<JpaContextNode>(items) {
+							@Override
+							protected boolean accept(JpaContextNode o) {
+								return o != null;
+							}
+						};
+					}
+				};
+		}
+		
+		protected CollectionValueModel<MappingFile> buildImpliedMappingFileCvm() {
+			return new PropertyCollectionValueModelAdapter<MappingFile>(
+				new PropertyAspectAdapter<MappingFileRef, MappingFile>(
+						new PropertyAspectAdapter<PersistenceUnit, MappingFileRef>(
+								PersistenceUnit.IMPLIED_MAPPING_FILE_REF_PROPERTY,
+								getModel()) {
+							@Override
+							protected MappingFileRef buildValue_() {
+								return subject.getImpliedMappingFileRef();
+							}
+						},
+						MappingFileRef.MAPPING_FILE_PROPERTY) {
+					@Override
+					protected MappingFile buildValue_() {
+						return subject.getMappingFile();
+					}
+				}
+			);
+		}
+		
+		protected CollectionValueModel<JpaContextNode> buildPersistentTypeCvm() {
+			return new FilteringCollectionValueModel<JpaContextNode>(
+					new ListCollectionValueModelAdapter<PersistentType>(
+						new TransformationListValueModelAdapter<ClassRef, PersistentType>(
+							new ItemPropertyListValueModelAdapter<ClassRef>(buildClassRefCvm(), ClassRef.JAVA_PERSISTENT_TYPE_PROPERTY)) {
+							@Override
+							protected PersistentType transformItem(ClassRef item) {
+								return item.getJavaPersistentType();
+							}
+						})) {
+					@Override
+					protected Iterable<JpaContextNode> filter(Iterable<? extends JpaContextNode> items) {
+						return new FilteringIterable<JpaContextNode>(items) {
+							@Override
+							protected boolean accept(JpaContextNode o) {
+								return o != null;
+							}
+						};
+					}
+				};
+		}
+		
+		protected CollectionValueModel<ClassRef> buildClassRefCvm() {
+			ArrayList<CollectionValueModel<ClassRef>> holders = new ArrayList<CollectionValueModel<ClassRef>>(2);
+			holders.add(buildSpecifiedClassRefCvm());
+			holders.add(buildImpliedClassRefCvm());
+			return new CompositeCollectionValueModel<CollectionValueModel<ClassRef>, ClassRef>(holders);
+		}
+		
+		protected CollectionValueModel<ClassRef> buildSpecifiedClassRefCvm() {
+			return new ListCollectionValueModelAdapter<ClassRef>(
+			new ListAspectAdapter<PersistenceUnit, ClassRef>(
+				PersistenceUnit.SPECIFIED_CLASS_REFS_LIST, getModel()) {
+					@Override
+					protected ListIterator<ClassRef> listIterator_() {
+						return subject.specifiedClassRefs();
+					}
+					@Override
+					protected int size_() {
+						return subject.specifiedClassRefsSize();
+					}
+			});
+		}
+		
+		protected CollectionValueModel<ClassRef> buildImpliedClassRefCvm() {
+			return new CollectionAspectAdapter<PersistenceUnit, ClassRef>(
+				PersistenceUnit.IMPLIED_CLASS_REFS_COLLECTION, getModel()) {
+					@Override
+					protected Iterator<ClassRef> iterator_() {
+						return subject.impliedClassRefs();
+					}
+					@Override
+					protected int size_() {
+						return subject.impliedClassRefsSize();
+					}
+			};
+		}
+		
+		protected CollectionValueModel<JpaContextNode> buildJarFileCvm() {
+			return new FilteringCollectionValueModel<JpaContextNode>(
+					new ListCollectionValueModelAdapter<JarFile>(
+						new TransformationListValueModelAdapter<JarFileRef, JarFile>(
+							new ItemPropertyListValueModelAdapter<JarFileRef>(buildJarFileRefCvm(), JarFileRef.JAR_FILE_PROPERTY)) {
+							@Override
+							protected JarFile transformItem(JarFileRef item) {
+								return item.getJarFile();
+							}
+						})) {
+					@Override
+					protected Iterable<JpaContextNode> filter(Iterable<? extends JpaContextNode> items) {
+						return new FilteringIterable<JpaContextNode>(items) {
+							@Override
+							protected boolean accept(JpaContextNode o) {
+								return o != null;
+							}
+						};
+					}
+				};
+		}
+		
+		protected CollectionValueModel<JarFileRef> buildJarFileRefCvm() {
+			return new ListCollectionValueModelAdapter<JarFileRef>(
+				new ListAspectAdapter<PersistenceUnit, JarFileRef>(
+					PersistenceUnit.JAR_FILE_REFS_LIST, getModel()) {
+						@Override
+						protected ListIterator<JarFileRef> listIterator_() {
+							return subject.jarFileRefs();
+						}
+						@Override
+						protected int size_() {
+							return subject.jarFileRefsSize();
+						}
+				});
+		}
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/platform/generic/GenericNavigatorItemLabelProviderFactory.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/platform/generic/GenericNavigatorItemLabelProviderFactory.java
new file mode 100644
index 0000000..d5dc95e
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/platform/generic/GenericNavigatorItemLabelProviderFactory.java
@@ -0,0 +1,51 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2009 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.ui.internal.platform.generic;
+
+import org.eclipse.jpt.core.context.JpaRootContextNode;
+import org.eclipse.jpt.core.context.PersistentAttribute;
+import org.eclipse.jpt.core.context.PersistentType;
+import org.eclipse.jpt.core.context.java.JarFile;
+import org.eclipse.jpt.core.context.orm.OrmXml;
+import org.eclipse.jpt.core.context.persistence.PersistenceUnit;
+import org.eclipse.jpt.core.context.persistence.PersistenceXml;
+import org.eclipse.jpt.ui.internal.jface.JarFileItemLabelProvider;
+import org.eclipse.jpt.ui.jface.DelegatingContentAndLabelProvider;
+import org.eclipse.jpt.ui.jface.ItemLabelProvider;
+import org.eclipse.jpt.ui.jface.ItemLabelProviderFactory;
+
+public class GenericNavigatorItemLabelProviderFactory
+	implements ItemLabelProviderFactory
+{
+	public ItemLabelProvider buildItemLabelProvider(Object item, DelegatingContentAndLabelProvider contentAndLabelProvider) {
+		if (item instanceof JpaRootContextNode) {
+			return new RootContextItemLabelProvider((JpaRootContextNode) item, contentAndLabelProvider);
+		}
+		else if (item instanceof PersistenceXml) {
+			return new PersistenceXmlItemLabelProvider((PersistenceXml) item, contentAndLabelProvider);	
+		}
+		else if (item instanceof PersistenceUnit) {
+			return new PersistenceUnitItemLabelProvider((PersistenceUnit) item, contentAndLabelProvider);	
+		}
+		else if (item instanceof OrmXml) {
+			return new OrmXmlItemLabelProvider((OrmXml) item, contentAndLabelProvider);	
+		}
+		else if (item instanceof PersistentType) {
+			return new PersistentTypeItemLabelProvider((PersistentType) item, contentAndLabelProvider);	
+		}
+		else if (item instanceof PersistentAttribute) {
+			return new PersistentAttributeItemLabelProvider((PersistentAttribute) item, contentAndLabelProvider);	
+		}
+		else if (item instanceof JarFile) {
+			return new JarFileItemLabelProvider((JarFile) item, contentAndLabelProvider);
+		}
+		return null;
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/platform/generic/GenericNavigatorProvider.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/platform/generic/GenericNavigatorProvider.java
new file mode 100644
index 0000000..8bb925c
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/platform/generic/GenericNavigatorProvider.java
@@ -0,0 +1,29 @@
+/*******************************************************************************
+ * Copyright (c) 2008 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.ui.internal.platform.generic;
+
+import org.eclipse.jpt.ui.jface.ItemLabelProviderFactory;
+import org.eclipse.jpt.ui.jface.TreeItemContentProviderFactory;
+import org.eclipse.jpt.ui.navigator.JpaNavigatorProvider;
+
+public class GenericNavigatorProvider implements JpaNavigatorProvider
+{
+	public ItemLabelProviderFactory getItemLabelProviderFactory() {
+		return new GenericNavigatorItemLabelProviderFactory();
+	}
+
+	public TreeItemContentProviderFactory getTreeItemContentProviderFactory() {
+		return new GenericNavigatorItemContentProviderFactory();
+	}
+	
+	public void dispose() {
+		// TODO Auto-generated method stub
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/platform/generic/JarFileRefItemLabelProvider.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/platform/generic/JarFileRefItemLabelProvider.java
new file mode 100644
index 0000000..3154f64
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/platform/generic/JarFileRefItemLabelProvider.java
@@ -0,0 +1,57 @@
+/*******************************************************************************
+ *  Copyright (c) 2009  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.ui.internal.platform.generic;
+
+import org.eclipse.jpt.core.context.persistence.JarFileRef;
+import org.eclipse.jpt.ui.JptUiPlugin;
+import org.eclipse.jpt.ui.internal.JptUiIcons;
+import org.eclipse.jpt.ui.internal.jface.AbstractItemLabelProvider;
+import org.eclipse.jpt.ui.jface.DelegatingContentAndLabelProvider;
+import org.eclipse.jpt.utility.internal.model.value.PropertyAspectAdapter;
+import org.eclipse.jpt.utility.internal.model.value.StaticPropertyValueModel;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.graphics.Image;
+
+public class JarFileRefItemLabelProvider extends AbstractItemLabelProvider
+{
+	public JarFileRefItemLabelProvider(
+			JarFileRef jarFileRef, DelegatingContentAndLabelProvider labelProvider) {
+		super(jarFileRef, labelProvider);
+	}
+	
+	
+	@Override
+	protected PropertyValueModel<String> buildTextModel() {
+		return new PropertyAspectAdapter<JarFileRef, String>(JarFileRef.FILE_NAME_PROPERTY, (JarFileRef) model()) {
+			 @Override
+			protected String buildValue_() {
+				return subject.getFileName();
+			}
+		};
+	}
+	
+	@Override
+	protected PropertyValueModel<Image> buildImageModel() {
+		return new StaticPropertyValueModel<Image>(JptUiPlugin.getImage(JptUiIcons.JAR_FILE_REF));
+	}
+	
+	@Override
+	protected PropertyValueModel<String> buildDescriptionModel() {
+		return new PropertyAspectAdapter<JarFileRef, String>(JarFileRef.FILE_NAME_PROPERTY, (JarFileRef) model()) {
+			@Override
+			protected String buildValue_() {
+				return subject.getPersistenceUnit().getName() 
+				+ "/\"" + subject.getFileName()
+				+ "\" - " + subject.getResource().getFullPath().makeRelative();
+			}
+		};
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/platform/generic/JavaPersistentTypeItemContentProvider.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/platform/generic/JavaPersistentTypeItemContentProvider.java
new file mode 100644
index 0000000..d5a6fe5
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/platform/generic/JavaPersistentTypeItemContentProvider.java
@@ -0,0 +1,55 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2009 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.ui.internal.platform.generic;
+
+import java.util.ListIterator;
+
+import org.eclipse.jpt.core.context.PersistentType;
+import org.eclipse.jpt.core.context.java.JavaPersistentAttribute;
+import org.eclipse.jpt.core.context.java.JavaPersistentType;
+import org.eclipse.jpt.ui.internal.jface.AbstractTreeItemContentProvider;
+import org.eclipse.jpt.ui.internal.jface.DelegatingTreeContentAndLabelProvider;
+import org.eclipse.jpt.utility.internal.model.value.ListAspectAdapter;
+import org.eclipse.jpt.utility.internal.model.value.ListCollectionValueModelAdapter;
+import org.eclipse.jpt.utility.model.value.CollectionValueModel;
+
+public class JavaPersistentTypeItemContentProvider extends AbstractTreeItemContentProvider<JavaPersistentAttribute>
+{
+	public JavaPersistentTypeItemContentProvider(
+			JavaPersistentType persistentType, DelegatingTreeContentAndLabelProvider contentProvider) {
+		super(persistentType, contentProvider);
+	}
+	
+	@Override
+	public JavaPersistentType getModel() {
+		return (JavaPersistentType) super.getModel();
+	}
+	
+	@Override
+	public Object getParent() {
+		return getModel().getParent();
+	}
+	
+	@Override
+	protected CollectionValueModel<JavaPersistentAttribute> buildChildrenModel() {
+		return new ListCollectionValueModelAdapter<JavaPersistentAttribute>(
+		new ListAspectAdapter<JavaPersistentType, JavaPersistentAttribute>(PersistentType.ATTRIBUTES_LIST, getModel()) {
+			@Override
+			protected ListIterator<JavaPersistentAttribute> listIterator_() {
+				return subject.attributes();
+			}
+			
+			@Override
+			protected int size_() {
+				return subject.attributesSize();
+			}
+		});
+	}
+}
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/platform/generic/MappingFileRefItemLabelProvider.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/platform/generic/MappingFileRefItemLabelProvider.java
new file mode 100644
index 0000000..619fdb3
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/platform/generic/MappingFileRefItemLabelProvider.java
@@ -0,0 +1,63 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2010 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.ui.internal.platform.generic;
+
+import org.eclipse.jpt.core.context.persistence.MappingFileRef;
+import org.eclipse.jpt.ui.JptUiPlugin;
+import org.eclipse.jpt.ui.internal.JptUiIcons;
+import org.eclipse.jpt.ui.internal.jface.AbstractItemLabelProvider;
+import org.eclipse.jpt.ui.jface.DelegatingContentAndLabelProvider;
+import org.eclipse.jpt.utility.internal.model.value.PropertyAspectAdapter;
+import org.eclipse.jpt.utility.internal.model.value.StaticPropertyValueModel;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.graphics.Image;
+
+public class MappingFileRefItemLabelProvider extends AbstractItemLabelProvider
+{
+	public MappingFileRefItemLabelProvider(
+			MappingFileRef mappingFileRef, DelegatingContentAndLabelProvider labelProvider) {
+		super(mappingFileRef, labelProvider);
+	}
+	
+	
+	@Override
+	protected PropertyValueModel<Image> buildImageModel() {
+		Image image;
+		if (((MappingFileRef) model()).isImplied()) {
+			image = JptUiIcons.ghost(JptUiIcons.MAPPING_FILE_REF);
+		}
+		else {
+			 image = JptUiPlugin.getImage(JptUiIcons.MAPPING_FILE_REF);
+		}
+		return new StaticPropertyValueModel<Image>(image);
+	}
+	
+	@Override
+	protected PropertyValueModel<String> buildTextModel() {
+		return new PropertyAspectAdapter<MappingFileRef, String>(MappingFileRef.FILE_NAME_PROPERTY, (MappingFileRef) model()) {
+			 @Override
+			protected String buildValue_() {
+				return subject.getFileName();
+			}
+		};
+	}
+	
+	@Override
+	protected PropertyValueModel<String> buildDescriptionModel() {
+		return new PropertyAspectAdapter<MappingFileRef, String>(MappingFileRef.FILE_NAME_PROPERTY, (MappingFileRef) model()) {
+			@Override
+			protected String buildValue_() {
+				return subject.getPersistenceUnit().getName() 
+				+ "/\"" + subject.getFileName() + "\""
+				+ " - " + subject.getResource().getFullPath().makeRelative();
+			}
+		};
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/platform/generic/OrmPersistentTypeItemContentProvider.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/platform/generic/OrmPersistentTypeItemContentProvider.java
new file mode 100644
index 0000000..75fb930
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/platform/generic/OrmPersistentTypeItemContentProvider.java
@@ -0,0 +1,79 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2009 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.ui.internal.platform.generic;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.ListIterator;
+
+import org.eclipse.jpt.core.context.PersistentType;
+import org.eclipse.jpt.core.context.orm.OrmPersistentAttribute;
+import org.eclipse.jpt.core.context.orm.OrmPersistentType;
+import org.eclipse.jpt.ui.internal.jface.AbstractTreeItemContentProvider;
+import org.eclipse.jpt.ui.internal.jface.DelegatingTreeContentAndLabelProvider;
+import org.eclipse.jpt.utility.internal.model.value.CompositeCollectionValueModel;
+import org.eclipse.jpt.utility.internal.model.value.ListAspectAdapter;
+import org.eclipse.jpt.utility.internal.model.value.ListCollectionValueModelAdapter;
+import org.eclipse.jpt.utility.model.value.CollectionValueModel;
+
+public class OrmPersistentTypeItemContentProvider extends AbstractTreeItemContentProvider<OrmPersistentAttribute>
+	{
+		public OrmPersistentTypeItemContentProvider(
+				OrmPersistentType persistentType, DelegatingTreeContentAndLabelProvider contentProvider) {
+			super(persistentType, contentProvider);
+		}
+		
+		@Override
+		public OrmPersistentType getModel() {
+			return (OrmPersistentType) super.getModel();
+		}
+		
+		@Override
+		public Object getParent() {
+			return getModel().getParent();
+		}
+		
+		@Override
+		protected CollectionValueModel<OrmPersistentAttribute> buildChildrenModel() {
+			List<CollectionValueModel<OrmPersistentAttribute>> list = new ArrayList<CollectionValueModel<OrmPersistentAttribute>>(2);
+			list.add(buildSpecifiedPersistentAttributesCollectionHolder());
+			list.add(buildVirtualPersistentAttributesCollectionHolder());
+			return new CompositeCollectionValueModel<CollectionValueModel<OrmPersistentAttribute>, OrmPersistentAttribute>(list);
+		}
+		
+
+		protected CollectionValueModel<OrmPersistentAttribute> buildSpecifiedPersistentAttributesCollectionHolder() {
+			return new ListCollectionValueModelAdapter<OrmPersistentAttribute>(
+			new ListAspectAdapter<OrmPersistentType, OrmPersistentAttribute>(PersistentType.ATTRIBUTES_LIST, getModel()) {
+				@Override
+				protected ListIterator<OrmPersistentAttribute> listIterator_() {
+					return subject.specifiedAttributes();
+				}
+				@Override
+				protected int size_() {
+					return subject.specifiedAttributesSize();
+				}
+			});
+		}
+		
+		protected CollectionValueModel<OrmPersistentAttribute> buildVirtualPersistentAttributesCollectionHolder() {
+			return new ListCollectionValueModelAdapter<OrmPersistentAttribute>(
+			new ListAspectAdapter<OrmPersistentType, OrmPersistentAttribute>(OrmPersistentType.VIRTUAL_ATTRIBUTES_LIST, getModel()) {
+				@Override
+				protected ListIterator<OrmPersistentAttribute> listIterator_() {
+					return subject.virtualAttributes();
+				}
+				@Override
+				protected int size_() {
+					return subject.virtualAttributesSize();
+				}
+			});
+		}
+}
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/platform/generic/OrmXmlItemContentProvider.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/platform/generic/OrmXmlItemContentProvider.java
new file mode 100644
index 0000000..a4f0974
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/platform/generic/OrmXmlItemContentProvider.java
@@ -0,0 +1,69 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2009 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.ui.internal.platform.generic;
+
+import org.eclipse.jpt.core.context.orm.EntityMappings;
+import org.eclipse.jpt.core.context.orm.OrmPersistentType;
+import org.eclipse.jpt.core.context.orm.OrmXml;
+import org.eclipse.jpt.core.context.persistence.PersistenceUnit;
+import org.eclipse.jpt.ui.internal.jface.AbstractTreeItemContentProvider;
+import org.eclipse.jpt.ui.internal.jface.DelegatingTreeContentAndLabelProvider;
+import org.eclipse.jpt.utility.internal.iterables.ListIterable;
+import org.eclipse.jpt.utility.internal.model.value.ListAspectAdapter;
+import org.eclipse.jpt.utility.internal.model.value.ListCollectionValueModelAdapter;
+import org.eclipse.jpt.utility.internal.model.value.PropertyAspectAdapter;
+import org.eclipse.jpt.utility.model.value.CollectionValueModel;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+
+public class OrmXmlItemContentProvider
+	extends AbstractTreeItemContentProvider<OrmPersistentType>
+{
+	public OrmXmlItemContentProvider(
+			OrmXml ormXml, DelegatingTreeContentAndLabelProvider contentProvider) {
+		super(ormXml, contentProvider);
+	}
+	
+	@Override
+	public OrmXml getModel() {
+		return (OrmXml) super.getModel();
+	}
+	
+	@Override
+	public PersistenceUnit getParent() {
+		return getModel().getPersistenceUnit();
+	}
+	
+	@Override
+	protected CollectionValueModel<OrmPersistentType> buildChildrenModel() {
+		return new ListCollectionValueModelAdapter<OrmPersistentType>(
+		new ListAspectAdapter<EntityMappings, OrmPersistentType>(
+				buildEntityMappingsHolder(),
+				EntityMappings.PERSISTENT_TYPES_LIST) {
+			@Override
+			protected ListIterable<OrmPersistentType> getListIterable() {
+				return subject.getPersistentTypes();
+			}
+			@Override
+			protected int size_() {
+				return subject.getPersistentTypesSize();
+			}
+		});
+	}
+	
+	protected PropertyValueModel<EntityMappings> buildEntityMappingsHolder() {
+		return new PropertyAspectAdapter<OrmXml, EntityMappings>(
+				OrmXml.ENTITY_MAPPINGS_PROPERTY, getModel()) {
+			@Override
+			protected EntityMappings buildValue_() {
+				return subject.getEntityMappings();
+			}
+		};
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/platform/generic/OrmXmlItemLabelProvider.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/platform/generic/OrmXmlItemLabelProvider.java
new file mode 100644
index 0000000..cb91248
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/platform/generic/OrmXmlItemLabelProvider.java
@@ -0,0 +1,46 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2009 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.ui.internal.platform.generic;
+
+import org.eclipse.jpt.core.context.orm.OrmXml;
+import org.eclipse.jpt.ui.JptUiPlugin;
+import org.eclipse.jpt.ui.internal.JptUiIcons;
+import org.eclipse.jpt.ui.internal.jface.AbstractItemLabelProvider;
+import org.eclipse.jpt.ui.jface.DelegatingContentAndLabelProvider;
+import org.eclipse.jpt.utility.internal.model.value.StaticPropertyValueModel;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.graphics.Image;
+
+public class OrmXmlItemLabelProvider extends AbstractItemLabelProvider
+{
+	public OrmXmlItemLabelProvider(
+			OrmXml ormXml, DelegatingContentAndLabelProvider labelProvider) {
+		super(ormXml, labelProvider);
+	}
+	
+	
+	@Override
+	protected PropertyValueModel<Image> buildImageModel() {
+		return new StaticPropertyValueModel<Image>(JptUiPlugin.getImage(JptUiIcons.JPA_FILE));
+	}
+	
+	@Override
+	protected PropertyValueModel<String> buildTextModel() {
+		return new StaticPropertyValueModel<String>(((OrmXml) model()).getResource().getName());
+	}
+	
+	@Override
+	protected PropertyValueModel<String> buildDescriptionModel() {
+		OrmXml ormXml = (OrmXml) model();
+		return new StaticPropertyValueModel<String>(
+			ormXml.getResource().getName()
+			+ " - " + ormXml.getResource().getParent().getFullPath().makeRelative().toString());
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/platform/generic/PersistenceItemLabelProvider.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/platform/generic/PersistenceItemLabelProvider.java
new file mode 100644
index 0000000..7107a66
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/platform/generic/PersistenceItemLabelProvider.java
@@ -0,0 +1,47 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2009 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.ui.internal.platform.generic;
+
+import org.eclipse.jpt.core.context.persistence.Persistence;
+import org.eclipse.jpt.ui.JptUiPlugin;
+import org.eclipse.jpt.ui.internal.JptUiIcons;
+import org.eclipse.jpt.ui.internal.JptUiMessages;
+import org.eclipse.jpt.ui.internal.jface.AbstractItemLabelProvider;
+import org.eclipse.jpt.ui.jface.DelegatingContentAndLabelProvider;
+import org.eclipse.jpt.utility.internal.model.value.StaticPropertyValueModel;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.graphics.Image;
+
+public class PersistenceItemLabelProvider extends AbstractItemLabelProvider
+{
+	public PersistenceItemLabelProvider(
+			Persistence persistence, DelegatingContentAndLabelProvider labelProvider) {
+		super(persistence, labelProvider);
+	}
+	
+	
+	@Override
+	protected PropertyValueModel<Image> buildImageModel() {
+		return new StaticPropertyValueModel<Image>(JptUiPlugin.getImage(JptUiIcons.PERSISTENCE));
+	}
+	
+	@Override
+	protected PropertyValueModel<String> buildTextModel() {
+		return new StaticPropertyValueModel<String>(
+			JptUiMessages.PersistenceItemLabelProviderFactory_persistenceLabel);
+	}
+	
+	@Override
+	protected PropertyValueModel<String> buildDescriptionModel() {
+		return new StaticPropertyValueModel<String>(
+			JptUiMessages.PersistenceItemLabelProviderFactory_persistenceLabel
+				+ " - " + ((Persistence) model()).getResource().getFullPath().makeRelative());
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/platform/generic/PersistenceUnitItemLabelProvider.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/platform/generic/PersistenceUnitItemLabelProvider.java
new file mode 100644
index 0000000..9a6e55a
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/platform/generic/PersistenceUnitItemLabelProvider.java
@@ -0,0 +1,55 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2009 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.ui.internal.platform.generic;
+
+import org.eclipse.jpt.core.context.persistence.PersistenceUnit;
+import org.eclipse.jpt.ui.JptUiPlugin;
+import org.eclipse.jpt.ui.internal.JptUiIcons;
+import org.eclipse.jpt.ui.internal.jface.AbstractItemLabelProvider;
+import org.eclipse.jpt.ui.jface.DelegatingContentAndLabelProvider;
+import org.eclipse.jpt.utility.internal.model.value.PropertyAspectAdapter;
+import org.eclipse.jpt.utility.internal.model.value.StaticPropertyValueModel;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.graphics.Image;
+
+public class PersistenceUnitItemLabelProvider extends AbstractItemLabelProvider
+{
+	public PersistenceUnitItemLabelProvider(
+			PersistenceUnit persistenceUnit, DelegatingContentAndLabelProvider labelProvider) {
+		super(persistenceUnit, labelProvider);
+	}
+	
+	
+	@Override
+	protected PropertyValueModel<Image> buildImageModel() {
+		return new StaticPropertyValueModel<Image>(JptUiPlugin.getImage(JptUiIcons.PERSISTENCE_UNIT));
+	}
+	
+	@Override
+	protected PropertyValueModel<String> buildTextModel() {
+		return new PropertyAspectAdapter<PersistenceUnit, String>(PersistenceUnit.NAME_PROPERTY, (PersistenceUnit) model()) {
+			 @Override
+			protected String buildValue_() {
+				return subject.getName();
+			}
+		};
+	}
+	
+	@Override
+	protected PropertyValueModel<String> buildDescriptionModel() {
+		return new PropertyAspectAdapter<PersistenceUnit, String>(PersistenceUnit.NAME_PROPERTY, (PersistenceUnit) model()) {
+			@Override
+			protected String buildValue_() {
+				return subject.getName()
+				+ " - " + subject.getResource().getFullPath().makeRelative();
+			}
+		};
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/platform/generic/PersistenceXmlItemContentProvider.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/platform/generic/PersistenceXmlItemContentProvider.java
new file mode 100644
index 0000000..bfe63a6
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/platform/generic/PersistenceXmlItemContentProvider.java
@@ -0,0 +1,61 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2009 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.ui.internal.platform.generic;
+
+import java.util.ListIterator;
+
+import org.eclipse.jpt.core.context.JpaRootContextNode;
+import org.eclipse.jpt.core.context.persistence.Persistence;
+import org.eclipse.jpt.core.context.persistence.PersistenceUnit;
+import org.eclipse.jpt.core.context.persistence.PersistenceXml;
+import org.eclipse.jpt.ui.internal.jface.AbstractTreeItemContentProvider;
+import org.eclipse.jpt.ui.internal.jface.DelegatingTreeContentAndLabelProvider;
+import org.eclipse.jpt.utility.internal.model.value.ListAspectAdapter;
+import org.eclipse.jpt.utility.internal.model.value.ListCollectionValueModelAdapter;
+import org.eclipse.jpt.utility.internal.model.value.PropertyAspectAdapter;
+import org.eclipse.jpt.utility.model.value.CollectionValueModel;
+
+public class PersistenceXmlItemContentProvider
+	extends AbstractTreeItemContentProvider<PersistenceUnit>
+{
+	public PersistenceXmlItemContentProvider(
+			PersistenceXml persistenceXml, DelegatingTreeContentAndLabelProvider contentProvider) {
+		super(persistenceXml, contentProvider);
+	}
+	
+	@Override
+	public PersistenceXml getModel() {
+		return (PersistenceXml) super.getModel();
+	}
+	
+	@Override
+	public JpaRootContextNode getParent() {
+		return (JpaRootContextNode) getModel().getParent();
+	}
+	
+	@Override
+	protected CollectionValueModel<PersistenceUnit> buildChildrenModel() {
+		return new ListCollectionValueModelAdapter<PersistenceUnit>(
+		new ListAspectAdapter<Persistence, PersistenceUnit>(
+				new PropertyAspectAdapter<PersistenceXml, Persistence>(
+						PersistenceXml.PERSISTENCE_PROPERTY, getModel()) {
+					@Override
+					protected Persistence buildValue_() {
+						return subject.getPersistence();
+					}
+				},
+				Persistence.PERSISTENCE_UNITS_LIST) {
+			@Override
+			protected ListIterator<PersistenceUnit> listIterator_() {
+				return subject.persistenceUnits();
+			}
+		});
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/platform/generic/PersistenceXmlItemLabelProvider.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/platform/generic/PersistenceXmlItemLabelProvider.java
new file mode 100644
index 0000000..c6ff9eb
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/platform/generic/PersistenceXmlItemLabelProvider.java
@@ -0,0 +1,46 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2009 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.ui.internal.platform.generic;
+
+import org.eclipse.jpt.core.context.persistence.PersistenceXml;
+import org.eclipse.jpt.ui.JptUiPlugin;
+import org.eclipse.jpt.ui.internal.JptUiIcons;
+import org.eclipse.jpt.ui.internal.jface.AbstractItemLabelProvider;
+import org.eclipse.jpt.ui.jface.DelegatingContentAndLabelProvider;
+import org.eclipse.jpt.utility.internal.model.value.StaticPropertyValueModel;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.graphics.Image;
+
+public class PersistenceXmlItemLabelProvider extends AbstractItemLabelProvider
+{
+	public PersistenceXmlItemLabelProvider(
+			PersistenceXml persistenceXml, DelegatingContentAndLabelProvider labelProvider) {
+		super(persistenceXml, labelProvider);
+	}
+	
+	
+	@Override
+	protected PropertyValueModel<Image> buildImageModel() {
+		return new StaticPropertyValueModel<Image>(JptUiPlugin.getImage(JptUiIcons.JPA_FILE));
+	}
+	
+	@Override
+	protected PropertyValueModel<String> buildTextModel() {
+		return new StaticPropertyValueModel<String>(((PersistenceXml) model()).getResource().getName());
+	}
+	
+	@Override
+	protected PropertyValueModel<String> buildDescriptionModel() {
+		PersistenceXml persistenceXml = (PersistenceXml) model();
+		return new StaticPropertyValueModel<String>(
+			persistenceXml.getResource().getName()
+			+ " - " + persistenceXml.getResource().getParent().getFullPath().makeRelative().toString());
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/platform/generic/PersistentAttributeItemContentProvider.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/platform/generic/PersistentAttributeItemContentProvider.java
new file mode 100644
index 0000000..9c7712f
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/platform/generic/PersistentAttributeItemContentProvider.java
@@ -0,0 +1,39 @@
+/*******************************************************************************
+ *  Copyright (c) 2008  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.ui.internal.platform.generic;
+
+import org.eclipse.jpt.core.context.PersistentAttribute;
+import org.eclipse.jpt.ui.internal.jface.AbstractTreeItemContentProvider;
+import org.eclipse.jpt.ui.internal.jface.DelegatingTreeContentAndLabelProvider;
+
+@SuppressWarnings("unchecked")
+public class PersistentAttributeItemContentProvider extends AbstractTreeItemContentProvider
+{
+	public PersistentAttributeItemContentProvider(
+			PersistentAttribute persistentAttribute, DelegatingTreeContentAndLabelProvider contentProvider) {
+		super(persistentAttribute, contentProvider);
+	}
+	
+	@Override
+	public PersistentAttribute getModel() {
+		return (PersistentAttribute) super.getModel();
+	}
+	
+	@Override
+	public Object getParent() {
+		return getModel().getParent();
+	}
+	
+	@Override
+	public boolean hasChildren() {
+		return false;
+	}
+}
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/platform/generic/PersistentAttributeItemLabelProvider.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/platform/generic/PersistentAttributeItemLabelProvider.java
new file mode 100644
index 0000000..77134e4
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/platform/generic/PersistentAttributeItemLabelProvider.java
@@ -0,0 +1,76 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2010 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.ui.internal.platform.generic;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.jpt.core.context.PersistentAttribute;
+import org.eclipse.jpt.ui.internal.JpaMappingImageHelper;
+import org.eclipse.jpt.ui.internal.JptUiIcons;
+import org.eclipse.jpt.ui.internal.jface.AbstractItemLabelProvider;
+import org.eclipse.jpt.ui.jface.DelegatingContentAndLabelProvider;
+import org.eclipse.jpt.utility.internal.model.value.PropertyAspectAdapter;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.graphics.Image;
+
+public class PersistentAttributeItemLabelProvider extends AbstractItemLabelProvider
+{
+	public PersistentAttributeItemLabelProvider(
+			PersistentAttribute persistentAttribute, DelegatingContentAndLabelProvider labelProvider) {
+		super(persistentAttribute, labelProvider);
+	}
+	
+	
+	
+	@Override
+	protected PropertyValueModel<Image> buildImageModel() {
+		return new PropertyAspectAdapter<PersistentAttribute, Image>(
+				new String[] {PersistentAttribute.DEFAULT_MAPPING_PROPERTY, PersistentAttribute.SPECIFIED_MAPPING_PROPERTY}, 
+				(PersistentAttribute) model()) {
+			@Override
+			protected Image buildValue_() {
+				if (((PersistentAttribute) model()).isVirtual()) {
+					return JptUiIcons.ghost(JpaMappingImageHelper.iconKeyForAttributeMapping(this.subject.getMappingKey()));
+				}
+				return JpaMappingImageHelper.imageForAttributeMapping(this.subject.getMappingKey());
+			}
+		};
+	}
+	
+	@Override
+	protected PropertyValueModel<String> buildTextModel() {
+		return new PropertyAspectAdapter<PersistentAttribute, String>(PersistentAttribute.NAME_PROPERTY, (PersistentAttribute) model()) {
+			@Override
+			protected String buildValue_() {
+				return subject.getName();
+			}
+		};
+	}
+	
+	@Override
+	protected PropertyValueModel<String> buildDescriptionModel() {
+		return new PropertyAspectAdapter<PersistentAttribute, String>(PersistentAttribute.NAME_PROPERTY, (PersistentAttribute) model()) {
+			@Override
+			protected String buildValue_() {
+				StringBuilder sb = new StringBuilder();
+				sb.append(this.subject.getPersistenceUnit().getName());
+				sb.append('/');
+				sb.append(this.subject.getOwningPersistentType().getName());
+				sb.append('/');
+				sb.append(this.subject.getName());
+				IResource resource = this.subject.getResource();
+				if (resource != null) {
+					sb.append(" - "); //$NON-NLS-1$
+					sb.append(resource.getFullPath().makeRelative());
+				}
+				return sb.toString();
+			}
+		};
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/platform/generic/PersistentTypeItemLabelProvider.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/platform/generic/PersistentTypeItemLabelProvider.java
new file mode 100644
index 0000000..53ce921
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/platform/generic/PersistentTypeItemLabelProvider.java
@@ -0,0 +1,67 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2009 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.ui.internal.platform.generic;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.jpt.core.context.PersistentType;
+import org.eclipse.jpt.ui.internal.JpaMappingImageHelper;
+import org.eclipse.jpt.ui.internal.jface.AbstractItemLabelProvider;
+import org.eclipse.jpt.ui.jface.DelegatingContentAndLabelProvider;
+import org.eclipse.jpt.utility.internal.model.value.PropertyAspectAdapter;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.graphics.Image;
+
+public class PersistentTypeItemLabelProvider extends AbstractItemLabelProvider
+{
+	public PersistentTypeItemLabelProvider(
+			PersistentType persistentType, DelegatingContentAndLabelProvider labelProvider) {
+		super(persistentType, labelProvider);
+	}
+	
+	
+	@Override
+	protected PropertyValueModel<Image> buildImageModel() {
+		return new PropertyAspectAdapter<PersistentType, Image>(PersistentType.MAPPING_PROPERTY, (PersistentType) model()) {
+			@Override
+			protected Image buildValue_() {
+				return JpaMappingImageHelper.imageForTypeMapping(subject.getMappingKey());
+			}
+		};
+	}
+	
+	@Override
+	protected PropertyValueModel<String> buildTextModel() {
+		return new PropertyAspectAdapter<PersistentType, String>(PersistentType.NAME_PROPERTY, (PersistentType) model()) {
+			@Override
+			protected String buildValue_() {
+				return subject.getShortName();
+			}
+		};
+	}
+	
+	@Override
+	protected PropertyValueModel<String> buildDescriptionModel() {
+		return new PropertyAspectAdapter<PersistentType, String>(PersistentType.NAME_PROPERTY, (PersistentType) model()) {
+			@Override
+			protected String buildValue_() {
+				StringBuilder sb = new StringBuilder();
+				sb.append(this.subject.getPersistenceUnit().getName());
+				sb.append('/');
+				sb.append(this.subject.getName());
+				IResource resource = this.subject.getResource();
+				if (resource != null) {
+					sb.append(" - "); //$NON-NLS-1$
+					sb.append(resource.getFullPath().makeRelative());
+				}
+				return sb.toString();
+			}
+		};
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/platform/generic/RootContextItemContentProvider.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/platform/generic/RootContextItemContentProvider.java
new file mode 100644
index 0000000..bb19f58
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/platform/generic/RootContextItemContentProvider.java
@@ -0,0 +1,51 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2009 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.ui.internal.platform.generic;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.jpt.core.context.JpaRootContextNode;
+import org.eclipse.jpt.core.context.persistence.PersistenceXml;
+import org.eclipse.jpt.ui.internal.jface.AbstractTreeItemContentProvider;
+import org.eclipse.jpt.ui.internal.jface.DelegatingTreeContentAndLabelProvider;
+import org.eclipse.jpt.utility.internal.model.value.PropertyAspectAdapter;
+import org.eclipse.jpt.utility.internal.model.value.PropertyCollectionValueModelAdapter;
+import org.eclipse.jpt.utility.model.value.CollectionValueModel;
+
+public class RootContextItemContentProvider
+	extends AbstractTreeItemContentProvider<PersistenceXml>
+{
+	public RootContextItemContentProvider(
+			JpaRootContextNode rootContext, DelegatingTreeContentAndLabelProvider contentProvider) {
+		super(rootContext, contentProvider);
+	}
+	
+	@Override
+	public JpaRootContextNode getModel() {
+		return (JpaRootContextNode) super.getModel();
+	}
+	
+	@Override
+	public IProject getParent() {
+		return getModel().getJpaProject().getProject();
+	}
+	
+	@Override
+	protected CollectionValueModel<PersistenceXml> buildChildrenModel() {
+		return new PropertyCollectionValueModelAdapter<PersistenceXml>(
+				new PropertyAspectAdapter<JpaRootContextNode, PersistenceXml>(
+						JpaRootContextNode.PERSISTENCE_XML_PROPERTY,
+						getModel()) {
+					 @Override
+					protected PersistenceXml buildValue_() {
+						return subject.getPersistenceXml();
+					}
+				});
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/platform/generic/RootContextItemLabelProvider.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/platform/generic/RootContextItemLabelProvider.java
new file mode 100644
index 0000000..cd20cab
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/platform/generic/RootContextItemLabelProvider.java
@@ -0,0 +1,46 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2009 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.ui.internal.platform.generic;
+
+import org.eclipse.jpt.core.context.JpaRootContextNode;
+import org.eclipse.jpt.ui.JptUiPlugin;
+import org.eclipse.jpt.ui.internal.JptUiIcons;
+import org.eclipse.jpt.ui.internal.JptUiMessages;
+import org.eclipse.jpt.ui.internal.jface.AbstractItemLabelProvider;
+import org.eclipse.jpt.ui.jface.DelegatingContentAndLabelProvider;
+import org.eclipse.jpt.utility.internal.model.value.StaticPropertyValueModel;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.graphics.Image;
+
+public class RootContextItemLabelProvider extends AbstractItemLabelProvider
+{
+	public RootContextItemLabelProvider(
+			JpaRootContextNode rootContextNode, DelegatingContentAndLabelProvider labelProvider) {
+		super(rootContextNode, labelProvider);
+	}
+	
+	
+	@Override
+	protected PropertyValueModel<Image> buildImageModel() {
+		return new StaticPropertyValueModel<Image>(JptUiPlugin.getImage(JptUiIcons.JPA_CONTENT));
+	}
+	
+	@Override
+	protected PropertyValueModel<String> buildTextModel() {
+		return new StaticPropertyValueModel<String>(JptUiMessages.JpaContent_label);
+	}
+	
+	@Override
+	protected PropertyValueModel<String> buildDescriptionModel() {
+		return new StaticPropertyValueModel<String>(
+			JptUiMessages.JpaContent_label
+				+ " - " + ((JpaRootContextNode) model()).getResource().getFullPath().makeRelative());
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/preferences/JpaPreferencesPage.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/preferences/JpaPreferencesPage.java
new file mode 100644
index 0000000..8072b83
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/preferences/JpaPreferencesPage.java
@@ -0,0 +1,68 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2009 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.ui.internal.preferences;
+
+import org.eclipse.jface.preference.PreferencePage;
+import org.eclipse.jpt.ui.JptUiPlugin;
+import org.eclipse.jpt.ui.internal.JptUiMessages;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.IWorkbenchPreferencePage;
+
+/**
+ * This is the root of the Java Persistence preferences hierarchy in the IDE
+ * preferences dialog.
+ * <p>
+ * Structure:
+ * <p>
+ * Java Persistence<br>
+ *  |- Errors/Warnings
+ *
+ * @version 2.2
+ * @since 2.2
+ */
+public class JpaPreferencesPage extends PreferencePage
+                                implements IWorkbenchPreferencePage {
+
+	/**
+	 * Creates a new <code>JpaPreferencesPage</code>.
+	 */
+	public JpaPreferencesPage() {
+		super();
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	protected Control createContents(Composite parent) {
+		parent = new Composite(parent, SWT.NONE);
+		parent.setLayout(new GridLayout(1, false));
+
+		// Message label
+		Label label = new Label(parent, SWT.NONE);
+		label.setText(JptUiMessages.JpaPreferencesPage_Description);
+		label.setData(new GridData(GridData.BEGINNING, GridData.BEGINNING, true, true));
+
+		return parent;
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public void init(IWorkbench workbench) {
+		setPreferenceStore(JptUiPlugin.instance().getPreferenceStore());
+	}
+}
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/preferences/JpaProblemSeveritiesPage.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/preferences/JpaProblemSeveritiesPage.java
new file mode 100644
index 0000000..ac3bff4
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/preferences/JpaProblemSeveritiesPage.java
@@ -0,0 +1,899 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2010 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.ui.internal.preferences;
+
+import java.lang.reflect.InvocationTargetException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IWorkspace;
+import org.eclipse.core.resources.IWorkspaceRunnable;
+import org.eclipse.core.resources.IncrementalProjectBuilder;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.preferences.IEclipsePreferences;
+import org.eclipse.jdt.internal.ui.JavaPlugin;
+import org.eclipse.jdt.internal.ui.preferences.PropertyAndPreferencePage;
+import org.eclipse.jdt.internal.ui.preferences.ScrolledPageContent;
+import org.eclipse.jface.dialogs.IDialogSettings;
+import org.eclipse.jface.dialogs.ProgressMonitorDialog;
+import org.eclipse.jface.layout.PixelConverter;
+import org.eclipse.jface.operation.IRunnableContext;
+import org.eclipse.jface.operation.IRunnableWithProgress;
+import org.eclipse.jface.resource.JFaceResources;
+import org.eclipse.jpt.core.JptCorePlugin;
+import org.eclipse.jpt.core.internal.validation.JpaValidationMessages;
+import org.eclipse.jpt.core.internal.validation.JpaValidationPreferences;
+import org.eclipse.jpt.ui.JptUiPlugin;
+import org.eclipse.jpt.ui.internal.JptUiMessages;
+import org.eclipse.jpt.ui.internal.JptUiValidationPreferenceMessages;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.forms.events.ExpansionAdapter;
+import org.eclipse.ui.forms.events.ExpansionEvent;
+import org.eclipse.ui.forms.widgets.ExpandableComposite;
+
+/**
+ * This page shows the Java Persistence validation options. It supports
+ * workspace and project levels severities.
+ *
+ * @version 2.3
+ * @since 2.2
+ */
+@SuppressWarnings("restriction")
+public class JpaProblemSeveritiesPage extends PropertyAndPreferencePage {
+
+	/**
+	 * Severity level state is stored in this Map and is either committed or discarded
+	 * based on user action.
+	 * <br> key is the preferenceKey which is also the validation message key @see JpaValidationMessages.
+	 * <br> value is a severity level - @see JpaValidationPreferences#ERROR WANRING INFO IGNORE
+	 */
+	private Map<String, String> severityLevels;
+
+	/**
+	 * Default severity levels are stored here,  ERROR is the default default so only need
+	 * to include WARNING, INFO, IGNORE in this Map. These will be displayed if neither the project 
+	 * or workspace preference applies.
+	 * <br> key is the preferenceKey which is also the validation message key @see JpaValidationMessages.
+	 * <br> value is a severity level - @see JpaValidationPreferences#ERROR WANRING INFO IGNORE
+	 */
+	private Map<String, String> defaultSeverities;
+	
+	/**
+	 * The list of <code>Combo</code>s is cached in order to perform a revert of
+	 * the properties.
+	 */
+	private List<Combo> combos;
+
+	/**
+	 * The list of <code>ExpandableComposite</code> is cached in order to save
+	 * and restore the expansion state.
+	 */
+	private List<ExpandableComposite> expandablePanes;
+
+	/**
+	 * The position of the "Error" choice in the combo's model.
+	 */
+	private static final int ERROR_INDEX = 0;
+
+	/**
+	 * The position of the "Warning" choice in the combo's model.
+	 */
+	private static final int WARNING_INDEX = 1;
+
+	/**
+	 * The position of the "Info" choice in the combo's model.
+	 */
+	private static final int INFO_INDEX = 2;
+
+	/**
+	 * The position of the "Ignore" choice in the combo's model.
+	 */
+	private static final int IGNORE_INDEX = 3;
+
+	/**
+	 * The unique identifier for this page when it is shown in the IDE
+	 * preferences dialog.
+	 */
+	private static final String JPT_PREFERENCES_PROBLEM_SEVERITIES_ID = "org.eclipse.jpt.ui.preferences.problemSeverities"; //$NON-NLS-1$
+
+	/**
+	 * The unique identifier for this page when it is shown in the project
+	 * preferences dialog.
+	 */
+	private static final String JPT_PROPERTY_PAGES_PROBLEM_SEVERITIES_ID = "org.eclipse.jpt.ui.propertyPages.problemSeverities"; //$NON-NLS-1$
+
+	/**
+	 * A constant used to store and retrieve the preference key (message ID) from
+	 * the combo.
+	 */
+	private static final String PREFERENCE_KEY = "preferenceKey"; //$NON-NLS-1$
+
+	/**
+	 * The scrollable pane used to show the content of this page.
+	 */
+	private ScrolledPageContent scrollable;
+
+	/**
+	 * The possible choices which describes the severity of a single problem.
+	 */
+	private String[] severityDisplayStrings;
+
+	/**
+	 * Constant used to store the expansion state of each expandable pane.
+	 */
+	public static final String SETTINGS_EXPANDED = "expanded"; //$NON-NLS-1$
+
+	/**
+	 * The preference key used to retrieve the dialog settings where the expansion
+	 * states have been stored.
+	 */
+	public static final String SETTINGS_SECTION_NAME = "JpaProblemSeveritiesPage"; //$NON-NLS-1$
+
+	private Boolean hasProjectSpecificPreferences = null;
+
+	/**
+	 * Creates a new <code>JpaProblemSeveritiesPage</code>.
+	 */
+	public JpaProblemSeveritiesPage() {
+		super();
+		initialize();
+	}
+
+	@Override
+	public void init(IWorkbench workbench) {
+		this.setPreferenceStore(JptUiPlugin.instance().getPreferenceStore());
+		this.setDescription(JptUiMessages.JpaProblemSeveritiesPage_Description);
+	}
+
+	protected void initialize() {
+		this.combos = new ArrayList<Combo>();
+		this.expandablePanes = new ArrayList<ExpandableComposite>();
+		this.severityDisplayStrings = buildSeverityDisplayStrings();
+		this.severityLevels = new HashMap<String, String>();
+		this.defaultSeverities = buildDefaultSeverties();
+	}
+
+	//since most of our problems have a default severity of ERROR, we are just defining the WARNING, INFO, IGNORE cases
+	protected Map<String, String> buildDefaultSeverties() {
+		 Map<String, String> defaultSeverities = new HashMap<String, String>();
+
+		 defaultSeverities.put(JpaValidationMessages.PROJECT_NO_CONNECTION, JpaValidationPreferences.WARNING);
+		 defaultSeverities.put(JpaValidationMessages.PROJECT_INVALID_CONNECTION, JpaValidationPreferences.WARNING);
+		 defaultSeverities.put(JpaValidationMessages.PROJECT_INACTIVE_CONNECTION, JpaValidationPreferences.WARNING);
+		 defaultSeverities.put(JpaValidationMessages.ENTITY_ABSTRACT_DISCRIMINATOR_VALUE_DEFINED, JpaValidationPreferences.WARNING);
+		 defaultSeverities.put(JpaValidationMessages.ENTITY_TABLE_PER_CLASS_DISCRIMINATOR_VALUE_DEFINED, JpaValidationPreferences.WARNING);
+		 defaultSeverities.put(JpaValidationMessages.ENTITY_TABLE_PER_CLASS_NOT_PORTABLE_ON_PLATFORM, JpaValidationPreferences.WARNING);
+		 defaultSeverities.put(JpaValidationMessages.PERSISTENCE_UNIT_JAR_FILE_DEPLOYMENT_PATH_WARNING, JpaValidationPreferences.WARNING);
+		 defaultSeverities.put(JpaValidationMessages.MAPPING_FILE_EXTRANEOUS_PERSISTENCE_UNIT_DEFAULTS, JpaValidationPreferences.WARNING);
+		 defaultSeverities.put(JpaValidationMessages.PERSISTENT_TYPE_ANNOTATED_BUT_NOT_INCLUDED_IN_PERSISTENCE_UNIT, JpaValidationPreferences.WARNING);
+		 defaultSeverities.put(JpaValidationMessages.PERSISTENT_ATTRIBUTE_INHERITED_ATTRIBUTES_NOT_SUPPORTED, JpaValidationPreferences.WARNING);
+		 defaultSeverities.put(JpaValidationMessages.PERSISTENCE_MULTIPLE_PERSISTENCE_UNITS, JpaValidationPreferences.WARNING);
+
+		 defaultSeverities.put(JpaValidationMessages.XML_VERSION_NOT_LATEST, JpaValidationPreferences.INFO);
+		 defaultSeverities.put(JpaValidationMessages.PERSISTENCE_UNIT_REDUNDANT_CLASS, JpaValidationPreferences.INFO);
+
+		 return defaultSeverities;
+	}
+
+	@Override
+	protected Control createPreferenceContent(Composite parent) {
+
+		PixelConverter pixelConverter = new PixelConverter(parent);
+
+		// Create a container because the caller will set the GridData and we need
+		// to change the heightHint of the first child and we also need to set the
+		// font otherwise the layout won't be calculated correctly
+		Composite container = new Composite(parent, SWT.NONE);
+		container.setFont(parent.getFont());
+		GridLayout layout = new GridLayout(1, false);
+		layout.marginHeight = 0;
+		layout.marginWidth  = 0;
+		container.setLayout(layout);
+
+		// Create the main composite of this page
+		this.scrollable = new ScrolledPageContent(container);
+
+		GridData gridData = new GridData(GridData.FILL, GridData.FILL, true, true);
+		gridData.heightHint = pixelConverter.convertHeightInCharsToPixels(20);
+		this.scrollable.setLayoutData(gridData);
+
+		// Update the layout of the ScrolledPageContent's body
+		layout = new GridLayout(1, false);
+		layout.marginHeight = 0;
+		layout.marginWidth  = 0;
+
+		parent = this.scrollable.getBody();
+		parent.setLayoutData(new GridData(GridData.FILL, GridData.FILL, true, true));
+		parent.setLayout(layout);
+
+		// Add each expandable category
+		addProjectLevelCategory(parent);
+		addPersistenceUnitLevelCategory(parent);
+		addTypeLevelCategory(parent);
+		addAttributeLevelCategory(parent);
+		addDatabaseCategory(parent);
+		addInheritanceStrategyCategory(parent);
+		addQueriesGeneratorsCategory(parent);
+
+		// Restore the expansion states
+		restoreSectionExpansionStates(getDialogPreferences());
+
+		return container;
+	}
+
+	protected void restoreSectionExpansionStates(IDialogSettings settings) {
+		for (int index = this.expandablePanes.size(); --index >= 0; ) {
+			ExpandableComposite expandablePane = this.expandablePanes.get(index);
+
+			if (settings == null) {
+				// Only expand the first node by default
+				expandablePane.setExpanded(index == 0);
+			}
+			else {
+				expandablePane.setExpanded(settings.getBoolean(SETTINGS_EXPANDED + index));
+			}
+		}
+	}
+
+	@Override
+	public Point computeSize() {
+		return this.doComputeSize();
+	}
+
+	private void addProjectLevelCategory(Composite parent) {
+
+		parent = addExpandableSection(parent, JptUiValidationPreferenceMessages.PROJECT_LEVEL_CATEGORY);
+
+		addLabeledCombo(parent, JptUiValidationPreferenceMessages.NO_JPA_PROJECT,                         JpaValidationMessages.NO_JPA_PROJECT);
+		addLabeledCombo(parent, JptUiValidationPreferenceMessages.PROJECT_NO_CONNECTION,                  JpaValidationMessages.PROJECT_NO_CONNECTION);
+		addLabeledCombo(parent, JptUiValidationPreferenceMessages.PROJECT_INVALID_CONNECTION,             JpaValidationMessages.PROJECT_INVALID_CONNECTION);
+		addLabeledCombo(parent, JptUiValidationPreferenceMessages.PROJECT_INACTIVE_CONNECTION,            JpaValidationMessages.PROJECT_INACTIVE_CONNECTION);
+		addLabeledCombo(parent, JptUiValidationPreferenceMessages.XML_VERSION_NOT_LATEST,                 JpaValidationMessages.XML_VERSION_NOT_LATEST);
+		addLabeledCombo(parent, JptUiValidationPreferenceMessages.PROJECT_NO_PERSISTENCE_XML,             JpaValidationMessages.PROJECT_NO_PERSISTENCE_XML);
+		addLabeledCombo(parent, JptUiValidationPreferenceMessages.PROJECT_MULTIPLE_PERSISTENCE_XML,       JpaValidationMessages.PROJECT_MULTIPLE_PERSISTENCE_XML);
+		addLabeledCombo(parent, JptUiValidationPreferenceMessages.PERSISTENCE_NO_PERSISTENCE_UNIT,        JpaValidationMessages.PERSISTENCE_NO_PERSISTENCE_UNIT);
+		addLabeledCombo(parent, JptUiValidationPreferenceMessages.PERSISTENCE_MULTIPLE_PERSISTENCE_UNITS, JpaValidationMessages.PERSISTENCE_MULTIPLE_PERSISTENCE_UNITS);
+		addLabeledCombo(parent, JptUiValidationPreferenceMessages.PERSISTENCE_XML_INVALID_CONTENT,        JpaValidationMessages.PERSISTENCE_XML_INVALID_CONTENT);
+	}
+
+	private void addPersistenceUnitLevelCategory(Composite parent) {
+
+		parent = addExpandableSection(parent, JptUiValidationPreferenceMessages.PERSISTENCE_UNIT_LEVEL_CATEGORY);
+
+		addLabeledCombo(parent, JptUiValidationPreferenceMessages.PERSISTENCE_UNIT_UNSPECIFIED_MAPPING_FILE,                      JpaValidationMessages.PERSISTENCE_UNIT_UNSPECIFIED_MAPPING_FILE);
+		addLabeledCombo(parent, JptUiValidationPreferenceMessages.PERSISTENCE_UNIT_UNSUPPORTED_MAPPING_FILE_CONTENT,              JpaValidationMessages.PERSISTENCE_UNIT_UNSUPPORTED_MAPPING_FILE_CONTENT);
+		addLabeledCombo(parent, JptUiValidationPreferenceMessages.PERSISTENCE_UNIT_NONEXISTENT_MAPPING_FILE,                      JpaValidationMessages.PERSISTENCE_UNIT_NONEXISTENT_MAPPING_FILE);
+		addLabeledCombo(parent, JptUiValidationPreferenceMessages.PERSISTENCE_UNIT_INVALID_MAPPING_FILE,                          JpaValidationMessages.PERSISTENCE_UNIT_INVALID_MAPPING_FILE);
+		addLabeledCombo(parent, JptUiValidationPreferenceMessages.PERSISTENCE_UNIT_DUPLICATE_MAPPING_FILE,                        JpaValidationMessages.PERSISTENCE_UNIT_DUPLICATE_MAPPING_FILE);
+		addLabeledCombo(parent, JptUiValidationPreferenceMessages.PERSISTENCE_UNIT_UNSPECIFIED_CLASS,                             JpaValidationMessages.PERSISTENCE_UNIT_UNSPECIFIED_CLASS);
+		addLabeledCombo(parent, JptUiValidationPreferenceMessages.PERSISTENCE_UNIT_NONEXISTENT_CLASS,                             JpaValidationMessages.PERSISTENCE_UNIT_NONEXISTENT_CLASS);
+		addLabeledCombo(parent, JptUiValidationPreferenceMessages.PERSISTENCE_UNIT_INVALID_CLASS,                                 JpaValidationMessages.PERSISTENCE_UNIT_INVALID_CLASS);
+		addLabeledCombo(parent, JptUiValidationPreferenceMessages.PERSISTENCE_UNIT_DUPLICATE_CLASS,                               JpaValidationMessages.PERSISTENCE_UNIT_DUPLICATE_CLASS);
+		addLabeledCombo(parent, JptUiValidationPreferenceMessages.PERSISTENCE_UNIT_REDUNDANT_CLASS,                               JpaValidationMessages.PERSISTENCE_UNIT_REDUNDANT_CLASS);
+		addLabeledCombo(parent, JptUiValidationPreferenceMessages.PERSISTENCE_UNIT_DUPLICATE_JAR_FILE,                            JpaValidationMessages.PERSISTENCE_UNIT_DUPLICATE_JAR_FILE);
+		addLabeledCombo(parent, JptUiValidationPreferenceMessages.PERSISTENCE_UNIT_UNSPECIFIED_JAR_FILE,                          JpaValidationMessages.PERSISTENCE_UNIT_UNSPECIFIED_JAR_FILE);
+		addLabeledCombo(parent, JptUiValidationPreferenceMessages.PERSISTENCE_UNIT_JAR_FILE_DEPLOYMENT_PATH_WARNING,              JpaValidationMessages.PERSISTENCE_UNIT_JAR_FILE_DEPLOYMENT_PATH_WARNING);
+		addLabeledCombo(parent, JptUiValidationPreferenceMessages.PERSISTENCE_UNIT_NONEXISTENT_JAR_FILE,                          JpaValidationMessages.PERSISTENCE_UNIT_NONEXISTENT_JAR_FILE);
+		addLabeledCombo(parent, JptUiValidationPreferenceMessages.MAPPING_FILE_EXTRANEOUS_PERSISTENCE_UNIT_DEFAULTS,              JpaValidationMessages.MAPPING_FILE_EXTRANEOUS_PERSISTENCE_UNIT_DEFAULTS);
+	}
+
+	private void addTypeLevelCategory(Composite parent) {
+
+		parent = addExpandableSection(parent, JptUiValidationPreferenceMessages.TYPE_LEVEL_CATEGORY);
+
+		addLabeledCombo(
+			parent, JptUiValidationPreferenceMessages.PERSISTENT_TYPE_MAPPED_BUT_NOT_INCLUDED_IN_PERSISTENCE_UNIT,
+			JpaValidationMessages.PERSISTENT_TYPE_MAPPED_BUT_NOT_INCLUDED_IN_PERSISTENCE_UNIT);
+		addLabeledCombo(
+			parent, JptUiValidationPreferenceMessages.PERSISTENT_TYPE_ANNOTATED_BUT_NOT_INCLUDED_IN_PERSISTENCE_UNIT,
+			JpaValidationMessages.PERSISTENT_TYPE_ANNOTATED_BUT_NOT_INCLUDED_IN_PERSISTENCE_UNIT);
+		addLabeledCombo(
+			parent, JptUiValidationPreferenceMessages.PERSISTENT_TYPE_UNSPECIFIED_CLASS,
+			JpaValidationMessages.PERSISTENT_TYPE_UNSPECIFIED_CLASS);
+		addLabeledCombo(
+			parent, JptUiValidationPreferenceMessages.PERSISTENT_TYPE_UNRESOLVED_CLASS,
+			JpaValidationMessages.PERSISTENT_TYPE_UNRESOLVED_CLASS);
+		addLabeledCombo(
+			parent, JptUiValidationPreferenceMessages.ENTITY_NO_PK,
+			JpaValidationMessages.ENTITY_NO_PK);
+	}
+
+	private void addAttributeLevelCategory(Composite parent) {
+
+		parent = addExpandableSection(parent, JptUiValidationPreferenceMessages.ATTRIBUTE_LEVEL_CATEGORY);
+		
+		addLabeledCombo(
+			parent, JptUiValidationPreferenceMessages.PERSISTENT_ATTRIBUTE_UNSPECIFIED_NAME,
+			JpaValidationMessages.PERSISTENT_ATTRIBUTE_UNSPECIFIED_NAME);
+		addLabeledCombo(
+			parent, JptUiValidationPreferenceMessages.PERSISTENT_ATTRIBUTE_UNRESOLVED_NAME,
+			JpaValidationMessages.PERSISTENT_ATTRIBUTE_UNRESOLVED_NAME);
+		addLabeledCombo(
+			parent, JptUiValidationPreferenceMessages.PERSISTENT_ATTRIBUTE_INHERITED_ATTRIBUTES_NOT_SUPPORTED
+			, JpaValidationMessages.PERSISTENT_ATTRIBUTE_INHERITED_ATTRIBUTES_NOT_SUPPORTED);
+		addLabeledCombo(
+			parent, JptUiValidationPreferenceMessages.PERSISTENT_ATTRIBUTE_INVALID_MAPPING,
+			JpaValidationMessages.PERSISTENT_ATTRIBUTE_INVALID_MAPPING);
+		addLabeledCombo(
+			parent, JptUiValidationPreferenceMessages.PERSISTENT_ATTRIBUTE_FINAL_FIELD,
+			JpaValidationMessages.PERSISTENT_ATTRIBUTE_FINAL_FIELD);
+		addLabeledCombo(
+			parent, JptUiValidationPreferenceMessages.PERSISTENT_ATTRIBUTE_PUBLIC_FIELD,
+			JpaValidationMessages.PERSISTENT_ATTRIBUTE_PUBLIC_FIELD);
+		addLabeledCombo(
+			parent, JptUiValidationPreferenceMessages.MAPPING_UNRESOLVED_MAPPED_BY,
+			JpaValidationMessages.MAPPING_UNRESOLVED_MAPPED_BY);
+		addLabeledCombo(
+			parent, JptUiValidationPreferenceMessages.MAPPING_INVALID_MAPPED_BY,
+			JpaValidationMessages.MAPPING_INVALID_MAPPED_BY);
+		addLabeledCombo(
+			parent, JptUiValidationPreferenceMessages.MAPPING_MAPPED_BY_ON_BOTH_SIDES,
+			JpaValidationMessages.MAPPING_MAPPED_BY_ON_BOTH_SIDES);
+		addLabeledCombo(
+			parent, JptUiValidationPreferenceMessages.TARGET_ENTITY_NOT_DEFINED,
+			JpaValidationMessages.TARGET_ENTITY_NOT_DEFINED);
+		addLabeledCombo(
+			parent, JptUiValidationPreferenceMessages.TARGET_ENTITY_IS_NOT_AN_ENTITY,
+			JpaValidationMessages.TARGET_ENTITY_IS_NOT_AN_ENTITY);
+		addLabeledCombo(
+			parent, JptUiValidationPreferenceMessages.MAPS_ID_VALUE_NOT_SPECIFIED,
+			JpaValidationMessages.MAPS_ID_VALUE_NOT_SPECIFIED);
+		addLabeledCombo(
+			parent, JptUiValidationPreferenceMessages.MAPS_ID_VALUE_NOT_RESOLVED,
+			JpaValidationMessages.MAPS_ID_VALUE_NOT_RESOLVED);
+		addLabeledCombo(
+			parent, JptUiValidationPreferenceMessages.MAPS_ID_VALUE_INVALID,
+			JpaValidationMessages.MAPS_ID_VALUE_INVALID);
+		addLabeledCombo(
+			parent, JptUiValidationPreferenceMessages.ORDER_COLUMN_AND_ORDER_BY_BOTH_SPECIFIED,
+			JpaValidationMessages.ORDER_COLUMN_AND_ORDER_BY_BOTH_SPECIFIED);
+		addLabeledCombo(
+			parent, JptUiValidationPreferenceMessages.ELEMENT_COLLECTION_TARGET_CLASS_NOT_DEFINED,
+			JpaValidationMessages.ELEMENT_COLLECTION_TARGET_CLASS_NOT_DEFINED);
+		addLabeledCombo(
+			parent, JptUiValidationPreferenceMessages.ELEMENT_COLLECTION_TARGET_CLASS_MUST_BE_EMBEDDABLE_OR_BASIC_TYPE,
+			JpaValidationMessages.ELEMENT_COLLECTION_TARGET_CLASS_MUST_BE_EMBEDDABLE_OR_BASIC_TYPE);
+		addLabeledCombo(
+			parent, JptUiValidationPreferenceMessages.ELEMENT_COLLECTION_MAP_KEY_CLASS_NOT_DEFINED,
+			JpaValidationMessages.ELEMENT_COLLECTION_MAP_KEY_CLASS_NOT_DEFINED);
+
+		parent = addSubExpandableSection(parent, JptUiValidationPreferenceMessages.IMPLIED_ATTRIBUTE_LEVEL_CATEGORY);
+		
+		addLabeledCombo(
+			parent, JptUiValidationPreferenceMessages.VIRTUAL_ATTRIBUTE_TARGET_ENTITY_IS_NOT_AN_ENTITY,
+			JpaValidationMessages.VIRTUAL_ATTRIBUTE_TARGET_ENTITY_IS_NOT_AN_ENTITY);
+		addLabeledCombo(
+			parent, JptUiValidationPreferenceMessages.VIRTUAL_ATTRIBUTE_TARGET_ENTITY_NOT_DEFINED,
+			JpaValidationMessages.VIRTUAL_ATTRIBUTE_TARGET_ENTITY_NOT_DEFINED);
+		addLabeledCombo(
+			parent, JptUiValidationPreferenceMessages.VIRTUAL_ATTRIBUTE_ELEMENT_COLLECTION_TARGET_CLASS_NOT_DEFINED,
+			JpaValidationMessages.VIRTUAL_ATTRIBUTE_ELEMENT_COLLECTION_TARGET_CLASS_NOT_DEFINED);
+		addLabeledCombo(
+			parent, JptUiValidationPreferenceMessages.VIRTUAL_ATTRIBUTE_ELEMENT_COLLECTION_TARGET_CLASS_MUST_BE_EMBEDDABLE_OR_BASIC_TYPE,
+			JpaValidationMessages.VIRTUAL_ATTRIBUTE_ELEMENT_COLLECTION_TARGET_CLASS_MUST_BE_EMBEDDABLE_OR_BASIC_TYPE);
+		addLabeledCombo(
+			parent, JptUiValidationPreferenceMessages.VIRTUAL_ATTRIBUTE_ELEMENT_COLLECTION_MAP_KEY_CLASS_NOT_DEFINED,
+			JpaValidationMessages.VIRTUAL_ATTRIBUTE_ELEMENT_COLLECTION_MAP_KEY_CLASS_NOT_DEFINED);	
+	}
+
+	private void addDatabaseCategory(Composite parent) {
+		parent = addExpandableSection(parent, JptUiValidationPreferenceMessages.DATABASE_CATEGORY);
+		parent.setLayout(new GridLayout(1, false));
+
+		addTableCategory(parent);
+		addColumnCategory(parent);
+		addOverridesCategory(parent);
+	}
+
+	private void addTableCategory(Composite parent) {
+		
+		parent = addExpandableSection(parent, JptUiValidationPreferenceMessages.TABLE_CATEGORY);
+		
+		addLabeledCombo(parent, JptUiValidationPreferenceMessages.TABLE_UNRESOLVED_CATALOG,                                            					JpaValidationMessages.TABLE_UNRESOLVED_CATALOG);
+		addLabeledCombo(parent, JptUiValidationPreferenceMessages.TABLE_UNRESOLVED_SCHEMA,                                             					JpaValidationMessages.TABLE_UNRESOLVED_SCHEMA);
+		addLabeledCombo(parent, JptUiValidationPreferenceMessages.TABLE_UNRESOLVED_NAME,                                               					JpaValidationMessages.TABLE_UNRESOLVED_NAME);
+		addLabeledCombo(parent, JptUiValidationPreferenceMessages.SECONDARY_TABLE_UNRESOLVED_CATALOG,                                  					JpaValidationMessages.SECONDARY_TABLE_UNRESOLVED_CATALOG);
+		addLabeledCombo(parent, JptUiValidationPreferenceMessages.SECONDARY_TABLE_UNRESOLVED_SCHEMA,                                   					JpaValidationMessages.SECONDARY_TABLE_UNRESOLVED_SCHEMA);
+		addLabeledCombo(parent, JptUiValidationPreferenceMessages.SECONDARY_TABLE_UNRESOLVED_NAME,                                     					JpaValidationMessages.SECONDARY_TABLE_UNRESOLVED_NAME);
+		addLabeledCombo(parent, JptUiValidationPreferenceMessages.JOIN_TABLE_UNRESOLVED_CATALOG,                                       					JpaValidationMessages.JOIN_TABLE_UNRESOLVED_CATALOG);
+		addLabeledCombo(parent, JptUiValidationPreferenceMessages.JOIN_TABLE_UNRESOLVED_SCHEMA,                                        					JpaValidationMessages.JOIN_TABLE_UNRESOLVED_SCHEMA);
+		addLabeledCombo(parent, JptUiValidationPreferenceMessages.JOIN_TABLE_UNRESOLVED_NAME,                                          					JpaValidationMessages.JOIN_TABLE_UNRESOLVED_NAME);
+		addLabeledCombo(parent, JptUiValidationPreferenceMessages.VIRTUAL_SECONDARY_TABLE_PRIMARY_KEY_JOIN_COLUMN_UNRESOLVED_NAME, 										JpaValidationMessages.VIRTUAL_SECONDARY_TABLE_PRIMARY_KEY_JOIN_COLUMN_UNRESOLVED_NAME);
+		addLabeledCombo(parent, JptUiValidationPreferenceMessages.VIRTUAL_SECONDARY_TABLE_PRIMARY_KEY_JOIN_COLUMN_UNRESOLVED_REFERENCED_COLUMN_NAME, 					JpaValidationMessages.VIRTUAL_SECONDARY_TABLE_PRIMARY_KEY_JOIN_COLUMN_UNRESOLVED_REFERENCED_COLUMN_NAME);
+		addLabeledCombo(parent, JptUiValidationPreferenceMessages.VIRTUAL_SECONDARY_TABLE_PRIMARY_KEY_JOIN_COLUMN_NAME_MUST_BE_SPECIFIED_MULTIPLE_JOIN_COLUMNS, 		JpaValidationMessages.VIRTUAL_SECONDARY_TABLE_PRIMARY_KEY_JOIN_COLUMN_NAME_MUST_BE_SPECIFIED_MULTIPLE_JOIN_COLUMNS);
+		addLabeledCombo(parent, JptUiValidationPreferenceMessages.VIRTUAL_SECONDARY_TABLE_PRIMARY_KEY_JOIN_COLUMN_REFERENCED_COLUMN_NAME_MUST_BE_SPECIFIED_MULTIPLE_JOIN_COLUMNS, JpaValidationMessages.VIRTUAL_SECONDARY_TABLE_PRIMARY_KEY_JOIN_COLUMN_REFERENCED_COLUMN_NAME_MUST_BE_SPECIFIED_MULTIPLE_JOIN_COLUMNS);
+		addLabeledCombo(parent, JptUiValidationPreferenceMessages.COLLECTION_TABLE_UNRESOLVED_CATALOG,                                					JpaValidationMessages.COLLECTION_TABLE_UNRESOLVED_CATALOG);
+		addLabeledCombo(parent, JptUiValidationPreferenceMessages.COLLECTION_TABLE_UNRESOLVED_SCHEMA,                                 		 			JpaValidationMessages.COLLECTION_TABLE_UNRESOLVED_SCHEMA);
+		addLabeledCombo(parent, JptUiValidationPreferenceMessages.COLLECTION_TABLE_UNRESOLVED_NAME,                                    					JpaValidationMessages.COLLECTION_TABLE_UNRESOLVED_NAME);
+
+		parent = addSubExpandableSection(parent, JptUiValidationPreferenceMessages.IMPLIED_ATTRIBUTE_LEVEL_CATEGORY);
+
+		addLabeledCombo(parent, JptUiValidationPreferenceMessages.VIRTUAL_ATTRIBUTE_JOIN_TABLE_UNRESOLVED_CATALOG,                                      JpaValidationMessages.VIRTUAL_ATTRIBUTE_JOIN_TABLE_UNRESOLVED_CATALOG);
+		addLabeledCombo(parent, JptUiValidationPreferenceMessages.VIRTUAL_ATTRIBUTE_JOIN_TABLE_UNRESOLVED_SCHEMA,                                       JpaValidationMessages.VIRTUAL_ATTRIBUTE_JOIN_TABLE_UNRESOLVED_SCHEMA);
+		addLabeledCombo(parent, JptUiValidationPreferenceMessages.VIRTUAL_ATTRIBUTE_JOIN_TABLE_UNRESOLVED_NAME,                                         JpaValidationMessages.VIRTUAL_ATTRIBUTE_JOIN_TABLE_UNRESOLVED_NAME);
+		addLabeledCombo(parent, JptUiValidationPreferenceMessages.VIRTUAL_ATTRIBUTE_COLLECTION_TABLE_UNRESOLVED_CATALOG,                                JpaValidationMessages.VIRTUAL_ATTRIBUTE_COLLECTION_TABLE_UNRESOLVED_CATALOG);
+		addLabeledCombo(parent, JptUiValidationPreferenceMessages.VIRTUAL_ATTRIBUTE_COLLECTION_TABLE_UNRESOLVED_SCHEMA,                                 JpaValidationMessages.VIRTUAL_ATTRIBUTE_COLLECTION_TABLE_UNRESOLVED_SCHEMA);
+		addLabeledCombo(parent, JptUiValidationPreferenceMessages.VIRTUAL_ATTRIBUTE_COLLECTION_TABLE_UNRESOLVED_NAME,                                   JpaValidationMessages.VIRTUAL_ATTRIBUTE_COLLECTION_TABLE_UNRESOLVED_NAME);
+	}
+	
+	private void addColumnCategory(Composite parent) {	
+		parent = addExpandableSection(parent, JptUiValidationPreferenceMessages.COLUMN_CATEGORY);
+		
+		addLabeledCombo(parent, JptUiValidationPreferenceMessages.COLUMN_TABLE_NOT_VALID,                                      							JpaValidationMessages.COLUMN_TABLE_NOT_VALID);
+		addLabeledCombo(parent, JptUiValidationPreferenceMessages.COLUMN_UNRESOLVED_TABLE,                                             					JpaValidationMessages.COLUMN_UNRESOLVED_TABLE);
+		addLabeledCombo(parent, JptUiValidationPreferenceMessages.COLUMN_UNRESOLVED_NAME,                                              					JpaValidationMessages.COLUMN_UNRESOLVED_NAME);
+		addLabeledCombo(parent, JptUiValidationPreferenceMessages.JOIN_COLUMN_TABLE_NOT_VALID,                                  						JpaValidationMessages.JOIN_COLUMN_TABLE_NOT_VALID);
+		addLabeledCombo(parent, JptUiValidationPreferenceMessages.JOIN_COLUMN_UNRESOLVED_NAME,                                         					JpaValidationMessages.JOIN_COLUMN_UNRESOLVED_NAME);
+		addLabeledCombo(parent, JptUiValidationPreferenceMessages.JOIN_COLUMN_NAME_MUST_BE_SPECIFIED_MULTIPLE_JOIN_COLUMNS,                   			JpaValidationMessages.JOIN_COLUMN_NAME_MUST_BE_SPECIFIED_MULTIPLE_JOIN_COLUMNS);
+		addLabeledCombo(parent, JptUiValidationPreferenceMessages.JOIN_COLUMN_UNRESOLVED_REFERENCED_COLUMN_NAME,                       					JpaValidationMessages.JOIN_COLUMN_UNRESOLVED_REFERENCED_COLUMN_NAME);
+		addLabeledCombo(parent, JptUiValidationPreferenceMessages.JOIN_COLUMN_REFERENCED_COLUMN_NAME_MUST_BE_SPECIFIED_MULTIPLE_JOIN_COLUMNS, 			JpaValidationMessages.JOIN_COLUMN_REFERENCED_COLUMN_NAME_MUST_BE_SPECIFIED_MULTIPLE_JOIN_COLUMNS);
+		addLabeledCombo(parent, JptUiValidationPreferenceMessages.INVERSE_JOIN_COLUMN_TABLE_NOT_VALID,                                  				JpaValidationMessages.INVERSE_JOIN_COLUMN_TABLE_NOT_VALID);
+		addLabeledCombo(parent, JptUiValidationPreferenceMessages.INVERSE_JOIN_COLUMN_UNRESOLVED_NAME,                                         			JpaValidationMessages.INVERSE_JOIN_COLUMN_UNRESOLVED_NAME);
+		addLabeledCombo(parent, JptUiValidationPreferenceMessages.INVERSE_JOIN_COLUMN_NAME_MUST_BE_SPECIFIED_MULTIPLE_JOIN_COLUMNS,                   	JpaValidationMessages.INVERSE_JOIN_COLUMN_NAME_MUST_BE_SPECIFIED_MULTIPLE_JOIN_COLUMNS);
+		addLabeledCombo(parent, JptUiValidationPreferenceMessages.INVERSE_JOIN_COLUMN_UNRESOLVED_REFERENCED_COLUMN_NAME,                       			JpaValidationMessages.INVERSE_JOIN_COLUMN_UNRESOLVED_REFERENCED_COLUMN_NAME);
+		addLabeledCombo(parent, JptUiValidationPreferenceMessages.INVERSE_JOIN_COLUMN_REFERENCED_COLUMN_NAME_MUST_BE_SPECIFIED_MULTIPLE_JOIN_COLUMNS, 	JpaValidationMessages.INVERSE_JOIN_COLUMN_REFERENCED_COLUMN_NAME_MUST_BE_SPECIFIED_MULTIPLE_JOIN_COLUMNS);
+		addLabeledCombo(parent, JptUiValidationPreferenceMessages.PRIMARY_KEY_JOIN_COLUMN_UNRESOLVED_NAME,                            	 				JpaValidationMessages.PRIMARY_KEY_JOIN_COLUMN_UNRESOLVED_NAME);
+		addLabeledCombo(parent, JptUiValidationPreferenceMessages.PRIMARY_KEY_JOIN_COLUMN_NAME_MUST_BE_SPECIFIED_MULTIPLE_JOIN_COLUMNS,                 JpaValidationMessages.PRIMARY_KEY_JOIN_COLUMN_NAME_MUST_BE_SPECIFIED_MULTIPLE_JOIN_COLUMNS);
+		addLabeledCombo(parent, JptUiValidationPreferenceMessages.PRIMARY_KEY_JOIN_COLUMN_UNRESOLVED_REFERENCED_COLUMN_NAME,           					JpaValidationMessages.PRIMARY_KEY_JOIN_COLUMN_UNRESOLVED_REFERENCED_COLUMN_NAME);
+		addLabeledCombo(parent, JptUiValidationPreferenceMessages.PRIMARY_KEY_JOIN_COLUMN_REFERENCED_COLUMN_NAME_MUST_BE_SPECIFIED_MULTIPLE_JOIN_COLUMNS,JpaValidationMessages.PRIMARY_KEY_JOIN_COLUMN_REFERENCED_COLUMN_NAME_MUST_BE_SPECIFIED_MULTIPLE_JOIN_COLUMNS);
+		addLabeledCombo(parent, JptUiValidationPreferenceMessages.VIRTUAL_PRIMARY_KEY_JOIN_COLUMN_UNRESOLVED_NAME, 														JpaValidationMessages.VIRTUAL_PRIMARY_KEY_JOIN_COLUMN_UNRESOLVED_NAME);
+		addLabeledCombo(parent, JptUiValidationPreferenceMessages.VIRTUAL_PRIMARY_KEY_JOIN_COLUMN_UNRESOLVED_REFERENCED_COLUMN_NAME, 									JpaValidationMessages.VIRTUAL_PRIMARY_KEY_JOIN_COLUMN_UNRESOLVED_REFERENCED_COLUMN_NAME);
+		addLabeledCombo(parent, JptUiValidationPreferenceMessages.ORDER_COLUMN_UNRESOLVED_NAME,                                        					JpaValidationMessages.ORDER_COLUMN_UNRESOLVED_NAME);
+		addLabeledCombo(parent, JptUiValidationPreferenceMessages.MAP_KEY_COLUMN_TABLE_NOT_VALID, 														JpaValidationMessages.MAP_KEY_COLUMN_TABLE_NOT_VALID);
+
+		parent = addSubExpandableSection(parent, JptUiValidationPreferenceMessages.IMPLIED_ATTRIBUTE_LEVEL_CATEGORY);
+
+		addLabeledCombo(parent, JptUiValidationPreferenceMessages.VIRTUAL_ATTRIBUTE_COLUMN_UNRESOLVED_NAME,                                              				JpaValidationMessages.VIRTUAL_ATTRIBUTE_COLUMN_UNRESOLVED_NAME);
+		addLabeledCombo(parent, JptUiValidationPreferenceMessages.VIRTUAL_ATTRIBUTE_COLUMN_TABLE_NOT_VALID,                  				                   	 		JpaValidationMessages.VIRTUAL_ATTRIBUTE_COLUMN_TABLE_NOT_VALID);
+		addLabeledCombo(parent, JptUiValidationPreferenceMessages.VIRTUAL_ATTRIBUTE_JOIN_COLUMN_UNRESOLVED_TABLE,                                        				JpaValidationMessages.VIRTUAL_ATTRIBUTE_JOIN_COLUMN_UNRESOLVED_TABLE);
+		addLabeledCombo(parent, JptUiValidationPreferenceMessages.VIRTUAL_ATTRIBUTE_JOIN_COLUMN_UNRESOLVED_NAME,                                         				JpaValidationMessages.VIRTUAL_ATTRIBUTE_JOIN_COLUMN_UNRESOLVED_NAME);
+		addLabeledCombo(parent, JptUiValidationPreferenceMessages.VIRTUAL_ATTRIBUTE_JOIN_COLUMN_NAME_MUST_BE_SPECIFIED_MULTIPLE_JOIN_COLUMNS,                   		JpaValidationMessages.VIRTUAL_ATTRIBUTE_JOIN_COLUMN_NAME_MUST_BE_SPECIFIED_MULTIPLE_JOIN_COLUMNS);
+		addLabeledCombo(parent, JptUiValidationPreferenceMessages.VIRTUAL_ATTRIBUTE_JOIN_COLUMN_UNRESOLVED_REFERENCED_COLUMN_NAME,                       				JpaValidationMessages.VIRTUAL_ATTRIBUTE_JOIN_COLUMN_UNRESOLVED_REFERENCED_COLUMN_NAME);
+		addLabeledCombo(parent, JptUiValidationPreferenceMessages.VIRTUAL_ATTRIBUTE_JOIN_COLUMN_REFERENCED_COLUMN_NAME_MUST_BE_SPECIFIED_MULTIPLE_JOIN_COLUMNS,		 	JpaValidationMessages.VIRTUAL_ATTRIBUTE_JOIN_COLUMN_REFERENCED_COLUMN_NAME_MUST_BE_SPECIFIED_MULTIPLE_JOIN_COLUMNS);
+		addLabeledCombo(parent, JptUiValidationPreferenceMessages.VIRTUAL_ATTRIBUTE_JOIN_COLUMN_TABLE_NOT_VALID,      													JpaValidationMessages.VIRTUAL_ATTRIBUTE_JOIN_COLUMN_TABLE_NOT_VALID);
+		addLabeledCombo(parent, JptUiValidationPreferenceMessages.VIRTUAL_ATTRIBUTE_INVERSE_JOIN_COLUMN_TABLE_NOT_VALID,      											JpaValidationMessages.VIRTUAL_ATTRIBUTE_INVERSE_JOIN_COLUMN_TABLE_NOT_VALID);
+		addLabeledCombo(parent, JptUiValidationPreferenceMessages.VIRTUAL_ATTRIBUTE_INVERSE_JOIN_COLUMN_UNRESOLVED_NAME,      											JpaValidationMessages.VIRTUAL_ATTRIBUTE_INVERSE_JOIN_COLUMN_UNRESOLVED_NAME);
+		addLabeledCombo(parent, JptUiValidationPreferenceMessages.VIRTUAL_ATTRIBUTE_INVERSE_JOIN_COLUMN_NAME_MUST_BE_SPECIFIED_MULTIPLE_JOIN_COLUMNS,      				JpaValidationMessages.VIRTUAL_ATTRIBUTE_INVERSE_JOIN_COLUMN_NAME_MUST_BE_SPECIFIED_MULTIPLE_JOIN_COLUMNS);
+		addLabeledCombo(parent, JptUiValidationPreferenceMessages.VIRTUAL_ATTRIBUTE_INVERSE_JOIN_COLUMN_UNRESOLVED_REFERENCED_COLUMN_NAME,      						JpaValidationMessages.VIRTUAL_ATTRIBUTE_INVERSE_JOIN_COLUMN_UNRESOLVED_REFERENCED_COLUMN_NAME);
+		addLabeledCombo(parent, JptUiValidationPreferenceMessages.VIRTUAL_ATTRIBUTE_INVERSE_JOIN_COLUMN_REFERENCED_COLUMN_NAME_MUST_BE_SPECIFIED_MULTIPLE_JOIN_COLUMNS, JpaValidationMessages.VIRTUAL_ATTRIBUTE_INVERSE_JOIN_COLUMN_REFERENCED_COLUMN_NAME_MUST_BE_SPECIFIED_MULTIPLE_JOIN_COLUMNS);
+		addLabeledCombo(parent, JptUiValidationPreferenceMessages.VIRTUAL_ATTRIBUTE_ORDER_COLUMN_UNRESOLVED_NAME,                                        				JpaValidationMessages.VIRTUAL_ATTRIBUTE_ORDER_COLUMN_UNRESOLVED_NAME);
+		addLabeledCombo(parent, JptUiValidationPreferenceMessages.VIRTUAL_ATTRIBUTE_MAP_KEY_COLUMN_TABLE_NOT_VALID, 													JpaValidationMessages.VIRTUAL_ATTRIBUTE_MAP_KEY_COLUMN_TABLE_NOT_VALID);
+	}
+
+	private void addOverridesCategory(Composite parent) {	
+
+		parent = addExpandableSection(parent, JptUiValidationPreferenceMessages.OVERRIDES_CATEGORY);
+
+		addLabeledCombo(parent, JptUiValidationPreferenceMessages.VIRTUAL_ATTRIBUTE_OVERRIDE_COLUMN_TABLE_NOT_VALID,                    				JpaValidationMessages.VIRTUAL_ATTRIBUTE_OVERRIDE_COLUMN_TABLE_NOT_VALID);
+		addLabeledCombo(parent, JptUiValidationPreferenceMessages.VIRTUAL_ATTRIBUTE_OVERRIDE_COLUMN_UNRESOLVED_NAME,                                    JpaValidationMessages.VIRTUAL_ATTRIBUTE_OVERRIDE_COLUMN_UNRESOLVED_NAME);
+		addLabeledCombo(parent, JptUiValidationPreferenceMessages.VIRTUAL_MAP_KEY_ATTRIBUTE_OVERRIDE_COLUMN_TABLE_NOT_VALID, 							JpaValidationMessages.VIRTUAL_MAP_KEY_ATTRIBUTE_OVERRIDE_COLUMN_TABLE_NOT_VALID);
+		addLabeledCombo(parent, JptUiValidationPreferenceMessages.VIRTUAL_ASSOCIATION_OVERRIDE_JOIN_COLUMN_UNRESOLVED_NAME,                   							JpaValidationMessages.VIRTUAL_ASSOCIATION_OVERRIDE_JOIN_COLUMN_UNRESOLVED_NAME);
+		addLabeledCombo(parent, JptUiValidationPreferenceMessages.VIRTUAL_ASSOCIATION_OVERRIDE_JOIN_COLUMN_UNRESOLVED_REFERENCED_COLUMN_NAME, 							JpaValidationMessages.VIRTUAL_ASSOCIATION_OVERRIDE_JOIN_COLUMN_UNRESOLVED_REFERENCED_COLUMN_NAME);
+		addLabeledCombo(parent, JptUiValidationPreferenceMessages.VIRTUAL_ASSOCIATION_OVERRIDE_JOIN_COLUMN_TABLE_NOT_VALID, 											JpaValidationMessages.VIRTUAL_ASSOCIATION_OVERRIDE_JOIN_COLUMN_TABLE_NOT_VALID);
+		addLabeledCombo(parent, JptUiValidationPreferenceMessages.VIRTUAL_ASSOCIATION_OVERRIDE_JOIN_COLUMN_NAME_MUST_BE_SPECIFIED_MULTIPLE_JOIN_COLUMNS, 				JpaValidationMessages.VIRTUAL_ASSOCIATION_OVERRIDE_JOIN_COLUMN_NAME_MUST_BE_SPECIFIED_MULTIPLE_JOIN_COLUMNS);
+		addLabeledCombo(parent, JptUiValidationPreferenceMessages.VIRTUAL_ASSOCIATION_OVERRIDE_JOIN_COLUMN_REFERENCED_COLUMN_NAME_MUST_BE_SPECIFIED_MULTIPLE_JOIN_COLUMNS, JpaValidationMessages.VIRTUAL_ASSOCIATION_OVERRIDE_JOIN_COLUMN_REFERENCED_COLUMN_NAME_MUST_BE_SPECIFIED_MULTIPLE_JOIN_COLUMNS);
+
+		
+		parent = addSubExpandableSection(parent, JptUiValidationPreferenceMessages.IMPLIED_ATTRIBUTE_LEVEL_CATEGORY);
+
+		addLabeledCombo(parent, JptUiValidationPreferenceMessages.VIRTUAL_ATTRIBUTE_ATTRIBUTE_OVERRIDE_COLUMN_TABLE_NOT_VALID,                  						JpaValidationMessages.VIRTUAL_ATTRIBUTE_ATTRIBUTE_OVERRIDE_COLUMN_TABLE_NOT_VALID);
+		addLabeledCombo(parent, JptUiValidationPreferenceMessages.VIRTUAL_ATTRIBUTE_ATTRIBUTE_OVERRIDE_COLUMN_UNRESOLVED_NAME,                                  		JpaValidationMessages.VIRTUAL_ATTRIBUTE_ATTRIBUTE_OVERRIDE_COLUMN_UNRESOLVED_NAME);
+		addLabeledCombo(parent, JptUiValidationPreferenceMessages.VIRTUAL_ATTRIBUTE_MAP_KEY_ATTRIBUTE_OVERRIDE_COLUMN_TABLE_NOT_VALID, 									JpaValidationMessages.VIRTUAL_ATTRIBUTE_MAP_KEY_ATTRIBUTE_OVERRIDE_COLUMN_TABLE_NOT_VALID);
+		addLabeledCombo(parent, JptUiValidationPreferenceMessages.VIRTUAL_ATTRIBUTE_ASSOCIATION_OVERRIDE_JOIN_COLUMN_TABLE_NOT_VALID,                   				JpaValidationMessages.VIRTUAL_ATTRIBUTE_ASSOCIATION_OVERRIDE_JOIN_COLUMN_TABLE_NOT_VALID);
+		addLabeledCombo(parent, JptUiValidationPreferenceMessages.VIRTUAL_ATTRIBUTE_ASSOCIATION_OVERRIDE_JOIN_COLUMN_UNRESOLVED_NAME, 									JpaValidationMessages.VIRTUAL_ATTRIBUTE_ASSOCIATION_OVERRIDE_JOIN_COLUMN_UNRESOLVED_NAME);
+		addLabeledCombo(parent, JptUiValidationPreferenceMessages.VIRTUAL_ATTRIBUTE_ASSOCIATION_OVERRIDE_JOIN_COLUMN_REFERENCED_COLUMN_UNRESOLVED_NAME, 				JpaValidationMessages.VIRTUAL_ATTRIBUTE_ASSOCIATION_OVERRIDE_JOIN_COLUMN_REFERENCED_COLUMN_UNRESOLVED_NAME);
+		addLabeledCombo(parent, JptUiValidationPreferenceMessages.VIRTUAL_ATTRIBUTE_ASSOCIATION_OVERRIDE_JOIN_COLUMN_NAME_MUST_BE_SPECIFIED_MULTIPLE_JOIN_COLUMNS, 		JpaValidationMessages.VIRTUAL_ATTRIBUTE_ASSOCIATION_OVERRIDE_JOIN_COLUMN_NAME_MUST_BE_SPECIFIED_MULTIPLE_JOIN_COLUMNS);
+		addLabeledCombo(parent, JptUiValidationPreferenceMessages.VIRTUAL_ATTRIBUTE_ASSOCIATION_OVERRIDE_JOIN_COLUMN_REFERENCED_COLUMN_NAME_MUST_BE_SPECIFIED_MULTIPLE_JOIN_COLUMNS, JpaValidationMessages.VIRTUAL_ATTRIBUTE_ASSOCIATION_OVERRIDE_JOIN_COLUMN_REFERENCED_COLUMN_NAME_MUST_BE_SPECIFIED_MULTIPLE_JOIN_COLUMNS);
+	}
+
+	private void addInheritanceStrategyCategory(Composite parent) {
+
+		parent = addExpandableSection(parent, JptUiValidationPreferenceMessages.INHERITANCE_CATEGORY);
+
+		addLabeledCombo(
+			parent, JptUiValidationPreferenceMessages.DISCRIMINATOR_COLUMN_UNRESOLVED_NAME,
+			JpaValidationMessages.DISCRIMINATOR_COLUMN_UNRESOLVED_NAME);
+		addLabeledCombo(
+			parent, JptUiValidationPreferenceMessages.ENTITY_TABLE_PER_CLASS_NOT_SUPPORTED_ON_PLATFORM,
+			JpaValidationMessages.ENTITY_TABLE_PER_CLASS_NOT_SUPPORTED_ON_PLATFORM);
+		addLabeledCombo(
+			parent, JptUiValidationPreferenceMessages.ENTITY_TABLE_PER_CLASS_NOT_PORTABLE_ON_PLATFORM,
+			JpaValidationMessages.ENTITY_TABLE_PER_CLASS_NOT_PORTABLE_ON_PLATFORM);
+		addLabeledCombo(
+			parent, JptUiValidationPreferenceMessages.ENTITY_SINGLE_TABLE_DESCENDANT_DEFINES_TABLE,
+			JpaValidationMessages.ENTITY_SINGLE_TABLE_DESCENDANT_DEFINES_TABLE);
+		addLabeledCombo(
+			parent, JptUiValidationPreferenceMessages.ENTITY_ABSTRACT_TABLE_PER_CLASS_DEFINES_TABLE,
+			JpaValidationMessages.ENTITY_ABSTRACT_TABLE_PER_CLASS_DEFINES_TABLE);
+		addLabeledCombo(
+			parent, JptUiValidationPreferenceMessages.ENTITY_ABSTRACT_DISCRIMINATOR_VALUE_DEFINED,
+			JpaValidationMessages.ENTITY_ABSTRACT_DISCRIMINATOR_VALUE_DEFINED);
+		addLabeledCombo(
+			parent, JptUiValidationPreferenceMessages.ENTITY_TABLE_PER_CLASS_DISCRIMINATOR_VALUE_DEFINED,
+			JpaValidationMessages.ENTITY_TABLE_PER_CLASS_DISCRIMINATOR_VALUE_DEFINED);
+		addLabeledCombo(
+			parent, JptUiValidationPreferenceMessages.ENTITY_NON_ROOT_DISCRIMINATOR_COLUMN_DEFINED,
+			JpaValidationMessages.ENTITY_NON_ROOT_DISCRIMINATOR_COLUMN_DEFINED);
+		addLabeledCombo(
+			parent, JptUiValidationPreferenceMessages.ENTITY_TABLE_PER_CLASS_DISCRIMINATOR_COLUMN_DEFINED,
+			JpaValidationMessages.ENTITY_TABLE_PER_CLASS_DISCRIMINATOR_COLUMN_DEFINED);
+	}
+
+	private void addQueriesGeneratorsCategory(Composite parent) {
+
+		parent = addExpandableSection(parent, JptUiValidationPreferenceMessages.QUERIES_GENERATORS_CATEGORY);
+
+		addLabeledCombo(parent, JptUiValidationPreferenceMessages.GENERATOR_DUPLICATE_NAME,             JpaValidationMessages.GENERATOR_DUPLICATE_NAME);
+		addLabeledCombo(parent, JptUiValidationPreferenceMessages.ID_MAPPING_UNRESOLVED_GENERATOR_NAME, JpaValidationMessages.ID_MAPPING_UNRESOLVED_GENERATOR_NAME);
+		addLabeledCombo(parent, JptUiValidationPreferenceMessages.GENERATED_VALUE_UNRESOLVED_GENERATOR, JpaValidationMessages.GENERATED_VALUE_UNRESOLVED_GENERATOR);
+		addLabeledCombo(parent, JptUiValidationPreferenceMessages.QUERY_DUPLICATE_NAME,                 JpaValidationMessages.QUERY_DUPLICATE_NAME);
+	}
+	
+	private Composite addExpandableSection(Composite parent, String text) {
+		return addExpandableSection(parent, text, new GridData(GridData.FILL, GridData.FILL, true, false));
+	}
+	
+	private Composite addSubExpandableSection(Composite parent, String text) {
+		return addExpandableSection(parent, text, new GridData(GridData.FILL, GridData.FILL, true, false, 2, 1));
+	}
+
+	/**
+	 * Creates and adds to the given <code>Composite</code> an expandable pane
+	 * where its content can be shown or hidden depending on the expansion state.
+	 *
+	 * @param parent The parent container
+	 * @param text The title of the expandable section
+	 * @return The container to which widgets can be added, which is a child of
+	 * the expandable pane
+	 */
+	private Composite addExpandableSection(Composite parent, String text, GridData gridData) {
+		ExpandableComposite expandablePane = new ExpandableComposite(
+			parent,
+			SWT.NONE,
+			ExpandableComposite.TWISTIE | ExpandableComposite.CLIENT_INDENT
+		);
+
+		expandablePane.setText(text);
+		expandablePane.setExpanded(false);
+		expandablePane.setFont(JFaceResources.getFontRegistry().getBold(JFaceResources.DIALOG_FONT));
+		expandablePane.setLayoutData(gridData);
+		expandablePane.addExpansionListener(buildExpansionListener());
+
+		this.scrollable.adaptChild(expandablePane);
+		this.expandablePanes.add(expandablePane);
+
+		parent = new Composite(expandablePane, SWT.NONE);
+		parent.setLayout(new GridLayout(2, false));
+		expandablePane.setClient(parent);
+
+		return parent;
+	}
+
+	/**
+	 * Creates and adds to the given parent a labeled combo where the possible
+	 * choices are "Ignore", "Error" and "Warning".
+	 *
+	 * @param parent The parent to which the widgets are added
+	 * @param labelText The text labelling the combo
+	 * @param preferenceKey The key used to retrieve and to store the value
+	 * associated with the validation problem
+	 */
+	private void addLabeledCombo(Composite parent, String labelText, String preferenceKey) {
+		Label label = new Label(parent, SWT.NONE);
+		label.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+		label.setText(labelText);
+
+		Combo combo = new Combo(parent, SWT.READ_ONLY);
+		combo.setItems(this.severityDisplayStrings);
+		combo.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL));
+		combo.setData(PREFERENCE_KEY, preferenceKey);
+		combo.select(convertPreferenceKeyToComboIndex(preferenceKey));
+		combo.addSelectionListener(buildComboSelectionListener());
+
+		this.scrollable.adaptChild(combo);
+		this.combos.add(combo);
+	}
+
+	private SelectionListener buildComboSelectionListener() {
+		return new SelectionAdapter() {
+			@Override
+			public void widgetSelected(SelectionEvent e) {
+				Combo combo = (Combo) e.widget;
+				String preferenceKey = (String) combo.getData(PREFERENCE_KEY);
+				String value = convertToPreferenceValue(combo.getSelectionIndex());
+				JpaProblemSeveritiesPage.this.severityLevels.put(preferenceKey, value);
+			}
+		};
+	}
+
+	private ExpansionAdapter buildExpansionListener() {
+		return new ExpansionAdapter() {
+			@Override
+			public void expansionStateChanged(ExpansionEvent e) {
+				JpaProblemSeveritiesPage.this.expansionStateChanged();
+			}
+		};
+	}
+
+	protected String[] buildSeverityDisplayStrings() {
+		String[] severities = new String[4];
+		severities[ERROR_INDEX]   = JptUiMessages.JpaProblemSeveritiesPage_Error;
+		severities[WARNING_INDEX] = JptUiMessages.JpaProblemSeveritiesPage_Warning;
+		severities[INFO_INDEX]    = JptUiMessages.JpaProblemSeveritiesPage_Info;
+		severities[IGNORE_INDEX]  = JptUiMessages.JpaProblemSeveritiesPage_Ignore;
+		return severities;
+	}
+
+	protected int convertPreferenceKeyToComboIndex(String preferenceKey) {
+		return convertPreferenceValueToComboIndex(getPreferenceValue(preferenceKey));
+	}
+
+	protected String getPreferenceValue(String preferenceKey) {
+		String preference = null;
+		if (isProjectPreferencePage() && hasProjectSpecificOptions(getProject())) { //useProjectSettings() won't work since the page is being built
+			preference = JpaValidationPreferences.getProjectLevelProblemPreference(getProject(), preferenceKey);
+		}
+		else {
+			//don't get the workspace preference when the project has overridden workspace preferences
+			preference = JpaValidationPreferences.getWorkspaceLevelProblemPreference(preferenceKey);
+		}
+		if (preference == null) {
+			preference = getDefaultPreferenceValue(preferenceKey);
+		}
+		return preference;
+	}
+
+	/**
+	 * Return the default severity or ERROR if no default exists.
+	 */
+	protected String getDefaultPreferenceValue(String preferenceKey) {
+		String preference = this.defaultSeverities.get(preferenceKey);
+		return preference == null ? JpaValidationPreferences.ERROR : preference;
+	}
+	
+	protected int convertPreferenceValueToComboIndex(String preferenceValue) {
+		if (JpaValidationPreferences.ERROR.equals(preferenceValue)) {
+			return ERROR_INDEX;
+		}
+		if (JpaValidationPreferences.WARNING.equals(preferenceValue)) {
+			return WARNING_INDEX;
+		}
+		if (JpaValidationPreferences.INFO.equals(preferenceValue)) {
+			return INFO_INDEX;
+		}
+		if (JpaValidationPreferences.IGNORE.equals(preferenceValue)) {
+			return IGNORE_INDEX;
+		}
+		throw new IllegalStateException();
+	}
+
+	protected String convertToPreferenceValue(int selectionIndex) {
+		switch (selectionIndex) {
+			case ERROR_INDEX:   return JpaValidationPreferences.ERROR;
+			case WARNING_INDEX: return JpaValidationPreferences.WARNING;
+			case INFO_INDEX:    return JpaValidationPreferences.INFO;
+			case IGNORE_INDEX:  return JpaValidationPreferences.IGNORE;
+			default:            return null;
+		}
+	}
+
+	/**
+	 * Revalidates the layout in order to show or hide the vertical scroll bar
+	 * after a section was either expanded or collapsed. This unfortunately does
+	 * not happen automatically.
+	 */
+	protected void expansionStateChanged() {
+		this.scrollable.reflow(true);
+	}
+
+	@Override
+	protected String getPreferencePageID() {
+		return JPT_PREFERENCES_PROBLEM_SEVERITIES_ID;
+	}
+
+	@Override
+	protected String getPropertyPageID() {
+		return JPT_PROPERTY_PAGES_PROBLEM_SEVERITIES_ID;
+	}
+
+	protected IEclipsePreferences getProjectPreferences(IProject project) {
+		return JptCorePlugin.getProjectPreferences(project);
+	}
+
+	@Override
+	protected boolean hasProjectSpecificOptions(IProject project) {
+		IEclipsePreferences projectPreferences = getProjectPreferences(project);
+		return projectPreferences.getBoolean(JpaValidationPreferences.WORKSPACE_PREFERENCES_OVERRIDEN, false);
+	}
+
+	@Override
+	protected void performDefaults() {
+		super.performDefaults();
+		//this call would be redundant on project preference page - bug in the JDT superclass
+		if (!isProjectPreferencePage()) {
+			revertToDefault();
+		}
+	}
+	
+	@Override
+	protected void enableProjectSpecificSettings(boolean useProjectSpecificSettings) {
+		super.enableProjectSpecificSettings(useProjectSpecificSettings);
+		if (getDefaultsButton() == null) {
+			//@Hack("If the defaults button is null the control is currently being built," +
+			//      "otherwise the 'enable project specific settings' checkbox is being pressed")
+			return;
+		}
+		
+		this.hasProjectSpecificPreferences = Boolean.valueOf(useProjectSpecificSettings);
+		
+		//set all specified workspace preferences in the project preferences
+		if (useProjectSpecificSettings){
+			this.overrideWorkspacePreferences();
+		}
+		else {//remove any project specific settings if set to false
+			this.revertToDefault();
+		}
+	}
+
+	@Override
+	protected void noDefaultAndApplyButton() {
+		throw new IllegalStateException("Don't call this, see enableProjectSpecificSettings for the hack that looks for the defaultsButton being null"); //$NON-NLS-1$
+	}
+
+	protected void revertToDefault() {
+		for (Combo combo : this.combos) {
+			String preferenceKey = (String) combo.getData(PREFERENCE_KEY);
+			String preference = JpaValidationPreferences.getWorkspaceLevelProblemPreference(preferenceKey);
+			if (preference == null) {
+				preference = getDefaultPreferenceValue(preferenceKey);
+			}
+			combo.select(convertPreferenceValueToComboIndex(preference));
+			//UI will show the defaults from the workspace, but set all preferences 
+			//to null so they will be deleted from project preferences
+			this.severityLevels.put(preferenceKey, null);
+		}
+	}
+
+	protected void overrideWorkspacePreferences() {
+		for (Combo combo : this.combos) {
+			String preferenceKey = (String) combo.getData(PREFERENCE_KEY);
+			String workspacePreference = JpaValidationPreferences.getWorkspaceLevelProblemPreference(preferenceKey);
+			String defaultPreference = getDefaultPreferenceValue(preferenceKey);
+			if (workspacePreference != null && !workspacePreference.equals(defaultPreference)) {
+				combo.select(convertPreferenceValueToComboIndex(workspacePreference));
+				//silly combo doesn't fire a selection event, so we can't expect our listener to set this
+				this.severityLevels.put(preferenceKey, workspacePreference);
+			}
+			else {
+				combo.select(convertPreferenceValueToComboIndex(defaultPreference));
+			}
+		}
+	}
+	
+	// ********** OK/Revert/Apply behavior **********
+
+	@Override
+	public boolean performOk() {
+		super.performOk();
+		if (this.hasProjectSpecificPreferences != null) {
+			IEclipsePreferences projectPreferences = getProjectPreferences(getProject());
+			if (this.hasProjectSpecificPreferences.booleanValue()) {
+				projectPreferences.putBoolean(JpaValidationPreferences.WORKSPACE_PREFERENCES_OVERRIDEN, true);
+			}
+			else {
+				projectPreferences.remove(JpaValidationPreferences.WORKSPACE_PREFERENCES_OVERRIDEN);
+			}
+			JpaValidationPreferences.flush(projectPreferences);
+		}
+		for (String validationPreferenceKey : this.severityLevels.keySet()) {
+			updatePreference(validationPreferenceKey, this.severityLevels.get(validationPreferenceKey));
+		}
+		try {
+			// true=fork; false=uncancellable
+			this.buildOkProgressMonitorDialog().run(true, false, this.buildOkRunnableWithProgress());
+		}
+		catch (InterruptedException ex) {
+			return false;
+		} 
+		catch (InvocationTargetException ex) {
+			throw new RuntimeException(ex.getTargetException());
+		}
+
+		return true;
+	}
+
+	protected void updatePreference(String preferenceKey, String value) {
+		if (isProjectPreferencePage()) {
+			JpaValidationPreferences.setProjectLevelProblemPreference(getProject(), preferenceKey, value);
+		}
+		else {
+			JpaValidationPreferences.setWorkspaceLevelProblemPreference(preferenceKey, value);
+		}
+	}
+
+	private IRunnableContext buildOkProgressMonitorDialog() {
+		return new ProgressMonitorDialog(this.getShell());
+	}
+
+	private IRunnableWithProgress buildOkRunnableWithProgress() {
+		return new IRunnableWithProgress() {
+			public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
+				IWorkspace ws = ResourcesPlugin.getWorkspace();
+				try {
+					// the build we execute in #performOk_() locks the workspace root,
+					// so we need to use the workspace root as our scheduling rule here
+					ws.run(
+							JpaProblemSeveritiesPage.this.buildOkWorkspaceRunnable(),
+							ws.getRoot(),
+							IWorkspace.AVOID_UPDATE,
+							monitor
+					);
+				}
+				catch (CoreException ex) {
+					throw new InvocationTargetException(ex);
+				}
+			}
+		};
+	}
+
+	IWorkspaceRunnable buildOkWorkspaceRunnable() {
+		return new IWorkspaceRunnable() {
+			public void run(IProgressMonitor monitor) throws CoreException {
+				JpaProblemSeveritiesPage.this.performOk_(monitor);
+			}
+		};
+	}
+
+	void performOk_(IProgressMonitor monitor) throws CoreException {
+		//if project is null this is a workspace preference page
+		if (this.getProject()==null) {
+			JavaPlugin.getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, monitor);
+		}
+		else this.getProject().build(IncrementalProjectBuilder.FULL_BUILD, monitor);
+	}
+
+	@Override
+	public void dispose() {
+		storeSectionExpansionStates(getDialogPreferences());
+		super.dispose();
+	}
+
+	protected IDialogSettings getDialogPreferences() {
+		IDialogSettings rootSettings = JptUiPlugin.instance().getDialogSettings();
+		IDialogSettings settings = rootSettings.getSection(SETTINGS_SECTION_NAME);
+		if (settings == null) {
+			settings = rootSettings.addNewSection(SETTINGS_SECTION_NAME);
+		}
+		return settings;
+	}
+
+	protected void storeSectionExpansionStates(IDialogSettings settings) {
+		for (int index = this.expandablePanes.size(); --index >= 0; ) {
+			ExpandableComposite expandablePane = this.expandablePanes.get(index);
+			settings.put(SETTINGS_EXPANDED + index, expandablePane.isExpanded());
+		}
+	}
+
+}
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/properties/DataModelPropertyPage.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/properties/DataModelPropertyPage.java
new file mode 100644
index 0000000..cc0b64d
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/properties/DataModelPropertyPage.java
@@ -0,0 +1,309 @@
+/*******************************************************************************
+ *  Copyright (c) 2007 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.ui.internal.properties;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.jface.dialogs.IMessageProvider;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Listener;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.dialogs.PropertyPage;
+import org.eclipse.wst.common.frameworks.datamodel.DataModelEvent;
+import org.eclipse.wst.common.frameworks.datamodel.IDataModel;
+import org.eclipse.wst.common.frameworks.datamodel.IDataModelListener;
+import org.eclipse.wst.common.frameworks.internal.datamodel.ui.DataModelSynchHelper;
+import org.eclipse.wst.common.frameworks.internal.ui.ValidationStatus;
+
+public abstract class DataModelPropertyPage 
+	extends PropertyPage
+	implements Listener, IDataModelListener
+{
+	protected IDataModel model;
+	
+	private ValidationStatus status = new ValidationStatus();
+	private Map validationMap;
+	private String[] validationPropertyNames;
+	private boolean isValidating = false;
+	
+	protected DataModelSynchHelper synchHelper;
+	
+	private String infopopID;
+	
+	
+	protected DataModelPropertyPage(IDataModel model) {
+		super();
+		this.model = model;
+		model.addListener(this);
+		synchHelper = initializeSynchHelper(model);
+	}
+	
+
+	/**
+	 * @return
+	 */
+	public DataModelSynchHelper initializeSynchHelper(IDataModel dm) {
+		return new DataModelSynchHelper(dm);
+	}
+
+	
+	@Override
+	protected Control createContents(Composite parent) {
+		Composite top = createTopLevelComposite(parent);
+		setupInfopop(top);
+		setDefaults();
+		addListeners();
+		initializeValidationProperties();
+		return top;
+	}
+	
+	private void initializeValidationProperties() {
+		validationPropertyNames = getValidationPropertyNames();
+		if (validationPropertyNames == null || validationPropertyNames.length == 0)
+			validationMap = Collections.EMPTY_MAP;
+		else {
+			validationMap = new HashMap(validationPropertyNames.length);
+			for (int i = 0; i < validationPropertyNames.length; i++)
+				validationMap.put(validationPropertyNames[i], new Integer(i));
+		}
+	}
+
+	/**
+	 * Subclass should return the model property names that need to be validated on this page in the
+	 * order that they should present their messages.
+	 * 
+	 * @return
+	 */
+	protected abstract String[] getValidationPropertyNames();
+
+	/**
+	 * Return the top level Composite for this page.
+	 */
+	protected abstract Composite createTopLevelComposite(Composite parent);
+
+	/**
+	 * Set up info pop hooks if set.
+	 */
+	protected void setupInfopop(Control parent) {
+		if (getInfopopID() != null)
+			PlatformUI.getWorkbench().getHelpSystem().setHelp(parent, getInfopopID());
+	}
+
+	/**
+	 * Setup the default values for this page. Subclasses should override to provide appropriate
+	 * defaults.
+	 */
+	protected void setDefaults() {
+		restoreDefaultSettings();
+	}
+
+	/**
+	 * Subclasses should implement this method if they have default settings that have been stored
+	 * and need to be restored.
+	 * 
+	 * @see storeDefaultSettings()
+	 */
+	protected void restoreDefaultSettings() {
+	}
+
+	/**
+	 * Add Listeners to controls at this point to avoid unnecessary events. Subclasses should
+	 * override to add listeners to its controls.
+	 */
+	protected void addListeners() {
+	}
+
+	/**
+	 * Exiting the page. Subclasses may extend.
+	 */
+	protected void exit() {
+	}
+
+	protected boolean getStatus(Integer key) {
+		return status.hasError(key);
+	}
+
+	/**
+	 * Sent when an event that the receiver has registered for occurs. If a subclass overrides this
+	 * method, it must call super.
+	 * 
+	 * @param event
+	 *            the event which occurred
+	 */
+	public void handleEvent(org.eclipse.swt.widgets.Event event) {
+	}
+
+	/**
+	 * Set the error message for this page based on the last error in the ValidationStatus.
+	 */
+	protected void setErrorMessage() {
+		String error = status.getLastErrMsg();
+		if (error == null) {
+			if (getErrorMessage() != null)
+				setErrorMessage((String) null);
+			String warning = status.getLastWarningMsg();
+			if (warning == null) {
+				if (getMessage() != null && getMessageType() == IMessageProvider.WARNING)
+					setMessage(null, IMessageProvider.WARNING);
+				else {
+					String info = status.getLastInfoMsg();
+					if (info == null) {
+						if (getMessage() != null && getMessageType() == IMessageProvider.INFORMATION)
+							setMessage(null, IMessageProvider.INFORMATION);
+					} else if (!info.equals(getMessage())) {
+						setMessage(info, IMessageProvider.INFORMATION);
+					}
+				}
+			} else if (!warning.equals(getMessage()))
+				setMessage(warning, IMessageProvider.WARNING);
+		} else if (!error.equals(getErrorMessage()))
+							setErrorMessage(error);
+						}
+
+	protected void setErrorStatus(Integer key, String errorMessage) {
+		status.setErrorStatus(key, errorMessage);
+	}
+
+	protected void setWarningStatus(Integer key, String warningMessage) {
+		status.setWarningStatus(key, warningMessage);
+	}
+	
+	protected void setInfoStatus(Integer key, String infoMessage) {
+		status.setInfoStatus(key, infoMessage);
+	}
+
+	protected void setOKStatus(Integer key) {
+		status.setOKStatus(key);
+	}
+
+	/**
+	 * This should be called by the Wizard just prior to running the performFinish operation.
+	 * Subclasses should override to store their default settings.
+	 */
+	public void storeDefaultSettings() {
+	}
+
+	/**
+	 * The page is now being validated. At this time, each control is validated and then the
+	 * controls are updated based on the results in the ValidationStatus which was updated during
+	 * <code>validateControls()</code>. Finally, it will display the last error message and it
+	 * will set the page complete. Subclasses will not typically override this method.
+	 */
+	protected void validatePage() {
+		if (!isValidating) {
+			isValidating = true;
+			try {
+				validateControlsBase();
+				updateControls();
+				setErrorMessage();
+				setValid(status.getLastErrMsg() == null);
+			} 
+			finally {
+				isValidating = false;
+			}
+		}
+	}
+
+	/**
+	 * Validate individual controls. Use validation keys to keep track of errors.
+	 * 
+	 * @see setOKStatus(Integer) and setErrorMessage(Integer, String)
+	 */
+	protected final String validateControlsBase() {
+		if (!validationMap.isEmpty()) {
+			String propName;
+			for (int i = 0; i < validationPropertyNames.length; i++) {
+				propName = validationPropertyNames[i];
+				Integer valKey = (Integer) validationMap.get(propName);
+				if (valKey != null)
+					validateProperty(propName, valKey);
+				if (!getStatus(valKey))
+					return propName;
+			}
+		}
+		return null;
+	}
+
+	/**
+	 * @param propertyName
+	 * @param validationkey
+	 */
+	private void validateProperty(String propertyName, Integer validationKey) {
+		setOKStatus(validationKey);
+		IStatus status1 = model.validateProperty(propertyName);
+		if (!status1.isOK()) {
+			String message = status1.isMultiStatus() ? status1.getChildren()[0].getMessage() : status1.getMessage();
+			switch (status1.getSeverity()) {
+				case IStatus.ERROR :
+					setErrorStatus(validationKey, message);
+					break;
+				case IStatus.WARNING :
+					setWarningStatus(validationKey, message);
+					break;
+				case IStatus.INFO :
+					setInfoStatus(validationKey, message);
+					break;
+			}
+		}
+	}
+
+	/**
+	 * Update the enablement of controls after validation. Sublcasses should check the status of
+	 * validation keys to determine enablement.
+	 */
+	protected void updateControls() {
+	}
+	
+	
+	/*
+	 * If a property changes that we want to validate, force validation on this page.
+	 * 
+	 * @see org.eclipse.wst.common.frameworks.internal.operation.WTPOperationDataModelListener#propertyChanged(java.lang.String,
+	 *      java.lang.Object, java.lang.Object)
+	 */
+	public void propertyChanged(DataModelEvent event) {
+		String propertyName = event.getPropertyName();
+		if (validationPropertyNames != null && (event.getFlag() == DataModelEvent.VALUE_CHG || (!isValid() && event.getFlag() == DataModelEvent.VALID_VALUES_CHG))) {
+			for (int i = 0; i < validationPropertyNames.length; i++) {
+				if (validationPropertyNames[i].equals(propertyName)) {
+					validatePage();
+					break;
+				}
+			}
+		}
+	}
+
+	/**
+	 * @return Returns the model.
+	 */
+	protected IDataModel getDataModel() {
+		return model;
+	}
+
+	public void dispose() {
+		super.dispose();
+		if (synchHelper != null) {
+			synchHelper.dispose();
+			synchHelper = null;
+		}
+	}
+
+	protected String getInfopopID() {
+		return infopopID;
+	}
+
+	public void setInfopopID(String infopopID) {
+		this.infopopID = infopopID;
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/properties/JpaProjectPropertiesPage.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/properties/JpaProjectPropertiesPage.java
new file mode 100644
index 0000000..6cc64a8
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/properties/JpaProjectPropertiesPage.java
@@ -0,0 +1,1827 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 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.ui.internal.properties;
+
+import static org.eclipse.jst.common.project.facet.ui.libprov.LibraryProviderFrameworkUi.createInstallLibraryPanel;
+import java.lang.reflect.InvocationTargetException;
+import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IWorkspace;
+import org.eclipse.core.resources.IWorkspaceRunnable;
+import org.eclipse.core.resources.IncrementalProjectBuilder;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.preferences.IEclipsePreferences;
+import org.eclipse.core.runtime.preferences.IEclipsePreferences.IPreferenceChangeListener;
+import org.eclipse.core.runtime.preferences.IEclipsePreferences.PreferenceChangeEvent;
+import org.eclipse.jdt.core.ElementChangedEvent;
+import org.eclipse.jdt.core.IElementChangedListener;
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.IJavaElementDelta;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.dialogs.ProgressMonitorDialog;
+import org.eclipse.jface.operation.IRunnableContext;
+import org.eclipse.jface.operation.IRunnableWithProgress;
+import org.eclipse.jpt.core.JpaDataSource;
+import org.eclipse.jpt.core.JpaProject;
+import org.eclipse.jpt.core.JpaProjectManager;
+import org.eclipse.jpt.core.JptCorePlugin;
+import org.eclipse.jpt.core.internal.JpaPlatformRegistry;
+import org.eclipse.jpt.core.internal.JptCoreMessages;
+import org.eclipse.jpt.core.internal.facet.JpaLibraryProviderConstants;
+import org.eclipse.jpt.core.jpa2.JpaProject2_0;
+import org.eclipse.jpt.db.Catalog;
+import org.eclipse.jpt.db.ConnectionAdapter;
+import org.eclipse.jpt.db.ConnectionListener;
+import org.eclipse.jpt.db.ConnectionProfile;
+import org.eclipse.jpt.db.ConnectionProfileFactory;
+import org.eclipse.jpt.db.ConnectionProfileListener;
+import org.eclipse.jpt.db.Database;
+import org.eclipse.jpt.db.JptDbPlugin;
+import org.eclipse.jpt.db.SchemaContainer;
+import org.eclipse.jpt.db.ui.internal.DTPUiTools;
+import org.eclipse.jpt.ui.internal.JpaHelpContextIds;
+import org.eclipse.jpt.ui.internal.JptUiMessages;
+import org.eclipse.jpt.ui.internal.jpa2.Jpa2_0ProjectFlagModel;
+import org.eclipse.jpt.ui.internal.utility.swt.SWTTools;
+import org.eclipse.jpt.utility.internal.ArrayTools;
+import org.eclipse.jpt.utility.internal.BitTools;
+import org.eclipse.jpt.utility.internal.CollectionTools;
+import org.eclipse.jpt.utility.internal.NotBooleanTransformer;
+import org.eclipse.jpt.utility.internal.StringConverter;
+import org.eclipse.jpt.utility.internal.StringTools;
+import org.eclipse.jpt.utility.internal.iterables.EmptyIterable;
+import org.eclipse.jpt.utility.internal.model.value.AbstractCollectionValueModel;
+import org.eclipse.jpt.utility.internal.model.value.AspectCollectionValueModelAdapter;
+import org.eclipse.jpt.utility.internal.model.value.AspectPropertyValueModelAdapter;
+import org.eclipse.jpt.utility.internal.model.value.BufferedWritablePropertyValueModel;
+import org.eclipse.jpt.utility.internal.model.value.CachingTransformationPropertyValueModel;
+import org.eclipse.jpt.utility.internal.model.value.CompositeCollectionValueModel;
+import org.eclipse.jpt.utility.internal.model.value.CompositePropertyValueModel;
+import org.eclipse.jpt.utility.internal.model.value.ExtendedListValueModelWrapper;
+import org.eclipse.jpt.utility.internal.model.value.PropertyAspectAdapter;
+import org.eclipse.jpt.utility.internal.model.value.PropertyCollectionValueModelAdapter;
+import org.eclipse.jpt.utility.internal.model.value.SetCollectionValueModel;
+import org.eclipse.jpt.utility.internal.model.value.SimplePropertyValueModel;
+import org.eclipse.jpt.utility.internal.model.value.SortedListValueModelAdapter;
+import org.eclipse.jpt.utility.internal.model.value.StaticCollectionValueModel;
+import org.eclipse.jpt.utility.internal.model.value.TransformationPropertyValueModel;
+import org.eclipse.jpt.utility.internal.model.value.TransformationWritablePropertyValueModel;
+import org.eclipse.jpt.utility.model.Model;
+import org.eclipse.jpt.utility.model.event.CollectionAddEvent;
+import org.eclipse.jpt.utility.model.event.PropertyChangeEvent;
+import org.eclipse.jpt.utility.model.listener.ChangeListener;
+import org.eclipse.jpt.utility.model.listener.CollectionChangeAdapter;
+import org.eclipse.jpt.utility.model.listener.CollectionChangeListener;
+import org.eclipse.jpt.utility.model.listener.PropertyChangeListener;
+import org.eclipse.jpt.utility.model.listener.SimpleChangeListener;
+import org.eclipse.jpt.utility.model.value.CollectionValueModel;
+import org.eclipse.jpt.utility.model.value.ListValueModel;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.jpt.utility.model.value.WritablePropertyValueModel;
+import org.eclipse.jst.common.project.facet.core.libprov.LibraryInstallDelegate;
+import org.eclipse.jst.common.project.facet.ui.libprov.LibraryFacetPropertyPage;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Group;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Link;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.preferences.IWorkbenchPreferenceContainer;
+import org.eclipse.wst.common.project.facet.core.IFacetedProject;
+import org.eclipse.wst.common.project.facet.core.IProjectFacet;
+import org.eclipse.wst.common.project.facet.core.IProjectFacetVersion;
+import org.eclipse.wst.common.project.facet.core.ProjectFacetsManager;
+import com.ibm.icu.text.Collator;
+
+/**
+ * Way more complicated UI than you would think....
+ */
+public class JpaProjectPropertiesPage
+	extends LibraryFacetPropertyPage 
+{
+	public static final String PROP_ID = "org.eclipse.jpt.ui.jpaProjectPropertiesPage"; //$NON-NLS-1$
+
+	private final WritablePropertyValueModel<IProject> projectModel;
+	private final PropertyValueModel<JpaProject> jpaProjectModel;
+	private final BufferedWritablePropertyValueModel.Trigger trigger;
+
+	private final BufferedWritablePropertyValueModel<String> platformIdModel;
+	private final PropertyChangeListener platformIdListener;
+
+	private final BufferedWritablePropertyValueModel<String> connectionModel;
+	private final PropertyValueModel<ConnectionProfile> connectionProfileModel;
+	private final PropertyValueModel<Boolean> disconnectedModel;
+	private Link connectLink;
+
+	private final BufferedWritablePropertyValueModel<Boolean> userOverrideDefaultCatalogFlagModel;
+	private final BufferedWritablePropertyValueModel<String> userOverrideDefaultCatalogModel;
+	private final WritablePropertyValueModel<String> defaultCatalogModel;
+	private final ListValueModel<String> catalogChoicesModel;
+
+	private final BufferedWritablePropertyValueModel<Boolean> userOverrideDefaultSchemaFlagModel;
+	private final BufferedWritablePropertyValueModel<String> userOverrideDefaultSchemaModel;
+	private final WritablePropertyValueModel<String> defaultSchemaModel;
+	private final ListValueModel<String> schemaChoicesModel;
+
+	private final BufferedWritablePropertyValueModel<Boolean> discoverAnnotatedClassesModel;
+	private final WritablePropertyValueModel<Boolean> listAnnotatedClassesModel;
+
+	private final PropertyValueModel<Boolean> jpa2_0ProjectFlagModel;
+
+	private final BufferedWritablePropertyValueModel<String> metamodelSourceFolderModel;
+	private final ListValueModel<String> javaSourceFolderChoicesModel;
+	private static final String BUILD_PATHS_PROPERTY_PAGE_ID = "org.eclipse.jdt.ui.propertyPages.BuildPathsPropertyPage"; //$NON-NLS-1$
+
+	private final ChangeListener validationListener;
+
+
+	@SuppressWarnings("unchecked")
+	/* private */ static final Comparator<String> STRING_COMPARATOR = Collator.getInstance();
+
+
+	// ************ construction ************
+
+	public JpaProjectPropertiesPage() {
+		super();
+
+		this.projectModel = new SimplePropertyValueModel<IProject>();
+		this.jpaProjectModel = new JpaProjectModel(this.projectModel);
+		this.trigger = new BufferedWritablePropertyValueModel.Trigger();
+
+		this.platformIdModel = this.buildPlatformIdModel();
+		this.platformIdListener = this.buildPlatformIdListener();
+		this.platformIdModel.addPropertyChangeListener(PropertyValueModel.VALUE, this.platformIdListener);
+
+		this.connectionModel = this.buildConnectionModel();
+		this.connectionProfileModel = this.buildConnectionProfileModel();
+		this.disconnectedModel = this.buildDisconnectedModel();
+
+		this.userOverrideDefaultCatalogFlagModel = this.buildUserOverrideDefaultCatalogFlagModel();
+		this.userOverrideDefaultCatalogModel = this.buildUserOverrideDefaultCatalogModel();
+		this.defaultCatalogModel = this.buildDefaultCatalogModel();
+		this.catalogChoicesModel = this.buildCatalogChoicesModel();
+
+		this.userOverrideDefaultSchemaFlagModel = this.buildUserOverrideDefaultSchemaFlagModel();
+		this.userOverrideDefaultSchemaModel = this.buildUserOverrideDefaultSchemaModel();
+		this.defaultSchemaModel = this.buildDefaultSchemaModel();
+		this.schemaChoicesModel = this.buildSchemaChoicesModel();
+
+		this.discoverAnnotatedClassesModel = this.buildDiscoverAnnotatedClassesModel();
+		this.listAnnotatedClassesModel = this.buildListAnnotatedClassesModel();
+
+		this.jpa2_0ProjectFlagModel = this.buildJpa2_0ProjectFlagModel();
+
+		this.metamodelSourceFolderModel = this.buildMetamodelSourceFolderModel();
+		this.javaSourceFolderChoicesModel = this.buildJavaSourceFolderChoicesModel();
+
+		this.validationListener = this.buildValidationListener();
+		this.engageValidationListener();
+	}
+
+	// ***** platform ID model
+	private BufferedWritablePropertyValueModel<String> buildPlatformIdModel() {
+		return new BufferedWritablePropertyValueModel<String>(new PlatformIdModel(this.jpaProjectModel), this.trigger);
+	}
+
+	private PropertyChangeListener buildPlatformIdListener(){
+		return new PropertyChangeListener() {
+			public void propertyChanged(PropertyChangeEvent event) {
+				JpaProjectPropertiesPage.this.platformIdChanged((String) event.getNewValue());
+			}
+		};
+	}
+
+	void platformIdChanged(String newPlatformId) {
+		if ( ! this.getControl().isDisposed()) {
+			// handle null, in the case the jpa facet is changed via the facets page,
+			// the library install delegate is temporarily null
+			if (getLibraryInstallDelegate() != null) {
+				getLibraryInstallDelegate().setEnablementContextVariable(JpaLibraryProviderConstants.EXPR_VAR_JPA_PLATFORM, newPlatformId);
+			}
+		}
+	}
+
+	// ***** connection models
+	private BufferedWritablePropertyValueModel<String> buildConnectionModel() {
+		return new BufferedWritablePropertyValueModel<String>(new ConnectionModel(this.jpaProjectModel), this.trigger);
+	}
+
+	private PropertyValueModel<ConnectionProfile> buildConnectionProfileModel() {
+		return new ConnectionProfileModel(this.connectionModel);
+	}
+
+	private PropertyValueModel<Boolean> buildDisconnectedModel() {
+		return new DisconnectedModel(this.connectionProfileModel);
+	}
+
+	// ***** catalog models
+	private BufferedWritablePropertyValueModel<Boolean> buildUserOverrideDefaultCatalogFlagModel() {
+		return new BufferedWritablePropertyValueModel<Boolean>(new UserOverrideDefaultCatalogFlagModel(this.jpaProjectModel), this.trigger);
+	}
+
+	private BufferedWritablePropertyValueModel<String> buildUserOverrideDefaultCatalogModel() {
+		return new BufferedWritablePropertyValueModel<String>(new UserOverrideDefaultCatalogModel(this.jpaProjectModel), this.trigger);
+	}
+
+	private WritablePropertyValueModel<String> buildDefaultCatalogModel() {
+		return new DefaultModel(
+					this.userOverrideDefaultCatalogFlagModel,
+					this.userOverrideDefaultCatalogModel,
+					this.buildDatabaseDefaultCatalogModel()
+				);
+	}
+
+	private PropertyValueModel<String> buildDatabaseDefaultCatalogModel() {
+		return new DatabaseDefaultCatalogModel(this.connectionProfileModel);
+	}
+
+	/**
+	 * Add the default catalog if it is not on the list from the database
+	 */
+	private ListValueModel<String> buildCatalogChoicesModel() {
+		return new SortedListValueModelAdapter<String>(this.buildUnsortedCatalogChoicesModel(), STRING_COMPARATOR);
+	}
+
+	/**
+	 * Add the default catalog if it is not on the list from the database
+	 */
+	@SuppressWarnings("unchecked")
+	private CollectionValueModel<String> buildUnsortedCatalogChoicesModel() {
+		return new SetCollectionValueModel<String>(
+					new CompositeCollectionValueModel<CollectionValueModel<String>, String>(
+							new PropertyCollectionValueModelAdapter<String>(this.defaultCatalogModel),
+							this.buildDatabaseCatalogChoicesModel()
+					)
+			);
+	}
+
+	private CollectionValueModel<String> buildDatabaseCatalogChoicesModel() {
+		return new DatabaseCatalogChoicesModel(this.connectionProfileModel);
+	}
+
+	// ***** schema models
+	private BufferedWritablePropertyValueModel<Boolean> buildUserOverrideDefaultSchemaFlagModel() {
+		return new BufferedWritablePropertyValueModel<Boolean>(new UserOverrideDefaultSchemaFlagModel(this.jpaProjectModel), this.trigger);
+	}
+
+	private BufferedWritablePropertyValueModel<String> buildUserOverrideDefaultSchemaModel() {
+		return new BufferedWritablePropertyValueModel<String>(new UserOverrideDefaultSchemaModel(this.jpaProjectModel), this.trigger);
+	}
+
+	private WritablePropertyValueModel<String> buildDefaultSchemaModel() {
+		return new DefaultModel(
+					this.userOverrideDefaultSchemaFlagModel,
+					this.userOverrideDefaultSchemaModel,
+					this.buildDatabaseDefaultSchemaModel()
+				);
+	}
+
+	private PropertyValueModel<String> buildDatabaseDefaultSchemaModel() {
+		return new DatabaseDefaultSchemaModel(this.connectionProfileModel, this.defaultCatalogModel);
+	}
+
+	/**
+	 * Add the default catalog if it is not on the list from the database
+	 */
+	private ListValueModel<String> buildSchemaChoicesModel() {
+		return new SortedListValueModelAdapter<String>(this.buildUnsortedSchemaChoicesModel(), STRING_COMPARATOR);
+	}
+
+	@SuppressWarnings("unchecked")
+	private CollectionValueModel<String> buildUnsortedSchemaChoicesModel() {
+		return new SetCollectionValueModel<String>(
+				new CompositeCollectionValueModel<CollectionValueModel<String>, String>(
+						new PropertyCollectionValueModelAdapter<String>(this.defaultSchemaModel),
+						this.buildDatabaseSchemaChoicesModel()
+				)
+			);
+	}
+
+	private CollectionValueModel<String> buildDatabaseSchemaChoicesModel() {
+		return new DatabaseSchemaChoicesModel(this.connectionProfileModel, this.defaultCatalogModel);
+	}
+
+	// ***** discover/list annotated classes models
+	private BufferedWritablePropertyValueModel<Boolean> buildDiscoverAnnotatedClassesModel() {
+		return new BufferedWritablePropertyValueModel<Boolean>(new DiscoverAnnotatedClassesModel(this.jpaProjectModel), this.trigger);
+	}
+
+	/**
+	 * The opposite of the "discover annotated classes" flag.
+	 */
+	private WritablePropertyValueModel<Boolean> buildListAnnotatedClassesModel() {
+		return new TransformationWritablePropertyValueModel<Boolean, Boolean>(this.discoverAnnotatedClassesModel, NotBooleanTransformer.instance());
+	}
+	
+	// ***** JPA 2.0 project flag
+	private PropertyValueModel<Boolean> buildJpa2_0ProjectFlagModel() {
+		return new Jpa2_0ProjectFlagModel<JpaProject>(this.jpaProjectModel);
+	}
+
+	// ***** metamodel models
+	private BufferedWritablePropertyValueModel<String> buildMetamodelSourceFolderModel() {
+		return new BufferedWritablePropertyValueModel<String>(new MetamodelSourceFolderModel(this.jpaProjectModel), this.trigger);
+	}
+
+	private ListValueModel<String> buildJavaSourceFolderChoicesModel() {
+		// by default, ExtendedListValueModelWrapper puts a null at the top of the list
+		return new ExtendedListValueModelWrapper<String>(
+					new SortedListValueModelAdapter<String>(
+						new JavaSourceFolderChoicesModel(this.jpaProjectModel),
+						STRING_COMPARATOR
+					)
+				);
+	}
+
+
+	// ********** convenience methods **********
+
+	private String getConnectionName() {
+		return this.connectionModel.getValue();
+	}
+
+	private ConnectionProfile getConnectionProfile() {
+		return this.connectionProfileModel.getValue();
+	}
+
+	private boolean userOverrideDefaultCatalogFlagIsSet() {
+		return flagIsSet(this.userOverrideDefaultCatalogFlagModel);
+	}
+
+	/* private */ static boolean flagIsSet(PropertyValueModel<Boolean> flagModel) {
+		Boolean flag = flagModel.getValue();
+		return (flag != null) && flag.booleanValue();
+	}
+
+	private String getUserOverrideDefaultCatalog() {
+		return this.userOverrideDefaultCatalogModel.getValue();
+	}
+
+	private boolean userOverrideDefaultSchemaFlagIsSet() {
+		return flagIsSet(this.userOverrideDefaultSchemaFlagModel);
+	}
+
+	private String getUserOverrideDefaultSchema() {
+		return this.userOverrideDefaultSchemaModel.getValue();
+	}
+
+	private IWorkbenchPreferenceContainer getWorkbenchPreferenceContainer() {
+		IWorkbenchPreferenceContainer container= (IWorkbenchPreferenceContainer) getContainer();
+		return container;
+	}
+
+	// ********** LibraryFacetPropertyPage implementation **********
+
+	@Override
+	public IProjectFacetVersion getProjectFacetVersion() {
+		IProjectFacet jpaFacet = ProjectFacetsManager.getProjectFacet(JptCorePlugin.FACET_ID);
+		return this.getFacetedProject().getInstalledVersion(jpaFacet);
+	}
+
+	@Override
+	protected LibraryInstallDelegate createLibraryInstallDelegate(IFacetedProject project, IProjectFacetVersion fv) {
+		Map<String, Object> enablementVariables = new HashMap<String, Object>();
+		enablementVariables.put(JpaLibraryProviderConstants.EXPR_VAR_JPA_PLATFORM, ""); //$NON-NLS-1$
+		return new LibraryInstallDelegate(project, fv, enablementVariables);
+	}
+
+
+	// ********** page **********
+
+	@Override
+	protected Control createPageContents(Composite parent) {
+		this.projectModel.setValue(this.getProject());
+
+		Composite composite = new Composite(parent, SWT.NONE);
+		GridLayout layout = new GridLayout();
+		layout.marginWidth = 0;
+		layout.marginHeight = 0;
+		composite.setLayout(layout);
+
+		this.buildPlatformGroup(composite);
+
+		Control libraryProviderComposite = createInstallLibraryPanel(
+				composite, 
+				this.getLibraryInstallDelegate(), 
+				JptUiMessages.JpaFacetWizardPage_jpaImplementationLabel);
+
+ 		libraryProviderComposite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+		this.buildConnectionGroup(composite);
+		this.buildPersistentClassManagementGroup(composite);
+		this.buildMetamodelGroup(composite);
+
+		Dialog.applyDialogFont(composite);
+		PlatformUI.getWorkbench().getHelpSystem().setHelp(composite, JpaHelpContextIds.PROPERTIES_JAVA_PERSISTENCE);
+
+		this.updateValidation();
+
+		return composite;
+	}
+
+	/**
+	 * Don't allow {@link org.eclipse.jface.preference.PreferencePage#computeSize()}
+	 * to cache the page's size, since the size of the "Library" panel can
+	 * change depending on the user's selection from the drop-down list.
+	 */
+	@Override
+	public Point computeSize() {
+		return this.doComputeSize();
+	}
+
+
+	// ********** platform group **********
+
+	private void buildPlatformGroup(Composite composite) {
+		Group group = new Group(composite, SWT.NONE);
+		group.setText(JptUiMessages.JpaFacetWizardPage_platformLabel);
+		group.setLayout(new GridLayout());
+		group.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+		Combo platformDropDown = this.buildDropDown(group);
+		SWTTools.bind(
+				this.buildPlatformChoicesModel(),
+				this.platformIdModel,
+				platformDropDown,
+				JPA_PLATFORM_LABEL_CONVERTER
+		);
+	}
+
+	/**
+	 * Add the project's JPA platform if it is not on the list of valid
+	 * platforms.
+	 * <p>
+	 * This is probably only useful if the project is corrupted
+	 * and has a platform that exists in the registry but is not on the
+	 * list of valid platforms for the project's JPA facet version.
+	 * Because, if the project's JPA platform is completely invalid, there
+	 * would be no JPA project!
+	 */
+	@SuppressWarnings("unchecked")
+	private ListValueModel<String> buildPlatformChoicesModel() {
+		return new SortedListValueModelAdapter<String>(
+				new SetCollectionValueModel<String>(
+						new CompositeCollectionValueModel<CollectionValueModel<String>, String>(
+								new PropertyCollectionValueModelAdapter<String>(this.platformIdModel),
+								this.buildRegistryPlatformsModel()
+						)
+				),
+				JPA_PLATFORM_COMPARATOR
+			);
+	}
+
+	private CollectionValueModel<String> buildRegistryPlatformsModel() {
+		String jpaFacetVersion = this.getProjectFacetVersion().getVersionString();
+		Iterable<String> enabledPlatformIds = JpaPlatformRegistry.instance().getJpaPlatformIdsForJpaFacetVersion(jpaFacetVersion);
+		return new StaticCollectionValueModel<String>(enabledPlatformIds);
+	}
+
+	private static final Comparator<String> JPA_PLATFORM_COMPARATOR =
+			new Comparator<String>() {
+				public int compare(String id1, String id2) {
+					String label1 = getJpaPlatformLabel(id1);
+					String label2 = getJpaPlatformLabel(id2);
+					return STRING_COMPARATOR.compare(label1, label2);
+				}
+			};
+
+	private static final StringConverter<String> JPA_PLATFORM_LABEL_CONVERTER =
+			new StringConverter<String>() {
+				public String convertToString(String id) {
+					return getJpaPlatformLabel(id);
+				}
+			};
+
+	/* private */ static String getJpaPlatformLabel(String id) {
+		return JpaPlatformRegistry.instance().getJpaPlatformLabel(id);
+	}
+
+
+	// ********** connection group **********
+
+	private void buildConnectionGroup(Composite composite) {
+		Group group = new Group(composite, SWT.NONE);
+		group.setText(JptUiMessages.JpaFacetWizardPage_connectionLabel);
+		group.setLayout(new GridLayout(3, false));
+		group.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+		PlatformUI.getWorkbench().getHelpSystem().setHelp(group, JpaHelpContextIds.PROPERTIES_JAVA_PERSISTENCE_CONNECTION);
+
+		Combo connectionDropDown = this.buildDropDown(group, 3);
+		SWTTools.bind(
+				CONNECTION_CHOICES_MODEL,
+				this.connectionModel,
+				connectionDropDown,
+				SIMPLE_STRING_CONVERTER
+			);
+
+		Link addConnectionLink = this.buildLink(group, JptUiMessages.JpaFacetWizardPage_connectionLink);
+		addConnectionLink.addSelectionListener(this.buildAddConnectionLinkListener());  // the link will be GCed
+
+		this.connectLink = this.buildLink(group, JptUiMessages.JpaFacetWizardPage_connectLink);
+		SWTTools.controlEnabledState(this.disconnectedModel, this.connectLink);
+		this.connectLink.addSelectionListener(this.buildConnectLinkListener());  // the link will be GCed
+
+		// override default catalog
+		Button overrideDefaultCatalogCheckBox = this.buildCheckBox(group, 3, JptUiMessages.JpaFacetWizardPage_overrideDefaultCatalogLabel);
+		SWTTools.bind(this.userOverrideDefaultCatalogFlagModel, overrideDefaultCatalogCheckBox);
+
+		Label defaultCatalogLabel = this.buildLabel(group, JptUiMessages.JpaFacetWizardPage_defaultCatalogLabel);
+		Combo defaultCatalogDropDown = this.buildDropDown(group);
+		SWTTools.bind(this.catalogChoicesModel, this.defaultCatalogModel, defaultCatalogDropDown);
+
+		SWTTools.controlEnabledState(this.userOverrideDefaultCatalogFlagModel, defaultCatalogLabel, defaultCatalogDropDown);
+
+		// override default schema
+		Button overrideDefaultSchemaButton = this.buildCheckBox(group, 3, JptUiMessages.JpaFacetWizardPage_overrideDefaultSchemaLabel);
+		SWTTools.bind(this.userOverrideDefaultSchemaFlagModel, overrideDefaultSchemaButton);
+
+		Label defaultSchemaLabel = this.buildLabel(group, JptUiMessages.JpaFacetWizardPage_defaultSchemaLabel);
+		Combo defaultSchemaDropDown = this.buildDropDown(group);
+		SWTTools.bind(this.schemaChoicesModel, this.defaultSchemaModel, defaultSchemaDropDown);
+
+		SWTTools.controlEnabledState(this.userOverrideDefaultSchemaFlagModel, defaultSchemaLabel, defaultSchemaDropDown);
+	}
+
+	private static final StringConverter<String> SIMPLE_STRING_CONVERTER =
+			new StringConverter<String>() {
+				public String convertToString(String string) {
+					return (string != null) ? string : JptUiMessages.JpaFacetWizardPage_none;
+				}
+			};
+
+	private SelectionListener buildAddConnectionLinkListener() {
+		return new SelectionAdapter() {
+			@Override
+			public void widgetSelected(SelectionEvent e) {
+				JpaProjectPropertiesPage.this.openNewConnectionWizard();
+			}
+			@Override
+			public String toString() {
+				return "connection link listener"; //$NON-NLS-1$
+			}
+		};
+	}
+
+	void openNewConnectionWizard() {
+		String connectionName = DTPUiTools.createNewConnectionProfile();
+		if (connectionName != null) {
+			this.connectionModel.setValue(connectionName);
+		}
+	}
+
+	private SelectionListener buildConnectLinkListener() {
+		return new SelectionAdapter() {
+			@Override
+			public void widgetSelected(SelectionEvent e) {
+				JpaProjectPropertiesPage.this.openConnectionProfile();
+			}
+			@Override
+			public String toString() {
+				return "connect link listener"; //$NON-NLS-1$
+			}
+		};
+	}
+
+	void openConnectionProfile() {
+		ConnectionProfile cp = this.getConnectionProfile();
+		if (cp != null) {
+			cp.connect();
+		}
+	}
+
+
+	// ********** persistent class management group **********
+
+	private void buildPersistentClassManagementGroup(Composite composite) {
+		Group group = new Group(composite, SWT.NONE);
+		group.setText(JptUiMessages.JpaFacetWizardPage_persistentClassManagementLabel);
+		group.setLayout(new GridLayout());
+		group.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+		Button discoverClassesRadioButton = this.buildRadioButton(group, 1, JptUiMessages.JpaFacetWizardPage_discoverClassesButton);
+		SWTTools.bind(this.discoverAnnotatedClassesModel, discoverClassesRadioButton);
+
+		Button listClassesRadioButton = this.buildRadioButton(group, 1, JptUiMessages.JpaFacetWizardPage_listClassesButton);
+		SWTTools.bind(this.listAnnotatedClassesModel, listClassesRadioButton);
+	}
+
+
+	// ********** metamodel group **********
+
+	private void buildMetamodelGroup(Composite composite) {
+		Group group = new Group(composite, SWT.NONE);
+		group.setText(JptUiMessages.JpaFacetWizardPage_metamodelLabel);
+		group.setLayout(new GridLayout(3, false));
+		group.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+		Link metamodelSourceFolderLink = this.buildLink(group, JptUiMessages.JpaFacetWizardPage_metamodelSourceFolderLink);
+		metamodelSourceFolderLink.addSelectionListener(buildMetamodelSourceFolderLinkListener());
+		Combo metamodelSourceFolderDropDown = this.buildDropDown(group);
+		SWTTools.bind(
+				this.javaSourceFolderChoicesModel,
+				this.metamodelSourceFolderModel,
+				metamodelSourceFolderDropDown,
+				SIMPLE_STRING_CONVERTER
+		);
+
+		PlatformUI.getWorkbench().getHelpSystem().setHelp(group, JpaHelpContextIds.PROPERTIES_JAVA_PERSISTENCE_METAMODEL);
+		
+		SWTTools.controlVisibleState(this.jpa2_0ProjectFlagModel, group, metamodelSourceFolderLink, metamodelSourceFolderDropDown);
+	}
+
+	private SelectionListener buildMetamodelSourceFolderLinkListener() {
+		return new SelectionAdapter() {
+			@Override
+			public void widgetSelected(SelectionEvent e) {
+				JpaProjectPropertiesPage.this.openJavaBuildPathPage();
+			}
+			@Override
+			public String toString() {
+				return "metamodel source folder link listener"; //$NON-NLS-1$
+			}
+		};
+	}
+
+	void openJavaBuildPathPage() {
+		IWorkbenchPreferenceContainer container = getWorkbenchPreferenceContainer();
+		container.openPage(BUILD_PATHS_PROPERTY_PAGE_ID, null);
+	}
+	
+	// ********** widgets **********
+
+	private Button buildCheckBox(Composite parent, int horizontalSpan, String text) {
+		return this.buildButton(parent, horizontalSpan, text, SWT.CHECK);
+	}
+
+	private Button buildRadioButton(Composite parent, int horizontalSpan, String text) {
+		return this.buildButton(parent, horizontalSpan, text, SWT.RADIO);
+	}
+
+	private Button buildButton(Composite parent, int horizontalSpan, String text, int style) {
+		Button button = new Button(parent, SWT.NONE | style);
+		button.setText(text);
+		GridData gd = new GridData();
+		gd.horizontalSpan = horizontalSpan;
+		button.setLayoutData(gd);
+		return button;
+	}
+
+	private Combo buildDropDown(Composite parent) {
+		return this.buildDropDown(parent, 1);
+	}
+
+	private Combo buildDropDown(Composite parent, int horizontalSpan) {
+		Combo combo = new Combo(parent, SWT.READ_ONLY);
+		GridData gd = new GridData(GridData.FILL_HORIZONTAL);
+		gd.horizontalSpan = horizontalSpan;
+		combo.setLayoutData(gd);
+		return combo;
+	}
+
+	private Label buildLabel(Composite parent, String text) {
+		Label label = new Label(parent, SWT.LEFT);
+		label.setText(text);
+		GridData gd = new GridData();
+		gd.horizontalSpan = 1;
+		label.setLayoutData(gd);
+		return label;
+	}
+
+	private Link buildLink(Composite parent, String text) {
+		Link link = new Link(parent, SWT.NONE);
+		GridData data = new GridData(GridData.END, GridData.CENTER, false, false);
+		data.horizontalSpan = 2;
+		link.setLayoutData(data);
+		link.setText(text);
+		return link;
+	}
+
+
+	// ********** OK/Revert/Apply behavior **********
+
+	@Override
+	public boolean performOk() {
+		super.performOk();
+
+		try {
+			// true=fork; false=uncancellable
+			this.buildOkProgressMonitorDialog().run(true, false, this.buildOkRunnableWithProgress());
+		}
+		catch (InterruptedException ex) {
+			return false;
+		} 
+		catch (InvocationTargetException ex) {
+			throw new RuntimeException(ex.getTargetException());
+		}
+
+		return true;
+	}
+
+	private IRunnableContext buildOkProgressMonitorDialog() {
+		return new ProgressMonitorDialog(this.getShell());
+	}
+
+	private IRunnableWithProgress buildOkRunnableWithProgress() {
+		return new IRunnableWithProgress() {
+			public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
+				IWorkspace ws = ResourcesPlugin.getWorkspace();
+				try {
+					// the build we execute in #performOk_() locks the workspace root,
+					// so we need to use the workspace root as our scheduling rule here
+					ws.run(
+							JpaProjectPropertiesPage.this.buildOkWorkspaceRunnable(),
+							ws.getRoot(),
+							IWorkspace.AVOID_UPDATE,
+							monitor
+					);
+				}
+				catch (CoreException ex) {
+					throw new InvocationTargetException(ex);
+				}
+			}
+		};
+	}
+
+	/* private */ IWorkspaceRunnable buildOkWorkspaceRunnable() {
+		return new IWorkspaceRunnable() {
+			public void run(IProgressMonitor monitor) throws CoreException {
+				JpaProjectPropertiesPage.this.performOk_(monitor);
+			}
+		};
+	}
+
+	void performOk_(IProgressMonitor monitor) throws CoreException {
+		if (this.isBuffering()) {
+			boolean platformChanged = this.platformIdModel.isBuffering();
+			this.trigger.accept();
+			if (platformChanged) {
+				// if the JPA platform is changed, we need to completely rebuild the JPA project
+				JptCorePlugin.rebuildJpaProject(this.getProject());
+			}
+			this.getProject().build(IncrementalProjectBuilder.FULL_BUILD, monitor);
+		}
+	}
+
+	/**
+	 * Return whether any of the models are buffering a change.
+	 */
+	private boolean isBuffering() {
+		for (BufferedWritablePropertyValueModel<?> model : this.buildBufferedModels()) {
+			if (model.isBuffering()) {
+				return true;
+			}
+		}
+		return false;
+	}
+
+	private BufferedWritablePropertyValueModel<?>[] buildBufferedModels() {
+		return new BufferedWritablePropertyValueModel[] {
+				this.platformIdModel,
+				this.connectionModel,
+				this.userOverrideDefaultCatalogFlagModel,
+				this.userOverrideDefaultCatalogModel,
+				this.userOverrideDefaultSchemaFlagModel,
+				this.userOverrideDefaultSchemaModel,
+				this.discoverAnnotatedClassesModel,
+				this.metamodelSourceFolderModel
+		};
+	}
+
+	@Override
+	protected void performDefaults() {
+		super.performDefaults();
+		this.trigger.reset();
+	}
+
+
+	// ********** dispose **********
+
+	@Override
+	public void dispose() {
+		this.disengageValidationListener();
+		this.platformIdModel.removePropertyChangeListener(PropertyValueModel.VALUE, this.platformIdListener);
+		super.dispose();
+	}
+
+
+	// ********** validation **********
+
+	private ChangeListener buildValidationListener() {
+		return new SimpleChangeListener() {
+			@Override
+			protected void modelChanged() {
+				JpaProjectPropertiesPage.this.validate();
+			}
+			@Override
+			public String toString() {
+				return "validation listener"; //$NON-NLS-1$
+			}
+		};
+	}
+
+	void validate() {
+		if ( ! this.getControl().isDisposed()) {
+			this.updateValidation();
+		}
+	}
+
+	private void engageValidationListener() {
+		for (Model model : this.buildValidationModels()) {
+			model.addChangeListener(this.validationListener);
+		}
+	}
+
+	private Model[] buildValidationModels() {
+		return new Model[] {
+				this.platformIdModel,
+				this.connectionModel,
+				this.userOverrideDefaultCatalogFlagModel,
+				this.defaultCatalogModel,
+				this.userOverrideDefaultSchemaFlagModel,
+				this.defaultSchemaModel,
+				this.discoverAnnotatedClassesModel
+		};
+	}
+
+	private void disengageValidationListener() {
+		for (Model model : this.buildReverseValidationModels()) {
+			model.removeChangeListener(this.validationListener);
+		}
+	}
+
+	private Model[] buildReverseValidationModels() {
+		return ArrayTools.reverse(this.buildValidationModels());
+	}
+
+	private static final Integer ERROR_STATUS = Integer.valueOf(IStatus.ERROR);
+	private static final Integer WARNING_STATUS = Integer.valueOf(IStatus.WARNING);
+	private static final Integer INFO_STATUS = Integer.valueOf(IStatus.INFO);
+	private static final Integer OK_STATUS = Integer.valueOf(IStatus.OK);
+
+	@Override
+	protected IStatus performValidation() {
+		HashMap<Integer, ArrayList<IStatus>> statuses = new HashMap<Integer, ArrayList<IStatus>>();
+		statuses.put(ERROR_STATUS, new ArrayList<IStatus>());
+		statuses.put(WARNING_STATUS, new ArrayList<IStatus>());
+		statuses.put(INFO_STATUS, new ArrayList<IStatus>());
+		statuses.put(OK_STATUS, CollectionTools.list(Status.OK_STATUS));
+
+		/* platform */
+		// user is unable to unset the platform, so no validation necessary
+
+		/* library provider */
+		IStatus lpStatus = super.performValidation();
+		statuses.get(Integer.valueOf(lpStatus.getSeverity())).add(lpStatus);
+
+		/* connection */
+		ConnectionProfile connectionProfile = this.getConnectionProfile();
+		String connectionName = this.getConnectionName();
+		if ( ! StringTools.stringIsEmpty(connectionName)) {
+			if (connectionProfile == null) {
+				statuses.get(ERROR_STATUS).add(this.buildErrorStatus(NLS.bind(
+						JptCoreMessages.VALIDATE_CONNECTION_INVALID,
+						connectionName
+				)));
+			}
+			else if ( ! connectionProfile.isActive()) {
+				statuses.get(INFO_STATUS).add(this.buildInfoStatus(JptCoreMessages.VALIDATE_CONNECTION_NOT_CONNECTED));
+			}
+		}
+
+		/* default catalog */
+		if (this.userOverrideDefaultCatalogFlagIsSet()) {
+			String defaultCatalog = this.getUserOverrideDefaultCatalog();
+			if (StringTools.stringIsEmpty(defaultCatalog)) {
+				statuses.get(ERROR_STATUS).add(this.buildErrorStatus(JptCoreMessages.VALIDATE_DEFAULT_CATALOG_NOT_SPECIFIED));
+			}
+			else if ((connectionProfile != null)
+					&& connectionProfile.isConnected()
+					&& ! CollectionTools.contains(this.catalogChoicesModel.iterator(), defaultCatalog)) {
+				statuses.get(WARNING_STATUS).add(this.buildWarningStatus(NLS.bind(
+						JptCoreMessages.VALIDATE_CONNECTION_DOESNT_CONTAIN_CATALOG,
+						defaultCatalog
+				)));
+			}
+		}
+
+		/* default schema */
+		if (this.userOverrideDefaultSchemaFlagIsSet()) {
+			String defaultSchema = this.getUserOverrideDefaultSchema();
+			if (StringTools.stringIsEmpty(defaultSchema)) {
+				statuses.get(ERROR_STATUS).add(this.buildErrorStatus(JptCoreMessages.VALIDATE_DEFAULT_SCHEMA_NOT_SPECIFIED));
+			}
+			else if ((connectionProfile != null)
+					&& connectionProfile.isConnected()
+					&& ! CollectionTools.contains(this.schemaChoicesModel.iterator(), defaultSchema)) {
+				statuses.get(WARNING_STATUS).add(this.buildWarningStatus(NLS.bind(
+						JptCoreMessages.VALIDATE_CONNECTION_DOESNT_CONTAIN_SCHEMA,
+						defaultSchema
+				)));
+			}
+		}
+
+		if ( ! statuses.get(ERROR_STATUS).isEmpty()) {
+			return statuses.get(ERROR_STATUS).get(0);
+		}
+		else if ( ! statuses.get(WARNING_STATUS).isEmpty()) {
+			return statuses.get(WARNING_STATUS).get(0);
+		}
+		else if ( ! statuses.get(INFO_STATUS).isEmpty()) {
+			return statuses.get(INFO_STATUS).get(0);
+		}
+		else {
+			return statuses.get(OK_STATUS).get(0);
+		}
+	}
+
+	private IStatus buildInfoStatus(String message) {
+		return this.buildStatus(IStatus.INFO, message);
+	}
+
+	private IStatus buildWarningStatus(String message) {
+		return this.buildStatus(IStatus.WARNING, message);
+	}
+
+	private IStatus buildErrorStatus(String message) {
+		return this.buildStatus(IStatus.ERROR, message);
+	}
+
+	private IStatus buildStatus(int severity, String message) {
+		return new Status(severity, JptCorePlugin.PLUGIN_ID, message);
+	}
+
+
+	// ********** UI model adapters **********
+
+	/**
+	 * Treat the JPA project as an "aspect" of the Eclipse project (IProject);
+	 * but the JPA project is stored in the JPA model, not the Eclipse project
+	 * itself....
+	 * We also need to listen for the JPA project to be rebuilt if the user
+	 * changes the Eclipse project's JPA platform (which is stored in the
+	 * Eclipse project's preferences).
+	 */
+	static class JpaProjectModel
+		extends AspectPropertyValueModelAdapter<IProject, JpaProject>
+	{
+		/**
+		 * The JPA project's platform is stored as a preference.
+		 * If it changes, a new JPA project is built.
+		 */
+		private final IPreferenceChangeListener preferenceChangeListener;
+		
+		/**
+		 * The JPA project may also change via another page (notably, the project facets page).
+		 * In that case, the preference change occurs before we actually have another project,
+		 * so we must listen to the projects manager
+		 */
+		private final CollectionChangeListener projectManagerListener;
+		
+		
+		JpaProjectModel(PropertyValueModel<IProject> projectModel) {
+			super(projectModel);
+			this.preferenceChangeListener = this.buildPreferenceChangeListener();
+			this.projectManagerListener = buildProjectManagerListener();
+		}
+		
+		private IPreferenceChangeListener buildPreferenceChangeListener() {
+			return new IPreferenceChangeListener() {
+				public void preferenceChange(PreferenceChangeEvent event) {
+					if (event.getKey().equals(JptCorePlugin.getJpaPlatformIdPrefKey())) {
+						JpaProjectModel.this.platformChanged();
+					}
+				}
+				@Override
+				public String toString() {
+					return "preference change listener"; //$NON-NLS-1$
+				}
+			};
+		}
+		
+		private CollectionChangeListener buildProjectManagerListener() {
+			return new CollectionChangeAdapter() {
+				// we are only looking for the project rebuild *add* event here so we can
+				// determine if the platform has changed.
+				// the other events are unimportant in this case
+				@Override
+				public void itemsAdded(CollectionAddEvent event) {
+					JpaProjectModel.this.platformChanged();
+				}
+			};
+		}
+		
+		void platformChanged() {
+			this.propertyChanged();
+		}
+		
+		@Override
+		protected void engageSubject_() {
+			this.getPreferences().addPreferenceChangeListener(this.preferenceChangeListener);
+			JptCorePlugin.getJpaProjectManager().addCollectionChangeListener(
+						JpaProjectManager.JPA_PROJECTS_COLLECTION, this.projectManagerListener);
+		}
+		
+		@Override
+		protected void disengageSubject_() {
+			this.getPreferences().removePreferenceChangeListener(this.preferenceChangeListener);
+			JptCorePlugin.getJpaProjectManager().removeCollectionChangeListener(
+						JpaProjectManager.JPA_PROJECTS_COLLECTION, this.projectManagerListener);
+		}
+		
+		@Override
+		protected JpaProject buildValue_() {
+			return JptCorePlugin.getJpaProject(this.subject);
+		}
+		
+		private IEclipsePreferences getPreferences() {
+			return JptCorePlugin.getProjectPreferences(this.subject);
+		}
+	}
+
+
+	/**
+	 * The JPA project's data source is an auxiliary object that never changes;
+	 * so if we have a JPA project, we have a JPA data source also.
+	 */
+	static class DataSourceModel
+		extends TransformationPropertyValueModel<JpaProject, JpaDataSource>
+	{
+		DataSourceModel(PropertyValueModel<JpaProject> jpaProjectModel) {
+			super(jpaProjectModel);
+		}
+
+		@Override
+		protected JpaDataSource transform_(JpaProject value) {
+			return value.getDataSource();
+		}
+	}
+
+
+	/**
+	 * The DTP connection profile name is an aspect of the JPA project's
+	 * data source
+	 */
+	static class ConnectionModel
+		extends PropertyAspectAdapter<JpaDataSource, String>
+	{
+		ConnectionModel(PropertyValueModel<JpaProject> jpaProjectModel) {
+			super(new DataSourceModel(jpaProjectModel), JpaDataSource.CONNECTION_PROFILE_NAME_PROPERTY);
+		}
+
+		@Override
+		protected String buildValue_() {
+			return this.subject.getConnectionProfileName();
+		}
+
+		@Override
+		public void setValue_(String connection) {
+			this.subject.setConnectionProfileName(connection);
+		}
+	}
+
+
+	/**
+	 * Convert the selected connection profile name to a connection profile
+	 */
+	static class ConnectionProfileModel
+		extends CachingTransformationPropertyValueModel<String, ConnectionProfile>
+	{
+		ConnectionProfileModel(PropertyValueModel<String> connectionModel) {
+			super(connectionModel);
+		}
+
+		@Override
+		protected ConnectionProfile transform_(String connectionName) {
+			return JptDbPlugin.instance().getConnectionProfileFactory().buildConnectionProfile(connectionName);
+		}
+	}
+
+
+	/**
+	 * Treat the JPA platform ID as an "aspect" of the JPA project.
+	 * The platform ID is stored in the project preferences.
+	 * The platform ID does not change for a JPA project - if the user wants a
+	 * different platform, we build an entirely new JPA project.
+	 */
+	static class PlatformIdModel
+		extends AspectPropertyValueModelAdapter<JpaProject, String>
+	{
+		PlatformIdModel(PropertyValueModel<JpaProject> jpaProjectModel) {
+			super(jpaProjectModel);
+		}
+
+		@Override
+		protected String buildValue_() {
+			return JptCorePlugin.getJpaPlatformId(this.subject.getProject());
+		}
+
+		@Override
+		public void setValue_(String newPlatformId) {
+			JptCorePlugin.setJpaPlatformId(this.subject.getProject(), newPlatformId);
+		}
+
+		@Override
+		protected void engageSubject_() {
+			// the platform ID does not change
+		}
+
+		@Override
+		protected void disengageSubject_() {
+			// the platform ID does not change
+		}
+	}
+
+
+	/**
+	 * The connections are held by a singleton, so the model can be a singleton
+	 * also.
+	 */
+	// by default, ExtendedListValueModelWrapper puts a null at the top of the list
+	private static final ListValueModel<String> CONNECTION_CHOICES_MODEL =
+			new ExtendedListValueModelWrapper<String>(
+					new SortedListValueModelAdapter<String>(
+							new ConnectionChoicesModel(),
+							STRING_COMPARATOR
+					)
+			);
+
+	/**
+	 * Wrap the connection profile names held by the connection profile
+	 * factory singleton.
+	 */
+	static class ConnectionChoicesModel
+		extends AbstractCollectionValueModel
+		implements CollectionValueModel<String>
+	{
+		private final ConnectionProfileListener connectionProfileListener;
+
+		ConnectionChoicesModel() {
+			super();
+			this.connectionProfileListener = this.buildConnectionProfileListener();
+		}
+
+		private ConnectionProfileListener buildConnectionProfileListener() {
+			return new ConnectionProfileListener() {
+				public void connectionProfileAdded(String name) {
+					ConnectionChoicesModel.this.collectionChanged();
+				}
+				public void connectionProfileRemoved(String name) {
+					ConnectionChoicesModel.this.collectionChanged();
+				}
+				public void connectionProfileRenamed(String oldName, String newName) {
+					// Ignore this event for now. Connecting a profile actually
+					// throws a connection renamed event, which messes up the 
+					// list selection. There shouldn't be a connection renamed
+					// within the scope of this dialog anyhow.
+					// ConnectionChoicesModel.this.collectionChanged();
+				}
+			};
+		}
+
+		void collectionChanged() {
+			this.fireCollectionChanged(CollectionValueModel.VALUES, CollectionTools.collection(this.iterator()));
+		}
+
+		public Iterator<String> iterator() {
+			return this.getConnectionProfileFactory().getConnectionProfileNames().iterator();
+		}
+
+		public int size() {
+			return CollectionTools.size(this.iterator());
+		}
+
+		@Override
+		protected void engageModel() {
+			this.getConnectionProfileFactory().addConnectionProfileListener(this.connectionProfileListener);
+		}
+
+		@Override
+		protected void disengageModel() {
+			this.getConnectionProfileFactory().removeConnectionProfileListener(this.connectionProfileListener);
+		}
+
+		private ConnectionProfileFactory getConnectionProfileFactory() {
+			return JptDbPlugin.instance().getConnectionProfileFactory();
+		}
+	}
+
+
+	/**
+	 * Adapt whether the JPA project has a user override specified
+	 * (either catalog or schema);
+	 */
+	abstract static class UserOverrideDefaultFlagModel
+		extends PropertyAspectAdapter<JpaProject, Boolean>
+	{
+		UserOverrideDefaultFlagModel(PropertyValueModel<JpaProject> jpaProjectModel, String propertyName) {
+			super(jpaProjectModel, propertyName);
+		}
+
+		@Override
+		protected Boolean buildValue_() {
+			return Boolean.valueOf(this.specifiesUserOverrideDefault());
+		}
+
+		boolean specifiesUserOverrideDefault() {
+			return ! StringTools.stringIsEmpty(this.getUserOverrideDefault());
+		}
+
+		abstract String getUserOverrideDefault();
+
+		@Override
+		protected void setValue_(Boolean value) {
+			// ignore
+		}
+	}
+
+
+	/**
+	 * Whether the JPA project has a user override default catalog specified.
+	 */
+	static class UserOverrideDefaultCatalogFlagModel
+		extends UserOverrideDefaultFlagModel
+	{
+		UserOverrideDefaultCatalogFlagModel(PropertyValueModel<JpaProject> jpaProjectModel) {
+			super(jpaProjectModel, JpaProject.USER_OVERRIDE_DEFAULT_CATALOG_PROPERTY);
+		}
+		@Override
+		public String getUserOverrideDefault() {
+			return this.subject.getUserOverrideDefaultCatalog();
+		}
+	}
+
+
+	/**
+	 * Whether the JPA project has a user override default schema specified.
+	 */
+	static class UserOverrideDefaultSchemaFlagModel
+		extends UserOverrideDefaultFlagModel
+	{
+		UserOverrideDefaultSchemaFlagModel(PropertyValueModel<JpaProject> jpaProjectModel) {
+			super(jpaProjectModel, JpaProject.USER_OVERRIDE_DEFAULT_SCHEMA_PROPERTY);
+		}
+		@Override
+		public String getUserOverrideDefault() {
+			return this.subject.getUserOverrideDefaultSchema();
+		}
+	}
+
+
+	/**
+	 * The JPA project's user override default catalog
+	 */
+	static class UserOverrideDefaultCatalogModel
+		extends PropertyAspectAdapter<JpaProject, String>
+	{
+		UserOverrideDefaultCatalogModel(PropertyValueModel<JpaProject> jpaProjectModel) { 
+			super(jpaProjectModel, JpaProject.USER_OVERRIDE_DEFAULT_CATALOG_PROPERTY);
+		}
+
+		@Override
+		protected String buildValue_() {
+			return this.subject.getUserOverrideDefaultCatalog();
+		}
+
+		@Override
+		public void setValue_(String catalog) {
+			this.subject.setUserOverrideDefaultCatalog(catalog);
+		}
+	}
+
+
+	/**
+	 * The JPA project's user override default catalog
+	 */
+	static class UserOverrideDefaultSchemaModel
+		extends PropertyAspectAdapter<JpaProject, String>
+	{
+		UserOverrideDefaultSchemaModel(PropertyValueModel<JpaProject> jpaProjectModel) { 
+			super(jpaProjectModel, JpaProject.USER_OVERRIDE_DEFAULT_SCHEMA_PROPERTY);
+		}
+
+		@Override
+		protected String buildValue_() {
+			return this.subject.getUserOverrideDefaultSchema();
+		}
+
+		@Override
+		public void setValue_(String schema) {
+			this.subject.setUserOverrideDefaultSchema(schema);
+		}
+	}
+
+
+	/**
+	 * Flag on the JPA project indicating whether it should discover annotated
+	 * classes
+	 */
+	static class DiscoverAnnotatedClassesModel
+		extends PropertyAspectAdapter<JpaProject, Boolean>
+	{
+		DiscoverAnnotatedClassesModel(PropertyValueModel<JpaProject> jpaProjectModel) { 
+			super(jpaProjectModel, JpaProject.DISCOVERS_ANNOTATED_CLASSES_PROPERTY);
+		}
+
+		@Override
+		protected Boolean buildValue_() {
+			return Boolean.valueOf(this.subject.discoversAnnotatedClasses());
+		}
+
+		@Override
+		protected void setValue_(Boolean value) {
+			this.subject.setDiscoversAnnotatedClasses(value.booleanValue());
+		}
+	}
+
+	/**
+	 * The folder where the source for the generated Canonical Metamodel
+	 * is written.
+	 */
+	static class MetamodelSourceFolderModel
+		extends PropertyAspectAdapter<JpaProject, String>
+	{
+		MetamodelSourceFolderModel(PropertyValueModel<JpaProject> jpaProjectModel) {
+			super(jpaProjectModel, JpaProject2_0.METAMODEL_SOURCE_FOLDER_NAME_PROPERTY);
+		}
+
+		@Override
+		protected String buildValue_() {
+			return jpaProjectIsJpa2_0() ? ((JpaProject2_0) this.subject).getMetamodelSourceFolderName() : null;
+		}
+
+		@Override
+		protected void setValue_(String value) {
+			if (this.jpaProjectIsJpa2_0()) {
+				((JpaProject2_0) this.subject).setMetamodelSourceFolderName(value);
+			}
+		}
+
+		private boolean jpaProjectIsJpa2_0() {
+			return JptCorePlugin.nodeIsJpa2_0Compatible(this.subject);
+		}
+	}
+
+
+	/**
+	 * Java project source folders.
+	 * We keep the metamodel source folder in synch with the Java source folders
+	 * (i.e. if a Java source folder is deleted or removed from the build path,
+	 * we remove the metamodel source folder); therefore the list of folder
+	 * choices does not need to be augmented with the current folder (as we do
+	 * when the current folder is not in the list of choices).
+	 */
+	static class JavaSourceFolderChoicesModel
+		extends AspectCollectionValueModelAdapter<JpaProject, String>
+	{
+		private final IElementChangedListener javaElementChangedListener;
+
+		JavaSourceFolderChoicesModel(PropertyValueModel<JpaProject> jpaProjectModel) { 
+			super(jpaProjectModel);
+			this.javaElementChangedListener = this.buildJavaElementChangedListener();
+		}
+
+		private IElementChangedListener buildJavaElementChangedListener() {
+			return new IElementChangedListener() {
+				public void elementChanged(ElementChangedEvent event) {
+					JavaSourceFolderChoicesModel.this.processJavaDelta(event.getDelta());
+				}
+			};
+		}
+
+		void processJavaDelta(IJavaElementDelta delta) {
+			switch (delta.getElement().getElementType()) {
+				case IJavaElement.JAVA_MODEL :
+					this.processJavaDeltaChildren(delta);
+					break;
+				case IJavaElement.JAVA_PROJECT :
+					this.processJavaProjectDelta(delta);
+					break;
+				default :
+					break; // ignore everything else
+			}
+		}
+
+		private void processJavaDeltaChildren(IJavaElementDelta delta) {
+			for (IJavaElementDelta child : delta.getAffectedChildren()) {
+				this.processJavaDelta(child); // recurse
+			}
+		}
+
+		private void processJavaProjectDelta(IJavaElementDelta delta) {
+			IJavaProject javaProject = (IJavaProject) delta.getElement();
+			if (javaProject.equals(this.subject.getJavaProject()) && this.classpathHasChanged(delta)) {
+				this.fireCollectionChanged(CollectionValueModel.VALUES, CollectionTools.collection(this.iterator()));
+			}
+		}
+
+		private boolean classpathHasChanged(IJavaElementDelta delta) {
+			return this.deltaFlagIsSet(delta, IJavaElementDelta.F_RESOLVED_CLASSPATH_CHANGED);
+		}
+
+		private boolean deltaFlagIsSet(IJavaElementDelta delta, int flag) {
+			return (delta.getKind() == IJavaElementDelta.CHANGED) &&
+					BitTools.flagIsSet(delta.getFlags(), flag);
+		}
+
+		@Override
+		protected Iterable<String> getIterable() {
+			return this.jpaProjectIsJpa2_0() ?
+					((JpaProject2_0) this.subject).getJavaSourceFolderNames() :
+					EmptyIterable.<String>instance();
+		}
+
+		private boolean jpaProjectIsJpa2_0() {
+			return JptCorePlugin.nodeIsJpa2_0Compatible(this.subject);
+		}
+
+		@Override
+		protected void engageSubject_() {
+			JavaCore.addElementChangedListener(this.javaElementChangedListener);
+		}
+
+		@Override
+		protected void disengageSubject_() {
+			JavaCore.removeElementChangedListener(this.javaElementChangedListener);
+		}
+	}
+
+
+	/**
+	 * Abstract property aspect adapter for DTP connection profile connection/database
+	 */
+	abstract static class ConnectionProfilePropertyAspectAdapter<V>
+		extends AspectPropertyValueModelAdapter<ConnectionProfile, V>
+	{
+		private final ConnectionListener connectionListener;
+
+		ConnectionProfilePropertyAspectAdapter(PropertyValueModel<ConnectionProfile> connectionProfileModel) {
+			super(connectionProfileModel);
+			this.connectionListener = this.buildConnectionListener();
+		}
+
+		// the connection opening is probably the only thing that will happen...
+		private ConnectionListener buildConnectionListener() {
+			return new ConnectionAdapter() {
+				@Override
+				public void opened(ConnectionProfile profile) {
+					ConnectionProfilePropertyAspectAdapter.this.connectionOpened(profile);
+				}
+			};
+		}
+
+		void connectionOpened(ConnectionProfile profile) {
+			if (profile.equals(this.subject)) {
+				this.propertyChanged();
+			}
+		}
+
+		@Override
+		protected void engageSubject_() {
+			this.subject.addConnectionListener(this.connectionListener);
+		}
+
+		@Override
+		protected void disengageSubject_() {
+			this.subject.removeConnectionListener(this.connectionListener);
+		}
+	}
+
+
+	/**
+	 * Monitor the connection profile's connection to the database
+	 * (used to enable the "Connect" link)
+	 */
+	static class DisconnectedModel
+		extends ConnectionProfilePropertyAspectAdapter<Boolean>
+	{
+		DisconnectedModel(PropertyValueModel<ConnectionProfile> connectionProfileModel) {
+			super(connectionProfileModel);
+		}
+
+		@Override
+		protected Boolean buildValue_() {
+			return Boolean.valueOf((this.subject != null) && this.subject.isDisconnected());
+		}
+	}
+
+
+	/**
+	 * Database-determined default catalog
+	 */
+	static class DatabaseDefaultCatalogModel
+		extends ConnectionProfilePropertyAspectAdapter<String>
+	{
+		DatabaseDefaultCatalogModel(PropertyValueModel<ConnectionProfile> connectionProfileModel) {
+			super(connectionProfileModel);
+		}
+
+		@Override
+		protected String buildValue_() {
+			Database db = this.subject.getDatabase();
+			return (db == null) ? null : db.getDefaultCatalogIdentifier();
+		}
+	}
+
+
+	/**
+	 * The default schema is not derived purely from the database; it is also dependent
+	 * on the current value of the default catalog (which may be overridden
+	 * by the user).
+	 */
+	static class DatabaseDefaultSchemaModel
+		extends ConnectionProfilePropertyAspectAdapter<String>
+	{
+		private final PropertyValueModel<String> defaultCatalogModel;
+		private final PropertyChangeListener catalogListener;
+
+		DatabaseDefaultSchemaModel(
+				PropertyValueModel<ConnectionProfile> connectionProfileModel,
+				PropertyValueModel<String> defaultCatalogModel
+		) {
+			super(connectionProfileModel);
+			this.defaultCatalogModel = defaultCatalogModel;
+			this.catalogListener = this.buildCatalogListener();
+		}
+
+		private PropertyChangeListener buildCatalogListener() {
+			return new PropertyChangeListener() {
+				public void propertyChanged(PropertyChangeEvent event) {
+					DatabaseDefaultSchemaModel.this.catalogChanged();
+				}
+			};
+		}
+
+		void catalogChanged() {
+			this.propertyChanged();
+		}
+
+		@Override
+		protected void engageSubject_() {
+			super.engageSubject_();
+			this.defaultCatalogModel.addPropertyChangeListener(PropertyValueModel.VALUE, this.catalogListener);
+		}
+
+		@Override
+		protected void disengageSubject_() {
+			this.defaultCatalogModel.removePropertyChangeListener(PropertyValueModel.VALUE, this.catalogListener);
+			super.disengageSubject_();
+		}
+
+		@Override
+		protected String buildValue_() {
+			SchemaContainer sc = this.getSchemaContainer();
+			return (sc == null) ? null : sc.getDefaultSchemaIdentifier();
+		}
+
+		private SchemaContainer getSchemaContainer() {
+			return this.databaseSupportsCatalogs() ? this.getCatalog() : this.getDatabase();
+		}
+
+		private boolean databaseSupportsCatalogs() {
+			Database db = this.getDatabase();
+			return (db != null) && db.supportsCatalogs();
+		}
+
+		private Catalog getCatalog() {
+			String name = this.defaultCatalogModel.getValue();
+			// if we get here we know the database is not null
+			return (name == null) ? null : this.getDatabase().getCatalogForIdentifier(name);
+		}
+
+		private Database getDatabase() {
+			return this.subject.getDatabase();
+		}
+	}
+
+
+	/**
+	 * Abstract collection aspect adapter for DTP connection profile connection/database
+	 */
+	abstract static class ConnectionProfileCollectionAspectAdapter<E>
+		extends AspectCollectionValueModelAdapter<ConnectionProfile, E>
+	{
+		private final ConnectionListener connectionListener;
+
+		ConnectionProfileCollectionAspectAdapter(PropertyValueModel<ConnectionProfile> connectionProfileModel) {
+			super(connectionProfileModel);
+			this.connectionListener = this.buildConnectionListener();
+		}
+
+		// the connection opening is probably the only thing that will happen...
+		private ConnectionListener buildConnectionListener() {
+			return new ConnectionAdapter() {
+				@Override
+				public void opened(ConnectionProfile profile) {
+					ConnectionProfileCollectionAspectAdapter.this.connectionOpened(profile);
+				}
+			};
+		}
+
+		void connectionOpened(ConnectionProfile profile) {
+			if (profile.equals(this.subject)) {
+				this.collectionChanged();
+			}
+		}
+
+		@Override
+		protected void engageSubject_() {
+			this.subject.addConnectionListener(this.connectionListener);
+		}
+
+		@Override
+		protected void disengageSubject_() {
+			this.subject.removeConnectionListener(this.connectionListener);
+		}
+	}
+
+
+	/**
+	 * Catalogs on the database.
+	 */
+	static class DatabaseCatalogChoicesModel
+		extends ConnectionProfileCollectionAspectAdapter<String>
+	{
+		DatabaseCatalogChoicesModel(PropertyValueModel<ConnectionProfile> connectionProfileModel) {
+			super(connectionProfileModel);
+		}
+
+		@Override
+		protected Iterable<String> getIterable() {
+			Database db = this.subject.getDatabase();
+			// use catalog *identifiers* since the string ends up being the "default" for various text entries
+			return (db != null) ? db.getSortedCatalogIdentifiers() : EmptyIterable.<String>instance();
+		}
+	}
+
+
+	/**
+	 * Schemas on the database or catalog.
+	 * This list is not derived purely from the database; it is also dependent
+	 * on the current value of the default catalog (which may be overridden
+	 * by the user).
+	 */
+	static class DatabaseSchemaChoicesModel
+		extends ConnectionProfileCollectionAspectAdapter<String>
+	{
+		private final PropertyValueModel<String> defaultCatalogModel;
+		private final PropertyChangeListener catalogListener;
+
+		DatabaseSchemaChoicesModel(
+				PropertyValueModel<ConnectionProfile> connectionProfileModel,
+				PropertyValueModel<String> defaultCatalogModel
+		) {
+			super(connectionProfileModel);
+			this.defaultCatalogModel = defaultCatalogModel;
+			this.catalogListener = this.buildCatalogListener();
+		}
+
+		private PropertyChangeListener buildCatalogListener() {
+			return new PropertyChangeListener() {
+				public void propertyChanged(PropertyChangeEvent event) {
+					DatabaseSchemaChoicesModel.this.catalogChanged();
+				}
+			};
+		}
+
+		void catalogChanged() {
+			this.collectionChanged();
+		}
+
+		@Override
+		protected void engageSubject_() {
+			super.engageSubject_();
+			this.defaultCatalogModel.addPropertyChangeListener(PropertyValueModel.VALUE, this.catalogListener);
+		}
+
+		@Override
+		protected void disengageSubject_() {
+			this.defaultCatalogModel.removePropertyChangeListener(PropertyValueModel.VALUE, this.catalogListener);
+			super.disengageSubject_();
+		}
+
+		@Override
+		protected Iterable<String> getIterable() {
+			SchemaContainer sc = this.getSchemaContainer();
+			// use schema *identifiers* since the string ends up being the "default" for various text entries
+			return (sc != null) ? sc.getSortedSchemaIdentifiers() : EmptyIterable.<String>instance();
+		}
+
+		private SchemaContainer getSchemaContainer() {
+			return this.databaseSupportsCatalogs() ? this.getCatalog() : this.getDatabase();
+		}
+
+		private boolean databaseSupportsCatalogs() {
+			Database db = this.getDatabase();
+			return (db != null) && db.supportsCatalogs();
+		}
+
+		private Catalog getCatalog() {
+			String name = this.defaultCatalogModel.getValue();
+			// if we get here we know the database is not null
+			return (name == null) ? null : this.getDatabase().getCatalogForIdentifier(name);
+		}
+
+		private Database getDatabase() {
+			return this.subject.getDatabase();
+		}
+	}
+
+	/**
+	 * Combine various models to determine the default catalog or schema.
+	 * If the user has checked the "Override Default" check-box, the default
+	 * is the JPA project's user override default, otherwise the default is
+	 * determined by the database.
+	 */
+	static class DefaultModel
+		extends CompositePropertyValueModel<String>
+		implements WritablePropertyValueModel<String>
+	{
+		private final PropertyValueModel<Boolean> userOverrideDefaultFlagModel;
+		private final WritablePropertyValueModel<String> userOverrideDefaultModel;
+		private final PropertyValueModel<String> databaseDefaultModel;
+
+		DefaultModel(
+				PropertyValueModel<Boolean> userOverrideDefaultFlagModel,
+				WritablePropertyValueModel<String> userOverrideDefaultModel,
+				PropertyValueModel<String> databaseDefaultModel
+		) {
+			super(userOverrideDefaultFlagModel, userOverrideDefaultModel, databaseDefaultModel);
+			this.userOverrideDefaultFlagModel = userOverrideDefaultFlagModel;
+			this.userOverrideDefaultModel = userOverrideDefaultModel;
+			this.databaseDefaultModel = databaseDefaultModel;
+		}
+
+		/**
+		 * If the checkbox has been unchecked, we need to clear out the JPA
+		 * project's user override.
+		 */
+		@Override
+		protected void propertyChanged(PropertyChangeEvent event) {
+			super.propertyChanged(event);
+			if (event.getSource() == this.userOverrideDefaultFlagModel) {
+				if ( ! this.userOverrideDefaultFlagIsSet()) {
+					this.userOverrideDefaultModel.setValue(null);
+				}
+			}
+		}
+
+		/**
+		 * If the checkbox is checked, return the user override from the JPA project;
+		 * otherwise return the default from the database
+		 */
+		@Override
+		protected String buildValue() {
+			return this.userOverrideDefaultFlagIsSet() ?
+					this.userOverrideDefaultModel.getValue() :
+					this.databaseDefaultModel.getValue();
+		}
+
+		/**
+		 * This will be called when the user makes a selection from the
+		 * drop-down; which is only possible when the checkbox is checked
+		 * (and the drop-down is enabled).
+		 */
+		public void setValue(String value) {
+			this.userOverrideDefaultModel.setValue(value);
+			this.propertyChanged();
+		}
+
+		private boolean userOverrideDefaultFlagIsSet() {
+			return flagIsSet(this.userOverrideDefaultFlagModel);
+		}
+
+		@Override
+		public void toString(StringBuilder sb) {
+			sb.append(this.getValue());
+		}
+	}
+
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/selection/DefaultJpaSelection.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/selection/DefaultJpaSelection.java
new file mode 100644
index 0000000..4f64a64
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/selection/DefaultJpaSelection.java
@@ -0,0 +1,60 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2008 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.ui.internal.selection;
+
+import org.eclipse.jpt.core.JpaStructureNode;
+
+/**
+ * Straightforward implementation of the JpaSelection interface.
+ */
+public class DefaultJpaSelection
+	implements JpaSelection
+{
+	private final JpaStructureNode selectedNode;
+
+
+	public DefaultJpaSelection(JpaStructureNode selectedNode) {
+		super();
+		if (selectedNode == null) {
+			throw new NullPointerException("A 'selectedNode' is required; otherwise use NULL_SELECTION.");
+		}
+		this.selectedNode = selectedNode;
+	}
+
+	public JpaStructureNode getSelectedNode() {
+		return this.selectedNode;
+	}
+
+	public boolean isEmpty() {
+		// by definition, this selection is never empty
+		// use IJpaSelection.NULL_SELECTION for empty selections
+		return false;
+	}
+
+	@Override
+	public boolean equals(Object obj) {
+		if (! (obj instanceof JpaSelection)) {
+			return false;
+		}
+		JpaSelection other = (JpaSelection) obj;
+		return ( ! other.isEmpty()) && this.selectedNode.equals(other.getSelectedNode());
+	}
+
+	@Override
+	public int hashCode() {
+		return this.selectedNode.hashCode();
+	}
+
+	@Override
+	public String toString() {
+		return this.selectedNode.toString();
+	}
+
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/selection/DefaultJpaSelectionManager.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/selection/DefaultJpaSelectionManager.java
new file mode 100644
index 0000000..e66de69
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/selection/DefaultJpaSelectionManager.java
@@ -0,0 +1,288 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2009 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.ui.internal.selection;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+import org.eclipse.jpt.utility.internal.iterators.CloneIterator;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IPageListener;
+import org.eclipse.ui.IPartListener2;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.IWorkbenchPartReference;
+import org.eclipse.ui.IWorkbenchWindow;
+
+/**
+ * A {@link JpaSelectionManager} stores the current {@link JpaSelection} and 
+ * notifies <code>ISelectionListener</code>s when the selection changes.
+ */
+public class DefaultJpaSelectionManager
+	implements JpaSelectionManager
+{
+	/* The window for which this object manages selections */
+	private IWorkbenchWindow window;
+	
+	/* The set of pages for which this object is managing selections */
+	private Set<IWorkbenchPage> pages;
+	
+	/* The active editor part */
+	private IEditorPart activeEditor;
+	
+	private JpaSelection currentSelection;
+	
+	/* The map of <code>IJpaSelectionParticipant</code>s (keyed by part) */
+	private Map<IWorkbenchPart, JpaSelectionParticipant> selectionParticipants;
+	
+	private IPageListener pageListener;
+	
+	private IPartListener2 partListener;
+	
+	
+	public DefaultJpaSelectionManager() {
+		super();
+		pages = Collections.synchronizedSet(new HashSet<IWorkbenchPage>());
+		selectionParticipants = Collections.synchronizedMap(new HashMap<IWorkbenchPart, JpaSelectionParticipant>());
+		pageListener = new PageListener();
+		partListener = new PartListener();
+		currentSelection = DefaultJpaSelection.NULL_SELECTION;
+	}
+	
+	void init(IWorkbenchWindow aWindow) {
+		window = aWindow;
+		aWindow.addPageListener(pageListener);
+		initPage(aWindow.getActivePage());
+	}
+	
+	private void initPage(IWorkbenchPage page) {
+		if ((page != null) && (! pages.contains(page))) {
+			page.addPartListener(partListener);
+			pages.add(page);
+			activateEditor(page.getActiveEditor());
+		}
+	}
+	
+	private void disposePage(IWorkbenchPage page) {
+		if ((page != null) && (pages.contains(page))) {
+			page.removePartListener(partListener);
+			pages.remove(page);
+		}
+	}
+	
+	private void activateEditor(IEditorPart editor) {
+		if (editor == activeEditor) {
+			return;
+		}
+		if (activeEditor != null) {
+			inactivateEditor(activeEditor);
+		}
+		initPart(editor);
+		activeEditor = editor;
+		selectEditor(activeEditor);
+	}
+	
+	private void inactivateEditor(IEditorPart editor) {
+		
+	}
+	
+	void initPart(IWorkbenchPart part) {
+		if (part != null) {
+			if (selectionParticipants.get(part) == null) {
+				JpaSelectionParticipant selectionParticipant = 
+					(JpaSelectionParticipant) part.getAdapter(JpaSelectionParticipant.class);
+				if (selectionParticipant != null) {
+					selectionParticipants.put(part, selectionParticipant);
+				}
+			}
+		}
+	}
+	
+	private void selectEditor(IEditorPart editor) {
+		selectPart(editor);
+	}
+	
+	void selectPart(IWorkbenchPart part) {
+		JpaSelectionParticipant selectionParticipant = getSelectionParticipant(part);
+		if (selectionParticipant != null) {
+			select(selectionParticipant.getSelection(), selectionParticipant);
+		}
+	}
+	
+	void hidePart(IWorkbenchPart part) {
+		JpaSelectionParticipant selectionParticipant = getSelectionParticipant(part);
+		if ((selectionParticipant != null) && (selectionParticipant.disposeOnHide())) {
+			closePart(part);
+		}
+	}
+	
+	void closePart(IWorkbenchPart part) {
+		JpaSelectionParticipant selectionParticipant = getSelectionParticipant(part);
+		if (selectionParticipant != null) {
+			disposePart(part);
+			checkForNoEditors();
+		}
+	}
+	
+	void disposePart(IWorkbenchPart part) {
+		if ((part != null) && (selectionParticipants.containsKey(part))) {
+			selectionParticipants.remove(part).dispose();
+		}
+	}
+	
+	void checkForNoEditors() {
+		IWorkbenchPage activePage = window.getActivePage();
+		if ((activePage == null)
+				|| (activePage.getEditorReferences().length == 0)) {
+			select(DefaultJpaSelection.NULL_SELECTION, null);
+		}
+	}
+	
+	public void register(IWorkbenchPart part) {
+		initPart(part);
+	}
+	
+	public boolean isRegistered(IWorkbenchPart part) {
+		return selectionParticipants.get(part) != null;
+	}
+	
+	public void select(JpaSelection newSelection, JpaSelectionParticipant source) {
+		if (currentSelection.equals(newSelection)) {
+			return;
+		}
+		
+		currentSelection = newSelection;
+		Object nonNullSource = (source == null) ? this : source;
+		fireSelectionChange(
+			new JpaSelectionEvent(newSelection, JpaSelectionEvent.SELECTION, nonNullSource)
+		);
+	}
+	
+	public void deselect(JpaSelection oldSelection, JpaSelectionParticipant source) {
+		if (currentSelection.equals(oldSelection)) {
+			currentSelection = DefaultJpaSelection.NULL_SELECTION;
+			Object nonNullSource = (source == null) ? this : source;
+			fireSelectionChange(
+				new JpaSelectionEvent(oldSelection, JpaSelectionEvent.DESELECTION, nonNullSource)
+			);
+		}
+	}
+	
+	private void fireSelectionChange(JpaSelectionEvent event) {
+		for (JpaSelectionParticipant sp : selectionParticipants.values()) {
+			sp.selectionChanged(event);
+		}
+	}
+	
+	private JpaSelectionParticipant getSelectionParticipant(IWorkbenchPart part) {
+		return selectionParticipants.get(part);
+	}
+		
+	public JpaSelection getCurrentSelection() {
+		return currentSelection;
+	}
+	
+	public void dispose() {
+		window.removePageListener(pageListener);
+		selectionParticipants.clear();
+		
+		for (Iterator<IWorkbenchPage> stream = new CloneIterator<IWorkbenchPage>(this.pages); stream.hasNext(); ) {
+			this.disposePage(stream.next());
+		}
+
+		for (Iterator<IWorkbenchPart> stream = new CloneIterator<IWorkbenchPart>(selectionParticipants.keySet()); stream.hasNext(); ) {
+			this.disposePart(stream.next());
+		}
+	}
+	
+	
+	private class PageListener implements IPageListener
+	{
+		public void pageActivated(IWorkbenchPage page) {
+			// nop
+		}
+		
+		PageListener() {
+			super();
+		}
+		
+		public void pageClosed(IWorkbenchPage page) {
+			DefaultJpaSelectionManager.this.disposePage(page);
+		}
+		
+		public void pageOpened(IWorkbenchPage page) {
+			DefaultJpaSelectionManager.this.initPage(page);
+		}
+	}
+	
+	
+	private class PartListener implements IPartListener2
+	{
+		PartListener() {
+			super();
+		}
+		
+		public void partActivated(IWorkbenchPartReference partRef) {
+			IWorkbenchPart part = partRef.getPart(false);
+			if (part != null) {
+				DefaultJpaSelectionManager.this.initPart(part);
+				DefaultJpaSelectionManager.this.selectPart(part);
+			}
+		}
+		
+		public void partBroughtToTop(IWorkbenchPartReference partRef) {
+			IWorkbenchPart part = partRef.getPart(false);
+			if (part != null) {
+				initPart(part);
+			}
+		}
+		
+		public void partClosed(IWorkbenchPartReference partRef) {
+			IWorkbenchPart part = partRef.getPart(false);
+			if (part != null) {
+				DefaultJpaSelectionManager.this.closePart(part);
+				DefaultJpaSelectionManager.this.disposePart(part);
+				DefaultJpaSelectionManager.this.checkForNoEditors();
+			}
+		}
+		
+		public void partDeactivated(IWorkbenchPartReference partRef) {
+			// nop
+		}
+		
+		public void partHidden(IWorkbenchPartReference partRef) {
+			IWorkbenchPart part = partRef.getPart(false);
+			if (part != null) {
+				DefaultJpaSelectionManager.this.hidePart(part);
+			}
+		}
+		
+		public void partInputChanged(IWorkbenchPartReference partRef) {
+			// nop
+		}
+		
+		public void partOpened(IWorkbenchPartReference partRef) {
+			IWorkbenchPart part = partRef.getPart(false);
+			if (part != null) {
+				initPart(part);
+			}
+		}
+		
+		public void partVisible(IWorkbenchPartReference partRef) {
+			IWorkbenchPart part = partRef.getPart(false);
+			if (part != null) {
+				initPart(part);
+			}
+		}
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/selection/JpaDetailsSelectionParticipant.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/selection/JpaDetailsSelectionParticipant.java
new file mode 100644
index 0000000..2a8eef6
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/selection/JpaDetailsSelectionParticipant.java
@@ -0,0 +1,42 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2008 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.ui.internal.selection;
+
+import org.eclipse.jpt.ui.internal.views.JpaDetailsView;
+
+
+public class JpaDetailsSelectionParticipant
+	implements JpaSelectionParticipant 
+{
+	private final JpaDetailsView detailsView;
+	
+	
+	public JpaDetailsSelectionParticipant(JpaDetailsView detailsView) {
+		super();
+		this.detailsView = detailsView;
+	}
+
+	public JpaSelection getSelection() {
+		return this.detailsView.getSelection();
+	}
+
+	public void selectionChanged(JpaSelectionEvent evt) {
+		this.detailsView.select(evt.getSelection());
+	}
+
+	public boolean disposeOnHide() {
+		return false;
+	}
+
+	public void dispose() {
+		// NOP
+	}
+
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/selection/JpaSelection.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/selection/JpaSelection.java
new file mode 100644
index 0000000..c923923
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/selection/JpaSelection.java
@@ -0,0 +1,37 @@
+/*******************************************************************************
+ *  Copyright (c) 2007, 2008 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.ui.internal.selection;
+
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jpt.core.JpaStructureNode;
+
+@SuppressWarnings("nls")
+public interface JpaSelection extends ISelection
+{
+	static JpaSelection NULL_SELECTION =
+		new JpaSelection() {
+			public JpaStructureNode getSelectedNode() {
+				return null;
+			}
+
+			public boolean isEmpty() {
+				return true;
+			}
+
+			@Override
+			public String toString() {
+				return "NULL SELECTION";
+			}
+		};
+
+
+	JpaStructureNode getSelectedNode();
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/selection/JpaSelectionEvent.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/selection/JpaSelectionEvent.java
new file mode 100644
index 0000000..d28bafe
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/selection/JpaSelectionEvent.java
@@ -0,0 +1,64 @@
+/*******************************************************************************
+ *  Copyright (c) 2006, 2008 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.ui.internal.selection;
+
+import java.util.EventObject;
+
+public class JpaSelectionEvent extends EventObject 
+{
+	/**
+	 * Serializable uid
+	 * @since 0.5
+	 */
+	private static final long serialVersionUID = 1L;
+    
+	
+	/**
+	 * Indicates that the selection object is now selected
+	 */
+	public static int SELECTION = 1;
+	
+	/**
+	 * Indicates that the selection object has now been deselected
+	 */
+	public static int DESELECTION = 2;
+	
+	
+	/**
+	 * The selection object whose selection status has changed
+	 */
+	private JpaSelection selection;
+	
+	/**
+	 * The type of the selection event, either a SELECTION or a DESELECTION
+	 */
+	private int type;
+	
+	
+	public JpaSelectionEvent(JpaSelection theSelection, int theType, Object source) {
+		super(source);
+		selection = theSelection;
+		type = theType;
+	}
+	
+	/**
+	 * Return the selection object whose selection status has changed
+	 */
+	public JpaSelection getSelection() {
+		return selection;
+	}
+	
+	/**
+	 * Return the type of selection event, either a SELECTION or a DESELECTION
+	 */
+	public int getType() {
+		return type;
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/selection/JpaSelectionManager.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/selection/JpaSelectionManager.java
new file mode 100644
index 0000000..6ee3e33
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/selection/JpaSelectionManager.java
@@ -0,0 +1,57 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2008 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.ui.internal.selection;
+
+import org.eclipse.ui.IWorkbenchPart;
+
+public interface JpaSelectionManager 
+{	
+	/**
+	 * Return the current selection.  
+	 * This will never be null, but it may be empty.
+	 */
+	public JpaSelection getCurrentSelection();
+	
+	/**
+	 * Not to be called lightly, this will affect the selection for all interested
+	 * objects in a window.
+	 * @param newSelection  The new selection for the current window.
+	 * @param source  The selection participant (if any) that is causing the 
+	 * selection.  May be null.
+	 */
+	public void select(JpaSelection newSelection, JpaSelectionParticipant source);
+	
+	/**
+	 * Not to be called lightly, this will affect the selection for all interested
+	 * objects in a window.
+	 * @param oldSelection  The oldSelection will be deselected, iff it matches 
+	 * the current selection.  If so, the new selection will be an empty JpaSelection.
+	 * @param source  The selection participant (if any) that is causing the 
+	 * selection.  May be null. 
+	 */
+	public void deselect(JpaSelection oldSelection, JpaSelectionParticipant source);
+	
+	/**
+	 * This may be used to register a part with the selection manager if the part
+	 * is known to need access to the selection manager before it is ever activated
+	 * or in the case it may be activated prior to the selection manager being 
+	 * created.
+	 * 
+	 * It should not be necessary to deregister a part, as that happens when the 
+	 * part is closed.
+	 */
+	public void register(IWorkbenchPart part);
+	
+	/**
+	 * Returns true if the part is currently registered to respond to selections
+	 * from this selection manager
+	 */
+	public boolean isRegistered(IWorkbenchPart part);
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/selection/JpaSelectionParticipant.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/selection/JpaSelectionParticipant.java
new file mode 100644
index 0000000..c8cf11d
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/selection/JpaSelectionParticipant.java
@@ -0,0 +1,38 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2008 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.ui.internal.selection;
+
+public interface JpaSelectionParticipant 
+{
+	/**
+	 * Return the current selection of the participant
+	 */
+	JpaSelection getSelection();
+	
+	/**
+	 * The selection has changed in the central selection manager.
+	 * Update this participant accordingly.
+	 */
+	void selectionChanged(JpaSelectionEvent evt);
+	
+	/**
+	 * Return whether this selection participant should disconnect itself from
+	 * its part when its part is hidden from view.
+	 * <b>Typically</b> editor participants will return true and view participants will
+	 * return false.
+	 */
+	boolean disposeOnHide();
+	
+	/**
+	 * This participant is no longer needed (most likely because its part has 
+	 * closed).  Dispose of it.
+	 */
+	void dispose();
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/selection/JpaStructureSelectionParticipant.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/selection/JpaStructureSelectionParticipant.java
new file mode 100644
index 0000000..ba3a368
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/selection/JpaStructureSelectionParticipant.java
@@ -0,0 +1,69 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2008 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.ui.internal.selection;
+
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jpt.ui.internal.views.structure.JpaStructureView;
+
+public class JpaStructureSelectionParticipant
+	implements JpaSelectionParticipant 
+{
+	final JpaStructureView structureView;
+	
+	
+	public JpaStructureSelectionParticipant(JpaSelectionManager selectionManager, JpaStructureView structureView) {
+		super();
+		this.structureView = structureView;
+		structureView.addSelectionChangedListener(new StructureViewSelectionListener(selectionManager, structureView));
+	}
+
+	public JpaSelection getSelection() {
+		return this.structureView.getJpaSelection();
+	}
+	
+	public void selectionChanged(JpaSelectionEvent evt) {
+		if (evt.getSource() != this) {
+			this.structureView.select(evt.getSelection());
+		}
+	}
+
+	public boolean disposeOnHide() {
+		return false;
+	}
+	
+	public void dispose() {
+		// NOP
+	}
+	
+
+	// ********** listener **********
+
+	private class StructureViewSelectionListener 
+		implements ISelectionChangedListener
+	{
+		private final JpaSelectionManager selectionManager;
+
+		StructureViewSelectionListener(JpaSelectionManager selectionManager, JpaStructureView structureView) {
+			super();
+			this.selectionManager = selectionManager;
+		}
+
+		public void selectionChanged(SelectionChangedEvent event) {
+			if (structureView.getViewSite().getWorkbenchWindow().getPartService().getActivePart() == structureView) {
+				selectionManager.select(this.structureViewSelection(), JpaStructureSelectionParticipant.this);
+			}
+		}
+
+		private JpaSelection structureViewSelection() {
+			return JpaStructureSelectionParticipant.this.structureView.getJpaSelection();
+		}
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/selection/SelectionManagerFactory.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/selection/SelectionManagerFactory.java
new file mode 100644
index 0000000..91283ac
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/selection/SelectionManagerFactory.java
@@ -0,0 +1,105 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2009 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.ui.internal.selection;
+
+import java.util.HashMap;
+import java.util.Map;
+import org.eclipse.ui.IWindowListener;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.PlatformUI;
+
+public class SelectionManagerFactory
+{
+	private static volatile SelectionManagerFactory INSTANCE;
+
+	private static Object MUTEX = new Object();
+
+
+	/**
+	 * Each <code>IWorkbenchWindow</code> has its own <code>JpaSelectionManager</code>
+	 * to track the selection events in the <code>IWorkbenchWindow</code>. All
+	 * <code>ISelectionListener</code>s in the same <code>IWorkbenchWindow</code>
+	 * share the same <code>JpaSelectionManager</code>.
+	 *
+	 * @return The <code>JpaSelectionManager</code> associated with the current
+	 * <code>IWorkbenchWindow</code>
+	 */
+	public static JpaSelectionManager getSelectionManager(IWorkbenchWindow window) {
+		if (INSTANCE == null) {
+			// this is thread safe for now. you never know whats comming
+			synchronized (MUTEX) {
+				if(INSTANCE == null) {
+					INSTANCE = new SelectionManagerFactory();
+					// if we do the init inside the constructor we end up in a loop
+					// because the addWindowListener(this) does a callback to us
+					INSTANCE.init();
+				}
+			}
+		}
+		return INSTANCE.internalGetSelectionManager(window);
+	}
+
+
+	Map<IWorkbenchWindow, DefaultJpaSelectionManager> managers;
+
+	private WindowListener windowListener;
+
+
+	private SelectionManagerFactory() {
+		managers = new HashMap<IWorkbenchWindow, DefaultJpaSelectionManager>();
+		windowListener = new WindowListener();
+	}
+
+	private void init() {
+		IWorkbench workbench = PlatformUI.getWorkbench();
+		workbench.addWindowListener(windowListener);
+	}
+
+	/**
+	 * Returns the JpaSelectionManager for the IWorkbenchWindow.
+	 * Creates a new one if none exists yet.
+	 */
+	DefaultJpaSelectionManager internalGetSelectionManager(IWorkbenchWindow window) {
+		if (window == null) {
+			throw new IllegalArgumentException("The IWorkbenchWindow cannot be null"); //$NON-NLS-1$
+		}
+
+		if (! managers.containsKey(window)) {
+			DefaultJpaSelectionManager manager = new DefaultJpaSelectionManager();
+			this.managers.put(window, manager);
+			manager.init(window);
+		}
+
+		return managers.get(window);
+	}
+
+
+	class WindowListener implements IWindowListener
+	{
+		public void windowOpened(IWorkbenchWindow aWindow) {
+			// do nothing
+		}
+
+		public void windowClosed(IWorkbenchWindow aWindow) {
+			DefaultJpaSelectionManager manager = internalGetSelectionManager(aWindow);
+			manager.dispose();
+			managers.remove(aWindow);
+		}
+
+		public void windowActivated(IWorkbenchWindow aWindow) {
+			// do nothing
+		}
+
+		public void windowDeactivated(IWorkbenchWindow aWindow) {
+			// do nothing
+		}
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/selection/TextEditorSelectionParticipant.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/selection/TextEditorSelectionParticipant.java
new file mode 100644
index 0000000..fa88212
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/selection/TextEditorSelectionParticipant.java
@@ -0,0 +1,224 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2012 Oracle and others. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0, which accompanies this distribution
+ * and is available at http://www.eclipse.org/legal/epl-v10.html.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *     IBM Corporation - modified to fix bug 377064
+ ******************************************************************************/
+package org.eclipse.jpt.ui.internal.selection;
+
+import org.eclipse.jface.text.ITextSelection;
+import org.eclipse.jface.viewers.IPostSelectionProvider;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.ISelectionProvider;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jpt.core.JpaFile;
+import org.eclipse.jpt.core.JpaStructureNode;
+import org.eclipse.jpt.core.JptCorePlugin;
+import org.eclipse.jpt.core.utility.TextRange;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IFileEditorInput;
+import org.eclipse.ui.IPropertyListener;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.texteditor.ITextEditor;
+
+public class TextEditorSelectionParticipant
+	implements JpaSelectionParticipant
+{
+	private final JpaSelectionManager selectionManager;
+
+	final ITextEditor textEditor;
+
+	private final IPropertyListener editorInputListener;
+
+	private final ISelectionChangedListener editorSelectionListener;
+
+	private JpaSelection currentSelection;
+
+	private boolean forwardSelection = true;  // TODO this just smells wrong  ~bjv
+
+
+	public TextEditorSelectionParticipant(JpaSelectionManager selectionManager, ITextEditor textEditor) {
+		super();
+		this.selectionManager = selectionManager;
+		this.textEditor = textEditor;
+		this.editorInputListener = new EditorInputListener();
+		this.textEditor.addPropertyListener(this.editorInputListener);
+		this.editorSelectionListener = new EditorSelectionListener();
+		IPostSelectionProvider postSelectionProvider = this.getPostSelectionProvider();
+		if (postSelectionProvider != null)
+			postSelectionProvider.addPostSelectionChangedListener(this.editorSelectionListener);
+		this.currentSelection = this.calculateSelection();
+	}
+
+	// ********** IJpaSelectionParticipant implementation **********
+
+	public JpaSelection getSelection() {
+		return this.currentSelection;
+	}
+
+	public void selectionChanged(JpaSelectionEvent evt) {
+		JpaSelection newSelection = evt.getSelection();
+
+		if ((newSelection == JpaSelection.NULL_SELECTION)
+			|| newSelection.equals(this.currentSelection)) {
+			return;
+		}
+
+		if (getActiveTextEditor() != this.textEditor) {
+			return;
+		}
+
+		this.forwardSelection = false;
+		TextRange textRange = newSelection.getSelectedNode().getSelectionTextRange();
+		if (textRange != null) {
+			this.textEditor.selectAndReveal(textRange.getOffset(), textRange.getLength());
+			this.currentSelection = newSelection;
+		}
+		this.forwardSelection = true;
+	}
+
+	public boolean disposeOnHide() {
+		return true;
+	}
+
+	public void dispose() {
+		this.textEditor.removePropertyListener(this.editorInputListener);
+		IPostSelectionProvider postSelectionProvider = this.getPostSelectionProvider();
+		if (postSelectionProvider != null)
+			postSelectionProvider.removePostSelectionChangedListener(this.editorSelectionListener);
+	}
+
+
+	// ********** internal methods **********
+
+	protected JpaSelection calculateSelection() {
+		ISelection selection = this.textEditor.getSelectionProvider().getSelection();
+		if (! (selection instanceof ITextSelection)) {
+			return JpaSelection.NULL_SELECTION;
+		}
+
+		JpaFile jpaFile = this.getJpaFile();
+		if (jpaFile == null) {
+			return JpaSelection.NULL_SELECTION;
+		}
+
+		return this.buildSelection(jpaFile.getStructureNode(((ITextSelection) selection).getOffset()));
+	}
+
+	protected JpaSelection buildSelection(JpaStructureNode selectedNode) {
+		return (selectedNode == null) ? JpaSelection.NULL_SELECTION : new DefaultJpaSelection(selectedNode);
+	}
+
+	protected IWorkbenchPage getActivePage() {
+		return this.textEditor.getEditorSite().getWorkbenchWindow().getActivePage();
+	}
+	
+	protected IWorkbenchPart getActivePart() {
+		IWorkbenchPage activePage = getActivePage();
+		return (activePage == null) ? null: activePage.getActivePart();
+	}
+	
+	protected IEditorPart getActiveEditor() {
+		IWorkbenchPage activePage = getActivePage();
+		return (activePage == null) ? null: activePage.getActiveEditor();
+	}
+	
+	protected ITextEditor getActiveTextEditor() {
+		return getTextEditor(getActiveEditor());
+	}
+	
+	protected ITextEditor getTextEditor(IWorkbenchPart part) {
+		return (part == null) ? null : (ITextEditor) part.getAdapter(ITextEditor.class);
+	}
+	
+	protected JpaFile getJpaFile() {
+		IEditorInput input = this.textEditor.getEditorInput();
+		if ( ! (input instanceof IFileEditorInput)) {
+			return null;
+		}
+		return JptCorePlugin.getJpaFile(((IFileEditorInput) input).getFile());
+	}
+
+	protected IPostSelectionProvider getPostSelectionProvider() {
+		ISelectionProvider selectionProvider = this.textEditor.getSelectionProvider();
+		if (selectionProvider instanceof IPostSelectionProvider)
+			return (IPostSelectionProvider) selectionProvider;
+		return null;
+	}
+
+
+	// ********** listener callbacks **********
+
+	protected void editorInputChanged() {
+		this.selectionChanged();
+	}
+
+	protected void editorSelectionChanged(SelectionChangedEvent event) {
+		// This is a bit kludgey.  We check to see if the selection event 
+		// occurred when a participating part is active (and so, ostensibly,
+		// *because* of the participating part).  If so, we reselect the valid 
+		// text.
+		IWorkbenchPart activePart = getActivePart();
+		if (getTextEditor(activePart) != this.textEditor && this.selectionManager.isRegistered(activePart)) {
+			if (this.currentSelection.isEmpty()) {
+				return;
+			}
+			
+			this.forwardSelection = false;
+			TextRange textRange = this.currentSelection.getSelectedNode().getSelectionTextRange();
+			if (textRange != null) {
+				this.textEditor.selectAndReveal(textRange.getOffset(), textRange.getLength());
+			}
+			this.forwardSelection = true;
+			
+			return;
+		}
+		
+		this.selectionChanged();
+	}
+
+	protected void selectionChanged() {
+		JpaSelection newSelection = this.calculateSelection();
+		if (newSelection.equals(this.currentSelection)) {
+			return;
+		}
+		this.currentSelection = newSelection;
+		
+		if (this.forwardSelection) {
+			this.selectionManager.select(newSelection, this);
+		}
+	}
+
+
+	// ********** listeners **********
+
+	protected class EditorInputListener implements IPropertyListener {
+		protected EditorInputListener() {
+			super();
+		}
+		public void propertyChanged(Object source, int propId) {
+			if ((source == TextEditorSelectionParticipant.this.textEditor)
+						&& (propId == IEditorPart.PROP_INPUT)) {
+				TextEditorSelectionParticipant.this.editorInputChanged();
+			}
+		}
+	}
+
+
+	protected class EditorSelectionListener implements ISelectionChangedListener {
+		protected EditorSelectionListener() {
+			super();
+		}
+		public void selectionChanged(SelectionChangedEvent event) {
+			TextEditorSelectionParticipant.this.editorSelectionChanged(event);
+		}
+	}
+
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/selection/WorkbenchPartAdapterFactory.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/selection/WorkbenchPartAdapterFactory.java
new file mode 100644
index 0000000..daa9aa2
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/selection/WorkbenchPartAdapterFactory.java
@@ -0,0 +1,61 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2009 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.ui.internal.selection;
+
+import org.eclipse.core.runtime.IAdapterFactory;
+import org.eclipse.jpt.ui.internal.views.JpaDetailsView;
+import org.eclipse.jpt.ui.internal.views.structure.JpaStructureView;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.texteditor.ITextEditor;
+
+/**
+ * Factory to build adapters for a workbench part:
+ *   - JPA selection participant (if the editor part is a text editor etc.)
+ * 
+ * See org.eclipse.jpt.ui plugin.xml.
+ */
+public class WorkbenchPartAdapterFactory 
+	implements IAdapterFactory
+{
+	private static final Class<?>[] ADAPTER_LIST = new Class[] { JpaSelectionParticipant.class };
+
+	public Class<?>[] getAdapterList() {
+		return ADAPTER_LIST;
+	}
+
+	public Object getAdapter(Object adaptableObject, @SuppressWarnings("unchecked") Class adapterType) {
+		if (adaptableObject instanceof IWorkbenchPart) {
+			return this.getAdapter((IWorkbenchPart) adaptableObject, adapterType);
+		}
+		return null;
+	}
+
+	private Object getAdapter(IWorkbenchPart workbenchPart, Class<?> adapterType) {
+		if (adapterType == JpaSelectionParticipant.class) {
+			return this.buildJpaSelectionParticipant(workbenchPart);
+		}
+		return null;
+	}
+
+	private JpaSelectionParticipant buildJpaSelectionParticipant(IWorkbenchPart workbenchPart) {
+		JpaSelectionManager selectionManager = SelectionManagerFactory.getSelectionManager(workbenchPart.getSite().getWorkbenchWindow());
+		if (workbenchPart instanceof ITextEditor) {
+			return new TextEditorSelectionParticipant(selectionManager, (ITextEditor) workbenchPart);
+		}
+		if (workbenchPart instanceof JpaStructureView) {
+			return new JpaStructureSelectionParticipant(selectionManager, (JpaStructureView) workbenchPart);
+		}
+		if (workbenchPart instanceof JpaDetailsView) {
+			return new JpaDetailsSelectionParticipant((JpaDetailsView) workbenchPart);
+		}
+		return null;
+	}
+
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/structure/GeneralJpaMappingItemLabelProviderFactory.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/structure/GeneralJpaMappingItemLabelProviderFactory.java
new file mode 100644
index 0000000..26c0e98
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/structure/GeneralJpaMappingItemLabelProviderFactory.java
@@ -0,0 +1,33 @@
+/*******************************************************************************
+ * Copyright (c) 2008 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.ui.internal.structure;
+
+import org.eclipse.jpt.core.context.PersistentAttribute;
+import org.eclipse.jpt.core.context.PersistentType;
+import org.eclipse.jpt.ui.internal.platform.generic.PersistentAttributeItemLabelProvider;
+import org.eclipse.jpt.ui.internal.platform.generic.PersistentTypeItemLabelProvider;
+import org.eclipse.jpt.ui.jface.DelegatingContentAndLabelProvider;
+import org.eclipse.jpt.ui.jface.ItemLabelProvider;
+import org.eclipse.jpt.ui.jface.ItemLabelProviderFactory;
+
+public abstract class GeneralJpaMappingItemLabelProviderFactory
+	implements ItemLabelProviderFactory
+{
+	public ItemLabelProvider buildItemLabelProvider(
+			Object item, DelegatingContentAndLabelProvider labelProvider) {
+		if (item instanceof PersistentType) {
+			return new PersistentTypeItemLabelProvider((PersistentType) item, labelProvider);
+		}
+		else if (item instanceof PersistentAttribute) {
+			return new PersistentAttributeItemLabelProvider((PersistentAttribute) item, labelProvider);
+		}
+		return null;
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/structure/JavaItemContentProviderFactory.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/structure/JavaItemContentProviderFactory.java
new file mode 100644
index 0000000..ad94b18
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/structure/JavaItemContentProviderFactory.java
@@ -0,0 +1,39 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2009 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.ui.internal.structure;
+
+import org.eclipse.jpt.core.JpaFile;
+import org.eclipse.jpt.core.context.java.JavaPersistentAttribute;
+import org.eclipse.jpt.core.context.java.JavaPersistentType;
+import org.eclipse.jpt.ui.internal.jface.DelegatingTreeContentAndLabelProvider;
+import org.eclipse.jpt.ui.internal.platform.generic.JavaPersistentTypeItemContentProvider;
+import org.eclipse.jpt.ui.internal.platform.generic.PersistentAttributeItemContentProvider;
+import org.eclipse.jpt.ui.jface.DelegatingContentAndLabelProvider;
+import org.eclipse.jpt.ui.jface.TreeItemContentProvider;
+import org.eclipse.jpt.ui.jface.TreeItemContentProviderFactory;
+
+
+public class JavaItemContentProviderFactory implements TreeItemContentProviderFactory
+{
+	public TreeItemContentProvider buildItemContentProvider(
+			Object item, DelegatingContentAndLabelProvider contentProvider) {
+		DelegatingTreeContentAndLabelProvider treeContentProvider = (DelegatingTreeContentAndLabelProvider) contentProvider;
+		if (item instanceof JpaFile) {
+			return new ResourceModelItemContentProvider((JpaFile) item, treeContentProvider);
+		}
+		if (item instanceof JavaPersistentType) {
+			return new JavaPersistentTypeItemContentProvider((JavaPersistentType) item, treeContentProvider);
+		}
+		if (item instanceof JavaPersistentAttribute) {
+			return new PersistentAttributeItemContentProvider((JavaPersistentAttribute) item, treeContentProvider);
+		}
+		return null;
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/structure/JavaItemLabelProviderFactory.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/structure/JavaItemLabelProviderFactory.java
new file mode 100644
index 0000000..ec78498
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/structure/JavaItemLabelProviderFactory.java
@@ -0,0 +1,17 @@
+/*******************************************************************************
+ *  Copyright (c) 2007, 2008 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.ui.internal.structure;
+
+
+public class JavaItemLabelProviderFactory extends GeneralJpaMappingItemLabelProviderFactory
+{
+	
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/structure/JavaResourceModelStructureProvider.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/structure/JavaResourceModelStructureProvider.java
new file mode 100644
index 0000000..b0b5cd4
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/structure/JavaResourceModelStructureProvider.java
@@ -0,0 +1,45 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2009 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.ui.internal.structure;
+
+import org.eclipse.jpt.ui.jface.ItemLabelProviderFactory;
+import org.eclipse.jpt.ui.jface.TreeItemContentProviderFactory;
+import org.eclipse.jpt.ui.structure.JpaStructureProvider;
+
+public class JavaResourceModelStructureProvider
+	implements JpaStructureProvider
+{
+	// singleton
+	private static final JpaStructureProvider INSTANCE = new JavaResourceModelStructureProvider();
+	
+	
+	/**
+	 * Return the singleton
+	 */
+	public static JpaStructureProvider instance() {
+		return INSTANCE;
+	}
+	
+	
+	/**
+	 * Enforce singleton usage
+	 */
+	private JavaResourceModelStructureProvider() {
+		super();
+	}
+	
+	public TreeItemContentProviderFactory getTreeItemContentProviderFactory() {
+		return new JavaItemContentProviderFactory();
+	}
+	
+	public ItemLabelProviderFactory getItemLabelProviderFactory() {
+		return new JavaItemLabelProviderFactory();
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/structure/OrmItemContentProviderFactory.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/structure/OrmItemContentProviderFactory.java
new file mode 100644
index 0000000..f6aae14
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/structure/OrmItemContentProviderFactory.java
@@ -0,0 +1,79 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2009 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.ui.internal.structure;
+
+import org.eclipse.jpt.core.JpaFile;
+import org.eclipse.jpt.core.context.orm.EntityMappings;
+import org.eclipse.jpt.core.context.orm.OrmPersistentAttribute;
+import org.eclipse.jpt.core.context.orm.OrmPersistentType;
+import org.eclipse.jpt.ui.internal.jface.AbstractTreeItemContentProvider;
+import org.eclipse.jpt.ui.internal.jface.DelegatingTreeContentAndLabelProvider;
+import org.eclipse.jpt.ui.internal.platform.generic.OrmPersistentTypeItemContentProvider;
+import org.eclipse.jpt.ui.internal.platform.generic.PersistentAttributeItemContentProvider;
+import org.eclipse.jpt.ui.jface.DelegatingContentAndLabelProvider;
+import org.eclipse.jpt.ui.jface.TreeItemContentProvider;
+import org.eclipse.jpt.ui.jface.TreeItemContentProviderFactory;
+import org.eclipse.jpt.utility.internal.iterables.ListIterable;
+import org.eclipse.jpt.utility.internal.model.value.ListAspectAdapter;
+import org.eclipse.jpt.utility.internal.model.value.ListCollectionValueModelAdapter;
+import org.eclipse.jpt.utility.model.value.CollectionValueModel;
+
+public class OrmItemContentProviderFactory implements TreeItemContentProviderFactory
+{
+	public TreeItemContentProvider buildItemContentProvider(
+			Object item, DelegatingContentAndLabelProvider contentProvider) {
+		DelegatingTreeContentAndLabelProvider treeContentProvider = (DelegatingTreeContentAndLabelProvider) contentProvider;
+		if (item instanceof JpaFile) {
+			return new ResourceModelItemContentProvider((JpaFile) item, treeContentProvider);
+		}
+		if (item instanceof EntityMappings) {
+			return new EntityMappingsItemContentProvider((EntityMappings) item, treeContentProvider);
+		}
+		if (item instanceof OrmPersistentType) {
+			return new OrmPersistentTypeItemContentProvider((OrmPersistentType) item, treeContentProvider);
+		}
+		if (item instanceof OrmPersistentAttribute) {
+			return new PersistentAttributeItemContentProvider((OrmPersistentAttribute) item, treeContentProvider);
+		}
+		return null;
+	}
+	
+	public static class EntityMappingsItemContentProvider extends AbstractTreeItemContentProvider<OrmPersistentType>
+	{
+		public EntityMappingsItemContentProvider(
+				EntityMappings entityMappings, DelegatingTreeContentAndLabelProvider contentProvider) {
+			super(entityMappings, contentProvider);
+		}
+		
+		@Override
+		public EntityMappings getModel() {
+			return (EntityMappings) super.getModel();
+		}
+		
+		@Override
+		public Object getParent() {
+			// I'd like to return the resource model here, but that involves a hefty 
+			// API change - we'll see what happens with this code first
+			return null;
+		}
+		
+		@Override
+		protected CollectionValueModel<OrmPersistentType> buildChildrenModel() {
+			return new ListCollectionValueModelAdapter<OrmPersistentType>(
+			new ListAspectAdapter<EntityMappings, OrmPersistentType>(
+					EntityMappings.PERSISTENT_TYPES_LIST, getModel()) {
+				@Override
+				protected ListIterable<OrmPersistentType> getListIterable() {
+					return this.subject.getPersistentTypes();
+				}
+			});
+		}
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/structure/OrmItemLabelProviderFactory.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/structure/OrmItemLabelProviderFactory.java
new file mode 100644
index 0000000..842728d
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/structure/OrmItemLabelProviderFactory.java
@@ -0,0 +1,27 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2008 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.ui.internal.structure;
+
+import org.eclipse.jpt.core.context.orm.EntityMappings;
+import org.eclipse.jpt.ui.internal.platform.generic.EntityMappingsItemLabelProvider;
+import org.eclipse.jpt.ui.jface.DelegatingContentAndLabelProvider;
+import org.eclipse.jpt.ui.jface.ItemLabelProvider;
+
+public class OrmItemLabelProviderFactory extends GeneralJpaMappingItemLabelProviderFactory
+{
+	@Override
+	public ItemLabelProvider buildItemLabelProvider(
+			Object item, DelegatingContentAndLabelProvider labelProvider) {
+		if (item instanceof EntityMappings) {
+			return new EntityMappingsItemLabelProvider((EntityMappings) item, labelProvider);
+		}
+		return super.buildItemLabelProvider(item, labelProvider);
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/structure/OrmResourceModelStructureProvider.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/structure/OrmResourceModelStructureProvider.java
new file mode 100644
index 0000000..c0aa373
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/structure/OrmResourceModelStructureProvider.java
@@ -0,0 +1,46 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2009 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.ui.internal.structure;
+
+import org.eclipse.jpt.ui.jface.ItemLabelProviderFactory;
+import org.eclipse.jpt.ui.jface.TreeItemContentProviderFactory;
+import org.eclipse.jpt.ui.structure.JpaStructureProvider;
+
+public class OrmResourceModelStructureProvider
+	implements JpaStructureProvider
+{
+	// singleton
+	private static final JpaStructureProvider INSTANCE = new OrmResourceModelStructureProvider();
+	
+	
+	/**
+	 * Return the singleton
+	 */
+	public static JpaStructureProvider instance() {
+		return INSTANCE;
+	}
+	
+	
+	/**
+	 * Enforce singleton usage
+	 */
+	private OrmResourceModelStructureProvider() {
+		super();
+	}
+	
+	
+	public TreeItemContentProviderFactory getTreeItemContentProviderFactory() {
+		return new OrmItemContentProviderFactory();
+	}
+	
+	public ItemLabelProviderFactory getItemLabelProviderFactory() {
+		return new OrmItemLabelProviderFactory();
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/structure/PersistenceItemContentProviderFactory.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/structure/PersistenceItemContentProviderFactory.java
new file mode 100644
index 0000000..2e012fd
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/structure/PersistenceItemContentProviderFactory.java
@@ -0,0 +1,271 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2009 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.ui.internal.structure;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+import org.eclipse.jpt.core.JpaFile;
+import org.eclipse.jpt.core.JpaStructureNode;
+import org.eclipse.jpt.core.context.persistence.ClassRef;
+import org.eclipse.jpt.core.context.persistence.JarFileRef;
+import org.eclipse.jpt.core.context.persistence.MappingFileRef;
+import org.eclipse.jpt.core.context.persistence.Persistence;
+import org.eclipse.jpt.core.context.persistence.PersistenceUnit;
+import org.eclipse.jpt.ui.internal.jface.AbstractTreeItemContentProvider;
+import org.eclipse.jpt.ui.internal.jface.DelegatingTreeContentAndLabelProvider;
+import org.eclipse.jpt.ui.jface.DelegatingContentAndLabelProvider;
+import org.eclipse.jpt.ui.jface.TreeItemContentProvider;
+import org.eclipse.jpt.ui.jface.TreeItemContentProviderFactory;
+import org.eclipse.jpt.utility.internal.model.value.CollectionAspectAdapter;
+import org.eclipse.jpt.utility.internal.model.value.CollectionListValueModelAdapter;
+import org.eclipse.jpt.utility.internal.model.value.CompositeListValueModel;
+import org.eclipse.jpt.utility.internal.model.value.ListAspectAdapter;
+import org.eclipse.jpt.utility.internal.model.value.ListCollectionValueModelAdapter;
+import org.eclipse.jpt.utility.internal.model.value.PropertyAspectAdapter;
+import org.eclipse.jpt.utility.internal.model.value.PropertyListValueModelAdapter;
+import org.eclipse.jpt.utility.model.value.CollectionValueModel;
+import org.eclipse.jpt.utility.model.value.ListValueModel;
+
+public class PersistenceItemContentProviderFactory
+	implements TreeItemContentProviderFactory
+{
+	public TreeItemContentProvider buildItemContentProvider(
+			Object item, DelegatingContentAndLabelProvider contentAndLabelProvider) {
+		DelegatingTreeContentAndLabelProvider treeContentProvider = (DelegatingTreeContentAndLabelProvider) contentAndLabelProvider;
+		if (item instanceof JpaFile) {
+			return new ResourceModelItemContentProvider((JpaFile) item, treeContentProvider);
+		}
+		else if (item instanceof Persistence) {
+			return new PersistenceItemContentProvider((Persistence) item, treeContentProvider);
+		}
+		else if (item instanceof PersistenceUnit) {
+			return new PersistenceUnitItemContentProvider((PersistenceUnit) item, treeContentProvider);	
+		}
+		else if (item instanceof MappingFileRef) {
+			return new MappingFileRefItemContentProvider((MappingFileRef) item, treeContentProvider);	
+		}
+		else if (item instanceof ClassRef) {
+			return new ClassRefItemContentProvider((ClassRef) item, treeContentProvider);	
+		}
+		else if (item instanceof JarFileRef) {
+			return new JarFileRefItemContentProvider((JarFileRef) item, treeContentProvider);
+		}
+		return null;
+	}
+	
+	
+	public static class PersistenceItemContentProvider extends AbstractTreeItemContentProvider<PersistenceUnit>
+	{
+		public PersistenceItemContentProvider(
+				Persistence persistence, DelegatingTreeContentAndLabelProvider contentProvider) {
+			super(persistence, contentProvider);
+		}
+			
+		@Override
+		public Persistence getModel() {
+			return (Persistence) super.getModel();
+		}
+		
+		@Override
+		public Object getParent() {
+			// I'd like to return the resource model here, but that involves a hefty 
+			// API change - we'll see what happens with this code first
+			return null;
+		}
+		
+		@Override
+		protected CollectionValueModel<PersistenceUnit> buildChildrenModel() {
+			return new ListCollectionValueModelAdapter<PersistenceUnit>(
+			new ListAspectAdapter<Persistence, PersistenceUnit>(Persistence.PERSISTENCE_UNITS_LIST, getModel()) {
+				@Override
+				protected ListIterator<PersistenceUnit> listIterator_() {
+					return subject.persistenceUnits();
+				}
+				@Override
+				protected int size_() {
+					return subject.persistenceUnitsSize();
+				}
+			});
+		}
+	}
+	
+	
+	public static class PersistenceUnitItemContentProvider extends AbstractTreeItemContentProvider<JpaStructureNode>
+	{
+		public PersistenceUnitItemContentProvider(
+				PersistenceUnit persistenceUnit, DelegatingTreeContentAndLabelProvider contentProvider) {
+			super(persistenceUnit, contentProvider);
+		}
+		
+		@Override
+		public PersistenceUnit getModel() {
+			return (PersistenceUnit) super.getModel();
+		}
+		
+		@Override
+		public Persistence getParent() {
+			return getModel().getParent();
+		}
+		
+		@Override
+		protected CollectionValueModel<JpaStructureNode> buildChildrenModel() {
+			ListValueModel<MappingFileRef> specifiedMappingFileLvm = 
+				new ListAspectAdapter<PersistenceUnit, MappingFileRef>(
+						PersistenceUnit.SPECIFIED_MAPPING_FILE_REFS_LIST,
+						getModel()) {
+					@Override
+					protected ListIterator<MappingFileRef> listIterator_() {
+						return subject.specifiedMappingFileRefs();
+					}
+					@Override
+					protected int size_() {
+						return subject.specifiedMappingFileRefsSize();
+					}
+				};
+			
+			ListValueModel<MappingFileRef> impliedMappingFileCvm = 
+				new PropertyListValueModelAdapter<MappingFileRef>(
+					new PropertyAspectAdapter<PersistenceUnit, MappingFileRef>(
+							PersistenceUnit.IMPLIED_MAPPING_FILE_REF_PROPERTY,
+							getModel()) {
+						@Override
+						protected MappingFileRef buildValue_() {
+							return subject.getImpliedMappingFileRef();
+						}
+					}
+				);
+			ListValueModel<ClassRef> specifiedClassCvm = 
+				new ListAspectAdapter<PersistenceUnit, ClassRef>(
+						PersistenceUnit.SPECIFIED_CLASS_REFS_LIST,
+						getModel()) {
+					@Override
+					protected ListIterator<ClassRef> listIterator_() {
+						return subject.specifiedClassRefs();
+					}
+					@Override
+					protected int size_() {
+						return subject.specifiedClassRefsSize();
+					}
+				};
+			ListValueModel<ClassRef> impliedClassCvm = 
+				new CollectionListValueModelAdapter<ClassRef>(
+					new CollectionAspectAdapter<PersistenceUnit, ClassRef>(
+							PersistenceUnit.IMPLIED_CLASS_REFS_COLLECTION,
+							getModel()) {
+						@Override
+						protected Iterator<ClassRef> iterator_() {
+							return subject.impliedClassRefs();
+						}
+						@Override
+						protected int size_() {
+							return subject.impliedClassRefsSize();
+						}
+					});
+			ListValueModel<JarFileRef> jarFileCvm =
+				new ListAspectAdapter<PersistenceUnit, JarFileRef>(
+						PersistenceUnit.JAR_FILE_REFS_LIST,
+						getModel()) {
+					@Override
+					protected ListIterator<JarFileRef> listIterator_() {
+						return subject.jarFileRefs();
+					}
+					@Override
+					protected int size_() {
+						return subject.jarFileRefsSize();
+					}
+				};
+			List<ListValueModel<? extends JpaStructureNode>> list = new ArrayList<ListValueModel<? extends JpaStructureNode>>(4);
+			list.add(specifiedMappingFileLvm);
+			list.add(impliedMappingFileCvm);
+			list.add(specifiedClassCvm);
+			list.add(impliedClassCvm);
+			list.add(jarFileCvm);
+			
+			return new ListCollectionValueModelAdapter<JpaStructureNode>(
+				new CompositeListValueModel
+					<ListValueModel<? extends JpaStructureNode>, JpaStructureNode>
+						(list));
+		}
+	}
+	
+	
+	public static class MappingFileRefItemContentProvider extends AbstractTreeItemContentProvider<MappingFileRef>
+	{
+		public MappingFileRefItemContentProvider(
+				MappingFileRef mappingFileRef, DelegatingTreeContentAndLabelProvider contentProvider) {
+			super(mappingFileRef, contentProvider);
+		}
+		
+		@Override
+		public MappingFileRef getModel() {
+			return (MappingFileRef) super.getModel();
+		}
+		
+		@Override
+		public Object getParent() {
+			return getModel().getPersistenceUnit();
+		}
+		
+		@Override
+		public boolean hasChildren() {
+			return false;
+		}
+	}
+	
+	
+	public static class ClassRefItemContentProvider extends AbstractTreeItemContentProvider<ClassRef>
+	{
+		public ClassRefItemContentProvider(
+				ClassRef classRef, DelegatingTreeContentAndLabelProvider contentProvider) {
+			super(classRef, contentProvider);
+		}
+		
+		@Override
+		public ClassRef getModel() {
+			return (ClassRef) super.getModel();
+		}
+		
+		@Override
+		public Object getParent() {
+			return getModel().getPersistenceUnit();
+		}
+		
+		@Override
+		public boolean hasChildren() {
+			return false;
+		}
+	}
+	
+	
+	public static class JarFileRefItemContentProvider extends AbstractTreeItemContentProvider<JarFileRef>
+	{
+		public JarFileRefItemContentProvider(
+				JarFileRef jarFileRef, DelegatingTreeContentAndLabelProvider contentProvider) {
+			super(jarFileRef, contentProvider);
+		}
+		
+		@Override
+		public JarFileRef getModel() {
+			return (JarFileRef) super.getModel();
+		}
+		
+		@Override
+		public Object getParent() {
+			return getModel().getPersistenceUnit();
+		}
+		
+		@Override
+		public boolean hasChildren() {
+			return false;
+		}
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/structure/PersistenceItemLabelProviderFactory.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/structure/PersistenceItemLabelProviderFactory.java
new file mode 100644
index 0000000..1212998
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/structure/PersistenceItemLabelProviderFactory.java
@@ -0,0 +1,48 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2009 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.ui.internal.structure;
+
+import org.eclipse.jpt.core.context.persistence.ClassRef;
+import org.eclipse.jpt.core.context.persistence.JarFileRef;
+import org.eclipse.jpt.core.context.persistence.MappingFileRef;
+import org.eclipse.jpt.core.context.persistence.Persistence;
+import org.eclipse.jpt.core.context.persistence.PersistenceUnit;
+import org.eclipse.jpt.ui.internal.platform.generic.ClassRefItemLabelProvider;
+import org.eclipse.jpt.ui.internal.platform.generic.JarFileRefItemLabelProvider;
+import org.eclipse.jpt.ui.internal.platform.generic.MappingFileRefItemLabelProvider;
+import org.eclipse.jpt.ui.internal.platform.generic.PersistenceItemLabelProvider;
+import org.eclipse.jpt.ui.internal.platform.generic.PersistenceUnitItemLabelProvider;
+import org.eclipse.jpt.ui.jface.DelegatingContentAndLabelProvider;
+import org.eclipse.jpt.ui.jface.ItemLabelProvider;
+import org.eclipse.jpt.ui.jface.ItemLabelProviderFactory;
+
+public class PersistenceItemLabelProviderFactory
+	implements ItemLabelProviderFactory
+{
+	public ItemLabelProvider buildItemLabelProvider(
+			Object item, DelegatingContentAndLabelProvider contentAndLabelProvider) {
+		if (item instanceof Persistence) {
+			return new PersistenceItemLabelProvider((Persistence) item, contentAndLabelProvider);
+		}
+		else if (item instanceof PersistenceUnit) {
+			return new PersistenceUnitItemLabelProvider((PersistenceUnit) item, contentAndLabelProvider);	
+		}
+		else if (item instanceof MappingFileRef) {
+			return new MappingFileRefItemLabelProvider((MappingFileRef) item, contentAndLabelProvider);	
+		}
+		else if (item instanceof ClassRef) {
+			return new ClassRefItemLabelProvider((ClassRef) item, contentAndLabelProvider);	
+		}
+		else if (item instanceof JarFileRef) {
+			return new JarFileRefItemLabelProvider((JarFileRef) item, contentAndLabelProvider);
+		}
+		return null;
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/structure/PersistenceResourceModelStructureProvider.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/structure/PersistenceResourceModelStructureProvider.java
new file mode 100644
index 0000000..d9d1945
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/structure/PersistenceResourceModelStructureProvider.java
@@ -0,0 +1,46 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2009 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.ui.internal.structure;
+
+import org.eclipse.jpt.ui.jface.ItemLabelProviderFactory;
+import org.eclipse.jpt.ui.jface.TreeItemContentProviderFactory;
+import org.eclipse.jpt.ui.structure.JpaStructureProvider;
+
+public class PersistenceResourceModelStructureProvider
+	implements JpaStructureProvider
+{
+	// singleton
+	private static final JpaStructureProvider INSTANCE = new PersistenceResourceModelStructureProvider();
+	
+	
+	/**
+	 * Return the singleton
+	 */
+	public static JpaStructureProvider instance() {
+		return INSTANCE;
+	}
+	
+	
+	/**
+	 * Enforce singleton usage
+	 */
+	private PersistenceResourceModelStructureProvider() {
+		super();
+	}
+	
+	
+	public TreeItemContentProviderFactory getTreeItemContentProviderFactory() {
+		return new PersistenceItemContentProviderFactory();
+	}
+	
+	public ItemLabelProviderFactory getItemLabelProviderFactory() {
+		return new PersistenceItemLabelProviderFactory();
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/structure/ResourceModelItemContentProvider.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/structure/ResourceModelItemContentProvider.java
new file mode 100644
index 0000000..e9dd728
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/structure/ResourceModelItemContentProvider.java
@@ -0,0 +1,55 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2009 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.ui.internal.structure;
+
+import java.util.Iterator;
+
+import org.eclipse.jpt.core.JpaFile;
+import org.eclipse.jpt.core.JpaStructureNode;
+import org.eclipse.jpt.ui.internal.jface.AbstractTreeItemContentProvider;
+import org.eclipse.jpt.ui.internal.jface.DelegatingTreeContentAndLabelProvider;
+import org.eclipse.jpt.utility.internal.model.value.CollectionAspectAdapter;
+import org.eclipse.jpt.utility.internal.model.value.SimplePropertyValueModel;
+import org.eclipse.jpt.utility.model.value.CollectionValueModel;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+
+public class ResourceModelItemContentProvider extends AbstractTreeItemContentProvider<JpaStructureNode>
+{
+	public ResourceModelItemContentProvider(
+			JpaFile jpaFile, 
+			DelegatingTreeContentAndLabelProvider contentProvider) {
+		super(jpaFile, contentProvider);
+	}
+	
+	@Override
+	public Object getParent() {
+		return null;
+	}
+	
+	@Override
+	public JpaFile getModel() {
+		return (JpaFile) super.getModel();
+	}
+	
+	@Override
+	protected CollectionValueModel<JpaStructureNode> buildChildrenModel() {
+		return new CollectionAspectAdapter<JpaFile, JpaStructureNode>(
+			buildJpaFileValueModel(), JpaFile.ROOT_STRUCTURE_NODES_COLLECTION) {
+			@Override
+			protected Iterator<JpaStructureNode> iterator_() {
+				return subject.rootStructureNodes();
+			}
+		};
+	}
+	
+	protected PropertyValueModel<JpaFile> buildJpaFileValueModel() {
+		return new SimplePropertyValueModel<JpaFile>(this.getModel());
+	}
+}
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/swt/AbstractComboModelAdapter.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/swt/AbstractComboModelAdapter.java
new file mode 100644
index 0000000..6d4a3cd
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/swt/AbstractComboModelAdapter.java
@@ -0,0 +1,699 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2010 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.ui.internal.swt;
+
+import java.util.EventListener;
+import java.util.EventObject;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.jpt.ui.internal.listeners.SWTListChangeListenerWrapper;
+import org.eclipse.jpt.ui.internal.listeners.SWTPropertyChangeListenerWrapper;
+import org.eclipse.jpt.utility.internal.ArrayTools;
+import org.eclipse.jpt.utility.internal.ListenerList;
+import org.eclipse.jpt.utility.internal.StringConverter;
+import org.eclipse.jpt.utility.internal.StringTools;
+import org.eclipse.jpt.utility.model.event.ListAddEvent;
+import org.eclipse.jpt.utility.model.event.ListChangeEvent;
+import org.eclipse.jpt.utility.model.event.ListClearEvent;
+import org.eclipse.jpt.utility.model.event.ListMoveEvent;
+import org.eclipse.jpt.utility.model.event.ListRemoveEvent;
+import org.eclipse.jpt.utility.model.event.ListReplaceEvent;
+import org.eclipse.jpt.utility.model.event.PropertyChangeEvent;
+import org.eclipse.jpt.utility.model.listener.ListChangeListener;
+import org.eclipse.jpt.utility.model.listener.PropertyChangeListener;
+import org.eclipse.jpt.utility.model.value.ListValueModel;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.jpt.utility.model.value.WritablePropertyValueModel;
+import org.eclipse.swt.events.DisposeEvent;
+import org.eclipse.swt.events.DisposeListener;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+
+/**
+ * This adapter provides a more object-oriented interface to the items and
+ * selected item in a combo.
+ * <p>
+ * <b>listHolder</b> contains the items in the combo.<br>
+ * <b>selectedItemHolder</b> contains the items in 'listHolder' that are
+ * selected in the combo.
+ *
+ * @param <E> The type of the items in <b>listHolder</b>
+ * @see ComboModelAdapter
+ * @see CComboModelAdapter
+ *
+ * @version 2.0
+ * @since 2.0
+ */
+@SuppressWarnings("nls")
+public abstract class AbstractComboModelAdapter<E> {
+
+	// ********** model **********
+	/**
+	 * A value model on the underlying model list.
+	 */
+	protected final ListValueModel<E> listHolder;
+
+	/**
+	 * A listener that allows us to synchronize the combo's contents with
+	 * the model list.
+	 */
+	protected final ListChangeListener listChangeListener;
+
+	/**
+	 * A value model on the underlying model selection.
+	 */
+	protected final WritablePropertyValueModel<E> selectedItemHolder;
+
+	/**
+	 * A listener that allows us to synchronize the combo's selection with the
+	 * model selection.
+	 */
+	protected final PropertyChangeListener selectedItemChangeListener;
+
+	/**
+	 * A converter that converts items in the model list
+	 * to strings that can be put in the combo.
+	 */
+	protected StringConverter<E> stringConverter;
+
+	// ********** UI **********
+	/**
+	 * The combo we keep synchronized with the model list.
+	 */
+	protected final ComboHolder comboHolder;
+
+	/**
+	 * A listener that allows us to synchronize our selection list holder
+	 * with the combo's text.
+	 */
+	protected ModifyListener comboModifyListener;
+
+	/**
+	 * A listener that allows us to synchronize our selection list holder
+	 * with the combo's selection.
+	 */
+	protected SelectionListener comboSelectionListener;
+
+	/**
+	 * Clients that are interested in selection change events.
+	 */
+	@SuppressWarnings("unchecked")
+	protected final ListenerList<SelectionChangeListener> selectionChangeListenerList;
+
+	/**
+	 * Clients that are interested in double click events.
+	 */
+	@SuppressWarnings("unchecked")
+	protected final ListenerList<DoubleClickListener> doubleClickListenerList;
+
+	/**
+	 * A listener that allows us to stop listening to stuff when the combo
+	 * is disposed.
+	 */
+	protected final DisposeListener comboDisposeListener;
+
+
+	// ********** constructors **********
+
+	/**
+	 * Constructor - the list holder, selections holder, combo, and
+	 * string converter are required.
+	 */
+	protected AbstractComboModelAdapter(
+			ListValueModel<E> listHolder,
+			WritablePropertyValueModel<E> selectedItemHolder,
+			ComboHolder comboHolder,
+			StringConverter<E> stringConverter)
+	{
+		super();
+
+		Assert.isNotNull(listHolder,         "The holder of the items");
+		Assert.isNotNull(selectedItemHolder, "The holder of the selected item cannot be null");
+		Assert.isNotNull(comboHolder,        "The holder of the combo widget cannot be null");
+		Assert.isNotNull(stringConverter,    "The string converter cannot be null");
+
+		this.listHolder         = listHolder;
+		this.selectedItemHolder = selectedItemHolder;
+		this.comboHolder        = comboHolder;
+		this.stringConverter    = stringConverter;
+
+		this.listChangeListener = this.buildListChangeListener();
+		this.listHolder.addListChangeListener(ListValueModel.LIST_VALUES, this.listChangeListener);
+
+		this.selectedItemChangeListener = this.buildSelectedItemChangeListener();
+		this.selectedItemHolder.addPropertyChangeListener(PropertyValueModel.VALUE, this.selectedItemChangeListener);
+
+		if (this.comboHolder.isEditable()) {
+			this.comboModifyListener = this.buildComboModifyListener();
+			this.comboHolder.addModifyListener(this.comboModifyListener);
+		}
+		else {
+			this.comboSelectionListener = this.buildComboSelectionListener();
+			this.comboHolder.addSelectionListener(this.comboSelectionListener);
+		}
+
+		this.selectionChangeListenerList = this.buildSelectionChangeListenerList();
+		this.doubleClickListenerList = this.buildDoubleClickListenerList();
+
+		this.comboDisposeListener = this.buildComboDisposeListener();
+		this.comboHolder.addDisposeListener(this.comboDisposeListener);
+
+		this.synchronizeCombo();
+	}
+
+
+	// ********** initialization **********
+
+	protected ListChangeListener buildListChangeListener() {
+		return new SWTListChangeListenerWrapper(this.buildListChangeListener_());
+	}
+
+	protected ListChangeListener buildListChangeListener_() {
+		return new ListChangeListener() {
+			public void itemsAdded(ListAddEvent event) {
+				AbstractComboModelAdapter.this.listItemsAdded(event);
+			}
+			public void itemsRemoved(ListRemoveEvent event) {
+				AbstractComboModelAdapter.this.listItemsRemoved(event);
+			}
+			public void itemsMoved(ListMoveEvent event) {
+				AbstractComboModelAdapter.this.listItemsMoved(event);
+			}
+			public void itemsReplaced(ListReplaceEvent event) {
+				AbstractComboModelAdapter.this.listItemsReplaced(event);
+			}
+			public void listCleared(ListClearEvent event) {
+				AbstractComboModelAdapter.this.listCleared(event);
+			}
+			public void listChanged(ListChangeEvent event) {
+				AbstractComboModelAdapter.this.listChanged(event);
+			}
+			@Override
+			public String toString() {
+				return "list listener";
+			}
+		};
+	}
+
+	protected PropertyChangeListener buildSelectedItemChangeListener() {
+		return new SWTPropertyChangeListenerWrapper(this.buildSelectedItemChangeListener_());
+	}
+
+	protected PropertyChangeListener buildSelectedItemChangeListener_() {
+		return new PropertyChangeListener() {
+			public void propertyChanged(PropertyChangeEvent e) {
+				AbstractComboModelAdapter.this.selectedItemChanged(e);
+			}
+		};
+	}
+
+	protected ModifyListener buildComboModifyListener() {
+		return new ModifyListener() {
+			public void modifyText(ModifyEvent event) {
+				AbstractComboModelAdapter.this.comboSelectionChanged(event);
+			}
+
+			@Override
+			public String toString() {
+				return "combo modify listener";
+			}
+		};
+	}
+
+	protected SelectionListener buildComboSelectionListener() {
+		return new SelectionAdapter() {
+			@Override
+			public void widgetSelected(SelectionEvent event) {
+				AbstractComboModelAdapter.this.comboSelectionChanged(event);
+			}
+
+			@Override
+			public String toString() {
+				return "combo modify listener";
+			}
+		};
+	}
+
+	@SuppressWarnings("unchecked")
+	protected ListenerList<DoubleClickListener> buildDoubleClickListenerList() {
+		return new ListenerList<DoubleClickListener>(DoubleClickListener.class);
+	}
+
+	@SuppressWarnings("unchecked")
+	protected ListenerList<SelectionChangeListener> buildSelectionChangeListenerList() {
+		return new ListenerList<SelectionChangeListener>(SelectionChangeListener.class);
+	}
+
+	protected DisposeListener buildComboDisposeListener() {
+		return new DisposeListener() {
+			public void widgetDisposed(DisposeEvent event) {
+				AbstractComboModelAdapter.this.comboDisposed(event);
+			}
+
+			@Override
+			public String toString() {
+				return "combo dispose listener";
+			}
+		};
+	}
+
+	protected void synchronizeCombo() {
+		this.synchronizeComboItems();
+		this.synchronizeComboSelection();
+	}
+
+
+	// ********** string converter **********
+
+	public void setStringConverter(StringConverter<E> stringConverter) {
+		Assert.isNotNull(stringConverter, "The StringConverter cannot be null");
+		this.stringConverter = stringConverter;
+		this.synchronizeCombo();
+	}
+
+
+	// ********** list **********
+
+	/**
+	 * Use the string converter to convert the specified item to a
+	 * string that can be added to the combo.
+	 */
+	protected String convert(E item) {
+		return this.stringConverter.convertToString(item);
+	}
+
+	/**
+	 * Brute force synchronization of combo with the model list.
+	 */
+	protected void synchronizeComboItems() {
+		if (this.comboHolder.isDisposed()) {
+			return;
+		}
+		int len = this.listHolder.size();
+		String[] items = new String[len];
+		for (int index = 0; index < len; index++) {
+			items[index] = this.convert(this.listHolder.get(index));
+		}
+		try {
+			this.comboHolder.setPopulating(true);
+			this.comboHolder.setItems(items);
+		}
+		finally {
+			this.comboHolder.setPopulating(false);
+		}
+	}
+
+	/**
+	 * The model has changed - synchronize the combo.
+	 */
+	protected void listItemsAdded(ListAddEvent event) {
+		if (this.comboHolder.isDisposed()) {
+			return;
+		}
+
+		int count = this.comboHolder.getItemCount();
+		int index = event.getIndex();
+
+		for (E item : this.getItems(event)) {
+			this.comboHolder.add(this.convert(item), index++);
+		}
+
+		// When the combo is populated, it's possible the selection was already
+		// set but no items was found, resync the selected item
+		synchronizeComboSelection();
+	}
+
+	/**
+	 * The model has changed - synchronize the combo.
+	 */
+	protected void listItemsRemoved(ListRemoveEvent event) {
+		if (this.comboHolder.isDisposed()) {
+			return;
+		}
+		this.comboHolder.remove(event.getIndex(), event.getIndex() + event.getItemsSize() - 1);
+		this.synchronizeComboSelection();
+	}
+
+	/**
+	 * The model has changed - synchronize the combo.
+	 */
+	protected void listItemsMoved(ListMoveEvent event) {
+		if (this.comboHolder.isDisposed()) {
+			return;
+		}
+		int target = event.getTargetIndex();
+		int source = event.getSourceIndex();
+		int len = event.getLength();
+		int loStart = Math.min(target, source);
+		int hiStart = Math.max(target, source);
+		// make a copy of the affected items...
+		String[] subArray = ArrayTools.subArray(this.comboHolder.getItems(), loStart, hiStart + len - loStart);
+		// ...move them around...
+		subArray = ArrayTools.move(subArray, target - loStart, source - loStart, len);
+		// ...and then put them back
+		for (int index = 0; index < subArray.length; index++) {
+			this.comboHolder.setItem(loStart + index, subArray[index]);
+		}
+	}
+
+	/**
+	 * The model has changed - synchronize the combo.
+	 */
+	protected void listItemsReplaced(ListReplaceEvent event) {
+		if (this.comboHolder.isDisposed()) {
+			return;
+		}
+		int index = event.getIndex();
+		int selectionIndex = this.comboHolder.getSelectionIndex();
+		//fixing bug 269100 by setting the populating flag to true
+		this.comboHolder.setPopulating(true);
+		try {
+			for (E item : this.getNewItems(event)) {
+				this.comboHolder.setItem(index++, this.convert(item));
+			}
+			if (selectionIndex == 0) {
+				this.comboHolder.setText(this.comboHolder.getItems()[0]);
+			}
+		}
+		finally {
+			this.comboHolder.setPopulating(false);
+		}
+	}
+
+	/**
+	 * The model has changed - synchronize the combo.
+	 */
+	protected void listCleared(ListClearEvent event) {
+		if (this.comboHolder.isDisposed()) {
+			return;
+		}
+		this.comboHolder.setPopulating(true);
+		try {
+			this.comboHolder.removeAll();
+		}
+		finally {
+			this.comboHolder.setPopulating(false);
+		}
+	}
+
+	/**
+	 * The model has changed - synchronize the combo.
+	 */
+	protected void listChanged(ListChangeEvent event) {
+		this.synchronizeCombo();
+	}
+
+	// minimized scope of suppressed warnings
+	@SuppressWarnings("unchecked")
+	protected Iterable<E> getItems(ListAddEvent event) {
+		return (Iterable<E>) event.getItems();
+	}
+
+	// minimized scope of suppressed warnings
+	@SuppressWarnings("unchecked")
+	protected Iterable<E> getNewItems(ListReplaceEvent event) {
+		return (Iterable<E>) event.getNewItems();
+	}
+
+
+	// ********** selected items **********
+
+	protected int indexOf(E item) {
+		int length = this.listHolder.size();
+		for (int index = 0; index < length; index++) {
+			if (valuesAreEqual(this.listHolder.get(index), item)) {
+				return index;
+			}
+		}
+		return -1;
+	}
+
+	protected void synchronizeComboSelection() {
+		if (this.comboHolder.isDisposed() || this.comboHolder.isPopulating()) {
+			return;
+		}
+
+		E selectedValue = this.selectedItemHolder.getValue();
+		if (this.comboHolder.getText().equals(selectedValue)) {
+			//if the selection is still the same, don't reset it
+			return;
+		}
+		this.comboHolder.setPopulating(true);
+		try {
+			this.comboHolder.deselectAll();
+			String selectedItem = this.convert(selectedValue);
+			if (selectedItem == null) {
+				selectedItem = "";
+			}
+			this.comboHolder.setText(selectedItem);
+			this.notifyListeners(selectedValue);
+		}
+		finally {
+			this.comboHolder.setPopulating(false);
+		}
+	}
+
+	protected void selectedItemChanged(PropertyChangeEvent event) {
+		this.synchronizeComboSelection();
+	}
+
+	/**
+	 * Return whether the values are equal, with the appropriate null checks.
+	 * Convenience method for checking whether an attribute value has changed.
+	 */
+	protected final boolean valuesAreEqual(Object value1, Object value2) {
+		if ((value1 == null) && (value2 == null)) {
+			return true;	// both are null
+		}
+		if ((value1 == null) || (value2 == null)) {
+			return false;	// one is null but the other is not
+		}
+		return value1.equals(value2);
+	}
+
+	// ********** combo events **********
+
+	protected void comboSelectionChanged(SelectionEvent event) {
+		this.selectionChanged();
+	}
+
+	protected void comboSelectionChanged(ModifyEvent event) {
+		this.selectionChanged();
+	}
+
+	protected void selectionChanged() {
+		if (!this.comboHolder.isPopulating()) {
+			E selectedItem = this.selectedItem();
+			this.comboHolder.setPopulating(true);
+			try {
+				this.selectedItemHolder.setValue(selectedItem);
+				this.notifyListeners(selectedItem);
+			}
+			finally {
+				this.comboHolder.setPopulating(false);
+			}
+		}
+	}
+
+	private void notifyListeners(E selectedItem) {
+		if (this.selectionChangeListenerList.size() > 0) {
+			SelectionChangeEvent<E> scEvent = new SelectionChangeEvent<E>(this, selectedItem);
+			for (SelectionChangeListener<E> selectionChangeListener : this.selectionChangeListenerList.getListeners()) {
+				selectionChangeListener.selectionChanged(scEvent);
+			}
+		}
+	}
+
+	@SuppressWarnings("unchecked")
+	protected E selectedItem() {
+		if (this.comboHolder.isDisposed()) {
+			return null;
+		}
+
+		if (this.comboHolder.isEditable()) {
+			String text = this.comboHolder.getText();
+
+			if (text.length() == 0) {
+				return null;
+			}
+
+			for (int index = this.listHolder.size(); --index >= 0; ) {
+				E item = this.listHolder.get(index);
+				String value = this.convert(item);
+				if (valuesAreEqual(text, value)) {
+					return item;
+				}
+			}
+
+			// TODO: Find a way to prevent this type cast (it'll work if E is
+			// String but it won't work if E is something else), maybe use a
+			// BidiStringConverter instead of StringConverter
+			try {
+				return (E) text;
+			}
+			catch (ClassCastException e) {
+				return null;
+			}
+		}
+
+		int index = this.comboHolder.getSelectionIndex();
+
+		if (index == -1) {
+			return null;
+		}
+
+		return this.listHolder.get(index);
+	}
+
+	protected void comboDoubleClicked(SelectionEvent event) {
+		if (this.comboHolder.isDisposed()) {
+			return;
+		}
+		if (this.doubleClickListenerList.size() > 0) {
+			// there should be only a single item selected during a double-click(?)
+			E selection = this.listHolder.get(this.comboHolder.getSelectionIndex());
+			DoubleClickEvent<E> dcEvent = new DoubleClickEvent<E>(this, selection);
+			for (DoubleClickListener<E> doubleClickListener : this.doubleClickListenerList.getListeners()) {
+				doubleClickListener.doubleClick(dcEvent);
+			}
+		}
+	}
+
+
+	// ********** dispose **********
+
+	protected void comboDisposed(DisposeEvent event) {
+		// the combo is not yet "disposed" when we receive this event
+		// so we can still remove our listeners
+		this.comboHolder.removeDisposeListener(this.comboDisposeListener);
+		if (this.comboHolder.isEditable()) {
+			this.comboHolder.removeModifyListener(this.comboModifyListener);
+		}
+		else {
+			this.comboHolder.removeSelectionListener(this.comboSelectionListener);
+		}
+		this.selectedItemHolder.removePropertyChangeListener(PropertyValueModel.VALUE, this.selectedItemChangeListener);
+		this.listHolder.removeListChangeListener(ListValueModel.LIST_VALUES, this.listChangeListener);
+	}
+
+
+	// ********** standard methods **********
+
+	@Override
+	public String toString() {
+		return StringTools.buildToStringFor(this, this.listHolder);
+	}
+
+
+	// ********** double click support **********
+
+	public void addDoubleClickListener(DoubleClickListener<E> listener) {
+		this.doubleClickListenerList.add(listener);
+	}
+
+	public void removeDoubleClickListener(DoubleClickListener<E> listener) {
+		this.doubleClickListenerList.remove(listener);
+	}
+
+	public interface DoubleClickListener<E> extends EventListener {
+		void doubleClick(DoubleClickEvent<E> event);
+	}
+
+	public static class DoubleClickEvent<E> extends EventObject {
+		private final E selection;
+		private static final long serialVersionUID = 1L;
+
+		protected DoubleClickEvent(AbstractComboModelAdapter<E> source, E selection) {
+			super(source);
+			if (selection == null) {
+				throw new NullPointerException();
+			}
+			this.selection = selection;
+		}
+
+		@Override
+		@SuppressWarnings("unchecked")
+		public AbstractComboModelAdapter<E> getSource() {
+			return (AbstractComboModelAdapter<E>) super.getSource();
+		}
+
+		public E selection() {
+			return this.selection;
+		}
+	}
+
+
+	// ********** selection support **********
+
+	public void addSelectionChangeListener(SelectionChangeListener<E> listener) {
+		this.selectionChangeListenerList.add(listener);
+	}
+
+	public void removeSelectionChangeListener(SelectionChangeListener<E> listener) {
+		this.selectionChangeListenerList.remove(listener);
+	}
+
+	public interface SelectionChangeListener<E> extends EventListener {
+		void selectionChanged(SelectionChangeEvent<E> event);
+	}
+
+	public static class SelectionChangeEvent<E> extends EventObject {
+		private final E selectedItem;
+		private static final long serialVersionUID = 1L;
+
+		protected SelectionChangeEvent(AbstractComboModelAdapter<E> source, E selectedItem) {
+			super(source);
+			this.selectedItem = selectedItem;
+		}
+
+		@Override
+		@SuppressWarnings("unchecked")
+		public AbstractComboModelAdapter<E> getSource() {
+			return (AbstractComboModelAdapter<E>) super.getSource();
+		}
+
+		public E selectedItem() {
+			return this.selectedItem;
+		}
+	}
+
+	// ********** Internal member **********
+
+	/**
+	 * This holder is required for supporting <code>Combo</code> and
+	 * <code>CCombo</code> transparently.
+	 */
+	protected static interface ComboHolder {
+		void add(String item, int index);
+		void addDisposeListener(DisposeListener disposeListener);
+		void addModifyListener(ModifyListener modifyListener);
+		void addSelectionListener(SelectionListener selectionListener);
+		void deselectAll();
+		int getItemCount();
+		String[] getItems();
+		int getSelectionIndex();
+		String getText();
+		boolean isDisposed();
+		boolean isEditable();
+		boolean isPopulating();
+		void removeDisposeListener(DisposeListener disposeListener);
+		void removeModifyListener(ModifyListener modifyListener);
+		void removeSelectionListener(SelectionListener selectionListener);
+		void setItem(int index, String item);
+		void setItems(String[] items);
+		void setPopulating(boolean populating);
+		void setText(String item);
+		void remove(int start, int end);
+		void removeAll();
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/swt/ColumnAdapter.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/swt/ColumnAdapter.java
new file mode 100644
index 0000000..d221ee3
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/swt/ColumnAdapter.java
@@ -0,0 +1,55 @@
+/*******************************************************************************
+ * Copyright (c) 2008 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.ui.internal.swt;
+
+import org.eclipse.jpt.utility.model.value.WritablePropertyValueModel;
+
+/**
+ * This adapter is used by the table model adapter to convert a model object
+ * into the models used for each of the cells for the object's corresponding row
+ * in the table.
+ *
+ * @version 2.0
+ * @since 2.0
+ */
+public interface ColumnAdapter<V> {
+
+	/**
+	 * Return the cell models for the specified subject
+	 * that corresponds to a single row in the table.
+	 */
+	WritablePropertyValueModel<?>[] cellModels(V subject);
+
+	/**
+	 * Returns the number of columns in the table. Typically this is static.
+	 *
+	 * @return The number of columns
+	 */
+	int columnCount();
+
+	/**
+	 * Returns the name of the column at the specified index.
+	 *
+	 * @param columnIndex The index of the column to retrieve its display text
+	 * @return The display text of the column
+	 */
+	String columnName(int columnIndex);
+
+	/**
+	 * Returns whether the specified column is editable. Typically this is the
+	 * same for every row.
+	 *
+	 * @param columnIndex The index of the column for which we determine if
+	 * the content can be modified
+	 * @return <code>true</code> to allow editing of the cell at the given
+	 * column index; <code>false</code> to keep it not editable
+	 */
+//	boolean columnIsEditable(int columnIndex);
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/swt/ComboModelAdapter.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/swt/ComboModelAdapter.java
new file mode 100644
index 0000000..d926c06
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/swt/ComboModelAdapter.java
@@ -0,0 +1,210 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2009 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.ui.internal.swt;
+
+import org.eclipse.jpt.utility.internal.StringConverter;
+import org.eclipse.jpt.utility.model.value.ListValueModel;
+import org.eclipse.jpt.utility.model.value.WritablePropertyValueModel;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.DisposeListener;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.widgets.Combo;
+
+/**
+ * This adapter provides a more object-oriented interface to the items and
+ * selected item in a <code>Combo</code>.
+ * <p>
+ * <b>listHolder</b> contains the items in the <code>Combo</code>.<br>
+ * <b>selectedItemHolder</b> contains the items in 'listHolder' that are
+ * selected in the <code>Combo</code>.
+ *
+ * @param <E> The type of the items in <b>listHolder</b>
+ * @version 2.0
+ * @since 2.0
+ */
+@SuppressWarnings("nls")
+public class ComboModelAdapter<E> extends AbstractComboModelAdapter<E> {
+
+	// ********** static methods **********
+
+	/**
+	 * Adapt the specified model list and selection to the specified combo.
+	 * Use the default string converter to convert the model items to strings
+	 * to be displayed in the combo, which calls #toString() on the
+	 * items in the model list.
+	 */
+	public static <T> ComboModelAdapter<T> adapt(
+			ListValueModel<T> listHolder,
+			WritablePropertyValueModel<T> selectedItemHolder,
+			Combo combo)
+	{
+		return adapt(
+			listHolder,
+			selectedItemHolder,
+			combo,
+			StringConverter.Default.<T>instance()
+		);
+	}
+
+	/**
+	 * Adapt the specified model list and selection to the specified combo.
+	 * Use the specified string converter to convert the model items to strings
+	 * to be displayed in the combo.
+	 */
+	public static <T> ComboModelAdapter<T> adapt(
+			ListValueModel<T> listHolder,
+			WritablePropertyValueModel<T> selectedItemHolder,
+			Combo combo,
+			StringConverter<T> stringConverter)
+	{
+		return new ComboModelAdapter<T>(
+			listHolder,
+			selectedItemHolder,
+			combo,
+			stringConverter
+		);
+	}
+
+
+	// ********** constructors **********
+
+	/**
+	 * Constructor - the list holder, selections holder, combo, and
+	 * string converter are required.
+	 */
+	protected ComboModelAdapter(
+			ListValueModel<E> listHolder,
+			WritablePropertyValueModel<E> selectedItemHolder,
+			Combo combo,
+			StringConverter<E> stringConverter)
+	{
+		super(listHolder,
+		      selectedItemHolder,
+		      new SWTComboHolder(combo),
+		      stringConverter);
+	}
+
+
+	// ********** Internal member **********
+
+	private static class SWTComboHolder implements ComboHolder {
+		private final Combo combo;
+		private final boolean editable;
+		private String selectedItem;
+
+		SWTComboHolder(Combo combo) {
+			super();
+			this.combo    = combo;
+			this.editable = (combo.getStyle() & SWT.READ_ONLY) == 0;
+		}
+
+		public void add(String item, int index) {
+			this.combo.add(item, index);
+
+			// It is possible the selected item was set before the combo is being
+			// populated, update the selected item if it's matches the item being
+			// added
+			if ((this.selectedItem != null) && this.selectedItem.equals(item)) {
+				this.setText(this.selectedItem);
+				this.selectedItem = null;
+			}
+		}
+
+		public void addDisposeListener(DisposeListener disposeListener) {
+			this.combo.addDisposeListener(disposeListener);
+		}
+
+		public void addModifyListener(ModifyListener modifyListener) {
+			this.combo.addModifyListener(modifyListener);
+		}
+
+		public void addSelectionListener(SelectionListener selectionListener) {
+			this.combo.addSelectionListener(selectionListener);
+		}
+
+		public void deselectAll() {
+			this.combo.deselectAll();
+		}
+
+		public int getItemCount() {
+			return this.combo.getItemCount();
+		}
+
+		public String[] getItems() {
+			return this.combo.getItems();
+		}
+
+		public int getSelectionIndex() {
+			return this.combo.getSelectionIndex();
+		}
+
+		public String getText() {
+			return this.combo.getText();
+		}
+
+		public boolean isDisposed() {
+			return this.combo.isDisposed();
+		}
+
+		public boolean isEditable() {
+			return this.editable;
+		}
+
+		public boolean isPopulating() {
+			return this.combo.getData("populating") == Boolean.TRUE;
+		}
+
+		public void remove(int start, int end) {
+			this.combo.remove(start, end);
+		}
+
+		public void removeAll() {
+			this.combo.removeAll();
+		}
+
+		public void removeDisposeListener(DisposeListener disposeListener) {
+			this.combo.removeDisposeListener(disposeListener);
+		}
+
+		public void removeModifyListener(ModifyListener modifyListener) {
+			this.combo.removeModifyListener(modifyListener);
+		}
+
+		public void removeSelectionListener(SelectionListener selectionListener) {
+			this.combo.removeSelectionListener(selectionListener);
+		}
+
+		public void setItem(int index, String item) {
+			this.combo.setItem(index, item);
+		}
+
+		public void setItems(String[] items) {
+			this.combo.setItems(items);
+		}
+
+		public void setPopulating(boolean populating) {
+			this.combo.setData("populating", Boolean.valueOf(populating));
+		}
+
+		public void setText(String item) {
+
+			// Keep track of the selected item since it's possible the selected
+			// item is before the combo is populated
+			if (this.combo.getItemCount() == 0) {
+				this.selectedItem = item;
+			}
+			else {
+				this.selectedItem = null;
+			}
+			this.combo.setText(item);
+		}
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/swt/DateTimeModelAdapter.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/swt/DateTimeModelAdapter.java
new file mode 100644
index 0000000..b90444f
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/swt/DateTimeModelAdapter.java
@@ -0,0 +1,352 @@
+/*******************************************************************************
+ * Copyright (c) 2008 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.ui.internal.swt;
+
+import org.eclipse.jpt.ui.internal.listeners.SWTPropertyChangeListenerWrapper;
+import org.eclipse.jpt.utility.internal.StringTools;
+import org.eclipse.jpt.utility.model.event.PropertyChangeEvent;
+import org.eclipse.jpt.utility.model.listener.PropertyChangeListener;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.jpt.utility.model.value.WritablePropertyValueModel;
+import org.eclipse.swt.events.DisposeEvent;
+import org.eclipse.swt.events.DisposeListener;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.widgets.DateTime;
+
+/**
+ * This adapter can be used to keep a DateTime widget in synch with
+ * model integers hours, minutes, and seconds.  Has default hours,
+ * minutes and seconds of 0 which corresponds to 12:00:00 AM. This model
+ * adapter can only be used for a DateTime widget with the style SWT.TIME
+ */
+@SuppressWarnings("nls")
+public class DateTimeModelAdapter {
+
+	/**
+	 * A value model on the underlying model hours integer.
+	 */
+	protected final WritablePropertyValueModel<Integer> hoursHolder;
+	
+	/**
+	 * A value model on the underlying model minutes integer.
+	 */
+	protected final WritablePropertyValueModel<Integer> minutesHolder;
+	
+	/**
+	 * A value model on the underlying model seconds integer.
+	 */
+	protected final WritablePropertyValueModel<Integer> secondsHolder;
+
+	/**
+	 * A listener that allows us to synchronize the dateTime's selection state with
+	 * the model hours integer.
+	 */
+	protected final PropertyChangeListener hoursPropertyChangeListener;
+	
+	/**
+	 * A listener that allows us to synchronize the dateTime's selection state with
+	 * the model minutes integer.
+	 */
+	protected final PropertyChangeListener minutesPropertyChangeListener;
+	
+	/**
+	 * A listener that allows us to synchronize the dateTime's selection state with
+	 * the model seconds integer.
+	 */
+	protected final PropertyChangeListener secondsPropertyChangeListener;
+
+	/**
+	 * The dateTime we keep synchronized with the model integers.
+	 */
+	protected final DateTime dateTime;
+
+	/**
+	 * A listener that allows us to synchronize our selection number holder
+	 * with the spinner's value.
+	 */
+	protected final SelectionListener dateTimeSelectionListener;
+
+	/**
+	 * A listener that allows us to stop listening to stuff when the dateTime
+	 * is disposed.
+	 */
+	protected final DisposeListener dateTimeDisposeListener;
+
+	/**
+	 * This lock is used to prevent the listeners to be notified when the value
+	 * changes from the spinner or from the holder.
+	 */
+	private boolean locked;
+
+	// ********** static methods **********
+
+	/**
+	 * Adapt the specified model integer holders to the specified dateTime.
+	 */
+	public static DateTimeModelAdapter adapt(
+			WritablePropertyValueModel<Integer> hoursHolder,
+			WritablePropertyValueModel<Integer> minutesHolder,
+			WritablePropertyValueModel<Integer> secondsHolder,
+			DateTime dateTime)
+	{
+		return new DateTimeModelAdapter(hoursHolder, minutesHolder, secondsHolder, dateTime);
+	}
+
+
+	// ********** constructors **********
+
+	/**
+	 * Constructor - the hoursHolder, minutesHolder, secondsHolder, and dateTime are required
+	 */
+	protected DateTimeModelAdapter(WritablePropertyValueModel<Integer> hoursHolder,
+									WritablePropertyValueModel<Integer> minutesHolder,
+									WritablePropertyValueModel<Integer> secondsHolder,
+									DateTime dateTime) {
+		super();
+		if ((hoursHolder == null) 
+			|| (minutesHolder == null) 
+			|| (secondsHolder == null) 
+			|| (dateTime == null)) {
+			throw new NullPointerException();
+		}
+		this.hoursHolder = hoursHolder;
+		this.minutesHolder = minutesHolder;
+		this.secondsHolder = secondsHolder;
+		this.dateTime = dateTime;
+
+		this.hoursPropertyChangeListener = this.buildHoursPropertyChangeListener();
+		this.hoursHolder.addPropertyChangeListener(PropertyValueModel.VALUE, this.hoursPropertyChangeListener);
+
+		this.minutesPropertyChangeListener = this.buildMinutesPropertyChangeListener();
+		this.minutesHolder.addPropertyChangeListener(PropertyValueModel.VALUE, this.minutesPropertyChangeListener);
+
+		this.secondsPropertyChangeListener = this.buildSecondsPropertyChangeListener();
+		this.secondsHolder.addPropertyChangeListener(PropertyValueModel.VALUE, this.secondsPropertyChangeListener);
+		
+		this.dateTimeSelectionListener = this.buildDateTimeSelectionListener();
+		this.dateTime.addSelectionListener(this.dateTimeSelectionListener);
+
+		this.dateTimeDisposeListener = this.buildDateTimeDisposeListener();
+		this.dateTime.addDisposeListener(this.dateTimeDisposeListener);
+
+		this.updateDateTimeHours(hoursHolder.getValue());
+		this.updateDateTimeMinutes(minutesHolder.getValue());
+		this.updateDateTimeSeconds(secondsHolder.getValue());
+	}
+
+
+	// ********** initialization **********
+
+	protected PropertyChangeListener buildHoursPropertyChangeListener() {
+		return new SWTPropertyChangeListenerWrapper(this.buildHoursPropertyChangeListener_());
+	}
+
+	protected PropertyChangeListener buildHoursPropertyChangeListener_() {
+		return new PropertyChangeListener() {
+			public void propertyChanged(PropertyChangeEvent event) {
+				DateTimeModelAdapter.this.hoursChanged(event);
+			}
+			@Override
+			public String toString() {
+				return "dateTime hours listener";
+			}
+		};
+	}
+	
+	protected PropertyChangeListener buildMinutesPropertyChangeListener() {
+		return new SWTPropertyChangeListenerWrapper(this.buildMinutesPropertyChangeListener_());
+	}
+
+	protected PropertyChangeListener buildMinutesPropertyChangeListener_() {
+		return new PropertyChangeListener() {
+			public void propertyChanged(PropertyChangeEvent event) {
+				DateTimeModelAdapter.this.minutesChanged(event);
+			}
+			@Override
+			public String toString() {
+				return "dateTime minutes listener";
+			}
+		};
+	}
+	
+	protected PropertyChangeListener buildSecondsPropertyChangeListener() {
+		return new SWTPropertyChangeListenerWrapper(this.buildSecondsPropertyChangeListener_());
+	}
+
+	protected PropertyChangeListener buildSecondsPropertyChangeListener_() {
+		return new PropertyChangeListener() {
+			public void propertyChanged(PropertyChangeEvent event) {
+				DateTimeModelAdapter.this.secondsChanged(event);
+			}
+			@Override
+			public String toString() {
+				return "dateTime seconds listener";
+			}
+		};
+	}
+
+	protected SelectionListener buildDateTimeSelectionListener() {
+		return new SelectionListener() {
+			public void widgetSelected(SelectionEvent e) {
+				DateTimeModelAdapter.this.dateTimeSelected(e);
+			}
+			
+			public void widgetDefaultSelected(SelectionEvent e) {				
+			}
+			
+			@Override
+			public String toString() {
+				return "dateTime selection listener";
+			}
+		};
+	}
+
+	protected DisposeListener buildDateTimeDisposeListener() {
+		return new DisposeListener() {
+			public void widgetDisposed(DisposeEvent event) {
+				DateTimeModelAdapter.this.dateTimeDisposed(event);
+			}
+			@Override
+			public String toString() {
+				return "dateTime dispose listener";
+			}
+		};
+	}
+
+
+	// ********** model events **********
+
+	protected void hoursChanged(PropertyChangeEvent event) {
+		if (!this.locked) {
+			this.updateDateTimeHours((Integer) event.getNewValue());
+		}
+	}
+
+	protected void minutesChanged(PropertyChangeEvent event) {
+		if (!this.locked) {
+			this.updateDateTimeMinutes((Integer) event.getNewValue());
+		}
+	}
+
+	protected void secondsChanged(PropertyChangeEvent event) {
+		if (!this.locked) {
+			this.updateDateTimeSeconds((Integer) event.getNewValue());
+		}
+	}
+
+	// ********** dateTime events **********
+
+	protected void dateTimeSelected(SelectionEvent event) {
+		if (!this.locked) {
+			this.locked = true;
+			try {
+				//too bad they didn't split the event up
+				hoursSelected();
+				minutesSelected();
+				secondsSelected();
+			}
+			finally {
+				this.locked = false;
+			}
+		}
+	}
+	
+	protected void hoursSelected() {
+		Integer hours = null;
+		if (this.dateTime.getHours() != 0) {
+			hours = Integer.valueOf(this.dateTime.getHours());
+		}
+		this.hoursHolder.setValue(hours);
+	}
+	
+	protected void minutesSelected() {
+		Integer minutes = null;
+		if (this.dateTime.getMinutes() != 0) {
+			minutes = Integer.valueOf(this.dateTime.getMinutes());
+		}
+		this.minutesHolder.setValue(minutes);
+	}
+	
+	protected void secondsSelected() {
+		Integer seconds = null;
+		if (this.dateTime.getSeconds() != 0) {
+			seconds = Integer.valueOf(this.dateTime.getSeconds());
+		}
+		this.secondsHolder.setValue(seconds);
+	}
+
+	protected void dateTimeDisposed(DisposeEvent event) {
+		// the dateTime is not yet "disposed" when we receive this event
+		// so we can still remove our listeners
+		this.dateTime.removeDisposeListener(this.dateTimeDisposeListener);
+		this.dateTime.removeSelectionListener(this.dateTimeSelectionListener);
+		this.hoursHolder.removePropertyChangeListener(PropertyValueModel.VALUE, this.hoursPropertyChangeListener);
+		this.minutesHolder.removePropertyChangeListener(PropertyValueModel.VALUE, this.minutesPropertyChangeListener);
+		this.secondsHolder.removePropertyChangeListener(PropertyValueModel.VALUE, this.secondsPropertyChangeListener);
+	}
+
+	// ********** update **********
+
+	protected void updateDateTimeHours(Integer hours) {
+		if (this.dateTime.isDisposed()) {
+			return;
+		}
+		if (hours == null) {
+			hours = Integer.valueOf(0);//TODO defaultHours
+		}
+		this.locked = true;
+		try {
+			this.dateTime.setHours(hours.intValue());
+		}
+		finally {
+			this.locked = false;
+		}
+	}
+	
+	protected void updateDateTimeMinutes(Integer minutes) {
+		if (this.dateTime.isDisposed()) {
+			return;
+		}
+		if (minutes == null) {
+			minutes = Integer.valueOf(0);//TODO defaultMinutes
+		}
+		this.locked = true;
+		try {
+			this.dateTime.setMinutes(minutes.intValue());
+		}
+		finally {
+			this.locked = false;
+		}
+	}
+	
+	protected void updateDateTimeSeconds(Integer seconds) {
+		if (this.dateTime.isDisposed()) {
+			return;
+		}
+		if (seconds == null) {
+			seconds = Integer.valueOf(0);//TODO defaultSeconds
+		}
+		this.locked = true;
+		try {
+			this.dateTime.setSeconds(seconds.intValue());
+		}
+		finally {
+			this.locked = false;
+		}
+	}
+
+	// ********** standard methods **********
+
+	@Override
+	public String toString() {
+		return StringTools.buildToStringFor(this, this.hoursHolder);
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/swt/SpinnerModelAdapter.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/swt/SpinnerModelAdapter.java
new file mode 100644
index 0000000..9f997ed
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/swt/SpinnerModelAdapter.java
@@ -0,0 +1,214 @@
+/*******************************************************************************
+ * Copyright (c) 2008 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.ui.internal.swt;
+
+import org.eclipse.jpt.ui.internal.listeners.SWTPropertyChangeListenerWrapper;
+import org.eclipse.jpt.utility.internal.StringTools;
+import org.eclipse.jpt.utility.model.event.PropertyChangeEvent;
+import org.eclipse.jpt.utility.model.listener.PropertyChangeListener;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.jpt.utility.model.value.WritablePropertyValueModel;
+import org.eclipse.swt.events.DisposeEvent;
+import org.eclipse.swt.events.DisposeListener;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.widgets.Spinner;
+
+/**
+ *
+ */
+@SuppressWarnings("nls")
+public class SpinnerModelAdapter {
+
+	/**
+	 * A value model on the underlying model list.
+	 */
+	protected final WritablePropertyValueModel<Integer> numberHolder;
+
+	/**
+	 * A listener that allows us to synchronize the spinner's contents with
+	 * the model list.
+	 */
+	protected final PropertyChangeListener propertyChangeListener;
+
+	/**
+	 * The spinner we keep synchronized with the model string.
+	 */
+	protected final Spinner spinner;
+
+	/**
+	 * A listener that allows us to synchronize our selection number holder
+	 * with the spinner's value.
+	 */
+	protected final ModifyListener spinnerModifyListener;
+
+	/**
+	 * A listener that allows us to stop listening to stuff when the spinner
+	 * is disposed.
+	 */
+	protected final DisposeListener spinnerDisposeListener;
+
+	/**
+	 * The value shown when the number holder's value is <code>null</code>.
+	 */
+	protected final int defaultValue;
+
+	/**
+	 * This lock is used to prevent the listeners to be notified when the value
+	 * changes from the spinner or from the holder.
+	 */
+	private boolean locked;
+
+	// ********** static methods **********
+
+	/**
+	 * Adapt the specified model list and selections to the specified spinner.
+	 * Use the specified string converter to convert the model items to strings
+	 * to be displayed in the spinner.
+	 */
+	public static SpinnerModelAdapter adapt(
+			WritablePropertyValueModel<Integer> numberHolder,
+			Spinner spinner,
+			int defaultValue)
+	{
+		return new SpinnerModelAdapter(numberHolder, spinner, defaultValue);
+	}
+
+
+	// ********** constructors **********
+
+	/**
+	 * Constructor - the list holder, selections holder, list box, and
+	 * string converter are required.
+	 */
+	protected SpinnerModelAdapter(WritablePropertyValueModel<Integer> numberHolder,
+	                              Spinner spinner,
+	                              int defaultValue) {
+		super();
+		if ((numberHolder == null) || (spinner == null)) {
+			throw new NullPointerException();
+		}
+		this.numberHolder = numberHolder;
+		this.spinner = spinner;
+		this.defaultValue = defaultValue;
+
+		this.propertyChangeListener = this.buildPropertyChangeListener();
+		this.numberHolder.addPropertyChangeListener(PropertyValueModel.VALUE, this.propertyChangeListener);
+
+		this.spinnerModifyListener = this.buildSpinnerModifyListener();
+		this.spinner.addModifyListener(this.spinnerModifyListener);
+
+		this.spinnerDisposeListener = this.buildSpinnerDisposeListener();
+		this.spinner.addDisposeListener(this.spinnerDisposeListener);
+
+		this.updateSpinner(numberHolder.getValue());
+	}
+
+
+	// ********** initialization **********
+
+	protected PropertyChangeListener buildPropertyChangeListener() {
+		return new SWTPropertyChangeListenerWrapper(this.buildPropertyChangeListener_());
+	}
+
+	protected PropertyChangeListener buildPropertyChangeListener_() {
+		return new PropertyChangeListener() {
+			public void propertyChanged(PropertyChangeEvent event) {
+				SpinnerModelAdapter.this.valueChanged(event);
+			}
+			@Override
+			public String toString() {
+				return "spinner listener";
+			}
+		};
+	}
+
+	protected ModifyListener buildSpinnerModifyListener() {
+		return new ModifyListener() {
+			public void modifyText(ModifyEvent e) {
+				SpinnerModelAdapter.this.spinnerModified(e);
+			}
+			@Override
+			public String toString() {
+				return "spinner selection listener";
+			}
+		};
+	}
+
+	protected DisposeListener buildSpinnerDisposeListener() {
+		return new DisposeListener() {
+			public void widgetDisposed(DisposeEvent event) {
+				SpinnerModelAdapter.this.spinnerDisposed(event);
+			}
+			@Override
+			public String toString() {
+				return "spinner dispose listener";
+			}
+		};
+	}
+
+
+	// ********** model events **********
+
+	protected void valueChanged(PropertyChangeEvent event) {
+		if (!this.locked) {
+			this.updateSpinner((Integer) event.getNewValue());
+		}
+	}
+
+
+	// ********** spinner events **********
+
+	protected void spinnerModified(ModifyEvent event) {
+		if (!this.locked) {
+			this.locked = true;
+			try {
+				this.numberHolder.setValue(this.spinner.getSelection());
+			}
+			finally {
+				this.locked = false;
+			}
+		}
+	}
+
+	protected void spinnerDisposed(DisposeEvent event) {
+		// the spinner is not yet "disposed" when we receive this event
+		// so we can still remove our listeners
+		this.spinner.removeDisposeListener(this.spinnerDisposeListener);
+		this.spinner.removeModifyListener(this.spinnerModifyListener);
+		this.numberHolder.removePropertyChangeListener(PropertyValueModel.VALUE, this.propertyChangeListener);
+	}
+
+	// ********** update **********
+
+	protected void updateSpinner(Integer value) {
+		if (this.spinner.isDisposed()) {
+			return;
+		}
+		// the model can be null, but the spinner cannot
+		if (value == null) {
+			value = defaultValue;
+		}
+		this.locked = true;
+		try {
+			this.spinner.setSelection(value);
+		}
+		finally {
+			this.locked = false;
+		}
+	}
+
+	// ********** standard methods **********
+
+	@Override
+	public String toString() {
+		return StringTools.buildToStringFor(this, this.numberHolder);
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/swt/TableItemModelAdapter.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/swt/TableItemModelAdapter.java
new file mode 100644
index 0000000..aa17710
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/swt/TableItemModelAdapter.java
@@ -0,0 +1,209 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2008 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.ui.internal.swt;
+
+import org.eclipse.jface.viewers.ITableLabelProvider;
+import org.eclipse.jpt.ui.internal.listeners.SWTPropertyChangeListenerWrapper;
+import org.eclipse.jpt.utility.internal.StringTools;
+import org.eclipse.jpt.utility.model.event.PropertyChangeEvent;
+import org.eclipse.jpt.utility.model.listener.PropertyChangeListener;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.jpt.utility.model.value.WritablePropertyValueModel;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.DisposeEvent;
+import org.eclipse.swt.events.DisposeListener;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.TableItem;
+
+/**
+ * This adapter can be used to keep a table item in synch with the properties of
+ * a model.
+ */
+@SuppressWarnings("nls")
+public class TableItemModelAdapter {
+
+	/** The table item we synchronize with the model. */
+	protected final TableItem tableItem;
+
+	/**
+	 * A listener that allows us to stop listening to stuff when the button
+	 * is disposed.
+	 */
+	protected final DisposeListener tableItemDisposeListener;
+
+	/**
+	 * Client-supplied adapter that provides with the various column settings and
+	 * converts the objects in the LVM into an array of cell models.
+	 */
+	private ColumnAdapter<Object> columnAdapter;
+
+	/**
+	 * The value models used to listen to each property that are display by the
+	 * table item.
+	 */
+	private WritablePropertyValueModel<?>[] valueHolders;
+
+	/**
+	 * The list of <code>PropertyChangeListener</code>s used to be notified when
+	 * the properties of the model being display into a row change.
+	 */
+	private PropertyChangeListener[] propertyChangeListeners;
+
+	/**
+	 * The label used to format the objects into a string representation.
+	 */
+	private ITableLabelProvider labelProvider;
+
+	// ********** static methods **********
+
+	/**
+	 * Adapt the specified boolean to the specified button.
+	 * If the boolean is null, the button's value will be "unselected".
+	 */
+	public static TableItemModelAdapter adapt(TableItem tableItem, ColumnAdapter<?> columnAdapter, ITableLabelProvider labelProvider) {
+		return new TableItemModelAdapter(tableItem, columnAdapter, labelProvider);
+	}
+
+
+	// ********** constructors **********
+
+	/**
+	 * Constructor - the boolean holder and button are required.
+	 */
+	@SuppressWarnings("unchecked")
+	protected TableItemModelAdapter(TableItem tableItem, ColumnAdapter<?> columnAdapter, ITableLabelProvider labelProvider) {
+		super();
+		if (tableItem == null || columnAdapter == null || labelProvider == null) {
+			throw new NullPointerException();
+		}
+		this.tableItem = tableItem;
+		this.labelProvider = labelProvider;
+		this.columnAdapter = (ColumnAdapter<Object>) columnAdapter;
+
+		this.tableItemDisposeListener = this.buildTableItemDisposeListener();
+		this.tableItem.addDisposeListener(this.tableItemDisposeListener);
+
+		this.valueHolders = this.columnAdapter.cellModels(tableItem.getData());
+		this.propertyChangeListeners = this.buildPropertyChangeListeners();
+
+		for (int index = this.columnAdapter.columnCount(); --index >= 0; ) {
+			tableItemChanged(index, tableItem.getData(), false);
+			valueHolders[index].addPropertyChangeListener(PropertyValueModel.VALUE, propertyChangeListeners[index]);
+		}
+	}
+
+
+	// ********** initialization **********
+
+	private PropertyChangeListener[] buildPropertyChangeListeners() {
+		PropertyChangeListener[] listeners = new PropertyChangeListener[columnAdapter.columnCount()];
+		for (int index = listeners.length; --index >= 0; ) {
+			listeners[index] = buildPropertyChangeListener(index);
+		}
+		return listeners;
+	}
+
+
+	protected PropertyChangeListener buildPropertyChangeListener(int index) {
+		return new SWTPropertyChangeListenerWrapper(
+			this.buildPropertyChangeListener_(index)
+		);
+	}
+
+	protected PropertyChangeListener buildPropertyChangeListener_(int index) {
+		return new TableItemPropertyChangeListener(index);
+	}
+
+	protected DisposeListener buildTableItemDisposeListener() {
+		return new DisposeListener() {
+			public void widgetDisposed(DisposeEvent event) {
+				TableItemModelAdapter.this.tableItemDisposed(event);
+			}
+		    @Override
+			public String toString() {
+				return "TableItem dispose listener";
+			}
+		};
+	}
+
+
+	// ********** behavior **********
+
+	protected void tableItemChanged(int index, Object subject, boolean revalidate) {
+
+		if (!this.tableItem.isDisposed()) {
+			this.updateTableItemText(index, subject);
+			this.updateTableItemImage(index, subject);
+
+			if (revalidate) {
+				this.layoutTable();
+			}
+		}
+	}
+
+	private void updateTableItemText(int index, Object subject) {
+		String text = this.labelProvider.getColumnText(subject, index);
+		if (text == null) {
+			text = "";
+		}
+		this.tableItem.setText(index, text);
+	}
+
+	private void updateTableItemImage(int index, Object subject) {
+		Image image = this.labelProvider.getColumnImage(subject, index);
+		this.tableItem.setImage(index, image);
+	}
+
+	private void layoutTable() {
+		// Refresh the table in order to show the scrollbar if required
+		Composite container = this.tableItem.getParent().getParent();
+		container.computeSize(SWT.DEFAULT, SWT.DEFAULT);
+		container.layout();
+	}
+
+	// ********** dispose **********
+
+	protected void tableItemDisposed(DisposeEvent event) {
+		// the button is not yet "disposed" when we receive this event
+		// so we can still remove our listeners
+		this.tableItem.removeDisposeListener(this.tableItemDisposeListener);
+
+		for (int index = valueHolders.length; --index >= 0; ) {
+			valueHolders[index].removePropertyChangeListener(PropertyValueModel.VALUE, propertyChangeListeners[index]);
+		}
+	}
+
+
+	// ********** standard methods **********
+
+	@Override
+	public String toString() {
+		return StringTools.buildToStringFor(this);
+	}
+
+   private class TableItemPropertyChangeListener implements PropertyChangeListener {
+
+   	private final int index;
+
+   	TableItemPropertyChangeListener(int index) {
+   		super();
+   		this.index = index;
+   	}
+
+   	public void propertyChanged(PropertyChangeEvent event) {
+   		if (!tableItem.isDisposed()) {
+   			Table table = tableItem.getParent();
+   			tableItemChanged(index, tableItem.getData(), table.getColumnCount() == 0);
+   		}
+   	}
+   }
+}
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/swt/TableModelAdapter.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/swt/TableModelAdapter.java
new file mode 100644
index 0000000..7c30689
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/swt/TableModelAdapter.java
@@ -0,0 +1,716 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2009 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.ui.internal.swt;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.EventListener;
+import java.util.EventObject;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.jface.viewers.ITableLabelProvider;
+import org.eclipse.jpt.ui.internal.listeners.SWTCollectionChangeListenerWrapper;
+import org.eclipse.jpt.ui.internal.listeners.SWTListChangeListenerWrapper;
+import org.eclipse.jpt.utility.internal.ArrayTools;
+import org.eclipse.jpt.utility.internal.ListenerList;
+import org.eclipse.jpt.utility.internal.StringTools;
+import org.eclipse.jpt.utility.internal.model.value.PropertyCollectionValueModelAdapter;
+import org.eclipse.jpt.utility.model.event.CollectionAddEvent;
+import org.eclipse.jpt.utility.model.event.CollectionChangeEvent;
+import org.eclipse.jpt.utility.model.event.CollectionClearEvent;
+import org.eclipse.jpt.utility.model.event.CollectionRemoveEvent;
+import org.eclipse.jpt.utility.model.event.ListAddEvent;
+import org.eclipse.jpt.utility.model.event.ListChangeEvent;
+import org.eclipse.jpt.utility.model.event.ListClearEvent;
+import org.eclipse.jpt.utility.model.event.ListMoveEvent;
+import org.eclipse.jpt.utility.model.event.ListRemoveEvent;
+import org.eclipse.jpt.utility.model.event.ListReplaceEvent;
+import org.eclipse.jpt.utility.model.listener.CollectionChangeListener;
+import org.eclipse.jpt.utility.model.listener.ListChangeListener;
+import org.eclipse.jpt.utility.model.value.CollectionValueModel;
+import org.eclipse.jpt.utility.model.value.ListValueModel;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.DisposeEvent;
+import org.eclipse.swt.events.DisposeListener;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.TableColumn;
+import org.eclipse.swt.widgets.TableItem;
+
+/**
+ * This adapter provides a more object-oriented interface to the items and
+ * selected items in a table.
+ * 'listHolder' contains the data of a single column in the column.
+ * 'selectedItemsHolder' contains the data of a single column in 'listHolder'
+ * that are selected in the table.
+ */
+@SuppressWarnings("nls")
+public class TableModelAdapter<E> {
+
+	// ********** model **********
+	/**
+	 * A value model on the underlying model list.
+	 */
+	protected final ListValueModel<E> listHolder;
+
+	/**
+	 * A listener that allows us to synchronize the table's contents with
+	 * the model list.
+	 */
+	protected final ListChangeListener listChangeListener;
+
+	/**
+	 * A value model on the underlying model selections.
+	 */
+	protected final CollectionValueModel<E> selectedItemsHolder;
+
+	/**
+	 * A listener that allows us to synchronize the table's selection with
+	 * the model selections.
+	 */
+	protected final CollectionChangeListener selectedItemsChangeListener;
+
+	/**
+	 * The table we keep synchronized with the model list.
+	 */
+	protected final Table table;
+
+	/**
+	 * A listener that allows us to synchronize our selection list holder
+	 * with the table's selection.
+	 */
+	protected final SelectionListener tableSelectionListener;
+
+	/**
+	 * Clients that are interested in selection change events.
+	 */
+	@SuppressWarnings("unchecked")
+	protected final ListenerList<SelectionChangeListener> selectionChangeListenerList;
+
+	/**
+	 * Clients that are interested in double click events.
+	 */
+	@SuppressWarnings("unchecked")
+	protected final ListenerList<DoubleClickListener> doubleClickListenerList;
+
+	/**
+	 * A listener that allows us to stop listening to stuff when the table
+	 * is disposed.
+	 */
+	protected final DisposeListener tableDisposeListener;
+
+	/**
+	 * This label provider is responsible to convert a property at a column index
+	 * to a string value.
+	 */
+	protected final ITableLabelProvider labelProvider;
+
+	/**
+	 * The column adapter is responsible to return the count of columns and to
+	 * create the value holders for all the properties.
+	 */
+	private ColumnAdapter<E> columnAdapter;
+
+	/**
+	 * Keeps track of the <code>TableItemModelAdapter</code>s that were created
+	 * for each item of the list holder.
+	 */
+	private List<TableItemModelAdapter> tableItemModelAdapters;
+
+
+	// ********** static methods **********
+
+	/**
+	 * Adapt the specified model list and selection to the specified table.
+	 * Use the specified string converter to convert the model items to strings
+	 * to be displayed in the table.
+	 */
+	public static <T> TableModelAdapter<T> adapt(
+			ListValueModel<T> listHolder,
+			PropertyValueModel<T> selectedItemHolder,
+			Table table,
+			ColumnAdapter<T> columnAdapter,
+			ITableLabelProvider labelProvider)
+	{
+		return new TableModelAdapter<T>(
+			listHolder,
+			new PropertyCollectionValueModelAdapter<T>(selectedItemHolder),
+			table,
+			columnAdapter,
+			labelProvider
+		);
+	}
+
+
+	// ********** constructors **********
+
+	/**
+	 * Constructor - the list holder, selections holder, table, and
+	 * string converter are required.
+	 */
+	protected TableModelAdapter(
+			ListValueModel<E> listHolder,
+			CollectionValueModel<E> selectedItemsHolder,
+			Table table,
+			ColumnAdapter<E> columnAdapter,
+			ITableLabelProvider labelProvider)
+	{
+		super();
+		if ((listHolder == null) || (selectedItemsHolder == null) || (table == null) || (labelProvider == null)) {
+			throw new NullPointerException();
+		}
+		this.listHolder = listHolder;
+		this.selectedItemsHolder = selectedItemsHolder;
+		this.table = table;
+		this.columnAdapter = columnAdapter;
+		this.labelProvider = labelProvider;
+		this.tableItemModelAdapters = new ArrayList<TableItemModelAdapter>(columnAdapter.columnCount());
+
+		this.listChangeListener = this.buildListChangeListener();
+		this.listHolder.addListChangeListener(ListValueModel.LIST_VALUES, this.listChangeListener);
+
+		this.selectedItemsChangeListener = this.buildSelectedItemsChangeListener();
+		this.selectedItemsHolder.addCollectionChangeListener(CollectionValueModel.VALUES, this.selectedItemsChangeListener);
+
+		this.tableSelectionListener = this.buildTableSelectionListener();
+		this.table.addSelectionListener(this.tableSelectionListener);
+
+		this.selectionChangeListenerList = this.buildSelectionChangeListenerList();
+		this.doubleClickListenerList = this.buildDoubleClickListenerList();
+
+		this.tableDisposeListener = this.buildTableDisposeListener();
+		this.table.addDisposeListener(this.tableDisposeListener);
+
+		this.synchronizeTable();
+	}
+
+
+	// ********** initialization **********
+
+	protected ListChangeListener buildListChangeListener() {
+		return new SWTListChangeListenerWrapper(this.buildListChangeListener_());
+	}
+
+	protected ListChangeListener buildListChangeListener_() {
+		return new ListChangeListener() {
+			public void itemsAdded(ListAddEvent event) {
+				TableModelAdapter.this.listItemsAdded(event);
+			}
+			public void itemsRemoved(ListRemoveEvent event) {
+				TableModelAdapter.this.listItemsRemoved(event);
+			}
+			public void itemsMoved(ListMoveEvent event) {
+				TableModelAdapter.this.listItemsMoved(event);
+			}
+			public void itemsReplaced(ListReplaceEvent event) {
+				TableModelAdapter.this.listItemsReplaced(event);
+			}
+			public void listCleared(ListClearEvent event) {
+				TableModelAdapter.this.listCleared(event);
+			}
+			public void listChanged(ListChangeEvent event) {
+				TableModelAdapter.this.listChanged(event);
+			}
+			@Override
+			public String toString() {
+				return "list listener";
+			}
+		};
+	}
+
+	protected CollectionChangeListener buildSelectedItemsChangeListener() {
+		return new SWTCollectionChangeListenerWrapper(this.buildSelectedItemsChangeListener_());
+	}
+
+	protected CollectionChangeListener buildSelectedItemsChangeListener_() {
+		return new CollectionChangeListener() {
+			public void itemsAdded(CollectionAddEvent event) {
+				TableModelAdapter.this.selectedItemsAdded(event);
+			}
+			public void itemsRemoved(CollectionRemoveEvent event) {
+				TableModelAdapter.this.selectedItemsRemoved(event);
+			}
+			public void collectionCleared(CollectionClearEvent event) {
+				TableModelAdapter.this.selectedItemsCleared(event);
+			}
+			public void collectionChanged(CollectionChangeEvent event) {
+				TableModelAdapter.this.selectedItemsChanged(event);
+			}
+			@Override
+			public String toString() {
+				return "selected items listener";
+			}
+		};
+	}
+
+	protected SelectionListener buildTableSelectionListener() {
+		return new SelectionListener() {
+			public void widgetSelected(SelectionEvent event) {
+				TableModelAdapter.this.tableSelectionChanged(event);
+			}
+			public void widgetDefaultSelected(SelectionEvent event) {
+				TableModelAdapter.this.tableDoubleClicked(event);
+			}
+			@Override
+			public String toString() {
+				return "table selection listener";
+			}
+		};
+	}
+
+	@SuppressWarnings("unchecked")
+	protected ListenerList<DoubleClickListener> buildDoubleClickListenerList() {
+		return new ListenerList<DoubleClickListener>(DoubleClickListener.class);
+	}
+
+	@SuppressWarnings("unchecked")
+	protected ListenerList<SelectionChangeListener> buildSelectionChangeListenerList() {
+		return new ListenerList<SelectionChangeListener>(SelectionChangeListener.class);
+	}
+
+	protected DisposeListener buildTableDisposeListener() {
+		return new DisposeListener() {
+			public void widgetDisposed(DisposeEvent event) {
+				TableModelAdapter.this.tableDisposed(event);
+			}
+			@Override
+			public String toString() {
+				return "table dispose listener";
+			}
+		};
+	}
+
+	protected void synchronizeTable() {
+		this.synchronizeTableColumns();
+		this.synchronizeTableItems();
+		this.synchronizeTableSelection();
+	}
+
+
+	// ********** list **********
+
+	/**
+	 * Creates the table colums.
+	 */
+	protected void synchronizeTableColumns() {
+		if (this.table.isDisposed()) {
+			return;
+		}
+
+		int columnCount = this.columnAdapter.columnCount();
+
+		for (int index = 0; index < columnCount; index++) {
+			TableColumn tableColumn = new TableColumn(this.table, SWT.NULL, index);
+			tableColumn.setMoveable(false);
+			tableColumn.setResizable(true);
+			tableColumn.setWidth(100);
+
+			String columnName = this.columnAdapter.columnName(index);
+
+			if (columnName == null) {
+				columnName = "";
+			}
+
+			tableColumn.setText(columnName);
+		}
+	}
+
+	/**
+	 * Brute force synchronization of table with the model list.
+	 */
+	protected void synchronizeTableItems() {
+		if (this.table.isDisposed()) {
+			return;
+		}
+
+		for (int index = table.getItemCount(); --index >= 0; ) {
+			this.table.remove(index);
+			this.tableItemModelAdapters.remove(index);
+		}
+
+		int itemCount = this.listHolder.size();
+
+		for (int index = 0; index < itemCount; index++) {
+
+			TableItem tableItem = new TableItem(this.table, SWT.NULL, index);
+			tableItem.setData(this.listHolder.get(index));
+
+			TableItemModelAdapter adapter = buildItemModel(tableItem);
+			tableItemModelAdapters.add(adapter);
+		}
+	}
+
+	/**
+	 * The model has changed - synchronize the table.
+	 */
+	protected void listItemsAdded(ListAddEvent event) {
+
+		if (this.table.isDisposed()) {
+			return;
+		}
+
+		int index = event.getIndex();
+
+		for (E item : this.getItems(event)) {
+
+			TableItem tableItem = new TableItem(this.table, SWT.NULL, index);
+			tableItem.setData(item);
+
+			TableItemModelAdapter adapter = this.buildItemModel(tableItem);
+			tableItemModelAdapters.add(index++, adapter);
+		}
+	}
+
+	/**
+	 * The model has changed - synchronize the table.
+	 */
+	protected void listItemsRemoved(ListRemoveEvent event) {
+
+		if (this.table.isDisposed()) {
+			return;
+		}
+
+		this.table.remove(event.getIndex(), event.getIndex() + event.getItemsSize() - 1);
+
+		for (int index = event.getIndex() + event.getItemsSize(); --index >= event.getIndex(); ) {
+			tableItemModelAdapters.remove(index);
+		}
+	}
+
+	/**
+	 * The model has changed - synchronize the table.
+	 */
+	protected void listItemsMoved(ListMoveEvent event) {
+
+		if (this.table.isDisposed()) {
+			return;
+		}
+
+		int length        = event.getLength();
+		int sourceIndex   = event.getSourceIndex();
+		int targetIndex   = event.getTargetIndex();
+		int lowStartIndex = Math.min(targetIndex, sourceIndex);
+		int hiStartIndex  = Math.max(targetIndex, sourceIndex);
+
+		Object[] items = new Object[hiStartIndex - lowStartIndex + length];
+		int itemsIndex = items.length;
+
+		// Remove the TableItems wrapping the moved items
+		for (int index = hiStartIndex + length; --index >= lowStartIndex; ) {
+
+			TableItemModelAdapter tableItemModel = this.tableItemModelAdapters.get(index);
+			items[--itemsIndex] = tableItemModel.tableItem.getData();
+
+			// Remove the TableItem, which will also dispose TableItemModelAdapter
+			this.table.remove(index);
+		}
+
+		// Move the items so they can retrieved in the right order when
+		// re-creating the TableItems
+		ArrayTools.move(
+			items,
+			targetIndex - lowStartIndex,
+			sourceIndex - lowStartIndex,
+			length
+		);
+
+		itemsIndex = 0;
+
+		// Add TableItems for the moved items
+		for (int index = lowStartIndex; index <= hiStartIndex + length - 1; index++) {
+
+			// Create the new TableItem
+			TableItem tableItem = new TableItem(this.table, SWT.NULL, index);
+			tableItem.setData(items[itemsIndex++]);
+
+			// Adapt it with a model adapter
+			TableItemModelAdapter adapter = this.buildItemModel(tableItem);
+			tableItemModelAdapters.set(index, adapter);
+		}
+	}
+
+
+	private TableItemModelAdapter buildItemModel(TableItem tableItem) {
+		return TableItemModelAdapter.adapt(
+			tableItem,
+			columnAdapter,
+			labelProvider
+		);
+	}
+
+	/**
+	 * The model has changed - synchronize the table.
+	 */
+	protected void listItemsReplaced(ListReplaceEvent event) {
+		if (this.table.isDisposed()) {
+			return;
+		}
+
+		int rowIndex = event.getIndex();
+
+		for (E item : this.getNewItems(event)) {
+			TableItem tableItem = this.table.getItem(rowIndex);
+			tableItem.setData(item);
+
+			TableItemModelAdapter adapter = tableItemModelAdapters.get(rowIndex);
+
+			int columnCount = this.columnAdapter.columnCount();
+			boolean revalidate = (columnCount == 1);
+
+			for (int columnIndex = columnCount; --columnIndex >= 0; ) {
+				adapter.tableItemChanged(columnIndex, tableItem.getData(), revalidate);
+			}
+
+			rowIndex++;
+		}
+	}
+
+	/**
+	 * The model has changed - synchronize the table.
+	 */
+	protected void listCleared(@SuppressWarnings("unused") ListClearEvent event) {
+		if (this.table.isDisposed()) {
+			return;
+		}
+		this.table.removeAll();
+	}
+
+	/**
+	 * The model has changed - synchronize the table.
+	 */
+	protected void listChanged(@SuppressWarnings("unused") ListChangeEvent event) {
+		this.synchronizeTableItems();
+	}
+
+	// minimized scope of suppressed warnings
+	@SuppressWarnings("unchecked")
+	protected Iterable<E> getItems(ListAddEvent event) {
+		return (Iterable<E>) event.getItems();
+	}
+
+	// minimized scope of suppressed warnings
+	@SuppressWarnings("unchecked")
+	protected Iterable<E> getNewItems(ListReplaceEvent event) {
+		return (Iterable<E>) event.getNewItems();
+	}
+
+
+	// ********** selected items **********
+
+	protected int indexOf(E item) {
+		int len = this.listHolder.size();
+		for (int i = 0; i < len; i++) {
+			if (this.listHolder.get(i) == item) {
+				return i;
+			}
+		}
+		return -1;
+	}
+
+	protected void synchronizeTableSelection() {
+		if (this.table.isDisposed()) {
+			return;
+		}
+		int[] indices = new int[this.selectedItemsHolder.size()];
+		int i = 0;
+		for (Iterator<E> stream = this.selectedItemsHolder.iterator(); stream.hasNext(); ) {
+			indices[i++] = this.indexOf(stream.next());
+		}
+		this.table.deselectAll();
+		this.table.select(indices);
+	}
+
+	protected void selectedItemsAdded(CollectionAddEvent event) {
+		if (this.table.isDisposed()) {
+			return;
+		}
+		this.table.select(this.getIndices(event.getItemsSize(), this.getItems(event)));
+	}
+
+	protected void selectedItemsRemoved(CollectionRemoveEvent event) {
+		if (this.table.isDisposed()) {
+			return;
+		}
+		this.table.deselect(this.getIndices(event.getItemsSize(), this.getItems(event)));
+	}
+
+	protected int[] getIndices(int itemsSize, Iterable<E> items) {
+		int[] indices = new int[itemsSize];
+		int i = 0;
+		for (E item : items) {
+			indices[i++] = this.indexOf(item);
+		}
+		return indices;
+	}
+
+	protected void selectedItemsCleared(@SuppressWarnings("unused") CollectionClearEvent event) {
+		if (this.table.isDisposed()) {
+			return;
+		}
+		this.table.deselectAll();
+	}
+
+	protected void selectedItemsChanged(@SuppressWarnings("unused") CollectionChangeEvent event) {
+		this.synchronizeTableSelection();
+	}
+
+	// minimized scope of suppressed warnings
+	@SuppressWarnings("unchecked")
+	protected Iterable<E> getItems(CollectionAddEvent event) {
+		return (Iterable<E>) event.getItems();
+	}
+
+	// minimized scope of suppressed warnings
+	@SuppressWarnings("unchecked")
+	protected Iterable<E> getItems(CollectionRemoveEvent event) {
+		return (Iterable<E>) event.getItems();
+	}
+
+
+	// ********** list box events **********
+
+	@SuppressWarnings("unchecked")
+	protected void tableSelectionChanged(@SuppressWarnings("unused") SelectionEvent event) {
+		if (this.selectionChangeListenerList.size() > 0) {
+			SelectionChangeEvent<E> scEvent = new SelectionChangeEvent(this, this.selectedItems());
+			for (SelectionChangeListener<E> selectionChangeListener : this.selectionChangeListenerList.getListeners()) {
+				selectionChangeListener.selectionChanged(scEvent);
+			}
+		}
+	}
+
+	@SuppressWarnings("unchecked")
+	protected Collection<E> selectedItems() {
+		if (this.table.isDisposed()) {
+			return Collections.emptySet();
+		}
+		ArrayList<E> selectedItems = new ArrayList(this.table.getSelectionCount());
+		for (int selectionIndex : this.table.getSelectionIndices()) {
+			selectedItems.add(this.listHolder.get(selectionIndex));
+		}
+		return selectedItems;
+	}
+
+	@SuppressWarnings("unchecked")
+	protected void tableDoubleClicked(@SuppressWarnings("unused") SelectionEvent event) {
+		if (this.table.isDisposed()) {
+			return;
+		}
+		if (this.doubleClickListenerList.size() > 0) {
+			// there should be only a single item selected during a double-click(?)
+			E selection = this.listHolder.get(this.table.getSelectionIndex());
+			DoubleClickEvent<E> dcEvent = new DoubleClickEvent(this, selection);
+			for (DoubleClickListener<E> doubleClickListener : this.doubleClickListenerList.getListeners()) {
+				doubleClickListener.doubleClick(dcEvent);
+			}
+		}
+	}
+
+
+	// ********** dispose **********
+
+	protected void tableDisposed(@SuppressWarnings("unused") DisposeEvent event) {
+		// the table is not yet "disposed" when we receive this event
+		// so we can still remove our listeners
+		this.table.removeDisposeListener(this.tableDisposeListener);
+		this.table.removeSelectionListener(this.tableSelectionListener);
+		this.selectedItemsHolder.removeCollectionChangeListener(CollectionValueModel.VALUES, this.selectedItemsChangeListener);
+		this.listHolder.removeListChangeListener(ListValueModel.LIST_VALUES, this.listChangeListener);
+	}
+
+
+	// ********** standard methods **********
+
+	@Override
+	public String toString() {
+		return StringTools.buildToStringFor(this, this.listHolder);
+	}
+
+
+	// ********** double click support **********
+
+	public void addDoubleClickListener(DoubleClickListener<E> listener) {
+		this.doubleClickListenerList.add(listener);
+	}
+
+	public void removeDoubleClickListener(DoubleClickListener<E> listener) {
+		this.doubleClickListenerList.remove(listener);
+	}
+
+	public interface DoubleClickListener<E> extends EventListener {
+		void doubleClick(DoubleClickEvent<E> event);
+	}
+
+	public static class DoubleClickEvent<E> extends EventObject {
+		private final E selection;
+		private static final long serialVersionUID = 1L;
+
+		protected DoubleClickEvent(TableModelAdapter<E> source, E selection) {
+			super(source);
+			if (selection == null) {
+				throw new NullPointerException();
+			}
+			this.selection = selection;
+		}
+
+		@Override
+		@SuppressWarnings("unchecked")
+		public TableModelAdapter<E> getSource() {
+			return (TableModelAdapter<E>) super.getSource();
+		}
+
+		public E selection() {
+			return this.selection;
+		}
+
+	}
+
+
+	// ********** selection support **********
+
+	public void addSelectionChangeListener(SelectionChangeListener<E> listener) {
+		this.selectionChangeListenerList.add(listener);
+	}
+
+	public void removeSelectionChangeListener(SelectionChangeListener<E> listener) {
+		this.selectionChangeListenerList.remove(listener);
+	}
+
+	public interface SelectionChangeListener<E> extends EventListener {
+		void selectionChanged(SelectionChangeEvent<E> event);
+	}
+
+	public static class SelectionChangeEvent<E> extends EventObject {
+		private final Collection<E> selection;
+		private static final long serialVersionUID = 1L;
+
+		protected SelectionChangeEvent(TableModelAdapter<E> source, Collection<E> selection) {
+			super(source);
+			if (selection == null) {
+				throw new NullPointerException();
+			}
+			this.selection = selection;
+		}
+
+		@Override
+		@SuppressWarnings("unchecked")
+		public TableModelAdapter<E> getSource() {
+			return (TableModelAdapter<E>) super.getSource();
+		}
+
+		public Iterator<E> selection() {
+			return this.selection.iterator();
+		}
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/swt/TriStateCheckBoxModelAdapter.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/swt/TriStateCheckBoxModelAdapter.java
new file mode 100644
index 0000000..1ca8be5
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/swt/TriStateCheckBoxModelAdapter.java
@@ -0,0 +1,188 @@
+/*******************************************************************************
+ * Copyright (c) 2008 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.ui.internal.swt;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.jpt.ui.internal.listeners.SWTPropertyChangeListenerWrapper;
+import org.eclipse.jpt.ui.internal.widgets.TriStateCheckBox;
+import org.eclipse.jpt.utility.internal.StringTools;
+import org.eclipse.jpt.utility.model.event.PropertyChangeEvent;
+import org.eclipse.jpt.utility.model.listener.PropertyChangeListener;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.jpt.utility.model.value.WritablePropertyValueModel;
+import org.eclipse.swt.events.DisposeEvent;
+import org.eclipse.swt.events.DisposeListener;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+
+/**
+ * This adapter can be used to keep a tri-state check box in synch with
+ * a model Boolean where the value can be <code>null</code>.
+ */
+@SuppressWarnings("nls")
+public class TriStateCheckBoxModelAdapter {
+
+	/** A value model on the underlying model boolean. */
+	protected final WritablePropertyValueModel<Boolean> booleanHolder;
+
+	/**
+	 * A listener that allows us to synchronize the button's selection state with
+	 * the model boolean.
+	 */
+	protected final PropertyChangeListener booleanChangeListener;
+
+	/** The check box/toggle button we synchronize with the model boolean. */
+	protected final TriStateCheckBox button;
+
+	/**
+	 * A listener that allows us to synchronize the model boolean with
+	 * the button's selection state.
+	 */
+	protected final SelectionListener buttonSelectionListener;
+
+	/**
+	 * A listener that allows us to stop listening to stuff when the button
+	 * is disposed.
+	 */
+	protected final DisposeListener buttonDisposeListener;
+
+
+	// ********** static methods **********
+
+	/**
+	 * Adapt the specified boolean to the specified button.
+	 * If the boolean is null, the button's value will be "partially checked"
+	 * (i.e. the button will be checked but grayed out).
+	 */
+	public static TriStateCheckBoxModelAdapter adapt(WritablePropertyValueModel<Boolean> booleanHolder, TriStateCheckBox button) {
+		return new TriStateCheckBoxModelAdapter(booleanHolder, button);
+	}
+
+
+	// ********** constructors **********
+
+	/**
+	 * Constructor - the boolean holder and button are required.
+	 */
+	protected TriStateCheckBoxModelAdapter(WritablePropertyValueModel<Boolean> booleanHolder, TriStateCheckBox button) {
+		super();
+
+		Assert.isNotNull(booleanHolder, "The boolean holder cannot be null");
+		Assert.isNotNull(button, "The check box cannot be null");
+
+		this.booleanHolder = booleanHolder;
+		this.button = button;
+
+		this.booleanChangeListener = this.buildBooleanChangeListener();
+		this.booleanHolder.addPropertyChangeListener(PropertyValueModel.VALUE, this.booleanChangeListener);
+
+		this.buttonDisposeListener = this.buildButtonDisposeListener();
+		this.button.addDisposeListener(this.buttonDisposeListener);
+
+		this.buttonSelectionListener = this.buildButtonSelectionListener();
+		this.button.addSelectionListener(this.buttonSelectionListener);
+
+		this.setButtonSelection(this.booleanHolder.getValue());
+	}
+
+
+	// ********** initialization **********
+
+	protected PropertyChangeListener buildBooleanChangeListener() {
+		return new SWTPropertyChangeListenerWrapper(this.buildBooleanChangeListener_());
+	}
+
+	protected PropertyChangeListener buildBooleanChangeListener_() {
+		return new PropertyChangeListener() {
+			public void propertyChanged(PropertyChangeEvent event) {
+				TriStateCheckBoxModelAdapter.this.booleanChanged(event);
+			}
+			@Override
+			public String toString() {
+				return "tri-state boolean listener";
+			}
+		};
+	}
+
+	protected SelectionListener buildButtonSelectionListener() {
+		return new SelectionAdapter() {
+			@Override
+			public void widgetSelected(SelectionEvent event) {
+				TriStateCheckBoxModelAdapter.this.buttonSelected(event);
+			}
+			@Override
+			public String toString() {
+				return "tri-state button selection listener";
+			}
+		};
+	}
+
+	protected DisposeListener buildButtonDisposeListener() {
+		return new DisposeListener() {
+			public void widgetDisposed(DisposeEvent event) {
+				TriStateCheckBoxModelAdapter.this.buttonDisposed(event);
+			}
+		    @Override
+			public String toString() {
+				return "tri-state button dispose listener";
+			}
+		};
+	}
+
+
+	// ********** behavior **********
+
+	/**
+	 * The model has changed - synchronize the button.
+	 * If the new model value is null, use the adapter's default value
+	 * (which is typically false).
+	 */
+	protected void booleanChanged(PropertyChangeEvent event) {
+		this.setButtonSelection((Boolean) event.getNewValue());
+	}
+
+	protected void setButtonSelection(Boolean selection) {
+		if (this.button.isDisposed()) {
+			return;
+		}
+		this.button.setSelection(selection);
+	}
+
+	/**
+	 * The button has been "selected" - synchronize the model.
+	 */
+	protected void buttonSelected(SelectionEvent event) {
+		if (this.button.isDisposed()) {
+			return;
+		}
+		this.booleanHolder.setValue(button.getSelection());
+	}
+
+
+	// ********** dispose **********
+
+	protected void buttonDisposed(DisposeEvent event) {
+		// the button is not yet "disposed" when we receive this event
+		// so we can still remove our listeners
+		this.button.removeSelectionListener(this.buttonSelectionListener);
+		this.button.removeDisposeListener(this.buttonDisposeListener);
+		this.booleanHolder.removePropertyChangeListener(PropertyValueModel.VALUE, this.booleanChangeListener);
+	}
+
+
+	// ********** standard methods **********
+
+    @Override
+	public String toString() {
+		return StringTools.buildToStringFor(this, this.booleanHolder);
+	}
+
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/util/ControlAligner.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/util/ControlAligner.java
new file mode 100644
index 0000000..a9ff3ba
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/util/ControlAligner.java
@@ -0,0 +1,913 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 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.ui.internal.util;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.jpt.utility.internal.StringTools;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Listener;
+
+/**
+ * This class is responsible to set a preferred width on the registered widgets
+ * (either <code>Control</code> or <code>ControlAligner</code>) based on the
+ * widest widget.
+ * <p>
+ * Important: The layout data has to be a <code>GridData</code>. If none is set,
+ * then a new <code>GridData</code> is automatically created.
+ * <p>
+ * Here an example of the result if this aligner is used to align controls
+ * within either one or two group boxes, the controls added are the labels in
+ * this case. It is also possible to align controls on the right side of the
+ * main component, a spacer can be used for extra space.
+ * <p>
+ * Here's an example:
+ * <pre>
+ * - Group Box 1 --------------------------------------------------------------
+ * |                     -------------------------------------- ------------- |
+ * | Name:               | I                                  | | Browse... | |
+ * |                     -------------------------------------- ------------- |
+ * |                     ---------                                            |
+ * | Preallocation Size: |     |I|                                            |
+ * |                     ---------                                            |
+ * |                     --------------------------------------               |
+ * | Descriptor:         |                                  |v|               |
+ * |                     --------------------------------------               |
+ * ----------------------------------------------------------------------------
+ *
+ * - Group Box 2 --------------------------------------------------------------
+ * |                     --------------------------------------               |
+ * | Mapping Type:       |                                  |V|               |
+ * |                     --------------------------------------               |
+ * |                     --------------------------------------               |
+ * | Check in Script:    | I                                  |               |
+ * |                     --------------------------------------               |
+ * ----------------------------------------------------------------------------</pre>
+ *
+ * @version 2.0
+ * @since 2.0
+ */
+@SuppressWarnings("nls")
+public final class ControlAligner
+{
+	/**
+	 * Flag used to prevent a validation so it can be done after an operation
+	 * completed.
+	 */
+	private boolean autoValidate;
+
+	/**
+	 * The utility class used to support bound properties.
+	 */
+	private Collection<Listener> changeSupport;
+
+	/**
+	 * The listener added to each of the controls that listens only to a text
+	 * change.
+	 */
+	private Listener listener;
+
+	/**
+	 * Prevents infinite recursion when recalculating the preferred width.
+	 * This happens in an hierarchy of <code>ControlAligner</code>s. The lock
+	 * has to be placed here and not in the {@link ControlAlignerWrapper}.
+	 */
+	private boolean locked;
+
+	/**
+	 * The length of the widest control. If the length was not calculated, then
+	 * this value is 0.
+	 */
+	private int maximumWidth;
+
+	/**
+	 * The collection of {@link Wrapper}s encapsulating either <code>Control</code>s
+	 * or {@link ControlAligner}s.
+	 */
+	private Collection<Wrapper> wrappers;
+
+	/**
+	 * A null-<code>Point</code> object used to clear the preferred size.
+	 */
+	private static final Point DEFAULT_SIZE = new Point(SWT.DEFAULT, SWT.DEFAULT);
+
+	/**
+	 * The types of events to listen in order to properly adjust the size of all
+	 * the widgets.
+	 */
+	private static final int[] EVENT_TYPES = {
+		SWT.Dispose,
+		SWT.Hide,
+		SWT.Resize,
+		SWT.Show
+	};
+
+	/**
+	 * Creates a new <code>ControlAligner</code>.
+	 */
+	public ControlAligner() {
+		super();
+		initialize();
+	}
+
+	/**
+	 * Creates a new <code>ControlAligner</code>.
+	 *
+	 * @param controls The collection of <code>Control</code>s
+	 */
+	public ControlAligner(Collection<? extends Control> controls) {
+		this();
+		addAllControls(controls);
+	}
+
+	/**
+	 * Adds the given control. Its width will be used along with the width of all
+	 * the other registered controls in order to get the greater witdh and use
+	 * it as the width for all the controls.
+	 *
+	 * @param control The <code>Control</code> to be added
+	 */
+	public void add(Control control) {
+
+		Assert.isNotNull(control, "Can't add null to this ControlAligner");
+
+		Wrapper wrapper = buildWrapper(control);
+		wrapper.addListener(listener);
+		wrappers.add(wrapper);
+
+		revalidate(false);
+	}
+
+	/**
+	 * Adds the given control. Its width will be used along with the width of all
+	 * the other registered controls in order to get the greater witdh and use
+	 * it as the width for all the controls.
+	 *
+	 * @param controlAligner The <code>ControlAligner</code> to be added
+	 * @exception IllegalArgumentException Can't add the <code>ControlAligner</code>
+	 * to itself
+	 */
+	public void add(ControlAligner controlAligner) {
+
+		Assert.isNotNull(controlAligner, "Can't add null to this ControlAligner");
+		Assert.isLegal(controlAligner != this, "Can't add the ControlAligner to itself");
+
+		Wrapper wrapper = buildWrapper(controlAligner);
+		wrapper.addListener(listener);
+		wrappers.add(wrapper);
+
+		if (!controlAligner.wrappers.isEmpty()) {
+			revalidate(false);
+		}
+	}
+
+	/**
+	 * Adds the items contained in the given collection into this
+	 * <code>ControlAligner</code>. The preferred width of each item will be
+	 * used along with the width of all the other items in order to get the
+	 * widest control and use its width as the width for all the controls.
+	 *
+	 * @param aligners The collection of <code>ControlAligner</code>s
+	 */
+	public void addAllControlAligners(Collection<ControlAligner> aligners) {
+
+		// Deactivate the auto validation while adding all the Controls and/or
+		// ControlAligners in order to improve performance
+		boolean oldAutoValidate = autoValidate;
+		autoValidate = false;
+
+		for (ControlAligner aligner : aligners) {
+			add(aligner);
+		}
+
+		autoValidate = oldAutoValidate;
+		revalidate(false);
+	}
+
+   /**
+	 * Adds the items contained in the given collection into this
+	 * <code>ControlAligner</code>. The preferred width of each item will be
+	 * used along with the width of all the other items in order to get the
+	 * widest control and use its width as the width for all the controls.
+	 *
+	 * @param controls The collection of <code>Control</code>s
+	 */
+	public void addAllControls(Collection<? extends Control> controls) {
+
+		// Deactivate the auto validation while adding all the Controls and/or
+		// ControlAligners in order to improve performance
+		boolean oldAutoValidate = autoValidate;
+		autoValidate = false;
+
+		for (Control control : controls) {
+			add(control);
+		}
+
+		autoValidate = oldAutoValidate;
+		revalidate(false);
+	}
+
+   /**
+	 * Adds the given <code>ControListener</code>.
+	 *
+	 * @param listener The <code>Listener</code> to be added
+	 */
+	private void addListener(Listener listener) {
+
+		if (changeSupport == null) {
+		    changeSupport = new ArrayList<Listener>();
+		}
+
+		changeSupport.add(listener);
+   }
+
+	/**
+	 * Creates a new <code>Wrapper</code> that encapsulates the given source.
+	 *
+	 * @param control The control to be wrapped
+	 * @return A new {@link Wrapper}
+	 */
+	private Wrapper buildWrapper(Control control) {
+		return new ControlWrapper(control);
+	}
+
+   /**
+	 * Creates a new <code>Wrapper</code> that encapsulates the given source.
+	 *
+	 * @param ControlAligner The <code>ControlAligner</code> to be wrapped
+	 * @return A new {@link ControlAlignerWrapper}
+	 */
+	private Wrapper buildWrapper(ControlAligner ControlAligner) {
+		return new ControlAlignerWrapper(ControlAligner);
+	}
+
+	/**
+	 * Calculates the width taken by the widgets and returns the maximum width.
+	 *
+	 * @param recalculateSize <code>true</code> to recalculate the preferred size
+	 * of all the wrappers contained within them rather than using the cached
+	 * size; <code>false</code> to use the cached size
+	 */
+	private int calculateWidth(boolean recalculateSize) {
+
+		int width = 0;
+
+		for (Wrapper wrapper : wrappers) {
+			Point size = wrapper.cachedSize();
+
+			// The size has not been calculated yet
+			if (recalculateSize || (size.x == 0)) {
+				size = wrapper.calculateSize();
+			}
+
+			// Only keep the greatest width
+			width = Math.max(size.x, width);
+		}
+
+		return width;
+	}
+
+	/**
+	 * Reports a bound property change.
+	 *
+	 * @param oldValue the old value of the property (as an int)
+	 * @param newValue the new value of the property (as an int)
+	 */
+	private void controlResized(int oldValue, int newValue) {
+
+		if ((changeSupport != null) && (oldValue != newValue)) {
+			Event event  = new Event();
+			event.widget = SWTUtil.getShell();
+			event.data   = this;
+
+			for (Listener listener : changeSupport) {
+				listener.handleEvent(event);
+			}
+		}
+	}
+
+	/**
+	 * Disposes this <code>ControlAligner</code>, this can improve the speed of
+	 * disposing a pane. When a pane is disposed, this aligner doesn't need to
+	 * revalidate its size upon dispose of its widgets.
+	 */
+	public void dispose() {
+
+		for (Iterator<Wrapper> iter = wrappers.iterator(); iter.hasNext(); ) {
+			Wrapper wrapper = iter.next();
+			wrapper.removeListener(listener);
+			iter.remove();
+		}
+
+		this.wrappers.clear();
+	}
+
+	/**
+	 * Returns the length of the widest control. If the length was not
+	 * calculated, then this value is 0.
+	 *
+	 * @return The width of the widest control or 0 if the length has not been
+	 * calculated yet
+	 */
+	public int getMaximumWidth() {
+		return maximumWidth;
+	}
+
+	/**
+	 * Initializes this <code>ControlAligner</code>.
+	 */
+	private void initialize() {
+
+		this.autoValidate = true;
+		this.maximumWidth = 0;
+		this.listener     = new ListenerHandler();
+		this.wrappers     = new ArrayList<Wrapper>();
+	}
+
+	/**
+	 * Invalidates the size of the given object.
+	 *
+	 * @param source The source object to be invalidated
+	 */
+	private void invalidate(Object source) {
+
+		Wrapper wrapper = retrieveWrapper(source);
+
+		if (!wrapper.locked()) {
+			Point size = wrapper.cachedSize();
+			size.x = size.y = 0;
+			wrapper.setSize(DEFAULT_SIZE);
+		}
+	}
+
+	/**
+	 * Updates the maximum length based on the widest control. This methods
+	 * does not update the width of the controls.
+	 *
+	 * @param recalculateSize <code>true</code> to recalculate the preferred size
+	 * of all the wrappers contained within them rather than using the cached
+	 * size; <code>false</code> to use the cached size
+	 */
+	private void recalculateWidth(boolean recalculateSize) {
+
+		int width = calculateWidth(recalculateSize);
+
+		try {
+			locked = true;
+			setMaximumWidth(width);
+		}
+		finally {
+			locked = false;
+		}
+	}
+
+	/**
+	 * Removes the given control. Its preferred width will not be used when
+	 * calculating the preferred width.
+	 *
+	 * @param control The control to be removed
+	 * @exception AssertionFailedException If the given <code>Control</code> is
+	 * <code>null</code>
+	 */
+	public void remove(Control control) {
+
+		Assert.isNotNull(control, "The Control to remove cannot be null");
+
+		Wrapper wrapper = retrieveWrapper(control);
+		wrapper.removeListener(listener);
+		wrappers.remove(wrapper);
+
+		revalidate(true);
+	}
+
+	/**
+	 * Removes the given <code>ControlAligner</code>. Its preferred width
+	 * will not be used when calculating the preferred witdh.
+	 *
+	 * @param controlAligner The <code>ControlAligner</code> to be removed
+	 * @exception AssertionFailedException If the given <code>ControlAligner</code>
+	 * is <code>null</code>
+	 */
+	public void remove(ControlAligner controlAligner) {
+
+		Assert.isNotNull(controlAligner, "The ControlAligner to remove cannot be null");
+
+		Wrapper wrapper = retrieveWrapper(controlAligner);
+		wrapper.removeListener(listener);
+		wrappers.remove(wrapper);
+
+		revalidate(true);
+	}
+
+	/**
+	 * Removes the given <code>Listener</code>.
+	 *
+	 * @param listener The <code>Listener</code> to be removed
+	 */
+	private void removeListener(Listener listener) {
+
+		changeSupport.remove(listener);
+
+		if (changeSupport.isEmpty()) {
+			changeSupport = null;
+		}
+	}
+
+	/**
+	 * Retrieves the <code>Wrapper</code> that is encapsulating the given object.
+	 *
+	 * @param source Either a <code>Control</code> or a <code>ControlAligner</code>
+	 * @return Its <code>Wrapper</code>
+	 */
+	private Wrapper retrieveWrapper(Object source) {
+
+		for (Wrapper wrapper : wrappers) {
+			if (wrapper.source() == source) {
+				return wrapper;
+			}
+		}
+
+		throw new IllegalArgumentException("Can't retrieve the Wrapper for " + source);
+	}
+
+	/**
+	 * If the count of control is greater than one and {@link #isAutoValidate()}
+	 * returns <code>true</code>, then the size of all the registered
+	 * <code>Control</code>s will be udpated.
+	 *
+	 * @param recalculateSize <code>true</code> to recalculate the preferred size
+	 * of all the wrappers contained within them rather than using the cached
+	 * size; <code>false</code> to use the cached size
+	 */
+	private void revalidate(boolean recalculateSize) {
+
+		if (autoValidate) {
+			recalculateWidth(recalculateSize);
+			updateWrapperSize(recalculateSize);
+		}
+	}
+
+	/**
+	 * Bases on the information contained in the given <code>Event</code>,
+	 * resize the controls.
+	 *
+	 * @param event The <code>Event</code> sent by the UI thread when the state
+	 * of a widget changed
+	 */
+	private void revalidate(Event event) {
+
+		// We don't need to revalidate during a revalidation process
+		if (locked) {
+			return;
+		}
+
+		Object source;
+
+		if (event.widget != SWTUtil.getShell()) {
+			source = event.widget;
+			Control control = (Control) source;
+
+			// When a dialog is opened, we need to actually force a layout of
+			// the controls, this is required because the control is actually
+			// not visible when the preferred width is caculated
+			if (control == control.getShell()) {
+				if (event.type == SWT.Dispose) {
+					return;
+				}
+
+				source = null;
+			}
+		}
+		else {
+			source = event.data;
+		}
+
+		// Either remove the ControlWrapper if the widget was disposed or
+		// invalidate the widget in order to recalculate the preferred size
+		if (source != null) {
+			if (event.type == SWT.Dispose) {
+				Wrapper wrapper = retrieveWrapper(source);
+				wrappers.remove(wrapper);
+			}
+			else {
+				invalidate(source);
+			}
+		}
+
+		// Now revalidate all the Controls and ControlAligners
+		revalidate(true);
+	}
+
+	/**
+	 * Sets the length of the widest control. If the length was not calulcated,
+	 * then this value is 0.
+	 *
+	 * @param maximumWidth The width of the widest control
+	 */
+	private void setMaximumWidth(int maximumWidth) {
+
+		int oldMaximumWidth = this.maximumWidth;
+		this.maximumWidth = maximumWidth;
+		controlResized(oldMaximumWidth, maximumWidth);
+	}
+
+	/**
+	 * Returns a string representation of this <code>ControlAligner</code>.
+	 *
+	 * @return Information about this object
+	 */
+	@Override
+	public String toString() {
+
+		StringBuffer sb = new StringBuffer();
+		sb.append("maximumWidth=");
+		sb.append(maximumWidth);
+		sb.append(", wrappers=");
+		sb.append(wrappers);
+		return StringTools.buildToStringFor(this, sb);
+	}
+
+	/**
+	 * Updates the size of every <code>Wrapper</code> based on the maximum width.
+	 *
+	 * @param forceRevalidate <code>true</code> to revalidate the wrapper's size
+	 * even though its current size might be the same as the maximum width;
+	 * <code>false</code> to only revalidate the wrappers with a different width
+	 */
+	private void updateWrapperSize(boolean forceRevalidate) {
+
+		for (Wrapper wrapper : wrappers) {
+			Point cachedSize = wrapper.cachedSize();
+
+			// No need to change the size of the wrapper since it's always using
+			// the maximum width
+			if (forceRevalidate || (cachedSize.x != maximumWidth)) {
+				Point size = new Point(maximumWidth, cachedSize.y);
+				wrapper.setSize(size);
+			}
+		}
+	}
+
+	/**
+	 * This <code>Wrapper</code> encapsulates a {@link ControlAligner}.
+	 */
+	private class ControlAlignerWrapper implements Wrapper {
+		/**
+		 * The cached size, which is {@link ControlAligner#maximumWidth}.
+		 */
+		private final Point cachedSize;
+
+		/**
+		 * The <code>ControlAligner</code> encapsulated by this
+		 * <code>Wrapper</code>.
+		 */
+		private final ControlAligner controlAligner;
+
+		/**
+		 * Creates a new <code>ControlAlignerWrapper</code> that encapsulates
+		 * the given <code>ControlAligner</code>.
+		 *
+		 * @param controlAligner The <code>ControlAligner</code> to be
+		 * encapsulated by this <code>Wrapper</code>
+		 */
+		private ControlAlignerWrapper(ControlAligner controlAligner) {
+			super();
+			this.controlAligner = controlAligner;
+			this.cachedSize     = new Point(controlAligner.maximumWidth, 0);
+		}
+
+		/*
+		 * (non-Javadoc)
+		 */
+		public void addListener(Listener listener) {
+			controlAligner.addListener(listener);
+		}
+
+		/*
+		 * (non-Javadoc)
+		 */
+		public Point cachedSize() {
+			cachedSize.x = controlAligner.maximumWidth;
+			return cachedSize;
+		}
+
+		/*
+		 * (non-Javadoc)
+		 */
+		public Point calculateSize() {
+
+			Point size = new Point(controlAligner.calculateWidth(false), 0);
+
+			if (size.x != SWT.DEFAULT) {
+				cachedSize.x = size.x;
+			}
+			else {
+				cachedSize.x = 0;
+			}
+
+			if (size.y != SWT.DEFAULT) {
+				cachedSize.y = size.y;
+			}
+			else {
+				cachedSize.y = 0;
+			}
+
+			return size;
+		}
+
+		/*
+		 * (non-Javadoc)
+		 */
+		public boolean locked() {
+			return controlAligner.locked;
+		}
+
+		/*
+		 * (non-Javadoc)
+		 */
+		public void removeListener(Listener listener) {
+			controlAligner.removeListener(listener);
+		}
+
+		/*
+		 * (non-Javadoc)
+		 */
+		public void setSize(Point size) {
+
+			if (size == DEFAULT_SIZE) {
+				controlAligner.maximumWidth = 0;
+			}
+			else if (controlAligner.maximumWidth != size.x) {
+				controlAligner.maximumWidth = size.x;
+				controlAligner.updateWrapperSize(true);
+			}
+		}
+
+		/*
+		 * (non-Javadoc)
+		 */
+		public Object source() {
+			return controlAligner;
+		}
+
+		/*
+		 * (non-Javadoc)
+		 */
+		@Override
+		public String toString() {
+
+			StringBuffer sb = new StringBuffer();
+			sb.append("Cached size=");
+			sb.append(cachedSize);
+			sb.append(", ControlAligner=");
+			sb.append(controlAligner);
+			return StringTools.buildToStringFor(this, sb);
+		}
+	}
+
+	/**
+	 * This <code>Wrapper</code> encapsulates a {@link Control}.
+	 */
+	private class ControlWrapper implements Wrapper {
+		/**
+		 * The cached size, which is control's size.
+		 */
+		private Point cachedSize;
+
+		/**
+		 * The control to be encapsulated by this <code>Wrapper</code>.
+		 */
+		private final Control control;
+
+		/**
+		 * Creates a new <code>controlWrapper</code> that encapsulates the given
+		 * control.
+		 *
+		 * @param control The control to be encapsulated by this <code>Wrapper</code>
+		 */
+		private ControlWrapper(Control control) {
+			super();
+
+			this.control    = control;
+			this.cachedSize = new Point(0, 0);
+		}
+
+		/*
+		 * (non-Javadoc)
+		 */
+		public void addListener(Listener listener) {
+
+			for (int eventType : EVENT_TYPES) {
+				control.addListener(eventType, listener);
+			}
+		}
+
+		/*
+		 * (non-Javadoc)
+		 */
+		public Point cachedSize() {
+			return cachedSize;
+		}
+
+		/*
+		 * (non-Javadoc)
+		 */
+		public Point calculateSize() {
+
+			cachedSize = control.computeSize(SWT.DEFAULT, SWT.DEFAULT, true);
+
+			// Update right away the control's GridData
+			GridData gridData = (GridData) control.getLayoutData();
+
+			if (gridData == null) {
+				gridData = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING);
+				control.setLayoutData(gridData);
+			}
+
+			gridData.widthHint  = cachedSize.x;
+			gridData.heightHint = cachedSize.y;
+
+			// Make sure the size is not -1
+			if (cachedSize.x == SWT.DEFAULT) {
+				cachedSize.x = 0;
+			}
+
+			if (cachedSize.y == SWT.DEFAULT) {
+				cachedSize.y = 0;
+			}
+
+			return cachedSize;
+		}
+
+		/*
+		 * (non-Javadoc)
+		 */
+		public boolean locked() {
+			return false;
+		}
+
+		/*
+		 * (non-Javadoc)
+		 */
+		public void removeListener(Listener listener) {
+
+			for (int eventType : EVENT_TYPES) {
+				control.removeListener(eventType, listener);
+			}
+		}
+
+		/*
+		 * (non-Javadoc)
+		 */
+		public void setSize(Point size) {
+
+			if (control.isDisposed()) {
+				return;
+			}
+
+			// Update the GridData with the new size
+			GridData gridData = (GridData) control.getLayoutData();
+
+			if (gridData == null) {
+				gridData = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING);
+				control.setLayoutData(gridData);
+			}
+
+			gridData.widthHint  = size.x;
+			gridData.heightHint = size.y;
+
+			// Force the control to be resized, and tell its parent to layout
+			// its widgets
+			if (size.x > 0) {
+//				locked = true;
+//				try  {
+////					control.getParent().layout(new Control[] { control });
+//					control.getParent().layout(true);
+//				}
+//				finally {
+//					locked = false;
+//				}
+				Rectangle bounds = control.getBounds();
+
+				// Only update the control's width if it's
+				// different from the current size
+				if (bounds.width != size.x) {
+					locked = true;
+
+					try {
+//						control.setBounds(bounds.x, bounds.y, size.x, size.y);
+						control.getParent().layout(true);
+					}
+					finally
+					{
+						locked = false;
+					}
+				}
+			}
+		}
+
+		/*
+		 * (non-Javadoc)
+		 */
+		public Control source() {
+			return control;
+		}
+
+		/*
+		 * (non-Javadoc)
+		 */
+		@Override
+		public String toString() {
+
+			StringBuffer sb = new StringBuffer();
+			sb.append("Cached size=");
+			sb.append(cachedSize);
+			sb.append(", Control=");
+			sb.append(control);
+			return StringTools.buildToStringFor(this, sb);
+		}
+	}
+
+	/**
+	 * The listener added to each of the control that is notified in order to
+	 * revalidate the preferred size.
+	 */
+	private class ListenerHandler implements Listener {
+		public void handleEvent(Event event) {
+			ControlAligner.this.revalidate(event);
+		}
+	}
+
+	/**
+	 * This <code>Wrapper</code> helps to encapsulate heterogeneous objects and
+	 * apply the same behavior on them.
+	 */
+	private interface Wrapper {
+	   /**
+		 * Adds the given <code>Listener</code> to wrapped object in order to
+		 * receive notification when its property changed.
+		 *
+		 * @param listener The <code>Listener</code> to be added
+		 */
+		void addListener(Listener listener);
+
+		/**
+		 * Returns the cached size of the encapsulated source.
+		 *
+		 * @return A non-<code>null</code> <code>Point</code> where the x is the
+		 * width and the y is the height of the widget
+		 */
+		Point cachedSize();
+
+		/**
+		 * Calculates the preferred size the wrapped object would take by itself.
+		 *
+		 * @return The calculated size
+		 */
+		Point calculateSize();
+
+		/**
+		 * Prevents infinite recursion when recalculating the preferred width.
+		 * This happens in an hierarchy of <code>ControlAligner</code>s.
+		 *
+		 * @return <code>true</code> to prevent this <code>Wrapper</code> from
+		 * being invalidated; otherwise <code>false</code>
+		 */
+		boolean locked();
+
+		/**
+		 * Removes the given <code>Listener</code>.
+		 *
+		 * @param listener The <code>Listener</code> to be removed
+		 */
+		void removeListener(Listener listener);
+
+		/**
+		 * Sets the size on the encapsulated source.
+		 *
+		 * @param size The new size
+		 */
+		void setSize(Point size);
+
+		/**
+		 * Returns the encapsulated object.
+		 *
+		 * @return The object that is been wrapped
+		 */
+		Object source();
+	}
+}
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/util/ControlSwitcher.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/util/ControlSwitcher.java
new file mode 100644
index 0000000..944631a
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/util/ControlSwitcher.java
@@ -0,0 +1,130 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2010 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.ui.internal.util;
+
+import org.eclipse.jpt.ui.internal.listeners.SWTPropertyChangeListenerWrapper;
+import org.eclipse.jpt.utility.internal.Transformer;
+import org.eclipse.jpt.utility.model.event.PropertyChangeEvent;
+import org.eclipse.jpt.utility.model.listener.PropertyChangeListener;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.ui.part.PageBook;
+
+/**
+ * This controller is responsible to switch the active page based on a value. A
+ * <code>Transformer</code> is used to transformed that value into a
+ * <code>Control</code>.
+ *
+ * @version 2.3
+ * @since 2.0
+ */
+public final class ControlSwitcher
+{
+	/**
+	 * The widget that is used to show the active <code>Control</code>.
+	 */
+	private PageBook pageBook;
+
+	/**
+	 * The <code>Transformer</code> used to transform the value into a
+	 * <code>Control</code>.
+	 */
+	private Transformer<?, Control> paneTransformer;
+
+	private Label emptyLabel;
+
+	/**
+	 * Creates a new <code>ControlSwitcher</code>.
+	 *
+	 * @param switchHolder The holder of the value that will be used to retrieve
+	 * the right <code>Control</code> when passed to the given transformer
+	 * @param paneTransformer The <code>Transformer</code> used to transform the value into a
+	 * <code>Control</code>
+	 * @param pageBook The <code>Transformer</code> used to transform the value
+	 * into a <code>Control</code>
+	 */
+	public <T> ControlSwitcher(PropertyValueModel<? extends T> switchHolder,
+	                           Transformer<T, Control> paneTransformer,
+	                           PageBook pageBook)
+	{
+		super();
+		initialize(switchHolder, paneTransformer, pageBook);
+	}
+
+	private void initialize(PropertyValueModel<?> switchHolder,
+	                        Transformer<?, Control> paneTransformer,
+	                        PageBook pageBook)
+	{
+		this.pageBook        = pageBook;
+		this.paneTransformer = paneTransformer;
+
+		this.emptyLabel = this.buildEmptyLabel();
+
+		switchHolder.addPropertyChangeListener(
+			PropertyValueModel.VALUE,
+			buildPropertyChangeListener()
+		);
+
+		switchPages(switchHolder.getValue());
+	}
+
+	//Build an empty label to display in the page book when the paneTransformer returns null.
+	//SWT.SHADOW_NONE makes the line separator not visible
+	//This is the best we can come up with for an empty page
+	private Label buildEmptyLabel() {
+		return new Label(this.pageBook, SWT.SEPARATOR | SWT.SHADOW_NONE | SWT.HORIZONTAL);
+	}
+
+	private PropertyChangeListener buildPropertyChangeListener() {
+		return new SWTPropertyChangeListenerWrapper(
+			buildPropertyChangeListener_()
+		);
+	}
+
+	private PropertyChangeListener buildPropertyChangeListener_() {
+		return new PropertyChangeListener() {
+			public void propertyChanged(PropertyChangeEvent e) {
+				switchPages(e.getNewValue());
+			}
+		};
+	}
+
+	/**
+	 * Switches the active page by transforming the given value into its
+	 * corresponding pane.
+	 *
+	 * @param value The state passed to the transformer in order to retrieve the
+	 * new pane
+	 */
+	private void switchPages(Object value) {
+		if (this.pageBook.isDisposed()) {
+			return;
+		}
+
+		// Retrieve the Control for the new value
+		Control page = transform(value);
+
+		if (page == null) {
+			//Note: We can't pass in null due to a bug in PageBook
+			page = this.emptyLabel;
+		}
+		this.pageBook.showPage(page);
+
+		// Revalidate the parents in order to update the layout
+		SWTUtil.reflow(this.pageBook);
+	}
+
+	@SuppressWarnings("unchecked")
+	private Control transform(Object value) {
+		return ((Transformer<Object, Control>) this.paneTransformer).transform(value);
+	}
+}
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/util/LabeledButton.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/util/LabeledButton.java
new file mode 100644
index 0000000..4febb30
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/util/LabeledButton.java
@@ -0,0 +1,64 @@
+/*******************************************************************************
+ *  Copyright (c) 2008 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.ui.internal.util;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Button;
+
+/**
+ * A default implementation of <code>LabeledControl</code> that updates a
+ * <code>Button</code> when required.
+ *
+ * @version 2.0
+ * @since 2.0
+ */
+@SuppressWarnings("nls")
+public final class LabeledButton implements LabeledControl
+{
+	/**
+	 * The button to be updated with a different icon and text.
+	 */
+	private final Button button;
+
+	/**
+	 * Creates a new <code>LabeledButton</code>.
+	 *
+	 * @param button The button that will have its text and icon updated when
+	 * required
+	 * @exception AssertionFailedException If the given <code>Button</code> is
+	 * <code>null</code>
+	 */
+	public LabeledButton(Button button) {
+		super();
+
+		Assert.isNotNull(button, "The button cannot be null");
+		this.button = button;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 */
+	public void setImage(Image image) {
+		if (!this.button.isDisposed()) {
+			this.button.setImage(image);
+			this.button.getParent().layout(true);
+		}
+	}
+
+	/*
+	 * (non-Javadoc)
+	 */
+	public void setText(String text) {
+		if (!this.button.isDisposed()) {
+			this.button.setText(text);
+			this.button.getParent().layout(true);
+		}
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/util/LabeledControl.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/util/LabeledControl.java
new file mode 100644
index 0000000..8a9716f
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/util/LabeledControl.java
@@ -0,0 +1,37 @@
+/*******************************************************************************
+ *  Copyright (c) 2008 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.ui.internal.util;
+
+import org.eclipse.swt.graphics.Image;
+
+/**
+ * This <code>LabeledControl</code> is used to encapsulate a widget and update
+ * its properties (icon and text).
+ *
+ * @see LabeledButton
+ * @see LabeledLabel
+ *
+ * @version 2.0
+ * @since 2.0
+ */
+public interface LabeledControl {
+	/**
+	 * Passes the image so the wrapped component can receive it.
+	 *
+	 * @param image The new <code>Image</code>
+	 */
+	void setImage(Image image);
+
+	/**
+	 * Passes the text so the wrapped component can receive it.
+	 *
+	 * @param text The new text
+	 */
+	void setText(String text);
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/util/LabeledControlUpdater.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/util/LabeledControlUpdater.java
new file mode 100644
index 0000000..e6333aa
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/util/LabeledControlUpdater.java
@@ -0,0 +1,130 @@
+/*******************************************************************************
+ * Copyright (c) 2008 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.ui.internal.util;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.jpt.ui.internal.listeners.SWTPropertyChangeListenerWrapper;
+import org.eclipse.jpt.utility.model.event.PropertyChangeEvent;
+import org.eclipse.jpt.utility.model.listener.PropertyChangeListener;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.graphics.Image;
+
+/**
+ * This updater is responsible to update the <code>LabeledControl</code> when
+ * the text and the icon need to change.
+ *
+ * @version 2.0
+ * @since 2.0
+ */
+@SuppressWarnings("nls")
+public final class LabeledControlUpdater {
+
+	/**
+	 * The wrapper around a control that has text and icon.
+	 */
+	private LabeledControl labeledControl;
+
+	/**
+	 * Creates a new <code>LabeledControlUpdater</code>.
+	 *
+	 * @param labeledControl The wrapper around the control that needs to
+	 * have its text updated
+	 * @param textHolder The holder this class will listen for changes
+	 */
+	public LabeledControlUpdater(LabeledControl labeledControl,
+	                             PropertyValueModel<String> textHolder)
+	{
+		this(labeledControl, textHolder, null);
+	}
+
+	/**
+	 * Creates a new <code>LabeledControlUpdater</code>.
+	 *
+	 * @param labeledControl The wrapper around the control that needs to
+	 * have its image and text updated
+	 * @param imageHolder The holder this class will listen for changes or
+	 * <code>null</code> if the text never changes
+	 * @param textHolder The holder this class will listen for changes or
+	 * <code>null</code> if the image never changes
+	 */
+	public LabeledControlUpdater(LabeledControl labeledControl,
+	                             PropertyValueModel<String> textHolder,
+	                             PropertyValueModel<Image> imageHolder)
+	{
+		super();
+		initialize(labeledControl, textHolder, imageHolder);
+	}
+
+	private PropertyChangeListener buildIconListener() {
+		return new SWTPropertyChangeListenerWrapper(buildIconListener_());
+	}
+
+	private PropertyChangeListener buildIconListener_() {
+		return new PropertyChangeListener() {
+			public void propertyChanged(PropertyChangeEvent e) {
+				LabeledControlUpdater.this.setImage((Image) e.getNewValue());
+			}
+
+			@Override
+			public String toString() {
+				return "LabeledControlUpdater.imageListener";
+			}
+		};
+	}
+
+	private PropertyChangeListener buildTextListener() {
+		return new SWTPropertyChangeListenerWrapper(buildTextListener_());
+	}
+
+	private PropertyChangeListener buildTextListener_() {
+		return new PropertyChangeListener() {
+			public void propertyChanged(PropertyChangeEvent e) {
+				LabeledControlUpdater.this.setText((String) e.getNewValue());
+			}
+
+			@Override
+			public String toString() {
+				return "LabeledControlUpdater.textListener";
+			}
+		};
+	}
+
+	private void initialize(LabeledControl labeledControl,
+	                        PropertyValueModel<String> textHolder,
+	                        PropertyValueModel<Image> imageHolder)
+	{
+		Assert.isNotNull(labeledControl, "The LabeledControl cannot be null");
+
+		this.labeledControl = labeledControl;
+
+		if (textHolder != null) {
+			textHolder.addPropertyChangeListener(PropertyValueModel.VALUE, buildTextListener());
+			setText(textHolder.getValue());
+		}
+
+		if (imageHolder != null) {
+			imageHolder.addPropertyChangeListener(PropertyValueModel.VALUE, buildIconListener());
+			setImage(imageHolder.getValue());
+		}
+	}
+
+	private void setImage(Image icon) {
+		labeledControl.setImage(icon);
+	}
+
+	private void setText(String text) {
+
+		if (text == null) {
+			text = "";
+		}
+
+		labeledControl.setText(text);
+	}
+}
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/util/LabeledLabel.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/util/LabeledLabel.java
new file mode 100644
index 0000000..ad4030b
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/util/LabeledLabel.java
@@ -0,0 +1,64 @@
+/*******************************************************************************
+ *  Copyright (c) 2008 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.ui.internal.util;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Label;
+
+/**
+ * A default implementation of <code>LabeledControl</code> that updates an
+ * <code>Label</code> when required.
+ *
+ * @version 2.0
+ * @since 2.0
+ */
+@SuppressWarnings("nls")
+public final class LabeledLabel implements LabeledControl
+{
+	/**
+	 * The label to be updated with a different icon and text.
+	 */
+	private final Label label;
+
+	/**
+	 * Creates a new <code>LabeledButton</code>.
+	 *
+	 * @param label The label that will have its text and icon updated when
+	 * required
+	 * @exception AssertionFailedException If the given <code>Label</code> is
+	 * <code>null</code>
+	 */
+	public LabeledLabel(Label label) {
+		super();
+
+		Assert.isNotNull(label, "The label cannot be null");
+		this.label = label;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 */
+	public void setImage(Image image) {
+		if (!this.label.isDisposed()) {
+			this.label.setImage(image);
+			this.label.getParent().layout(true);
+		}
+	}
+
+	/*
+	 * (non-Javadoc)
+	 */
+	public void setText(String text) {
+		if (!this.label.isDisposed()) {
+			this.label.setText(text);
+			this.label.getParent().layout(true);
+		}
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/util/PaneEnabler.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/util/PaneEnabler.java
new file mode 100644
index 0000000..6a12881
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/util/PaneEnabler.java
@@ -0,0 +1,175 @@
+/*******************************************************************************
+ * Copyright (c) 2008 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.ui.internal.util;
+
+import java.util.Collection;
+import java.util.Iterator;
+import org.eclipse.jpt.ui.internal.widgets.Pane;
+import org.eclipse.jpt.utility.internal.CollectionTools;
+import org.eclipse.jpt.utility.internal.iterators.TransformationIterator;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+
+/**
+ * This <code>PaneEnabler</code> keeps the "enabled" state of a collection of
+ * controls in synch with the provided boolean holder.
+ *
+ * @version 2.0
+ * @since 2.0
+ */
+public class PaneEnabler extends StateController
+{
+	/**
+	 * Creates a new <code>PaneEnabler</code> with a default value of
+	 * <code>false</code> (i.e. disabled).
+	 *
+	 * @param booleanHolder A value model on the underlying boolean model
+	 * @param pane The pane whose "enabled" state is kept in sync with the
+	 * boolean holder's value
+	 */
+	public PaneEnabler(PropertyValueModel<Boolean> booleanHolder,
+	                   Pane<?> pane) {
+
+		this(booleanHolder, pane, false);
+	}
+
+	/**
+	 * Creates a new <code>PaneEnabler</code> with a default value of
+	 * <code>false</code> (i.e. disabled).
+	 *
+	 * @param booleanHolder A value model on the underlying boolean model
+	 * @param panes The collection of panes whose "enabled" state is kept in sync
+	 * with the boolean holder's value
+	 */
+	public PaneEnabler(PropertyValueModel<Boolean> booleanHolder,
+	                   Pane<?>... panes) {
+
+		this(booleanHolder, CollectionTools.collection(panes), false);
+	}
+
+	/**
+	 * Creates a new <code>PaneEnabler</code>.
+	 *
+	 * @param booleanHolder A value model on the underlying boolean model
+	 * @param pane The pane whose "enabled" state is kept in sync with the
+	 * boolean holder's value
+	 * @param defaultValue The value to use when the underlying model is
+	 * <code>null</code>
+	 */
+	public PaneEnabler(PropertyValueModel<Boolean> booleanHolder,
+	                   Pane<?> pane,
+	                   boolean defaultValue) {
+
+		this(booleanHolder, CollectionTools.singletonIterator(pane), false);
+	}
+
+	/**
+	 * Creates a new <code>PaneEnabler</code>.
+	 *
+	 * @param booleanHolder A value model on the underlying boolean model
+	 * @param panes The collection of panes whose "enabled" state is kept in sync
+	 * with the boolean holder's value
+	 * @param defaultValue The value to use when the underlying model is
+	 * <code>null</code>
+	 */
+	public PaneEnabler(PropertyValueModel<Boolean> booleanHolder,
+	                   Pane<?>[] panes,
+	                   boolean defaultValue) {
+
+		this(booleanHolder, CollectionTools.iterator(panes), defaultValue);
+	}
+
+	/**
+	 * Creates a new <code>BaseJpaControllerEnabler</code> with a default value
+	 * of* <code>false</code> (i.e. disabled).
+	 *
+	 * @param booleanHolder A value model on the underlying boolean model
+	 * @param panes The collection of panes whose "enabled" state is kept in sync
+	 * with the boolean holder's value
+	 */
+	public PaneEnabler(PropertyValueModel<Boolean> booleanHolder,
+	                   Collection<? extends Pane<?>> panes) {
+
+		this(booleanHolder, panes, false);
+	}
+
+	/**
+	 * Creates a new <code>BaseJpaControllerEnabler</code>.
+	 *
+	 * @param booleanHolder A value model on the underlying boolean model
+	 * @param panes The collection of panes whose "enabled" state is kept in sync
+	 * with the boolean holder's value
+	 * @param defaultValue The value to use when the underlying model is
+	 * <code>null</code>
+	 */
+	public PaneEnabler(PropertyValueModel<Boolean> booleanHolder,
+	                   Collection<? extends Pane<?>> panes,
+	                   boolean defaultValue) {
+
+		this(booleanHolder, panes.iterator(), defaultValue);
+	}
+
+	/**
+	 * Creates a new <code>BaseJpaControllerEnabler</code> with a default value of
+	 * <code>false</code> (i.e. disabled).
+	 *
+	 * @param booleanHolder A value model on the underlying boolean model
+	 * @param panes An iterator on the collection of panes whose "enabled" state
+	 * is kept in sync with the boolean holder's value
+	 */
+	public PaneEnabler(PropertyValueModel<Boolean> booleanHolder,
+	                   Iterator<? extends Pane<?>> panes) {
+
+		this(booleanHolder, panes, false);
+	}
+
+	/**
+	 * Creates a new <code>BaseJpaControllerEnabler</code>.
+	 *
+	 * @param booleanHolder A value model on the underlying boolean model
+	 * @param panes An iterator on the collection of panes whose "enabled" state
+	 * is kept in sync with the boolean holder's value
+	 * @param defaultValue The value to use when the underlying model is
+	 * <code>null</code>
+	 */
+	public PaneEnabler(PropertyValueModel<Boolean> booleanHolder,
+	                   Iterator<? extends Pane<?>> panes,
+	                   boolean defaultValue) {
+
+		super(booleanHolder, wrap(panes), defaultValue);
+	}
+
+	private static Collection<ControlHolder> wrap(Iterator<? extends Pane<?>> panes) {
+		return CollectionTools.collection(new TransformationIterator<Pane<?>, ControlHolder>(panes) {
+			@Override
+			protected ControlHolder transform(Pane<?> pane) {
+				return new PaneHolder(pane);
+			}
+		});
+	}
+
+	/**
+	 * This holder holds onto an <code>Pane</code> and update its enabled
+	 * state.
+	 */
+	private static class PaneHolder implements ControlHolder {
+		private final Pane<?> pane;
+
+		PaneHolder(Pane<?> pane) {
+			super();
+			this.pane = pane;
+		}
+
+		public void updateState(boolean state) {
+			if (!this.pane.getControl().isDisposed()) {
+				this.pane.enableWidgets(state);
+			}
+		}
+	}
+}
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/util/PaneVisibilityEnabler.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/util/PaneVisibilityEnabler.java
new file mode 100644
index 0000000..7e6f03d
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/util/PaneVisibilityEnabler.java
@@ -0,0 +1,173 @@
+/*******************************************************************************
+ * Copyright (c) 2008 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.ui.internal.util;
+
+import java.util.Collection;
+import java.util.Iterator;
+import org.eclipse.jpt.ui.internal.widgets.Pane;
+import org.eclipse.jpt.utility.internal.CollectionTools;
+import org.eclipse.jpt.utility.internal.iterators.TransformationIterator;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+
+/**
+ * This <code>PaneVisibilityEnabler</code> keeps the "visible" state of a
+ * collection of controls in synch with the provided boolean holder.
+ *
+ * @version 2.0
+ * @since 2.0
+ */
+public class PaneVisibilityEnabler extends StateController
+{
+	/**
+	 * Creates a new <code>PaneVisibilityEnabler</code> with a default value of
+	 * <code>false</code> (i.e. not visible).
+	 *
+	 * @param booleanHolder A value model on the underlying boolean model
+	 * @param pane The pane whose "visible" state is kept in sync with the
+	 * boolean holder's value
+	 */
+	public PaneVisibilityEnabler(PropertyValueModel<Boolean> booleanHolder,
+	                             Pane<?> pane) {
+
+		this(booleanHolder, pane, false);
+	}
+
+	/**
+	 * Creates a new <code>PaneVisibilityEnabler</code> with a default value of
+	 * <code>false</code> (i.e. not visible).
+	 *
+	 * @param booleanHolder A value model on the underlying boolean model
+	 * @param panes The collection of panes whose "visible" state is kept in sync
+	 * with the boolean holder's value
+	 */
+	public PaneVisibilityEnabler(PropertyValueModel<Boolean> booleanHolder,
+	                             Pane<?>... panes) {
+
+		this(booleanHolder, CollectionTools.collection(panes), false);
+	}
+
+	/**
+	 * Creates a new <code>PaneVisibilityEnabler</code>.
+	 *
+	 * @param booleanHolder A value model on the underlying boolean model
+	 * @param pane The pane whose "visible" state is kept in sync with the
+	 * boolean holder's value
+	 * @param defaultValue The value to use when the underlying model is
+	 * <code>null</code>
+	 */
+	public PaneVisibilityEnabler(PropertyValueModel<Boolean> booleanHolder,
+	                             Pane<?> pane,
+	                             boolean defaultValue) {
+
+		this(booleanHolder, CollectionTools.singletonIterator(pane), false);
+	}
+
+	/**
+	 * Creates a new <code>PaneVisibilityEnabler</code>.
+	 *
+	 * @param booleanHolder A value model on the underlying boolean model
+	 * @param panes The collection of panes whose "visible" state is kept in sync
+	 * with the boolean holder's value
+	 * @param defaultValue The value to use when the underlying model is
+	 * <code>null</code>
+	 */
+	public PaneVisibilityEnabler(PropertyValueModel<Boolean> booleanHolder,
+	                             Pane<?>[] panes,
+	                             boolean defaultValue) {
+
+		this(booleanHolder, CollectionTools.iterator(panes), defaultValue);
+	}
+
+	/**
+	 * Creates a new <code>PaneVisibilityEnabler</code> with a default value of
+	 * <code>false</code> (i.e. not visible).
+	 *
+	 * @param booleanHolder A value model on the underlying boolean model
+	 * @param panes The collection of panes whose "visible" state is kept in sync
+	 * with the boolean holder's value
+	 */
+	public PaneVisibilityEnabler(PropertyValueModel<Boolean> booleanHolder,
+	                             Collection<? extends Pane<?>> panes) {
+
+		this(booleanHolder, panes, false);
+	}
+
+	/**
+	 * Creates a new <code>PaneVisibilityEnabler</code>.
+	 *
+	 * @param booleanHolder A value model on the underlying boolean model
+	 * @param panes The collection of panes whose "visible" state is kept in sync
+	 * with the boolean holder's value
+	 * @param defaultValue The value to use when the underlying model is
+	 * <code>null</code>
+	 */
+	public PaneVisibilityEnabler(PropertyValueModel<Boolean> booleanHolder,
+	                             Collection<? extends Pane<?>> panes,
+	                             boolean defaultValue) {
+
+		this(booleanHolder, panes.iterator(), defaultValue);
+	}
+
+	/**
+	 * Creates a new <code>PaneVisibilityEnabler</code> with a default value of
+	 * <code>false</code> (i.e. not visible).
+	 *
+	 * @param booleanHolder A value model on the underlying boolean model
+	 * @param panes An iterator on the collection of panes whose "visible" state
+	 * is kept in sync with the boolean holder's value
+	 */
+	public PaneVisibilityEnabler(PropertyValueModel<Boolean> booleanHolder,
+	                             Iterator<? extends Pane<?>> panes) {
+
+		this(booleanHolder, panes, false);
+	}
+
+	/**
+	 * Creates a new <code>PaneVisibilityEnabler</code>.
+	 *
+	 * @param booleanHolder A value model on the underlying boolean model
+	 * @param panes An iterator on the collection of panes whose "visible" state
+	 * is kept in sync with the boolean holder's value
+	 * @param defaultValue The value to use when the underlying model is
+	 * <code>null</code>
+	 */
+	public PaneVisibilityEnabler(PropertyValueModel<Boolean> booleanHolder,
+	                             Iterator<? extends Pane<?>> panes,
+	                             boolean defaultValue) {
+
+		super(booleanHolder, wrap(panes), defaultValue);
+	}
+
+	private static Collection<ControlHolder> wrap(Iterator<? extends Pane<?>> panes) {
+		return CollectionTools.collection(new TransformationIterator<Pane<?>, ControlHolder>(panes) {
+			@Override
+			protected ControlHolder transform(Pane<?> pane) {
+				return new PaneHolder(pane);
+			}
+		});
+	}
+
+	/**
+	 * This holder holds onto an <code>Pane</code> and update its visible
+	 * state.
+	 */
+	private static class PaneHolder implements ControlHolder {
+		private final Pane<?> pane;
+
+		PaneHolder(Pane<?> pane) {
+			super();
+			this.pane = pane;
+		}
+
+		public void updateState(boolean state) {
+			this.pane.setVisible(state);
+		}
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/util/SWTUtil.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/util/SWTUtil.java
new file mode 100644
index 0000000..1039d09
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/util/SWTUtil.java
@@ -0,0 +1,447 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2010 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.ui.internal.util;
+
+import java.util.Locale;
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.AssertionFailedException;
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.resource.JFaceResources;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jpt.ui.internal.widgets.NullPostExecution;
+import org.eclipse.jpt.ui.internal.widgets.PostExecution;
+import org.eclipse.jpt.utility.internal.ReflectionTools;
+import org.eclipse.swt.events.FocusEvent;
+import org.eclipse.swt.events.FocusListener;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.Widget;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.forms.widgets.ScrolledForm;
+
+/**
+ * A suite of utility methods related to the user interface.
+ *
+ * @version 2.0
+ * @since 1.0
+ */
+@SuppressWarnings("nls")
+public class SWTUtil {
+
+	/**
+	 * Causes the <code>run()</code> method of the given runnable to be invoked
+	 * by the user-interface thread at the next reasonable opportunity. The caller
+	 * of this method continues to run in parallel, and is not notified when the
+	 * runnable has completed.
+	 *
+	 * @param runnable Code to run on the user-interface thread
+	 * @exception org.eclipse.swt.SWTException
+	 * <ul>
+	 * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
+	 * </ul>
+	 * @see #syncExec
+	 */
+	public static void asyncExec(Runnable runnable) {
+		getStandardDisplay().asyncExec(runnable);
+	}
+
+	/**
+	 * Tweaks the given <code>Combo</code> to remove the default value when the
+	 * widget receives the focus and to show the default when the widget loses
+	 * the focus.
+	 *
+	 * @param combo The widget having a default value that is always at the
+	 * beginning of the list
+	 */
+	public static void attachDefaultValueHandler(Combo combo) {
+		ComboHandler handler = new ComboHandler();
+		combo.addFocusListener(handler);
+		combo.addModifyListener(handler);
+	}
+
+	/**
+	 * Retrieves the localized string from the given NLS class by creating the
+	 * key. That key is the concatenation of the composite's short class name
+	 * with the toString() of the given value separated by an underscore.
+	 *
+	 * @param nlsClass The NLS class used to retrieve the localized text
+	 * @param compositeClass The class used for creating the key, its short class
+	 * name is the beginning of the key
+	 * @param value The value used to append its toString() to the generated key
+	 * @return The localized text associated with the value
+	 */
+	public static String buildDisplayString(Class<?> nlsClass,
+	                                        Class<?> compositeClass,
+	                                        Object value) {
+
+		StringBuilder sb = new StringBuilder();
+		sb.append(compositeClass.getSimpleName());
+		sb.append("_");
+		sb.append(value.toString().toLowerCase(Locale.ENGLISH));//bug 234953
+		//TODO in a future release we should not be converting the key using toLowerCase()
+
+		return (String) ReflectionTools.getStaticFieldValue(nlsClass, sb.toString());
+	}
+
+	/**
+	 * Retrieves the localized string from the given NLS class by creating the
+	 * key. That key is the concatenation of the composite's short class name
+	 * with the toString() of the given value separated by an underscore.
+	 *
+	 * @param nlsClass The NLS class used to retrieve the localized text
+	 * @param composite The object used to retrieve the short class name that is
+	 * the beginning of the key
+	 * @param value The value used to append its toString() to the generated key
+	 * @return The localized text associated with the value
+	 */
+	public static final String buildDisplayString(Class<?> nlsClass,
+	                                              Object composite,
+	                                              Object value) {
+
+		return buildDisplayString(nlsClass, composite.getClass(), value);
+	}
+
+	/**
+	 * Creates the <code>Runnable</code> that will invoke the given
+	 * <code>PostExecution</code> in order to its execution to be done in the
+	 * UI thread.
+	 *
+	 * @param dialog The dialog that was just diposed
+	 * @param postExecution The post execution once the dialog is disposed
+	 * @return The <code>Runnable</code> that will invoke
+	 * {@link PostExecution#execute(Dialog)}
+	 */
+	@SuppressWarnings("unchecked")
+	private static <D1 extends Dialog, D2 extends D1>
+		Runnable buildPostExecutionRunnable(
+			final D1 dialog,
+			final PostExecution<D2> postExecution) {
+
+		return new Runnable() {
+			public void run() {
+				setUserInterfaceActive(false);
+				try {
+					postExecution.execute((D2) dialog);
+				}
+				finally {
+					setUserInterfaceActive(true);
+				}
+			}
+		};
+	}
+
+	/**
+	 * Convenience method for getting the current shell. If the current thread is
+	 * not the UI thread, then an invalid thread access exception will be thrown.
+	 *
+	 * @return The shell, never <code>null</code>
+	 */
+	public static Shell getShell() {
+
+		// Retrieve the active shell, which can be the shell from any window
+		Shell shell = getStandardDisplay().getActiveShell();
+
+		// No shell could be found, revert back to the active workbench window
+		if (shell == null) {
+			shell = getWorkbench().getActiveWorkbenchWindow().getShell();
+		}
+
+		// Make sure it's never null
+		if (shell == null) {
+			shell = new Shell(getStandardDisplay().getActiveShell());
+		}
+
+		return shell;
+	}
+
+	/**
+	 * Returns the standard display to be used. The method first checks, if the
+	 * thread calling this method has an associated display. If so, this display
+	 * is returned. Otherwise the method returns the default display.
+	 *
+	 * @return The current display if not <code>null</code> otherwise the default
+	 * display is returned
+	 */
+	public static Display getStandardDisplay()
+	{
+		Display display = Display.getCurrent();
+
+		if (display == null) {
+			display = Display.getDefault();
+		}
+
+		return display;
+	}
+
+	public static int getTableHeightHint(Table table, int rows) {
+		if (table.getFont().equals(JFaceResources.getDefaultFont()))
+			table.setFont(JFaceResources.getDialogFont());
+		int result= table.getItemHeight() * rows + table.getHeaderHeight();
+		if (table.getLinesVisible())
+			result+= table.getGridLineWidth() * (rows - 1);
+		return result;
+	}
+
+   /**
+	 * Returns the Platform UI workbench.
+	 *
+	 * @return The workbench for this plug-in
+	 */
+	public static IWorkbench getWorkbench() {
+		return PlatformUI.getWorkbench();
+	}
+
+	/**
+	 * Relays out the parents of the <code>Control</code>. This was taken from
+	 * the widget <code>Section</code>.
+	 *
+	 * @param pane The pane to revalidate as well as its parents
+	 */
+	public static void reflow(Composite pane) {
+
+		for (Composite composite = pane; composite != null; ) {
+			composite.setRedraw(false);
+			composite = composite.getParent();
+
+			if (composite instanceof ScrolledForm || composite instanceof Shell) {
+				break;
+			}
+		}
+
+		for (Composite composite = pane; composite != null; ) {
+			composite.layout(true);
+			composite = composite.getParent();
+
+			if (composite instanceof ScrolledForm) {
+				((ScrolledForm) composite).reflow(true);
+				break;
+			}
+		}
+
+		for (Composite composite = pane; composite != null; ) {
+			composite.setRedraw(true);
+			composite = composite.getParent();
+
+			if (composite instanceof ScrolledForm || composite instanceof Shell) {
+				break;
+			}
+		}
+	}
+
+	/**
+	 * Sets whether the entire shell and its widgets should be enabled or
+	 * everything should be unaccessible.
+	 *
+	 * @param active <code>true</code> to make all the UI active otherwise
+	 * <code>false</code> to deactivate it
+	 */
+	public static void setUserInterfaceActive(boolean active) {
+		Shell[] shells = getStandardDisplay().getShells();
+
+		for (Shell shell : shells) {
+			shell.setEnabled(active);
+		}
+	}
+
+	/**
+	 * Asynchronously launches the specified dialog in the UI thread.
+	 *
+	 * @param dialog The dialog to show on screen
+	 * @param postExecution This interface let the caller to invoke a piece of
+	 * code once the dialog is disposed
+	 */
+	public static <D1 extends Dialog, D2 extends D1>
+		void show(final D1 dialog, final PostExecution<D2> postExecution) {
+
+		try {
+			Assert.isNotNull(dialog,        "The dialog cannot be null");
+			Assert.isNotNull(postExecution, "The PostExecution cannot be null");
+		}
+		catch (AssertionFailedException e) {
+			// Make sure the UI is interactive
+			setUserInterfaceActive(true);
+			throw e;
+		}
+
+		new Thread() {
+			@Override
+			public void run() {
+				asyncExec(
+					new Runnable() {
+						public void run() {
+							showImp(dialog, postExecution);
+						}
+					}
+				);
+			}
+		}.start();
+	}
+
+	/**
+	 * Asynchronously launches the specified dialog in the UI thread.
+	 *
+	 * @param dialog The dialog to show on screen
+	 */
+	public static void show(Dialog dialog) {
+		show(dialog, NullPostExecution.<Dialog>instance());
+	}
+
+	/**
+	 * Asynchronously launches the specified dialog in the UI thread.
+	 *
+	 * @param dialog The dialog to show on screen
+	 * @param postExecution This interface let the caller to invoke a piece of
+	 * code once the dialog is disposed
+	 */
+	private static <D1 extends Dialog, D2 extends D1>
+		void showImp(D1 dialog, PostExecution<D2> postExecution) {
+
+		setUserInterfaceActive(true);
+		dialog.open();
+
+		if (postExecution != NullPostExecution.<D2>instance()) {
+			asyncExec(buildPostExecutionRunnable(dialog, postExecution));
+		}
+	}
+
+	/**
+	 * Causes the <code>run()</code> method of the given runnable to be invoked
+	 * by the user-interface thread at the next reasonable opportunity. The
+	 * thread which calls this method is suspended until the runnable completes.
+	 *
+	 * @param runnable code to run on the user-interface thread.
+	 * @see #asyncExec
+	 */
+	public static void syncExec(Runnable runnable) {
+		getStandardDisplay().syncExec(runnable);
+	}
+
+	/**
+	 * Determines if the current thread is the UI event thread.
+	 *
+	 * @return <code>true</code> if it's the UI event thread, <code>false</code>
+	 * otherwise
+	 */
+	public static boolean uiThread() {
+		return getStandardDisplay().getThread() == Thread.currentThread();
+	}
+
+	/**
+	 * Determines if the current thread is the UI event thread by using the
+	 * thread from which the given viewer's display was instantiated.
+	 *
+	 * @param viewer The viewer used to determine if the current thread
+	 * is the UI event thread
+	 * @return <code>true</code> if the current thread is the UI event thread;
+	 * <code>false</code> otherwise
+	 */
+	public static boolean uiThread(Viewer viewer) {
+		return uiThread(viewer.getControl());
+	}
+
+	/**
+	 * Determines if the current thread is the UI event thread by using the
+	 * thread from which the given widget's display was instantiated.
+	 *
+	 * @param widget The widget used to determine if the current thread
+	 * is the UI event thread
+	 * @return <code>true</code> if the current thread is the UI event thread;
+	 * <code>false</code> otherwise
+	 */
+	public static boolean uiThread(Widget widget) {
+		return widget.getDisplay().getThread() == Thread.currentThread();
+	}
+
+
+	/**
+	 * This handler is responsible for removing the default value when the combo
+	 * has the focus or when the selected item is the default value and to select
+	 * it when the combo loses the focus.
+	 */
+	private static class ComboHandler implements ModifyListener,
+	                                             FocusListener {
+
+		public void focusGained(FocusEvent e) {
+			Combo combo = (Combo) e.widget;
+
+			if (combo.getSelectionIndex() == 0) {	
+				// The text selection has to be changed outside of the context of this
+				// listener otherwise the combo won't update because it's currently
+				// notifying its listeners
+				asyncExec(new SelectText(combo));
+			}
+		}
+
+		public void focusLost(FocusEvent e) {
+			//do nothing
+		}
+
+		public void modifyText(ModifyEvent e) {
+
+			Combo combo = (Combo) e.widget;
+
+			if (combo.isFocusControl() &&
+			    combo.getSelectionIndex() == 0) {
+
+				// The text has to be changed outside of the context of this
+				// listener otherwise the combo won't update because it's currently
+				// notifying its listeners
+				asyncExec(new ModifyText(combo));
+			}
+		}
+
+		private class ModifyText implements Runnable {
+			private final Combo combo;
+
+			public ModifyText(Combo combo) {
+				super();
+				this.combo = combo;
+			}
+
+			public void run() {
+				if (this.combo.isDisposed()) {
+					return;
+				}
+				String text = this.combo.getText();
+
+				if (text.length() == 0) {
+					text = this.combo.getItem(0);
+					this.combo.setText(text);
+				}
+
+				this.combo.setSelection(new Point(0, text.length()));
+			}
+		}
+
+		private class SelectText implements Runnable {
+			private final Combo combo;
+
+			public SelectText(Combo combo) {
+				super();
+				this.combo = combo;
+			}
+
+			public void run() {
+				if (this.combo.isDisposed()) {
+					return;
+				}
+				String text = this.combo.getText();
+				this.combo.setSelection(new Point(0, text.length()));
+			}
+		}
+	}
+}
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/util/StateController.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/util/StateController.java
new file mode 100644
index 0000000..d5df233
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/util/StateController.java
@@ -0,0 +1,320 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2009 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.ui.internal.util;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.jpt.ui.internal.listeners.SWTPropertyChangeListenerWrapper;
+import org.eclipse.jpt.utility.internal.CollectionTools;
+import org.eclipse.jpt.utility.internal.iterators.CloneIterator;
+import org.eclipse.jpt.utility.model.event.PropertyChangeEvent;
+import org.eclipse.jpt.utility.model.listener.PropertyChangeListener;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+
+/**
+ * A <code>StateController</code> keeps the state of a collection of widgets in
+ * synch with the provided boolean holder.
+ *
+ * @see ControlEnabler
+ * @see ControlVisibilityEnabler
+ * @see PaneEnabler
+ * @see PaneVisibilityEnabler
+ *
+ * @version 2.0
+ * @since 2.0
+ */
+@SuppressWarnings("nls")
+abstract class StateController
+{
+	/**
+	 * A listener that allows us to synchronize the controlHolders with changes
+	 * made to the underlying boolean model.
+	 */
+	private PropertyChangeListener booleanChangeListener;
+
+	/**
+	 * A value model on the underlying boolean model
+	 */
+	private PropertyValueModel<Boolean> booleanHolder;
+
+	/**
+	 * The collection of <code>ControlHolder</code>s whose state is kept in sync
+	 * with the boolean holder's value.
+	 */
+	private Collection<ControlHolder> controlHolders;
+
+	/**
+	 * The default setting for the state; for when the underlying model is
+	 * <code>null</code>. The default [default value] is <code>false<code>.
+	 */
+	private boolean defaultValue;
+
+	/**
+	 * Creates a new <code>StateController</code>.
+	 */
+	StateController() {
+		super();
+		initialize();
+	}
+
+	/**
+	 * Creates a new <code>StateController</code> with a default value of
+	 * <code>false</code>.
+	 *
+	 * @param booleanHolder A value model on the underlying boolean model
+	 * @param controlHolders The collection of <code>ControlHolder</code>s whose
+	 * state is kept in sync with the boolean holder's value
+	 */
+	StateController(PropertyValueModel<Boolean> booleanHolder,
+	                Collection<ControlHolder> controlHolders) {
+
+		this(booleanHolder, controlHolders, false);
+	}
+
+	/**
+	 * Creates a new <code>StateController</code> with a default value of
+	 * <code>false</code>.
+	 *
+	 * @param booleanHolder A value model on the underlying boolean model
+	 * @param controlHolders The collection of <code>ControlHolder</code>s whose
+	 * state is kept in sync with the boolean holder's value
+	 * @param defaultValue The value to use when the underlying model is
+	 * <code>null</code>
+	 */
+	StateController(PropertyValueModel<Boolean> booleanHolder,
+	                Collection<ControlHolder> controlHolders,
+	                boolean defaultValue) {
+
+		this();
+		initialize(booleanHolder, controlHolders, defaultValue);
+	}
+
+	/**
+	 * Creates a new <code>StateController</code> with a default value of
+	 * <code>false</code>.
+	 *
+	 * @param booleanHolder A value model on the underlying boolean model
+	 * @param controlHolder The <code>ControlHolder</code> whose state is kept
+	 * in sync with the boolean holder's value
+	 */
+	StateController(PropertyValueModel<Boolean> booleanHolder,
+	                ControlHolder controlHolder) {
+
+		this(booleanHolder, controlHolder, false);
+	}
+
+	/**
+	 * Creates a new <code>StateController</code> with a default value of
+	 * <code>false</code>.
+	 *
+	 * @param booleanHolder A value model on the underlying boolean model
+	 * @param controlHolders The collection of <code>ControlHolder</code>s whose
+	 * state is kept in sync with the boolean holder's value
+	 */
+	StateController(PropertyValueModel<Boolean> booleanHolder,
+	                ControlHolder... controlHolders) {
+
+		this(booleanHolder, CollectionTools.collection(controlHolders), false);
+	}
+
+	/**
+	 * Creates a new <code>StateController</code> with a default value of
+	 * <code>false</code>.
+	 *
+	 * @param booleanHolder A value model on the underlying boolean model
+	 * @param controlHolder The <code>ControlHolder</code> whose state is kept
+	 * in sync with the boolean holder's value
+	 * @param defaultValue The value to use when the underlying model is
+	 * <code>null</code>
+	 */
+	StateController(PropertyValueModel<Boolean> booleanHolder,
+	                ControlHolder controlHolder,
+	                boolean defaultValue) {
+
+		this(booleanHolder, new ControlHolder[] { controlHolder }, false);
+	}
+
+	/**
+	 * Creates a new <code>StateController</code>.
+	 *
+	 * @param booleanHolder A value model on the underlying boolean model
+	 * @param controlHolders The collection of <code>ControlHolder</code>s whose
+	 * state is kept in sync with the boolean holder's value
+	 * @param defaultValue The value to use when the underlying model is
+	 * <code>null</code>
+	 */
+	StateController(PropertyValueModel<Boolean> booleanHolder,
+	                ControlHolder[] controlHolders,
+	                boolean defaultValue) {
+
+		this();
+		this.initialize(booleanHolder, CollectionTools.collection(controlHolders), defaultValue);
+	}
+
+	/**
+	 * Creates a new <code>StateController</code> with a default value of
+	 * <code>false</code>.
+	 *
+	 * @param booleanHolder A value model on the underlying boolean model
+	 * @param controlHolders An iterator on the collection of
+	 * <code>ControlHolder</code>s whose state is kept in sync with the boolean
+	 * holder's value
+	 */
+	StateController(PropertyValueModel<Boolean> booleanHolder,
+	                Iterator<ControlHolder> controlHolders) {
+
+		this(booleanHolder, CollectionTools.collection(controlHolders), false);
+	}
+
+	/**
+	 * Creates a new <code>StateController</code>.
+	 *
+	 * @param booleanHolder A value model on the underlying boolean model
+	 * @param controlHolders An iterator on the collection of
+	 * <code>ControlHolder</code>s whose state is kept in sync with the boolean
+	 * holder's value
+	 * @param defaultValue The value to use when the underlying model is
+	 * <code>null</code>
+	 */
+	StateController(PropertyValueModel<Boolean> booleanHolder,
+	                Iterator<ControlHolder> controlHolders,
+	                boolean defaultValue) {
+
+		this();
+		initialize(booleanHolder, CollectionTools.collection(controlHolders), defaultValue);
+	}
+
+	/**
+	 * Returns the boolean primitive of the given <code>Boolean</code> value but
+	 * also checks for <code>null</code>, if that is the case, then
+	 * {@link #defaultValue} is returned.
+	 *
+	 * @param value The <code>Boolean</code> value to be returned as a primitive
+	 * @return The primitive of the given value or {@link #defaultValue}when the
+	 * value is <code>null</code>
+	 */
+	protected boolean booleanValue(Boolean value) {
+		return (value == null) ? this.defaultValue : value.booleanValue();
+	}
+
+	/**
+	 * Creates a listener for the boolean holder.
+	 *
+	 * @return A new <code>PropertyChangeListener</code>
+	 */
+	private PropertyChangeListener buildBooleanChangeListener() {
+		return new SWTPropertyChangeListenerWrapper(
+			buildBooleanChangeListener_()
+		)
+		{
+			@Override
+			public String toString() {
+				return "StateController.SWTPropertyChangeListenerWrapper";
+			}
+		};
+	}
+
+	/**
+	 * Creates a listener for the boolean holder.
+	 *
+	 * @return A new <code>PropertyChangeListener</code>
+	 */
+	private PropertyChangeListener buildBooleanChangeListener_() {
+		return new PropertyChangeListener() {
+			public void propertyChanged(PropertyChangeEvent event) {
+				updateState();
+			}
+
+			@Override
+			public String toString() {
+				return "StateController.PropertyChangeListener";
+			}
+		};
+	}
+
+	/**
+	 * Returns an <code>Iterator</code> over the collection of
+	 * <code>ControlHolder</code>s.
+	 *
+	 * @return The iteration of <code>ControlHolder</code>s
+	 */
+	protected final Iterator<ControlHolder> controlHolders() {
+		return new CloneIterator<ControlHolder>(this.controlHolders);
+	}
+
+	/**
+	 * Initializes this <code>StateController</code> by building the appropriate
+	 * listeners.
+	 */
+	protected void initialize() {
+		this.booleanChangeListener = this.buildBooleanChangeListener();
+	}
+
+	/**
+	 * Initializes this <code>StateController</code> with the given state.
+	 *
+	 * @param booleanHolder A value model on the underlying boolean model
+	 * @param controlHolders A <code>ControlHolder</code>s whose enablement state
+	 * is kept in sync with the boolean holder's value
+	 * @param defaultValue The value to use when the underlying model is
+	 * <code>null</code>
+	 */
+	protected void initialize(PropertyValueModel<Boolean> booleanHolder,
+									  Collection<ControlHolder> controlHolders,
+									  boolean defaultValue) {
+
+		Assert.isNotNull(booleanHolder,  "The holder of the boolean value cannot be null");
+		Assert.isNotNull(controlHolders, "The collection of ControlHolders cannot be null");
+
+		this.controlHolders = new ArrayList<ControlHolder>(controlHolders);
+		this.defaultValue   = defaultValue;
+		this.booleanHolder  = booleanHolder;
+
+		this.booleanHolder.addPropertyChangeListener(
+			PropertyValueModel.VALUE,
+			this.booleanChangeListener
+		);
+
+		this.updateState();
+	}
+
+	/**
+	 * Updates the state of the control holders.
+	 */
+	protected void updateState() {
+		this.updateState(booleanValue(this.booleanHolder.getValue()));
+	}
+
+	/**
+	 * Updates the state of the <code>Control</code>s.
+	 *
+	 * @param state The new state the widgets need to have
+	 */
+	protected void updateState(boolean state) {
+		for (ControlHolder controlHolder : this.controlHolders) {
+			controlHolder.updateState(state);
+		}
+	}
+
+	/**
+	 * The holder of the actual widget.
+	 */
+	static interface ControlHolder {
+
+		/**
+		 * Updates the state of the wrapped control.
+		 *
+		 * @param state The new state the control should have
+		 */
+		void updateState(boolean state);
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/util/TableLayoutComposite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/util/TableLayoutComposite.java
new file mode 100644
index 0000000..4b65666
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/util/TableLayoutComposite.java
@@ -0,0 +1,207 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+// copied from org.eclipse.jdt.internal.ui.util.TableLayoutComposite
+package org.eclipse.jpt.ui.internal.util;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.ControlAdapter;
+import org.eclipse.swt.events.ControlEvent;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.TableColumn;
+
+import org.eclipse.core.runtime.Assert;
+
+import org.eclipse.jface.viewers.ColumnLayoutData;
+import org.eclipse.jface.viewers.ColumnPixelData;
+import org.eclipse.jface.viewers.ColumnWeightData;
+
+/**
+ * A special composite to layout columns inside a table. The composite is needed since we have
+ * to layout the columns "before" the actual table gets layouted. Hence we can't use a normal
+ * layout manager.
+ * <p>
+ * XXX: Should switch to use {@link org.eclipse.jface.layout.TableColumnLayout}.
+ * </p>
+ */
+public class TableLayoutComposite extends Composite {
+
+	/**
+	 * The number of extra pixels taken as horizontal trim by the table column.
+	 * To ensure there are N pixels available for the content of the column,
+	 * assign N+COLUMN_TRIM for the column width.
+	 * <p>
+	 * XXX: Should either switch to use {@link org.eclipse.jface.layout.TableColumnLayout} or get API from JFace or SWT, see: https://bugs.eclipse.org/bugs/show_bug.cgi?id=218483
+	 * </p>
+	 *
+	 * @since 3.1
+	 */
+	private static int COLUMN_TRIM;
+	static {
+		String platform= SWT.getPlatform();
+		if ("win32".equals(platform)) //$NON-NLS-1$
+			COLUMN_TRIM= 4;
+		else if ("carbon".equals(platform)) //$NON-NLS-1$
+			COLUMN_TRIM= 24;
+		else
+			COLUMN_TRIM= 3;
+	}
+
+	private List columns= new ArrayList();
+
+	/**
+	 * Creates a new <code>TableLayoutComposite</code>.
+	 *
+	 * @param parent the parent composite
+	 * @param style the SWT style
+	 */
+	public TableLayoutComposite(Composite parent, int style) {
+		super(parent, style);
+        addControlListener(new ControlAdapter() {
+            public void controlResized(ControlEvent e) {
+                Rectangle area= getClientArea();
+                Table table= (Table)getChildren()[0];
+                Point preferredSize= computeTableSize(table);
+                int width= area.width - 2 * table.getBorderWidth();
+                if (preferredSize.y > area.height) {
+                    // Subtract the scrollbar width from the total column width
+                    // if a vertical scrollbar will be required
+                    Point vBarSize = table.getVerticalBar().getSize();
+                    width -= vBarSize.x;
+                }
+                layoutTable(table, width, area, table.getSize().x < area.width);
+            }
+        });
+	}
+
+	/**
+	 * Adds a new column of data to this table layout.
+	 *
+	 * @param data the column layout data
+	 */
+	public void addColumnData(ColumnLayoutData data) {
+		columns.add(data);
+	}
+
+	//---- Helpers -------------------------------------------------------------------------------------
+
+	private Point computeTableSize(Table table) {
+		Point result= table.computeSize(SWT.DEFAULT, SWT.DEFAULT);
+
+		int width= 0;
+		int size= columns.size();
+		for (int i= 0; i < size; ++i) {
+			ColumnLayoutData layoutData= (ColumnLayoutData) columns.get(i);
+			if (layoutData instanceof ColumnPixelData) {
+				ColumnPixelData col= (ColumnPixelData) layoutData;
+				width += col.width;
+				if (col.addTrim) {
+					width += COLUMN_TRIM;
+				}
+			} else if (layoutData instanceof ColumnWeightData) {
+				ColumnWeightData col= (ColumnWeightData) layoutData;
+				width += col.minimumWidth;
+			} else {
+				Assert.isTrue(false, "Unknown column layout data"); //$NON-NLS-1$
+			}
+		}
+		if (width > result.x)
+			result.x= width;
+		return result;
+	}
+
+	private void layoutTable(Table table, int width, Rectangle area, boolean increase) {
+		// XXX: Layout is being called with an invalid value the first time
+		// it is being called on Linux. This method resets the
+		// Layout to null so we make sure we run it only when
+		// the value is OK.
+		if (width <= 1)
+			return;
+
+		TableColumn[] tableColumns= table.getColumns();
+		int size= Math.min(columns.size(), tableColumns.length);
+		int[] widths= new int[size];
+		int fixedWidth= 0;
+		int numberOfWeightColumns= 0;
+		int totalWeight= 0;
+
+		// First calc space occupied by fixed columns
+		for (int i= 0; i < size; i++) {
+			ColumnLayoutData col= (ColumnLayoutData) columns.get(i);
+			if (col instanceof ColumnPixelData) {
+				ColumnPixelData cpd= (ColumnPixelData) col;
+				int pixels= cpd.width;
+				if (cpd.addTrim) {
+					pixels += COLUMN_TRIM;
+				}
+				widths[i]= pixels;
+				fixedWidth += pixels;
+			} else if (col instanceof ColumnWeightData) {
+				ColumnWeightData cw= (ColumnWeightData) col;
+				numberOfWeightColumns++;
+				// first time, use the weight specified by the column data, otherwise use the actual width as the weight
+				// int weight = firstTime ? cw.weight : tableColumns[i].getWidth();
+				int weight= cw.weight;
+				totalWeight += weight;
+			} else {
+				Assert.isTrue(false, "Unknown column layout data"); //$NON-NLS-1$
+			}
+		}
+
+		// Do we have columns that have a weight
+		if (numberOfWeightColumns > 0) {
+			// Now distribute the rest to the columns with weight.
+			int rest= width - fixedWidth;
+			int totalDistributed= 0;
+			for (int i= 0; i < size; ++i) {
+				ColumnLayoutData col= (ColumnLayoutData) columns.get(i);
+				if (col instanceof ColumnWeightData) {
+					ColumnWeightData cw= (ColumnWeightData) col;
+					// calculate weight as above
+					// int weight = firstTime ? cw.weight : tableColumns[i].getWidth();
+					int weight= cw.weight;
+					int pixels= totalWeight == 0 ? 0 : weight * rest / totalWeight;
+					if (pixels < cw.minimumWidth)
+						pixels= cw.minimumWidth;
+					totalDistributed += pixels;
+					widths[i]= pixels;
+				}
+			}
+
+			// Distribute any remaining pixels to columns with weight.
+			int diff= rest - totalDistributed;
+			for (int i= 0; diff > 0; ++i) {
+				if (i == size)
+					i= 0;
+				ColumnLayoutData col= (ColumnLayoutData) columns.get(i);
+				if (col instanceof ColumnWeightData) {
+					++widths[i];
+					--diff;
+				}
+			}
+		}
+
+		if (increase) {
+			table.setSize(area.width, area.height);
+		}
+		for (int i= 0; i < size; i++) {
+			tableColumns[i].setWidth(widths[i]);
+		}
+		if (!increase) {
+			table.setSize(area.width, area.height);
+		}
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/utility/AsynchronousUiCommandExecutor.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/utility/AsynchronousUiCommandExecutor.java
new file mode 100644
index 0000000..2257344
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/utility/AsynchronousUiCommandExecutor.java
@@ -0,0 +1,49 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2009 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.ui.internal.utility;
+
+import org.eclipse.jpt.utility.Command;
+import org.eclipse.jpt.utility.CommandExecutor;
+import org.eclipse.jpt.utility.internal.CommandRunnable;
+import org.eclipse.swt.widgets.Display;
+
+/**
+ * This implementation of CommandExecutor can be used by a non-UI
+ * thread to asynchronously modify a JPA project with any objects associated
+ * with documents that are currently displayed in the UI.
+ */
+public final class AsynchronousUiCommandExecutor
+	implements CommandExecutor
+{
+	public static final CommandExecutor INSTANCE = new AsynchronousUiCommandExecutor();
+
+	public static CommandExecutor instance() {
+		return INSTANCE;
+	}
+
+	// ensure single instance
+	private AsynchronousUiCommandExecutor() {
+		super();
+	}
+
+	public void execute(Command command) {
+		this.getDisplay().asyncExec(this.buildRunnable(command));
+	}
+
+	private Runnable buildRunnable(Command command) {
+		return new CommandRunnable(command);
+	}
+
+	private Display getDisplay() {
+		Display display = Display.getCurrent();
+		return (display != null) ? display : Display.getDefault();
+	}
+
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/utility/SynchronousUiCommandExecutor.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/utility/SynchronousUiCommandExecutor.java
new file mode 100644
index 0000000..16d15e1
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/utility/SynchronousUiCommandExecutor.java
@@ -0,0 +1,49 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2009 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.ui.internal.utility;
+
+import org.eclipse.jpt.utility.Command;
+import org.eclipse.jpt.utility.CommandExecutor;
+import org.eclipse.jpt.utility.internal.CommandRunnable;
+import org.eclipse.swt.widgets.Display;
+
+/**
+ * This implementation of CommandExecutor can be used by a non-UI
+ * thread to synchronously modify a JPA project with any objects associated
+ * with documents that are currently displayed in the UI.
+ */
+public final class SynchronousUiCommandExecutor
+	implements CommandExecutor
+{
+	public static final CommandExecutor INSTANCE = new SynchronousUiCommandExecutor();
+
+	public static CommandExecutor instance() {
+		return INSTANCE;
+	}
+
+	// ensure single instance
+	private SynchronousUiCommandExecutor() {
+		super();
+	}
+
+	public void execute(Command command) {
+		this.getDisplay().syncExec(this.buildRunnable(command));
+	}
+
+	private Runnable buildRunnable(Command command) {
+		return new CommandRunnable(command);
+	}
+
+	private Display getDisplay() {
+		Display display = Display.getCurrent();
+		return (display != null) ? display : Display.getDefault();
+	}
+
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/utility/swt/AbstractListWidgetAdapter.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/utility/swt/AbstractListWidgetAdapter.java
new file mode 100644
index 0000000..eee1eb1
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/utility/swt/AbstractListWidgetAdapter.java
@@ -0,0 +1,42 @@
+/*******************************************************************************
+ * Copyright (c) 2009 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.ui.internal.utility.swt;
+
+import org.eclipse.swt.events.DisposeListener;
+import org.eclipse.swt.widgets.Widget;
+
+/**
+ * All the "list widgets" are subclasses of {@link Widget}; so we can provide
+ * a smidgen of common behavior here.
+ */
+abstract class AbstractListWidgetAdapter<W extends Widget>
+	implements ListWidgetModelBinding.ListWidget
+{
+	final W widget;
+
+	AbstractListWidgetAdapter(W widget) {
+		super();
+		this.widget = widget;
+	}
+
+	public boolean isDisposed() {
+		return this.widget.isDisposed();
+	}
+
+	public void addDisposeListener(DisposeListener listener) {
+		this.widget.addDisposeListener(listener);
+	}
+
+	public void removeDisposeListener(DisposeListener listener) {
+		this.widget.removeDisposeListener(listener);
+	}
+
+}
+
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/utility/swt/BooleanButtonModelBinding.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/utility/swt/BooleanButtonModelBinding.java
new file mode 100644
index 0000000..15d1f89
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/utility/swt/BooleanButtonModelBinding.java
@@ -0,0 +1,190 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 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.ui.internal.utility.swt;
+
+import org.eclipse.jpt.ui.internal.listeners.SWTPropertyChangeListenerWrapper;
+import org.eclipse.jpt.utility.internal.StringTools;
+import org.eclipse.jpt.utility.model.event.PropertyChangeEvent;
+import org.eclipse.jpt.utility.model.listener.PropertyChangeListener;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.jpt.utility.model.value.WritablePropertyValueModel;
+import org.eclipse.swt.events.DisposeEvent;
+import org.eclipse.swt.events.DisposeListener;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.widgets.Button;
+
+/**
+ * This binding can be used to keep a check-box, toggle button, or radio button
+ * "selection" synchronized with a model boolean.
+ * 
+ * @see WritablePropertyValueModel
+ * @see Button
+ */
+@SuppressWarnings("nls")
+final class BooleanButtonModelBinding {
+
+	// ***** model
+	/** A value model on the underlying model boolean. */
+	private final WritablePropertyValueModel<Boolean> booleanModel;
+
+	/**
+	 * A listener that allows us to synchronize the button's selection state with
+	 * the model boolean.
+	 */
+	private final PropertyChangeListener booleanChangeListener;
+
+	/**
+	 * The default setting for the check-box/toggle button/radio button;
+	 * for when the underlying model is <code>null</code>.
+	 * The default [default value] is <code>false</code> (i.e. the check-box
+	 * is unchecked/toggle button popped out/radio button unchecked).
+	 */
+	private final boolean defaultValue;
+
+	// ***** UI
+	/** The check-box/toggle button/radio button we synchronize with the model boolean. */
+	private final Button button;
+
+	/**
+	 * A listener that allows us to synchronize the model boolean with
+	 * the button's selection state.
+	 */
+	private final SelectionListener buttonSelectionListener;
+
+	/**
+	 * A listener that allows us to stop listening to stuff when the button
+	 * is disposed. (Critical for preventing memory leaks.)
+	 */
+	private final DisposeListener buttonDisposeListener;
+
+
+	// ********** constructor **********
+
+	/**
+	 * Constructor - the boolean model and button are required.
+	 */
+	BooleanButtonModelBinding(WritablePropertyValueModel<Boolean> booleanModel, Button button, boolean defaultValue) {
+		super();
+		if ((booleanModel == null) || (button == null)) {
+			throw new NullPointerException();
+		}
+		this.booleanModel = booleanModel;
+		this.button = button;
+		this.defaultValue = defaultValue;
+
+		this.booleanChangeListener = this.buildBooleanChangeListener();
+		this.booleanModel.addPropertyChangeListener(PropertyValueModel.VALUE, this.booleanChangeListener);
+
+		this.buttonSelectionListener = this.buildButtonSelectionListener();
+		this.button.addSelectionListener(this.buttonSelectionListener);
+
+		this.buttonDisposeListener = this.buildButtonDisposeListener();
+		this.button.addDisposeListener(this.buttonDisposeListener);
+
+		this.setButtonSelection(this.booleanModel.getValue());
+	}
+
+
+	// ********** initialization **********
+
+	private PropertyChangeListener buildBooleanChangeListener() {
+		return new SWTPropertyChangeListenerWrapper(this.buildBooleanChangeListener_());
+	}
+
+	private PropertyChangeListener buildBooleanChangeListener_() {
+		return new PropertyChangeListener() {
+			public void propertyChanged(PropertyChangeEvent event) {
+				BooleanButtonModelBinding.this.booleanChanged(event);
+			}
+		    @Override
+			public String toString() {
+				return "boolean listener";
+			}
+		};
+	}
+
+	private SelectionListener buildButtonSelectionListener() {
+		return new SelectionAdapter() {
+			@Override
+			public void widgetSelected(SelectionEvent event) {
+				BooleanButtonModelBinding.this.buttonSelected();
+			}
+		    @Override
+			public String toString() {
+				return "button selection listener";
+			}
+		};
+	}
+
+	private DisposeListener buildButtonDisposeListener() {
+		return new DisposeListener() {
+			public void widgetDisposed(DisposeEvent event) {
+				BooleanButtonModelBinding.this.buttonDisposed();
+			}
+		    @Override
+			public String toString() {
+				return "button dispose listener";
+			}
+		};
+	}
+
+
+	// ********** boolean model events **********
+
+	/**
+	 * The model has changed - synchronize the button.
+	 * If the new model value is null, use the binding's default value
+	 * (which is typically false).
+	 */
+	/* private */ void booleanChanged(PropertyChangeEvent event) {
+		this.setButtonSelection((Boolean) event.getNewValue());
+	}
+
+	private void setButtonSelection(Boolean b) {
+		if ( ! this.button.isDisposed()) {
+			this.button.setSelection(this.booleanValue(b));
+		}
+	}
+
+	private boolean booleanValue(Boolean b) {
+		return (b != null) ? b.booleanValue() : this.defaultValue;
+	}
+
+
+	// ********** button events **********
+
+	/**
+	 * The button has been "selected" - synchronize the model.
+	 */
+	/* private */ void buttonSelected() {
+		if ( ! this.button.isDisposed()) {
+			this.booleanModel.setValue(Boolean.valueOf(this.button.getSelection()));
+		}
+	}
+
+	/* private */ void buttonDisposed() {
+		// the button is not yet "disposed" when we receive this event
+		// so we can still remove our listeners
+		this.button.removeSelectionListener(this.buttonSelectionListener);
+		this.button.removeDisposeListener(this.buttonDisposeListener);
+		this.booleanModel.removePropertyChangeListener(PropertyValueModel.VALUE, this.booleanChangeListener);
+	}
+
+
+	// ********** standard methods **********
+
+    @Override
+	public String toString() {
+		return StringTools.buildToStringFor(this, this.booleanModel);
+	}
+
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/utility/swt/BooleanStateController.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/utility/swt/BooleanStateController.java
new file mode 100644
index 0000000..69b3730
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/utility/swt/BooleanStateController.java
@@ -0,0 +1,188 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2010 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.ui.internal.utility.swt;
+
+import org.eclipse.jpt.ui.internal.listeners.SWTPropertyChangeListenerWrapper;
+import org.eclipse.jpt.utility.internal.StringTools;
+import org.eclipse.jpt.utility.model.event.PropertyChangeEvent;
+import org.eclipse.jpt.utility.model.listener.PropertyChangeListener;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.events.DisposeEvent;
+import org.eclipse.swt.events.DisposeListener;
+import org.eclipse.swt.widgets.Control;
+
+/**
+ * This controller enables a boolean model to control either the
+ * <em>enabled</em> or <em>visible</em> properties of SWT controls; i.e. the
+ * controls' properties are kept in synch with the boolean model,
+ * but <em>not</em> vice-versa.
+ * <p>
+ * Subclasses must manage the listeners; i.e. the engaging and disengaging of
+ * the boolean model and the control(s).
+ * 
+ * @see PropertyValueModel
+ * @see Control#setEnabled(boolean)
+ * @see Control#setVisible(boolean)
+ */
+abstract class BooleanStateController {
+
+	/**
+	 * The controlling boolean model.
+	 */
+	private final PropertyValueModel<Boolean> booleanModel;
+
+	/**
+	 * A listener that allows us to synchronize the control states with
+	 * changes in the value of the boolean model.
+	 */
+	private final PropertyChangeListener booleanChangeListener;
+
+	/**
+	 * A listener that allows us to stop listening to stuff when all the
+	 * controls are disposed. (Critical for preventing memory leaks.)
+	 */
+	private final DisposeListener controlDisposeListener;
+
+	/**
+	 * The default setting for the state; for when the underlying boolean model is
+	 * <code>null</code>. The default [default value] is <code>false<code>.
+	 */
+	private final boolean defaultValue;
+
+	/**
+	 * The adapter determines whether the 'enabled' or 'visible' property is
+	 * controlled.
+	 */
+	private final Adapter adapter;
+
+
+	// ********** constructor **********
+
+	/**
+	 * Constructor - the boolean model and the adapter are required.
+	 */
+	BooleanStateController(PropertyValueModel<Boolean> booleanModel, boolean defaultValue, Adapter adapter) {
+		super();
+		if ((booleanModel == null) || (adapter == null)) {
+			throw new NullPointerException();
+		}
+		this.booleanModel = booleanModel;
+		this.defaultValue = defaultValue;
+		this.adapter = adapter;
+
+		this.booleanChangeListener = this.buildBooleanChangeListener();
+		this.controlDisposeListener = this.buildControlDisposeListener();
+	}
+
+
+	// ********** initialization **********
+
+	private PropertyChangeListener buildBooleanChangeListener() {
+		return new SWTPropertyChangeListenerWrapper(this.buildBooleanChangeListener_());
+	}
+
+	private PropertyChangeListener buildBooleanChangeListener_() {
+		return new PropertyChangeListener() {
+			public void propertyChanged(PropertyChangeEvent event) {
+				BooleanStateController.this.booleanChanged(event);
+			}
+			@Override
+			public String toString() {
+				return "boolean listener"; //$NON-NLS-1$
+			}
+		};
+	}
+
+	private DisposeListener buildControlDisposeListener() {
+		return new DisposeListener() {
+			public void widgetDisposed(DisposeEvent event) {
+				// the control is not yet "disposed" when we receive this event
+				// so we can still remove our listener
+				BooleanStateController.this.controlDisposed((Control) event.widget);
+			}
+			@Override
+			public String toString() {
+				return "control dispose listener"; //$NON-NLS-1$
+			}
+		};
+	}
+
+
+	// ********** boolean model **********
+
+	void engageBooleanModel() {
+		this.booleanModel.addPropertyChangeListener(PropertyValueModel.VALUE, this.booleanChangeListener);
+	}
+
+	void disengageBooleanModel() {
+		this.booleanModel.removePropertyChangeListener(PropertyValueModel.VALUE, this.booleanChangeListener);
+	}
+
+	/**
+	 * The boolean model has changed - synchronize the controls.
+	 * If the new boolean model value is <code>null</code>, use the controller's
+	 * default value (which is typically false).
+	 */
+	/* private */ void booleanChanged(PropertyChangeEvent event) {
+		this.setControlState((Boolean) event.getNewValue());
+	}
+
+
+	boolean getBooleanValue() {
+		return this.booleanValue(this.booleanModel.getValue());
+	}
+
+	private boolean booleanValue(Boolean b) {
+		return (b != null) ? b.booleanValue() : this.defaultValue;
+	}
+
+
+	// ********** control **********
+
+	void engageControl(Control control) {
+		control.addDisposeListener(this.controlDisposeListener);
+	}
+
+	void disengageControl(Control control) {
+		control.removeDisposeListener(this.controlDisposeListener);
+	}
+
+	private void setControlState(Boolean b) {
+		this.setControlState(this.booleanValue(b));
+	}
+
+	abstract void setControlState(boolean b);
+
+	void setControlState(Control control, boolean b) {
+		if ( ! control.isDisposed()) {
+			this.adapter.setState(control, b);
+		}
+	}
+
+	void controlDisposed(Control control) {
+		this.disengageControl(control);
+	}
+
+
+	// ********** standard methods **********
+
+	@Override
+	public String toString() {
+		return StringTools.buildToStringFor(this, this.booleanModel);
+	}
+
+
+	// ********** adapter interface **********
+
+	interface Adapter {
+		void setState(Control control, boolean b);
+	}
+
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/utility/swt/DropDownListBoxSelectionBinding.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/utility/swt/DropDownListBoxSelectionBinding.java
new file mode 100644
index 0000000..0585c00
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/utility/swt/DropDownListBoxSelectionBinding.java
@@ -0,0 +1,283 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2010 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.ui.internal.utility.swt;
+
+import org.eclipse.jpt.ui.internal.listeners.SWTPropertyChangeListenerWrapper;
+import org.eclipse.jpt.utility.internal.StringTools;
+import org.eclipse.jpt.utility.internal.Tools;
+import org.eclipse.jpt.utility.model.event.PropertyChangeEvent;
+import org.eclipse.jpt.utility.model.listener.PropertyChangeListener;
+import org.eclipse.jpt.utility.model.value.ListValueModel;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.jpt.utility.model.value.WritablePropertyValueModel;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+
+/**
+ * This binding can be used to keep a drop-down list box's selection
+ * synchronized with a model. The selection can be modified by either the
+ * drop-down list box or the model, so changes must be coordinated.
+ * <p>
+ * <strong>NB:</strong> A selected item value of <code>null</code> can be used
+ * to clear the drop-down list box's selection. If <code>null</code> is a
+ * valid item in the model list, an invalid selected item can be used to clear
+ * the selection.
+ * 
+ * @see ListValueModel
+ * @see WritablePropertyValueModel
+ * @see DropDownListBox
+ * @see SWTTools
+ */
+@SuppressWarnings("nls")
+final class DropDownListBoxSelectionBinding<E>
+	implements ListWidgetModelBinding.SelectionBinding
+{
+	// ***** model
+	/**
+	 * The underlying list model.
+	 */
+	private final ListValueModel<E> listModel;
+
+	/**
+	 * A writable value model on the underlying model selection.
+	 */
+	private final WritablePropertyValueModel<E> selectedItemModel;
+
+	/**
+	 * A listener that allows us to synchronize the drop-down list box's
+	 * selection with the model selection.
+	 */
+	private final PropertyChangeListener selectedItemChangeListener;
+
+	// ***** UI
+	/**
+	 * The drop-down list box whose selection we keep synchronized
+	 * with the model selection.
+	 */
+	private final DropDownListBox dropdownListBox;
+
+	/**
+	 * A listener that allows us to synchronize our selected item holder
+	 * with the drop-down list box's selection.
+	 */
+	private final SelectionListener dropdownListBoxSelectionListener;
+
+
+	// ********** constructor **********
+
+	/**
+	 * Constructor - all parameters are required.
+	 */
+	DropDownListBoxSelectionBinding(
+			ListValueModel<E> listModel,
+			WritablePropertyValueModel<E> selectedItemModel,
+			DropDownListBox dropdownListBox
+	) {
+		super();
+		if ((listModel == null) || (selectedItemModel == null) || (dropdownListBox == null)) {
+			throw new NullPointerException();
+		}
+		this.listModel = listModel;
+		this.selectedItemModel = selectedItemModel;
+		this.dropdownListBox = dropdownListBox;
+
+		this.selectedItemChangeListener = this.buildSelectedItemChangeListener();
+		this.selectedItemModel.addPropertyChangeListener(PropertyValueModel.VALUE, this.selectedItemChangeListener);
+
+		this.dropdownListBoxSelectionListener = this.buildDropDownListBoxSelectionListener();
+		this.dropdownListBox.addSelectionListener(this.dropdownListBoxSelectionListener);
+	}
+
+
+	// ********** initialization **********
+
+	private PropertyChangeListener buildSelectedItemChangeListener() {
+		return new SWTPropertyChangeListenerWrapper(this.buildSelectedItemChangeListener_());
+	}
+
+	private PropertyChangeListener buildSelectedItemChangeListener_() {
+		return new PropertyChangeListener() {
+			public void propertyChanged(PropertyChangeEvent event) {
+				DropDownListBoxSelectionBinding.this.selectedItemChanged(event);
+			}
+			@Override
+			public String toString() {
+				return "selected item listener";
+			}
+		};
+	}
+
+	private SelectionListener buildDropDownListBoxSelectionListener() {
+		return new SelectionListener() {
+			public void widgetSelected(SelectionEvent event) {
+				DropDownListBoxSelectionBinding.this.dropDownListBoxSelectionChanged(event);
+			}
+			public void widgetDefaultSelected(SelectionEvent event) {
+				DropDownListBoxSelectionBinding.this.dropDownListBoxDoubleClicked(event);
+			}
+			@Override
+			public String toString() {
+				return "drop-down list box selection listener";
+			}
+		};
+	}
+
+
+	// ********** ListWidgetModelBinding.SelectionBinding implementation **********
+
+	/**
+	 * Modifying the drop-down lisb box's selected item programmatically does
+	 * not trigger a SelectionEvent.
+	 * <p>
+	 * Pre-condition: The drop-down list box is not disposed.
+	 */
+	public void synchronizeListWidgetSelection() {
+		int oldIndex = this.dropdownListBox.getSelectionIndex();
+		E value = this.selectedItemModel.getValue();
+		int newIndex = this.indexOf(value);
+		if ((oldIndex != -1) && (newIndex != -1) && (newIndex != oldIndex)) {
+			this.dropdownListBox.deselect(oldIndex);
+		}
+		if (newIndex == -1) {
+			this.dropdownListBox.deselectAll();
+		} else {
+			if (newIndex != oldIndex) {
+				this.dropdownListBox.select(newIndex);
+			}
+		}
+	}
+
+	public void dispose() {
+		this.dropdownListBox.removeSelectionListener(this.dropdownListBoxSelectionListener);
+		this.selectedItemModel.removePropertyChangeListener(PropertyValueModel.VALUE, this.selectedItemChangeListener);
+	}
+
+
+	// ********** selected item **********
+
+	void selectedItemChanged(PropertyChangeEvent event) {
+		if ( ! this.dropdownListBox.isDisposed()) {
+			this.selectedItemChanged_(event);
+		}
+	}
+
+	/**
+	 * Modifying the drop-down list box's selected item programmatically does
+	 * not trigger a SelectionEvent.
+	 */
+	private void selectedItemChanged_(@SuppressWarnings("unused") PropertyChangeEvent event) {
+		this.synchronizeListWidgetSelection();
+	}
+
+	private int indexOf(E item) {
+		int len = this.listModel.size();
+		for (int i = 0; i < len; i++) {
+			if (Tools.valuesAreEqual(this.listModel.get(i), item)) {
+				return i;
+			}
+		}
+		// if 'null' is not in the list, use it to clear the selection
+		if (item == null) {
+			return -1;
+		}
+		// We can get here via one of the following:
+		// 1. The selected item model is invalid and not in sync with the list
+		//    model. This is not good and we don't make this (programming
+		//    error) obvious (e.g. via an exception). :-(
+		// 2. If both the selected item model and the list model are dependent
+		//    on the same underlying model, the selected item model may receive
+		//    its event first, resulting in a missing item. This will resolve
+		//    itself once the list model receives its event and synchronizes
+		//    with the same underlying model. This situation is acceptable.
+		return -1;
+
+// This is what we used to do:
+//		throw new IllegalStateException("selected item not found: " + item);
+	}
+
+
+	// ********** combo-box events **********
+
+	void dropDownListBoxSelectionChanged(SelectionEvent event) {
+		if ( ! this.dropdownListBox.isDisposed()) {
+			this.dropDownListBoxSelectionChanged_(event);
+		}
+	}
+
+	void dropDownListBoxDoubleClicked(SelectionEvent event) {
+		if ( ! this.dropdownListBox.isDisposed()) {
+			this.dropDownListBoxSelectionChanged_(event);
+		}
+	}
+
+	private void dropDownListBoxSelectionChanged_(@SuppressWarnings("unused") SelectionEvent event) {
+		this.selectedItemModel.setValue(this.getDropDownListBoxSelectedItem());
+	}
+
+	private E getDropDownListBoxSelectedItem() {
+		int selectionIndex = this.dropdownListBox.getSelectionIndex();
+		return (selectionIndex == -1) ? null : this.listModel.get(selectionIndex);
+	}
+
+
+	// ********** standard methods **********
+
+	@Override
+	public String toString() {
+		return StringTools.buildToStringFor(this, this.selectedItemModel);
+	}
+
+
+	// ********** adapter interface **********
+
+	/**
+	 * Adapter used by the drop-down list box selection binding to query and manipulate
+	 * the drop-down list box.
+	 */
+	interface DropDownListBox {
+
+		/**
+		 * Return whether the combo-box is "disposed".
+		 */
+		boolean isDisposed();
+
+		/**
+		 * Add the specified selection listener to the combo-box.
+		 */
+		void addSelectionListener(SelectionListener listener);
+
+		/**
+		 * Remove the specified selection listener from the combo-box.
+		 */
+		void removeSelectionListener(SelectionListener listener);
+
+		/**
+		 * Return the index of the combo-box's selection.
+		 */
+		int getSelectionIndex();
+
+		/**
+		 * Select the item at the specified index in the combo-box.
+		 */
+		void select(int index);
+
+		/**
+		 * Deselect the item at the specified index in the combo-box.
+		 */
+		void deselect(int index);
+
+		/**
+		 * Clear the combo-box's selection.
+		 */
+		void deselectAll();
+
+	}
+
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/utility/swt/ListBoxSelectionBinding.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/utility/swt/ListBoxSelectionBinding.java
new file mode 100644
index 0000000..f056866
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/utility/swt/ListBoxSelectionBinding.java
@@ -0,0 +1,305 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2010 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.ui.internal.utility.swt;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+
+import org.eclipse.jpt.ui.internal.listeners.SWTCollectionChangeListenerWrapper;
+import org.eclipse.jpt.utility.internal.ArrayTools;
+import org.eclipse.jpt.utility.internal.StringTools;
+import org.eclipse.jpt.utility.internal.Tools;
+import org.eclipse.jpt.utility.model.event.CollectionAddEvent;
+import org.eclipse.jpt.utility.model.event.CollectionChangeEvent;
+import org.eclipse.jpt.utility.model.event.CollectionClearEvent;
+import org.eclipse.jpt.utility.model.event.CollectionRemoveEvent;
+import org.eclipse.jpt.utility.model.listener.CollectionChangeListener;
+import org.eclipse.jpt.utility.model.value.CollectionValueModel;
+import org.eclipse.jpt.utility.model.value.ListValueModel;
+import org.eclipse.jpt.utility.model.value.WritableCollectionValueModel;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.widgets.List;
+
+/**
+ * This binding can be used to keep a list box's selection
+ * synchronized with a model. The selection can be modified by either the list
+ * box or the model, so changes must be coordinated.
+ * 
+ * @see ListValueModel
+ * @see WritableCollectionValueModel
+ * @see List
+ * @see SWTTools
+ */
+@SuppressWarnings("nls")
+final class ListBoxSelectionBinding<E>
+	implements ListWidgetModelBinding.SelectionBinding
+{
+	// ***** model
+	/**
+	 * The underlying list model.
+	 */
+	private final ListValueModel<E> listModel;
+
+	/**
+	 * A writable value model on the underlying model selections.
+	 */
+	private final WritableCollectionValueModel<E> selectedItemsModel;
+
+	/**
+	 * A listener that allows us to synchronize the list box's selection with
+	 * the model selections.
+	 */
+	private final CollectionChangeListener selectedItemsChangeListener;
+
+	// ***** UI
+	/**
+	 * The list box whose selection we keep synchronized with the model selections.
+	 */
+	private final List listBox;
+
+	/**
+	 * A listener that allows us to synchronize our selected items holder
+	 * with the list box's selection.
+	 */
+	private final SelectionListener listBoxSelectionListener;
+
+
+	// ********** constructor **********
+
+	/**
+	 * Constructor - all parameters are required.
+	 */
+	ListBoxSelectionBinding(
+			ListValueModel<E> listModel,
+			WritableCollectionValueModel<E> selectedItemsModel,
+			List listBox
+	) {
+		super();
+		if ((listModel == null) || (selectedItemsModel == null) || (listBox == null)) {
+			throw new NullPointerException();
+		}
+		this.listModel = listModel;
+		this.selectedItemsModel = selectedItemsModel;
+		this.listBox = listBox;
+
+		this.selectedItemsChangeListener = this.buildSelectedItemsChangeListener();
+		this.selectedItemsModel.addCollectionChangeListener(CollectionValueModel.VALUES, this.selectedItemsChangeListener);
+
+		this.listBoxSelectionListener = this.buildListBoxSelectionListener();
+		this.listBox.addSelectionListener(this.listBoxSelectionListener);
+	}
+
+
+	// ********** initialization **********
+
+	private CollectionChangeListener buildSelectedItemsChangeListener() {
+		return new SWTCollectionChangeListenerWrapper(this.buildSelectedItemsChangeListener_());
+	}
+
+	private CollectionChangeListener buildSelectedItemsChangeListener_() {
+		return new CollectionChangeListener() {
+			public void itemsAdded(CollectionAddEvent event) {
+				ListBoxSelectionBinding.this.selectedItemsAdded(event);
+			}
+			public void itemsRemoved(CollectionRemoveEvent event) {
+				ListBoxSelectionBinding.this.selectedItemsRemoved(event);
+			}
+			public void collectionCleared(CollectionClearEvent event) {
+				ListBoxSelectionBinding.this.selectedItemsCleared(event);
+			}
+			public void collectionChanged(CollectionChangeEvent event) {
+				ListBoxSelectionBinding.this.selectedItemsChanged(event);
+			}
+			@Override
+			public String toString() {
+				return "selected items listener";
+			}
+		};
+	}
+
+	private SelectionListener buildListBoxSelectionListener() {
+		return new SelectionListener() {
+			public void widgetSelected(SelectionEvent event) {
+				ListBoxSelectionBinding.this.listBoxSelectionChanged(event);
+			}
+			public void widgetDefaultSelected(SelectionEvent event) {
+				ListBoxSelectionBinding.this.listBoxDoubleClicked(event);
+			}
+			@Override
+			public String toString() {
+				return "list box selection listener";
+			}
+		};
+	}
+
+
+	// ********** ListWidgetModelBinding.SelectionBinding implementation **********
+
+	/**
+	 * Modifying the list box's selected items programmatically does not
+	 * trigger a SelectionEvent.
+	 * 
+	 * Pre-condition: The list-box is not disposed.
+	 */
+	public void synchronizeListWidgetSelection() {
+		int selectedItemsSize = this.selectedItemsModel.size();
+		int[] select = new int[selectedItemsSize];
+		int i = 0;
+		for (E item : this.selectedItemsModel) {
+			select[i++] = this.indexOf(item);
+		}
+
+		int listSize = this.listModel.size();
+		int[] deselect = new int[listSize - selectedItemsSize];
+		i = 0;
+		for (int j = 0; j < listSize; j++) {
+			if ( ! ArrayTools.contains(select, j)) {
+				deselect[i++] = j;
+			}
+		}
+
+		int[] old = ArrayTools.sort(this.listBox.getSelectionIndices());
+		select = ArrayTools.sort(select);
+		if ( ! Arrays.equals(select, old)) {
+			this.listBox.deselect(deselect);
+			this.listBox.select(select);
+		}
+	}
+
+	public void dispose() {
+		this.listBox.removeSelectionListener(this.listBoxSelectionListener);
+		this.selectedItemsModel.removeCollectionChangeListener(CollectionValueModel.VALUES, this.selectedItemsChangeListener);
+	}
+
+
+	// ********** selected items **********
+
+	void selectedItemsAdded(CollectionAddEvent event) {
+		if ( ! this.listBox.isDisposed()) {
+			this.selectedItemsAdded_(event);
+		}
+	}
+
+	/**
+	 * Modifying the list box's selected items programmatically does not
+	 * trigger a SelectionEvent.
+	 */
+	private void selectedItemsAdded_(CollectionAddEvent event) {
+		int[] indices = new int[event.getItemsSize()];
+		int i = 0;
+		for (E item : this.getItems(event)) {
+			indices[i++] = this.indexOf(item);
+		}
+		this.listBox.select(indices);
+	}
+
+	// minimized scope of suppressed warnings
+	@SuppressWarnings("unchecked")
+	private Iterable<E> getItems(CollectionAddEvent event) {
+		return (Iterable<E>) event.getItems();
+	}
+
+	void selectedItemsRemoved(CollectionRemoveEvent event) {
+		if ( ! this.listBox.isDisposed()) {
+			this.selectedItemsRemoved_(event);
+		}
+	}
+
+	/**
+	 * Modifying the list box's selected items programmatically does not
+	 * trigger a SelectionEvent.
+	 */
+	private void selectedItemsRemoved_(CollectionRemoveEvent event) {
+		int[] indices = new int[event.getItemsSize()];
+		int i = 0;
+		for (E item : this.getItems(event)) {
+			indices[i++] = this.indexOf(item);
+		}
+		this.listBox.deselect(indices);
+	}
+
+	// minimized scope of suppressed warnings
+	@SuppressWarnings("unchecked")
+	private Iterable<E> getItems(CollectionRemoveEvent event) {
+		return (Iterable<E>) event.getItems();
+	}
+
+	void selectedItemsCleared(CollectionClearEvent event) {
+		if ( ! this.listBox.isDisposed()) {
+			this.selectedItemsCleared_(event);
+		}
+	}
+
+	/**
+	 * Modifying the list box's selected items programmatically does not
+	 * trigger a SelectionEvent.
+	 */
+	private void selectedItemsCleared_(@SuppressWarnings("unused") CollectionClearEvent event) {
+		this.listBox.deselectAll();
+	}
+
+	void selectedItemsChanged(CollectionChangeEvent event) {
+		if ( ! this.listBox.isDisposed()) {
+			this.selectedItemsChanged_(event);
+		}
+	}
+
+	private void selectedItemsChanged_(@SuppressWarnings("unused") CollectionChangeEvent event) {
+		this.synchronizeListWidgetSelection();
+	}
+
+	private int indexOf(E item) {
+		int len = this.listModel.size();
+		for (int i = 0; i < len; i++) {
+			if (Tools.valuesAreEqual(this.listModel.get(i), item)) {
+				return i;
+			}
+		}
+		// see comment in DropDownListBoxSelectionBinding.indexOf(E)
+		return -1;
+	}
+
+
+	// ********** list box events **********
+
+	void listBoxSelectionChanged(SelectionEvent event) {
+		if ( ! this.listBox.isDisposed()) {
+			this.listBoxSelectionChanged_(event);
+		}
+	}
+
+	void listBoxDoubleClicked(SelectionEvent event) {
+		if ( ! this.listBox.isDisposed()) {
+			this.listBoxSelectionChanged_(event);
+		}
+	}
+
+	private void listBoxSelectionChanged_(@SuppressWarnings("unused") SelectionEvent event) {
+		this.selectedItemsModel.setValues(this.getListBoxSelectedItems());
+	}
+
+	private Iterable<E> getListBoxSelectedItems() {
+		ArrayList<E> selectedItems = new ArrayList<E>(this.listBox.getSelectionCount());
+		for (int selectionIndex : this.listBox.getSelectionIndices()) {
+			selectedItems.add(this.listModel.get(selectionIndex));
+		}
+		return selectedItems;
+	}
+
+
+	// ********** standard methods **********
+
+	@Override
+	public String toString() {
+		return StringTools.buildToStringFor(this, this.selectedItemsModel);
+	}
+
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/utility/swt/ListWidgetModelBinding.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/utility/swt/ListWidgetModelBinding.java
new file mode 100644
index 0000000..e63f84e
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/utility/swt/ListWidgetModelBinding.java
@@ -0,0 +1,428 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2010 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.ui.internal.utility.swt;
+
+import java.util.ArrayList;
+
+import org.eclipse.jpt.ui.internal.listeners.SWTListChangeListenerWrapper;
+import org.eclipse.jpt.utility.internal.ArrayTools;
+import org.eclipse.jpt.utility.internal.StringConverter;
+import org.eclipse.jpt.utility.internal.StringTools;
+import org.eclipse.jpt.utility.model.event.ListAddEvent;
+import org.eclipse.jpt.utility.model.event.ListChangeEvent;
+import org.eclipse.jpt.utility.model.event.ListClearEvent;
+import org.eclipse.jpt.utility.model.event.ListMoveEvent;
+import org.eclipse.jpt.utility.model.event.ListRemoveEvent;
+import org.eclipse.jpt.utility.model.event.ListReplaceEvent;
+import org.eclipse.jpt.utility.model.listener.ListChangeListener;
+import org.eclipse.jpt.utility.model.value.ListValueModel;
+import org.eclipse.swt.events.DisposeEvent;
+import org.eclipse.swt.events.DisposeListener;
+
+/**
+ * This binding can be used to keep a list widget's contents
+ * synchronized with a model. The list widget never alters
+ * its contents directly; all changes are driven by the model.
+ * 
+ * @see ListValueModel
+ * @see StringConverter
+ * @see ListWidget
+ * @see SelectionBinding
+ * @see SWTTools
+ */
+@SuppressWarnings("nls")
+final class ListWidgetModelBinding<E> {
+
+	// ***** model
+	/**
+	 * The underlying list model.
+	 */
+	private final ListValueModel<E> listModel;
+
+	/**
+	 * A listener that allows us to synchronize the list widget's contents with
+	 * the model list.
+	 */
+	private final ListChangeListener listChangeListener;
+
+	/**
+	 * A converter that converts items in the model list
+	 * to strings that can be put in the list widget.
+	 */
+	private final StringConverter<E> stringConverter;
+
+	// ***** UI
+	/**
+	 * An adapter on the list widget we keep synchronized with the model list.
+	 */
+	private final ListWidget listWidget;
+
+	/**
+	 * A listener that allows us to stop listening to stuff when the list widget
+	 * is disposed. (Critical for preventing memory leaks.)
+	 */
+	private final DisposeListener listWidgetDisposeListener;
+
+	// ***** selection
+	/**
+	 * Widget-specific selection binding.
+	 */
+	private final SelectionBinding selectionBinding;
+
+
+	// ********** constructor **********
+
+	/**
+	 * Constructor - all parameters are required.
+	 */
+	ListWidgetModelBinding(
+			ListValueModel<E> listModel,
+			ListWidget listWidget,
+			StringConverter<E> stringConverter,
+			SelectionBinding selectionBinding
+	) {
+		super();
+		if ((listModel == null) || (listWidget == null) || (stringConverter == null) || (selectionBinding == null)) {
+			throw new NullPointerException();
+		}
+		this.listModel = listModel;
+		this.listWidget = listWidget;
+		this.stringConverter = stringConverter;
+		this.selectionBinding = selectionBinding;
+
+		this.listChangeListener = this.buildListChangeListener();
+		this.listModel.addListChangeListener(ListValueModel.LIST_VALUES, this.listChangeListener);
+
+		this.listWidgetDisposeListener = this.buildListWidgetDisposeListener();
+		this.listWidget.addDisposeListener(this.listWidgetDisposeListener);
+
+		this.synchronizeListWidget();
+	}
+
+
+	// ********** initialization **********
+
+	private ListChangeListener buildListChangeListener() {
+		return new SWTListChangeListenerWrapper(this.buildListChangeListener_());
+	}
+
+	private ListChangeListener buildListChangeListener_() {
+		return new ListChangeListener() {
+			public void itemsAdded(ListAddEvent event) {
+				ListWidgetModelBinding.this.listItemsAdded(event);
+			}
+			public void itemsRemoved(ListRemoveEvent event) {
+				ListWidgetModelBinding.this.listItemsRemoved(event);
+			}
+			public void itemsMoved(ListMoveEvent event) {
+				ListWidgetModelBinding.this.listItemsMoved(event);
+			}
+			public void itemsReplaced(ListReplaceEvent event) {
+				ListWidgetModelBinding.this.listItemsReplaced(event);
+			}
+			public void listCleared(ListClearEvent event) {
+				ListWidgetModelBinding.this.listCleared(event);
+			}
+			public void listChanged(ListChangeEvent event) {
+				ListWidgetModelBinding.this.listChanged(event);
+			}
+			@Override
+			public String toString() {
+				return "list listener";
+			}
+		};
+	}
+
+	private DisposeListener buildListWidgetDisposeListener() {
+		return new DisposeListener() {
+			public void widgetDisposed(DisposeEvent event) {
+				ListWidgetModelBinding.this.listWidgetDisposed(event);
+			}
+			@Override
+			public String toString() {
+				return "list widget dispose listener";
+			}
+		};
+	}
+
+
+	// ********** list **********
+
+	/**
+	 * Brute force synchronization of list widget with the model list.
+	 */
+	private void synchronizeListWidget() {
+		if ( ! this.listWidget.isDisposed()) {
+			this.synchronizeListWidget_();
+		}
+	}
+
+	private void synchronizeListWidget_() {
+		ArrayList<String> items = new ArrayList<String>(this.listModel.size());
+		for (E item : this.listModel) {
+			items.add(this.convert(item));
+		}
+		this.listWidget.setItems(items.toArray(new String[items.size()]));
+
+		// now that the list has changed, we need to synch the selection
+		this.selectionBinding.synchronizeListWidgetSelection();
+	}
+
+	/**
+	 * The model has changed - synchronize the list widget.
+	 */
+	void listItemsAdded(ListAddEvent event) {
+		if ( ! this.listWidget.isDisposed()) {
+			this.listItemsAdded_(event);
+		}
+	}
+
+	private void listItemsAdded_(ListAddEvent event) {
+		int i = event.getIndex();
+		for (E item : this.getItems(event)) {
+			this.listWidget.add(this.convert(item), i++);
+		}
+
+		// now that the list has changed, we need to synch the selection
+		this.selectionBinding.synchronizeListWidgetSelection();
+	}
+
+	// minimized scope of suppressed warnings
+	@SuppressWarnings("unchecked")
+	private Iterable<E> getItems(ListAddEvent event) {
+		return (Iterable<E>) event.getItems();
+	}
+
+	/**
+	 * The model has changed - synchronize the list widget.
+	 */
+	void listItemsRemoved(ListRemoveEvent event) {
+		if ( ! this.listWidget.isDisposed()) {
+			this.listItemsRemoved_(event);
+		}
+	}
+
+	private void listItemsRemoved_(ListRemoveEvent event) {
+		this.listWidget.remove(event.getIndex(), event.getIndex() + event.getItemsSize() - 1);
+
+		// now that the list has changed, we need to synch the selection
+		this.selectionBinding.synchronizeListWidgetSelection();
+	}
+
+	/**
+	 * The model has changed - synchronize the list widget.
+	 */
+	void listItemsMoved(ListMoveEvent event) {
+		if ( ! this.listWidget.isDisposed()) {
+			this.listItemsMoved_(event);
+		}
+	}
+
+	private void listItemsMoved_(ListMoveEvent event) {
+		int target = event.getTargetIndex();
+		int source = event.getSourceIndex();
+		int len = event.getLength();
+		int loStart = Math.min(target, source);
+		int hiStart = Math.max(target, source);
+		// make a copy of the affected items...
+		String[] subArray = ArrayTools.subArray(this.listWidget.getItems(), loStart, hiStart + len);
+		// ...move them around...
+		subArray = ArrayTools.move(subArray, target - loStart, source - loStart, len);
+		// ...and then put them back
+		int i = loStart;
+		for (String item : subArray) {
+			this.listWidget.setItem(i++, item);
+		}
+
+		// now that the list has changed, we need to synch the selection
+		this.selectionBinding.synchronizeListWidgetSelection();
+	}
+
+	/**
+	 * The model has changed - synchronize the list widget.
+	 */
+	void listItemsReplaced(ListReplaceEvent event) {
+		if ( ! this.listWidget.isDisposed()) {
+			this.listItemsReplaced_(event);
+		}
+	}
+
+	private void listItemsReplaced_(ListReplaceEvent event) {
+		int i = event.getIndex();
+		for (E item : this.getNewItems(event)) {
+			this.listWidget.setItem(i++, this.convert(item));
+		}
+
+		// now that the list has changed, we need to synch the selection
+		this.selectionBinding.synchronizeListWidgetSelection();
+	}
+
+	// minimized scope of suppressed warnings
+	@SuppressWarnings("unchecked")
+	private Iterable<E> getNewItems(ListReplaceEvent event) {
+		return (Iterable<E>) event.getNewItems();
+	}
+
+	/**
+	 * The model has changed - synchronize the list widget.
+	 */
+	void listCleared(ListClearEvent event) {
+		if ( ! this.listWidget.isDisposed()) {
+			this.listCleared_(event);
+		}
+	}
+
+	private void listCleared_(@SuppressWarnings("unused") ListClearEvent event) {
+		this.listWidget.removeAll();
+	}
+
+	/**
+	 * The model has changed - synchronize the list widget.
+	 */
+	void listChanged(ListChangeEvent event) {
+		if ( ! this.listWidget.isDisposed()) {
+			this.listChanged_(event);
+		}
+	}
+
+	private void listChanged_(@SuppressWarnings("unused") ListChangeEvent event) {
+		this.synchronizeListWidget_();
+	}
+
+	/**
+	 * Use the string converter to convert the specified item to a
+	 * string that can be added to the list widget.
+	 */
+	private String convert(E item) {
+		return this.stringConverter.convertToString(item);
+	}
+
+
+	// ********** list widget events **********
+
+	void listWidgetDisposed(@SuppressWarnings("unused") DisposeEvent event) {
+		// the list widget is not yet "disposed" when we receive this event
+		// so we can still remove our listeners
+		this.listWidget.removeDisposeListener(this.listWidgetDisposeListener);
+		this.listModel.removeListChangeListener(ListValueModel.LIST_VALUES, this.listChangeListener);
+		this.selectionBinding.dispose();
+	}
+
+
+	// ********** standard methods **********
+
+	@Override
+	public String toString() {
+		return StringTools.buildToStringFor(this, this.listModel);
+	}
+
+
+	// ********** adapter interfaces **********
+
+	/**
+	 * Adapter used by the list widget model binding to query and manipulate
+	 * the widget.
+	 */
+	interface ListWidget {
+
+		/**
+		 * Return whether the list widget is "disposed".
+		 */
+		boolean isDisposed();
+
+		/**
+		 * Add the specified dispose listener to the list widget.
+		 */
+		void addDisposeListener(DisposeListener listener);
+
+		/**
+		 * Remove the specified dispose listener from the list widget.
+		 */
+		void removeDisposeListener(DisposeListener listener);
+
+		/**
+		 * Return the list widget's items.
+		 */
+		String[] getItems();
+
+		/**
+		 * Set the list widget's item at the specified index to the specified item.
+		 */
+		void setItem(int index, String item);
+
+		/**
+		 * Set the list widget's items.
+		 */
+		void setItems(String[] items);
+
+		/**
+		 * Add the specified item to the list widget's items at the specified index.
+		 */
+		void add(String item, int index);
+
+		/**
+		 * Remove the specified range of items from the list widget's items.
+		 */
+		void remove(int start, int end);
+
+		/**
+		 * Remove all the items from the list widget.
+		 */
+		void removeAll();
+
+	}
+
+
+	/**
+	 * Widget-specific selection binding that is controlled by the list widget
+	 * model binding.
+	 */
+	interface SelectionBinding {
+
+		/**
+		 * Synchronize the selection binding's widget with the selection model.
+		 * <p>
+		 * Pre-condition: The widget is not disposed.
+		 */
+		void synchronizeListWidgetSelection();
+
+		/**
+		 * The widget has been disposed; dispose the selection binding.
+		 */
+		void dispose();
+
+
+		/**
+		 * Useful for list boxes that ignore the selection.
+		 */
+		final class Null implements SelectionBinding {
+			public static final SelectionBinding INSTANCE = new Null();
+			public static SelectionBinding instance() {
+				return INSTANCE;
+			}
+			// ensure single instance
+			private Null() {
+				super();
+			}
+			public void synchronizeListWidgetSelection() {
+				// do nothing
+			}
+			public void dispose() {
+				// do nothing
+			}
+			@Override
+			public String toString() {
+				return "SelectionBinding.Null"; //$NON-NLS-1$
+			}
+		}
+
+	}
+
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/utility/swt/MultiControlBooleanStateController.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/utility/swt/MultiControlBooleanStateController.java
new file mode 100644
index 0000000..8395769
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/utility/swt/MultiControlBooleanStateController.java
@@ -0,0 +1,157 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2010 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.ui.internal.utility.swt;
+
+import java.util.HashSet;
+
+import org.eclipse.jpt.utility.internal.iterables.SnapshotCloneIterable;
+import org.eclipse.jpt.utility.model.event.CollectionAddEvent;
+import org.eclipse.jpt.utility.model.event.CollectionChangeEvent;
+import org.eclipse.jpt.utility.model.event.CollectionClearEvent;
+import org.eclipse.jpt.utility.model.event.CollectionRemoveEvent;
+import org.eclipse.jpt.utility.model.listener.CollectionChangeListener;
+import org.eclipse.jpt.utility.model.value.CollectionValueModel;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Control;
+
+/**
+ * This controller enables a boolean model to control either the
+ * <em>enabled</em> or <em>visible</em> properties of a set of SWT controls;
+ * i.e. the controls' properties are kept in synch with the boolean model,
+ * but <em>not</em> vice-versa.
+ * 
+ * @see PropertyValueModel
+ * @see CollectionValueModel
+ * @see Control#setEnabled(boolean)
+ * @see Control#setVisible(boolean)
+ */
+final class MultiControlBooleanStateController
+	extends BooleanStateController
+{
+	/**
+	 * The set of controls whose state is kept in sync with the boolean model.
+	 */
+	private final CollectionValueModel<? extends Control> controlsModel;
+
+	/**
+	 * A listener that allows clients to add/remove controls.
+	 */
+	private final CollectionChangeListener controlsListener;
+
+	/**
+	 * Cache of controls.
+	 */
+	private final HashSet<Control> controls = new HashSet<Control>();
+
+
+	// ********** constructor **********
+
+	/**
+	 * Constructor - the boolean model, the controls model, and the adapter are required.
+	 */
+	MultiControlBooleanStateController(
+			PropertyValueModel<Boolean> booleanModel,
+			CollectionValueModel<? extends Control> controlsModel,
+			boolean defaultValue,
+			Adapter adapter
+	) {
+		super(booleanModel, defaultValue, adapter);
+		if (controlsModel == null) {
+			throw new NullPointerException();
+		}
+		this.controlsModel = controlsModel;
+		this.controlsListener = this.buildControlsListener();
+		this.addControls(controlsModel);
+	}
+
+
+	// ********** initialization **********
+
+	private CollectionChangeListener buildControlsListener() {
+		return new CollectionChangeListener() {
+			@SuppressWarnings("unchecked")
+			public void itemsAdded(CollectionAddEvent event) {
+				MultiControlBooleanStateController.this.addControls((Iterable<? extends Control>) event.getItems());
+			}
+			@SuppressWarnings("unchecked")
+			public void itemsRemoved(CollectionRemoveEvent event) {
+				MultiControlBooleanStateController.this.removeControls((Iterable<? extends Control>) event.getItems());
+			}
+			public void collectionCleared(CollectionClearEvent event) {
+				MultiControlBooleanStateController.this.clearControls();
+			}
+			@SuppressWarnings("unchecked")
+			public void collectionChanged(CollectionChangeEvent event) {
+				MultiControlBooleanStateController.this.clearControls();
+				MultiControlBooleanStateController.this.addControls((Iterable<? extends Control>) event.getCollection());
+			}
+			@Override
+			public String toString() {
+				return "controls listener"; //$NON-NLS-1$
+			}
+		};
+	}
+
+
+	// ********** controls **********
+
+	@Override
+	void setControlState(boolean b) {
+		for (Control control : this.controls) {
+			this.setControlState(control, b);
+		}
+	}
+
+	/* private */ void addControls(Iterable<? extends Control> controls_) {
+		boolean b = this.getBooleanValue();
+		for (Control control : controls_) {
+			this.addControl(control, b);
+		}
+	}
+
+	private void addControl(Control control, boolean b) {
+		if (this.controls.isEmpty()) {
+			this.engageBooleanModel();
+			this.controlsModel.addCollectionChangeListener(CollectionValueModel.VALUES, this.controlsListener);
+		}
+		if (this.controls.add(control)) {
+			this.engageControl(control);
+			this.setControlState(control, b);
+		} else {
+			throw new IllegalArgumentException("duplicate control: " + control); //$NON-NLS-1$
+		}
+	}
+
+	/* private */ void clearControls() {
+		this.removeControls(new SnapshotCloneIterable<Control>(this.controls));
+	}
+
+	/* private */ void removeControls(Iterable<? extends Control> controls_) {
+		for (Control control : controls_) {
+			this.disengageControl(control);
+			this.removeControl(control);
+		}
+	}
+
+	private void removeControl(Control control) {
+		this.controls.remove(control);
+		if (this.controls.isEmpty()) {
+			this.controlsModel.removeCollectionChangeListener(CollectionValueModel.VALUES, this.controlsListener);
+			this.disengageBooleanModel();
+		}
+	}
+
+	@Override
+	void controlDisposed(Control control) {
+		super.controlDisposed(control);
+		this.removeControl(control);
+	}
+
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/utility/swt/SWTComboAdapter.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/utility/swt/SWTComboAdapter.java
new file mode 100644
index 0000000..6d5071e
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/utility/swt/SWTComboAdapter.java
@@ -0,0 +1,67 @@
+/*******************************************************************************
+ * Copyright (c) 2009 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.ui.internal.utility.swt;
+
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.widgets.Combo;
+
+/**
+ * Adapt an SWT {@link Combo} to the list widget expected by
+ * {@link ListWidgetModelBinding} and the
+ * drop-down list box expected by {@link DropDownListBoxSelectionBinding}.
+ */
+final class SWTComboAdapter
+	extends AbstractListWidgetAdapter<Combo>
+	implements DropDownListBoxSelectionBinding.DropDownListBox
+{
+	SWTComboAdapter(Combo combo) {
+		super(combo);
+	}
+
+	// ********** ListWidgetModelBinding.ListWidget implementation **********
+	public String[] getItems() {
+		return this.widget.getItems();
+	}
+	public void setItem(int index, String item) {
+		this.widget.setItem(index, item);
+	}
+	public void setItems(String[] items) {
+		this.widget.setItems(items);
+	}
+	public void add(String item, int index) {
+		this.widget.add(item, index);
+	}
+	public void remove(int start, int end) {
+		this.widget.remove(start, end);
+	}
+	public void removeAll() {
+		this.widget.removeAll();
+	}
+
+	// ********** ComboBoxSelectionBinding.ComboBox implementation **********
+	public void addSelectionListener(SelectionListener listener) {
+		this.widget.addSelectionListener(listener);
+	}
+	public void removeSelectionListener(SelectionListener listener) {
+		this.widget.removeSelectionListener(listener);
+	}
+	public int getSelectionIndex() {
+		return this.widget.getSelectionIndex();
+	}
+	public void select(int index) {
+		this.widget.select(index);
+	}
+	public void deselect(int index) {
+		this.widget.deselect(index);
+	}
+	public void deselectAll() {
+		this.widget.deselectAll();
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/utility/swt/SWTListAdapter.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/utility/swt/SWTListAdapter.java
new file mode 100644
index 0000000..8f681e2
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/utility/swt/SWTListAdapter.java
@@ -0,0 +1,49 @@
+/*******************************************************************************
+ * Copyright (c) 2009 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.ui.internal.utility.swt;
+
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.widgets.List;
+
+/**
+ * Adapt an SWT {@link List} to the list widget expected by
+ * {@link ListWidgetModelBinding}.
+ */
+final class SWTListAdapter
+	extends AbstractListWidgetAdapter<List>
+{
+	SWTListAdapter(List list) {
+		super(list);
+	}
+	public void addSelectionListener(SelectionListener listener) {
+		this.widget.addSelectionListener(listener);
+	}
+	public void removeSelectionListener(SelectionListener listener) {
+		this.widget.removeSelectionListener(listener);
+	}
+	public String[] getItems() {
+		return this.widget.getItems();
+	}
+	public void setItem(int index, String item) {
+		this.widget.setItem(index, item);
+	}
+	public void setItems(String[] items) {
+		this.widget.setItems(items);
+	}
+	public void add(String item, int index) {
+		this.widget.add(item, index);
+	}
+	public void remove(int start, int end) {
+		this.widget.remove(start, end);
+	}
+	public void removeAll() {
+		this.widget.removeAll();
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/utility/swt/SWTTools.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/utility/swt/SWTTools.java
new file mode 100644
index 0000000..1f25f52
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/utility/swt/SWTTools.java
@@ -0,0 +1,392 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2010 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.ui.internal.utility.swt;
+
+import java.util.Arrays;
+
+import org.eclipse.jpt.utility.internal.BitTools;
+import org.eclipse.jpt.utility.internal.StringConverter;
+import org.eclipse.jpt.utility.internal.model.value.StaticCollectionValueModel;
+import org.eclipse.jpt.utility.internal.model.value.WritablePropertyCollectionValueModelAdapter;
+import org.eclipse.jpt.utility.model.value.CollectionValueModel;
+import org.eclipse.jpt.utility.model.value.ListValueModel;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.jpt.utility.model.value.WritableCollectionValueModel;
+import org.eclipse.jpt.utility.model.value.WritablePropertyValueModel;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.List;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.swt.widgets.Widget;
+
+/**
+ * Various SWT tools.
+ */
+@SuppressWarnings("nls")
+public final class SWTTools {
+
+	// ********** check-box/radio button/toggle button **********
+
+	/**
+	 * Bind the specified button (check-box, radio button, or toggle button)
+	 * to the specified boolean model.
+	 * If the boolean model is <code>null<code>, the button's 'selection' state will
+	 * be <code>false<code>.
+	 */
+	public static void bind(WritablePropertyValueModel<Boolean> booleanModel, Button button) {
+		bind(booleanModel, button, false);
+	}
+
+	/**
+	 * Bind the specified button (check-box, radio button, or toggle button)
+	 * to the specified boolean model.
+	 * If the boolean model is <code>null<code>, the button's 'selection' state will
+	 * be the specified default value.
+	 */
+	public static void bind(WritablePropertyValueModel<Boolean> booleanModel, Button button, boolean defaultValue) {
+		// the new binding will add itself as a listener to the boolean model and the button
+		new BooleanButtonModelBinding(booleanModel, button, defaultValue);
+	}
+
+
+	// ********** text field **********
+
+	/**
+	 * Bind the specified text model to the specified text field.
+	 */
+	public static <E> void bind(WritablePropertyValueModel<String> textModel, Text textField) {
+		// the new binding will add itself as a listener to the text model and the text field
+		new TextFieldModelBinding(textModel, textField);
+	}
+
+
+	// ********** list box **********
+
+	/**
+	 * Bind the specified model list to the specified list box.
+	 * The list box selection is ignored.
+	 * Use the default string converter to convert the model items to strings
+	 * to be displayed in the list box, which calls {@link Object#toString()}
+	 * on the items in the model list.
+	 */
+	public static <E> void bind(ListValueModel<E> listModel, List listBox) {
+		bind(listModel, listBox, StringConverter.Default.<E>instance());
+	}
+
+	/**
+	 * Bind the specified model list to the specified list box.
+	 * The list box selection is ignored.
+	 * Use the specified string converter to convert the model items to strings
+	 * to be displayed in the list box.
+	 */
+	public static <E> void bind(ListValueModel<E> listModel, List listBox, StringConverter<E> stringConverter) {
+		bind(listModel, new SWTListAdapter(listBox), stringConverter);
+	}
+
+	/**
+	 * Bind the specified model list and selection to the specified list box.
+	 * Use the default string converter to convert the model items to strings
+	 * to be displayed in the list box, which calls {@link Object#toString()}
+	 * on the items in the model list.
+	 */
+	public static <E> void bind(ListValueModel<E> listModel, WritablePropertyValueModel<E> selectedItemModel, List listBox) {
+		bind(listModel, selectedItemModel, listBox, StringConverter.Default.<E>instance());
+	}
+
+	/**
+	 * Adapt the specified model list and selection to the specified list box.
+	 * Use the specified string converter to convert the model items to strings
+	 * to be displayed in the list box.
+	 */
+	public static <E> void bind(ListValueModel<E> listModel, WritablePropertyValueModel<E> selectedItemModel, List listBox, StringConverter<E> stringConverter) {
+		checkForSingleSelectionStyle(listBox);
+		bind(listModel, new WritablePropertyCollectionValueModelAdapter<E>(selectedItemModel), listBox, stringConverter);
+	}
+
+	/**
+	 * Bind the specified model list and selections to the specified list box.
+	 * Use the default string converter to convert the model items to strings
+	 * to be displayed in the list box, which calls {@link Object#toString()}
+	 * on the items in the model list.
+	 */
+	public static <E> void bind(ListValueModel<E> listModel, WritableCollectionValueModel<E> selectedItemsModel, List listBox) {
+		bind(listModel, selectedItemsModel, listBox, StringConverter.Default.<E>instance());
+	}
+
+	/**
+	 * Bind the specified model list and selections to the specified list box.
+	 * Use the specified string converter to convert the model items to strings
+	 * to be displayed in the list box.
+	 */
+	public static <E> void bind(ListValueModel<E> listModel, WritableCollectionValueModel<E> selectedItemsModel, List listBox, StringConverter<E> stringConverter) {
+		bind(
+			listModel,
+			new SWTListAdapter(listBox),
+			stringConverter,
+			new ListBoxSelectionBinding<E>(listModel, selectedItemsModel, listBox)
+		);
+	}
+
+	private static void checkForSingleSelectionStyle(List listBox) {
+		if ( ! BitTools.flagIsSet(listBox.getStyle(), SWT.SINGLE)) {
+			throw new IllegalStateException("list box must be single-selection: " + listBox);
+		}
+	}
+
+
+	// ********** drop-down list box **********
+
+	/**
+	 * Bind the specified model list and selection to the specified drop-down list box.
+	 * Use the default string converter to convert the model items to strings
+	 * to be displayed in the drop-down list box, which calls {@link Object#toString()}
+	 * on the items in the model list.
+	 */
+	public static <E> void bind(ListValueModel<E> listModel, WritablePropertyValueModel<E> selectedItemModel, Combo dropDownListBox) {
+		bind(listModel, selectedItemModel, dropDownListBox, StringConverter.Default.<E>instance());
+	}
+
+	/**
+	 * Adapt the specified model list and selection to the specified drop-down list box.
+	 * Use the specified string converter to convert the model items to strings
+	 * to be displayed in the drop-down list box.
+	 */
+	public static <E> void bind(ListValueModel<E> listModel, WritablePropertyValueModel<E> selectedItemModel, Combo dropDownListBox, StringConverter<E> stringConverter) {
+		checkForReadOnlyStyle(dropDownListBox);
+		SWTComboAdapter comboAdapter = new SWTComboAdapter(dropDownListBox);
+		bind(
+			listModel,
+			comboAdapter,
+			stringConverter,
+			new DropDownListBoxSelectionBinding<E>(listModel, selectedItemModel, comboAdapter)
+		);
+	}
+
+	private static void checkForReadOnlyStyle(Widget comboBox) {
+		if ( ! BitTools.flagIsSet(comboBox.getStyle(), SWT.READ_ONLY)) {
+			throw new IllegalStateException("combo-box must be read-only: " + comboBox);
+		}
+	}
+
+
+	// ********** list "widget" **********
+
+	/**
+	 * Bind the specified model list to the specified list widget.
+	 * The list widget's selection is ignored.
+	 * Use the specified string converter to convert the model items to strings
+	 * to be displayed in the list box.
+	 */
+	private static <E> void bind(ListValueModel<E> listModel, ListWidgetModelBinding.ListWidget listWidget, StringConverter<E> stringConverter) {
+		bind(listModel, listWidget, stringConverter, ListWidgetModelBinding.SelectionBinding.Null.instance());
+	}
+
+	/**
+	 * Bind the specified model list to the specified list widget.
+	 * Use the specified selection binding to control the list widget's selection.
+	 * Use the specified string converter to convert the model items to strings
+	 * to be displayed in the list box.
+	 */
+	private static <E> void bind(ListValueModel<E> listModel, ListWidgetModelBinding.ListWidget listWidget, StringConverter<E> stringConverter, ListWidgetModelBinding.SelectionBinding selectionBinding) {
+		// the new binding will add itself as a listener to the value models and the list box
+		new ListWidgetModelBinding<E>(listModel, listWidget, stringConverter, selectionBinding);
+	}
+
+
+	// ********** 'enabled' state **********
+
+	/**
+	 * Control the <em>enabled</em> state of the specified controls with the
+	 * specified boolean. If the boolean is <code>null<code>, the controls'
+	 * <em>enabled</em> states will be <code>false<code>.
+	 */
+	public static void controlEnabledState(PropertyValueModel<Boolean> booleanModel, Control... controls) {
+		controlEnabledState(booleanModel, controls, false);
+	}
+
+	/**
+	 * Control the <em>enabled</em> state of the specified controls with the
+	 * specified boolean. If the boolean is <code>null<code>, the controls'
+	 * <em>enabled</em> states will be the specified default value.
+	 */
+	public static void controlEnabledState(PropertyValueModel<Boolean> booleanModel, Control[] controls, boolean defaultValue) {
+		switch (controls.length) {
+			case 0:
+				throw new IllegalArgumentException("empty controls array: " + Arrays.toString(controls));
+			case 1:
+				controlEnabledState(booleanModel, controls[0], defaultValue);
+				break;
+			default:
+				controlEnabledState(booleanModel, new StaticCollectionValueModel<Control>(controls), defaultValue);
+				break;
+		}
+	}
+
+	/**
+	 * Control the <em>enabled</em> state of the specified controls with the
+	 * specified boolean. If the boolean is <code>null<code>, the controls'
+	 * <em>enabled</em> states will be <code>false<code>.
+	 */
+	public static void controlEnabledState(PropertyValueModel<Boolean> booleanModel, Iterable<? extends Control> controls) {
+		controlEnabledState(booleanModel, controls, false);
+	}
+
+	/**
+	 * Control the <em>enabled</em> state of the specified controls with the
+	 * specified boolean. If the boolean is <code>null<code>, the controls'
+	 * <em>enabled</em> states will be the specified default value.
+	 */
+	public static void controlEnabledState(PropertyValueModel<Boolean> booleanModel, Iterable<? extends Control> controls, boolean defaultValue) {
+		controlEnabledState(booleanModel, new StaticCollectionValueModel<Control>(controls), defaultValue);
+	}
+
+	/**
+	 * Control the <em>enabled</em> state of the specified controls with the
+	 * specified boolean. If the boolean is <code>null<code>, the controls'
+	 * <em>enabled</em> states will be <code>false<code>.
+	 */
+	public static void controlEnabledState(PropertyValueModel<Boolean> booleanModel, CollectionValueModel<? extends Control> controlsModel) {
+		controlEnabledState(booleanModel, controlsModel, false);
+	}
+
+	/**
+	 * Control the <em>enabled</em> state of the specified controls with the
+	 * specified boolean. If the boolean is <code>null<code>, the controls'
+	 * <em>enabled</em> states will be the specified default value.
+	 */
+	public static void controlEnabledState(PropertyValueModel<Boolean> booleanModel, CollectionValueModel<? extends Control> controlsModel, boolean defaultValue) {
+		control(booleanModel, controlsModel, defaultValue, ENABLED_ADAPTER);
+	}
+
+	/**
+	 * Control the <em>enabled</em> state of the specified control with the
+	 * specified boolean. If the boolean is <code>null<code>, the control's
+	 * <em>enabled</em> state will be the specified default value.
+	 */
+	public static void controlEnabledState(PropertyValueModel<Boolean> booleanModel, Control control, boolean defaultValue) {
+		control(booleanModel, control, defaultValue, ENABLED_ADAPTER);
+	}
+
+	private static final BooleanStateController.Adapter ENABLED_ADAPTER =
+			new BooleanStateController.Adapter() {
+				public void setState(Control control, boolean b) {
+					control.setEnabled(b);
+				}
+			};
+   
+
+	// ********** 'visible' state **********
+
+	/**
+	 * Control the <em>visible</em> state of the specified controls with the
+	 * specified boolean. If the boolean is <code>null<code>, the controls'
+	 * <em>visible</em> states will be <code>false<code>.
+	 */
+	public static void controlVisibleState(PropertyValueModel<Boolean> booleanModel, Control... controls) {
+		controlVisibleState(booleanModel, controls, false);
+	}
+
+	/**
+	 * Control the <em>visible</em> state of the specified controls with the
+	 * specified boolean. If the boolean is <code>null<code>, the controls'
+	 * <em>visible</em> states will be the specified default value.
+	 */
+	public static void controlVisibleState(PropertyValueModel<Boolean> booleanModel, Control[] controls, boolean defaultValue) {
+		switch (controls.length) {
+			case 0:
+				throw new IllegalArgumentException("empty controls array: " + Arrays.toString(controls));
+			case 1:
+				controlVisibleState(booleanModel, controls[0], defaultValue);
+				break;
+			default:
+				controlVisibleState(booleanModel, new StaticCollectionValueModel<Control>(controls), defaultValue);
+				break;
+		}
+	}
+
+	/**
+	 * Control the <em>visible</em> state of the specified controls with the
+	 * specified boolean. If the boolean is <code>null<code>, the controls'
+	 * <em>visible</em> states will be <code>false<code>.
+	 */
+	public static void controlVisibleState(PropertyValueModel<Boolean> booleanModel, Iterable<? extends Control> controls) {
+		controlVisibleState(booleanModel, controls, false);
+	}
+
+	/**
+	 * Control the <em>visible</em> state of the specified controls with the
+	 * specified boolean. If the boolean is <code>null<code>, the controls'
+	 * <em>visible</em> states will be the specified default value.
+	 */
+	public static void controlVisibleState(PropertyValueModel<Boolean> booleanModel, Iterable<? extends Control> controls, boolean defaultValue) {
+		controlVisibleState(booleanModel, new StaticCollectionValueModel<Control>(controls), defaultValue);
+	}
+
+	/**
+	 * Control the <em>visible</em> state of the specified controls with the
+	 * specified boolean. If the boolean is <code>null<code>, the controls'
+	 * <em>visible</em> states will be <code>false<code>.
+	 */
+	public static void controlVisibleState(PropertyValueModel<Boolean> booleanModel, CollectionValueModel<? extends Control> controlsModel) {
+		controlVisibleState(booleanModel, controlsModel, false);
+	}
+
+	/**
+	 * Control the <em>visible</em> state of the specified controls with the
+	 * specified boolean. If the boolean is <code>null<code>, the controls'
+	 * <em>visible</em> states will be the specified default value.
+	 */
+	public static void controlVisibleState(PropertyValueModel<Boolean> booleanModel, CollectionValueModel<? extends Control> controlsModel, boolean defaultValue) {
+		control(booleanModel, controlsModel, defaultValue, VISIBLE_ADAPTER);
+	}
+
+	/**
+	 * Control the <em>visible</em> state of the specified control with the
+	 * specified boolean. If the boolean is <code>null<code>, the control's
+	 * <em>visible</em> state will be the specified default value.
+	 */
+	public static void controlVisibleState(PropertyValueModel<Boolean> booleanModel, Control control, boolean defaultValue) {
+		control(booleanModel, control, defaultValue, VISIBLE_ADAPTER);
+	}
+
+	private static final BooleanStateController.Adapter VISIBLE_ADAPTER =
+			new BooleanStateController.Adapter() {
+				public void setState(Control control, boolean b) {
+					control.setVisible(b);
+				}
+			};
+   
+
+	// ********** boolean state controller **********
+
+	private static void control(PropertyValueModel<Boolean> booleanModel, CollectionValueModel<? extends Control> controlsModel, boolean defaultValue, BooleanStateController.Adapter adapter) {
+		// the new controller will add itself as a listener to the value model and the controls
+		new MultiControlBooleanStateController(booleanModel, controlsModel, defaultValue, adapter);
+	}
+
+	private static void control(PropertyValueModel<Boolean> booleanModel, Control control, boolean defaultValue, BooleanStateController.Adapter adapter) {
+		// the new controller will add itself as a listener to the value model and the controls
+		new SimpleBooleanStateController(booleanModel, control, defaultValue, adapter);
+	}
+
+
+	// ********** constructor **********
+
+	/**
+	 * Suppress default constructor, ensuring non-instantiability.
+	 */
+	private SWTTools() {
+		super();
+		throw new UnsupportedOperationException();
+	}
+
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/utility/swt/SimpleBooleanStateController.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/utility/swt/SimpleBooleanStateController.java
new file mode 100644
index 0000000..12f158e
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/utility/swt/SimpleBooleanStateController.java
@@ -0,0 +1,68 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2010 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.ui.internal.utility.swt;
+
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Control;
+
+/**
+ * This controller enables a boolean model to control either the
+ * <em>enabled</em> or <em>visible</em> properties of an SWT control; i.e. the
+ * control's property is kept in synch with the boolean model,
+ * but <em>not</em> vice-versa.
+ * <p>
+ * Once the control is disposed, this controller is kaput.
+ * 
+ * @see PropertyValueModel
+ * @see Control#setEnabled(boolean)
+ * @see Control#setVisible(boolean)
+ */
+final class SimpleBooleanStateController
+	extends BooleanStateController
+{
+	private final Control control;
+
+
+	// ********** constructor **********
+
+	/**
+	 * Constructor - the boolean model, the control, and the adapter are required.
+	 */
+	SimpleBooleanStateController(
+			PropertyValueModel<Boolean> booleanModel,
+			Control control,
+			boolean defaultValue,
+			Adapter adapter
+	) {
+		super(booleanModel, defaultValue, adapter);
+		if (control == null) {
+			throw new NullPointerException();
+		}
+		this.control = control;
+		this.engageBooleanModel();
+		this.engageControl(control);
+		this.setControlState(control, this.getBooleanValue());
+	}
+
+
+	// ********** controls **********
+
+	@Override
+	void setControlState(boolean b) {
+		this.setControlState(this.control, b);
+	}
+
+	@Override
+	void controlDisposed(Control c) {
+		super.controlDisposed(c);
+		this.disengageBooleanModel();
+	}
+
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/utility/swt/TextFieldModelBinding.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/utility/swt/TextFieldModelBinding.java
new file mode 100644
index 0000000..5bb0c4e
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/utility/swt/TextFieldModelBinding.java
@@ -0,0 +1,196 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2010 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.ui.internal.utility.swt;
+
+import org.eclipse.jpt.ui.internal.listeners.SWTPropertyChangeListenerWrapper;
+import org.eclipse.jpt.utility.internal.StringTools;
+import org.eclipse.jpt.utility.model.event.PropertyChangeEvent;
+import org.eclipse.jpt.utility.model.listener.PropertyChangeListener;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.jpt.utility.model.value.WritablePropertyValueModel;
+import org.eclipse.swt.events.DisposeEvent;
+import org.eclipse.swt.events.DisposeListener;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.widgets.Text;
+
+/**
+ * This binding can be used to keep a text field
+ * synchronized with a model text/string.
+ * 
+ * @see WritablePropertyValueModel
+ * @see Text
+ */
+@SuppressWarnings("nls")
+class TextFieldModelBinding {
+
+	/**
+	 * The text model we keep synchronized with the text field.
+	 */
+	private final WritablePropertyValueModel<String> textModel;
+
+	/**
+	 * A listener that allows us to synchronize the text field's contents with
+	 * the text model.
+	 */
+	private final PropertyChangeListener textModelChangeListener;
+
+	/**
+	 * The text field we keep synchronized with the text model.
+	 */
+	private final Text textField;
+
+	/**
+	 * A listener that allows us to synchronize our text model
+	 * with the text field's contents.
+	 */
+	private final ModifyListener textFieldModifyListener;
+
+	/**
+	 * A listener that allows us to stop listening to stuff when the text field
+	 * is disposed.
+	 */
+	private final DisposeListener textFieldDisposeListener;
+
+	/**
+	 * Hmm...
+	 */
+	private boolean settingTextFieldText = false;
+
+
+	// ********** constructor **********
+
+	/**
+	 * Constructor - the text model and text field are required.
+	 */
+	TextFieldModelBinding(WritablePropertyValueModel<String> textModel, Text textField) {
+		super();
+		if ((textModel == null) || (textField == null)) {
+			throw new NullPointerException();
+		}
+		this.textModel = textModel;
+		this.textField = textField;
+
+		this.textModelChangeListener = this.buildTextModelChangeListener();
+		this.textModel.addPropertyChangeListener(PropertyValueModel.VALUE, this.textModelChangeListener);
+
+		this.textFieldModifyListener = this.buildTextFieldModifyListener();
+		this.textField.addModifyListener(this.textFieldModifyListener);
+
+		this.textFieldDisposeListener = this.buildTextFieldDisposeListener();
+		this.textField.addDisposeListener(this.textFieldDisposeListener);
+
+		this.setTextFieldText(textModel.getValue());
+	}
+
+
+	// ********** initialization **********
+
+	private PropertyChangeListener buildTextModelChangeListener() {
+		return new SWTPropertyChangeListenerWrapper(this.buildTextModelChangeListener_());
+	}
+
+	private PropertyChangeListener buildTextModelChangeListener_() {
+		return new PropertyChangeListener() {
+			public void propertyChanged(PropertyChangeEvent event) {
+				TextFieldModelBinding.this.textModelChanged(event);
+			}
+			@Override
+			public String toString() {
+				return "text listener";
+			}
+		};
+	}
+
+	private ModifyListener buildTextFieldModifyListener() {
+		return new ModifyListener() {
+			public void modifyText(ModifyEvent event) {
+				TextFieldModelBinding.this.textFieldModified();
+			}
+			@Override
+			public String toString() {
+				return "text field modify listener";
+			}
+		};
+	}
+
+	private DisposeListener buildTextFieldDisposeListener() {
+		return new DisposeListener() {
+			public void widgetDisposed(DisposeEvent event) {
+				TextFieldModelBinding.this.textFieldDisposed();
+			}
+			@Override
+			public String toString() {
+				return "text field dispose listener";
+			}
+		};
+	}
+
+
+	// ********** text model events **********
+
+	/* private */ void textModelChanged(PropertyChangeEvent event) {
+		if ( ! this.textField.isDisposed()) {  // ???
+			this.setTextFieldText((String) event.getNewValue());
+		}
+	}
+
+	private void setTextFieldText(String text) {
+		// the text model can be null, but the text field cannot
+		this.setTextFieldText_((text == null) ? "" : text);
+	}
+
+	private void setTextFieldText_(String text) {
+		if ( ! text.equals(this.textField.getText())) {  // ???
+			this.setTextFieldText__(text);
+		}
+	}
+
+	private void setTextFieldText__(String text) {
+		this.settingTextFieldText = true;
+		try {
+			this.textField.setText(text);
+		} finally {
+			this.settingTextFieldText = false;
+		}
+	}
+
+
+	// ********** text field events **********
+
+	/* private */ void textFieldModified() {
+		if ( ! this.settingTextFieldText) {
+			this.setTextModelText(this.textField.getText());
+		}
+	}
+
+	private void setTextModelText(String text) {
+		if ( ! text.equals(this.textModel.getValue())) {  // ???
+			this.textModel.setValue(text);
+		}
+	}
+
+	/* private */ void textFieldDisposed() {
+		// the text field is not yet "disposed" when we receive this event
+		// so we can still remove our listeners
+		this.textField.removeDisposeListener(this.textFieldDisposeListener);
+		this.textField.removeModifyListener(this.textFieldModifyListener);
+		this.textModel.removePropertyChangeListener(PropertyValueModel.VALUE, this.textModelChangeListener);
+	}
+
+
+	// ********** standard methods **********
+
+	@Override
+	public String toString() {
+		return StringTools.buildToStringFor(this, this.textModel);
+	}
+
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/views/AbstractJpaView.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/views/AbstractJpaView.java
new file mode 100644
index 0000000..002fcdf
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/views/AbstractJpaView.java
@@ -0,0 +1,166 @@
+/********************************************************************************
+ * Copyright (c) 2006, 2009 Versant. 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: Versant and Others. - initial API and implementation
+ ********************************************************************************/
+package org.eclipse.jpt.ui.internal.views;
+
+import org.eclipse.jpt.ui.JptUiPlugin;
+import org.eclipse.jpt.ui.WidgetFactory;
+import org.eclipse.jpt.ui.internal.selection.JpaSelection;
+import org.eclipse.jpt.ui.internal.selection.JpaSelectionManager;
+import org.eclipse.jpt.ui.internal.selection.SelectionManagerFactory;
+import org.eclipse.jpt.ui.internal.widgets.FormWidgetFactory;
+import org.eclipse.jpt.ui.internal.widgets.PropertySheetWidgetFactory;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.FillLayout;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.ui.forms.widgets.FormToolkit;
+import org.eclipse.ui.forms.widgets.ScrolledForm;
+import org.eclipse.ui.part.PageBook;
+import org.eclipse.ui.part.ViewPart;
+import org.eclipse.ui.views.properties.tabbed.TabbedPropertySheetWidgetFactory;
+
+/**
+ * This is the abstract implementation of the JPA view. The selection is changed
+ * by receiving a <code>IJpaSelection</code>.
+ *
+ * @see JpaSelection
+ *
+ * @version 2.0
+ * @since 1.0
+ */
+public abstract class AbstractJpaView extends ViewPart
+{
+	/**
+	 * The default page used when nothing can be shown.
+	 */
+	private Composite defaultComposite;
+
+	/**
+	 * The string to display when there is no view content
+	 */
+	private String defaultLabel;
+
+	/**
+	 * The container of the current page.
+	 */
+	private PageBook pageBook;
+
+	private ScrolledForm scrolledForm;
+	
+	
+	/**
+	 * The factory used to create the various widgets.
+	 */
+	private WidgetFactory widgetFactory;
+
+	/**
+	 * Creates a new <code>AbstractJpaView</code>.
+	 *
+	 * @param defaultLabel
+	 */
+	public AbstractJpaView(String defaultLabel) {
+		super();
+		this.defaultLabel = defaultLabel;
+		this.initialize();
+	}
+
+	private Composite buildDefaultComposite() {
+		Composite composite = widgetFactory.createComposite(pageBook);
+		composite.setLayout(new FillLayout(SWT.VERTICAL));
+		getWidgetFactory().createLabel(composite, defaultLabel);
+		return composite;
+	}
+
+	@Override
+	public final void createPartControl(Composite parent) {
+		this.scrolledForm = getFormWidgetFactory().createScrolledForm(parent);
+		JptUiPlugin.instance().controlAffectsJavaSource(this.scrolledForm);
+		this.scrolledForm.getBody().setLayout(new GridLayout());
+
+		this.pageBook = new PageBook(this.scrolledForm.getBody(), SWT.NONE);
+		GridData gridData = new GridData();
+		gridData.grabExcessHorizontalSpace = true;
+		gridData.horizontalAlignment = SWT.FILL;
+		this.pageBook.setLayoutData(gridData);
+		this.scrolledForm.setContent(this.pageBook);
+
+		this.defaultComposite = buildDefaultComposite();
+		this.pageBook.showPage(this.defaultComposite);
+
+		subcreatePartControl(parent);
+
+		JpaSelectionManager selectionManager =
+			SelectionManagerFactory.getSelectionManager(getViewSite().getWorkbenchWindow());
+
+		selectionManager.register(this);
+		select(selectionManager.getCurrentSelection());
+	}
+
+	protected final PageBook getPageBook() {
+		return this.pageBook;
+	}
+
+	public final WidgetFactory getWidgetFactory() {
+		return this.widgetFactory;
+	}
+
+	/**
+	 * Initializes this JPA view.
+	 */
+	protected void initialize() {
+		this.widgetFactory = new PropertySheetWidgetFactory(
+			new TabbedPropertySheetWidgetFactory()
+		);
+	}
+
+	private FormToolkit getFormWidgetFactory() {
+		return ((FormWidgetFactory) widgetFactory).getWidgetFactory();
+	}
+
+	/**
+	 * The selection has changed, update the current page by using the given
+	 * selection state.
+	 *
+	 * @param jpaSelection The new selection used to update this JPA view
+	 */
+	public abstract void select(JpaSelection jpaSelection);
+
+	/*
+	 * (non-Javadoc)
+	 */
+	@Override
+	public void setFocus() {
+		pageBook.setFocus();
+	}
+
+	/**
+	 * Changes the current page and show the default one.
+	 */
+	protected void showDefaultPage() {
+		showPage(defaultComposite);
+	}
+
+	/**
+	 * Changes the current page and show the given one.
+	 *
+	 * @param page The new page to show, <code>null</code> can't be passed
+	 */
+	protected final void showPage(Control page) {
+		page.setParent(this.pageBook);
+		this.pageBook.showPage(page);
+		this.scrolledForm.reflow(true);
+	}
+
+	protected void subcreatePartControl(@SuppressWarnings("unused") Composite parent) {
+		// no op - for subclasses to override if wished
+	}
+
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/views/JpaDetailsView.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/views/JpaDetailsView.java
new file mode 100644
index 0000000..228056d
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/views/JpaDetailsView.java
@@ -0,0 +1,190 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2010 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.ui.internal.views;
+
+import java.util.HashMap;
+import java.util.Map;
+import org.eclipse.jpt.core.JpaResourceType;
+import org.eclipse.jpt.core.JpaStructureNode;
+import org.eclipse.jpt.ui.JpaPlatformUi;
+import org.eclipse.jpt.ui.JptUiPlugin;
+import org.eclipse.jpt.ui.details.JpaDetailsPage;
+import org.eclipse.jpt.ui.internal.JptUiMessages;
+import org.eclipse.jpt.ui.internal.platform.JpaPlatformUiRegistry;
+import org.eclipse.jpt.ui.internal.selection.JpaSelection;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.FillLayout;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * The JPA view that shows the details of a structure node
+ *
+ * @version 2.2
+ * @since 1.0
+ */
+public class JpaDetailsView extends AbstractJpaView
+{
+	/**
+	 * The current <code>JpaDetailsPage</code> that was retrieve based on the
+	 * current selection.
+	 */
+	private JpaDetailsPage<JpaStructureNode> currentPage;
+
+	/**
+	 * The current selection used to show the right <code>IJpaDetailsPage</code>.
+	 */
+	private JpaSelection currentSelection;
+
+	//TODO this is crap, a Map of Maps of Maps. Needs to be done differently, the factory/platform should handle caching instead
+	// key1 platform id
+	// key2 JpaResourceType
+	// key3 structure node type
+	// value Composite page
+	private Map<String, Map<JpaResourceType, Map<String, JpaDetailsPage<? extends JpaStructureNode>>>> detailsPages;
+
+	/**
+	 * Creates a new <code>JpaDetailsView</code>.
+	 */
+	public JpaDetailsView() {
+		super(JptUiMessages.JpaDetailsView_viewNotAvailable);
+	}
+
+	@Override
+	protected void initialize() {
+		super.initialize();
+
+		this.currentSelection = JpaSelection.NULL_SELECTION;
+		this.detailsPages = new HashMap<String, Map<JpaResourceType, Map<String, JpaDetailsPage<? extends JpaStructureNode>>>>();
+	}
+
+	private JpaPlatformUi getJpaPlatformUi(JpaStructureNode structureNode) {
+		String platformId = structureNode.getJpaProject().getJpaPlatform().getId();
+		return JpaPlatformUiRegistry.instance().getJpaPlatformUi(platformId);
+	}
+
+	public JpaSelection getSelection() {
+		return this.currentSelection;
+	}
+	
+	private JpaDetailsPage<? extends JpaStructureNode> getDetailsPage(JpaStructureNode structureNode) {
+		String platformId = structureNode.getJpaProject().getJpaPlatform().getId();
+		if (this.detailsPages.containsKey(platformId)) {
+			Map<JpaResourceType, Map<String, JpaDetailsPage<? extends JpaStructureNode>>> platformDetailsPages = this.detailsPages.get(platformId);
+			Map<String, JpaDetailsPage<? extends JpaStructureNode>> contentTypeDetailsPages = platformDetailsPages.get(structureNode.getResourceType());
+			if (contentTypeDetailsPages != null) {
+				JpaDetailsPage<? extends JpaStructureNode> page =  contentTypeDetailsPages.get(structureNode.getId());
+				if (page != null) {
+					if (page.getControl().isDisposed()) {
+						platformDetailsPages.remove(structureNode.getId());
+					} else {
+						return page;
+					}
+				}
+			}
+		}
+		return buildDetailsPage(structureNode);
+	}
+
+	private JpaDetailsPage<? extends JpaStructureNode> buildDetailsPage(JpaStructureNode structureNode) {
+		JpaPlatformUi jpaPlatformUi = getJpaPlatformUi(structureNode);
+		
+		Composite container = getWidgetFactory().createComposite(getPageBook());
+		container.setLayout(new FillLayout(SWT.HORIZONTAL));
+
+		JpaDetailsPage<? extends JpaStructureNode> page = jpaPlatformUi.buildJpaDetailsPage(container, structureNode, getWidgetFactory());
+		if (page == null) {
+			return null;
+		}
+
+		String platformId = structureNode.getJpaProject().getJpaPlatform().getId();
+		Map<JpaResourceType, Map<String, JpaDetailsPage<? extends JpaStructureNode>>> platformDetailsPages = this.detailsPages.get(platformId);
+		if (platformDetailsPages == null) {
+			platformDetailsPages = new HashMap<JpaResourceType, Map<String, JpaDetailsPage<? extends JpaStructureNode>>>();
+			this.detailsPages.put(platformId, platformDetailsPages);
+		}
+		JpaResourceType resourceType = structureNode.getResourceType();
+		Map<String, JpaDetailsPage<? extends JpaStructureNode>> contentTypeDetailsPages = platformDetailsPages.get(resourceType);
+		if (contentTypeDetailsPages == null) {
+			contentTypeDetailsPages = new HashMap<String, JpaDetailsPage<? extends JpaStructureNode>>();
+			platformDetailsPages.put(resourceType, contentTypeDetailsPages);
+		}
+		contentTypeDetailsPages.put(structureNode.getId(), page);
+
+		return page;
+	}
+
+	@Override
+	@SuppressWarnings("unchecked")
+	public void select(JpaSelection jpaSelection) {
+		if (jpaSelection.equals(this.currentSelection)) {
+			return;
+		}
+
+		this.currentSelection = jpaSelection;
+		if (jpaSelection == JpaSelection.NULL_SELECTION) {
+			if (this.currentPage != null) {
+				this.currentPage.setSubject(null);
+				this.setCurrentPage(null);
+			}
+			return;
+		}
+		JpaStructureNode newNode = jpaSelection.getSelectedNode();
+		JpaDetailsPage<JpaStructureNode> newPage = (JpaDetailsPage<JpaStructureNode>) getDetailsPage(newNode);
+		if (this.currentPage != null && this.currentPage != newPage){
+			try {
+				this.currentPage.setSubject(null);
+			} catch (Exception e) {
+				JptUiPlugin.log(e);
+			}
+		}
+		if (newPage != null) {
+			try {
+				newPage.setSubject(newNode);
+			} catch (Exception e) {
+				newPage = null;// Show error page
+				JptUiPlugin.log(e);
+			}
+		}
+		setCurrentPage(newPage);
+	}
+
+	/**
+	 * Changes the current page and shows the given page.
+	 *
+	 * @param newPage The new page to display
+	 */
+	private void setCurrentPage(JpaDetailsPage<JpaStructureNode> newPage) {
+		this.currentPage = newPage;
+
+		// Show new page
+		if (newPage == null) {
+			showDefaultPage();
+		}
+		else {
+			showPage(newPage.getControl());
+		}
+	}
+
+	@Override
+	public void dispose() {
+		for (Map<JpaResourceType, Map<String, JpaDetailsPage<? extends JpaStructureNode>>> resourceTypeMap : this.detailsPages.values()) {
+			for (Map<String, JpaDetailsPage<? extends JpaStructureNode>> detailsPageMap : resourceTypeMap.values()) {
+				for (JpaDetailsPage<? extends JpaStructureNode> detailsPage : detailsPageMap.values()) {
+					detailsPage.dispose();
+				}
+			}
+		}
+		this.detailsPages.clear();
+
+		this.currentSelection = JpaSelection.NULL_SELECTION;
+		this.currentPage = null;
+
+		super.dispose();
+	}
+}
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/views/structure/JpaStructurePage.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/views/structure/JpaStructurePage.java
new file mode 100644
index 0000000..e7f7823
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/views/structure/JpaStructurePage.java
@@ -0,0 +1,409 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 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.ui.internal.views.structure;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.runtime.ListenerList;
+import org.eclipse.core.runtime.SafeRunner;
+import org.eclipse.jface.action.IMenuListener;
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.action.IStatusLineManager;
+import org.eclipse.jface.action.MenuManager;
+import org.eclipse.jface.action.Separator;
+import org.eclipse.jface.util.SafeRunnable;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.ISelectionProvider;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.ITreeSelection;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.jpt.core.JpaFile;
+import org.eclipse.jpt.core.JpaProject;
+import org.eclipse.jpt.core.JpaProjectManager;
+import org.eclipse.jpt.core.JpaStructureNode;
+import org.eclipse.jpt.core.JptCorePlugin;
+import org.eclipse.jpt.ui.internal.JptUiMessages;
+import org.eclipse.jpt.ui.internal.jface.DelegatingTreeContentAndLabelProvider;
+import org.eclipse.jpt.ui.internal.selection.DefaultJpaSelection;
+import org.eclipse.jpt.ui.internal.selection.JpaSelection;
+import org.eclipse.jpt.ui.internal.util.SWTUtil;
+import org.eclipse.jpt.ui.jface.DelegatingContentAndLabelProvider;
+import org.eclipse.jpt.ui.structure.JpaStructureProvider;
+import org.eclipse.jpt.utility.model.event.CollectionAddEvent;
+import org.eclipse.jpt.utility.model.event.CollectionChangeEvent;
+import org.eclipse.jpt.utility.model.event.CollectionClearEvent;
+import org.eclipse.jpt.utility.model.event.CollectionRemoveEvent;
+import org.eclipse.jpt.utility.model.listener.CollectionChangeListener;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.FillLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Menu;
+import org.eclipse.ui.IWorkbenchActionConstants;
+import org.eclipse.ui.part.IPageSite;
+import org.eclipse.ui.part.Page;
+
+public class JpaStructurePage 
+	extends Page
+	implements ISelectionProvider
+{
+	private final JpaStructureView jpaStructureView;
+	
+	JpaFile jpaFile;
+	
+	private final IFile file;
+	
+	private JpaProject jpaProject;
+	
+	private final JpaStructureProvider structureProvider;
+	
+	private Composite control;
+	
+	private DelegatingContentAndLabelProvider contentAndLabelProvider;
+	
+	TreeViewer viewer;
+	
+	private final ListenerList selectionChangedListenerList;
+	
+	private final ISelectionChangedListener treeSelectionListener;
+	
+	private final ISelectionChangedListener treePostSelectionListener;
+	
+	private final CollectionChangeListener projectsListener;
+	
+	private final CollectionChangeListener jpaFilesListener;
+	
+	
+	public JpaStructurePage(
+			JpaStructureView jpaStructureView, JpaFile jpaFile, JpaStructureProvider structureProvider) {
+		
+		this.jpaStructureView = jpaStructureView;
+		this.jpaFile = jpaFile;
+		this.jpaProject = jpaFile.getJpaProject();
+		this.file = jpaFile.getFile();
+		this.structureProvider = structureProvider;
+		this.selectionChangedListenerList = new ListenerList();
+		this.treeSelectionListener = new TreeSelectionChangedListener();
+		this.treePostSelectionListener = new TreePostSelectionChangedListener();
+		this.projectsListener = buildProjectsListener();
+		this.jpaFilesListener = buildJpaFilesListener();
+	}
+	
+	
+	private CollectionChangeListener buildProjectsListener() {
+		return new CollectionChangeListener(){
+		
+			public void itemsRemoved(CollectionRemoveEvent event) {
+				JpaStructurePage.this.projectsRemoved(event);
+			}
+		
+			public void itemsAdded(CollectionAddEvent event) {
+				JpaStructurePage.this.projectsAdded(event);
+			}
+		
+			public void collectionCleared(CollectionClearEvent event) {
+				JpaStructurePage.this.projectsCleared(event);
+			}
+		
+			public void collectionChanged(CollectionChangeEvent event) {
+				JpaStructurePage.this.projectsChanged(event);
+			}
+		};
+	}
+
+	@SuppressWarnings("unchecked")
+	void projectsRemoved(CollectionRemoveEvent event) {
+		for (JpaProject item : (Iterable<JpaProject>) event.getItems()) {
+			if (item.getProject() == JpaStructurePage.this.file.getProject()) {
+				setJpaProject(null);
+				break;
+			}
+		}
+	}
+
+	@SuppressWarnings("unchecked")
+	void projectsAdded(CollectionAddEvent event) {
+		for (JpaProject item : (Iterable<JpaProject>) event.getItems()) {
+			if (item.getProject() == JpaStructurePage.this.file.getProject()) {
+				setJpaProject(item);
+				break;
+			}
+		}
+	}
+
+	void projectsCleared(@SuppressWarnings("unused") CollectionClearEvent event) {
+		setJpaProject(null);
+	}
+	
+	void projectsChanged(@SuppressWarnings("unused") CollectionChangeEvent event) {
+		setJpaProject(JptCorePlugin.getJpaProject(this.file.getProject()));
+	}
+	
+	private CollectionChangeListener buildJpaFilesListener() {
+		return new CollectionChangeListener(){
+		
+			public void itemsRemoved(CollectionRemoveEvent event) {
+				JpaStructurePage.this.jpaFilesRemoved(event);
+			}
+		
+			public void itemsAdded(CollectionAddEvent event) {
+				JpaStructurePage.this.jpaFilesAdded(event);
+			}
+		
+			public void collectionCleared(CollectionClearEvent event) {
+				JpaStructurePage.this.jpaFilesCleared(event);
+			}
+		
+			public void collectionChanged(CollectionChangeEvent event) {
+				JpaStructurePage.this.jpaFilesChanged(event);
+			}
+		};
+	}
+	
+	@SuppressWarnings("unchecked")
+	void jpaFilesRemoved(CollectionRemoveEvent event) {
+		for (JpaFile item : (Iterable<JpaFile>) event.getItems()) {
+			if (item == JpaStructurePage.this.jpaFile) {
+				setJpaFile(null);
+				break;
+			}
+		}
+	}
+
+	@SuppressWarnings("unchecked")
+	void jpaFilesAdded(CollectionAddEvent event) {
+		for (JpaFile item : (Iterable<JpaFile>) event.getItems()) {
+			if (item.getFile() != null && item.getFile().equals(JpaStructurePage.this.file)) {
+				setJpaFile(item);
+				break;
+			}
+		}
+	}
+
+	void jpaFilesCleared(@SuppressWarnings("unused") CollectionClearEvent event) {
+		setJpaFile(null);
+	}
+
+	void jpaFilesChanged(@SuppressWarnings("unused") CollectionChangeEvent event) {
+		setJpaFile(this.jpaProject.getJpaFile(this.file));
+	}
+
+	private void setJpaProject(JpaProject jpaProject) {
+		if (this.jpaProject == jpaProject) {
+			return;
+		}
+		if (this.jpaProject != null) {
+			this.jpaProject.removeCollectionChangeListener(JpaProject.JPA_FILES_COLLECTION, this.jpaFilesListener);
+		}
+		this.jpaProject = jpaProject;
+		if (this.jpaProject != null) {
+			this.jpaProject.addCollectionChangeListener(JpaProject.JPA_FILES_COLLECTION, this.jpaFilesListener);
+			setJpaFile(this.jpaProject.getJpaFile(JpaStructurePage.this.file));
+		}
+		else {
+			setJpaFile(null);
+		}
+	}
+	
+	private void setJpaFile(JpaFile jpaFile) {
+		if (this.jpaFile == jpaFile) {
+			return;
+		}
+		this.jpaFile = jpaFile;
+		SWTUtil.asyncExec(new Runnable(){						
+			public void run() {
+				JpaStructurePage.this.viewer.setInput(JpaStructurePage.this.jpaFile);
+			}
+		});
+	}
+	
+	@Override
+	public void init(IPageSite pageSite) {
+		super.init(pageSite);
+		pageSite.setSelectionProvider(this);
+	}
+	
+	@Override
+	public void createControl(Composite parent) {
+		control = new Composite(parent, SWT.NULL);
+		control.setLayout(new FillLayout());		
+		viewer = new TreeViewer(control, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL);
+		viewer.setAutoExpandLevel(2);
+		DelegatingTreeContentAndLabelProvider provider
+			= new DelegatingTreeContentAndLabelProvider(
+				structureProvider.getTreeItemContentProviderFactory(),
+				structureProvider.getItemLabelProviderFactory());
+		this.contentAndLabelProvider = provider;
+		viewer.setContentProvider(provider);
+		// TODO Use problem decorator
+		viewer.setLabelProvider(provider);
+		this.viewer.setInput(this.jpaFile);
+		engageListeners();
+		initContextMenu();
+	}
+	
+	protected void engageListeners() {
+		this.viewer.addSelectionChangedListener(this.treeSelectionListener);
+		this.viewer.addPostSelectionChangedListener(this.treePostSelectionListener);
+		this.jpaProject.addCollectionChangeListener(JpaProject.JPA_FILES_COLLECTION, this.jpaFilesListener);
+		JptCorePlugin.getJpaProjectManager().addCollectionChangeListener(JpaProjectManager.JPA_PROJECTS_COLLECTION, this.projectsListener);
+	}
+	
+	@Override
+	public void dispose() {
+		disengageListeners();
+		super.dispose();
+	}
+	
+	protected void disengageListeners() {
+		JptCorePlugin.getJpaProjectManager().removeCollectionChangeListener(JpaProjectManager.JPA_PROJECTS_COLLECTION, this.projectsListener);
+		if (this.jpaProject != null) {
+			this.jpaProject.removeCollectionChangeListener(JpaProject.JPA_FILES_COLLECTION, this.jpaFilesListener);
+		}
+		this.viewer.removePostSelectionChangedListener(this.treePostSelectionListener);
+		this.viewer.removeSelectionChangedListener(this.treeSelectionListener);
+	}
+	
+    protected void initContextMenu() {
+        // Create dynamic menu mgr.  Dynamic is currently required to
+        // support action contributions.
+        MenuManager mgr = new MenuManager();
+        mgr.setRemoveAllWhenShown(true);
+        mgr.addMenuListener(new IMenuListener() {
+            public void menuAboutToShow(IMenuManager menuManager) {
+                JpaStructurePage.this.fillContextMenu(menuManager);
+            }
+        });
+        Menu menu = mgr.createContextMenu(viewer.getControl());
+        viewer.getControl().setMenu(menu);
+        this.jpaStructureView.getSite().registerContextMenu(mgr, viewer);
+    }	
+	
+    /**
+     * Called when the context menu is about to open.
+     * Delegates to the action group using the viewer's selection as the action context.
+     * @since 2.0
+     */
+    protected void fillContextMenu(IMenuManager manager) {
+        manager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
+    }
+	
+	@Override
+	public Control getControl() {
+		return control;
+	}
+	
+	@Override
+	public void setFocus() {
+		control.setFocus();
+	}
+	
+	
+	
+	void select(JpaSelection selection) {
+		if (selection.isEmpty()) {
+			viewer.setSelection(StructuredSelection.EMPTY);
+		}
+		else {
+			viewer.setSelection(new StructuredSelection(selection.getSelectedNode()), true);
+		}
+	}
+	
+	
+	// **************** ISelectionProvider impl ********************************
+	
+	public void addSelectionChangedListener(ISelectionChangedListener listener) {
+		selectionChangedListenerList.add(listener);
+	}
+	
+	public void removeSelectionChangedListener(ISelectionChangedListener listener) {
+		selectionChangedListenerList.remove(listener);
+	}
+	
+	public ITreeSelection getSelection() {
+		return (ITreeSelection) viewer.getSelection();
+	}
+	
+	public JpaSelection getJpaSelection() {
+		ITreeSelection viewerSelection = getSelection();
+		
+		if (viewerSelection.isEmpty() || viewerSelection.size() > 1) {
+			return JpaSelection.NULL_SELECTION;
+		}
+		return new DefaultJpaSelection((JpaStructureNode) viewerSelection.getFirstElement());
+	}
+	
+	
+	public void setSelection(ISelection selection) {
+		if (viewer != null) {
+			viewer.setSelection(selection);
+		}
+	}
+	
+	/*
+	 * relays tree selection event to listeners of this page
+	 */
+	protected void fireSelectionChanged(ISelection selection) {
+		// create an event
+		final SelectionChangedEvent event = 
+				new SelectionChangedEvent(this, selection);
+		
+		// fire the event
+		Object[] listeners = selectionChangedListenerList.getListeners();
+		for (int i = 0; i < listeners.length; ++i) {
+			final ISelectionChangedListener l = (ISelectionChangedListener) listeners[i];
+			SafeRunner.run(
+					new SafeRunnable() {
+						public void run() {
+							l.selectionChanged(event);
+						}
+					});
+        }
+    }
+	
+	protected void updateStatusBar(ISelection selection) {
+		IStatusLineManager statusLineManager = getSite().getActionBars().getStatusLineManager();
+		if (! (selection instanceof IStructuredSelection) || selection.isEmpty()) {
+			statusLineManager.setMessage(""); //$NON-NLS-1$
+			return;
+		}
+		IStructuredSelection sselection = (IStructuredSelection) selection;
+		if (sselection.size() > 1) {
+			statusLineManager.setMessage(NLS.bind(JptUiMessages.JpaStructureView_numItemsSelected, sselection.size()));
+		}
+		else {
+			Object selObj = sselection.getFirstElement();
+			statusLineManager.setMessage(
+				this.contentAndLabelProvider.getImage(selObj), 
+				this.contentAndLabelProvider.getDescription(selObj));
+		}
+	}
+	
+	
+	class TreeSelectionChangedListener
+		implements ISelectionChangedListener
+	{
+		public void selectionChanged(SelectionChangedEvent event) {
+			JpaStructurePage.this.fireSelectionChanged(event.getSelection());
+		}
+	}
+	
+	
+	class TreePostSelectionChangedListener
+		implements ISelectionChangedListener
+	{
+		public void selectionChanged(SelectionChangedEvent event) {
+			JpaStructurePage.this.updateStatusBar(event.getSelection());
+		}
+	}
+}
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/views/structure/JpaStructureView.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/views/structure/JpaStructureView.java
new file mode 100644
index 0000000..9ced410
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/views/structure/JpaStructureView.java
@@ -0,0 +1,134 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2009 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.ui.internal.views.structure;
+
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jpt.core.JpaFile;
+import org.eclipse.jpt.ui.JpaPlatformUi;
+import org.eclipse.jpt.ui.JptUiPlugin;
+import org.eclipse.jpt.ui.internal.JptUiMessages;
+import org.eclipse.jpt.ui.internal.selection.JpaSelection;
+import org.eclipse.jpt.ui.internal.selection.JpaSelectionManager;
+import org.eclipse.jpt.ui.internal.selection.SelectionManagerFactory;
+import org.eclipse.jpt.ui.structure.JpaStructureProvider;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.part.IPage;
+import org.eclipse.ui.part.MessagePage;
+import org.eclipse.ui.part.PageBook;
+import org.eclipse.ui.part.PageBookView;
+
+public class JpaStructureView
+	extends PageBookView
+{
+	public JpaStructureView() {
+		super();
+	}
+	
+	@Override
+	public void createPartControl(Composite parent) {
+		super.createPartControl(parent);
+		
+		JpaSelectionManager selectionManager =
+			SelectionManagerFactory.getSelectionManager(this.getViewSite().getWorkbenchWindow());
+		
+		selectionManager.register(this);
+		this.select(selectionManager.getCurrentSelection());
+	}
+	
+	@Override
+	public void partBroughtToTop(IWorkbenchPart part) {
+		// do same thing as partActivated, which will check to see if the 
+		// part is an editor, in which case, we want to show the right page
+		partActivated(part);
+	}
+	
+	@Override
+	protected boolean isImportant(IWorkbenchPart part) {
+		return part instanceof IEditorPart;
+	}
+	
+	@Override
+	protected IWorkbenchPart getBootstrapPart() {
+		IWorkbenchPage page = this.getSite().getPage();
+        return (page == null) ? null : page.getActiveEditor();
+	}
+	
+	@Override
+	protected IPage createDefaultPage(PageBook book) {
+		MessagePage page = new MessagePage();
+        this.initPage(page);
+        page.createControl(book);
+        page.setMessage(JptUiMessages.JpaStructureView_structureNotAvailable);
+        return page;
+	}
+	
+	@Override
+	protected PageRec doCreatePage(IWorkbenchPart part) {
+		// use the platform adapter service so the structure view can be
+		// associated with any IEditorPart that has an associated adapter
+		// factory that can give us the JPA file associated with the editor part
+		// @see org.eclipse.jpt.ui.internal.EditorPartAdapterFactory
+		JpaFile jpaFile = (JpaFile) part.getAdapter(JpaFile.class);
+		if (jpaFile == null) {
+			return null;
+		}
+
+		JpaStructureProvider structureProvider = this.getStructureProvider(jpaFile);
+		if (structureProvider == null) {
+			return null;
+		}
+
+		JpaStructurePage page = new JpaStructurePage(this, jpaFile, structureProvider);
+		this.initPage(page);
+		page.createControl(this.getPageBook());
+		return new PageRec(part, page);
+	}
+	
+	private JpaStructureProvider getStructureProvider(JpaFile jpaFile) {
+		return this.getPlatformUi(jpaFile).getStructureProvider(jpaFile);
+	}
+	
+	private JpaPlatformUi getPlatformUi(JpaFile jpaFile) {
+		return JptUiPlugin.instance().getJpaPlatformUi(jpaFile.getJpaProject().getJpaPlatform());
+	}
+	
+	@Override
+	protected void doDestroyPage(IWorkbenchPart part, PageRec pageRecord) {
+		JpaStructurePage page = (JpaStructurePage) pageRecord.page;
+        page.dispose();
+        pageRecord.dispose();
+	}
+	
+	public JpaSelection getJpaSelection() {
+		if (this.getCurrentPage() != this.getDefaultPage()) {
+			return ((JpaStructurePage) this.getCurrentPage()).getJpaSelection();
+		}
+		return JpaSelection.NULL_SELECTION;
+	}
+	
+	public void select(JpaSelection newSelection) {
+		// correct page should be shown
+		if (this.getCurrentPage() != this.getDefaultPage()) {
+			((JpaStructurePage) this.getCurrentPage()).select(newSelection);
+		}
+	}
+	
+	public void addSelectionChangedListener(ISelectionChangedListener listener) {
+		this.getSelectionProvider().addSelectionChangedListener(listener);
+	}
+	
+	public void removeSelectionChangedListener(ISelectionChangedListener listener) {
+		this.getSelectionProvider().removeSelectionChangedListener(listener);
+	}
+
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/widgets/AddRemoveListPane.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/widgets/AddRemoveListPane.java
new file mode 100644
index 0000000..89069c5
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/widgets/AddRemoveListPane.java
@@ -0,0 +1,554 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2009 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.ui.internal.widgets;
+
+import org.eclipse.jface.viewers.IBaseLabelProvider;
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.jface.viewers.ITableLabelProvider;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.jpt.ui.internal.listeners.SWTPropertyChangeListenerWrapper;
+import org.eclipse.jpt.ui.internal.swt.ColumnAdapter;
+import org.eclipse.jpt.ui.internal.swt.TableModelAdapter;
+import org.eclipse.jpt.ui.internal.swt.TableModelAdapter.SelectionChangeEvent;
+import org.eclipse.jpt.ui.internal.swt.TableModelAdapter.SelectionChangeListener;
+import org.eclipse.jpt.ui.internal.util.SWTUtil;
+import org.eclipse.jpt.utility.internal.model.value.SimplePropertyValueModel;
+import org.eclipse.jpt.utility.internal.model.value.swing.ObjectListSelectionModel;
+import org.eclipse.jpt.utility.model.Model;
+import org.eclipse.jpt.utility.model.event.ListAddEvent;
+import org.eclipse.jpt.utility.model.event.ListChangeEvent;
+import org.eclipse.jpt.utility.model.event.ListClearEvent;
+import org.eclipse.jpt.utility.model.event.ListMoveEvent;
+import org.eclipse.jpt.utility.model.event.ListRemoveEvent;
+import org.eclipse.jpt.utility.model.event.ListReplaceEvent;
+import org.eclipse.jpt.utility.model.event.PropertyChangeEvent;
+import org.eclipse.jpt.utility.model.listener.PropertyChangeListener;
+import org.eclipse.jpt.utility.model.value.ListValueModel;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.jpt.utility.model.value.WritablePropertyValueModel;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Layout;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.TableColumn;
+
+/**
+ * This implementation of the <code>AddRemovePane</code> uses a <code>Table</code>
+ * as its main widget, a <code>List</code> can't be used because it doesn't
+ * support showing images. However, the table is displayed like a list.
+ * <p>
+ * Here the layot of this pane:
+ * <pre>
+ * -----------------------------------------------------------------------------
+ * | ------------------------------------------------------------- ----------- |
+ * | | Item 1                                                    | | Add...  | |
+ * | | ...                                                       | ----------- |
+ * | | Item n                                                    | ----------- |
+ * | |                                                           | | Edit... | |
+ * | |                                                           | ----------- |
+ * | |                                                           | ----------- |
+ * | |                                                           | | Remove  | |
+ * | |                                                           | ----------- |
+ * | -------------------------------------------------------------             |
+ * -----------------------------------------------------------------------------</pre>
+ *
+ * @version 2.0
+ * @since 1.0
+ */
+@SuppressWarnings("nls")
+public class AddRemoveListPane<T extends Model> extends AddRemovePane<T>
+{
+
+	/**
+	 * The main widget of this add/remove pane.
+	 */
+	private Table table;
+
+	/**
+	 * Creates a new <code>AddRemoveListPane</code>.
+	 *
+	 * @param parentPane The parent container of this one
+	 * @param parent The parent container
+	 * @param adapter
+	 * @param listHolder The <code>ListValueModel</code> containing the items
+	 * @param selectedItemHolder The holder of the selected item, if more than
+	 * one item or no items are selected, then <code>null</code> will be passed
+	 * @param labelProvider The renderer used to format the table holder's items
+	 */
+	public AddRemoveListPane(Pane<? extends T> parentPane,
+	                         Composite parent,
+	                         Adapter adapter,
+	                         ListValueModel<?> listHolder,
+	                         WritablePropertyValueModel<?> selectedItemHolder,
+	                         ILabelProvider labelProvider) {
+
+		super(parentPane,
+		      parent,
+		      adapter,
+		      listHolder,
+		      selectedItemHolder,
+		      labelProvider);
+	}
+
+	/**
+	 * Creates a new <code>AddRemoveListPane</code>.
+	 *
+	 * @param parentPane The parent container of this one
+	 * @param parent The parent container
+	 * @param adapter
+	 * @param listHolder The <code>ListValueModel</code> containing the items
+	 * @param selectedItemHolder The holder of the selected item, if more than
+	 * one item or no items are selected, then <code>null</code> will be passed
+	 * @param labelProvider The renderer used to format the table holder's items
+	 * @param helpId The topic help ID to be registered with this pane
+	 */
+	public AddRemoveListPane(Pane<? extends T> parentPane,
+	                         Composite parent,
+	                         Adapter adapter,
+	                         ListValueModel<?> listHolder,
+	                         WritablePropertyValueModel<?> selectedItemHolder,
+	                         ILabelProvider labelProvider,
+	                         String helpId) {
+
+		super(parentPane,
+		      parent,
+		      adapter,
+		      listHolder,
+		      selectedItemHolder,
+		      labelProvider,
+		      helpId);
+	}
+
+	/**
+	 * Creates a new <code>AddRemoveListPane</code>.
+	 *
+	 * @param parentPane The parent container of this one
+	 * @param parent The parent container
+	 * @param adapter
+	 * @param listHolder The <code>ListValueModel</code> containing the items
+	 * @param selectedItemHolder The holder of the selected item, if more than
+	 * one item or no items are selected, then <code>null</code> will be passed
+	 * @param labelProvider The renderer used to format the table holder's items
+	 * @param helpId The topic help ID to be registered with this pane
+	 * @param parentManagePane <code>true</code> to have the parent pane manage
+	 * the enabled state of this pane
+	 */
+	public AddRemoveListPane(Pane<? extends T> parentPane,
+	                         Composite parent,
+	                         Adapter adapter,
+	                         ListValueModel<?> listHolder,
+	                         WritablePropertyValueModel<?> selectedItemHolder,
+	                         ILabelProvider labelProvider,
+	                         String helpId,
+	                         boolean parentManagePane) {
+
+		super(parentPane,
+		      parent,
+		      adapter,
+		      listHolder,
+		      selectedItemHolder,
+		      labelProvider,
+		      helpId,
+		      parentManagePane);
+	}
+
+	/**
+	 * Creates a new <code>AddRemoveListPane</code>.
+	 *
+	 * @param parentPane The parent container of this one
+	 * @param subjectHolder The holder of the subject
+	 * @param adapter
+	 * @param parent The parent container
+	 * @param listHolder The <code>ListValueModel</code> containing the items
+	 * @param selectedItemHolder The holder of the selected item, if more than
+	 * one item or no items are selected, then <code>null</code> will be passed
+	 * @param labelProvider The renderer used to format the table holder's items
+	 */
+	public AddRemoveListPane(Pane<?> parentPane,
+	                         PropertyValueModel<? extends T> subjectHolder,
+	                         Composite parent,
+	                         Adapter adapter,
+	                         ListValueModel<?> listHolder,
+	                         WritablePropertyValueModel<?> selectedItemHolder,
+	                         ILabelProvider labelProvider) {
+
+		super(parentPane,
+		      subjectHolder,
+		      parent,
+		      adapter,
+		      listHolder,
+		      selectedItemHolder,
+		      labelProvider);
+	}
+
+	/**
+	 * Creates a new <code>AddRemoveListPane</code>.
+	 *
+	 * @param parentPane The parent container of this one
+	 * @param subjectHolder The holder of the subject
+	 * @param adapter
+	 * @param parent The parent container
+	 * @param listHolder The <code>ListValueModel</code> containing the items
+	 * @param selectedItemHolder The holder of the selected item, if more than
+	 * one item or no items are selected, then <code>null</code> will be passed
+	 * @param labelProvider The renderer used to format the table holder's items
+	 * @param helpId The topic help ID to be registered with this pane
+	 */
+	public AddRemoveListPane(Pane<?> parentPane,
+	                         PropertyValueModel<? extends T> subjectHolder,
+	                         Composite parent,
+	                         Adapter adapter,
+	                         ListValueModel<?> listHolder,
+	                         WritablePropertyValueModel<?> selectedItemHolder,
+	                         ILabelProvider labelProvider,
+	                         String helpId) {
+
+		super(parentPane,
+		      subjectHolder,
+		      parent,
+		      adapter,
+		      listHolder,
+		      selectedItemHolder,
+		      labelProvider,
+		      helpId);
+	}
+
+	private ColumnAdapter<Object> buildColumnAdapter() {
+		return new ColumnAdapter<Object>() {
+			public WritablePropertyValueModel<?>[] cellModels(Object subject) {
+				WritablePropertyValueModel<?>[] valueHolders = new WritablePropertyValueModel<?>[1];
+				valueHolders[0] = new SimplePropertyValueModel<Object>(subject);
+				return valueHolders;
+			}
+
+			public int columnCount() {
+				return 1;
+			}
+
+			public String columnName(int columnIndex) {
+				return "";
+			}
+		};
+	}
+
+	@Override
+	protected void itemsAdded(ListAddEvent e) {
+		super.itemsAdded(e);
+		revalidateLayout();
+	}
+
+	@Override
+	protected void itemsMoved(ListMoveEvent e) {
+		super.itemsMoved(e);
+		revalidateLayout();
+	}
+
+	@Override
+	protected void itemsRemoved(ListRemoveEvent e) {
+		super.itemsRemoved(e);
+		revalidateLayout();
+	}
+
+	@Override
+	protected void itemsReplaced(ListReplaceEvent e) {
+		super.itemsReplaced(e);
+		revalidateLayout();
+	}
+
+	@Override
+	protected void listChanged(ListChangeEvent e) {
+		super.listChanged(e);
+		revalidateLayout();
+	}
+
+	@Override
+	protected void listCleared(ListClearEvent e) {
+		super.listCleared(e);
+		revalidateLayout();
+	}
+
+	/**
+	 * Revalidates the table layout after the list of items has changed. The
+	 * layout has to be done in a new UI thread because our listener might be
+	 * notified before the table has been updated (table column added or removed).
+	 */
+	private void revalidateLayout() {
+		SWTUtil.asyncExec(new Runnable() { public void run() {
+			if (!table.isDisposed()) {
+				table.getParent().computeSize(SWT.DEFAULT, SWT.DEFAULT);
+				table.getParent().layout();
+			}
+		}});
+	}
+
+	private PropertyChangeListener buildSelectedItemPropertyChangeListener() {
+		return new SWTPropertyChangeListenerWrapper(
+			buildSelectedItemPropertyChangeListener_()
+		);
+	}
+
+	private PropertyChangeListener buildSelectedItemPropertyChangeListener_() {
+		return new PropertyChangeListener() {
+			public void propertyChanged(PropertyChangeEvent e) {
+				if (table.isDisposed()) {
+					return;
+				}
+				getSelectionModel().setSelectedValue(e.getNewValue());
+				updateButtons();
+			}
+		};
+	}
+
+	private SelectionChangeListener<Object> buildSelectionListener() {
+		return new SelectionChangeListener<Object>() {
+			public void selectionChanged(SelectionChangeEvent<Object> e) {
+				AddRemoveListPane.this.selectionChanged();
+			}
+		};
+	}
+
+	private Composite addTableContainer(Composite container) {
+
+		container = addPane(container, buildTableContainerLayout());
+		container.setLayoutData(new GridData(GridData.FILL_BOTH));
+		return container;
+	}
+
+	private Layout buildTableContainerLayout() {
+		return new Layout() {
+			@Override
+			protected Point computeSize(Composite composite,
+			                            int widthHint,
+			                            int heightHint,
+			                            boolean flushCache) {
+
+				Table table = (Table) composite.getChildren()[0];
+				TableColumn tableColumn = table.getColumn(0);
+				int columnWidth = tableColumn.getWidth();
+				packColumn(table);
+
+				// Calculate the table size and adjust it with the hints
+				Point size = table.computeSize(SWT.DEFAULT, SWT.DEFAULT);
+
+				if (widthHint != SWT.DEFAULT) {
+					size.x = widthHint;
+				}
+
+				if (heightHint != SWT.DEFAULT) {
+					size.y = heightHint;
+				}
+
+				// Revert the column's width to its current value
+				table.setRedraw(false);
+				table.setLayoutDeferred(true);
+				tableColumn.setWidth(columnWidth);
+				table.setLayoutDeferred(false);
+				table.setRedraw(true);
+
+				return size;
+			}
+
+			private boolean isVerticalScrollbarBarVisible(Table table,
+			                                              Rectangle clientArea) {
+
+				// Get the height of all the rows
+				int height = table.getItemCount() * table.getItemHeight();
+
+				// Remove the border from the height
+				height += (table.getBorderWidth() * 2);
+
+				return (clientArea.height < height);
+			}
+
+			@Override
+			protected void layout(Composite composite, boolean flushCache) {
+
+				Rectangle bounds = composite.getClientArea();
+
+				if (bounds.width > 0) {
+
+					Table table = (Table) composite.getChildren()[0];
+					table.setBounds(0, 0, bounds.width, bounds.height);
+
+					updateTableColumnWidth(
+						table,
+						bounds.width,
+						isVerticalScrollbarBarVisible(table, bounds)
+					);
+				}
+			}
+
+			private void packColumn(Table table) {
+
+				TableColumn tableColumn = table.getColumn(0);
+
+				table.setRedraw(false);
+				table.setLayoutDeferred(true);
+				tableColumn.pack();
+				table.setLayoutDeferred(false);
+				table.setRedraw(true);
+
+				// Cache the column width so it can be used in
+				// updateTableColumnWidth() when determine which width to use
+				table.setData(
+					"column.width",
+					Integer.valueOf(tableColumn.getWidth())
+				);
+			}
+
+			private void updateTableColumnWidth(Table table,
+			                                    int width,
+			                                    boolean verticalScrollbarBarVisible) {
+
+				// Remove the border from the width
+				width -= (table.getBorderWidth() * 2);
+
+				// Remove the scrollbar from the width if it is shown
+				if (verticalScrollbarBarVisible) {
+					width -= table.getVerticalBar().getSize().x;
+				}
+
+				TableColumn tableColumn = table.getColumn(0);
+
+				// Retrieve the cached column width, which is required for
+				// determining which width to use (the column width or the
+				// calculated width)
+				Integer columnWitdh = (Integer) table.getData("column.width");
+
+				// Use the calculated width if the column is smaller, otherwise
+				// use the column width and a horizontal scroll bar will show up
+				width = Math.max(width, columnWitdh);
+
+				// Adjust the column width
+				tableColumn.setWidth(width);
+			}
+		};
+	}
+
+	private ITableLabelProvider buildTableLabelProvider(IBaseLabelProvider labelProvider) {
+		return new TableLabelProvider((ILabelProvider) labelProvider);
+	}
+
+	/*
+	 * (non-Javadoc)
+	 */
+	@Override
+	public Table getMainControl() {
+		return table;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 */
+	@Override
+	@SuppressWarnings("unchecked")
+	protected void initializeMainComposite(Composite container,
+	                                       Adapter adapter,
+	                                       ListValueModel<?> listHolder,
+	                                       WritablePropertyValueModel<?> selectedItemHolder,
+	                                       IBaseLabelProvider labelProvider,
+	                                       String helpId) {
+
+		table = addUnmanagedTable(
+			addTableContainer(container),
+			SWT.H_SCROLL | SWT.V_SCROLL | SWT.FULL_SELECTION | SWT.MULTI,
+			helpId
+		);
+
+
+		TableModelAdapter model = TableModelAdapter.adapt(
+			(ListValueModel<Object>) listHolder,
+			getSelectedItemHolder(),
+			table,
+			buildColumnAdapter(),
+			buildTableLabelProvider(labelProvider)
+		);
+
+		model.addSelectionChangeListener(buildSelectionListener());
+
+		selectedItemHolder.addPropertyChangeListener(
+			PropertyValueModel.VALUE,
+			buildSelectedItemPropertyChangeListener()
+		);
+
+		initializeTable(table);
+	}
+
+	/**
+	 * Initializes the given table, which acts like a list in our case.
+	 *
+	 * @param table The main widget of this pane
+	 */
+	protected void initializeTable(Table table) {
+
+		table.setData("column.width", new Integer(0));
+		table.setHeaderVisible(false);
+		table.setLinesVisible(false);
+	}
+
+	/**
+	 * The selection has changed, update (1) the selected item holder, (2) the
+	 * selection model and (3) the buttons.
+	 */
+	private void selectionChanged() {
+		WritablePropertyValueModel<Object> selectedItemHolder = getSelectedItemHolder();
+		ObjectListSelectionModel selectionModel = getSelectionModel();
+		int selectionCount = this.table.getSelectionCount();
+
+		if (selectionCount == 0) {
+			selectedItemHolder.setValue(null);
+			selectionModel.clearSelection();
+		}
+		else if (selectionCount != 1) {
+			selectedItemHolder.setValue(null);
+			selectionModel.clearSelection();
+
+			for (int index : this.table.getSelectionIndices()) {
+				selectionModel.addSelectionInterval(index, index);
+			}
+		}
+		else {
+			int selectedIndex = this.table.getSelectionIndex();
+			Object selectedItem = getListHolder().get(selectedIndex);
+
+			selectedItemHolder.setValue(selectedItem);
+			selectionModel.setSelectedValue(selectedItem);
+		}
+
+		updateButtons();
+	}
+
+	/**
+	 * This label provider simply delegates the rendering to the provided
+	 * <code>ILabelProvider</code>.
+	 */
+	private class TableLabelProvider extends LabelProvider
+	                                 implements ITableLabelProvider {
+
+		private ILabelProvider labelProvider;
+
+		TableLabelProvider(ILabelProvider labelProvider) {
+			super();
+			this.labelProvider = labelProvider;
+		}
+
+		public Image getColumnImage(Object element, int columnIndex) {
+			return labelProvider.getImage(element);
+		}
+
+		public String getColumnText(Object element, int columnIndex) {
+			return labelProvider.getText(element);
+		}
+	}
+}
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/widgets/AddRemovePane.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/widgets/AddRemovePane.java
new file mode 100644
index 0000000..49022fa
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/widgets/AddRemovePane.java
@@ -0,0 +1,923 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2009 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.ui.internal.widgets;
+
+import java.util.Arrays;
+
+import org.eclipse.jface.viewers.IBaseLabelProvider;
+import org.eclipse.jpt.ui.internal.JptUiMessages;
+import org.eclipse.jpt.ui.internal.listeners.SWTListChangeListenerWrapper;
+import org.eclipse.jpt.utility.internal.CollectionTools;
+import org.eclipse.jpt.utility.internal.model.value.swing.ListModelAdapter;
+import org.eclipse.jpt.utility.internal.model.value.swing.ObjectListSelectionModel;
+import org.eclipse.jpt.utility.model.Model;
+import org.eclipse.jpt.utility.model.event.ListAddEvent;
+import org.eclipse.jpt.utility.model.event.ListChangeEvent;
+import org.eclipse.jpt.utility.model.event.ListClearEvent;
+import org.eclipse.jpt.utility.model.event.ListMoveEvent;
+import org.eclipse.jpt.utility.model.event.ListRemoveEvent;
+import org.eclipse.jpt.utility.model.event.ListReplaceEvent;
+import org.eclipse.jpt.utility.model.listener.ListChangeListener;
+import org.eclipse.jpt.utility.model.value.ListValueModel;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.jpt.utility.model.value.WritablePropertyValueModel;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * The abstract definition of a pane that has buttons for adding, removing and
+ * possibly editing the items.
+ *
+ * @see AddRemoveListPane
+ *
+ * @version 1.0
+ * @since 2.0
+ */
+public abstract class AddRemovePane<T extends Model> extends Pane<T>
+{
+	private Adapter adapter;
+	private Button addButton;
+	private Composite container;
+	private boolean enabled;
+	private IBaseLabelProvider labelProvider;
+	private ListValueModel<?> listHolder;
+	private Button optionalButton;
+	private Button removeButton;
+	private WritablePropertyValueModel<Object> selectedItemHolder;
+	private ObjectListSelectionModel selectionModel;
+
+	/**
+	 * Creates a new <code>AddRemovePane</code>.
+	 *
+	 * @param parentPane The parent container of this one
+	 * @param parent The parent container
+	 * @param adapter This <code>Adapter</code> is used to dictacte the behavior
+	 * of this <code>AddRemovePane</code> and by delegating to it some of the
+	 * behavior
+	 * @param listHolder The <code>ListValueModel</code> containing the items
+	 * @param selectedItemHolder The holder of the selected item, if more than
+	 * one item or no items are selected, then <code>null</code> will be passed
+	 * @param labelProvider The renderer used to format the list holder's items
+	 */
+	protected AddRemovePane(Pane<? extends T> parentPane,
+	                        Composite parent,
+	                        Adapter adapter,
+	                        ListValueModel<?> listHolder,
+	                        WritablePropertyValueModel<?> selectedItemHolder,
+	                        IBaseLabelProvider labelProvider) {
+
+		this(parentPane,
+		     parent,
+		     adapter,
+		     listHolder,
+		     selectedItemHolder,
+		     labelProvider,
+		     null);
+	}
+
+	/**
+	 * Creates a new <code>AddRemovePane</code>.
+	 *
+	 * @param parentPane The parent container of this one
+	 * @param parent The parent container
+	 * @param adapter This <code>Adapter</code> is used to dictacte the behavior
+	 * of this <code>AddRemovePane</code> and by delegating to it some of the
+	 * behavior
+	 * @param listHolder The <code>ListValueModel</code> containing the items
+	 * @param selectedItemHolder The holder of the selected item, if more than
+	 * one item or no items are selected, then <code>null</code> will be passed
+	 * @param labelProvider The renderer used to format the list holder's items
+	 * @param helpId The topic help ID to be registered with this pane
+	 */
+	protected AddRemovePane(Pane<? extends T> parentPane,
+	                        Composite parent,
+	                        Adapter adapter,
+	                        ListValueModel<?> listHolder,
+	                        WritablePropertyValueModel<?> selectedItemHolder,
+	                        IBaseLabelProvider labelProvider,
+	                        String helpId) {
+
+		this(parentPane,
+		     parent,
+		     adapter,
+		     listHolder,
+		     selectedItemHolder,
+		     labelProvider,
+		     helpId,
+		     true);
+	}
+	/**
+	 * Creates a new <code>AddRemovePane</code>.
+	 *
+	 * @param parentPane The parent container of this one
+	 * @param parent The parent container
+	 * @param adapter This <code>Adapter</code> is used to dictacte the behavior
+	 * of this <code>AddRemovePane</code> and by delegating to it some of the
+	 * behavior
+	 * @param listHolder The <code>ListValueModel</code> containing the items
+	 * @param selectedItemHolder The holder of the selected item, if more than
+	 * one item or no items are selected, then <code>null</code> will be passed
+	 * @param labelProvider The renderer used to format the list holder's items
+	 * @param helpId The topic help ID to be registered with this pane
+	 * @param parentManagePane <code>true</code> to have the parent pane manage
+	 * the enabled state of this pane
+	 */
+	protected AddRemovePane(Pane<? extends T> parentPane,
+	                        Composite parent,
+	                        Adapter adapter,
+	                        ListValueModel<?> listHolder,
+	                        WritablePropertyValueModel<?> selectedItemHolder,
+	                        IBaseLabelProvider labelProvider,
+	                        String helpId, 
+	                        boolean parentManagePane) {
+
+		super(parentPane, parent, true, parentManagePane);
+
+		initialize(
+			adapter,
+			listHolder,
+			selectedItemHolder,
+			labelProvider
+		);
+
+		initializeLayout(
+			adapter,
+			listHolder,
+			selectedItemHolder,
+			labelProvider,
+			helpId
+		);
+	}
+
+	/**
+	 * Creates a new <code>AddRemovePane</code>.
+	 *
+	 * @param parentPane The parent container of this one
+	 * @param subjectHolder The holder of the subject
+	 * @param adapter This <code>Adapter</code> is used to dictacte the behavior
+	 * of this <code>AddRemovePane</code> and by delegating to it some of the
+	 * behavior
+	 * @param parent The parent container
+	 * @param listHolder The <code>ListValueModel</code> containing the items
+	 * @param selectedItemHolder The holder of the selected item, if more than
+	 * one item or no items are selected, then <code>null</code> will be passed
+	 * @param labelProvider The renderer used to format the list holder's items
+	 */
+	protected AddRemovePane(Pane<?> parentPane,
+	                        PropertyValueModel<? extends T> subjectHolder,
+	                        Composite parent,
+	                        Adapter adapter,
+	                        ListValueModel<?> listHolder,
+	                        WritablePropertyValueModel<?> selectedItemHolder,
+	                        IBaseLabelProvider labelProvider) {
+
+		this(parentPane,
+		     subjectHolder,
+		     parent,
+		     adapter,
+		     listHolder,
+		     selectedItemHolder,
+		     labelProvider,
+		     null);
+	}
+
+	/**
+	 * Creates a new <code>AddRemovePane</code>.
+	 *
+	 * @param parentPane The parent container of this one
+	 * @param subjectHolder The holder of the subject
+	 * @param adapter This <code>Adapter</code> is used to dictacte the behavior
+	 * of this <code>AddRemovePane</code> and by delegating to it some of the
+	 * behavior
+	 * @param parent The parent container
+	 * @param listHolder The <code>ListValueModel</code> containing the items
+	 * @param selectedItemHolder The holder of the selected item, if more than
+	 * one item or no items are selected, then <code>null</code> will be passed
+	 * @param labelProvider The renderer used to format the list holder's items
+	 * @param helpId The topic help ID to be registered with this pane
+	 */
+	protected AddRemovePane(Pane<?> parentPane,
+	                        PropertyValueModel<? extends T> subjectHolder,
+	                        Composite parent,
+	                        Adapter adapter,
+	                        ListValueModel<?> listHolder,
+	                        WritablePropertyValueModel<?> selectedItemHolder,
+	                        IBaseLabelProvider labelProvider,
+	                        String helpId) {
+
+		super(parentPane, subjectHolder, parent);
+
+		initialize(
+			adapter,
+			listHolder,
+			selectedItemHolder,
+			labelProvider
+		);
+
+		initializeLayout(
+			adapter,
+			listHolder,
+			selectedItemHolder,
+			labelProvider,
+			helpId
+		);
+	}
+
+	/**
+	 * Gives the possibility to add buttons after the Add button and before the
+	 * optional button.
+	 *
+	 * @param container The parent container
+	 * @param helpId The topic help ID to be registered with the buttons
+	 *
+	 * @category Layout
+	 */
+	protected void addCustomButtonAfterAddButton(Composite container,
+	                                             String helpId) {
+	}
+
+	/**
+	 * Gives the possibility to add buttons after the optional button and before
+	 * the Remove button.
+	 *
+	 * @param container The parent container
+	 * @param helpId The topic help ID to be registered with the buttons
+	 *
+	 * @category Layout
+	 */
+	protected void addCustomButtonAfterOptionalButton(Composite container,
+	                                                  String helpId) {
+	}
+
+	/**
+	 * @category Add
+	 */
+	protected void addItem() {
+		adapter.addNewItem(selectionModel);
+	}
+
+	/**
+	 * @category Initialize
+	 */
+	protected Adapter buildAdapter() {
+		return adapter;
+	}
+
+	/**
+	 * @category Add
+	 */
+	protected Button addAddButton(Composite parent) {
+		return addUnmanagedButton(
+			parent,
+			adapter.addButtonText(),
+			buildAddItemAction()
+		);
+	}
+
+	/**
+	 * @category Add
+	 */
+	private Runnable buildAddItemAction() {
+		return new Runnable() {
+			public void run() {
+				AddRemovePane.this.addItem();
+			}
+		};
+	}
+
+	private ListChangeListener buildListChangeListener() {
+		return new SWTListChangeListenerWrapper(buildListChangeListener_());
+	}
+
+	private ListChangeListener buildListChangeListener_() {
+		return new ListChangeListener() {
+
+			public void itemsAdded(ListAddEvent e) {
+				AddRemovePane.this.itemsAdded(e);
+			}
+
+			public void itemsMoved(ListMoveEvent e) {
+				AddRemovePane.this.itemsMoved(e);
+			}
+
+			public void itemsRemoved(ListRemoveEvent e) {
+				AddRemovePane.this.itemsRemoved(e);
+			}
+
+			public void itemsReplaced(ListReplaceEvent e) {
+				AddRemovePane.this.itemsReplaced(e);
+			}
+
+			public void listChanged(ListChangeEvent e) {
+				AddRemovePane.this.listChanged(e);
+			}
+
+			public void listCleared(ListClearEvent e) {
+				AddRemovePane.this.listCleared(e);
+			}
+		};
+	}
+
+	protected void itemsAdded(ListAddEvent e) {
+		
+	}
+	
+	protected void itemsMoved(ListMoveEvent e) {
+		
+	}
+	
+	protected void itemsRemoved(ListRemoveEvent e) {
+		Object selectedItem = this.selectedItemHolder.getValue();
+
+		if (selectedItem == null) {
+			updateButtons();
+			return;
+		}
+
+		if (CollectionTools.contains(e.getItems(), selectedItem)) {
+			this.selectedItemHolder.setValue(null);
+			updateButtons();
+		}		
+	}
+	
+	protected void itemsReplaced(ListReplaceEvent e) {
+		
+	}
+	
+	protected void listChanged(ListChangeEvent e) {
+		
+	}
+	
+	protected void listCleared(ListClearEvent e) {
+		this.selectedItemHolder.setValue(null);
+		updateButtons();
+	}
+	
+	
+	/**
+	 * @category Option
+	 */
+	private Runnable buildOptionalAction() {
+		return new Runnable() {
+			public void run() {
+				AddRemovePane.this.editItem();
+			}
+		};
+	}
+
+	/**
+	 * @category Option
+	 */
+	protected Button addOptionalButton(Composite container) {
+		return addUnmanagedButton(
+			container,
+			adapter.optionalButtonText(),
+			buildOptionalAction()
+		);
+	}
+
+	/**
+	 * @category Add
+	 */
+	protected Button addRemoveButton(Composite parent) {
+		return addUnmanagedButton(
+			parent,
+			adapter.removeButtonText(),
+			buildRemoveItemsAction()
+		);
+	}
+
+	/**
+	 * @category Remove
+	 */
+	private Runnable buildRemoveItemsAction() {
+		return new Runnable() {
+			public void run() {
+				AddRemovePane.this.removeItems();
+			}
+		};
+	}
+
+	protected ObjectListSelectionModel buildRowSelectionModel(ListValueModel<?> listModel) {
+		return new ObjectListSelectionModel(new ListModelAdapter(listModel));
+	}
+
+	/**
+	 * @category Option
+	 */
+	protected void editItem() {
+		this.adapter.optionOnSelection(getSelectionModel());
+	}
+
+	/*
+	 * (non-Javadoc)
+	 */
+	@Override
+	public void enableWidgets(boolean enabled) {
+
+		super.enableWidgets(enabled);
+		this.enabled = enabled;
+
+		if (!this.getMainControl().isDisposed()) {
+			this.getMainControl().setEnabled(enabled);
+		}
+
+		this.updateButtons();
+	}
+
+	protected final Composite getContainer() {
+		return container;
+	}
+
+	protected IBaseLabelProvider getLabelProvider() {
+		return labelProvider;
+	}
+
+	protected final ListValueModel<?> getListHolder() {
+		return listHolder;
+	}
+
+	/**
+	 * Returns
+	 *
+	 * @return
+	 */
+	public abstract Composite getMainControl();
+
+	protected final WritablePropertyValueModel<Object> getSelectedItemHolder() {
+		return selectedItemHolder;
+	}
+
+	public final ObjectListSelectionModel getSelectionModel() {
+		return selectionModel;
+	}
+
+	/**
+	 * Initializes this add/remove pane.
+	 *
+	 * @param adapter This <code>Adapter</code> is used to dictacte the behavior
+	 * of this <code>AddRemovePane</code> and by delegating to it some of the
+	 * behavior
+	 * @param listHolder The <code>ListValueModel</code> containing the items
+	 * @param selectedItemHolder The holder of the selected item, if more than
+	 * one item or no items are selected, then <code>null</code> will be passed
+	 * @param labelProvider The renderer used to format the list holder's items
+	 *
+	 * @category Initialization
+	 */
+	@SuppressWarnings("unchecked")
+	protected void initialize(Adapter adapter,
+	                          ListValueModel<?> listHolder,
+	                          WritablePropertyValueModel<?> selectedItemHolder,
+	                          IBaseLabelProvider labelProvider)
+	{
+		this.listHolder         = listHolder;
+		this.labelProvider      = labelProvider;
+		this.adapter            = (adapter == null) ? buildAdapter() : adapter;
+		this.selectedItemHolder = (WritablePropertyValueModel<Object>) selectedItemHolder;
+		this.selectionModel     = new ObjectListSelectionModel(new ListModelAdapter(listHolder));
+
+		this.listHolder.addListChangeListener(
+			ListValueModel.LIST_VALUES,
+			buildListChangeListener()
+		);
+	}
+
+	/**
+	 * Initializes the pane containing the buttons (Add, optional (if required)
+	 * and Remove).
+	 *
+	 * @param container The parent container
+	 * @param helpId The topic help ID to be registered with the buttons
+	 *
+	 * @category Layout
+	 */
+	protected void initializeButtonPane(Composite container, String helpId) {
+
+		container = addSubPane(container);
+
+		GridData gridData = new GridData();
+		gridData.grabExcessVerticalSpace = true;
+		gridData.verticalAlignment       = SWT.TOP;
+		container.setLayoutData(gridData);
+
+		// Add button
+		this.addButton = addAddButton(container);
+		addAlignRight(this.addButton);
+
+		// Custom button
+		addCustomButtonAfterAddButton(container, helpId);
+
+		// Optional button
+		if (this.adapter.hasOptionalButton()) {
+			this.optionalButton = addOptionalButton(container);
+			addAlignRight(this.optionalButton);
+		}
+
+		// Custom button
+		addCustomButtonAfterOptionalButton(container, helpId);
+
+		// Remove button
+		removeButton = addRemoveButton(container);
+		addAlignRight(removeButton);
+
+		// Update the help topic ID
+		if (helpId != null) {
+			getHelpSystem().setHelp(addButton, helpId);
+			getHelpSystem().setHelp(removeButton, helpId);
+
+			if (optionalButton != null) {
+				getHelpSystem().setHelp(optionalButton, helpId);
+			}
+		}
+	}
+
+	/**
+	 * Initializes this add/remove pane by creating the widgets. The subclass is
+	 * required to build the main widget.
+	 *
+	 * @param adapter This <code>Adapter</code> is used to dictacte the behavior
+	 * of this <code>AddRemovePane</code> and by delegating to it some of the
+	 * behavior
+	 * @param listHolder The <code>ListValueModel</code> containing the items
+	 * @param selectedItemHolder The holder of the selected item, if more than
+	 * one item or no items are selected, then <code>null</code> will be passed
+	 * @param labelProvider The renderer used to format the list holder's items
+	 * @param helpId The topic help ID to be registered with this pane
+	 *
+	 * @category Layout
+	 */
+	protected void initializeLayout(Adapter adapter,
+    	                             ListValueModel<?> listHolder,
+   	                             WritablePropertyValueModel<?> selectedItemHolder,
+   	                             IBaseLabelProvider labelProvider,
+   	                             String helpId) {
+
+		initializeMainComposite(
+			container,
+			adapter,
+			listHolder,
+			selectedItemHolder,
+			labelProvider,
+			helpId);
+
+		initializeButtonPane(container, helpId);
+		enableWidgets(getSubject() != null);
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	protected void initializeLayout(Composite container) {
+		this.container = addSubPane(container, 2, 0, 0, 0, 0);
+	}
+
+	/**
+	 * Initializes the main widget of this add/remove pane.
+	 *
+	 * @param container The parent container
+	 * @param adapter This <code>Adapter</code> is used to dictacte the behavior
+	 * of this <code>AddRemovePane</code> and by delegating to it some of the
+	 * behavior
+	 * @param listHolder The <code>ListValueModel</code> containing the items
+	 * @param selectedItemHolder The holder of the selected item, if more than
+	 * one item or no items are selected, then <code>null</code> will be passed
+	 * @param labelProvider The renderer used to format the list holder's items
+	 * @param helpId The topic help ID to be registered with this pane or
+	 * <code>null</code> if it was not specified
+	 *
+	 * @category Layout
+	 */
+	protected abstract void initializeMainComposite(Composite container,
+	                                                Adapter adapter,
+	                   	                           ListValueModel<?> listHolder,
+	                  	                           WritablePropertyValueModel<?> selectedItemHolder,
+	                  	                           IBaseLabelProvider labelProvider,
+	                  	                           String helpId);
+
+	/**
+	 * @category Remove
+	 */
+	protected void removeItems() {
+
+		// Keep track of the selected indices so we can select an item
+		// before the lowest index
+		int[] indices = selectionModel.selectedIndices();
+		Arrays.sort(indices);
+
+		// Notify the adapter to remove the selected items
+		adapter.removeSelectedItems(selectionModel);
+
+		// Select a new item
+		if (getListHolder().size() > 0) {
+			int index = Math.min(indices[0], getListHolder().size() - 1);
+			Object item = getListHolder().get(index);
+			selectedItemHolder.setValue(item);
+		}
+		// The list is empty, clear the value
+		else {
+			selectedItemHolder.setValue(null);
+		}
+	}
+
+	/**
+	 * Selects the given value, which can be <code>null</code>.
+	 *
+	 * @param value The new selected value
+	 */
+	public void setSelectedItem(Object value) {
+		selectedItemHolder.setValue(value);
+	}
+
+	/**
+	 * @category UpdateButtons
+	 */
+	protected void updateAddButton(Button addButton) {
+		addButton.setEnabled(enabled);
+	}
+
+	/**
+	 * @category UpdateButtons
+	 */
+	protected void updateButtons() {
+		if (!container.isDisposed()) {
+			updateAddButton(addButton);
+			updateRemoveButton(removeButton);
+			updateOptionalButton(optionalButton);
+		}
+	}
+
+	/**
+	 * @category UpdateButtons
+	 */
+	protected void updateOptionalButton(Button optionalButton) {
+		if (optionalButton != null) {
+			optionalButton.setEnabled(
+				enabled &&
+				adapter.enableOptionOnSelectionChange(selectionModel)
+			);
+		}
+	}
+
+	/**
+	 * @category UpdateButtons
+	 */
+	protected void updateRemoveButton(Button removeButton) {
+		removeButton.setEnabled(
+			enabled &&
+			adapter.enableRemoveOnSelectionChange(selectionModel)
+		);
+	}
+
+	/**
+	 * An abstract implementation of <code>Adapter</code>.
+	 */
+	public static abstract class AbstractAdapter implements Adapter {
+
+		/**
+		 * The text of the add button.
+		 */
+		private String addButtonText;
+
+		/**
+		 * Determines whether the optional button should be shown or not.
+		 */
+		private boolean hasOptionalButton;
+
+		/**
+		 * The text of the optional button, if used.
+		 */
+		private String optionalButtonText;
+
+		/**
+		 * The text of the remove button.
+		 */
+		private String removeButtonText;
+
+		/**
+		 * Creates a new <code>AbstractAdapter</code> with default text for the
+		 * add and remove buttons.
+		 */
+		public AbstractAdapter() {
+			this(JptUiMessages.AddRemovePane_AddButtonText,
+			     JptUiMessages.AddRemovePane_RemoveButtonText);
+		}
+
+		/**
+		 * Creates a new <code>AbstractAdapter</code> with default text for the
+		 * add and remove buttons.
+		 *
+		 * @param hasOptionalButton <code>true</code> to show an optional button
+		 * and to use the behavior related to the optional button;
+		 * <code>false</code> to not use it
+		 */
+		public AbstractAdapter(boolean hasOptionalButton) {
+			this();
+			this.setHasOptionalButton(hasOptionalButton);
+		}
+
+		/**
+		 * Creates a new <code>AbstractAdapter</code> with default text for the
+		 * add and remove buttons.
+		 *
+		 * @param optionalButtonText The text of the optional button, which means
+		 * the optional button will be shown
+		 */
+		public AbstractAdapter(String optionalButtonText) {
+			this(true);
+			this.setOptionalButtonText(optionalButtonText);
+		}
+
+		/**
+		 * Creates a new <code>AbstractAdapter</code>.
+		 *
+		 * @param addButtonText The add button's text
+		 * @param removeButtonText The remove button's text
+		 */
+		public AbstractAdapter(String addButtonText,
+		                       String removeButtonText) {
+
+			super();
+			this.addButtonText    = addButtonText;
+			this.removeButtonText = removeButtonText;
+		}
+
+		/**
+		 * Creates a new <code>AbstractAdapter</code>.
+		 *
+		 * @param addButtonText The add button's text
+		 * @param removeButtonText The remove button's text
+		 * @param optionalButtonText The text of the optional button, which means
+		 * the optional button will be shown
+		 */
+		public AbstractAdapter(String addButtonText,
+		                       String removeButtonText,
+		                       String optionalButtonText) {
+
+			this(optionalButtonText);
+			this.setAddButtonText(addButtonText);
+			this.setRemoveButtonText(removeButtonText);
+		}
+
+		/*
+		 * (non-Javadoc)
+		 */
+		public String addButtonText() {
+			return addButtonText;
+		}
+
+		/*
+		 * (non-Javadoc)
+		 */
+		public boolean enableOptionOnSelectionChange(ObjectListSelectionModel listSelectionModel) {
+			return listSelectionModel.selectedValuesSize() == 1;
+		}
+
+		public boolean enableRemoveOnSelectionChange(ObjectListSelectionModel listSelectionModel) {
+			return listSelectionModel.selectedValue() != null;
+		}
+
+		/*
+		 * (non-Javadoc)
+		 */
+		public boolean hasOptionalButton() {
+			return hasOptionalButton;
+		}
+
+		/*
+		 * (non-Javadoc)
+		 */
+		public String optionalButtonText() {
+			return optionalButtonText;
+		}
+
+		/*
+		 * (non-Javadoc)
+		 */
+		public void optionOnSelection(ObjectListSelectionModel listSelectionModel) {
+		}
+
+		/*
+		 * (non-Javadoc)
+		 */
+		public String removeButtonText() {
+			return removeButtonText;
+		}
+
+		/**
+		 * Changes the text of the add button. This method has to be called before
+		 * the <code>AddRemoveListPane</code> is initialized.
+		 *
+		 * @param addButtonText The add button's text
+		 */
+		public void setAddButtonText(String addButtonText) {
+			this.addButtonText = addButtonText;
+		}
+
+		/**
+		 * Changes the state of the optional button, meaning if it should be shown
+		 * between the add and remove buttons or not.
+		 *
+		 * @param hasOptionalButton <code>true</code> to show an optional button
+		 * and to use the behavior related to the optional button;
+		 * <code>false</code> to not use it
+		 */
+		public void setHasOptionalButton(boolean hasOptionalButton) {
+			this.hasOptionalButton = hasOptionalButton;
+		}
+
+		/**
+		 * Changes the text of the optional button. This method has to be called
+		 * before the <code>AddRemoveListPane</code> is initialized. This does not
+		 * make the optional button visible.
+		 *
+		 * @param optionalButtonText The optional button's text
+		 */
+		public void setOptionalButtonText(String optionalButtonText) {
+			this.optionalButtonText = optionalButtonText;
+		}
+
+		/**
+		 * Changes the text of the remove button. This method has to be called
+		 * before the <code>AddRemoveListPane</code> is initialized.
+		 *
+		 * @param removeButtonText The remove button's text
+		 */
+		public void setRemoveButtonText(String removeButtonText) {
+			this.removeButtonText = removeButtonText;
+		}
+	}
+
+	/**
+	 * This adapter is used to perform the actual action when adding a new item
+	 * or removing the selected items. It is possible to add an optional button.
+	 */
+	public static interface Adapter {
+
+		/**
+		 * The add button's text.
+		 *
+		 * @return The text shown on the add button
+		 */
+		String addButtonText();
+
+		/**
+		 * Invoked when the user selects the Add button.
+		 */
+		void addNewItem(ObjectListSelectionModel listSelectionModel);
+
+		/**
+		 * Invoked when selection changes. Implementation dictates whether button
+		 * should be enabled.
+		 */
+		boolean enableOptionOnSelectionChange(ObjectListSelectionModel listSelectionModel);
+
+		/**
+		 * Invoked when selection changes. Implementation dictates whether remove button
+		 * should be enabled.
+		 */
+		boolean enableRemoveOnSelectionChange(ObjectListSelectionModel listSelectionModel);
+
+		/**
+		 * Determines whether an optional button should be added between the add
+		 * and remove buttons.
+		 *
+		 * @return <code>true</code> to show an optional button and to use the
+		 * behavior related to the optional button; <code>false</code> to not use
+		 * it
+		 */
+		boolean hasOptionalButton();
+
+		/**
+		 * Resource string key for the optional button.
+		 */
+		String optionalButtonText();
+
+		/**
+		 * Invoked when the user selects the optional button
+		 */
+		void optionOnSelection(ObjectListSelectionModel listSelectionModel);
+
+		/**
+		 * The remove button's text.
+		 *
+		 * @return The text shown on the remove button
+		 */
+		String removeButtonText();
+
+		/**
+		 * Invoked when the user selects the Remove button.
+		 */
+		void removeSelectedItems(ObjectListSelectionModel listSelectionModel);
+	}
+}
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/widgets/AddRemoveTablePane.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/widgets/AddRemoveTablePane.java
new file mode 100644
index 0000000..a5503c9
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/widgets/AddRemoveTablePane.java
@@ -0,0 +1,314 @@
+/*******************************************************************************
+ * Copyright (c) 2008 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.ui.internal.widgets;
+
+import org.eclipse.jface.viewers.IBaseLabelProvider;
+import org.eclipse.jface.viewers.ITableLabelProvider;
+import org.eclipse.jpt.ui.internal.listeners.SWTPropertyChangeListenerWrapper;
+import org.eclipse.jpt.ui.internal.swt.ColumnAdapter;
+import org.eclipse.jpt.ui.internal.swt.TableModelAdapter;
+import org.eclipse.jpt.ui.internal.swt.TableModelAdapter.SelectionChangeEvent;
+import org.eclipse.jpt.ui.internal.swt.TableModelAdapter.SelectionChangeListener;
+import org.eclipse.jpt.utility.internal.CollectionTools;
+import org.eclipse.jpt.utility.internal.model.value.SimplePropertyValueModel;
+import org.eclipse.jpt.utility.internal.model.value.swing.ObjectListSelectionModel;
+import org.eclipse.jpt.utility.model.Model;
+import org.eclipse.jpt.utility.model.event.PropertyChangeEvent;
+import org.eclipse.jpt.utility.model.listener.PropertyChangeListener;
+import org.eclipse.jpt.utility.model.value.ListValueModel;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.jpt.utility.model.value.WritablePropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Table;
+
+/**
+ * This implementation of the <code>AddRemovePane</code> uses a <code>Table</code>
+ * as its main widget.
+ * <p>
+ * Here the layot of this pane:
+ * <pre>
+ * -----------------------------------------------------------------------------
+ * | ------------------------------------------------------------- ----------- |
+ * | | Column 1 | Column 2 | ...   | Column i | ...   | Colunm n | | Add...  | |
+ * | |-----------------------------------------------------------| ----------- |
+ * | |          |          |       |          |       |          | ----------- |
+ * | |-----------------------------------------------------------| | Edit... | |
+ * | |          |          |       |          |       |          | ----------- |
+ * | |-----------------------------------------------------------| ----------- |
+ * | |          |          |       |          |       |          | | Remove  | |
+ * | |-----------------------------------------------------------| ----------- |
+ * | -------------------------------------------------------------             |
+ * -----------------------------------------------------------------------------</pre>
+ *
+ * @version 2.0
+ * @since 1.0
+ */
+public abstract class AddRemoveTablePane<T extends Model> extends AddRemovePane<T>
+{
+	/**
+	 * Flag used to prevent circular
+	 */
+	private boolean locked;
+
+	/**
+	 * The main widget of this add/remove pane.
+	 */
+	private Table table;
+
+	/**
+	 * Creates a new <code>AddRemoveTablePane</code>.
+	 *
+	 * @param parentPane The parent container of this one
+	 * @param parent The parent container
+	 * @param adapter
+	 * @param listHolder The <code>ListValueModel</code> containing the items
+	 * @param selectedItemHolder The holder of the selected item, if more than
+	 * one item or no items are selected, then <code>null</code> will be passed
+	 * @param labelProvider The renderer used to format the list holder's items
+	 */
+	public AddRemoveTablePane(Pane<? extends T> parentPane,
+	                          Composite parent,
+	                          Adapter adapter,
+	                          ListValueModel<?> listHolder,
+	                          WritablePropertyValueModel<?> selectedItemHolder,
+	                          ITableLabelProvider labelProvider) {
+
+		super(parentPane,
+		      parent,
+		      adapter,
+		      listHolder,
+		      selectedItemHolder,
+		      labelProvider);
+
+	}
+
+	/**
+	 * Creates a new <code>AddRemoveTablePane</code>.
+	 *
+	 * @param parentPane The parent container of this one
+	 * @param parent The parent container
+	 * @param adapter
+	 * @param listHolder The <code>ListValueModel</code> containing the items
+	 * @param selectedItemHolder The holder of the selected item, if more than
+	 * one item or no items are selected, then <code>null</code> will be passed
+	 * @param labelProvider The renderer used to format the list holder's items
+	 * @param helpId The topic help ID to be registered with this pane
+	 */
+	public AddRemoveTablePane(Pane<? extends T> parentPane,
+	                          Composite parent,
+	                          Adapter adapter,
+	                          ListValueModel<?> listHolder,
+	                          WritablePropertyValueModel<?> selectedItemHolder,
+	                          ITableLabelProvider labelProvider,
+	                          String helpId) {
+
+		super(parentPane,
+		      parent,
+		      adapter,
+		      listHolder,
+		      selectedItemHolder,
+		      labelProvider,
+		      helpId);
+	}
+
+	/**
+	 * Creates a new <code>AddRemoveTablePane</code>.
+	 *
+	 * @param parentPane The parent container of this one
+	 * @param subjectHolder The holder of the subject
+	 * @param adapter
+	 * @param parent The parent container
+	 * @param listHolder The <code>ListValueModel</code> containing the items
+	 * @param selectedItemHolder The holder of the selected item, if more than
+	 * one item or no items are selected, then <code>null</code> will be passed
+	 * @param labelProvider The renderer used to format the list holder's items
+	 */
+	public AddRemoveTablePane(Pane<?> parentPane,
+	                          PropertyValueModel<? extends T> subjectHolder,
+	                          Composite parent,
+	                          Adapter adapter,
+	                          ListValueModel<?> listHolder,
+	                          WritablePropertyValueModel<?> selectedItemHolder,
+	                          ITableLabelProvider labelProvider) {
+
+		super(parentPane,
+		      subjectHolder,
+		      parent,
+		      adapter,
+		      listHolder,
+		      selectedItemHolder,
+		      labelProvider);
+	}
+
+	/**
+	 * Creates a new <code>AddRemoveTablePane</code>.
+	 *
+	 * @param parentPane The parent container of this one
+	 * @param subjectHolder The holder of the subject
+	 * @param adapter
+	 * @param parent The parent container
+	 * @param listHolder The <code>ListValueModel</code> containing the items
+	 * @param selectedItemHolder The holder of the selected item, if more than
+	 * one item or no items are selected, then <code>null</code> will be passed
+	 * @param labelProvider The renderer used to format the list holder's items
+	 * @param helpId The topic help ID to be registered with this pane
+	 */
+	public AddRemoveTablePane(Pane<?> parentPane,
+	                          PropertyValueModel<? extends T> subjectHolder,
+	                          Composite parent,
+	                          Adapter adapter,
+	                          ListValueModel<?> listHolder,
+	                          WritablePropertyValueModel<?> selectedItemHolder,
+	                          ITableLabelProvider labelProvider,
+	                          String helpId) {
+
+		super(parentPane,
+		      subjectHolder,
+		      parent,
+		      adapter,
+		      listHolder,
+		      selectedItemHolder,
+		      labelProvider,
+		      helpId);
+	}
+
+	protected abstract ColumnAdapter<?> buildColumnAdapter();
+
+	private WritablePropertyValueModel<Object> buildSelectedItemHolder() {
+		return new SimplePropertyValueModel<Object>();
+	}
+
+	private PropertyChangeListener buildSelectedItemPropertyChangeListener() {
+		return new SWTPropertyChangeListenerWrapper(
+			buildSelectedItemPropertyChangeListener_()
+		);
+	}
+
+	private PropertyChangeListener buildSelectedItemPropertyChangeListener_() {
+		return new PropertyChangeListener() {
+			public void propertyChanged(PropertyChangeEvent e) {
+				if (table.isDisposed()) {
+					return;
+				}
+
+				if (!locked) {
+					locked = true;
+
+					try {
+						Object value = e.getNewValue();
+						getSelectionModel().setSelectedValue(e.getNewValue());
+						int index = -1;
+
+						if (value != null) {
+							index = CollectionTools.indexOf(getListHolder().iterator(), value);
+						}
+
+						table.select(index);
+						updateButtons();
+					}
+					finally {
+						locked = false;
+					}
+				}
+			}
+		};
+	}
+
+	private SelectionChangeListener<Object> buildSelectionListener() {
+		return new SelectionChangeListener<Object>() {
+			public void selectionChanged(SelectionChangeEvent<Object> e) {
+				AddRemoveTablePane.this.selectionChanged();
+			}
+		};
+	}
+
+	/*
+	 * (non-Javadoc)
+	 */
+	@Override
+	public Table getMainControl() {
+		return table;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 */
+	@Override
+	@SuppressWarnings("unchecked")
+	protected void initializeMainComposite(Composite container,
+	                                       Adapter adapter,
+	                                       ListValueModel<?> listHolder,
+	                                       WritablePropertyValueModel<?> selectedItemHolder,
+	                                       IBaseLabelProvider labelProvider,
+	                                       String helpId)
+	{
+		table = addUnmanagedTable(container, helpId);
+		table.setHeaderVisible(true);
+
+		TableModelAdapter<Object> tableModel = TableModelAdapter.adapt(
+			(ListValueModel<Object>) listHolder,
+			buildSelectedItemHolder(),
+			table,
+			(ColumnAdapter<Object>) buildColumnAdapter(),
+			(ITableLabelProvider) labelProvider
+		);
+
+		tableModel.addSelectionChangeListener(buildSelectionListener());
+
+		selectedItemHolder.addPropertyChangeListener(
+			PropertyValueModel.VALUE,
+			buildSelectedItemPropertyChangeListener()
+		);
+	}
+
+	/**
+	 * The selection has changed, update (1) the selected item holder, (2) the
+	 * selection model and (3) the buttons.
+	 */
+	private void selectionChanged() {
+
+		if (locked) {
+			return;
+		}
+
+		locked = true;
+
+		try {
+			WritablePropertyValueModel<Object> selectedItemHolder = getSelectedItemHolder();
+			ObjectListSelectionModel selectionModel = getSelectionModel();
+			int selectionCount = table.getSelectionCount();
+
+			if (selectionCount == 0) {
+				selectedItemHolder.setValue(null);
+				selectionModel.clearSelection();
+			}
+			else if (selectionCount != 1) {
+				selectedItemHolder.setValue(null);
+				selectionModel.clearSelection();
+
+				for (int index : table.getSelectionIndices()) {
+					selectionModel.addSelectionInterval(index, index);
+				}
+			}
+			else {
+				int selectedIndex = table.getSelectionIndex();
+				Object selectedItem = getListHolder().get(selectedIndex);
+
+				selectedItemHolder.setValue(selectedItem);
+				selectionModel.setSelectedValue(selectedItem);
+			}
+
+			updateButtons();
+		}
+		finally {
+			locked = false;
+		}
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/widgets/ChooserPane.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/widgets/ChooserPane.java
new file mode 100644
index 0000000..d224c43
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/widgets/ChooserPane.java
@@ -0,0 +1,167 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2009 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.ui.internal.widgets;
+
+import org.eclipse.jpt.ui.internal.JptUiMessages;
+import org.eclipse.jpt.utility.model.Model;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+
+/**
+ * A chooser is simply a pane with three widgets, the label on the left, a main
+ * widget, usually a text field, and a right widget which is usually a browse
+ * button.
+ *
+ * @see ClassChooserPane
+ * @see PackageChooserPane
+ *
+ * @version 3.0
+ * @since 2.0
+ */
+public abstract class ChooserPane<T extends Model> extends Pane<T>
+{
+	/**
+	 * The control shown after the label (left control).
+	 */
+	private Control mainControl;
+
+	/**
+	 * The control shown after the main control.
+	 */
+	private Control rightControl;
+
+	/**
+	 * Creates a new <code>ChooserPane</code>.
+	 *
+	 * @param parentPane The parent pane of this one
+	 * @param parent The parent container
+	 */
+	public ChooserPane(Pane<? extends T> parentPane,
+	                           Composite parent) {
+
+		super(parentPane, parent);
+	}
+
+	/**
+	 * Creates a new <code>ChooserPane</code>.
+	 *
+	 * @param parentPane The parent container of this one
+	 * @param subjectHolder The holder of this pane's subject
+	 * @param parent The parent container
+	 */
+	public ChooserPane(Pane<?> parentPane,
+	                           PropertyValueModel<? extends T> subjectHolder,
+	                           Composite parent) {
+
+		super(parentPane, subjectHolder, parent);
+	}
+
+	@Override
+	protected void initializeLayout(Composite container) {
+
+		this.mainControl  = addMainControl(container);
+		this.rightControl = addRightControl(container);
+
+		addLabeledComposite(
+			container,
+			addLeftControl(container),
+			this.mainControl,
+			this.rightControl,
+			getHelpId()
+		);
+	}
+
+	/**
+	 * Creates the left control. By default a label is created and its text is
+	 * retrieved by {@link #getLabelText()}.
+	 *
+	 * @param container The parent container
+	 * @return The newly created left control
+	 */
+	protected Control addLeftControl(Composite container) {
+		return addLabel(container, getLabelText());
+	}
+
+	/**
+	 * The text of the label. This method is called by
+	 * {@link #buildLeftControl(Composite)}.
+	 *
+	 * @return The localized text of the left control (which is a label by
+	 * default)
+	 */
+	protected abstract String getLabelText();
+
+	/**
+	 * Creates the main control of this pane.
+	 *
+	 * @param container The parent container
+	 * @return The newly created main control
+	 */
+	protected abstract Control addMainControl(Composite container);
+
+	/**
+	 * Creates the right control. By default a browse button is created and its
+	 * action is performed by {@link #buildBrowseAction()} and its text is
+	 * retrieved by {@link #getBrowseButtonText()}.
+	 *
+	 * @param container The parent container
+	 * @return The newly created right control
+	 */
+	protected Control addRightControl(Composite container) {
+		return addButton(
+			container,
+			getBrowseButtonText(),
+			buildBrowseAction()
+		);
+	}
+
+	/**
+	 * Returns the text of the browse button. This method is called by
+	 * {@link #buildRightControl(Composite)}.
+	 *
+	 * @return "Browse..."
+	 */
+	protected String getBrowseButtonText() {
+		return JptUiMessages.ChooserPane_browseButton;
+	}
+
+	/**
+	 * Creates the action responsible to perform the action when the Browse is
+	 * clicked.
+	 *
+	 * @return A new <code>Runnable</code> performing the actual action of the
+	 * button
+	 */
+	protected abstract Runnable buildBrowseAction();
+
+	/**
+	 * Returns the help topic ID for the controls of this pane.
+	 *
+	 * @return <code>null</code> is returned otherwise the subclass can return an ID
+	 */
+	protected String getHelpId() {
+		return null;
+	}
+
+	@Override
+	public void enableWidgets(boolean enabled) {
+
+		super.enableWidgets(enabled);
+
+		if (!this.mainControl.isDisposed()) {
+			this.mainControl.setEnabled(enabled);
+		}
+
+		if (!this.rightControl.isDisposed()) {
+			this.rightControl.setEnabled(enabled);
+		}
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/widgets/ClassChooserComboPane.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/widgets/ClassChooserComboPane.java
new file mode 100644
index 0000000..065b977
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/widgets/ClassChooserComboPane.java
@@ -0,0 +1,92 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2010 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.ui.internal.widgets;
+
+import org.eclipse.jdt.internal.ui.refactoring.contentassist.ControlContentAssistHelper;
+import org.eclipse.jpt.utility.internal.StringConverter;
+import org.eclipse.jpt.utility.model.Model;
+import org.eclipse.jpt.utility.model.value.ListValueModel;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+
+/**
+ * This chooser allows the user to choose a type when browsing and it adds code
+ * completion support to the text field, which is the main component.
+ * <p>
+ * Here the layout of this pane:
+ * <pre>
+ * -----------------------------------------------------------------------------
+ * |        ---------------------------------------------------- ------------- |
+ * | Label: | I                                             X  | | Browse... | |
+ * |        ---------------------------------------------------- ------------- |
+ * -----------------------------------------------------------------------------</pre>
+ *
+ * @version 2.0
+ * @since 2.0
+ */
+public abstract class ClassChooserComboPane<T extends Model> extends ClassChooserPane<T>
+{
+
+	/**
+	 * Creates a new <code>ClassChooserPane</code>.
+	 *
+	 * @param parentPane The parent pane of this one
+	 * @param parent The parent container
+	 */
+	public ClassChooserComboPane(Pane<? extends T> parentPane,
+	                        Composite parent) {
+
+		super(parentPane, parent);
+	}
+
+	/**
+	 * Creates a new <code>ClassChooserPane</code>.
+	 *
+	 * @param parentPane The parent container of this one
+	 * @param subjectHolder The holder of this pane's subject
+	 * @param parent The parent container
+	 */
+	public ClassChooserComboPane(Pane<?> parentPane,
+	                        PropertyValueModel<? extends T> subjectHolder,
+	                        Composite parent) {
+
+		super(parentPane, subjectHolder, parent);
+	}
+
+	@Override
+	protected Control addMainControl(Composite container) {
+		Composite subPane = addSubPane(container);
+    	Combo combo = this.addClassCombo(subPane);
+
+		ControlContentAssistHelper.createComboContentAssistant(
+			combo,
+			javaTypeCompletionProcessor
+		);
+
+		return subPane;
+	}
+	
+	protected Combo addClassCombo(Composite container) {
+		return this.addEditableCombo(
+			container,
+			this.buildClassListHolder(),
+			this.buildTextHolder(),
+			this.buildClassConverter()
+		);
+ 	}
+	
+	protected abstract ListValueModel<String> buildClassListHolder();
+	
+	protected StringConverter<String> buildClassConverter() {
+		return StringConverter.Default.instance();
+	}
+}
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/widgets/ClassChooserPane.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/widgets/ClassChooserPane.java
new file mode 100644
index 0000000..31ba898
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/widgets/ClassChooserPane.java
@@ -0,0 +1,368 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2010 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.ui.internal.widgets;
+
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.IPackageFragment;
+import org.eclipse.jdt.core.IPackageFragmentRoot;
+import org.eclipse.jdt.core.IType;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.core.search.IJavaSearchScope;
+import org.eclipse.jdt.core.search.SearchEngine;
+import org.eclipse.jdt.internal.ui.refactoring.contentassist.ControlContentAssistHelper;
+import org.eclipse.jdt.internal.ui.refactoring.contentassist.JavaTypeCompletionProcessor;
+import org.eclipse.jdt.internal.ui.wizards.NewClassCreationWizard;
+import org.eclipse.jdt.ui.IJavaElementSearchConstants;
+import org.eclipse.jdt.ui.JavaUI;
+import org.eclipse.jdt.ui.wizards.NewClassWizardPage;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.jface.window.Window;
+import org.eclipse.jface.wizard.WizardDialog;
+import org.eclipse.jpt.core.JpaProject;
+import org.eclipse.jpt.core.internal.utility.jdt.JDTTools;
+import org.eclipse.jpt.ui.JptUiPlugin;
+import org.eclipse.jpt.ui.internal.JptUiMessages;
+import org.eclipse.jpt.ui.internal.listeners.SWTPropertyChangeListenerWrapper;
+import org.eclipse.jpt.utility.internal.ClassName;
+import org.eclipse.jpt.utility.internal.StringTools;
+import org.eclipse.jpt.utility.model.Model;
+import org.eclipse.jpt.utility.model.event.PropertyChangeEvent;
+import org.eclipse.jpt.utility.model.listener.PropertyChangeListener;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.jpt.utility.model.value.WritablePropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.dialogs.SelectionDialog;
+import org.eclipse.ui.forms.widgets.Hyperlink;
+
+/**
+ * This chooser allows the user to choose a type when browsing and it adds code
+ * completion support to the text field, which is the main component.
+ * <p>
+ * Here the layout of this pane:
+ * <pre>
+ * -----------------------------------------------------------------------------
+ * |        ---------------------------------------------------- ------------- |
+ * | Label: | I                                                | | Browse... | |
+ * |        ---------------------------------------------------- ------------- |
+ * -----------------------------------------------------------------------------</pre>
+ *
+ * @version 2.3
+ * @since 2.0
+ */
+@SuppressWarnings("nls")
+public abstract class ClassChooserPane<T extends Model> extends ChooserPane<T>
+{
+	/**
+	 * The code completion manager.
+	 */
+	protected JavaTypeCompletionProcessor javaTypeCompletionProcessor;
+
+	private PropertyChangeListener subjectChangeListener;
+
+	/**
+	 * Creates a new <code>ClassChooserPane</code>.
+	 *
+	 * @param parentPane The parent pane of this one
+	 * @param parent The parent container
+	 */
+	public ClassChooserPane(Pane<? extends T> parentPane,
+	                        Composite parent) {
+
+		super(parentPane, parent);
+	}
+
+	/**
+	 * Creates a new <code>ClassChooserPane</code>.
+	 *
+	 * @param parentPane The parent container of this one
+	 * @param subjectHolder The holder of this pane's subject
+	 * @param parent The parent container
+	 */
+	public ClassChooserPane(Pane<?> parentPane,
+	                        PropertyValueModel<? extends T> subjectHolder,
+	                        Composite parent) {
+
+		super(parentPane, subjectHolder, parent);
+	}
+
+	@Override
+	protected void initialize() {
+		super.initialize();
+
+		// TODO bug 156185 - when this is fixed there should be api for this
+		this.javaTypeCompletionProcessor = new JavaTypeCompletionProcessor(false, false);
+
+		this.subjectChangeListener = this.buildSubjectChangeListener();
+		this.getSubjectHolder().addPropertyChangeListener(PropertyValueModel.VALUE, this.subjectChangeListener);
+
+		this.classChooserSubjectChanged(getSubject());
+	}
+
+	private PropertyChangeListener buildSubjectChangeListener() {
+		return new SWTPropertyChangeListenerWrapper(this.buildSubjectChangeListener_());
+	}
+
+	private PropertyChangeListener buildSubjectChangeListener_() {
+		return new PropertyChangeListener() {
+			@SuppressWarnings("unchecked")
+			public void propertyChanged(PropertyChangeEvent e) {
+				ClassChooserPane.this.classChooserSubjectChanged((T) e.getNewValue());
+			}
+		};
+	}
+
+	protected void classChooserSubjectChanged(T newSubject) {
+		IPackageFragment packageFragment = null;
+		if (newSubject != null) {
+			IPackageFragmentRoot root = getPackageFragmentRoot();
+			if (root != null) {
+				packageFragment = root.getPackageFragment("");
+			}
+		}
+		this.javaTypeCompletionProcessor.setPackageFragment(packageFragment);
+	}
+
+	@Override
+	protected Control addLeftControl(Composite container) {
+		if( ! this.allowTypeCreation()) {
+			return super.addLeftControl(container);
+		}
+		Hyperlink labelLink = this.addHyperlink(container,
+			this.getLabelText(),
+			this.buildHyperLinkAction()
+		);
+		return labelLink;
+	}
+
+	private Runnable buildHyperLinkAction() {
+		return new Runnable() {
+			public void run() {
+				ClassChooserPane.this.hyperLinkSelected();
+			}
+		};
+	}
+
+	protected void hyperLinkSelected() {
+		IType type = getType();
+		if (type != null) {
+			openInEditor(type);	
+		}
+		else if (allowTypeCreation()){
+			createType();
+		}
+	}
+	
+	protected IType getType() {
+		if (getClassName() == null) {
+			return null;
+		}
+		IType type = null;
+		try {
+			type = getJpaProject().getJavaProject().findType(getClassName().replace('$', '.'));
+		}
+		catch (JavaModelException e) {
+			JptUiPlugin.log(e);
+		}
+		return type;
+	}
+	
+	protected void createType() {
+		StructuredSelection selection = new StructuredSelection(getJpaProject().getProject());
+
+		NewClassWizardPage newClassWizardPage = new NewClassWizardPage();
+		newClassWizardPage.init(selection);
+		newClassWizardPage.setSuperClass(getSuperclassName(), true);
+		newClassWizardPage.setSuperInterfaces(getSuperInterfaceNames(), true);
+		if (!StringTools.stringIsEmpty(getClassName())) {
+			newClassWizardPage.setTypeName(ClassName.getSimpleName(getClassName()), true);
+			String packageName = ClassName.getPackageName(getClassName());
+			newClassWizardPage.setPackageFragment(getFirstJavaSourceFolder().getPackageFragment(packageName), true);
+		}
+		NewClassCreationWizard wizard = new NewClassCreationWizard(newClassWizardPage, false);
+		wizard.init(PlatformUI.getWorkbench(), selection);
+
+		WizardDialog dialog = new WizardDialog(getShell(), wizard);
+		dialog.create();
+		int dResult = dialog.open();
+		if (dResult == Window.OK) {
+			String className = (newClassWizardPage.getCreatedType()).getFullyQualifiedName(getEnclosingTypeSeparator());
+			setClassName(className);
+		}
+	}
+	
+	protected abstract void setClassName(String className);
+	
+	/**
+	 * Override this to change the enclosing type separator
+	 */
+	protected char getEnclosingTypeSeparator() {
+		return '$';
+	}
+	
+	/**
+	 * Override this to set a superclass in the New Class wizard.  If no class is chosen, 
+	 * clicking the hyperlink label will open the new class wizard.
+	 */
+	protected String getSuperclassName() {
+		return "";
+	}
+	
+	/**
+	 * Override this to set a super interface in the New Class wizard.  If no class is chosen, 
+	 * clicking the hyperlink label will open the new class wizard.
+	 * @see getSuperInterfaceName
+	 */
+	protected List<String> getSuperInterfaceNames() {
+		return getSuperInterfaceName() != null ? Collections.singletonList(getSuperInterfaceName()) : Collections.<String>emptyList();
+	}
+	
+	/**
+	 * Override this to set a super interface in the New Class wizard.  If no class is chosen, 
+	 * clicking the hyperlink label will open the new class wizard.
+	 */
+	protected String getSuperInterfaceName() {
+		return null;
+	}
+	
+	/**
+	 * Override this if it does not make sense to allow the user to create a new type.
+	 * This will determine whether clicking the hyperlink opens the New Class wizard
+	 * @return
+	 */
+	protected boolean allowTypeCreation() {
+		return true;
+	}
+	
+	protected void openInEditor(IType type) {
+		IJavaElement javaElement = type.getParent();
+		try {
+			JavaUI.openInEditor(javaElement, true, true);
+		}
+		catch (JavaModelException e) {
+			JptUiPlugin.log(e);
+		}
+		catch (PartInitException e) {
+			JptUiPlugin.log(e);
+		}
+	}
+
+	protected abstract JpaProject getJpaProject();
+	
+	@Override
+	protected final Runnable buildBrowseAction() {
+		return new Runnable() {
+			public void run() {
+				promptType();
+			}
+		};
+	}
+
+	@Override
+	protected Control addMainControl(Composite container) {
+		Composite subPane = addSubPane(container);
+		Text text = addText(subPane, buildTextHolder());
+
+		ControlContentAssistHelper.createTextContentAssistant(
+			text,
+			javaTypeCompletionProcessor
+		);
+
+		return subPane;
+	}
+
+	/**
+	 * Creates the value holder of the subject's property.
+	 *
+	 * @return The holder of the class name
+	 */
+	protected abstract WritablePropertyValueModel<String> buildTextHolder();
+
+	/**
+	 * Prompts the user the Open Type dialog.
+	 *
+	 * @return Either the selected type or <code>null</code> if the user
+	 * cancelled the dialog
+	 */
+	protected IType chooseType() {
+		IJavaElement[] elements = new IJavaElement[] { getJpaProject().getJavaProject() };
+		IJavaSearchScope scope = SearchEngine.createJavaSearchScope(elements);
+		SelectionDialog typeSelectionDialog;
+
+		try {
+			typeSelectionDialog = JavaUI.createTypeDialog(
+				getShell(),
+				PlatformUI.getWorkbench().getProgressService(),
+				scope,
+				getTypeDialogStyle(),
+				false,
+				StringTools.stringIsEmpty(getClassName()) ? "" : ClassName.getSimpleName(getClassName())
+			);
+		}
+		catch (JavaModelException e) {
+			JptUiPlugin.log(e);
+			return null;
+		}
+
+		typeSelectionDialog.setTitle(JptUiMessages.ClassChooserPane_dialogTitle);
+		typeSelectionDialog.setMessage(JptUiMessages.ClassChooserPane_dialogMessage);
+
+		if (typeSelectionDialog.open() == Window.OK) {
+			return (IType) typeSelectionDialog.getResult()[0];
+		}
+
+		return null;
+	}
+
+	protected int getTypeDialogStyle() {
+		return IJavaElementSearchConstants.CONSIDER_CLASSES;
+	}
+	
+	/**
+	 * Returns the class name from its subject.
+	 *
+	 * @return The class name or <code>null</code> if none is defined
+	 */
+	protected abstract String getClassName();
+
+	protected IPackageFragmentRoot getFirstJavaSourceFolder() {
+		Iterator<IPackageFragmentRoot> i = JDTTools.getJavaSourceFolders(getJpaProject().getJavaProject()).iterator();
+		return i.hasNext() ? i.next() : null;
+	}
+
+	/**
+	 * The browse button was clicked, its action invokes this action which should
+	 * prompt the user to select a class and set it.
+	 */
+	protected void promptType() {
+		IType type = this.chooseType();
+
+		if (type != null) {
+			String className = type.getFullyQualifiedName(getEnclosingTypeSeparator());
+			setClassName(className);
+		}
+	}
+
+	protected IPackageFragmentRoot getPackageFragmentRoot() {
+		return JDTTools.getCodeCompletionContextRoot(getJpaProject().getJavaProject());
+	}
+
+	@Override
+	public void dispose() {
+		this.getSubjectHolder().removePropertyChangeListener(PropertyValueModel.VALUE, this.subjectChangeListener);
+		super.dispose();
+	}
+}
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/widgets/ComboPane.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/widgets/ComboPane.java
new file mode 100644
index 0000000..3824595
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/widgets/ComboPane.java
@@ -0,0 +1,288 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2010 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.ui.internal.widgets;
+
+import org.eclipse.jpt.ui.internal.details.JptUiDetailsMessages;
+import org.eclipse.jpt.ui.internal.util.SWTUtil;
+import org.eclipse.jpt.utility.internal.StringTools;
+import org.eclipse.jpt.utility.internal.Tools;
+import org.eclipse.jpt.utility.model.Model;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * Pane with combo box support for automatic updating of:
+ *  - selected value
+ *  - default value
+ *  - value choices
+ */
+public abstract class ComboPane<T extends Model> extends Pane<T>
+{
+	/**
+	 * The main (only) widget of this pane.
+	 */
+	protected Combo comboBox;
+	
+	
+	// **************** constructors ******************************************
+	
+	protected ComboPane(
+			Pane<? extends T> parentPane, 
+			Composite parent) {
+		
+		super(parentPane, parent);
+	}
+	
+	protected ComboPane(
+			Pane<?> parentPane,
+			PropertyValueModel<? extends T> subjectHolder,
+			Composite parent) {
+	
+		super(parentPane, subjectHolder, parent);
+	}
+	
+	protected ComboPane(
+			Pane<?> parentPane,
+			PropertyValueModel<? extends T> subjectHolder,
+			Composite parent,
+			PropertyValueModel<Boolean> enabledModel) {
+	
+		super(parentPane, subjectHolder, parent, enabledModel);
+	}
+	
+	
+	// **************** initialization ****************************************
+	
+	@Override
+	protected void initializeLayout(Composite container) {
+		this.comboBox = this.addEditableCombo(container);
+		this.comboBox.addModifyListener(this.buildModifyListener());
+		SWTUtil.attachDefaultValueHandler(this.comboBox);
+	}
+	
+	protected ModifyListener buildModifyListener() {
+		return new ModifyListener() {
+			public void modifyText(ModifyEvent e) {
+				ComboPane.this.comboBoxModified();
+			}
+		};
+	}
+	
+	
+	// **************** typical overrides *************************************
+	
+	/**
+	 * Return the possible values to be added to the combo during
+	 * population.
+	 */
+	protected abstract Iterable<String> getValues();
+	
+	/**
+	 * Return whether the combo is to add a default value to the choices
+	 */
+	protected boolean usesDefaultValue() {
+		// default response is 'true'
+		return true;
+	}
+	
+	/**
+	 * Return the default value, or <code>null</code> if no default is
+	 * specified. This method is only called when the subject is non-null.
+	 */
+	protected abstract String getDefaultValue();
+	
+	/**
+	 * Return the current value from the subject.
+	 * This method is only called when the subject is non-null.
+	 */
+	protected abstract String getValue();
+	
+	/**
+	 * Set the specified value as the new value on the subject.
+	 */
+	protected abstract void setValue(String value);
+	
+	
+	// **************** overrides *********************************************
+	
+	@Override
+	protected void propertyChanged(String propertyName) {
+		super.propertyChanged(propertyName);
+		this.updateSelectedItem();
+	}
+	
+	@Override
+	protected void doPopulate() {
+		super.doPopulate();
+		this.populateComboBox();
+	}
+	
+	
+	// **************** populating ********************************************
+	
+	/**
+	 * Populate the combo-box list by clearing it, then adding first the default
+	 * value, if available, and then the possible choices.
+	 */
+	protected void populateComboBox() {
+		this.comboBox.removeAll();
+		
+		if (usesDefaultValue()) {
+			this.comboBox.add(this.buildDefaultValueEntry());
+		}
+			
+		for (String value : this.getValues()) {
+			this.comboBox.add(value);
+		}
+		
+		this.updateSelectedItem_();
+	}
+	
+	protected String buildDefaultValueEntry() {
+		if (getSubject() == null) {
+			return JptUiDetailsMessages.NoneSelected;
+		}
+		String defaultValue = this.getDefaultValue();
+		return (defaultValue == null) ? this.buildNullDefaultValueEntry() : this.buildNonNullDefaultValueEntry(defaultValue);
+	}
+	
+	protected String buildNullDefaultValueEntry() {
+		return JptUiDetailsMessages.DefaultEmpty;
+	}
+	
+	protected String buildNonNullDefaultValueEntry(String defaultValue) {
+		return NLS.bind(
+				JptUiDetailsMessages.DefaultWithOneParam,
+				defaultValue);
+	}
+	
+	protected void updateSelectedItem() {
+		// make sure the default value is up to date (??? ~bjv)
+		if (usesDefaultValue()) {
+			String defaultValueEntry = this.buildDefaultValueEntry();
+			if ( ! this.comboBox.getItem(0).equals(defaultValueEntry)) {
+				this.comboBox.remove(0);
+				this.comboBox.add(defaultValueEntry, 0);
+			}
+		}
+		
+		this.updateSelectedItem_();
+	}
+	
+	/**
+	 * Updates the selected item by selecting the current value, if not
+	 * <code>null</code>, or select the default value if one is available,
+	 * otherwise remove the selection.
+	 */
+	protected void updateSelectedItem_() {
+		String value = (this.getSubject() == null) ? null : this.getValue();
+		if (value == null) {
+			if (usesDefaultValue()) {
+				// select the default value
+				this.comboBox.select(0);
+			}
+			else {
+				this.comboBox.setText("");
+			}
+		} else {
+			// select the new value
+			if ( ! value.equals(this.comboBox.getText())) {
+				// This prevents the cursor from being set back to the beginning of the line (bug 234418).
+				// The reason we are hitting this method at all is because the
+				// context model is updating from the resource model in a way
+				// that causes change notifications to be fired (the annotation
+				// is added to the resource model, change notification occurs
+				// on the update thread, and then the name is set, these 2
+				// threads can get in the wrong order).
+				// The #valueChanged() method sets the populating flag to true,
+				// but in this case it is already set back to false when we
+				// receive notification back from the model because it has
+				// moved to the update thread and then jumps back on the UI thread.
+				this.comboBox.setText(value);
+			}
+		}
+	}
+	
+	protected void repopulateComboBox() {
+		if ( ! this.comboBox.isDisposed()) {
+			this.repopulate();
+		}
+	}
+	
+	
+	// **************** combo-box listener callback ***************************
+	
+	protected void comboBoxModified() {
+		if ( ! this.isPopulating()) {
+			this.valueChanged(this.comboBox.getText());
+		}
+	}
+	
+	/**
+	 * The combo-box selection has changed, update the model if necessary.
+	 * If the value has changed and the subject is null, we can build a subject
+	 * before setting the value.
+	 */
+	protected void valueChanged(String newValue) {
+		T subject = this.getSubject();
+		String oldValue;
+		if (subject == null) {
+			if (this.nullSubjectIsNotAllowed()) {
+				return;  // no subject to set the value on
+			}
+			oldValue = null;
+		} else {
+			oldValue = this.getValue();
+		}
+		
+		// convert empty string or default to null
+		if (StringTools.stringIsEmpty(newValue) || this.valueIsDefault(newValue)) {
+			newValue = null;
+		}
+		
+		// set the new value if it is different from the old value
+		if (Tools.valuesAreDifferent(oldValue, newValue)) {
+			this.setPopulating(true);
+			
+			try {
+				this.setValue(newValue);
+			} finally {
+				this.setPopulating(false);
+			}
+		}
+	}
+	
+	/**
+	 * Return whether we can set the value when the subject is null
+	 * (i.e. #setValue(String) will construct the subject if necessary).
+	 */
+	protected boolean nullSubjectIsAllowed() {
+		return false;
+	}
+	
+	protected final boolean nullSubjectIsNotAllowed() {
+		return ! this.nullSubjectIsAllowed();
+	}
+	
+	/**
+	 * pre-condition: value is not null
+	 */
+	protected boolean valueIsDefault(String value) {
+		if (! usesDefaultValue()) {
+			return false;
+		}
+		return (this.comboBox.getItemCount() > 0)
+				&& value.equals(this.comboBox.getItem(0));
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/widgets/DefaultWidgetFactory.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/widgets/DefaultWidgetFactory.java
new file mode 100644
index 0000000..a69961d
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/widgets/DefaultWidgetFactory.java
@@ -0,0 +1,260 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2010 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.ui.internal.widgets;
+
+import org.eclipse.jpt.ui.WidgetFactory;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.CCombo;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.DateTime;
+import org.eclipse.swt.widgets.Group;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.List;
+import org.eclipse.swt.widgets.Spinner;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.ui.forms.widgets.FormText;
+import org.eclipse.ui.forms.widgets.FormToolkit;
+import org.eclipse.ui.forms.widgets.Hyperlink;
+import org.eclipse.ui.forms.widgets.Section;
+import org.eclipse.ui.forms.widgets.TableWrapData;
+import org.eclipse.ui.forms.widgets.TableWrapLayout;
+
+/**
+ * This <code>WidgetFactory</code> simply creates plain SWT widgets.
+ *
+ * @version 2.0
+ * @since 2.0
+ */
+public class DefaultWidgetFactory implements WidgetFactory {
+
+	/**
+	 * The singleton instance of this <code>IWidgetFactory</code>
+	 */
+	private static final WidgetFactory INSTANCE = new DefaultWidgetFactory();
+
+	/**
+	 * Creates a new <code>DefaultWidgetFactory</code>.
+	 */
+	private DefaultWidgetFactory() {
+		super();
+	}
+
+	/**
+	 * Returns the singleton instance of this <code>IWidgetFactory</code>.
+	 *
+	 * @return The singleton instance of this <code>IWidgetFactory</code>
+	 */
+	public static WidgetFactory instance() {
+		return INSTANCE;
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public Button createButton(Composite parent, String text) {
+		return this.createButton(parent, text, SWT.NULL);
+	}
+
+	/**
+	 * Creates a new button.
+	 *
+	 * @param parent The parent container
+	 * @param text The button's text
+	 * @param style The style to apply to the button, which determines its type:
+	 * toggle, push, check box, radio
+	 * @return The newly created <code>Button</code>
+	 */
+	private Button createButton(Composite parent, String text, int style) {
+		Button button = new Button(parent, style);
+		button.setText(text);
+		return button;
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Deprecated
+	public CCombo createCCombo(Composite parent) {
+		return new CCombo(parent, SWT.BORDER | SWT.READ_ONLY);
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public Button createCheckBox(Composite parent, String text) {
+		return this.createButton(parent, text, SWT.CHECK);
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public Combo createCombo(Composite parent) {
+		return new Combo(parent, SWT.BORDER | SWT.READ_ONLY);
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public Composite createComposite(Composite parent) {
+		return new Composite(parent, SWT.NULL);
+	}
+	
+	/**
+	 * {@inheritDoc}
+	 */
+	public DateTime createDateTime(Composite parent, int style) {
+		return new DateTime(parent, style);
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Deprecated
+	public CCombo createEditableCCombo(Composite parent) {
+		return new CCombo(parent, SWT.BORDER);
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public Combo createEditableCombo(Composite parent) {
+		return new Combo(parent, SWT.BORDER);
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public Group createGroup(Composite parent, String title) {
+		Group group = new Group(parent, SWT.NULL);
+		group.setText(title);
+		return group;
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public Hyperlink createHyperlink(Composite parent, String text) {
+		Hyperlink hyperlink = new Hyperlink(parent, SWT.NULL);
+		hyperlink.setText(text);
+		return hyperlink;
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public Label createLabel(Composite parent, String labelText) {
+		Label label = new Label(parent, SWT.WRAP);
+		label.setText(labelText);
+		return label;
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public List createList(Composite parent, int style) {
+		return new List(parent, SWT.BORDER | style);
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public FormText createMultiLineLabel(Composite parent, String labelText) {
+
+		Composite container = new Composite(parent, SWT.NONE);
+
+		GridData gridData = new GridData();
+		gridData.horizontalAlignment       = GridData.FILL;
+		gridData.grabExcessHorizontalSpace = true;
+		container.setLayoutData(gridData);
+
+		TableWrapLayout layout = new TableWrapLayout();
+		layout.numColumns   = 1;
+		layout.bottomMargin = 0;
+		layout.leftMargin   = 0;
+		layout.rightMargin  = 0;
+		layout.topMargin    = 0;
+		container.setLayout(layout);
+
+		FormToolkit widgetFactory = new FormToolkit(parent.getDisplay());
+		FormText text = widgetFactory.createFormText(container, true);
+		text.setLayoutData(new TableWrapData(TableWrapData.FILL_GRAB));
+		text.setText(labelText, false, false);
+
+		return text;
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public Text createMultiLineText(Composite parent) {
+		return new Text(parent, SWT.BORDER | SWT.MULTI | SWT.V_SCROLL);
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public Text createPasswordText(Composite parent) {
+		return new Text(parent, SWT.BORDER | SWT.PASSWORD);
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public Button createPushButton(Composite parent, String text) {
+		return this.createButton(parent, text, SWT.PUSH);
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public Button createRadioButton(Composite parent, String text) {
+		return this.createButton(parent, text, SWT.RADIO);
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public Section createSection(Composite parent, int style) {
+		return new Section(parent, style);
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public Spinner createSpinner(Composite parent) {
+		return new Spinner(parent, SWT.NULL);
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public Table createTable(Composite parent, int style) {
+		return new Table(parent, SWT.BORDER | style);
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public Text createText(Composite parent) {
+		return new Text(parent, SWT.BORDER);
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public Button createTriStateCheckBox(Composite parent, String text) {
+		TriStateCheckBox checkBox = new TriStateCheckBox(parent, text, this);
+		return checkBox.getCheckBox();
+	}
+}
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/widgets/Dialog.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/widgets/Dialog.java
new file mode 100644
index 0000000..636a8e9
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/widgets/Dialog.java
@@ -0,0 +1,350 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2009 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.ui.internal.widgets;
+
+import org.eclipse.jface.dialogs.TitleAreaDialog;
+import org.eclipse.jpt.ui.internal.util.SWTUtil;
+import org.eclipse.jpt.utility.internal.model.value.SimplePropertyValueModel;
+import org.eclipse.jpt.utility.internal.node.Node;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.jpt.utility.model.value.WritablePropertyValueModel;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.help.IWorkbenchHelpSystem;
+
+/**
+ * The abstract implementation of a dialog using a "state object" (model object)
+ * for behavior.
+ * <p>
+ * The main pane of this dialog should be extending <code>DialogPane</code>
+ * for creating the right type of widgets and it has the "state object" (subject)
+ * behavior built-in.
+ *
+ * @see Node
+ * @see DialogPane
+ *
+ * @version 2.0
+ * @since 2.0
+ */
+@SuppressWarnings("nls")
+public abstract class Dialog<T extends Node> extends TitleAreaDialog
+{
+	/**
+	 * The main content pane of this dialog.
+	 */
+	private DialogPane<?> pane;
+
+	/**
+	 * The holder of the "state object" used by this dialog.
+	 */
+	private WritablePropertyValueModel<T> subjectHolder;
+
+	/**
+	 * Caches the title text until the dialog is created and the dialog's shell
+	 * needs to be configured.
+	 */
+	private String title;
+
+	/**
+	 * Creates a new <code>Dialog</code>.
+	 *
+	 * @param parent The parent shell
+	 */
+	protected Dialog(Shell parent) {
+		this(parent, "");
+	}
+
+	/**
+	 * Creates a new <code>Dialog</code>.
+	 *
+	 * @param parent The parent shell
+	 * @param title The dialog's title
+	 */
+	protected Dialog(Shell parent, String title) {
+		super(parent);
+		this.title = title;
+		initialize();
+	}
+
+	/**
+	 * Initializes the main pane of this dialog. This method is invoked only
+	 * when the dialog is requested to show on screen and not during
+	 * initialization.
+	 *
+	 * @param container The container to which the widgets should be added to,
+	 * the layout is already set
+	 */
+	protected abstract DialogPane<?> buildLayout(Composite container);
+
+	/**
+	 * Creates the state object (model object) that will be used to keep track
+	 * of the information entered in this dialog. The state object will be stored
+	 * in the subject holder and can be retrieved using {@link #subject()}.
+	 *
+	 * @return A new state object
+	 */
+	protected T buildStateObject() {
+		return null;
+	}
+
+	/**
+	 * Creates the <code>Validator</code> that will be notified when changes are
+	 * made to the state object.
+	 *
+	 * @return The validator that will be set on the state object
+	 */
+	Node.Validator buildValidator() {
+		return Node.NULL_VALIDATOR;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 */
+	@Override
+	public boolean close() {
+
+		// Dispose the pane in order to remove any listeners that could
+		// have been installed outside the scrope of the state object
+		if (pane != null) {
+			pane.dispose();
+			pane = null;
+		}
+
+		return super.close();
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	protected void configureShell(Shell shell) {
+		super.configureShell(shell);
+		shell.setText(getTitle());
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	public void create() {
+		super.create();
+		installSubject();
+	}
+
+	/*
+	 * (non-Javadoc)
+	 */
+	@Override
+	protected Control createContents(Composite parent) {
+		if (hasTitleArea()) {
+			return super.createContents(parent);
+		}
+
+		return createDefaultContent(parent);
+	}
+
+	/**
+	 * Creates the default main container of this dialog when the title area is
+	 * not required. The top part is the dialog area populated by the subclass
+	 * and the lower part is the button pane having the OK and Cancel buttons.
+	 *
+	 * @param parent The parent container
+	 * @return The
+	 */
+	private Composite createDefaultContent(Composite parent) {
+
+		Composite composite = new Composite(parent, SWT.NULL);
+
+		GridLayout layout      = new GridLayout(1, false);
+		layout.marginHeight    = 0;
+		layout.marginWidth     = 0;
+		layout.verticalSpacing = 0;
+		composite.setLayout(layout);
+		composite.setLayoutData(new GridData(GridData.FILL_BOTH));
+
+		applyDialogFont(composite);
+		initializeDialogUnits(composite);
+		dialogArea = createDialogArea(composite);
+		buttonBar  = createButtonBar(composite);
+
+		return composite;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 */
+	@Override
+	protected Composite createDialogArea(Composite parent) {
+
+		// If the title area needs to be shown, then leave the superclass to
+		// create the necessary widgets
+		if (hasTitleArea()) {
+			parent = (Composite) super.createDialogArea(parent);
+		}
+
+		// Create the main area's container
+		Composite container = new Composite(parent, SWT.NULL);
+		container.setLayout(new GridLayout(1, false));
+
+		GridData gridData = new GridData();
+		gridData.horizontalAlignment       = GridData.FILL;
+		gridData.verticalAlignment         = GridData.FILL;
+		gridData.grabExcessHorizontalSpace = true;
+		gridData.grabExcessVerticalSpace   = true;
+		container.setLayoutData(gridData);
+
+		// Initialize the content pane
+		pane = buildLayout(container);
+
+		// Initialize the UI part, which requires the widgets being created
+		initializeUI();
+
+		return parent;
+	}
+
+	/**
+	 * Determines whether the description area (where a title, description and
+	 * image) should be visible or hidden. <code>ValidatingDialog</code>
+	 * automatically show the description area in order to show problems.
+	 *
+	 * @return <code>false</code> by default, which means the methods used to
+	 * update the title, description and image shouldn't be called; <code>true</code>
+	 * to make the description pane visible
+	 */
+	protected boolean hasTitleArea() {
+		return false;
+	}
+
+	/**
+	 * Returns the helps system.
+	 *
+	 * @return The platform's help system
+	 *
+	 * @category Helper
+	 */
+	protected final IWorkbenchHelpSystem getHelpSystem() {
+		return PlatformUI.getWorkbench().getHelpSystem();
+	}
+
+	/**
+	 * Initializes this dialog.
+	 */
+	protected void initialize() {
+		this.subjectHolder = new SimplePropertyValueModel<T>();
+	}
+
+	/**
+	 * Initializes the UI part of this dialog, this is called after the widgets
+	 * have been created.
+	 */
+	protected void initializeUI() {
+	}
+
+	/**
+	 * Creates the state object, if one is needed and install a <code>Validator</code>
+	 * in order to receive notification of changes done to that state object. The
+	 * subject can be retrieved from the subject holder.
+	 */
+	private void installSubject() {
+
+		T subject = buildStateObject();
+
+		if (subject != null) {
+			subject.setValidator(buildValidator());
+		}
+
+		subjectHolder.setValue(subject);
+	}
+
+	/**
+	 * Asynchronously launches this dialog in the UI thread.
+	 */
+	public final void openDialog() {
+		SWTUtil.setUserInterfaceActive(false);
+		SWTUtil.show(this);
+	}
+
+	/**
+	 * Asynchronously launches this dialog in the UI thread and invoke the given
+	 * <code>PostExecution</code> to perform any post-task.
+	 *
+	 * @param postExecution This interface let the caller to invoke a piece of
+	 * code once the dialog is disposed
+	 */
+	public final void openDialog(PostExecution<? extends Dialog<T>> execution) {
+		SWTUtil.setUserInterfaceActive(false);
+		SWTUtil.show(this, execution);
+	}
+
+	/**
+	 * Gives access to the dialog's main pane.
+	 *
+	 * @return The pane showing the custom widgets
+	 */
+	protected DialogPane<?> getPane() {
+		return pane;
+	}
+
+	/**
+	 * Returns the subject of this dialog.
+	 *
+	 * @return The subject of this dialog or <code>null</code> if no subject was
+	 * used
+	 */
+	public T getSubject() {
+		return subjectHolder.getValue();
+	}
+
+	/**
+	 * Returns the holder of the subject.
+	 *
+	 * @return The subject holder used to be passed to the dialog pane, which is
+	 * an instance of <code>DialogPane</code>
+	 */
+	protected final PropertyValueModel<T> getSubjectHolder() {
+		return subjectHolder;
+	}
+
+	/**
+	 * Retrieves the dialog's title. The title passed to the constructor will be
+	 * returned by default but if it wasn't specified, this method can be used
+	 * to return it.
+	 *
+	 * @return Either the title passed to the constructor or a different title
+	 */
+	protected String getTitle() {
+		return title;
+	}
+
+	/**
+	 * Determines whether the dialog was cancelled or not.
+	 *
+	 * @return <code>true</code> if the dialog was cancelled; <code>false</code>
+	 * if it was confirmed
+	 */
+	public final boolean wasCancelled() {
+		return getReturnCode() == CANCEL;
+	}
+
+	/**
+	 * Determines whether the dialog was confirmed or not.
+	 *
+	 * @return <code>true</code> if the dialog was confirmed; <code>false</code>
+	 * if it was cancelled
+	 */
+	public final boolean wasConfirmed() {
+		return getReturnCode() == OK;
+	}
+}
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/widgets/DialogPane.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/widgets/DialogPane.java
new file mode 100644
index 0000000..1789087
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/widgets/DialogPane.java
@@ -0,0 +1,109 @@
+/*******************************************************************************
+ * Copyright (c) 2008 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.ui.internal.widgets;
+
+import org.eclipse.jpt.utility.internal.node.Node;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * The abstract pane to use when the pane is shown in an <code>Dialog</code>.
+ *
+ * @see Dialog
+ *
+ * @version 2.0
+ * @since 2.0
+ */
+public abstract class DialogPane<T extends Node> extends Pane<T> {
+
+	/**
+	 * Creates a new <code>DialogPane</code>.
+	 *
+	 * @param parentPane The parent controller of this one
+	 * @param parent The parent container
+	 *
+	 * @category Constructor
+	 */
+	protected DialogPane(DialogPane<? extends T> parentPane,
+	                             Composite parent) {
+
+		super(parentPane, parent);
+	}
+
+	/**
+	 * Creates a new <code>DialogPane</code>.
+	 *
+	 * @param parentPane The parent container of this one
+	 * @param parent The parent container
+	 * @param widgetFactory The factory used to create various widgets
+	 * @param automaticallyAlignWidgets <code>true</code> to make the widgets
+	 * this pane aligned with the widgets of the given parent controller;
+	 * <code>false</code> to not align them
+	 *
+	 * @category Constructor
+	 */
+	protected DialogPane(DialogPane<? extends T> parentPane,
+	                             Composite parent,
+	                             boolean automaticallyAlignWidgets) {
+
+		super(parentPane, parent, automaticallyAlignWidgets);
+	}
+
+	/**
+	 * Creates a new <code>DialogPane</code>.
+	 *
+	 * @param parentPane The parent container of this one
+	 * @param subjectHolder The holder of this pane's subject
+	 * @param parent The parent container
+	 *
+	 * @category Constructor
+	 */
+	protected DialogPane(DialogPane<?> parentPane,
+	                             PropertyValueModel<? extends T> subjectHolder,
+	                             Composite parent) {
+
+		super(parentPane, subjectHolder, parent);
+	}
+
+	/**
+	 * Creates a new <code>DialogPane</code>.
+	 *
+	 * @param parentPane The parent container of this one
+	 * @param subjectHolder The holder of this pane's subject
+	 * @param parent The parent container
+	 * @param widgetFactory The factory used to create various widgets
+	 * @param automaticallyAlignWidgets <code>true</code> to make the widgets
+	 * this pane aligned with the widgets of the given parent controller;
+	 * <code>false</code> to not align them
+	 *
+	 * @category Constructor
+	 */
+	protected DialogPane(DialogPane<?> parentPane,
+	                             PropertyValueModel<? extends T> subjectHolder,
+	                             Composite parent,
+	                             boolean automaticallyAlignWidgets) {
+
+		super(parentPane, subjectHolder, parent, automaticallyAlignWidgets);
+	}
+
+	/**
+	 * Creates a new <code>DialogPane</code>.
+	 *
+	 * @param subjectHolder The holder of this pane's subject
+	 * @param parent The parent container
+	 *
+	 * @category Constructor
+	 */
+	protected DialogPane(PropertyValueModel<? extends T> subjectHolder,
+	                             Composite parent) {
+
+		super(subjectHolder, parent, DefaultWidgetFactory.instance());
+	}
+}
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/widgets/EnumComboViewer.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/widgets/EnumComboViewer.java
new file mode 100644
index 0000000..0810236
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/widgets/EnumComboViewer.java
@@ -0,0 +1,369 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2010 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.ui.internal.widgets;
+
+import com.ibm.icu.text.Collator;
+import java.util.Arrays;
+import java.util.Comparator;
+import org.eclipse.jface.viewers.ComboViewer;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.jpt.ui.WidgetFactory;
+import org.eclipse.jpt.ui.internal.JptUiMessages;
+import org.eclipse.jpt.ui.internal.util.SWTUtil;
+import org.eclipse.jpt.utility.model.Model;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * This pane simply shows a combo where its data is populating through
+ * {@link #choices()} and a default value can also be added.
+ * <p>
+ * Here the layout of this pane:
+ * <pre>
+ * -----------------------------------------------------------------------------
+ * | ------------------------------------------------------------------------- |
+ * | | I                                                                   |v| |
+ * | ------------------------------------------------------------------------- |
+ * -----------------------------------------------------------------------------</pre>
+ *
+ * @version 2.0
+ * @since 1.0
+ */
+@SuppressWarnings("nls")
+abstract class EnumComboViewer<T extends Model, V> extends Pane<T>
+{
+	/**
+	 * The main widget of this pane.
+	 */
+	private ComboViewer comboViewer;
+
+	/**
+	 * A constant used to represent the <code>null</code> value.
+	 */
+	public static final String NULL_VALUE = "null";
+
+	/**
+	 * Creates a new <code>EnumComboViewer</code>.
+	 *
+	 * @param parentPane The parent container of this one
+	 * @param parent The parent container
+	 * @param widgetFactory The factory used to create various widgets
+	 */
+	EnumComboViewer(Pane<? extends T> parentPane,
+	                        Composite parent) {
+
+		super(parentPane, parent);
+	}
+
+	/**
+	 * Creates a new <code>EnumComboViewer</code>.
+	 *
+	 * @param parentPane The parent container of this one
+	 * @param parent The parent container
+	 * @param widgetFactory The factory used to create various widgets
+	 */
+	EnumComboViewer(Pane<?> parentPane,
+	                        PropertyValueModel<? extends T> subjectHolder,
+	                        Composite parent) {
+
+		super(parentPane, subjectHolder, parent);
+	}
+
+	/**
+	 * Creates a new <code>EnumComboViewer</code>.
+	 *
+	 * @param subjectHolder The holder of this pane's subject
+	 * @param parent The parent container
+	 * @param widgetFactory The factory used to create various widgets
+	 */
+	EnumComboViewer(PropertyValueModel<? extends T> subjectHolder,
+	                        Composite parent,
+	                        WidgetFactory widgetFactory) {
+
+		super(subjectHolder, parent, widgetFactory);
+	}
+
+	/**
+	 * Creates the list of choices and add an extra element that represents the
+	 * default value.
+	 *
+	 * @return The combo's choices including the default value
+	 */
+	private Object[] buildChoices() {
+		V[] choices = getChoices();
+		if (sortChoices()) {
+			Arrays.sort(choices, buildComparator());
+		}
+
+		Object[] extendedChoices = new Object[choices.length + 1];
+		System.arraycopy(choices, 0, extendedChoices, 1, choices.length);
+		extendedChoices[0] = NULL_VALUE;
+
+		return extendedChoices;
+	}
+
+	/**
+	 * Return true to sort the choices in alphabetical order
+	 * @return
+	 */
+	protected boolean sortChoices() {
+		return true;
+	}
+	
+	/**
+	 * Creates the <code>ComboViewer</code> with the right combo widgets.
+	 *
+	 * @param container The container of the combo
+	 * @return A new <code>ComboViewer</code> containing the right combo widget
+	 */
+	protected ComboViewer addComboViewer(Composite container) {
+		return addComboViewer(container, buildLabelProvider());
+	}
+
+	private Comparator<Object> buildComparator() {
+		return new Comparator<Object>() {
+			final LabelProvider labelProvider = buildLabelProvider();
+
+			public int compare(Object value1, Object value2) {
+				String displayString1 = labelProvider.getText(value1);
+				String displayString2 = labelProvider.getText(value2);
+				return Collator.getInstance().compare(displayString1, displayString2);
+			}
+		};
+	}
+
+	/**
+	 * Retrieves the localized string from the given NLS class by creating the
+	 * key. That key is the concatenation of the composite's short class name
+	 * with the toString() of the given value separated by an underscore.
+	 *
+	 * @param nlsClass The NLS class used to retrieve the localized text
+	 * @param compositeClass The class used for creating the key, its short class
+	 * name is the beginning of the key
+	 * @param value The value used to append its toString() to the generated key
+	 * @return The localized text associated with the value
+	 */
+	protected final String buildDisplayString(Class<?> nlsClass,
+	                                          Class<?> compositeClass,
+	                                          Object value) {
+
+		return SWTUtil.buildDisplayString(nlsClass, compositeClass, value);
+	}
+
+	/**
+	 * Retrieves the localized string from the given NLS class by creating the
+	 * key. That key is the concatenation of the composite's short class name
+	 * with the toString() of the given value separated by an underscore.
+	 *
+	 * @param nlsClass The NLS class used to retrieve the localized text
+	 * @param composite The object used to retrieve the short class name that is
+	 * the beginning of the key
+	 * @param value The value used to append its toString() to the generated key
+	 * @return The localized text associated with the value
+	 */
+	protected final String buildDisplayString(Class<?> nlsClass,
+	                                          Object composite,
+	                                          Object value) {
+
+		return SWTUtil.buildDisplayString(nlsClass, composite, value);
+	}
+
+	/**
+	 * Creates the display string for the given element. If the element is the
+	 * virtual <code>null</code> value then its display string will be "Default"
+	 * appended by the actual default value, if it exists.
+	 *
+	 * @param value The value to convert into a human readable string
+	 * @return The string representation of the given element
+	 */
+	@SuppressWarnings("unchecked")
+	private String buildDisplayString(Object value) {
+		if (value == NULL_VALUE) {
+			V defaultValue = (getSubject() != null) ? getDefaultValue() : null;
+
+			if (defaultValue != null) {
+				String displayString = displayString(defaultValue);
+				return NLS.bind(JptUiMessages.EnumComboViewer_defaultWithDefault, displayString);
+			}
+			return nullDisplayString();
+		}
+
+		return displayString((V) value);
+	}
+
+	final LabelProvider buildLabelProvider() {
+		return new LabelProvider() {
+			@Override
+			public String getText(Object element) {
+				return buildDisplayString(element);
+			}
+		};
+	}
+
+	private ISelection buildSelection() {
+		Object value = (getSubject() != null) ? getValue() : null;
+
+		if (value == null) {
+			value = NULL_VALUE;
+		}
+
+		return new StructuredSelection(value);
+	}
+
+	private ISelectionChangedListener buildSelectionChangedListener() {
+		return new ISelectionChangedListener() {
+			public void selectionChanged(SelectionChangedEvent e) {
+				if (!isPopulating()) {
+					StructuredSelection selection = (StructuredSelection) e.getSelection();
+					valueChanged(selection.getFirstElement());
+				}
+			}
+		};
+	}
+
+	/**
+	 * Returns the possible choices to show in the viewer.
+	 *
+	 * @return The items to show in the combos
+	 */
+	protected abstract V[] getChoices();
+
+	/**
+	 * Returns the default value, this method is not called if the subject is
+	 * <code>null</code>.
+	 *
+	 * @return The value that is declared as being the default when it is not
+	 * defined or <code>null</code> if there is no default value
+	 */
+	protected abstract V getDefaultValue();
+
+	/**
+	 * Returns the displayable string for the given value.
+	 *
+	 * @param value The value to translate into a human readable string
+	 * @return The localized text representing the given value
+	 */
+	protected abstract String displayString(V value);
+	
+	/**
+	 * Returns the displayable string for a null value.
+	 */
+	protected String nullDisplayString() {
+		return null; //I would rather display nothing than "Default()"
+	}
+
+	/*
+	 * (non-Javadoc)
+	 */
+	@Override
+	protected void doPopulate() {
+		super.doPopulate();
+		this.populateCombo();
+	}
+
+	/**
+	 * Returns
+	 *
+	 * @return
+	 */
+	final ComboViewer getComboViewer() {
+		return comboViewer;
+	}
+
+	/**
+	 * Retrieves the subject's value. The subject is never <code>null</code>.
+	 *
+	 * @return The subject' value, which can be <code>null</code>
+	 */
+	protected abstract V getValue();
+
+	/*
+	 * (non-Javadoc)
+	 */
+	@Override
+	protected final void initializeLayout(Composite container) {
+
+		this.comboViewer = this.addComboViewer(container);
+		this.comboViewer.addSelectionChangedListener(buildSelectionChangedListener());
+	}
+
+	/**
+	 * Populates the combo by re-adding all the items.
+	 */
+	private void populateCombo() {
+
+		removeAll();
+		comboViewer.add(buildChoices());
+		updateSelection();
+	}
+
+	/*
+	 * (non-Javadoc)
+	 */
+	@Override
+	protected void propertyChanged(String propertyName) {
+		super.propertyChanged(propertyName);
+		this.populateCombo();
+	}
+
+	/**
+	 * Removes all the items from the combo.
+	 */
+	abstract void removeAll();
+
+	/**
+	 * Requests the given new value be set on the subject.
+	 *
+	 * @param value The new value to be set
+	 */
+	protected abstract void setValue(V value);
+
+	/**
+	 * Updates the cursor, which is required to show the entire selected item
+	 * within the combo's area.
+	 */
+	abstract void updateCursor();
+
+	/**
+	 * Updates the combo's selected item.
+	 */
+	private void updateSelection() {
+		comboViewer.setSelection(buildSelection());
+		updateCursor();
+	}
+
+	/**
+	 * The selection changes, notify the subclass to set the value.
+	 *
+	 * @param value The new selected item
+	 */
+	@SuppressWarnings("unchecked")
+	private void valueChanged(Object value) {
+
+		// Convert the default "null" value to a real null
+		if (value == NULL_VALUE) {
+			value = null;
+		}
+
+		setPopulating(true);
+
+		try {
+			setValue((V) value);
+		}
+		finally {
+			setPopulating(false);
+		}
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/widgets/EnumDialogComboViewer.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/widgets/EnumDialogComboViewer.java
new file mode 100644
index 0000000..591a32d
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/widgets/EnumDialogComboViewer.java
@@ -0,0 +1,77 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2010 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.ui.internal.widgets;
+
+import org.eclipse.jpt.utility.model.Model;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * This <code>EnumComboViewer</code> should be used within a dialog pane.
+ *
+ * @version 2.0
+ * @since 2.0
+ */
+public abstract class EnumDialogComboViewer<T extends Model, V>
+	extends EnumComboViewer<T, V>
+{
+	/**
+	 * Creates a new <code>EnumDialogComboViewer</code>.
+	 *
+	 * @param parentPane The parent container of this one
+	 * @param parent The parent container
+	 * @param widgetFactory The factory used to create various widgets
+	 */
+	protected EnumDialogComboViewer(DialogPane<? extends T> parentPane,
+	                                Composite parent
+	) {
+		super(parentPane, parent);
+	}
+
+	/**
+	 * Creates a new <code>EnumDialogComboViewer</code>.
+	 *
+	 * @param parentPane The parent container of this one
+	 * @param parent The parent container
+	 * @param widgetFactory The factory used to create various widgets
+	 */
+	protected EnumDialogComboViewer(DialogPane<?> parentPane,
+	                                PropertyValueModel<? extends T> subjectHolder,
+	                                Composite parent
+	) {
+		super(parentPane, subjectHolder, parent);
+	}
+
+	@Override
+	public void enableWidgets(boolean enabled) {
+		super.enableWidgets(enabled);
+
+		Combo combo = getCombo();
+		if ( ! combo.isDisposed()) {
+			combo.setEnabled(enabled);
+		}
+	}
+
+	protected final Combo getCombo() {
+		return getComboViewer().getCombo();
+	}
+
+	@Override
+	void removeAll() {
+		getCombo().removeAll();
+	}
+
+	@Override
+	void updateCursor() {
+		getCombo().setSelection(new Point(0, 0));
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/widgets/EnumFormComboViewer.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/widgets/EnumFormComboViewer.java
new file mode 100644
index 0000000..67d7a41
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/widgets/EnumFormComboViewer.java
@@ -0,0 +1,77 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2010 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.ui.internal.widgets;
+
+import org.eclipse.jpt.utility.model.Model;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * This <code>EnumComboViewer</code> should be used within a form pane.
+ *
+ * @version 2.3
+ * @since 1.0
+ */
+public abstract class EnumFormComboViewer<T extends Model, V>
+	extends EnumComboViewer<T, V>
+{
+	/**
+	 * Creates a new <code>EnumFormComboViewer</code>.
+	 *
+	 * @param parentPane The parent container of this one
+	 * @param parent The parent container
+	 * @param widgetFactory The factory used to create various widgets
+	 */
+	protected EnumFormComboViewer(Pane<? extends T> parentPane,
+	                              Composite parent
+	) {
+		super(parentPane, parent);
+	}
+
+	/**
+	 * Creates a new <code>EnumFormComboViewer</code>.
+	 *
+	 * @param parentPane The parent container of this one
+	 * @param parent The parent container
+	 * @param widgetFactory The factory used to create various widgets
+	 */
+	protected EnumFormComboViewer(Pane<?> parentPane,
+	                              PropertyValueModel<? extends T> subjectHolder,
+	                              Composite parent
+	) {
+		super(parentPane, subjectHolder, parent);
+	}
+
+	@Override
+	public void enableWidgets(boolean enabled) {
+		super.enableWidgets(enabled);
+
+		Combo combo = getCombo();
+		if ( ! combo.isDisposed()) {
+			combo.setEnabled(enabled);
+		}
+	}
+
+	protected final Combo getCombo() {
+		return this.getComboViewer().getCombo();
+	}
+
+	@Override
+	void removeAll() {
+		getCombo().removeAll();
+	}
+
+	@Override
+	void updateCursor() {
+		getCombo().setSelection(new Point(0, 0));
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/widgets/FileChooserComboPane.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/widgets/FileChooserComboPane.java
new file mode 100644
index 0000000..7599ec6
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/widgets/FileChooserComboPane.java
@@ -0,0 +1,105 @@
+/*******************************************************************************
+* Copyright (c) 2010 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.ui.internal.widgets;
+
+import java.util.Arrays;
+import java.util.List;
+
+import org.eclipse.jpt.utility.internal.StringConverter;
+import org.eclipse.jpt.utility.internal.model.value.SimpleListValueModel;
+import org.eclipse.jpt.utility.model.Model;
+import org.eclipse.jpt.utility.model.value.ListValueModel;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+
+/**
+ * This chooser allows the user to choose a file when browsing.
+ * <p>
+ * Here the layout of this pane:
+ * <pre>
+ * -----------------------------------------------------------------------------
+ * |        ---------------------------------------------------- ------------- |
+ * | Label: | I                                            |v| | | Browse... | |
+ * |        ---------------------------------------------------- ------------- |
+ * -----------------------------------------------------------------------------</pre>
+ *
+ * @version 3.0
+ * @since 3.0
+ */
+public abstract class FileChooserComboPane<T extends Model> extends FileChooserPane<T>
+{
+	/**
+	 * Creates a new <code>FileChooserComboPane</code>.
+	 *
+	 * @param parentPane The parent pane of this one
+	 * @param parent The parent container
+	 */
+	public FileChooserComboPane(Pane<? extends T> parentPane,
+	                       Composite parent) {
+
+		super(parentPane, parent);
+	}
+
+	/**
+	 * Creates a new <code>FileChooserComboPane</code>.
+	 *
+	 * @param parentPane The parent container of this one
+	 * @param subjectHolder The holder of this pane's subject
+	 * @param parent The parent container
+	 */
+	public FileChooserComboPane(Pane<?> parentPane,
+	                       PropertyValueModel<? extends T> subjectHolder,
+	                       Composite parent) {
+
+		super(parentPane, subjectHolder, parent);
+	}
+
+	@Override
+	protected Control addMainControl(Composite container) {
+		
+		return addEditableCombo(
+			container,
+			this.buildListHolder(),
+			this.getTextHolder(),
+			this.buildStringConverter()
+		);
+	}
+
+	/**
+	 * Creates the list holder of the combo box.
+	 */
+	protected ListValueModel<String> buildListHolder() {
+		return new SimpleListValueModel<String>(
+			this.buildDefaultList()
+		);
+	}
+
+	/**
+	 * Creates the default list of the combo box.
+	 */
+	protected List<String> buildDefaultList() {
+		return Arrays.asList(this.getDefaultString());
+	}
+
+	/**
+	 * Returns the default value of the combo box.
+	 */
+	protected abstract String getDefaultString();
+	
+	/**
+	 * The converter responsible to transform each combo box item
+	 * into a string representation
+	 */
+	protected StringConverter<String> buildStringConverter() {
+		return StringConverter.Default.<String>instance();
+	}
+
+}
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/widgets/FileChooserPane.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/widgets/FileChooserPane.java
new file mode 100644
index 0000000..a04f05c
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/widgets/FileChooserPane.java
@@ -0,0 +1,167 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2010 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.ui.internal.widgets;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerFilter;
+import org.eclipse.jpt.ui.JptUiPlugin;
+import org.eclipse.jpt.utility.model.Model;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.jpt.utility.model.value.WritablePropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.FileDialog;
+import org.eclipse.ui.dialogs.ISelectionStatusValidator;
+
+/**
+ * This chooser allows the user to choose a file when browsing.
+ * <p>
+ * Here the layout of this pane:
+ * <pre>
+ * -----------------------------------------------------------------------------
+ * |        ---------------------------------------------------- ------------- |
+ * | Label: | I                                                | | Browse... | |
+ * |        ---------------------------------------------------- ------------- |
+ * -----------------------------------------------------------------------------</pre>
+ *
+ * @version 2.0
+ * @since 2.0
+ */
+@SuppressWarnings("nls")
+public abstract class FileChooserPane<T extends Model> extends ChooserPane<T>
+{
+	private WritablePropertyValueModel<String> textHolder;
+
+	/**
+	 * Creates a new <code>FileChooserPane</code>.
+	 *
+	 * @param parentPane The parent pane of this one
+	 * @param parent The parent container
+	 */
+	public FileChooserPane(Pane<? extends T> parentPane,
+	                       Composite parent) {
+
+		super(parentPane, parent);
+	}
+
+	/**
+	 * Creates a new <code>FileChooserPane</code>.
+	 *
+	 * @param parentPane The parent container of this one
+	 * @param subjectHolder The holder of this pane's subject
+	 * @param parent The parent container
+	 */
+	public FileChooserPane(Pane<?> parentPane,
+	                       PropertyValueModel<? extends T> subjectHolder,
+	                       Composite parent) {
+
+		super(parentPane, subjectHolder, parent);
+	}
+
+	@Override
+	protected final Runnable buildBrowseAction() {
+		return new Runnable() {
+			public void run() {
+				promptFile();
+			}
+		};
+	}
+
+	/**
+	 * Creates the <code>ViewerFilter</code> that will filter the content of the
+	 * dialog and only displays what is valid.
+	 *
+	 * @return A new <code>ViewerFilter</code>
+	 */
+	protected ViewerFilter buildFilter() {
+		return new ViewerFilter() {
+			@Override
+			public boolean select(Viewer viewer,
+			                      Object parentElement,
+			                      Object element) {
+
+				return true;
+			}
+		};
+	}
+
+	@Override
+	protected Control addMainControl(Composite container) {
+		return this.addText(container, this.textHolder);
+	}
+
+	/**
+	 * Creates the value holder of the subject's property.
+	 *
+	 * @return The holder of the class name
+	 */
+	protected abstract WritablePropertyValueModel<String> buildTextHolder();
+
+	/**
+	 * Creates the validator that will show a status message based on what is
+	 * selected in the selection dialog.
+	 *
+	 * @return A new <code>ISelectionStatusValidator</code>
+	 */
+	protected ISelectionStatusValidator buildValidator() {
+		return new ISelectionStatusValidator() {
+			public IStatus validate(Object[] selection) {
+
+				if (selection.length != 1) {
+					return new Status(IStatus.ERROR, JptUiPlugin.PLUGIN_ID, "");
+				}
+
+				return new Status(IStatus.OK, JptUiPlugin.PLUGIN_ID, "");
+			}
+		};
+	}
+
+	/**
+	 * Returns the selection dialog's title.
+	 *
+	 * @return A non-<code>null</code> string
+	 */
+	protected abstract String getDialogTitle();
+
+	/**
+	 * Retrieves the project path that will be used by the selection dialog.
+	 *
+	 * @return The project path used to display its content in a selection dialog
+	 */
+	protected abstract String getProjectPath();
+
+	protected  WritablePropertyValueModel<String> getTextHolder() {
+		return this.textHolder;
+	}
+
+	@Override
+	protected void initialize() {
+		super.initialize();
+		this.textHolder = this.buildTextHolder();
+	}
+
+	/**
+	 * The browse button was clicked, its action invokes this action which should
+	 * prompt the user to select a file and set it.
+	 */
+	protected void promptFile() {
+		String projectPath= this.getProjectPath();
+
+		FileDialog dialog = new FileDialog(getShell());
+		dialog.setText(this.getDialogTitle());
+		dialog.setFilterPath(projectPath);
+		String filePath = dialog.open();
+		if (filePath != null) {
+			FileChooserPane.this.textHolder.setValue(filePath);
+		}
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/widgets/FolderChooserComboPane.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/widgets/FolderChooserComboPane.java
new file mode 100644
index 0000000..f505869
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/widgets/FolderChooserComboPane.java
@@ -0,0 +1,106 @@
+/*******************************************************************************
+* Copyright (c) 2010 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.ui.internal.widgets;
+
+import java.util.Arrays;
+import java.util.List;
+
+import org.eclipse.jpt.utility.internal.StringConverter;
+import org.eclipse.jpt.utility.internal.model.value.SimpleListValueModel;
+import org.eclipse.jpt.utility.model.Model;
+import org.eclipse.jpt.utility.model.value.ListValueModel;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+
+
+/**
+ * This chooser allows the user to choose a folder when browsing.
+ * <p>
+ * Here the layout of this pane:
+ * <pre>
+ * -----------------------------------------------------------------------------
+ * |        ---------------------------------------------------- ------------- |
+ * | Label: | I                                            |v| | | Browse... | |
+ * |        ---------------------------------------------------- ------------- |
+ * -----------------------------------------------------------------------------</pre>
+ *
+ * @version 3.0
+ * @since 3.0
+ */
+public abstract class FolderChooserComboPane<T extends Model> extends FolderChooserPane<T>
+{
+	/**
+	 * Creates a new <code>FolderChooserComboPane</code>.
+	 *
+	 * @param parentPane The parent pane of this one
+	 * @param parent The parent container
+	 */
+	public FolderChooserComboPane(Pane<? extends T> parentPane,
+	                         Composite parent) {
+
+		super(parentPane, parent);
+	}
+
+	/**
+	 * Creates a new <code>FolderChooserComboPane</code>.
+	 *
+	 * @param parentPane The parent container of this one
+	 * @param subjectHolder The holder of this pane's subject
+	 * @param parent The parent container
+	 */
+	public FolderChooserComboPane(Pane<?> parentPane,
+	                         PropertyValueModel<? extends T> subjectHolder,
+	                         Composite parent) {
+
+		super(parentPane, subjectHolder, parent);
+	}
+
+	@Override
+	protected Control addMainControl(Composite container) {
+		
+		return addEditableCombo(
+			container,
+			this.buildListHolder(),
+			this.getTextHolder(),
+			this.buildStringConverter()
+		);
+	}
+
+	/**
+	 * Creates the list holder of the combo box.
+	 */
+	protected ListValueModel<String> buildListHolder() {
+		return new SimpleListValueModel<String>(
+			this.buildDefaultList()
+		);
+	}
+
+	/**
+	 * Creates the default list of the combo box.
+	 */
+	protected List<String> buildDefaultList() {
+		return Arrays.asList(this.getDefaultString());
+	}
+
+	/**
+	 * Returns the default value of the combo box.
+	 */
+	protected abstract String getDefaultString();
+	
+	/**
+	 * The converter responsible to transform each combo box item
+	 * into a string representation
+	 */
+	protected StringConverter<String> buildStringConverter() {
+		return StringConverter.Default.<String>instance();
+	}
+
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/widgets/FolderChooserPane.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/widgets/FolderChooserPane.java
new file mode 100644
index 0000000..001b70c
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/widgets/FolderChooserPane.java
@@ -0,0 +1,140 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 20010 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.ui.internal.widgets;
+
+import org.eclipse.jpt.utility.model.Model;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.jpt.utility.model.value.WritablePropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.DirectoryDialog;
+
+/**
+ * This chooser allows the user to choose a folder when browsing.
+ * <p>
+ * Here the layout of this pane:
+ * <pre>
+ * -----------------------------------------------------------------------------
+ * |        ---------------------------------------------------- ------------- |
+ * | Label: | I                                                | | Browse... | |
+ * |        ---------------------------------------------------- ------------- |
+ * -----------------------------------------------------------------------------</pre>
+ *
+ * @version 3.0
+ * @since 2.0
+ */
+public abstract class FolderChooserPane<T extends Model> extends ChooserPane<T>
+{
+	private WritablePropertyValueModel<String> textHolder;
+
+	/**
+	 * Creates a new <code>FolderChooserPane</code>.
+	 *
+	 * @param parentPane The parent pane of this one
+	 * @param parent The parent container
+	 */
+	public FolderChooserPane(Pane<? extends T> parentPane,
+	                         Composite parent) {
+
+		super(parentPane, parent);
+	}
+
+	/**
+	 * Creates a new <code>FolderChooserPane</code>.
+	 *
+	 * @param parentPane The parent container of this one
+	 * @param subjectHolder The holder of this pane's subject
+	 * @param parent The parent container
+	 */
+	public FolderChooserPane(Pane<?> parentPane,
+	                         PropertyValueModel<? extends T> subjectHolder,
+	                         Composite parent) {
+
+		super(parentPane, subjectHolder, parent);
+	}
+
+	@Override
+	protected final Runnable buildBrowseAction() {
+		return new Runnable() {
+			public void run() {
+				promptFolder();
+			}
+		};
+	}
+
+	@Override
+	protected Control addMainControl(Composite container) {
+		return this.addText(container, this.textHolder);
+	}
+
+	/**
+	 * Creates the value holder of the subject's property.
+	 *
+	 * @return The holder of the class name
+	 */
+	protected abstract WritablePropertyValueModel<String> buildTextHolder();
+
+	/**
+	 * Returns the message to be shown in the selection dialog.
+	 *
+	 * @return A non-<code>null</code> string shown above the text field of the
+	 * selection dialog
+	 */
+	protected abstract String getDialogMessage();
+
+	/**
+	 * Returns the selection dialog's title.
+	 *
+	 * @return A non-<code>null</code> string
+	 */
+	protected abstract String getDialogTitle();
+
+	/**
+	 * Returns the path that the dialog will use to filter the directories it
+	 * shows to the argument, which may be null. If the string is null, then the
+	 * operating system's default filter path will be used.
+	 * <p>
+	 * Note that the path string is platform dependent. For convenience, either
+	 * '/' or '\' can be used as a path separator.
+	 * </p>
+	 *
+	 * @return The filter path
+	 */
+	protected String filterPath() {
+		return null;
+	}
+
+	protected  WritablePropertyValueModel<String> getTextHolder() {
+		return this.textHolder;
+	}
+
+	@Override
+	protected void initialize() {
+		super.initialize();
+		this.textHolder = this.buildTextHolder();
+	}
+
+	/**
+	 * The browse button was clicked, its action invokes this action which should
+	 * prompt the user to select a folder and set it.
+	 */
+	protected void promptFolder() {
+
+		DirectoryDialog dialog = new DirectoryDialog(getShell());
+		dialog.setMessage(this.getDialogMessage());
+		dialog.setText(this.getDialogTitle());
+		dialog.setFilterPath(this.filterPath());
+		String directory = dialog.open();
+
+		if (directory != null) {
+			this.textHolder.setValue(directory);
+		}
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/widgets/FormWidgetFactory.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/widgets/FormWidgetFactory.java
new file mode 100644
index 0000000..3364b3a
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/widgets/FormWidgetFactory.java
@@ -0,0 +1,338 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2010 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.ui.internal.widgets;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.jpt.ui.WidgetFactory;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.CCombo;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.DateTime;
+import org.eclipse.swt.widgets.Group;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.List;
+import org.eclipse.swt.widgets.Spinner;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.ui.forms.widgets.FormText;
+import org.eclipse.ui.forms.widgets.FormToolkit;
+import org.eclipse.ui.forms.widgets.Hyperlink;
+import org.eclipse.ui.forms.widgets.Section;
+import org.eclipse.ui.forms.widgets.TableWrapData;
+import org.eclipse.ui.forms.widgets.TableWrapLayout;
+
+/**
+ * This <code>WidgetFactory</code> is responsible to create the widgets
+ * using the <code>FormToolkit</code> in order use the form style (flat-style)
+ * look and feel.
+ *
+ * @see FormToolkit
+ *
+ * @version 2.0
+ * @since 2.0
+ */
+@SuppressWarnings("nls")
+public class FormWidgetFactory implements WidgetFactory {
+
+	/**
+	 * The actual factory responsible for creating the new widgets.
+	 */
+	private final FormToolkit widgetFactory;
+
+	/**
+	 * Creates a new <code>FormWidgetFactory</code>.
+	 *
+	 * @param widgetFactory The actual factory responsible for creating the new
+	 * widgets
+	 */
+	public FormWidgetFactory(FormToolkit widgetFactory) {
+		super();
+
+		Assert.isNotNull(widgetFactory, "The widget factory cannot be null");
+		this.widgetFactory = widgetFactory;
+	}
+
+	/**
+	 * Wraps the given <code>Composite</code> into a new <code>Composite</code>
+	 * in order to have the widgets' border painted. Except for <code>CCombo</code>,
+	 * the top and bottom margins have to be 2 pixel and the left and right
+	 * margins have to be 1 pixel.
+	 *
+	 * @param container The parent of the sub-pane
+	 * @return A new <code>Composite</code> that has the necessary space to paint
+	 * the border
+	 */
+	protected Composite createBorderContainer(Composite container) {
+		return createBorderContainer(container, 2, 1);
+	}
+	
+	protected Composite createBorderContainer(Composite container, int marginHeight, int marginWidth) {
+
+		GridLayout layout = new GridLayout(1, false);
+		layout.marginHeight = marginHeight;
+		layout.marginWidth  = marginWidth;
+
+		GridData gridData = new GridData();
+		gridData.horizontalAlignment       = GridData.FILL;
+		gridData.grabExcessHorizontalSpace = true;
+
+		container = widgetFactory.createComposite(container);
+		container.setLayoutData(gridData);
+		container.setLayout(layout);
+
+		return container;
+	}
+	
+	/**
+	 * {@inheritDoc}
+	 */
+	public Button createButton(Composite parent, String text) {
+		return createButton(parent, text, SWT.NULL);
+	}
+
+	/**
+	 * Creates a new button.
+	 *
+	 * @param parent The parent container
+	 * @param text The button's text
+	 * @param style The style to apply to the button, which determines its type:
+	 * toggle, push, check box, radio
+	 * @return The newly created <code>Button</code>
+	 */
+	protected Button createButton(Composite parent, String text, int style) {
+		return widgetFactory.createButton(parent, text, SWT.FLAT | style);
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Deprecated
+	public CCombo createCCombo(Composite parent) {
+		return createCCombo(parent, SWT.READ_ONLY);
+	}
+
+	/**
+	 * Creates a new combo.
+	 *
+	 * @param parent The parent container
+	 * @param style The style to apply to the combo, usually read-only, flat
+	 * @return The newly created <code>CCombo</code>
+	 */
+	protected CCombo createCCombo(Composite parent, int style) {
+		parent = createBorderContainer(parent, 1, 1);
+
+		CCombo combo = new CCombo(parent, style);
+		widgetFactory.adapt(combo, true, false);
+
+		// Bugzilla 145837 - workaround for no borders on Windows XP
+		if (widgetFactory.getBorderStyle() == SWT.BORDER) {
+			combo.setData(FormToolkit.KEY_DRAW_BORDER, FormToolkit.TEXT_BORDER);
+		}
+
+		return combo;
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public Button createCheckBox(Composite parent, String text) {
+		return createButton(parent, text, SWT.CHECK);
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public Combo createCombo(Composite parent) {
+		return new Combo(parent, SWT.READ_ONLY | SWT.FLAT);
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public Composite createComposite(Composite parent) {
+		return this.widgetFactory.createComposite(parent);
+	}
+	/**
+	 * {@inheritDoc}
+	 */
+	public DateTime createDateTime(Composite parent, int style) {
+		parent = createBorderContainer(parent);
+
+		DateTime dateTime = new DateTime(parent, style | SWT.FLAT);
+		dateTime.setData(FormToolkit.KEY_DRAW_BORDER, FormToolkit.TEXT_BORDER);
+		this.widgetFactory.adapt(dateTime, true, false);
+
+		return dateTime;
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Deprecated
+	public CCombo createEditableCCombo(Composite parent) {
+		return createCCombo(parent, SWT.NULL);
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public Combo createEditableCombo(Composite parent) {
+		Combo combo = new Combo(parent, SWT.FLAT);
+		return combo;
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public Group createGroup(Composite parent, String title) {
+		Group group = new Group(parent, SWT.NULL);
+		group.setText(title);
+		return group;
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public Hyperlink createHyperlink(Composite parent, String text) {
+		return widgetFactory.createHyperlink(parent, text, SWT.FLAT);
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public Label createLabel(Composite container, String labelText) {
+		return widgetFactory.createLabel(container, labelText, SWT.WRAP);
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public List createList(Composite container, int style) {
+		List list = new List(container, SWT.FLAT | style);
+		list.setData(FormToolkit.KEY_DRAW_BORDER, FormToolkit.TEXT_BORDER);
+		return list;
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public FormText createMultiLineLabel(Composite parent, String labelText) {
+
+		Composite container = widgetFactory.createComposite(parent, SWT.NONE);
+
+		GridData gridData = new GridData();
+		gridData.horizontalAlignment       = GridData.FILL;
+		gridData.grabExcessHorizontalSpace = true;
+		container.setLayoutData(gridData);
+
+		TableWrapLayout layout = new TableWrapLayout();
+		layout.numColumns   = 1;
+		layout.bottomMargin = 0;
+		layout.leftMargin   = 0;
+		layout.rightMargin  = 0;
+		layout.topMargin    = 0;
+		container.setLayout(layout);
+
+		FormText text = widgetFactory.createFormText(container, true);
+		text.setLayoutData(new TableWrapData(TableWrapData.FILL_GRAB));
+		text.setText(labelText, false, false);
+
+		return text;
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public Text createMultiLineText(Composite parent) {
+		return createText(parent, SWT.MULTI | SWT.V_SCROLL);
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public Text createPasswordText(Composite parent) {
+		return createText(parent, SWT.PASSWORD);
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public Button createPushButton(Composite parent, String text) {
+		return createButton(parent, text, SWT.PUSH);
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public Button createRadioButton(Composite parent, String text) {
+		return createButton(parent, text, SWT.RADIO);
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public Section createSection(Composite parent, int style) {
+		return widgetFactory.createSection(parent, SWT.FLAT | style);
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public Spinner createSpinner(Composite parent) {
+		parent = createBorderContainer(parent);
+
+		Spinner spinner = new Spinner(parent, SWT.FLAT);
+		spinner.setData(FormToolkit.KEY_DRAW_BORDER, FormToolkit.TEXT_BORDER);
+		widgetFactory.adapt(spinner, true, false);
+
+		return spinner;
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public Table createTable(Composite parent, int style) {
+		Table table = this.widgetFactory.createTable(parent, SWT.BORDER | style);
+		table.setData(FormToolkit.KEY_DRAW_BORDER, FormToolkit.TEXT_BORDER);
+		return table;
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public Text createText(Composite parent) {
+		return createText(parent, SWT.NONE);
+	}
+
+	protected Text createText(Composite parent, int style) {
+		return widgetFactory.createText(parent, null, SWT.BORDER | SWT.FLAT | style);
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public Button createTriStateCheckBox(Composite parent, String text) {
+		TriStateCheckBox checkBox = new TriStateCheckBox(parent, text, this);
+		return checkBox.getCheckBox();
+	}
+
+	/**
+	 * Returns the actual factory responsible for creating the new widgets.
+	 *
+	 * @return The factory creating the widgets with the form style (flat-style)
+	 */
+	public FormToolkit getWidgetFactory() {
+		return widgetFactory;
+	}
+}
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/widgets/IntegerCombo.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/widgets/IntegerCombo.java
new file mode 100644
index 0000000..8ec13a8
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/widgets/IntegerCombo.java
@@ -0,0 +1,188 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2010 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.ui.internal.widgets;
+
+import org.eclipse.jface.fieldassist.FieldDecorationRegistry;
+import org.eclipse.jpt.ui.internal.details.JptUiDetailsMessages;
+import org.eclipse.jpt.ui.internal.util.SWTUtil;
+import org.eclipse.jpt.utility.internal.model.value.PropertyListValueModelAdapter;
+import org.eclipse.jpt.utility.internal.model.value.TransformationPropertyValueModel;
+import org.eclipse.jpt.utility.internal.model.value.TransformationWritablePropertyValueModel;
+import org.eclipse.jpt.utility.model.Model;
+import org.eclipse.jpt.utility.model.value.ListValueModel;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.jpt.utility.model.value.WritablePropertyValueModel;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.swt.events.VerifyEvent;
+import org.eclipse.swt.events.VerifyListener;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * This is a replacement for a Spinner.  It is a combo that only accepts integers.
+ * It also includes a Default option in the combo.
+ */
+public abstract class IntegerCombo<T extends Model>
+	extends Pane<T>
+{
+
+	/**
+	 * The main (only) widget of this pane.
+	 */
+	private Combo comboBox;
+
+
+	private PropertyValueModel<String> defaultValueHolder;
+	
+	// ********** constructors **********
+
+	protected IntegerCombo(
+						Pane<? extends T> parentPane,
+						Composite parent
+	) {
+		super(parentPane, parent);
+	}
+
+	protected IntegerCombo(
+						Pane<?> parentPane,
+						PropertyValueModel<? extends T> subjectHolder,
+						Composite parent
+	) {
+		super(parentPane, subjectHolder, parent);
+	}
+
+	public Combo getCombo() {
+		return this.comboBox;
+	}
+	
+	// ********** initialization **********
+
+	@Override
+	protected void initializeLayout(Composite container) {
+		this.defaultValueHolder = buildDefaultStringHolder();
+		this.comboBox = this.addIntegerCombo(container);
+
+		int margin = FieldDecorationRegistry.getDefault().getMaximumDecorationWidth();
+		GridData gridData = new GridData();
+		gridData.horizontalAlignment = GridData.FILL_HORIZONTAL;
+		gridData.horizontalIndent = margin;
+		gridData.grabExcessHorizontalSpace = false;
+		this.comboBox.setLayoutData(gridData);
+		
+		this.comboBox.addVerifyListener(this.buildVerifyListener());
+		SWTUtil.attachDefaultValueHandler(this.comboBox);
+	}
+	
+	protected Combo addIntegerCombo(Composite container) {
+		return this.addLabeledEditableCombo(
+				container,
+				getLabelText(),
+				buildDefaultListHolder(),
+				buildSelectedItemStringHolder(),
+				getHelpId()
+				);
+		
+	}
+	
+	protected VerifyListener buildVerifyListener() {
+		return new VerifyListener() {
+			public void verifyText(VerifyEvent e) {
+				IntegerCombo.this.verifyComboBox(e);
+			}
+		};
+	}
+
+	protected ListValueModel<String> buildDefaultListHolder() {
+		return new PropertyListValueModelAdapter<String>(this.defaultValueHolder);
+	}
+	
+	private PropertyValueModel<String> buildDefaultStringHolder() {
+		return new TransformationPropertyValueModel<Integer, String>(buildDefaultHolder()) {
+			@Override
+			protected String transform(Integer value) {
+				if (value == null) {
+					return JptUiDetailsMessages.NoneSelected;
+				}
+				return super.transform(value);
+			}
+			@Override
+			protected String transform_(Integer value) {
+				return getDefaultValueString(value);
+			}
+		};
+	}
+	
+	private String getDefaultValueString(Integer defaultValue) {
+		return NLS.bind(
+				JptUiDetailsMessages.DefaultWithOneParam,
+				defaultValue
+			);
+	}
+	
+	private String getDefaultValueString() {
+		return this.defaultValueHolder.getValue();
+	}
+
+	protected WritablePropertyValueModel<String> buildSelectedItemStringHolder() {
+		return new TransformationWritablePropertyValueModel<Integer, String>(buildSelectedItemHolder()) {
+			@Override
+			protected String transform(Integer value) {
+				return value == null ? 
+						getDefaultValueString()
+					: 
+						value.toString();
+			}
+			
+			@Override
+			protected Integer reverseTransform_(String value) {
+				int intLength;
+				try {
+					intLength = Integer.parseInt(value);
+				}
+				catch (NumberFormatException e) {
+					//if the default is selected from the combo, set length to null
+					return null;
+				}
+				return Integer.valueOf(intLength);
+			}
+		};
+	}
+
+	// ********** abstract methods **********
+	
+	protected abstract String getLabelText();
+	
+	protected abstract String getHelpId();
+
+	protected abstract PropertyValueModel<Integer> buildDefaultHolder();
+	
+	protected abstract WritablePropertyValueModel<Integer> buildSelectedItemHolder();
+
+	// ********** combo-box verify listener callback **********
+
+	protected void verifyComboBox(VerifyEvent e) {
+		if (e.character == '\b') {
+			//ignore backspace
+			return;
+		}
+		if (e.text.equals("") //DefaultValueHandler sets the text to "" //$NON-NLS-1$
+				|| e.text.equals(this.defaultValueHolder.getValue())) { 
+			return;
+		}
+		try {
+			Integer.parseInt(e.text);
+		}
+		catch (NumberFormatException exception) {
+			e.doit = false;
+		}
+	}
+
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/widgets/NewNameDialog.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/widgets/NewNameDialog.java
new file mode 100644
index 0000000..3fb83f8
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/widgets/NewNameDialog.java
@@ -0,0 +1,166 @@
+/*******************************************************************************
+ * Copyright (c) 2008 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.ui.internal.widgets;
+
+import java.util.Collection;
+import org.eclipse.jpt.utility.internal.model.value.PropertyAspectAdapter;
+import org.eclipse.jpt.utility.model.value.WritablePropertyValueModel;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Text;
+
+/**
+ * The dialog used to requests a name from the user.
+ *
+ * @version 2.0
+ * @since 2.0
+ */
+public class NewNameDialog extends ValidatingDialog<NewNameStateObject>
+{
+	private String description;
+	private Image descriptionImage;
+	private String descriptionTitle;
+	private String labelText;
+	private String name;
+	private Collection<String> names;
+
+	/**
+	 * Creates a new <code>NewNameDialog</code>.
+	 *
+	 * @param parentShell
+	 * @param dialogTitle
+	 * @param descriptionTitle
+	 * @param descriptionImage
+	 * @param description
+	 * @param labelText
+	 * @param name
+	 * @param names
+	 */
+	NewNameDialog(Shell parentShell,
+	              String dialogTitle,
+	              String descriptionTitle,
+	              Image descriptionImage,
+	              String description,
+	              String labelText,
+	              String name,
+	              Collection<String> names)
+	{
+		super(parentShell, dialogTitle);
+
+		this.name             = name;
+		this.names            = names;
+		this.labelText        = labelText;
+		this.description      = description;
+		this.descriptionImage = descriptionImage;
+		this.descriptionTitle = descriptionTitle;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 */
+	@Override
+	protected DialogPane<NewNameStateObject> buildLayout(Composite container) {
+		return new NewNameDialogPane(container);
+	}
+
+	/*
+	 * (non-Javadoc)
+	 */
+	@Override
+	protected NewNameStateObject buildStateObject() {
+		return new NewNameStateObject(name, names);
+	}
+
+	/*
+	 * (non-Javadoc)
+	 */
+	@Override
+	public void create() {
+		super.create();
+
+		NewNameDialogPane pane = (NewNameDialogPane) getPane();
+		pane.selectAll();
+
+		getButton(OK).setEnabled(false);
+	}
+
+	/*
+	 * (non-Javadoc)
+	 */
+	@Override
+	protected String getDescription() {
+		return description;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 */
+	@Override
+	protected Image getDescriptionImage() {
+		return descriptionImage;
+	}
+
+	/* (non-Javadoc)
+	 */
+	@Override
+	protected String getDescriptionTitle() {
+		return descriptionTitle;
+	}
+
+	/**
+	 * Returns the text field's input, which is the new name the user entered.
+	 *
+	 * @return The name the user entered
+	 */
+	public String getName() {
+		return getSubject().getName();
+	}
+
+	private class NewNameDialogPane extends DialogPane<NewNameStateObject> {
+
+		private Text text;
+
+		NewNameDialogPane(Composite parent) {
+			super(NewNameDialog.this.getSubjectHolder(), parent);
+		}
+
+		private WritablePropertyValueModel<String> buildNameHolder() {
+			return new PropertyAspectAdapter<NewNameStateObject, String>(getSubjectHolder(), NewNameStateObject.NAME_PROPERTY) {
+				@Override
+				protected String buildValue_() {
+					return subject.getName();
+				}
+
+				@Override
+				protected void setValue_(String value) {
+					subject.setName(value);
+				}
+			};
+		}
+
+		/*
+		 * (non-Javadoc)
+		 */
+		@Override
+		protected void initializeLayout(Composite container) {
+
+			text = addLabeledText(
+				container,
+				labelText,
+				buildNameHolder()
+			);
+		}
+
+		void selectAll() {
+			text.selectAll();
+		}
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/widgets/NewNameDialogBuilder.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/widgets/NewNameDialogBuilder.java
new file mode 100644
index 0000000..1a4024e
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/widgets/NewNameDialogBuilder.java
@@ -0,0 +1,179 @@
+/*******************************************************************************
+ * Copyright (c) 2008 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.ui.internal.widgets;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.jpt.utility.internal.CollectionTools;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Shell;
+
+/**
+ * This builder is responsible to create a fully initialized
+ * <code>NewNameDialog</code> once all the properties have been set.
+ *
+ * @see NewNameDialog
+ *
+ * @version 2.0
+ * @since 2.0
+ */
+@SuppressWarnings("nls")
+public final class NewNameDialogBuilder {
+
+	/**
+	 * The message to show in the description area.
+	 */
+	private String description;
+
+	/**
+	 * The image of the description area.
+	 */
+	private Image descriptionImage;
+
+	/**
+	 * The title to show in the description area.
+	 */
+	private String descriptionTitle;
+
+	/**
+	 * The title of the new name dialog.
+	 */
+	private String dialogTitle;
+
+	/**
+	 * The text field's label.
+	 */
+	private String labelText;
+
+	/**
+	 * The initial input or <code>null</code> if no initial value can be
+	 * specified.
+	 */
+	private String name;
+
+	/**
+	 * The collection of names that can't be used or an empty collection if none
+	 * are available.
+	 */
+	private Collection<String> names;
+
+	/**
+	 * The parent shell of the new name dialog.
+	 */
+	private Shell parentShell;
+
+	/**
+	 * Creates a new <code>NewNameDialogBuilder</code>.
+	 *
+	 * @param parentShell The parent shell of the new name dialog
+	 */
+	public NewNameDialogBuilder(Shell parentShell) {
+		super();
+		initialize(parentShell);
+	}
+
+	/**
+	 * Creates the dialog that will be used to request a new name from the user.
+	 *
+	 * @return The initialized dialog
+	 */
+	public NewNameDialog buildDialog() {
+		return new NewNameDialog(
+			parentShell,
+			dialogTitle,
+			descriptionTitle,
+			descriptionImage,
+			description,
+			labelText,
+			name,
+			names
+		);
+	}
+
+	/**
+	 * Initializes this builder.
+	 *
+	 * @param parentShell The parent shell of the new name dialog
+	 */
+	protected void initialize(Shell parentShell) {
+
+		Assert.isNotNull(parentShell, "The parent shell cannot be null");
+
+		this.parentShell = parentShell;
+		this.names       = Collections.emptyList();
+	}
+
+	/**
+	 * Sets the description to be shown in the description area under the title.
+	 *
+	 * @param description The message to show in the description area
+	 */
+	public void setDescription(String description) {
+		this.description = description;
+	}
+
+	/**
+	 * Sets the image to be shown to the right side of the description area.
+	 *
+	 * @param descriptionImage The image of the description area
+	 */
+	public void setDescriptionImage(Image descriptionImage) {
+		this.descriptionImage = descriptionImage;
+	}
+
+	/**
+	 * Sets the title to be shown in the description area.
+	 *
+	 * @param descriptionTitle The title to show in the description area
+	 */
+	public void setDescriptionTitle(String descriptionTitle) {
+		this.descriptionTitle = descriptionTitle;
+	}
+
+	/**
+	 * Sets the dialog's title.
+	 *
+	 * @param dialogTitle The title of the new name dialog
+	 */
+	public void setDialogTitle(String dialogTitle) {
+		this.dialogTitle = dialogTitle;
+	}
+
+	/**
+	 * Sets the existing names that will be used to validate the text field's
+	 * input and prevent the user from using it.
+	 *
+	 * @param names The collection of names that can't be used
+	 */
+	public void setExistingNames(Iterator<String> names) {
+		this.names = CollectionTools.collection(names);
+	}
+
+	/**
+	 * Sets the text to label the text field.
+	 *
+	 * @param labelText The text field's label
+	 */
+	public void setLabelText(String labelText) {
+		this.labelText = labelText;
+	}
+
+	/**
+	 * Sets the initial name if one exists. It is valid to leave this
+	 * <code>null</code> when the user has to enter something.
+	 *
+	 * @param name The initial input
+	 */
+	public void setName(String name) {
+		this.name = name;
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/widgets/NewNameStateObject.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/widgets/NewNameStateObject.java
new file mode 100644
index 0000000..b825255
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/widgets/NewNameStateObject.java
@@ -0,0 +1,145 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2009 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.ui.internal.widgets;
+
+import java.util.Collection;
+import java.util.List;
+import org.eclipse.jpt.ui.internal.details.JptUiDetailsMessages;
+import org.eclipse.jpt.utility.internal.StringTools;
+import org.eclipse.jpt.utility.internal.node.AbstractNode;
+import org.eclipse.jpt.utility.internal.node.Node;
+import org.eclipse.jpt.utility.internal.node.Problem;
+
+/**
+ * This is the state object used by the <code>NewNameDialog</code>, which stores
+ * the current name and validates it when it is modified.
+ *
+ * @see NewNameDialog
+ *
+ * @version 2.0
+ * @since 2.0
+ */
+@SuppressWarnings("nls")
+final class NewNameStateObject extends AbstractNode
+{
+	/**
+	 * The initial input or <code>null</code> if no initial value can be
+	 * specified.
+	 */
+	private String name;
+
+	/**
+	 * The collection of names that can't be used or an empty collection if none
+	 * are available.
+	 */
+	private Collection<String> names;
+
+	/**
+	 * The <code>Validator</code> used to validate this state object.
+	 */
+	private Validator validator;
+
+	/**
+	 * Notifies a change in the name property.
+	 */
+	static final String NAME_PROPERTY = "name";
+
+	/**
+	 * Creates a new <code>NewNameStateObject</code>.
+	 *
+	 * @param name The initial input or <code>null</code> if no initial value can
+	 * be specified
+	 * @param names The collection of names that can't be used or an empty
+	 * collection if none are available
+	 */
+	NewNameStateObject(String name, Collection<String> names) {
+		super(null);
+
+		this.name  = name;
+		this.names = names;
+	}
+
+	/**
+	 * Validates the name property.
+	 *
+	 * @param currentProblems The list to which <code>Problem</code>s can be
+	 * added
+	 */
+	private void addNameProblems(List<Problem> currentProblems) {
+
+		if (StringTools.stringIsEmpty(name)) {
+			currentProblems.add(buildProblem(JptUiDetailsMessages.NewNameStateObject_nameMustBeSpecified));
+		}
+		else if (names.contains(name.trim())) {
+			currentProblems.add(buildProblem(JptUiDetailsMessages.NewNameStateObject_nameAlreadyExists));
+		}
+	}
+
+	/*
+	 * (non-Javadoc)
+	 */
+	@Override
+	protected void addProblemsTo(List<Problem> currentProblems)
+	{
+		super.addProblemsTo(currentProblems);
+		addNameProblems(currentProblems);
+	}
+
+	/*
+	 * (non-Javadoc)
+	 */
+	@Override
+	protected void checkParent(Node parentNode) {
+	}
+
+	/*
+	 * (non-Javadoc)
+	 */
+	public String displayString() {
+		return null;
+	}
+
+	/**
+	 * Returns the current name stored in this state object.
+	 *
+	 * @return The current name or <code>null</code>
+	 */
+	String getName() {
+		return name;
+	}
+
+	/**
+	 * Sets the current name stored in this state object or <code>null</code> to
+	 * clear it.
+	 *
+	 * @param name The new name or <code>null</code>
+	 */
+	public void setName(String name) {
+		String oldName = this.name;
+		this.name = name;
+		firePropertyChanged(NAME_PROPERTY, oldName, name);
+	}
+
+	/*
+	 * (non-Javadoc)
+	 */
+	@Override
+	public void setValidator(Validator validator) {
+		this.validator = validator;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 */
+	@Override
+	public Validator getValidator() {
+		return validator;
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/widgets/NullPostExecution.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/widgets/NullPostExecution.java
new file mode 100644
index 0000000..1f5edba
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/widgets/NullPostExecution.java
@@ -0,0 +1,56 @@
+/*******************************************************************************
+ * Copyright (c) 2008 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.ui.internal.widgets;
+
+import org.eclipse.jface.dialogs.Dialog;
+
+/**
+ * A <code>null</code> instance of <code>PostExecution</code>.
+ *
+ * @version 2.0
+ * @since 1.0
+ */
+public final class NullPostExecution implements PostExecution<Dialog> {
+
+	/**
+	 * The singleton instance of this <code>NullPostExecution</code>.
+	 */
+	private static PostExecution<Dialog> INSTANCE;
+
+	/**
+	 * Creates a new <code>NullPostExecution</code>.
+	 */
+	private NullPostExecution() {
+		super();
+	}
+
+	/**
+	 * Returns the singleton instance of this <code>NullPostExecution</code>.
+	 *
+	 * @param <T> The dialog where this <code>PostExecution</code> will be used
+	 * @return The singleton instance with the proper type
+	 */
+	@SuppressWarnings("unchecked")
+	public static synchronized <T extends Dialog> PostExecution<T> instance() {
+
+		if (INSTANCE == null) {
+			INSTANCE = new NullPostExecution();
+		}
+
+		return (PostExecution<T>) INSTANCE;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 */
+	public void execute(Dialog dialog) {
+		// Nothing to do
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/widgets/PackageChooserPane.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/widgets/PackageChooserPane.java
new file mode 100644
index 0000000..860b1c0
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/widgets/PackageChooserPane.java
@@ -0,0 +1,237 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2010 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.ui.internal.widgets;
+
+import org.eclipse.jdt.core.IPackageFragment;
+import org.eclipse.jdt.core.IPackageFragmentRoot;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.internal.ui.refactoring.contentassist.ControlContentAssistHelper;
+import org.eclipse.jdt.internal.ui.refactoring.contentassist.JavaPackageCompletionProcessor;
+import org.eclipse.jdt.ui.JavaElementLabelProvider;
+import org.eclipse.jdt.ui.JavaUI;
+import org.eclipse.jface.fieldassist.FieldDecorationRegistry;
+import org.eclipse.jface.window.Window;
+import org.eclipse.jpt.core.JpaProject;
+import org.eclipse.jpt.core.internal.utility.jdt.JDTTools;
+import org.eclipse.jpt.ui.JptUiPlugin;
+import org.eclipse.jpt.ui.internal.JptUiMessages;
+import org.eclipse.jpt.ui.internal.listeners.SWTPropertyChangeListenerWrapper;
+import org.eclipse.jpt.utility.model.Model;
+import org.eclipse.jpt.utility.model.event.PropertyChangeEvent;
+import org.eclipse.jpt.utility.model.listener.PropertyChangeListener;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.jpt.utility.model.value.WritablePropertyValueModel;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.ui.dialogs.SelectionDialog;
+
+/**
+ * This chooser allows the user to choose a package when browsing and it adds
+ * code completion support to the text field, which is the main component.
+ * <p>
+ * Here the layout of this pane:
+ * <pre>
+ * -----------------------------------------------------------------------------
+ * |       !---------------------------------------------------- ------------- |
+ * | Label: | I                                                | | Browse... | |
+ * |        ---------------------------------------------------- ------------- |
+ * -----------------------------------------------------------------------------</pre>
+ *
+ * @version 2.0
+ * @since 2.0
+ */
+public abstract class PackageChooserPane<T extends Model> extends ChooserPane<T>
+{
+	/**
+	 * The code completion manager.
+	 */
+	private JavaPackageCompletionProcessor javaPackageCompletionProcessor;
+
+	private PropertyChangeListener subjectChangeListener;
+
+	/**
+	 * Creates a new <code>PackageChooserPane</code>.
+	 *
+	 * @param parentPane The parent pane of this one
+	 * @param parent The parent container
+	 */
+	public PackageChooserPane(Pane<? extends T> parentPane,
+	                          Composite parent) {
+
+		super(parentPane, parent);
+	}
+
+	/**
+	 * Creates a new <code>PackageChooserPane</code>.
+	 *
+	 * @param parentPane The parent container of this one
+	 * @param subjectHolder The holder of this pane's subject
+	 * @param parent The parent container
+	 */
+	public PackageChooserPane(Pane<?> parentPane,
+	                          PropertyValueModel<? extends T> subjectHolder,
+	                          Composite parent) {
+
+		super(parentPane, subjectHolder, parent);
+	}
+
+	@Override
+	protected void initialize() {
+		super.initialize();
+
+		// TODO bug 156185 - when this is fixed there should be api for this
+		this.javaPackageCompletionProcessor = new JavaPackageCompletionProcessor(
+			new JavaElementLabelProvider(JavaElementLabelProvider.SHOW_ROOT)
+		);
+		this.subjectChangeListener = this.buildSubjectChangeListener();
+		this.getSubjectHolder().addPropertyChangeListener(PropertyValueModel.VALUE, this.subjectChangeListener);
+		this.packageChooserSubjectChanged(getSubject());
+	}
+
+	private PropertyChangeListener buildSubjectChangeListener() {
+		return new SWTPropertyChangeListenerWrapper(this.buildSubjectChangeListener_());
+	}
+
+	private PropertyChangeListener buildSubjectChangeListener_() {
+		return new PropertyChangeListener() {
+			@SuppressWarnings("unchecked")
+			public void propertyChanged(PropertyChangeEvent e) {
+				PackageChooserPane.this.packageChooserSubjectChanged((T) e.getNewValue());
+			}
+		};
+	}
+
+	protected void packageChooserSubjectChanged(T newSubject) {
+		IPackageFragmentRoot root = null;
+		if (newSubject != null) {
+			root = getPackageFragmentRoot();
+		}
+		this.javaPackageCompletionProcessor.setPackageFragmentRoot(root);
+	}
+
+	@Override
+	protected final Runnable buildBrowseAction() {
+		return new Runnable() {
+			public void run() {
+				promptPackage();
+			}
+		};
+	}
+
+	@Override
+	protected Control addMainControl(Composite container) {
+		Composite subPane = addSubPane(container);
+
+		Text text = addText(subPane, buildTextHolder());
+
+		Image image = FieldDecorationRegistry.getDefault().getFieldDecoration(FieldDecorationRegistry.DEC_CONTENT_PROPOSAL).getImage();
+		GridData data = new GridData(GridData.FILL_HORIZONTAL);
+		data.horizontalIndent = image.getBounds().width;
+		text.setLayoutData(data);
+
+		ControlContentAssistHelper.createTextContentAssistant(
+			text,
+			javaPackageCompletionProcessor
+		);
+
+		return subPane;
+	}
+
+	/**
+	 * Creates the value holder of the subject's property.
+	 *
+	 * @return The holder of the package name
+	 */
+	protected abstract WritablePropertyValueModel<String> buildTextHolder();
+
+	/**
+	 * Prompts the user the Open Package dialog.
+	 *
+	 * @return Either the selected package or <code>null</code> if the user
+	 * cancelled the dialog
+	 */
+	protected IPackageFragment choosePackage() {
+
+		SelectionDialog selectionDialog;
+
+		try {
+			selectionDialog = JavaUI.createPackageDialog(
+				getShell(),
+				getPackageFragmentRoot()
+			);
+		}
+		catch (JavaModelException e) {
+			JptUiPlugin.log(e);
+			return null;
+		}
+
+		selectionDialog.setTitle(JptUiMessages.ClassChooserPane_dialogTitle);
+		selectionDialog.setMessage(JptUiMessages.ClassChooserPane_dialogMessage);
+
+		IPackageFragment pack = getPackageFragment();
+
+		if (pack != null) {
+			selectionDialog.setInitialSelections(new Object[] { pack });
+		}
+
+		if (selectionDialog.open() == Window.OK) {
+			return (IPackageFragment) selectionDialog.getResult()[0];
+		}
+
+		return null;
+	}
+
+	protected abstract JpaProject getJpaProject();
+
+	/**
+	 * Returns the package name from its subject.
+	 *
+	 * @return The package name or <code>null</code> if none is defined
+	 */
+	protected abstract String getPackageName();
+
+	/**
+	 * The browse button was clicked, its action invokes this action which should
+	 * prompt the user to select a package and set it.
+	 */
+	protected void promptPackage() {
+		IPackageFragment packageFragment = choosePackage();
+
+		if (packageFragment != null) {
+			String packageName = packageFragment.getElementName();
+			this.setPackageName(packageName);
+		}
+	}
+	
+	protected abstract void setPackageName(String packageName);
+
+	private IPackageFragment getPackageFragment() {
+		String packageName = getPackageName();
+
+		if (packageName == null) {
+			return null;
+		}
+
+		return getPackageFragmentRoot().getPackageFragment(packageName);
+	}
+
+	protected IPackageFragmentRoot getPackageFragmentRoot() {
+		return JDTTools.getCodeCompletionContextRoot(getJpaProject().getJavaProject());
+	}
+
+	@Override
+	public void dispose() {
+		this.getSubjectHolder().removePropertyChangeListener(PropertyValueModel.VALUE, this.subjectChangeListener);
+		super.dispose();
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/widgets/Pane.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/widgets/Pane.java
new file mode 100644
index 0000000..2aed9c5
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/widgets/Pane.java
@@ -0,0 +1,3732 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2010 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.ui.internal.widgets;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.fieldassist.FieldDecorationRegistry;
+import org.eclipse.jface.viewers.ComboViewer;
+import org.eclipse.jface.viewers.IBaseLabelProvider;
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.jpt.ui.WidgetFactory;
+import org.eclipse.jpt.ui.internal.Tracing;
+import org.eclipse.jpt.ui.internal.listeners.SWTPropertyChangeListenerWrapper;
+import org.eclipse.jpt.ui.internal.swt.ComboModelAdapter;
+import org.eclipse.jpt.ui.internal.swt.DateTimeModelAdapter;
+import org.eclipse.jpt.ui.internal.swt.SpinnerModelAdapter;
+import org.eclipse.jpt.ui.internal.swt.TriStateCheckBoxModelAdapter;
+import org.eclipse.jpt.ui.internal.util.ControlAligner;
+import org.eclipse.jpt.ui.internal.util.LabeledButton;
+import org.eclipse.jpt.ui.internal.util.LabeledControlUpdater;
+import org.eclipse.jpt.ui.internal.util.SWTUtil;
+import org.eclipse.jpt.ui.internal.utility.swt.SWTTools;
+import org.eclipse.jpt.utility.internal.NonNullBooleanTransformer;
+import org.eclipse.jpt.utility.internal.StringConverter;
+import org.eclipse.jpt.utility.internal.model.value.CompositeBooleanPropertyValueModel;
+import org.eclipse.jpt.utility.internal.model.value.SimplePropertyValueModel;
+import org.eclipse.jpt.utility.internal.model.value.TransformationPropertyValueModel;
+import org.eclipse.jpt.utility.model.Model;
+import org.eclipse.jpt.utility.model.event.PropertyChangeEvent;
+import org.eclipse.jpt.utility.model.listener.PropertyChangeListener;
+import org.eclipse.jpt.utility.model.value.ListValueModel;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.jpt.utility.model.value.WritablePropertyValueModel;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.events.MouseAdapter;
+import org.eclipse.swt.events.MouseEvent;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.DateTime;
+import org.eclipse.swt.widgets.Group;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Layout;
+import org.eclipse.swt.widgets.List;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Spinner;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.forms.widgets.ExpandableComposite;
+import org.eclipse.ui.forms.widgets.FormText;
+import org.eclipse.ui.forms.widgets.Hyperlink;
+import org.eclipse.ui.forms.widgets.Section;
+import org.eclipse.ui.help.IWorkbenchHelpSystem;
+import org.eclipse.ui.part.PageBook;
+
+/**
+ * The abstract definition of a pane which holds onto a <code>PropertyValueModel</code>
+ * that contains the subject of this pane.
+ * <p>
+ * It also contains convenience methods for building buttons, labels, check
+ * boxes, and radio buttons, etc.
+ * <p>
+ * It is possible to easily listen to any property changes coming from the
+ * subject, {@link #addPropertyNames(Collection)} is specify which properties
+ * are of interest and {@link #propertyChanged(String)} is used to notify the
+ * pane when the property has changed.
+ *
+ * @see FormPane
+ * @see DialogPane
+ *
+ * @version 2.0
+ * @since 2.0
+ */
+@SuppressWarnings("nls")
+public abstract class Pane<T extends Model>
+{
+	/**
+	 * The listener registered with the subject in order to be notified when a
+	 * property has changed, the property names are determined by
+	 * {@link #propertyNames()}.
+	 */
+	private PropertyChangeListener aspectChangeListener;
+
+	/**
+	 * The container of this composite.
+	 */
+	private Composite container;
+
+	/**
+	 * The aligner responsible to align the left controls.
+	 */
+	private ControlAligner leftControlAligner;
+
+	/**
+	 * Flag used to stop the circular population of widgets.
+	 */
+	private boolean populating;
+
+	/**
+	 * The aligner responsible to align the left controls.
+	 */
+	private ControlAligner rightControlAligner;
+
+	/**
+	 * This listener is registered with the subject holder in order to
+	 * automatically repopulate this pane with the new subject.
+	 */
+	private PropertyChangeListener subjectChangeListener;
+
+	/**
+	 * The subject of this pane.
+	 */
+	private PropertyValueModel<T> subjectHolder;
+
+	/**
+	 * The collection of registered sub-panes will be automatically notified
+	 * when listeners need to be engaged or disengaged or when to populate its
+	 * widgets.
+	 */
+	private Collection<Pane<?>> subPanes;
+
+	/**
+	 * The factory used to create various common widgets.
+	 */
+	private WidgetFactory widgetFactory;
+
+	/**
+	 * The collection of <code>Control</code>s that are displayed in this pane,
+	 * which will have their enablement state updated when
+	 * {@link #enableWidgets(boolean)} is called.
+	 */
+	private ArrayList<Control> managedWidgets;
+	
+	/**
+	 * The collection of <code>Pane</code>s that are displayed in this pane,
+	 * which will have their enablement state updated when
+	 * {@link #enableWidgets(boolean)} is called.
+	 */
+	private ArrayList<Pane<?>> managedSubPanes;
+	
+	/**
+	 * This enabled model is used to store the pane's base enablement state.
+	 * If API is called to set the pane enabled, this model gets updated.  If the pane is thereby
+	 * fully enabled (controller enabled model is also in agreement) the pane's widgets are set
+	 * enabled.
+	 * @see #getCombinedEnabledModel()
+	 */
+	private final WritablePropertyValueModel<Boolean> baseEnabledModel 
+			= new SimplePropertyValueModel<Boolean>(Boolean.TRUE);
+	
+	/**
+	 * This enabled model is used to define the pane's enablement as controlled by other widgets,
+	 * tests, etc. (for example a radio button)
+	 * If this model is changed, and the pane is thereby fully enabled (base enabled model is also 
+	 * in agreement) the pane's widgets are set enabled.
+	 * @see #getCombinedEnabledModel()
+	 */
+	private PropertyValueModel<Boolean> controllerEnabledModel;
+	
+	/**
+	 * The "and" combination of {@link #baseEnabledModel} and {@link #controllerEnabledModel}
+	 */
+	private PropertyValueModel<Boolean> combinedEnabledModel;
+	
+	private PropertyChangeListener combinedEnabledModelListener;
+	
+	/**
+	 * Creates a new <code>Pane</code>.
+	 *
+	 * @category Constructor
+	 */
+	@SuppressWarnings("unused")
+	private Pane() {
+		super();
+	}
+
+	/**
+	 * Creates a new <code>Pane</code>.
+	 *
+	 * @param parentPane The parent pane of this one
+	 * @param parent The parent container
+	 *
+	 * @category Constructor
+	 */
+	protected Pane(
+			Pane<? extends T> parentPane,
+	        Composite parent) {
+		
+		this(parentPane, parent, true);
+	}
+
+	/**
+	 * Creates a new <code>Pane</code>.
+	 *
+	 * @param parentPane The parent container of this one
+	 * @param parent The parent container
+	 * @param widgetFactory The factory used to create various widgets
+	 * @param automaticallyAlignWidgets <code>true</code> to make the widgets
+	 * this pane aligned with the widgets of the given parent pane;
+	 * <code>false</code> to not align them
+	 *
+	 * @category Constructor
+	 */
+	protected Pane(
+			Pane<? extends T> parentPane,
+	        Composite parent,
+	        boolean automaticallyAlignWidgets) {
+		
+		this(
+			parentPane,
+			parentPane.getSubjectHolder(),
+			parent,
+			automaticallyAlignWidgets);
+	}
+
+	/**
+	 * Creates a new <code>Pane</code>.
+	 *
+	 * @param parentPane The parent container of this one
+	 * @param parent The parent container
+	 * @param widgetFactory The factory used to create various widgets
+	 * @param automaticallyAlignWidgets <code>true</code> to make the widgets
+	 * this pane aligned with the widgets of the given parent pane;
+	 * <code>false</code> to not align them
+	 *
+	 * @category Constructor
+	 */
+	protected Pane(
+			Pane<? extends T> parentPane,
+	        Composite parent,
+	        boolean automaticallyAlignWidgets,
+	        boolean parentManagePane) {
+		
+		this(
+			parentPane,
+			parentPane.getSubjectHolder(),
+			parent,
+			automaticallyAlignWidgets,
+			parentManagePane);
+	}
+
+	/**
+	 * Creates a new <code>Pane</code>.
+	 *
+	 * @param parentPane The parent container of this one
+	 * @param subjectHolder The holder of this pane's subject
+	 * @param parent The parent container
+	 *
+	 * @category Constructor
+	 */
+	protected Pane(
+			Pane<?> parentPane,
+	        PropertyValueModel<? extends T> subjectHolder,
+	        Composite parent) {
+		
+		this(parentPane, subjectHolder, parent, true);
+	}
+	
+	protected Pane(
+			Pane<?> parentPane,
+	        PropertyValueModel<? extends T> subjectHolder,
+	        Composite parent,
+	        PropertyValueModel<Boolean> enabledModel) {
+		
+		this(parentPane, subjectHolder, parent, true, enabledModel);
+	}
+
+	/**
+	 * Creates a new <code>Pane</code>.
+	 *
+	 * @param parentPane The parent container of this one
+	 * @param subjectHolder The holder of this pane's subject
+	 * @param parent The parent container
+	 * @param widgetFactory The factory used to create various widgets
+	 * @param automaticallyAlignWidgets <code>true</code> to make the widgets
+	 * this pane aligned with the widgets of the given parent pane;
+	 * <code>false</code> to not align them
+	 *
+	 * @category Constructor
+	 */
+	protected Pane(
+			Pane<?> parentPane,
+			PropertyValueModel<? extends T> subjectHolder,
+			Composite parent,
+			boolean automaticallyAlignWidgets) {
+		
+		this(parentPane, subjectHolder, parent, automaticallyAlignWidgets, true);
+	}
+	
+	protected Pane(
+			Pane<?> parentPane,
+			PropertyValueModel<? extends T> subjectHolder,
+			Composite parent,
+			boolean automaticallyAlignWidgets,
+			PropertyValueModel<Boolean> enabledModel) {
+		
+		this(parentPane, subjectHolder, parent, automaticallyAlignWidgets, true, enabledModel);
+	}
+	
+	/**
+	 * Creates a new <code>Pane</code>.
+	 *
+	 * @param parentPane The parent container of this one
+	 * @param subjectHolder The holder of this pane's subject
+	 * @param parent The parent container
+	 * @param widgetFactory The factory used to create various widgets
+	 * @param automaticallyAlignWidgets <code>true</code> to make the widgets
+	 * this pane aligned with the widgets of the given parent pane;
+	 * <code>false</code> to not align them
+	 * @param parentManagePane <code>true</code> to have the parent pane manage
+	 * the enabled state of this pane
+	 *
+	 * @category Constructor
+	 */
+	protected Pane(
+			Pane<?> parentPane,
+			PropertyValueModel<? extends T> subjectHolder,
+			Composite parent,
+			boolean automaticallyAlignWidgets, 
+			boolean parentManagePane) {
+		
+		this(subjectHolder, parent, parentPane.getWidgetFactory());
+		this.initialize(parentPane, automaticallyAlignWidgets, parentManagePane);
+	}
+	
+	protected Pane(
+			Pane<?> parentPane,
+			PropertyValueModel<? extends T> subjectHolder,
+			Composite parent,
+			boolean automaticallyAlignWidgets, 
+			boolean parentManagePane,
+			PropertyValueModel<Boolean> enabledModel) {
+		
+		this(subjectHolder, parent, parentPane.getWidgetFactory());
+		this.initialize(parentPane, automaticallyAlignWidgets, parentManagePane);
+		this.initializeEnabledModel(enabledModel);
+	}
+	
+	/**
+	 * Creates a new <code>Pane</code>.
+	 *
+	 * @param subjectHolder The holder of this pane's subject
+	 * @param parent The parent container
+	 * @param widgetFactory The factory used to create various common widgets
+	 *
+	 * @category Constructor
+	 */
+	protected Pane(
+			PropertyValueModel<? extends T> subjectHolder,
+			Composite parent,
+			WidgetFactory widgetFactory) {
+		
+		super();
+		this.initialize(subjectHolder, widgetFactory);
+		this.container = this.addContainer(parent);
+		this.initializeLayout(this.container);
+		this.engageSubjectHolder();
+		this.engageListeners(getSubject());
+		this.populate();
+	}
+
+
+	// ********** initialization **********
+
+	@SuppressWarnings("unchecked")
+	private void initialize(
+			PropertyValueModel<? extends T> subjectHolder,
+	        WidgetFactory widgetFactory) {
+		
+		Assert.isNotNull(subjectHolder, "The subject holder cannot be null");
+
+		this.subjectHolder         = (PropertyValueModel<T>) subjectHolder;
+		this.widgetFactory         = widgetFactory;
+		this.subPanes              = new ArrayList<Pane<?>>();
+		this.managedWidgets        = new ArrayList<Control>();
+		this.managedSubPanes       = new ArrayList<Pane<?>>();
+		this.leftControlAligner    = new ControlAligner();
+		this.rightControlAligner   = new ControlAligner();
+		this.subjectChangeListener = this.buildSubjectChangeListener();
+		this.aspectChangeListener  = this.buildAspectChangeListener();
+		
+		this.initialize();
+	}
+
+	protected void initialize() {
+		// do nothing by default
+	}
+
+	/**
+	 * Registers this pane with the parent pane.
+	 *
+	 * @param parentPane The parent pane
+	 * @param automaticallyAlignWidgets <code>true</code> to make the widgets
+	 * this pane aligned with the widgets of the given parent pane;
+	 * <code>false</code> to not align them
+	 * @param parentManagePane <code>true</code> to have the parent pane manage
+	 * the enabled state of this pane
+	 *
+	 * @category Initialization
+	 */
+	private void initialize(
+			Pane<?> parentPane,
+			boolean automaticallyAlignWidgets,
+	        boolean parentManagePane) {
+		
+		// Register this pane with the parent pane, it will call the methods
+		// automatically (engageListeners(), disengageListeners(), populate(),
+		// dispose(), etc)
+		parentPane.registerSubPane(this);
+		
+		if (parentManagePane) {
+			parentPane.manageSubPane(this);
+		}
+		
+		// Align the left and right controls with the controls from the parent
+		// pane
+		if (automaticallyAlignWidgets) {
+			parentPane.addAlignLeft(this);
+			parentPane.addAlignRight(this);
+		}
+	}
+	
+	private void initializeEnabledModel(PropertyValueModel<Boolean> enabledModel) {
+		this.controllerEnabledModel = enabledModel;
+		this.combinedEnabledModel = 
+				CompositeBooleanPropertyValueModel.and(this.baseEnabledModel, this.controllerEnabledModel);
+		this.combinedEnabledModelListener = buildCombinedEnabledModelListener();
+		this.combinedEnabledModel.addPropertyChangeListener(
+				PropertyValueModel.VALUE, this.combinedEnabledModelListener);
+		enableWidgets_(getCombinedEnablement());
+	}
+	
+	private PropertyChangeListener buildCombinedEnabledModelListener() {
+		return new SWTPropertyChangeListenerWrapper(buildControllerEnabledModelListener_());
+	}
+	
+	private PropertyChangeListener buildControllerEnabledModelListener_() {
+		return new PropertyChangeListener() {
+			@SuppressWarnings("unchecked")
+			public void propertyChanged(PropertyChangeEvent e) {
+				Pane.this.controllerEnablementChanged();
+			}
+		};
+	}
+	
+	/**
+	 * Initializes the layout of this pane.
+	 *
+	 * @param container The parent container
+	 *
+	 * @category Layout
+	 */
+	protected abstract void initializeLayout(Composite container);
+
+	private void manageWidget(Control control) {
+		if (this.managedWidgets.contains(control)) {
+			throw new IllegalStateException();
+		}
+		this.managedWidgets.add(control);
+	}
+	
+	private void manageSubPane(Pane<?> subPane) {
+		if (this.managedSubPanes.contains(subPane)) {
+			throw new IllegalStateException();
+		}
+		this.managedSubPanes.add(subPane);
+	}
+
+	/**
+	 * Adds the given pane's widgets (those that were registered with its
+	 * left <code>ControlAligner</code>) to this pane's left
+	 * <code>ControlAligner</code> so that their width can be adjusted to have
+	 * the width of the widest widget.
+	 *
+	 * @param pane The pane containing the widgets to add
+	 *
+	 * @category Layout
+	 */
+	protected final void addAlignLeft(Pane<?> container) {
+		this.leftControlAligner.add(container.leftControlAligner);
+	}
+
+	/**
+	 * Adds the given control to the collection of widgets that have their width
+	 * adjust with the width of the widest widget. The left alignment is usually
+	 * used for labels.
+	 *
+	 * @param pane The pane to add
+	 *
+	 * @category Layout
+	 */
+	protected final void addAlignLeft(Control control) {
+		this.leftControlAligner.add(control);
+	}
+
+	/**
+	 * Adds the given pane's widgets (those that were registered with its
+	 * right <code>ControlAligner</code>) to this pane's right
+	 * <code>ControlAligner</code> so that their width can be adjusted to have
+	 * the width of the widest widget.
+	 *
+	 * @param pane The pane containing the widgets to add
+	 *
+	 * @category Layout
+	 */
+	protected final void addAlignRight(Pane<?> container) {
+		this.rightControlAligner.add(container.rightControlAligner);
+	}
+
+	/**
+	 * Adds the given control to the collection of widgets that have their width
+	 * adjust with the width of the widest widget. The left alignment is usually
+	 * used for buttons.
+	 *
+	 * @param pane The pane to add
+	 *
+	 * @category Layout
+	 */
+	protected final void addAlignRight(Control control) {
+		this.rightControlAligner.add(control);
+	}
+
+	/**
+	 * Adds the given pane's controls (those that were registered for
+	 * alignment) from this pane.
+	 *
+	 * @param pane The pane containing the widgets to add for
+	 * alignment
+	 *
+	 * @category Layout
+	 */
+	protected final void addPaneForAlignment(Pane<?> container) {
+		addAlignLeft(container);
+		addAlignRight(container);
+	}
+
+	/**
+	 * Adds any property names to the given collection in order to be notified
+	 * when the actual property changes in the subject.
+	 *
+	 * @param propertyNames The collection of property names to register with the
+	 * subject
+	 */
+	protected void addPropertyNames(Collection<String> propertyNames) {
+	}
+
+	private PropertyChangeListener buildAspectChangeListener() {
+		return new SWTPropertyChangeListenerWrapper(buildAspectChangeListener_());
+	}
+
+	private PropertyChangeListener buildAspectChangeListener_() {
+		return new PropertyChangeListener() {
+			public void propertyChanged(PropertyChangeEvent e) {
+				//subject() could have changed or is null because of the possibility of
+				//"jumping" on the UI thread here and a selection change occuring
+				if (e.getSource() == getSubject()) {
+					updatePane(e.getPropertyName());
+				}
+			}
+		};
+	}
+
+	/**
+	 * Creates a new button using the given information.
+	 *
+	 * @param parent The parent container
+	 * @param buttonText The button's text
+	 * @param buttonAction The action to be invoked when the button is pressed
+	 * @return The newly created <code>Button</code>
+	 *
+	 * @category Layout
+	 */
+	protected final Button addButton(Composite container,
+	                                   String text,
+	                                   final Runnable buttonAction) {
+
+		return this.addButton(container, text, null, buttonAction);
+	}
+	
+	/**
+	 * Creates a new unmanaged <code>Button</code> widget.  Unmanaged means 
+	 * that this Pane will not handle the enabling/disabling of this widget.  
+	 * The owning object will handle it with its own PaneEnabler or ControlEnabler.
+	 *
+	 * @param parent The parent container
+	 * @param buttonText The button's text
+	 * @param buttonAction The action to be invoked when the button is pressed
+	 * @return The newly created <code>Button</code>
+	 *
+	 * @category Layout
+	 */
+	protected final Button addUnmanagedButton(Composite container,
+	                                   String text,
+	                                   final Runnable buttonAction) {
+
+		return this.addUnmanagedButton(container, text, null, buttonAction);
+	}
+
+	/**
+	 * Creates a new button using the given information.
+	 *
+	 * @param parent The parent container
+	 * @param buttonText The button's text
+	 * @param helpId The topic help ID to be registered for the new check box
+	 * @param buttonAction The action to be invoked when the button is pressed
+	 * @return The newly created <code>Button</code>
+	 *
+	 * @category Layout
+	 */
+	protected final Button addButton(Composite container,
+	                                   String text,
+	                                   String helpId,
+	                                   final Runnable buttonAction) {
+
+		Button button = addUnmanagedButton(container, text, helpId, buttonAction);
+		this.manageWidget(button);
+
+		return button;
+	}
+	
+	/**
+	 * Creates a new unmanaged <code>Button</code> widget.  Unmanaged means 
+	 * that this Pane will not handle the enabling/disabling of this widget.  
+	 * The owning object will handle it with its own PaneEnabler or ControlEnabler.
+	 *
+	 * @param parent The parent container
+	 * @param buttonText The button's text
+	 * @param helpId The topic help ID to be registered for the new check box
+	 * @param buttonAction The action to be invoked when the button is pressed
+	 * @return The newly created <code>Button</code>
+	 *
+	 * @category Layout
+	 */
+	private Button addUnmanagedButton(Composite container,
+	                                   String text,
+	                                   String helpId,
+	                                   final Runnable buttonAction) {
+
+		Button button = this.widgetFactory.createButton(container, text);
+		button.addSelectionListener(new SelectionAdapter() {
+			@Override
+			public void widgetSelected(SelectionEvent e) {
+				SWTUtil.asyncExec(buttonAction);
+			}
+		});
+
+		if (helpId != null) {
+			getHelpSystem().setHelp(button, helpId);
+		}
+
+		GridData gridData = new GridData();
+		gridData.grabExcessHorizontalSpace = false;
+		gridData.horizontalAlignment       = GridData.FILL;
+		button.setLayoutData(gridData);
+
+		return button;
+	}
+
+	/**
+	 * This layout will leave space for decorations on widgets.
+	 * Whether decorated or not, all of the widgets need the same indent
+ 	 * so that they align properly.
+	 */
+	protected GridData getFieldGridData() {
+		int margin = FieldDecorationRegistry.getDefault()
+				.getMaximumDecorationWidth();
+		GridData data = new GridData();
+		data.horizontalAlignment = SWT.FILL;
+		data.widthHint = IDialogConstants.ENTRY_FIELD_WIDTH + margin;
+		data.horizontalIndent = margin;
+		data.grabExcessHorizontalSpace = true;
+		return data;
+	}
+
+	/**
+	 * Creates a new check box using the given information.
+	 *
+	 * @param parent The parent container
+	 * @param buttonText The button's text
+	 * @param booleanHolder The holder of the selection state
+	 * @param helpId The topic help ID to be registered for the new check box
+	 * @return The newly created <code>Button</code>
+	 *
+	 * @category Layout
+	 */
+	protected final Button addCheckBox(
+			Composite parent,
+	        String buttonText,
+	        WritablePropertyValueModel<Boolean> booleanHolder,
+	        String helpId) {
+		
+		return this.addToggleButton(
+			parent,
+			buttonText,
+			booleanHolder,
+			helpId,
+			SWT.CHECK);
+	}
+	
+	protected final Button addCheckBox(
+			Composite parent,
+			String buttonText,
+			WritablePropertyValueModel<Boolean> booleanHolder,
+			String helpId,
+			PropertyValueModel<Boolean> enabledModel) {
+		
+		Button button = this.addUnmanagedToggleButton(parent, buttonText, booleanHolder, helpId, SWT.CHECK);
+		this.controlEnabledState(enabledModel, button);
+		return button;
+	}
+	
+	/**
+	 * Creates a new <code>Section</code> that can be collapsed. A sub-pane is
+	 * automatically added as its client and is the returned <code>Composite</code>.
+	 *
+	 * @param container The container of the new widget
+	 * @param sectionText The text of the new section
+	 * @return The <code>Section</code>'s sub-pane
+	 *
+	 * @category Layout
+	 */
+	protected final Composite addCollapsibleSection(
+			Composite container,
+	        String sectionText) {
+		
+		return this.addCollapsibleSection(
+				container,
+				sectionText,
+				new SimplePropertyValueModel<Boolean>(Boolean.FALSE));
+	}
+	
+	/**
+	 * Creates a new <code>Section</code> that can be collapsed. A sub-pane is
+	 * automatically added as its client and is the returned <code>Composite</code>.
+	 *
+	 * @param container The container of the new widget
+	 * @param sectionText The text of the new section
+	 * @param description The section's description or <code>null</code> if none
+	 * @return The <code>Section</code>'s sub-pane
+	 *
+	 * @category Layout
+	 */
+	protected final Composite addCollapsibleSection(Composite container,
+	                                                  String sectionText,
+	                                                  String description) {
+
+		return this.addCollapsibleSection(
+			container,
+			sectionText,
+			description,
+			new SimplePropertyValueModel<Boolean>(Boolean.FALSE)
+		);
+	}
+
+	/**
+	 * Creates a new <code>Section</code>. A sub-pane is automatically added as
+	 * its client and is the returned <code>Composite</code>.
+	 *
+	 * @param container The container of the new widget
+	 * @param sectionText The text of the new section
+	 * @param type The type of section to create
+	 * @param expandedStateHolder The holder of the boolean that will dictate
+	 * when to expand or collapse the section
+	 * @return The <code>Section</code>'s sub-pane
+	 *
+	 * @category Layout
+	 */
+	private Composite addCollapsibleSection(Composite container,
+	                                          String sectionText,
+	                                          int type,
+	                                          PropertyValueModel<Boolean> expandedStateHolder) {
+		
+		return addCollapsibleSection(container, sectionText, null, type, expandedStateHolder);
+	}
+	
+	/**
+	 * Creates a new <code>Section</code>. A sub-pane is automatically added as
+	 * its client and is the returned <code>Composite</code>.
+	 *
+	 * @param container The container of the new widget
+	 * @param sectionText The text of the new section
+	 * @param description The section's description or <code>null</code> if none
+	 * was provided
+	 * @param type The type of section to create
+	 * @param expandedStateHolder The holder of the boolean that will dictate
+	 * when to expand or collapse the section
+	 * @return The <code>Section</code>'s sub-pane
+	 *
+	 * @category Layout
+	 */
+	private Composite addCollapsibleSection(Composite container,
+	                                          String sectionText,
+	                                          String description,
+	                                          int type,
+	                                          PropertyValueModel<Boolean> expandedStateHolder) {
+
+		Composite subPane = this.addSection(
+			container,
+			sectionText,
+			description,
+			ExpandableComposite.TWISTIE | type
+		);
+
+		Section section = (Section) subPane.getParent();
+
+		expandedStateHolder.addPropertyChangeListener(
+			PropertyValueModel.VALUE,
+			buildExpandedStateChangeListener(section)
+		);
+
+		section.setExpanded(
+			expandedStateHolder.getValue() != null ? expandedStateHolder.getValue() : true
+		);
+
+		return subPane;
+	}
+
+	/**
+	 * Creates a new <code>Section</code>. A sub-pane is automatically added as
+	 * its client and is the returned <code>Composite</code>.
+	 *
+	 * @param container The container of the new widget
+	 * @param sectionText The text of the new section
+	 * @param expandedStateHolder The holder of the boolean that will dictate
+	 * when to expand or collapse the section
+	 * @return The <code>Section</code>'s sub-pane
+	 *
+	 * @category Layout
+	 */
+	protected final Composite addCollapsibleSection(Composite container,
+	                                                  String sectionText,
+	                                                  PropertyValueModel<Boolean> expandedStateHolder) {
+
+		return this.addCollapsibleSection(
+			container,
+			sectionText,
+			ExpandableComposite.TITLE_BAR | ExpandableComposite.TWISTIE,
+			expandedStateHolder
+		);
+	}
+	
+	/**
+	 * Creates a new <code>Section</code>. A sub-pane is automatically added as
+	 * its client and is the returned <code>Composite</code>.
+	 *
+	 * @param container The container of the new widget
+	 * @param sectionText The text of the new section
+	 * @param description The section's description or <code>null</code> if none
+	 * @param expandedStateHolder The holder of the boolean that will dictate
+	 * when to expand or collapse the section
+	 * @return The <code>Section</code>'s sub-pane
+	 *
+	 * @category Layout
+	 */
+	protected final Composite addCollapsibleSection(Composite container,
+	                                                  String sectionText,
+	                                                  String description,
+	                                                  PropertyValueModel<Boolean> expandedStateHolder) {
+
+		return this.addCollapsibleSection(
+			container,
+			sectionText,
+			description,
+			ExpandableComposite.TITLE_BAR | ExpandableComposite.TWISTIE,
+			expandedStateHolder
+		);
+	}
+
+	/**
+	 * Creates a new <code>Section</code>. A sub-pane is automatically added as
+	 * its client which can be typed cast directly as a <code>Composite</code>.
+	 *
+	 * @param container The container of the new widget
+	 * @param sectionText The text of the new section
+	 * @param expandedStateHolder The holder of the boolean that will dictate
+	 * when to expand or collapse the section
+	 * @return The <code>Section</code>'s sub-pane
+	 *
+	 * @category Layout
+	 */
+	protected final Composite addCollapsibleSubSection(Composite container,
+	                                          String sectionText,
+	                                          PropertyValueModel<Boolean> expandedStateHolder) {
+
+		return this.addCollapsibleSection(
+			container,
+			sectionText,
+			SWT.NULL,
+			expandedStateHolder
+		);
+	}
+
+	/**
+	 * Creates a new non-editable <code>Combo</code>.
+	 *
+	 * @param container The parent container
+	 * @return The newly created <code>Combo</code>
+	 *
+	 * @category Layout
+	 */
+	protected final Combo addCombo(Composite container) {
+		Combo combo = this.addUnmanagedCombo(container);
+		this.manageWidget(combo);
+		return combo;
+	}
+
+	/**
+	 * Creates a new non-editable <code>Combo</code>.
+	 *
+	 * @param container The parent container
+	 * @return The newly created <code>Combo</code>
+	 *
+	 * @category Layout
+	 */
+	private Combo addUnmanagedCombo(Composite container) {
+		Combo combo = this.widgetFactory.createCombo(container);
+		combo.setLayoutData(getFieldGridData());
+		return combo;
+	}
+
+	/**
+	 * Creates a new non-editable <code>Combo</code>.
+	 *
+	 * @param container The parent container
+	 * @param listHolder The <code>ListValueHolder</code>
+	 * @param selectedItemHolder The holder of the selected item
+	 * @param stringConverter The converter responsible to transform each item
+	 * into a string representation
+	 * @return The newly created <code>Combo</code>
+	 *
+	 * @category Layout
+	 */
+	protected final <V> Combo addCombo(Composite container,
+	                                     ListValueModel<V> listHolder,
+	                                     WritablePropertyValueModel<V> selectedItemHolder,
+	                                     StringConverter<V> stringConverter) {
+
+		Combo combo = this.addCombo(container);
+
+		ComboModelAdapter.adapt(
+			listHolder,
+			selectedItemHolder,
+			combo,
+			stringConverter
+		);
+
+		return combo;
+	}
+
+	/**
+	 * Creates a new non-editable <code>Combo</code>.
+	 *
+	 * @param container The parent container
+	 * @param listHolder The <code>ListValueHolder</code>
+	 * @param selectedItemHolder The holder of the selected item
+	 * @param stringConverter The converter responsible to transform each item
+	 * into a string representation
+	 * @return The newly created <code>Combo</code>
+	 *
+	 * @category Layout
+	 */
+	private <V> Combo addUnmanagedCombo(Composite container,
+	                                     ListValueModel<V> listHolder,
+	                                     WritablePropertyValueModel<V> selectedItemHolder,
+	                                     StringConverter<V> stringConverter) {
+
+		Combo combo = this.addUnmanagedCombo(container);
+
+		ComboModelAdapter.adapt(
+			listHolder,
+			selectedItemHolder,
+			combo,
+			stringConverter
+		);
+
+		return combo;
+	}
+
+	protected final <V> Combo addCombo(
+			Composite container,
+			ListValueModel<V> listHolder,
+			WritablePropertyValueModel<V> selectedItemHolder,
+			StringConverter<V> stringConverter,
+			PropertyValueModel<Boolean> enabledModel) {
+		
+		Combo combo = this.addUnmanagedCombo(container, listHolder, selectedItemHolder, stringConverter);
+		this.controlEnabledState(enabledModel, combo);
+		return combo;
+	}
+
+	/**
+	 * Creates a new <code>ComboViewer</code> using a <code>Combo</code>.
+	 *
+	 * @param container The parent container
+	 * @param labelProvider The provider responsible to convert the combo's items
+	 * into human readable strings
+	 * @return The newly created <code>ComboViewer</code>
+	 *
+	 * @category Layout
+	 */
+	protected final ComboViewer addComboViewer(Composite container,
+	                                             IBaseLabelProvider labelProvider) {
+
+		Combo combo = this.addCombo(container);
+		ComboViewer viewer = new ComboViewer(combo);
+		viewer.setLabelProvider(labelProvider);
+		return viewer;
+	}
+
+	/**
+	 * Creates the main container of this pane. The layout and layout data are
+	 * automatically set.
+	 *
+	 * @param parent The parent container
+	 * @return The newly created <code>Composite</code> that will holds all the
+	 * widgets created by this pane through {@link #initializeLayout(Composite)}
+	 *
+	 * @category Layout
+	 */
+	protected Composite addContainer(Composite parent) {
+		return this.addSubPane(parent);
+	}
+	
+	protected final <V> Combo addEditableCombo(
+			Composite container,
+			ListValueModel<V> listHolder,
+			WritablePropertyValueModel<V> selectedItemHolder,
+			StringConverter<V> stringConverter,
+			PropertyValueModel<Boolean> enabledModel) {
+		
+		Combo combo = this.addUnmanagedEditableCombo(container, listHolder, selectedItemHolder, stringConverter);
+		this.controlEnabledState(enabledModel, combo);
+		return combo;
+	}
+	
+	protected final Combo addEditableCombo(
+			Composite container) {
+		
+		Combo combo = this.widgetFactory.createEditableCombo(container);
+		combo.setLayoutData(getFieldGridData());
+		this.manageWidget(combo);
+		return combo;
+	}
+	
+	/**
+	 * Creates a new editable <code>Combo</code>.
+	 *
+	 * @param container The parent container
+	 * @param listHolder The <code>ListValueHolder</code>
+	 * @param selectedItemHolder The holder of the selected item
+	 * @param stringConverter The converter responsible to transform each item
+	 * into a string representation
+	 * @return The newly created <code>Combo</code>
+	 *
+	 * @category Layout
+	 */
+	protected final <V> Combo addEditableCombo(Composite container,
+	                                             ListValueModel<V> listHolder,
+	                                             WritablePropertyValueModel<V> selectedItemHolder,
+	                                             StringConverter<V> stringConverter) {
+
+		Combo combo = this.addEditableCombo(container);
+
+		ComboModelAdapter.adapt(
+			listHolder,
+			selectedItemHolder,
+			combo,
+			stringConverter
+		);
+
+		return combo;
+	}
+
+	/**
+	 * Creates a new editable <code>ComboViewer</code> using a <code>Combo</code>.
+	 *
+	 * @param container The parent container
+	 * @param labelProvider The provider responsible to convert the combo's items
+	 * into human readable strings
+	 * @return The newly created <code>ComboViewer</code>
+	 *
+	 * @category Layout
+	 */
+	protected final ComboViewer addEditableComboViewer(Composite container,
+	                                                     IBaseLabelProvider labelProvider) {
+
+		Combo combo = this.addEditableCombo(container);
+		ComboViewer viewer = new ComboViewer(combo);
+		viewer.setLabelProvider(labelProvider);
+		return viewer;
+	}
+
+	private PropertyChangeListener buildExpandedStateChangeListener(final Section section) {
+		return new SWTPropertyChangeListenerWrapper(buildExpandedStateChangeListener_(section));
+	}
+
+	private PropertyChangeListener buildExpandedStateChangeListener_(final Section section) {
+		return new PropertyChangeListener() {
+			public void propertyChanged(final PropertyChangeEvent e) {
+				Boolean value = (Boolean) e.getNewValue();
+				if (value == null) {
+					value = Boolean.TRUE;
+				}
+				section.setExpanded(value);
+			}
+		};
+	}
+
+	/**
+	 * Creates a new <code>Hyperlink</code> that will invoked the given
+	 * <code>Runnable</code> when selected. The given action is always invoked
+	 * from the UI thread.
+	 *
+	 * @param parent The parent container
+	 * @param text The hyperlink's text
+	 * @param hyperLinkAction The action to be invoked when the link was selected
+	 * return The newly created <code>Hyperlink</code>
+	 *
+	 * @category Layout
+	 */
+	protected final Hyperlink addHyperlink(Composite parent,
+	                                         String text,
+	                                         final Runnable hyperLinkAction) {
+
+		Hyperlink link = this.widgetFactory.createHyperlink(parent, text);
+		this.manageWidget(link);
+
+		link.addMouseListener(new MouseAdapter() {
+			@Override
+			public void mouseUp(MouseEvent e) {
+
+				Hyperlink hyperLink = (Hyperlink) e.widget;
+
+				if (hyperLink.isEnabled()) {
+					SWTUtil.asyncExec(hyperLinkAction);
+				}
+			}
+		});
+
+		return link;
+	}
+
+	/**
+	 * Creates a new label using the given information.
+	 *
+	 * @param parent The parent container
+	 * @param labelText The label's text
+	 *
+	 * @category Layout
+	 */
+	protected final Label addLabel(Composite container,
+	                                 String labelText) {
+		
+		Label label = addUnmanagedLabel(container, labelText);
+		manageWidget(label);
+		return label;
+	}
+
+	protected final Label addLabel(
+			Composite container,
+			String labelText,
+			PropertyValueModel<Boolean> enabledModel
+	) {
+		Label label = this.addUnmanagedLabel(container, labelText);
+		this.controlEnabledState(enabledModel, label);
+		return label;
+	}
+
+	/**
+	 * Creates a new unmanaged <code>Label</code> widget.  Unmanaged means 
+	 * that this Pane will not handle the enabling/disabling of this widget.  
+	 * The owning object will handle it with its own PaneEnabler or ControlEnabler.
+	 *
+	 * @param parent The parent container
+	 * @param labelText The label's text
+	 *
+	 * @category Layout
+	 */
+	private Label addUnmanagedLabel(Composite container,
+	                                 String labelText) {
+
+		return this.widgetFactory.createLabel(container, labelText);
+	}
+
+	/**
+	 * Creates a new container that will have a non-editable combo labeled with
+	 * the given text.
+	 *
+	 * @param container The parent container
+	 * @param labelText The text of the label
+	 * @param listHolder The <code>ListValueHolder</code>
+	 * @param selectedItemHolder The holder of the selected item
+	 * @param rightControl The control shown to the right of the main widget
+	 * @param helpId The topic help ID to be registered for the given center
+	 * compositer
+	 * @return The container of the label and the given center control
+	 *
+	 * @category Layout
+	 */
+	protected final <V> Combo addLabeledCombo(Composite container,
+	                                            String labelText,
+	                                            ListValueModel<V> listHolder,
+	                                            WritablePropertyValueModel<V> selectedItemHolder,
+	                                            StringConverter<V> stringConverter,
+	                                            Control rightControl,
+	                                            String helpId) {
+
+		Combo combo = this.addCombo(
+			container,
+			listHolder,
+			selectedItemHolder,
+			stringConverter
+		);
+
+		this.addLabeledComposite(
+			container,
+			labelText,
+			(combo.getParent() != container) ? combo.getParent() : combo,
+			rightControl,
+			helpId
+		);
+
+		return combo;
+	}
+
+	/**
+	 * Creates a new container that will have a non-editable combo labeled with
+	 * the given text.
+	 *
+	 * @param container The parent container
+	 * @param labelText The text of the label
+	 * @param listHolder The <code>ListValueHolder</code>
+	 * @param selectedItemHolder The holder of the selected item
+	 * @param helpId The topic help ID to be registered for the given center
+	 * compositer
+	 * @return The container of the label and the given center control
+	 *
+	 * @category Layout
+	 */
+	protected final <V> Combo addLabeledCombo(Composite container,
+	                                            String labelText,
+	                                            ListValueModel<V> listHolder,
+	                                            WritablePropertyValueModel<V> selectedItemHolder,
+	                                            StringConverter<V> stringConverter,
+	                                            String helpId) {
+
+		return this.addLabeledCombo(
+			container,
+			labelText,
+			listHolder,
+			selectedItemHolder,
+			stringConverter,
+			null,
+			helpId
+		);
+	}
+
+	/**
+	 * Creates a new container that will have the given center control labeled
+	 * with the given label.
+	 *
+	 * @param container The parent container
+	 * @param leftControl The widget shown to the left of the main widget
+	 * @param centerControl The main widget
+	 * @param rightControl The control shown to the right of the main widget
+	 * @param helpId The topic help ID to be registered for the given center
+	 * compositer
+	 * @return The container of the label and the given center control
+	 *
+	 * @category Layout
+	 */
+	protected final Composite addLabeledComposite(Composite container,
+													Control leftControl,
+	                                                Control centerControl,
+	                                                Control rightControl,
+	                                                String helpId) {
+
+		// Container for the label and main composite
+		container = this.addSubPane(container, 3, 0, 0, 0, 0);
+
+		// Left control
+		GridData gridData = new GridData();
+		gridData.horizontalAlignment       = GridData.BEGINNING;
+		gridData.grabExcessHorizontalSpace = false;
+		leftControl.setLayoutData(gridData);
+
+		// Re-parent the left control to the new sub pane
+		leftControl.setParent(container);
+		this.addAlignLeft(leftControl);
+
+
+		// Re-parent the center control to the new sub pane
+		centerControl.setParent(container);
+
+		// Register the help id for the center control
+		if (helpId != null) {
+			getHelpSystem().setHelp(centerControl, helpId);
+		}
+
+		// Right control
+		if (rightControl == null) {
+			Composite spacer = this.addPane(container);
+			spacer.setLayout(this.buildSpacerLayout());
+			rightControl = spacer;
+		}
+		else {
+			rightControl.setParent(container);
+
+			// Register the help id for the right control
+			if (helpId != null) {
+				getHelpSystem().setHelp(rightControl, helpId);
+			}
+		}
+
+		gridData = new GridData();
+		gridData.horizontalAlignment       = GridData.FILL_HORIZONTAL;
+		gridData.grabExcessHorizontalSpace = false;
+
+		rightControl.setLayoutData(gridData);
+		this.addAlignRight(rightControl);
+
+		return container;
+	}
+	
+	/**
+	 * Creates a new container that will have the given center control labeled
+	 * with the given label.
+	 *
+	 * @param container The parent container
+	 * @param label The label used to describe the center control
+	 * @param centerControl The main widget
+	 * @param helpId The topic help ID to be registered for the given center
+	 * control
+	 * @return The container of the label and the given center control
+	 *
+	 * @category Layout
+	 */
+	protected final Composite addLabeledComposite(Composite container,
+													Control label,
+	                                                Control centerControl,
+	                                                String helpId) {
+
+		return this.addLabeledComposite(
+			container,
+			label,
+			centerControl,
+			null,
+			helpId
+		);
+	}
+
+	/**
+	 * Creates a new container that will have the given center composite labeled
+	 * with the given label text.
+	 *
+	 * @param container The parent container
+	 * @param labelText The text to label the main composite
+	 * @param centerPane The main widget
+	 * @param helpId The topic help ID to be registered for the given center
+	 * compositer
+	 * @return The container of the label and the given center control
+	 *
+	 * @category Layout
+	 */
+	protected final Composite addLabeledComposite(Composite container,
+	                                                String labelText,
+	                                                Pane<?> centerPane,
+	                                                String helpId) {
+
+		return this.addLabeledComposite(
+			container,
+			labelText,
+			centerPane.getControl(),
+			helpId
+		);
+	}
+
+	/**
+	 * Creates a new container that will have the given center composite labeled
+	 * with the given label text.
+	 *
+	 * @param container The parent container
+	 * @param labelText The text to label the main composite
+	 * @param centerControl The main widget
+	 * @return The container of the label and the given center control
+	 *
+	 * @category Layout
+	 */
+	protected final Composite addLabeledComposite(Composite container,
+	                                                String labelText,
+	                                                Control centerControl) {
+
+
+		return this.addLabeledComposite(
+			container,
+			labelText,
+			centerControl,
+			null,
+			null
+		);
+	}
+
+	/**
+	 * Creates a new container that will have the given center composite labeled
+	 * with the given label text.
+	 *
+	 * @param container The parent container
+	 * @param labelText The text to label the main composite
+	 * @param centerControl The main widget
+	 * @param rightControl The control shown to the right of the main widget
+	 * @param helpId The topic help ID to be registered for the given center
+	 * compositer
+	 * @return The container of the label and the given center control
+	 *
+	 * @category Layout
+	 */
+	protected final Composite addLabeledComposite(Composite container,
+	                                                String labelText,
+	                                                Control centerControl,
+	                                                Control rightControl,
+	                                                String helpId) {
+
+		return this.addLabeledComposite(
+			container,
+			this.addLabel(container, labelText),
+			centerControl,
+			rightControl,
+			helpId
+		);
+	}
+
+	/**
+	 * Creates a new container that will have the given center composite labeled
+	 * with the given label text.
+	 *
+	 * @param container The parent container
+	 * @param labelText The text to label the main composite
+	 * @param centerControl The main widget
+	 * @param helpId The topic help ID to be registered for the given center
+	 * compositer
+	 * @return The container of the label and the given center control
+	 *
+	 * @category Layout
+	 */
+	protected final Composite addLabeledComposite(Composite container,
+	                                                String labelText,
+	                                                Control centerControl,
+	                                                String helpId) {
+
+		Label label = this.addLabel(container, labelText);
+
+		return this.addLabeledComposite(
+			container,
+			label,
+			centerControl,
+			helpId
+		);
+	}
+
+	/**
+	 * Creates a new container that will have the given center control labeled
+	 * with the given label.
+	 *
+	 * @param container The parent container
+	 * @param leftControl The widget shown to the left of the main widget
+	 * @param centerControl The main widget
+	 * @param rightControl The control shown to the right of the main widget
+	 * @param helpId The topic help ID to be registered for the given center
+	 * compositer
+	 * @return The newly created <code>CCombo</code>
+	 *
+	 * @category Layout
+	 */
+	protected final Combo addLabeledEditableCombo(Composite container,
+	                                                  String labelText,
+	                                                  ModifyListener comboListener,
+	                                                  Control rightControl,
+	                                                  String helpId) {
+
+		Combo combo = this.addEditableCombo(container);
+		combo.addModifyListener(comboListener);
+
+		this.addLabeledComposite(
+			container,
+			labelText,
+			(combo.getParent() != container) ? combo.getParent() : combo,
+			rightControl,
+			helpId
+		);
+
+		return combo;
+	}
+
+	/**
+	 * Creates a new container that will have an editable combo labeled with the
+	 * given text.
+	 *
+	 * @param container The parent container
+	 * @param labelText The text of the label
+	 * @param comboListener The listener that will be notified when the selection
+	 * changes
+	 * @param helpId The topic help ID to be registered for the given center
+	 * compositer
+	 * @return The newly created <code>CCombo</code>
+	 *
+	 * @category Layout
+	 */
+	protected final Combo addLabeledEditableCombo(Composite container,
+	                                                  String labelText,
+	                                                  ModifyListener comboListener,
+	                                                  String helpId) {
+
+		return this.addLabeledEditableCombo(
+			container,
+			labelText,
+			comboListener,
+			null,
+			helpId
+		);
+	}
+
+	/**
+	 * Creates a new container that will have the given center control labeled
+	 * with the given label.
+	 *
+	 * @param container The parent container
+	 * @param leftControl The widget shown to the left of the main widget
+	 * @param centerControl The main widget
+	 * @param labelProvider The provider responsible to convert the combo's items
+	 * into human readable strings
+	 * @param rightControl The control shown to the right of the main widget
+	 * @param helpId The topic help ID to be registered for the given center
+	 * compositer
+	 * @return The newly created <code>CCombo</code>
+	 *
+	 * @category Layout
+	 */
+	protected final Combo addLabeledEditableComboViewer(Composite container,
+	                                                        String labelText,
+	                                                        ModifyListener comboListener,
+	                                                        ILabelProvider labelProvider,
+	                                                        Control rightControl,
+	                                                        String helpId) {
+
+		ComboViewer comboViewer = this.addEditableComboViewer(
+			container,
+			labelProvider
+		);
+
+		Combo combo = comboViewer.getCombo();
+		combo.addModifyListener(comboListener);
+
+		this.addLabeledComposite(
+			container,
+			labelText,
+			(combo.getParent() != container) ? combo.getParent() : combo,
+			rightControl,
+			helpId
+		);
+
+		return combo;
+	}
+
+	/**
+	 * Creates a new container that will have an editable combo labeled with the
+	 * given text.
+	 *
+	 * @param container The parent container
+	 * @param labelText The text of the label
+	 * @param comboListener The listener that will be notified when the selection
+	 * changes
+	 * @param labelProvider The provider responsible to convert the combo's items
+	 * into human readable strings
+	 * @param helpId The topic help ID to be registered for the given center
+	 * compositer
+	 * @return The newly created <code>CCombo</code>
+	 *
+	 * @category Layout
+	 */
+	protected final Combo addLabeledEditableComboViewer(Composite container,
+	                                                        String labelText,
+	                                                        ModifyListener comboListener,
+	                                                        ILabelProvider labelProvider,
+	                                                        String helpId) {
+
+		return this.addLabeledEditableComboViewer(
+			container,
+			labelText,
+			comboListener,
+			labelProvider,
+			null,
+			helpId
+		);
+	}
+	
+	/**
+	 * Creates a new container that will have an editable combo labeled with the
+	 * given text.
+	 *
+	 * @param container The parent container
+	 * @param labelText The text of the label
+	 * @param listHolder The <code>ListValueHolder</code>
+	 * @param selectedItemHolder The holder of the selected item
+	 * @param helpId The topic help ID to be registered for the given center
+	 * composite
+	 * @return The newly created <code>CCombo</code>
+	 *
+	 * @category Layout
+	 */
+	protected final <V> Combo addLabeledEditableCombo(Composite container,
+	                                                      String labelText,
+	                                                      ListValueModel<V> listHolder,
+	                                                      WritablePropertyValueModel<V> selectedItemHolder,
+	                                                      String helpId) {
+
+		return this.addLabeledEditableCombo(
+			container,
+			labelText,
+			listHolder,
+			selectedItemHolder,
+			StringConverter.Default.<V>instance(),
+			null,
+			helpId
+		);
+	}
+
+	/**
+	 * Creates a new container that will have the given center control labeled
+	 * with the given label.
+	 *
+	 * @param container The parent container
+	 * @param labelText The text of the label
+	 * @param listHolder The <code>ListValueHolder</code>
+	 * @param selectedItemHolder The holder of the selected item
+	 * @param stringConverter The converter responsible to transform each item
+	 * into a string representation
+	 * @param rightControl The control shown to the right of the main widget
+	 * @param helpId The topic help ID to be registered for the given center
+	 * compositer
+	 * @return The newly created <code>Combo</code>
+	 *
+	 * @category Layout
+	 */
+	protected final <V> Combo addLabeledEditableCombo(Composite container,
+	                                                    String labelText,
+	                                                    ListValueModel<V> listHolder,
+	                                                    WritablePropertyValueModel<V> selectedItemHolder,
+	                                                    StringConverter<V> stringConverter,
+	                                                    Control rightControl,
+	                                                    String helpId) {
+
+		Combo combo = this.addEditableCombo(
+			container,
+			listHolder,
+			selectedItemHolder,
+			stringConverter
+		);
+
+		this.addLabeledComposite(
+			container,
+			labelText,
+			(combo.getParent() != container) ? combo.getParent() : combo,
+			rightControl,
+			helpId
+		);
+
+		return combo;
+	}
+
+	/**
+	 * Creates a new container that will have an editable combo labeled with the
+	 * given text.
+	 *
+	 * @param container The parent container
+	 * @param labelText The text of the label
+	 * @param listHolder The <code>ListValueHolder</code>
+	 * @param selectedItemHolder The holder of the selected item
+	 * @param stringConverter The converter responsible to transform each item
+	 * into a string representation
+	 * @param helpId The topic help ID to be registered for the given center
+	 * compositer
+	 * @return The newly created <code>Combo</code>
+	 *
+	 * @category Layout
+	 */
+	protected final <V> Combo addLabeledEditableCombo(Composite container,
+	                                                    String labelText,
+	                                                    ListValueModel<V> listHolder,
+	                                                    WritablePropertyValueModel<V> selectedItemHolder,
+	                                                    StringConverter<V> stringConverter,
+	                                                    String helpId) {
+
+		return this.addLabeledEditableCombo(
+			container,
+			labelText,
+			listHolder,
+			selectedItemHolder,
+			stringConverter,
+			null,
+			helpId
+		);
+	}
+
+	/**
+	 * Creates a new container that will have a text field as the center control
+	 * labeled with the given label.
+	 *
+	 * @param container The parent container
+	 * @param labelText The text area's label
+	 * @param textHolder The holder of the text field's input
+	 * @param lineCount The number of lines the text area should display
+	 * @param helpId The topic help ID to be registered for the text field
+	 * @return The newly created <code>Text</code>
+	 *
+	 * @category Layout
+	 */
+	protected final Text addLabeledMultiLineText(Composite container,
+	                                               String labelText,
+	                                               WritablePropertyValueModel<String> textHolder,
+	                                               int lineCount,
+	                                               String helpId) {
+
+		Text text = this.addMultiLineText(container, textHolder, lineCount);
+
+		container = this.addLabeledComposite(
+			container,
+			labelText,
+			text,
+			helpId
+		);
+
+		int textHeight = text.computeSize(SWT.DEFAULT, SWT.DEFAULT).y;
+
+		// Specify the number of lines the text area should display
+		GridData gridData = (GridData) text.getLayoutData();
+		gridData.heightHint = text.getLineHeight() * lineCount;
+
+		// Move the label to the top of its cell
+		Control label = container.getChildren()[0];
+		int labelHeight = label.computeSize(SWT.DEFAULT, SWT.DEFAULT).y;
+
+		gridData = (GridData) label.getLayoutData();
+		gridData.verticalAlignment = SWT.TOP;
+		gridData.verticalIndent   += (Math.abs(textHeight - labelHeight) / 2);
+
+		return text;
+	}
+
+	/**
+	 * Creates a new container that will have a text field as the center control
+	 * labeled with the given label.
+	 *
+	 * @param container The parent container
+	 * @param textHolder The holder of the text field's input
+	 * @return The newly created <code>Text</code>
+	 *
+	 * @category Layout
+	 */
+	protected final Text addLabeledPasswordText(Composite container,
+	                                              String labelText,
+	                                              WritablePropertyValueModel<String> textHolder) {
+
+		return this.addLabeledPasswordText(
+			container,
+			labelText,
+			textHolder,
+			null
+		);
+	}
+
+	/**
+	 * Creates a new container that will have a text field as the center control
+	 * labeled with the given label.
+	 *
+	 * @param container The parent container
+	 * @param labelText The text field's label
+	 * @param rightComponent The component to be placed to the right of the text
+	 * field
+	 * @param textHolder The holder of the text field's input
+	 * @param helpId The topic help ID to be registered for the text field
+	 * @return The newly created <code>Text</code>
+	 *
+	 * @category Layout
+	 */
+	protected final Text addLabeledPasswordText(Composite container,
+	                                              String labelText,
+	                                              WritablePropertyValueModel<String> textHolder,
+	                                              Control rightControl,
+	                                              String helpId) {
+
+		Text text = this.addPasswordText(container, textHolder);
+
+		this.addLabeledComposite(
+			container,
+			labelText,
+			text,
+			rightControl,
+			helpId
+		);
+
+		return text;
+	}
+
+	/**
+	 * Creates a new container that will have a text field as the center control
+	 * labeled with the given label.
+	 *
+	 * @param container The parent container
+	 * @param textHolder The holder of the text field's input
+	 * @param helpId The topic help ID to be registered for the text field
+	 * @return The newly created <code>Text</code>
+	 *
+	 * @category Layout
+	 */
+	protected final Text addLabeledPasswordText(Composite container,
+	                                              String labelText,
+	                                              WritablePropertyValueModel<String> textHolder,
+	                                              String helpId) {
+
+		return this.addLabeledPasswordText(
+			container,
+			labelText,
+			textHolder,
+			null,
+			helpId
+		);
+	}
+
+	/**
+	 * Creates a new spinner.
+	 *
+	 * @param parent The parent container
+	 * @param labelText The label's text
+	 * @param numberHolder The holder of the integer value
+	 * @param defaultValue The value shown when the holder has <code>null</code>
+	 * @param minimumValue The minimum value that the spinner will allow
+	 * @param maximumValue The maximum value that the spinner will allow
+	 * @param rightControl The widget to be placed to the right of spinner
+	 * @param helpId The topic help ID to be registered for the spinner
+	 * @return The newly created <code>Spinner</code>
+	 *
+	 * @category Layout
+	 */
+	protected final Spinner addLabeledSpinner(Composite parent,
+	                                            String labelText,
+	                                            WritablePropertyValueModel<Integer> numberHolder,
+	                                            int defaultValue,
+	                                            int minimumValue,
+	                                            int maximumValue,
+	                                            Control rightControl,
+	                                            String helpId) {
+
+		Spinner spinner = this.addSpinner(
+			parent,
+			numberHolder,
+			defaultValue,
+			minimumValue,
+			maximumValue,
+			helpId
+		);
+		Label label = addLabel(parent, labelText);
+		addLabeledComposite(
+			parent,
+			label,
+			(spinner.getParent() != parent) ? spinner.getParent() : spinner,
+			rightControl,
+			helpId
+		);
+
+		GridData gridData = (GridData) spinner.getLayoutData();
+		gridData.horizontalAlignment = GridData.BEGINNING;
+
+		return spinner;
+	}
+
+	/**
+	 * Creates a new managed spinner. Managed means that this Pane will
+	 * handle enabling/disabling of this widget if a PaneEnabler is used.  
+	 *
+	 * @param parent The parent container
+	 * @param numberHolder The holder of the integer value
+	 * @param defaultValue The value shown when the holder has <code>null</code>
+	 * @param minimumValue The minimum value that the spinner will allow
+	 * @param maximumValue The maximum value that the spinner will allow
+	 * @param helpId The topic help ID to be registered for the new button
+	 * @return The newly created <code>Spinner</code>
+	 *
+	 * @category Layout
+	 */
+	protected final Spinner addSpinner(Composite parent,
+	                                     WritablePropertyValueModel<Integer> numberHolder,
+	                                     int defaultValue,
+	                                     int minimumValue,
+	                                     int maximumValue,
+	                                     String helpId) {
+
+		Spinner spinner = addUnmanagedSpinner(parent, numberHolder, defaultValue, minimumValue, maximumValue, helpId);
+		this.manageWidget(spinner);
+		return spinner;
+	}
+
+	/**
+	 * Creates a new unmanaged spinner.  Unmanaged means that this Pane will
+	 * not handle the enabling/disabling of this widget.  The owning object will handle
+	 * it with its own PaneEnabler or ControlEnabler.
+	 *
+	 * @param parent The parent container
+	 * @param numberHolder The holder of the integer value
+	 * @param defaultValue The value shown when the holder has <code>null</code>
+	 * @param minimumValue The minimum value that the spinner will allow
+	 * @param maximumValue The maximum value that the spinner will allow
+	 * @param helpId The topic help ID to be registered for the new button
+	 * @return The newly created <code>Spinner</code>
+	 *
+	 * @category Layout
+	 */
+	private Spinner addUnmanagedSpinner(Composite parent,
+	                                     WritablePropertyValueModel<Integer> numberHolder,
+	                                     int defaultValue,
+	                                     int minimumValue,
+	                                     int maximumValue,
+	                                     String helpId) {
+
+		Spinner spinner = this.widgetFactory.createSpinner(parent);
+		spinner.setMinimum(minimumValue);
+		spinner.setMaximum(maximumValue);
+		GridData gridData = getFieldGridData();
+		gridData.grabExcessHorizontalSpace = false;
+		spinner.setLayoutData(gridData);
+
+		SpinnerModelAdapter.adapt(numberHolder, spinner, defaultValue);
+
+		if (helpId != null) {
+			getHelpSystem().setHelp(spinner, helpId);
+		}
+
+		return spinner;
+	}
+	
+	/**
+	 * Creates a new managed DateTime of type SWT.TIME.  Managed means that this Pane will
+	 * handle enabling/disabling of this widget if a PaneEnabler is used.  
+	 *
+	 * @param parent The parent container
+	 * @param hoursHolder The holder of the hours integer value
+	 * @param minutesHolder The holder of the minutes integer value
+	 * @param secondsHolder The holder of the seconds integer value
+	 * @param helpId The topic help ID to be registered for the new dateTime
+	 * @return The newly created <code>DateTime</code>
+	 *
+	 * @category Layout
+	 */
+	protected final DateTime addDateTime(Composite parent,
+											WritablePropertyValueModel<Integer> hoursHolder,
+											WritablePropertyValueModel<Integer> minutesHolder,
+											WritablePropertyValueModel<Integer> secondsHolder,
+											String helpId) {
+		
+		DateTime dateTime = this.addUnmanagedDateTime(parent, hoursHolder, minutesHolder, secondsHolder, helpId);
+		this.manageWidget(dateTime);
+
+		return dateTime;
+	}
+
+	protected final DateTime addDateTime(
+			Composite parent,
+			WritablePropertyValueModel<Integer> hoursHolder,
+			WritablePropertyValueModel<Integer> minutesHolder,
+			WritablePropertyValueModel<Integer> secondsHolder,
+			String helpId,
+			PropertyValueModel<Boolean> enabledModel
+	) {
+		DateTime dateTime = this.addUnmanagedDateTime(parent, hoursHolder, minutesHolder, secondsHolder, helpId);
+		this.controlEnabledState(enabledModel, dateTime);
+		return dateTime;
+	}
+
+	/**
+	 * Creates a new unmanaged DateTime of type SWT.TIME.  Unmanaged means that this Pane will
+	 * not handle the enabling/disabling of this widget.  The owning object will handle
+	 * it with its own PaneEnabler or ControlEnabler.
+	 *
+	 * @param parent The parent container
+	 * @param hoursHolder The holder of the hours integer value
+	 * @param minutesHolder The holder of the minutes integer value
+	 * @param secondsHolder The holder of the seconds integer value
+	 * @param helpId The topic help ID to be registered for the new dateTime
+	 * @return The newly created <code>DateTime</code>
+	 *
+	 * @category Layout
+	 */
+	private DateTime addUnmanagedDateTime(Composite parent,
+											WritablePropertyValueModel<Integer> hoursHolder,
+											WritablePropertyValueModel<Integer> minutesHolder,
+											WritablePropertyValueModel<Integer> secondsHolder,
+											String helpId) {
+		
+		DateTime dateTime = this.widgetFactory.createDateTime(parent, SWT.TIME);
+		
+		DateTimeModelAdapter.adapt(hoursHolder, minutesHolder, secondsHolder, dateTime);
+	
+		if (helpId != null) {
+			getHelpSystem().setHelp(dateTime, helpId);
+		}
+
+		return dateTime;
+	}
+	/**
+	 * Creates a new editable <code>Combo</code>.
+	 *
+	 * @param container The parent container
+	 * @param listHolder The <code>ListValueHolder</code>
+	 * @param selectedItemHolder The holder of the selected item
+	 * @param stringConverter The converter responsible to transform each item
+	 * into a string representation
+	 * @return The newly created <code>CCombo</code>
+	 *
+	 * @category Layout
+	 */
+	private <V> Combo addUnmanagedEditableCombo(Composite container,
+	                                               ListValueModel<V> listHolder,
+	                                               WritablePropertyValueModel<V> selectedItemHolder,
+	                                               StringConverter<V> stringConverter) {
+
+		Combo combo = addUnmanagedEditableCombo(container);
+
+		ComboModelAdapter.adapt(
+			listHolder,
+			selectedItemHolder,
+			combo,
+			stringConverter
+		);
+
+		return combo;
+	}
+
+	
+	/**
+	 * Creates a new editable <code>Combo</code>.
+	 *
+	 * @param container The parent container
+	 * @return The newly created <code>CCombo</code>
+	 *
+	 * @category Layout
+	 */
+	private Combo addUnmanagedEditableCombo(Composite container) {
+
+		Combo combo = this.widgetFactory.createEditableCombo(container);
+		combo.setLayoutData(getFieldGridData());
+		return combo;
+	}
+
+	/**
+	 * Creates a new container that will have a text field as the center control
+	 * labeled with the given label.
+	 *
+	 * @param container The parent container
+	 * @param textHolder The holder of the text field's input
+	 * @return The newly created <code>Text</code>
+	 *
+	 * @category Layout
+	 */
+	protected final Text addLabeledText(Composite container,
+	                                      String labelText,
+	                                      WritablePropertyValueModel<String> textHolder) {
+
+		return this.addLabeledText(container, labelText, textHolder, null);
+	}
+
+	/**
+	 * Creates a new container that will have a text field as the center control
+	 * labeled with the given label.
+	 *
+	 * @param container The parent container
+	 * @param labelText The text field's label
+	 * @param rightComponent The component to be placed to the right of the text
+	 * field
+	 * @param textHolder The holder of the text field's input
+	 * @param helpId The topic help ID to be registered for the text field
+	 * @return The newly created <code>Text</code>
+	 *
+	 * @category Layout
+	 */
+	protected final Text addLabeledText(Composite container,
+	                                      String labelText,
+	                                      WritablePropertyValueModel<String> textHolder,
+	                                      Control rightComponent,
+	                                      String helpId) {
+
+		Text text = this.addText(container, textHolder);
+
+		this.addLabeledComposite(
+			container,
+			labelText,
+			text,
+			rightComponent,
+			helpId
+		);
+
+		return text;
+	}
+	/**
+	 * 
+	 * Creates a new container that will have a text field as the center control
+	 * labeled with the given label.
+	 *
+	 * @param container The parent container
+	 * @param labelText The text field's label
+	 * @param rightComponent The component to be placed to the right of the text
+	 * field
+	 * @param textHolder The holder of the text field's input
+	 * @param helpId The topic help ID to be registered for the text field
+	 * @return The newly created <code>Text</code>
+	 *
+	 * @category Layout
+	 */
+	protected final Text addLabeledText(Composite container,
+	                                      Label label,
+	                                      WritablePropertyValueModel<String> textHolder,
+	                                      Control rightComponent,
+	                                      String helpId) {
+
+		Text text = this.addText(container, textHolder);
+
+		this.addLabeledComposite(
+			container,
+			label,
+			text,
+			rightComponent,
+			helpId
+		);
+
+		return text;
+	}
+
+	/**
+	 * Creates a new container that will have a text field as the center control
+	 * labeled with the given label.
+	 *
+	 * @param container The parent container
+	 * @param textHolder The holder of the text field's input
+	 * @param helpId The topic help ID to be registered for the text field
+	 * @return The newly created <code>Text</code>
+	 *
+	 * @category Layout
+	 */
+	protected final Text addLabeledText(Composite container,
+	                                      String labelText,
+	                                      WritablePropertyValueModel<String> textHolder,
+	                                      String helpId) {
+
+		return this.addLabeledText(
+			container,
+			labelText,
+			textHolder,
+			null,
+			helpId
+		);
+	}
+
+	/**
+	 * Creates a new container that will have a text field as the center control
+	 * labeled with the given label.
+	 *
+	 * @param container The parent container
+	 * @param textHolder The holder of the text field's input
+	 * @param helpId The topic help ID to be registered for the text field
+	 * @return The newly created <code>Text</code>
+	 *
+	 * @category Layout
+	 */
+	protected final Text addLabeledText(Composite container,
+	                                      Label label,
+	                                      WritablePropertyValueModel<String> textHolder,
+	                                      String helpId) {
+
+		return this.addLabeledText(
+			container,
+			label,
+			textHolder,
+			null,
+			helpId
+		);
+	}
+
+	/**
+	 * Creates a new list and notify the given selection holder when the
+	 * selection changes. If the selection count is different than one than the
+	 * holder will receive <code>null</code>.
+	 *
+	 * @param container The parent container
+	 * @param helpId The topic help ID to be registered for the new radio button
+	 * @return The newly created <code>List</code>
+	 *
+	 * @category Layout
+	 */
+	protected final List addList(Composite container, String helpId) {
+
+		return this.addList(
+			container,
+			new SimplePropertyValueModel<String>(),
+			helpId
+		);
+	}
+
+	/**
+	 * Creates a new list and notify the given selection holder when the
+	 * selection changes. If the selection count is different than one than the
+	 * holder will receive <code>null</code>.
+	 *
+	 * @param container The parent container
+	 * @param selectionHolder The holder of the unique selected item
+	 * @param helpId The topic help ID to be registered for the new radio button
+	 * @return The newly created <code>List</code>
+	 *
+	 * @category Layout
+	 */
+	protected final List addList(Composite container,
+	                               WritablePropertyValueModel<String> selectionHolder,
+	                               String helpId) {
+
+		List list = this.addUnmanagedList(container, selectionHolder, helpId);
+		this.manageWidget(list);
+
+		return list;
+	}
+	
+	/**
+	 * Creates a new unmanaged list and notify the given selection holder when the
+	 * selection changes. If the selection count is different than one than the
+	 * holder will receive <code>null</code>. 
+	 * Unmanaged means that this Pane will not handle the enabling/disabling of this widget.  
+	 * The owning object will handle it with its own PaneEnabler or ControlEnabler.
+	 *
+	 * @param container The parent container
+	 * @param selectionHolder The holder of the unique selected item
+	 * @param helpId The topic help ID to be registered for the new radio button
+	 * @return The newly created <code>List</code>
+	 *
+	 * @category Layout
+	 */
+	private List addUnmanagedList(Composite container,
+	                               WritablePropertyValueModel<String> selectionHolder,
+	                               String helpId) {
+
+		List list = this.widgetFactory.createList(
+			container,
+			SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL | SWT.MULTI
+		);
+
+		list.addSelectionListener(buildSelectionListener(selectionHolder));
+		list.setLayoutData(new GridData(GridData.FILL_BOTH));
+
+		if (helpId != null) {
+			getHelpSystem().setHelp(list, helpId);
+		}
+
+		return list;
+	}
+
+	/**
+	 * Creates a new lable expanding on multiple lines.
+	 *
+	 * @param parent The parent container
+	 * @param labelText The label's text
+	 *
+	 * @category Layout
+	 */
+	protected final FormText addMultiLineLabel(Composite container,
+	                                         String labelText) {
+
+		FormText label = this.widgetFactory.createMultiLineLabel(container, labelText);
+		manageWidget(label);
+		return label;
+	}
+
+	/**
+	 * Creates a new <code>Text</code> widget that has multiple lines.
+	 *
+	 * @param container The parent container
+	 * @return The newly created <code>Text</code> widget
+	 *
+	 */
+	protected final Text addMultiLineText(Composite container) {
+
+		Text text = this.widgetFactory.createMultiLineText(container);
+		text.setLayoutData(getFieldGridData());
+		this.manageWidget(text);
+
+		return text;
+	}
+	
+	/**
+	 * Creates a new <code>Text</code> widget that has multiple lines.
+	 *
+	 * @param container The parent container
+	 * @param lineCount The number of lines the text area should display
+	 * @param helpId The topic help ID to be registered for the new text
+	 * @return The newly created <code>Text</code> widget
+	 *
+	 * @category Layout
+	 */
+	protected final Text addMultiLineText(Composite container,
+	                                        int lineCount,
+	                                        String helpId) {
+
+		Text text = this.addMultiLineText(container);
+		
+		GridData gridData   = getFieldGridData();
+		gridData.heightHint = text.getLineHeight() * lineCount;
+		text.setLayoutData(gridData);
+
+		if (helpId != null) {
+			getHelpSystem().setHelp(text, helpId);
+		}
+
+		return text;
+	}
+
+	/**
+	 * Creates a new <code>Text</code> widget that has multiple lines.
+	 *
+	 * @param container The parent container
+	 * @param textHolder The holder of the text field's input
+	 * @param lineCount The number of lines the text area should display
+	 * @return The newly created <code>Text</code> widget
+	 *
+	 * @category Layout
+	 */
+	protected final Text addMultiLineText(Composite container,
+	                                        WritablePropertyValueModel<String> textHolder,
+	                                        int lineCount) {
+
+		return this.addMultiLineText(container, textHolder, lineCount, null);
+	}
+
+	/**
+	 * Creates a new <code>Text</code> widget that has multiple lines.
+	 *
+	 * @param container The parent container
+	 * @param textHolder The holder of the text field's input
+	 * @param helpId The topic help ID to be registered for the new text
+	 * @return The newly created <code>Text</code> widget
+	 *
+	 * @category Layout
+	 */
+	protected final Text addMultiLineText(Composite container,
+	                                        WritablePropertyValueModel<String> textHolder,
+	                                        int lineCount,
+	                                        String helpId) {
+
+		Text text = this.addMultiLineText(container, lineCount, helpId);
+		SWTTools.bind(textHolder, text);
+		return text;
+	}
+
+	/**
+	 * Creates a new <code>PageBook</code> and set the proper layout and layout
+	 * data.
+	 *
+	 * @param container The parent container
+	 * @return The newly created <code>PageBook</code>
+	 *
+	 * @category Layout
+	 */
+	protected final PageBook addPageBook(Composite container) {
+
+		PageBook pageBook = new PageBook(container, SWT.NULL);
+		pageBook.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+		return pageBook;
+	}
+
+	/**
+	 * Creates a new container without specifying any layout manager.
+	 *
+	 * @param container The parent of the new container
+	 * @return The newly created <code>Composite</code>
+	 *
+	 * @category Layout
+	 */
+	protected final Composite addPane(Composite parent) {
+		return this.widgetFactory.createComposite(parent);
+	}
+
+	/**
+	 * Creates a new container using the given layout manager.
+	 *
+	 * @param parent The parent of the new container
+	 * @param layout The layout manager of the new container
+	 * @return The newly created container
+	 *
+	 * @category Layout
+	 */
+	protected final Composite addPane(Composite container, Layout layout) {
+
+		container = this.addPane(container);
+		container.setLayout(layout);
+		container.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+		return container;
+	}
+
+	/**
+	 * Creates a new <code>Text</code> widget.
+	 *
+	 * @param container The parent container
+	 * @param textHolder The holder of the text field's input
+	 * @return The newly created <code>Text</code> widget
+	 *
+	 * @category Layout
+	 */
+	protected final Text addPasswordText(Composite container,
+	                                       WritablePropertyValueModel<String> textHolder) {
+
+		Text text = this.addPasswordText(container);
+		SWTTools.bind(textHolder, text);
+
+		return text;
+	}
+	
+	/**
+	 * Creates a new <code>Text</code> widget.
+	 *
+	 * @param container The parent container
+	 * @param textHolder The holder of the text field's input
+	 * @return The newly created <code>Text</code> widget
+	 *
+	 * @category Layout
+	 */
+	protected final Text addPasswordText(Composite container) {
+
+		Text text = this.widgetFactory.createPasswordText(container);
+		text.setLayoutData(getFieldGridData());
+
+		this.manageWidget(text);
+		return text;
+	}
+
+	/**
+	 * Creates a new push button using the given information.
+	 *
+	 * @param parent The parent container
+	 * @param buttonText The button's text
+	 * @param buttonAction The action to be invoked when the button is pressed
+	 * @return The newly created <code>Button</code>
+	 *
+	 * @category Layout
+	 */
+	protected final Button addPushButton(Composite parent,
+	                                       String buttonText,
+	                                       final Runnable buttonAction) {
+
+		return this.addPushButton(parent, buttonText, null, buttonAction);
+	}
+
+	/**
+	 * Creates a new push button using the given information.
+	 *
+	 * @param parent The parent container
+	 * @param buttonText The button's text
+	 * @param buttonAction The action to be invoked when the button is pressed
+	 * @param helpId The topic help ID to be registered for the new radio button
+	 * @return The newly created <code>Button</code>
+	 *
+	 * @category Layout
+	 */
+	protected final Button addPushButton(Composite parent,
+	                                       String buttonText,
+	                                       String helpId,
+	                                       final Runnable buttonAction) {
+
+		Button button = this.widgetFactory.createPushButton(parent, buttonText);
+		manageWidget(button);
+		button.addSelectionListener(new SelectionAdapter() {
+			@Override
+			public void widgetSelected(SelectionEvent e) {
+				SWTUtil.asyncExec(buttonAction);
+			}
+		});
+
+		button.setLayoutData(new GridData());
+
+		if (helpId != null) {
+			getHelpSystem().setHelp(button, helpId);
+		}
+
+		return button;
+	}
+
+	/**
+	 * Creates a new check box using the given information.
+	 *
+	 * @param parent The parent container
+	 * @param buttonText The button's text
+	 * @param booleanHolder The holder of the selection state
+	 * @param helpId The topic help ID to be registered for the new radio button
+	 * @return The newly created <code>Button</code>
+	 *
+	 * @category Layout
+	 */
+	protected final Button addRadioButton(Composite parent,
+	                                        String buttonText,
+	                                        WritablePropertyValueModel<Boolean> booleanHolder,
+	                                        String helpId) {
+
+		return this.addToggleButton(
+			parent,
+			buttonText,
+			booleanHolder,
+			helpId,
+			SWT.RADIO
+		);
+	}
+
+	/**
+	 * Creates a new <code>Section</code>. A sub-pane is automatically added as
+	 * its client and is the returned <code>Composite</code>.
+	 *
+	 * @param container The container of the new widget
+	 * @param sectionText The text of the new section
+	 * @return The <code>Section</code>'s sub-pane
+	 *
+	 * @category Layout
+	 */
+	protected final Composite addSection(Composite container,
+	                                       String sectionText) {
+
+		return this.addSection(
+			container,
+			sectionText,
+			ExpandableComposite.TITLE_BAR
+		);
+	}
+
+	/**
+	 * Creates a new <code>Section</code>. A sub-pane is automatically added as
+	 * its client and is the returned <code>Composite</code>.
+	 *
+	 * @param container The container of the new widget
+	 * @param sectionText The text of the new section
+	 * @param type The type of section to create
+	 * @param expandedStateHolder The holder of the boolean that will dictate
+	 * when to expand or collapse the section
+	 * @return The <code>Section</code>'s sub-pane
+	 *
+	 * @category Layout
+	 */
+	private Composite addSection(Composite container,
+	                               String sectionText,
+	                               int type) {
+
+		return this.addSection(container, sectionText, null, type);
+	}
+
+	/**
+	 * Creates a new <code>Section</code>. A sub-pane is automatically added as
+	 * its client and is the returned <code>Composite</code>.
+	 *
+	 * @param container The container of the new widget
+	 * @param sectionText The text of the new section
+	 * @param description The section's description
+	 * @return The <code>Section</code>'s sub-pane
+	 *
+	 * @category Layout
+	 */
+	protected final Composite addSection(Composite container,
+	                                       String sectionText,
+	                                       String description) {
+
+		return this.addSection(
+			container,
+			sectionText,
+			description,
+			ExpandableComposite.TITLE_BAR
+		);
+	}
+
+	/**
+	 * Creates a new <code>Section</code>. A sub-pane is automatically added as
+	 * its client and is the returned <code>Composite</code>.
+	 *
+	 * @param container The container of the new widget
+	 * @param sectionText The text of the new section
+	 * @param description The section's description or <code>null</code> if none
+	 * was provider
+	 * @param type The type of section to create
+	 * @param expandedStateHolder The holder of the boolean that will dictate
+	 * when to expand or collapse the section
+	 * @return The <code>Section</code>'s sub-pane
+	 *
+	 * @category Layout
+	 */
+	private Composite addSection(Composite container,
+	                               String sectionText,
+	                               String description,
+	                               int type) {
+
+		Section section = this.widgetFactory.createSection(container, type | ((description != null) ? Section.DESCRIPTION : SWT.NULL));
+		section.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+		section.setText(sectionText);
+		section.marginWidth  = 0;
+		section.marginHeight = 0;
+		
+		if (description != null) {
+			section.setDescription(description);
+		}
+
+		Composite subPane = this.addSubPane(section);
+		section.setClient(subPane);
+
+		return subPane;
+	}
+
+	private SelectionListener buildSelectionListener(final WritablePropertyValueModel<String> selectionHolder) {
+		return new SelectionAdapter() {
+			@Override
+			public void widgetSelected(SelectionEvent e) {
+				List list = (List) e.widget;
+				String[] selectedItems = list.getSelection();
+				if ((selectedItems == null) || (selectedItems.length != 1)) {
+					selectionHolder.setValue(null);
+				}
+				else {
+					selectionHolder.setValue(selectedItems[0]);
+				}
+			}
+		};
+	}
+
+	/**
+	 * Creates the layout responsible to compute the size of the spacer created
+	 * for the right control when none was given. The spacer helps to align all
+	 * the right controls.
+	 *
+	 * @category Layout
+	 */
+	private Layout buildSpacerLayout() {
+		return new Layout() {
+			@Override
+			protected Point computeSize(Composite composite,
+			                            int widthHint,
+			                            int heightHint,
+			                            boolean flushCache) {
+
+				return new Point(widthHint, heightHint);
+			}
+
+			@Override
+			protected void layout(Composite composite, boolean flushCache) {
+				GridData data = (GridData) composite.getLayoutData();
+				composite.setBounds(0, 0, data.widthHint, data.heightHint);
+			}
+		};
+	}
+
+	private PropertyChangeListener buildSubjectChangeListener() {
+		return new SWTPropertyChangeListenerWrapper(this.buildSubjectChangeListener_());
+	}
+
+	private PropertyChangeListener buildSubjectChangeListener_() {
+		return new PropertyChangeListener() {
+			@SuppressWarnings("unchecked")
+			public void propertyChanged(PropertyChangeEvent e) {
+				Pane.this.subjectChanged((T) e.getOldValue(), (T) e.getNewValue());
+			}
+		};
+	}
+
+	/**
+	 * Creates a new <code>Composite</code> used as a sub-pane.
+	 *
+	 * @param container The parent container
+	 * @return The newly created <code>Composite</code> used as a sub-pane
+	 *
+	 * @category Layout
+	 */
+	protected final Composite addSubPane(Composite container) {
+		return this.addSubPane(container, 0);
+	}
+
+	/**
+	 * Creates a new <code>Composite</code> used as a sub-pane.
+	 *
+	 * @param container The parent container
+	 * @param topMargin The extra spacing to add at the top of the pane
+	 * @return The newly created <code>Composite</code> used as a sub-pane
+	 *
+	 * @category Layout
+	 */
+	protected final Composite addSubPane(Composite container, int topMargin) {
+		return this.addSubPane(container, topMargin, 0);
+	}
+
+	/**
+	 * Creates a new <code>Composite</code> used as a sub-pane.
+	 *
+	 * @param container The parent container
+	 * @param topMargin The extra spacing to add at the top of the pane
+	 * @param leftMargin The extra spacing to add to the left of the pane
+	 * @return The newly created <code>Composite</code> used as a sub-pane
+	 *
+	 * @category Layout
+	 */
+	protected final Composite addSubPane(Composite container,
+	                                       int topMargin,
+	                                       int leftMargin) {
+
+		return this.addSubPane(container, topMargin, leftMargin, 0, 0);
+	}
+
+	/**
+	 * Creates a new <code>Composite</code> used as a sub-pane, the new widget
+	 * will have its layout and layout data already initialized, the layout will
+	 * be a <code>GridLayout</code> with 1 column.
+	 *
+	 * @param container The parent container
+	 * @param topMargin The extra spacing to add at the top of the pane
+	 * @param leftMargin The extra spacing to add to the left of the pane
+	 * @param bottomMargin The extra spacing to add at the bottom of the pane
+	 * @param rightMargin The extra spacing to add to the right of the pane
+	 * @return The newly created <code>Composite</code> used as a sub-pane
+	 *
+	 * @category Layout
+	 */
+	protected final Composite addSubPane(Composite container,
+	                                       int topMargin,
+	                                       int leftMargin,
+	                                       int bottomMargin,
+	                                       int rightMargin) {
+
+		return this.addSubPane(
+			container,
+			1,
+			topMargin,
+			leftMargin,
+			bottomMargin,
+			rightMargin);
+	}
+
+	/**
+	 * Creates a new <code>Composite</code> used as a sub-pane, the new widget
+	 * will have its layout and layout data already initialized, the layout will
+	 * be a <code>GridLayout</code> with 1 column.
+	 *
+	 * @param container The parent container
+	 * @param topMargin The extra spacing to add at the top of the pane
+	 * @param leftMargin The extra spacing to add to the left of the pane
+	 * @param bottomMargin The extra spacing to add at the bottom of the pane
+	 * @param rightMargin The extra spacing to add to the right of the pane
+	 * @return The newly created <code>Composite</code> used as a sub-pane
+	 *
+	 * @category Layout
+	 */
+	protected final Composite addSubPane(Composite container,
+	                                       int columnCount,
+	                                       int topMargin,
+	                                       int leftMargin,
+	                                       int bottomMargin,
+	                                       int rightMargin) {
+
+		GridLayout layout = new GridLayout(columnCount, false);
+		layout.marginHeight = 0;
+		layout.marginWidth  = 0;
+		layout.marginTop    = topMargin;
+		layout.marginLeft   = leftMargin;
+		layout.marginBottom = bottomMargin;
+		layout.marginRight  = rightMargin;
+
+		container = this.addPane(container, layout);
+
+		return container;
+	}
+
+	/**
+	 * Creates a new <code>Section</code>. A sub-pane is automatically added as
+	 * its client which can be typed cast directly as a <code>Composite</code>.
+	 *
+	 * @param container The container of the new widget
+	 * @param sectionText The text of the new section
+	 * @return The <code>Section</code>'s sub-pane
+	 *
+	 * @category Layout
+	 */
+	protected final Composite addSubSection(Composite container,
+	                                          String sectionText) {
+
+		return this.addCollapsibleSubSection(
+			container,
+			sectionText,
+			new SimplePropertyValueModel<Boolean>(Boolean.TRUE)
+		);
+	}
+
+	/**
+	 * Creates a new table.
+	 *
+	 * @param container The parent container
+	 * @param style The style to apply to the table
+	 * @param helpId The topic help ID to be registered for the new table or
+	 * <code>null</code> if no help ID is required
+	 * @return The newly created <code>Table</code>
+	 *
+	 * @category Layout
+	 */
+	protected final Table addTable(Composite container,
+	                                 int style,
+	                                 String helpId) {
+
+		Table table = addUnmanagedTable(container, style, helpId);
+		this.manageWidget(table);
+
+		return table;
+	}
+	/**
+	 * Creates a new unmanaged table.  Unmanaged means that this Pane will
+	 * not handle the enabling/disabling of this widget.  The owning object will handle
+	 * it with its own PaneEnabler or ControlEnabler.
+	 *
+	 * @param container The parent container
+	 * @param style The style to apply to the table
+	 * @param helpId The topic help ID to be registered for the new table or
+	 * <code>null</code> if no help ID is required
+	 * @return The newly created <code>Table</code>
+	 *
+	 * @category Layout
+	 */
+	protected final Table addUnmanagedTable(Composite container,
+	                                 int style,
+	                                 String helpId) {
+
+		Table table = this.widgetFactory.createTable(container, style);
+		table.setHeaderVisible(true);
+		table.setLinesVisible(true);
+
+		GridData gridData   = new GridData(GridData.FILL_BOTH);
+		gridData.heightHint = table.getItemHeight() * 4;
+		table.setLayoutData(gridData);
+
+		if (helpId != null) {
+			getHelpSystem().setHelp(table, helpId);
+		}
+
+		return table;
+	}
+
+	/**
+	 * Creates a new table.
+	 *
+	 * @param container The parent container
+	 * @param helpId The topic help ID to be registered for the new table or
+	 * <code>null</code> if no help ID is required
+	 * @return The newly created <code>Table</code>
+	 *
+	 * @category Layout
+	 */
+	protected final Table addTable(Composite container, String helpId) {
+
+		return this.addTable(
+			container,
+			SWT.V_SCROLL | SWT.H_SCROLL | SWT.FULL_SELECTION | SWT.MULTI,
+			helpId
+		);
+	}
+	
+	/**
+	 * Creates a new unmanaged table.  Unmanaged means that this Pane will
+	 * not handle the enabling/disabling of this widget.  The owning object will handle
+	 * it with its own PaneEnabler or ControlEnabler.
+	 *
+	 * @param container The parent container
+	 * @param helpId The topic help ID to be registered for the new table or
+	 * <code>null</code> if no help ID is required
+	 * @return The newly created <code>Table</code>
+	 *
+	 * @category Layout
+	 */
+	protected final Table addUnmanagedTable(Composite container, String helpId) {
+
+		return this.addUnmanagedTable(
+			container,
+			SWT.V_SCROLL | SWT.H_SCROLL | SWT.FULL_SELECTION | SWT.MULTI,
+			helpId
+		);
+	}
+
+	/**
+	 * Creates a new managed <code>Text</code> widget.
+	 *
+	 * @param container The parent container
+	 * @return The newly created <code>Text</code> widget
+	 *
+	 * @category Layout
+	 */
+	protected final Text addText(Composite container) {
+		Text text = this.addUnmanagedText(container);
+		this.manageWidget(text);
+		return text;
+	}
+	
+	/**
+	 * Creates a new unmanaged <code>Text</code> widget.  Unmanaged means 
+	 * that this Pane will not handle the enabling/disabling of this widget.  
+	 * The owning object will handle it with its own PaneEnabler or ControlEnabler.
+	 *
+	 * @param container The parent container
+	 * @return The newly created <code>Text</code> widget
+	 *
+	 * @category Layout
+	 */
+	private Text addUnmanagedText(Composite container) {
+		Text text = this.widgetFactory.createText(container);
+		text.setLayoutData(getFieldGridData());
+		return text;
+	}
+
+	/**
+	 * Creates a new <code>Text</code> widget.
+	 *
+	 * @param container The parent container
+	 * @param helpId The topic help ID to be registered for the new text
+	 * @return The newly created <code>Text</code> widget
+	 *
+	 * @category Layout
+	 */
+	protected final Text addText(Composite container, String helpId) {
+
+		Text text = this.addText(container);
+
+		if (helpId != null) {
+			getHelpSystem().setHelp(text, helpId);
+		}
+
+		return text;
+	}
+	
+	/**
+	 * Creates a new unmanaged <code>Text</code> widget.  Unmanaged means 
+	 * that this Pane will not handle the enabling/disabling of this widget.  
+	 * The owning object will handle it with its own PaneEnabler or ControlEnabler.
+	 *
+	 * @param container The parent container
+	 * @param helpId The topic help ID to be registered for the new text
+	 * @return The newly created <code>Text</code> widget
+	 *
+	 * @category Layout
+	 */
+	private Text addUnmanagedText(Composite container, String helpId) {
+
+		Text text = this.addUnmanagedText(container);
+
+		if (helpId != null) {
+			getHelpSystem().setHelp(text, helpId);
+		}
+		
+		return text;
+	}
+	
+	/**
+	 * Creates a new <code>Text</code> widget.
+	 *
+	 * @param container The parent container
+	 * @param textHolder The holder of the text field's input
+	 * @return The newly created <code>Text</code> widget
+	 *
+	 * @category Layout
+	 */
+	protected final Text addText(Composite container,
+	                               WritablePropertyValueModel<String> textHolder) {
+
+		return this.addText(container, textHolder, null);
+	}
+
+	/**
+	 * Creates a new <code>Text</code> widget.
+	 *
+	 * @param container The parent container
+	 * @param textHolder The holder of the text field's input
+	 * @param helpId The topic help ID to be registered for the new text
+	 * @return The newly created <code>Text</code> widget
+	 *
+	 * @category Layout
+	 */
+	protected final Text addText(Composite container,
+	                               WritablePropertyValueModel<String> textHolder,
+	                               String helpId) {
+
+		Text text = this.addText(container, helpId);
+		SWTTools.bind(textHolder, text);
+
+		return text;
+	}
+	
+	protected final Text addText(
+			Composite container,
+			WritablePropertyValueModel<String> textHolder,
+			String helpId,
+			PropertyValueModel<Boolean> enabledModel
+	) {
+		Text text = this.addUnmanagedText(container, textHolder, helpId);
+		this.controlEnabledState(enabledModel, text);
+		return text;
+	}
+
+	/**
+	 * Creates a new unmanaged <code>Text</code> widget.  Unmanaged means 
+	 * that this Pane will not handle the enabling/disabling of this widget.  
+	 * The owning object will handle it with its own PaneEnabler or ControlEnabler.
+	 *
+	 * @param container The parent container
+	 * @param textHolder The holder of the text field's input
+	 * @param helpId The topic help ID to be registered for the new text
+	 * @return The newly created <code>Text</code> widget
+	 *
+	 * @category Layout
+	 */
+	private Text addUnmanagedText(Composite container,
+	                               WritablePropertyValueModel<String> textHolder,
+	                               String helpId) {
+
+		Text text = this.addUnmanagedText(container, helpId);
+		SWTTools.bind(textHolder, text);
+
+		return text;
+	}
+
+	/**
+	 * Creates a new container with a titled border.
+	 *
+	 * @param title The text of the titled border
+	 * @param container The parent container
+	 * @return The newly created <code>Composite</code> with a titled border
+	 *
+	 * @category Layout
+	 */
+	protected final Group addTitledGroup(Composite container, String title) {
+		return this.addTitledGroup(container, title, null);
+	}
+
+	/**
+	 * Creates a new container with a titled border.
+	 *
+	 * @param title The text of the titled border
+	 * @param container The parent container
+	 * @param helpId The topic help ID to be registered for the new group
+	 * @return The newly created <code>Composite</code> with a titled border
+	 *
+	 * @category Layout
+	 */
+	protected final Group addTitledGroup(Composite container,
+	                                      String title,
+	                                      String helpId) {
+
+		return addTitledGroup(container, title, 1, helpId);
+	}
+	
+	/**
+	 * Creates a new container with a titled border.
+	 *
+	 * @param title The text of the titled border
+	 * @param container The parent container
+	 * @param helpId The topic help ID to be registered for the new group
+	 * @return The newly created <code>Composite</code> with a titled border
+	 *
+	 * @category Layout
+	 */
+	protected final Group addTitledGroup(Composite container,
+	                                      String title,
+	                                      int columnCount,
+	                                      String helpId) {
+
+		Group group = this.widgetFactory.createGroup(container, title);
+		//manageWidget(group); TODO unsure if I want to manage groups, 
+		//also should probably rename this addUnmanagedTitledPane
+		group.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+		GridLayout layout = new GridLayout(columnCount, false);
+		layout.marginHeight = 0;
+		layout.marginWidth  = 0;
+		layout.marginTop    = 5;
+		layout.marginLeft   = 5;
+		layout.marginBottom = 5;
+		layout.marginRight  = 5;
+		group.setLayout(layout);
+
+		if (helpId != null) {
+			getHelpSystem().setHelp(group, helpId);
+		}
+
+		return group;
+	}
+
+	/**
+	 * Creates a new unmanaged new toggle button (radio button or check box).  
+	 * Unmanaged means  that this Pane will not handle the enabling/disabling 
+	 * of this widget. The owning object will handle it with its own PaneEnabler 
+	 * or ControlEnabler.
+	 *
+	 * @param parent The parent container
+	 * @param buttonText The button's text
+	 * @param booleanHolder The holder of the selection state
+	 * @param helpId The topic help ID to be registered for the new button
+	 * @return The newly created <code>Button</code>
+	 *
+	 * @category Layout
+	 */
+	private Button addUnmanagedToggleButton(
+			Composite parent,
+	        String buttonText,
+	        WritablePropertyValueModel<Boolean> booleanHolder,
+	        String helpId,
+	        int toggleButtonType) {
+		
+		Button button;
+		
+		if (toggleButtonType == SWT.PUSH) {
+			button = this.widgetFactory.createPushButton(parent, buttonText);
+		}
+		else if (toggleButtonType == SWT.RADIO) {
+			button = this.widgetFactory.createRadioButton(parent, buttonText);
+		}
+		else if (toggleButtonType == SWT.CHECK) {
+			button = this.widgetFactory.createCheckBox(parent, buttonText);
+		}
+		else {
+			button = this.widgetFactory.createButton(parent, buttonText);
+		}
+		
+		button.setLayoutData(new GridData());
+		SWTTools.bind(booleanHolder, button);
+		
+		if (helpId != null) {
+			getHelpSystem().setHelp(button, helpId);
+		}
+		
+		return button;
+	}
+	
+	/**
+	 * Creates a new toggle button (radio button or check box) using the given
+	 * information.
+	 *
+	 * @param parent The parent container
+	 * @param buttonText The button's text
+	 * @param booleanHolder The holder of the selection state
+	 * @param helpId The topic help ID to be registered for the new button
+	 * @return The newly created <code>Button</code>
+	 *
+	 * @category Layout
+	 */
+	private Button addToggleButton(
+			Composite parent,
+	        String buttonText,
+	        WritablePropertyValueModel<Boolean> booleanHolder,
+	        String helpId,
+	        int toggleButtonType) {
+		
+		Button button = addUnmanagedToggleButton(
+				parent, 
+				buttonText, 
+				booleanHolder, 
+				helpId, 
+				toggleButtonType);
+		this.manageWidget(button);
+		return button;
+	}
+
+	/**
+	 * Creates a new check box that can have 3 selection states (selected,
+	 * unselected and partially selected.
+	 *
+	 * @param parent The parent container
+	 * @param text The button's text
+	 * @param booleanHolder The holder of the boolean value where <code>null</code>
+	 * means partially selected
+	 * @param helpId The topic help ID to be registered for the new check box
+	 * @return The newly created <code>TriStateCheckBox</code>
+	 *
+	 * @category Layout
+	 */
+	protected final TriStateCheckBox addTriStateCheckBox(Composite parent,
+	                                                       String text,
+	                                                       WritablePropertyValueModel<Boolean> booleanHolder,
+	                                                       String helpId) {
+
+		TriStateCheckBox checkBox = new TriStateCheckBox(
+			parent,
+			text,
+			this.getWidgetFactory()
+		);
+
+		this.manageWidget(checkBox.getCheckBox());
+
+		TriStateCheckBoxModelAdapter.adapt(
+			booleanHolder,
+			checkBox
+		);
+
+		if (helpId != null) {
+			getHelpSystem().setHelp(checkBox.getCheckBox(), helpId);
+		}
+
+		return checkBox;
+	}
+
+	/**
+	 * Creates a new check box that can have 3 selection states (selected,
+	 * unselected and partially selected.
+	 *
+	 * @param parent The parent container
+	 * @param text The button's text
+	 * @param booleanHolder The holder of the boolean value where <code>null</code>
+	 * means partially selected
+	 * @param stringHolder The holder of the string to put in parenthesis after
+	 * the check box's text when it is partially selected
+	 * @param helpId The topic help ID to be registered for the new check box
+	 * @return The newly created <code>TriStateCheckBox</code>
+	 *
+	 * @category Layout
+	 */
+	protected final TriStateCheckBox addTriStateCheckBoxWithDefault(Composite parent,
+	                                                                  String text,
+	                                                                  WritablePropertyValueModel<Boolean> booleanHolder,
+	                                                                  PropertyValueModel<String> stringHolder,
+	                                                                  String helpId) {
+
+		TriStateCheckBox checkBox = this.addTriStateCheckBox(
+			parent,
+			text,
+			booleanHolder,
+			helpId
+		);
+
+		new LabeledControlUpdater(
+			new LabeledButton(checkBox.getCheckBox()),
+			stringHolder
+		);
+
+		return checkBox;
+	}
+
+	/**
+	 * Requests this pane to populate its widgets with the subject's values.
+	 *
+	 * @category Populate
+	 */
+	protected void doPopulate() {
+		this.log(Tracing.UI_LAYOUT, "   ->doPopulate()");
+	}
+	
+	private void controlEnabledState(PropertyValueModel<Boolean> booleanModel, Control... controls) {
+		this.controlEnabledState_(this.wrapEnabledModel(booleanModel), controls);
+	}
+
+	/**
+	 * Assume the "enabled" models can return null (which is typical with aspect
+	 * adapters etc.).
+	 */
+	private PropertyValueModel<Boolean> wrapEnabledModel(PropertyValueModel<Boolean> booleanModel) {
+		return new TransformationPropertyValueModel<Boolean, Boolean>(booleanModel, NonNullBooleanTransformer.FALSE);
+	}
+	
+	private void controlEnabledState_(PropertyValueModel<Boolean> booleanModel, Control... controls) {
+		SWTTools.controlEnabledState(this.andEnabledModel(booleanModel), controls);
+	}
+	
+	private PropertyValueModel<Boolean> getCombinedEnabledModel() {
+		return (this.combinedEnabledModel != null) ? this.combinedEnabledModel : this.baseEnabledModel;
+	}
+	
+	private boolean getCombinedEnablement() {
+		Boolean enabled = getCombinedEnabledModel().getValue();
+		return (enabled == null) ? true : enabled.booleanValue();
+	}
+	
+	private PropertyValueModel<Boolean> andEnabledModel(PropertyValueModel<Boolean> booleanModel) {
+		return CompositeBooleanPropertyValueModel.and(getCombinedEnabledModel(), booleanModel);
+	}
+	
+	protected void controllerEnablementChanged() {
+		enableWidgets_(getCombinedEnablement());
+	}
+	
+	/**
+	 * Changes the enablement state of the widgets of this pane.
+	 *
+	 * @param enabled <code>true</code> to enable the widgets or <code>false</code>
+	 * to disable them
+	 *
+	 * @category Layout
+	 */
+	public void enableWidgets(boolean enabled) {
+		this.baseEnabledModel.setValue(Boolean.valueOf(enabled));
+		enableWidgets_(getCombinedEnablement());
+	}
+	
+	private void enableWidgets_(boolean enabled) {
+		if (! this.container.isDisposed()) {
+			for (Control control : this.managedWidgets) {
+				control.setEnabled(enabled);
+			}
+			
+			for (Pane<?> subPane : this.managedSubPanes) {
+				subPane.enableWidgets(enabled);
+			}
+		}
+	}
+	
+	private void engageSubjectHolder() {
+		this.subjectHolder.addPropertyChangeListener(PropertyValueModel.VALUE, this.subjectChangeListener);
+	}
+	
+	/**
+	 * engage the specified subject
+	 */
+	protected void engageListeners(T subject) {
+		if (subject != null) {
+			this.engageListeners_(subject);
+		}
+	}
+
+	/**
+	 * specified subject is not null
+	 */
+	protected void engageListeners_(T subject) {
+		this.log(Tracing.UI_LAYOUT, "   ->engageListeners_(" + subject + ')');
+
+		for (String propertyName : this.getPropertyNames()) {
+			subject.addPropertyChangeListener(propertyName, this.aspectChangeListener);
+		}
+	}
+
+	/**
+	 * disengage the specified subject
+	 */
+	protected void disengageListeners(T subject) {
+		if (subject != null) {
+			this.disengageListeners_(subject);
+		}
+	}
+
+	/**
+	 * specified subject is not null
+	 */
+	protected void disengageListeners_(T subject) {
+		this.log(Tracing.UI_LAYOUT, "   ->disengageListeners_(" + subject + ')');
+
+		for (String propertyName : this.getPropertyNames()) {
+			subject.removePropertyChangeListener(propertyName, this.aspectChangeListener);
+		}
+	}
+
+	private void disengageSubjectHolder() {
+		this.subjectHolder.removePropertyChangeListener(PropertyValueModel.VALUE, this.subjectChangeListener);
+	}
+
+	/**
+	 * Returns the main <code>Control</code> of this pane.
+	 *
+	 * @return The main container
+	 *
+	 * @category Layout
+	 */
+	public Composite getControl() {
+		return this.container;
+	}
+
+	/**
+	 * Returns the subject holder used by this pane.
+	 *
+	 * @return The holder of the subject
+	 *
+	 * @category Populate
+	 */
+	protected final PropertyValueModel<T> getSubjectHolder() {
+		return this.subjectHolder;
+	}
+
+	/**
+	 * Returns the factory responsible for creating the widgets.
+	 *
+	 * @return The factory used by this pane to create the widgets
+	 *
+	 * @category Layout
+	 */
+	protected final WidgetFactory getWidgetFactory() {
+		return this.widgetFactory;
+	}
+
+	/**
+	 * Returns the margin taken by a group box, which is the number of pixel the
+	 * group box border and its margin takes before displaying its widgets plus
+	 * 5 pixels since the widgets inside of the group box and the border should
+	 * have that extra 5 pixels.
+	 *
+	 * @return The width taken by the group box border with its margin
+	 *
+	 * @category Layout
+	 */
+	protected final int getGroupBoxMargin() {
+		Group group = this.widgetFactory.createGroup(SWTUtil.getShell(), "");
+		Rectangle clientArea = group.getClientArea();
+		group.dispose();
+		return clientArea.x + 5;
+	}
+
+	/**
+	 * Returns the helps system.
+	 *
+	 * @return The platform's help system
+	 *
+	 * @category Helper
+	 */
+	protected final IWorkbenchHelpSystem getHelpSystem() {
+		return PlatformUI.getWorkbench().getHelpSystem();
+	}
+
+
+	/**
+	 * Determines whether
+	 *
+	 * @return
+	 *
+	 * @category Populate
+	 */
+	protected final boolean isPopulating() {
+		return this.populating;
+	}
+
+	/**
+	 * Logs the given message if the <code>Tracing.DEBUG_LAYOUT</code> is enabled.
+	 *
+	 * @param flag
+	 * @param message The logging message
+	 */
+	protected void log(String flag, String message) {
+		if (flag.equals(Tracing.UI_LAYOUT) && Tracing.booleanDebugOption(Tracing.UI_LAYOUT)) {
+			this.log(message);
+		}
+	}
+
+	protected void log(String message) {
+		Class<?> thisClass = this.getClass();
+		String className = thisClass.getSimpleName();
+
+		if (thisClass.isAnonymousClass()) {
+			className = className.substring(0, className.indexOf('$'));
+			className += "->" + thisClass.getSuperclass().getSimpleName();
+		}
+
+		Tracing.log(className + ": " + message);
+	}
+
+	/**
+	 * Notifies this pane to populate itself using the subject's information.
+	 *
+	 * @category Populate
+	 */
+	private void populate() {
+		if (!this.container.isDisposed()) {
+			this.log(Tracing.UI_LAYOUT, "populate()");
+			this.repopulate();
+		}
+	}
+
+	/**
+	 * Notifies the subject's property associated with the given property name
+	 * has changed.
+	 *
+	 * @param propertyName The property name associated with the property change
+	 *
+	 * @category Populate
+	 */
+	protected void propertyChanged(String propertyName) {
+	}
+
+	/**
+	 * Returns the list of names to listen for properties changing from the
+	 * subject.
+	 *
+	 * @return A non-<code>null</code> list of property names
+	 *
+	 * @category Populate
+	 */
+	protected Collection<String> getPropertyNames() {
+		ArrayList<String> propertyNames = new ArrayList<String>();
+		addPropertyNames(propertyNames);
+		return propertyNames;
+	}
+
+	/**
+	 * Removes the given pane's widgets (those that were registered with
+	 * its left <code>ControlAligner</code>) from this pane's left
+	 * <code>ControlAligner</code> so that their width will no longer be adjusted
+	 * with the width of the widest widget.
+	 *
+	 * @param pane The pane containing the widgets to remove
+	 *
+	 * @category Layout
+	 */
+	protected final void removeAlignLeft(Pane<?> pane) {
+		this.leftControlAligner.remove(pane.leftControlAligner);
+	}
+
+	/**
+	 * Removes the given control from the collection of widgets that are aligned
+	 * to have the same width when they are shown to the left side of the 3
+	 * widget colums.
+	 *
+	 * @param pane The pane to remove, its width will no longer be
+	 * ajusted to be the width of the longest widget
+	 *
+	 * @category Layout
+	 */
+	protected final void removeAlignLeft(Control control) {
+		this.leftControlAligner.remove(control);
+	}
+
+	/**
+	 * Removes the given pane's widgets (those that were registered with
+	 * its right <code>ControlAligner</code>) from this pane's right
+	 * <code>ControlAligner</code> so that their width will no longer be adjusted
+	 * with the width of the widest widget.
+	 *
+	 * @param pane The pane containing the widgets to remove
+	 *
+	 * @category Layout
+	 */
+	protected final void removeAlignRight(Pane<?> pane) {
+		this.rightControlAligner.remove(pane.rightControlAligner);
+	}
+
+	/**
+	 * Removes the given control from the collection of widgets that are aligned
+	 * to have the same width when they are shown to the right side of the 3
+	 * widget colums.
+	 *
+	 * @param pane The pane to remove, its width will no longer be
+	 * ajusted to be the width of the longest widget
+	 *
+	 * @category Layout
+	 */
+	protected final void removeAlignRight(Control control) {
+		this.rightControlAligner.remove(control);
+	}
+
+	/**
+	 * Removes the given pane's controls (those that were registered for
+	 * alignment) from this pane.
+	 *
+	 * @param pane The pane containing the widgets that no longer
+	 * requires their width adjusted with the width of the longest widget
+	 *
+	 * @category Layout
+	 */
+	protected final void removePaneForAlignment(Pane<?> pane) {
+		removeAlignLeft(pane);
+		removeAlignRight(pane);
+	}
+
+	/**
+	 * This method is called (perhaps internally) when this needs to repopulate
+	 * but the object of interest has not changed.
+	 *
+	 * @category Populate
+	 */
+	protected final void repopulate() {
+
+		this.log(Tracing.UI_LAYOUT, "   ->repopulate()");
+
+		// Populate this pane
+		try {
+			setPopulating(true);
+			doPopulate();
+		}
+		finally {
+			setPopulating(false);
+		}
+
+		// Ask the sub-panes to repopulate themselves
+		for (Pane<?> subPane : this.subPanes) {
+			subPane.repopulate();
+		}
+	}
+
+	/**
+	 * Sets the internal flag that is used to determine whether the pane is being
+	 * populated or not. During population, it is required to not update the
+	 * widgets when the model is updated nor to update the model when the widgets
+	 * are being synchronized with the model's values.
+	 *
+	 * @param populating
+	 *
+	 * @category Populate
+	 */
+	protected final void setPopulating(boolean populating) {
+		this.populating = populating;
+	}
+
+	/**
+	 * Either show or hides this pane.
+	 *
+	 * @param visible The new visibility state
+	 */
+	public void setVisible(boolean visible) {
+		if (!this.container.isDisposed()) {
+			this.container.setVisible(visible);
+		}
+	}
+
+	/**
+	 * Returns the nearest <code>Shell</code> displaying the main widget of this
+	 * pane.
+	 *
+	 * @return The nearest window displaying this pane
+	 */
+	public final Shell getShell() {
+		return this.container.getShell();
+	}
+
+	/**
+	 * Returns the subject of this pane.
+	 *
+	 * @return The subject if this pane was not disposed; <code>null</code>
+	 * if it was
+	 *
+	 * @category Populate
+	 */
+	public T getSubject() {
+		return this.subjectHolder.getValue();
+	}
+
+	/**
+	 * The subject has changed, disconnects any listeners from the old subject
+	 * and connects those listeners onto the new subject.
+	 *
+	 * @param oldsubject The old subject or <code>null</code> if none was set
+	 * @param newSubject The new subject or <code>null</code> if none needs to be
+	 * set
+	 *
+	 * @category Populate
+	 */
+	protected final void subjectChanged(T oldSubject, T newSubject) {
+		if (!this.container.isDisposed()) {
+
+			this.log(Tracing.UI_LAYOUT, "subjectChanged()");
+			this.disengageListeners(oldSubject);
+
+			this.repopulate();
+
+			this.engageListeners(newSubject);
+		}
+	}
+
+
+	/**
+	 * Registers another <code>Pane</code> with this one so it can
+	 * be automatically notified about certain events such as engaging or
+	 * disengaging the listeners, etc.
+	 *
+	 * @param subPane The sub-pane to register
+	 *
+	 * @category Controller
+	 */
+	protected final void registerSubPane(Pane<?> subPane) {
+		this.subPanes.add(subPane);
+	}
+
+	/**
+	 * Unregisters the given <code>Pane</code> from this one so it
+	 * can no longer be automatically notified about certain events such as
+	 * engaging or disengaging the listeners, etc.
+	 *
+	 * @param subPane The sub-pane to unregister
+	 *
+	 * @category Controller
+	 */
+	protected final void unregisterSubPane(Pane<?> subPane) {
+		this.subPanes.remove(subPane);
+	}
+
+	private void updatePane(String propertyName) {
+		if (!isPopulating() && !this.container.isDisposed()) {
+			this.populating = true;
+
+			try {
+				propertyChanged(propertyName);
+			}
+			finally {
+				this.populating = false;
+			}
+		}
+	}
+	
+	public void dispose() {
+		this.log(Tracing.UI_LAYOUT, "dispose()");
+
+		// Dispose this pane
+		this.disengageListeners(getSubject());
+		this.disengageSubjectHolder();
+		
+		if (this.combinedEnabledModel != null && this.combinedEnabledModelListener != null) {
+			this.combinedEnabledModel.removePropertyChangeListener(PropertyValueModel.VALUE, this.combinedEnabledModelListener);
+		}
+		
+		this.leftControlAligner.dispose();
+		this.rightControlAligner.dispose();
+
+		// Ask the sub-panes to dispose themselves
+		for (Pane<?> subPane : this.subPanes) {
+			subPane.dispose();
+		}
+	}
+
+}
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/widgets/PostExecution.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/widgets/PostExecution.java
new file mode 100644
index 0000000..0b6b920
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/widgets/PostExecution.java
@@ -0,0 +1,31 @@
+/*******************************************************************************
+ * Copyright (c) 2008 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.ui.internal.widgets;
+
+import org.eclipse.jface.dialogs.Dialog;
+
+/**
+ * This <code>PostExecution</code> is used to post execute a portion of code
+ * once a dialog, that was launched into a different UI thread, has been
+ * disposed.
+ *
+ * @version 2.0
+ * @since 1.0
+ */
+public interface PostExecution<T extends Dialog> {
+
+	/**
+	 * Notifies this post exection the dialog that was launched into a different
+	 * UI thread has been disposed.
+	 *
+	 * @param dialog The dialog that was launched into a different thread
+	 */
+	public void execute(T dialog);
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/widgets/PropertySheetWidgetFactory.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/widgets/PropertySheetWidgetFactory.java
new file mode 100644
index 0000000..dc320a1
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/widgets/PropertySheetWidgetFactory.java
@@ -0,0 +1,61 @@
+/*******************************************************************************
+ * Copyright (c) 2008 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.ui.internal.widgets;
+
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Group;
+import org.eclipse.ui.views.properties.tabbed.TabbedPropertySheetWidgetFactory;
+
+/**
+ * This <code>WidgetFactory</code> is responsible to create the widgets using
+ * <code>TabbedPropertySheetWidgetFactory</code> in order use the form style
+ * (flat-style) look and feel.
+ *
+ * @see TabbedPropertySheetWidgetFactory
+ *
+ * @version 2.0
+ * @since 2.0
+ */
+public class PropertySheetWidgetFactory extends FormWidgetFactory {
+
+	/**
+	 * Creates a new <code>PropertySheetWidgetFactory</code>.
+	 *
+	 * @param widgetFactory The actual factory responsible for creating the new
+	 * widgets
+	 */
+	public PropertySheetWidgetFactory(TabbedPropertySheetWidgetFactory widgetFactory) {
+		super(widgetFactory);
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	public Composite createComposite(Composite parent) {
+		return getWidgetFactory().createComposite(parent);
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	public Group createGroup(Composite parent, String title) {
+		return getWidgetFactory().createGroup(parent, title);
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	public TabbedPropertySheetWidgetFactory getWidgetFactory() {
+		return (TabbedPropertySheetWidgetFactory) super.getWidgetFactory();
+	}
+}
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/widgets/TriStateCheckBox.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/widgets/TriStateCheckBox.java
new file mode 100644
index 0000000..b6f4c7e
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/widgets/TriStateCheckBox.java
@@ -0,0 +1,287 @@
+/*******************************************************************************
+ * Copyright (c) 2008 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.ui.internal.widgets;
+
+import org.eclipse.jpt.ui.WidgetFactory;
+import org.eclipse.swt.events.DisposeListener;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * This <code>TriStateCheckBox</code> can display one of three states:
+ * unchecked, checked, or partially checked. It can be modified via a mouse
+ * selection, via a keyboard selection, or programmatically. The selection state is
+ * represented by a <code>Boolean</code> value where a <code>null</code>
+ * value means partially checked.
+ * <p>
+ * The order of state changes is: unchecked -> partially checked -> checked.
+ *
+ * @version 2.0
+ * @since 2.0
+ */
+@SuppressWarnings("nls")
+public final class TriStateCheckBox
+{
+	/**
+	 * A check box button.
+	 */
+	private final Button button;
+
+	/**
+	 * The current selection state.
+	 */
+	private TriState state;
+
+	/**
+	 * Creates a new <code>TriStateCheckBox</code> with no text.
+	 *
+	 * @param parent The parent composite
+	 * @param widgetFactory The factory used to create the check box
+	 */
+	public TriStateCheckBox(Composite parent, WidgetFactory widgetFactory) {
+		this(parent, null, widgetFactory);
+	}
+
+	/**
+	 * Creates a new <code>TriStateCheckBox</code>.
+	 *
+	 * @param parent The parent composite
+	 * @param text The check box's text
+	 * @param widgetFactory The factory used to create the check box
+	 */
+	public TriStateCheckBox(Composite parent,
+	                        String text,
+	                        WidgetFactory widgetFactory) {
+		super();
+		this.state = TriState.UNCHECKED;
+		this.button = widgetFactory.createCheckBox(parent, text);
+		this.button.addSelectionListener(this.buildSelectionListener());
+	}
+
+	/**
+	 * Convenience method: Adds a dispose listener to the check box.
+	 * The source of any events sent to the listener will be the check box widget.
+	 */
+	public void addDisposeListener(DisposeListener disposeListener) {
+		this.button.addDisposeListener(disposeListener);
+	}
+
+	/**
+	 * Convenience method: Adds a selection listener to the check box.
+	 * The source of any events sent to the listener will be the check box widget.
+	 */
+	public void addSelectionListener(SelectionListener selectionListener) {
+		this.button.addSelectionListener(selectionListener);
+	}
+
+	private SelectionListener buildSelectionListener() {
+		return new SelectionAdapter() {
+			@Override
+			public void widgetSelected(SelectionEvent e) {
+				TriStateCheckBox.this.checkBoxClicked();
+			}
+		};
+	}
+
+	/**
+	 * The check box was clicked, change the tri-state to the next value and
+	 * update the check box's state.
+	 */
+	void checkBoxClicked() {
+		this.state = this.nextState();
+		this.updateCheckBox();
+	}
+
+	/**
+	 * Disposes the check box widget.
+	 */
+	public void dispose() {
+		this.button.dispose();
+	}
+
+	/**
+	 * Returns the <code>Button</code> used to show a tri-state check box.
+	 *
+	 * @return The <code>Button</code> used to show a tri-state check box
+	 */
+	public Button getCheckBox() {
+		return this.button;
+	}
+
+	/**
+	 * Returns the check box's image.
+	 *
+	 * @return The check box's image.
+	 */
+	public Image getImage() {
+		return this.button.getImage();
+	}
+
+	/**
+	 * Returns the check box's selection state.
+	 *
+	 * @return Either <code>true</code> or <code>false</code> for checked or
+	 * unchecked; or <code>null</code> for partially selected
+	 */
+	public Boolean getSelection() {
+		return (this.state == TriState.PARTIALLY_CHECKED) ? null : Boolean.valueOf(this.state == TriState.CHECKED);
+	}
+
+	/**
+	 * Returns the check box's text.
+	 *
+	 * @return The text of the check box
+	 */
+	public String getText() {
+		return this.button.getText();
+	}
+
+	/**
+	 * Returns whether the check box is disposed.
+	 *
+	 * @return <code>true</code> if the check box is disposed; <code>false</code>
+	 * otherwise
+	 */
+	public boolean isDisposed() {
+		return this.button.isDisposed();
+	}
+
+	/**
+	 * Returns whether the check box is enabled.
+	 *
+	 * @return <code>true</code> if the check box is enabled; <code>false</code>
+	 * otherwise
+	 */
+	public boolean isEnabled() {
+		return this.button.isEnabled();
+	}
+
+	/**
+	 * Returns the next state:
+	 *     UNCHECKED -> PARTIALLY_CHECKED
+	 *     PARTIALLY_CHECKED -> CHECKED
+	 *     CHECKED -> UNCHECKED
+	 */
+	private TriState nextState() {
+		switch (this.state) {
+			case UNCHECKED:
+				return TriState.PARTIALLY_CHECKED;
+			case PARTIALLY_CHECKED:
+				return TriState.CHECKED;
+			case CHECKED:
+				return TriState.UNCHECKED;
+			default:
+				throw new IllegalStateException("unknown state: " + this.state);
+		}
+	}
+
+	/**
+	 * Convenience method: Removes a dispose listener from the check box.
+	 */
+	public void removeDisposeListener(DisposeListener disposeListener) {
+		this.button.removeDisposeListener(disposeListener);
+	}
+
+	/**
+	 * Convenience method: Removes a selection listener from the check box.
+	 */
+	public void removeSelectionListener(SelectionListener selectionListener) {
+		this.button.removeSelectionListener(selectionListener);
+	}
+
+	/**
+	 * Changes the check box's enablement state.
+	 *
+	 * @param enabled <code>true</code> to enable the check box or <code>false</code>
+	 * to disable it
+	 */
+	public void setEnabled(boolean enabled) {
+		this.button.setEnabled(enabled);
+	}
+
+	/**
+	 * Sets the check box's image.
+	 *
+	 * @param image The new image of the check box
+	 */
+	public void setImage(Image image) {
+		this.button.setImage(image);
+	}
+
+	/**
+	 * Changes the check box's selection state.
+	 *
+	 * @param selection Either <code>true</code> or <code>false</code> for
+	 * checked and unchecked; or <code>null</code> for partially selected
+	 */
+	public void setSelection(Boolean selection) {
+		TriState old = this.state;
+		this.state = this.stateForBoolean(selection);
+		if (old != this.state) {
+			this.updateCheckBox();
+		}
+	}
+
+	/**
+	 * Sets the check box's text.
+	 *
+	 * @param text The new text of the check box
+	 */
+	public void setText(String text) {
+		this.button.setText(text);
+	}
+
+	/**
+	 * Returns the tri-state corresponding to the boolean.
+	 *
+	 * @param selection The boolean to be converted to a tri-state
+	 */
+	private TriState stateForBoolean(Boolean selection) {
+		return (selection == null) ? TriState.PARTIALLY_CHECKED :
+			selection.booleanValue() ? TriState.CHECKED : TriState.UNCHECKED;
+	}
+
+	/**
+	 * Updates the selection state of the of the check box based on the tri-state
+	 * value.
+	 */
+	void updateCheckBox() {
+		switch (this.state) {
+			case UNCHECKED:
+				this.button.setSelection(false);
+				this.button.setGrayed(false);
+				break;
+			case PARTIALLY_CHECKED:
+				this.button.setSelection(true);
+				this.button.setGrayed(true);
+				break;
+			case CHECKED:
+				this.button.setSelection(true);
+				this.button.setGrayed(false);
+				break;
+			default:
+				throw new IllegalStateException("unknown state: " + this.state);
+		}
+	}
+
+	/**
+	 * An enum containing the possible selections.
+	 */
+	enum TriState {
+		CHECKED,
+		PARTIALLY_CHECKED,
+		UNCHECKED
+	}
+
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/widgets/ValidatingDialog.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/widgets/ValidatingDialog.java
new file mode 100644
index 0000000..d7e6da1
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/widgets/ValidatingDialog.java
@@ -0,0 +1,198 @@
+/*******************************************************************************
+ * Copyright (c) 2008 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.ui.internal.widgets;
+
+import org.eclipse.jpt.utility.internal.node.Node;
+import org.eclipse.jpt.utility.internal.node.Problem;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.widgets.Shell;
+
+/**
+ * This dialog is similar to it superclass, <code>Dialog</code>, with
+ * the added value of an error message label below the main panel. A subclass
+ * can set this error message as needed so that it can inform the user something
+ * incorrect has been entered.
+ * <p>
+ * If there is an error message, it will be shown. If there is a warning
+ * message, it will only be shown if there is no error message. Warning messages
+ * have a different icon than error messages.
+ *
+ * @version 2.0
+ * @since 2.0
+ */
+public abstract class ValidatingDialog<T extends Node> extends Dialog<T> {
+
+	/**
+	 * Creates a new <code>ValidatingDialog</code>.
+	 *
+	 * @param parent The parent shell
+	 */
+	public ValidatingDialog(Shell parent) {
+		super(parent);
+	}
+
+	/**
+	 * Creates a new <code>ValidatingDialog</code>.
+	 *
+	 * @param parent The parent shell
+	 * @param title The dialog's title
+	 */
+	public ValidatingDialog(Shell parent, String title) {
+		super(parent, title);
+	}
+
+	/*
+	 * (non-Javadoc)
+	 */
+	@Override
+	final Node.Validator buildValidator() {
+		return new Node.Validator() {
+			public void pause() {
+			}
+
+			public void resume() {
+			}
+
+			public void validate() {
+				ValidatingDialog.this.validate();
+			}
+		};
+	}
+
+	/**
+	 * Clears the error message from the description pane.
+	 */
+	protected final void clearErrorMessage() {
+		setErrorMessage(null);
+	}
+
+	/**
+	 * Returns the description shown in the description pane.
+	 *
+	 * @return The description under the description's title
+	 */
+	protected String getDescription() {
+		return null;
+	}
+
+	/**
+	 * Returns the image shown in the description pane.
+	 *
+	 * @return The image of the description pane or <code>null</code> if none is
+	 * required
+	 */
+	protected Image getDescriptionImage() {
+		return null;
+	}
+
+	/**
+	 * Returns the title of the description pane.
+	 *
+	 * @return The title shown in the description pane
+	 */
+	protected String getDescriptionTitle() {
+		return null;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 */
+	@Override
+	protected Point getInitialSize() {
+		Point result = getShell().computeSize(SWT.DEFAULT, SWT.DEFAULT);
+		Point paneSize = getPane().getControl().computeSize(SWT.DEFAULT, SWT.DEFAULT);
+		int width = convertHorizontalDLUsToPixels(400);
+		result.x = Math.max(width, paneSize.x);
+		return result;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 */
+	@Override
+	protected final boolean hasTitleArea() {
+		return true;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 */
+	@Override
+	protected void initializeUI() {
+
+		super.initializeUI();
+
+		// Update the description title
+		String descriptionTitle = getDescriptionTitle();
+
+		if (descriptionTitle != null) {
+			setTitle(descriptionTitle);
+		}
+
+		// Update the description title
+		String description = getDescription();
+
+		if (description != null) {
+			setMessage(description);
+		}
+
+		// Update the description image
+		Image image = getDescriptionImage();
+
+		if (image != null) {
+			setTitleImage(image);
+		}
+	}
+
+	/**
+	 * Updates the description pane by showing the given error message and format
+	 * the text with the given list of arguments if any exists.
+	 *
+	 * @param errorMessage The error message to show in the description pane
+	 * @param arguments The list of arguments used to format the error message
+	 */
+	protected final void setErrorMessage(String errorMessage, Object... arguments) {
+		setErrorMessage(NLS.bind(errorMessage, arguments));
+	}
+
+	/**
+	 * Updates the error message, either shows the first error problem or hides
+	 * the error pane. If the progress bar is shown, then the error message will
+	 * not be shown.
+	 */
+	private void updateErrorMessage() {
+		if (getSubject().hasBranchProblems()) {
+			Problem problem = getSubject().branchProblems().next();
+			setErrorMessage(problem.messageKey(), problem.messageArguments());
+		}
+		// TODO: It would be nice to add warnings to the model
+//		else if (this.subject().hasBranchWarnings()) {
+//			Problem problem = this.subject().branchWarnings().next();
+//			this.setWarningMessageKey(problem.getMessageKey(), problem.getMessageArguments());
+//		}
+		else {
+			clearErrorMessage();
+		}
+	}
+
+	/**
+	 * Validates the state object and based on its status, update the description
+	 * pane to show the first error if any exists and update the enablement of
+	 * the OK button.
+	 */
+	private void validate() {
+		getSubject().validateBranch();
+		updateErrorMessage();
+		getButton(OK).setEnabled(!getSubject().hasBranchProblems());
+	}
+}
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/DatabaseSchemaWizardPage.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/DatabaseSchemaWizardPage.java
new file mode 100644
index 0000000..43494a9
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/DatabaseSchemaWizardPage.java
@@ -0,0 +1,445 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2009 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.ui.internal.wizards;
+
+import java.util.EventListener;
+
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.preference.PreferenceDialog;
+import org.eclipse.jface.wizard.WizardPage;
+import org.eclipse.jpt.core.JpaProject;
+import org.eclipse.jpt.db.ConnectionAdapter;
+import org.eclipse.jpt.db.ConnectionListener;
+import org.eclipse.jpt.db.ConnectionProfile;
+import org.eclipse.jpt.db.Schema;
+import org.eclipse.jpt.db.SchemaContainer;
+import org.eclipse.jpt.ui.internal.JpaHelpContextIds;
+import org.eclipse.jpt.ui.internal.JptUiMessages;
+import org.eclipse.jpt.ui.internal.properties.JpaProjectPropertiesPage;
+import org.eclipse.jpt.utility.internal.ListenerList;
+import org.eclipse.jpt.utility.internal.iterables.EmptyIterable;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Group;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Link;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.dialogs.PreferencesUtil;
+
+/**
+ * Most of the behavior is in DatabaseGroup....
+ * 
+ * We open the wizard page with the JPA project's connection profile and
+ * default schema selected (if possible), but then the selections are driven
+ * by the user. If the user re-selects the JPA project's connection profile,
+ * we will pre-select the project's default schema if possible.
+ */
+public class DatabaseSchemaWizardPage extends WizardPage {
+
+	final JpaProject jpaProject;
+
+	private final ListenerList<Listener> listenerList = new ListenerList<Listener>(Listener.class);
+
+	private DatabaseGroup databaseGroup;
+
+
+	public DatabaseSchemaWizardPage(JpaProject jpaProject) {
+		super("Database Schema"); //$NON-NLS-1$
+		if (jpaProject == null) {
+			throw new NullPointerException();
+		}
+		this.jpaProject = jpaProject;
+		this.setTitle(JptUiMessages.DatabaseSchemaWizardPage_title);
+		this.setMessage(JptUiMessages.DatabaseSchemaWizardPage_desc);
+	}
+
+	public void createControl(Composite parent) {
+		this.setPageComplete(false);
+		this.setControl(this.buildTopLevelControl(parent));
+	}
+
+	private Control buildTopLevelControl(Composite parent) {
+		Composite composite = new Composite(parent, SWT.NULL);
+		composite.setLayout(new GridLayout());
+		this.databaseGroup = new DatabaseGroup(composite);
+		Dialog.applyDialogFont(parent);
+		PlatformUI.getWorkbench().getHelpSystem().setHelp(composite, JpaHelpContextIds.PROPERTIES_JAVA_PERSISTENCE_CONNECTION);
+		return composite;
+	}
+
+	public ConnectionProfile getJpaProjectConnectionProfile() {
+		return this.jpaProject.getConnectionProfile();
+	}
+	
+	public Schema getSelectedSchema() {
+		return this.databaseGroup.getSelectedSchema();
+	}
+
+	@Override
+	public void dispose() {
+		this.databaseGroup.dispose();
+		super.dispose();
+	}
+
+
+	// ********** listeners **********
+
+	public void addListener(Listener listener) {
+		this.listenerList.add(listener);
+	}
+
+	public void removeListener(Listener listener) {
+		this.listenerList.remove(listener);
+	}
+
+	void fireSchemaChanged(Schema schema) {
+		this.setPageComplete(schema != null);
+		for (Listener listener : this.listenerList.getListeners()) {
+			listener.selectedSchemaChanged(schema);
+		}
+	}
+
+
+	// ********** listener interface **********
+
+	/**
+	 * Allows clients to listen for changes to the selected connection profile
+	 * and schema.
+	 */
+	public interface Listener extends EventListener {
+		void selectedSchemaChanged(Schema schema);
+	}
+
+
+	// ********** database group **********
+
+	/**
+	 * schema combo-box
+	 * add project connection link
+	 * reconnect link
+	 */
+	class DatabaseGroup {
+
+		// these are kept in synch with the selection
+		private Schema selectedSchema;
+
+		private final Combo schemaComboBox;
+
+		private final Link reconnectLink;
+
+		private Link addJpaProjectConnectionLink;
+		
+		private final ConnectionListener connectionListener;
+
+
+		// ********** construction **********
+
+		DatabaseGroup(Composite composite) {
+			super();
+
+			Group group = new Group(composite, SWT.NONE);
+			group.setLayout(new GridLayout(2, false));  // false = do not make columns equal width
+			group.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+			group.setText(JptUiMessages.DatabaseSchemaWizardPage_schemaSettings);
+			// TODO PlatformUI.getWorkbench().getHelpSystem().setHelp(this.group, JpaHelpContextIds.XXX);
+
+			// schema combo-box
+			this.buildLabel(group, 1, JptUiMessages.DatabaseSchemaWizardPage_schema);
+			this.schemaComboBox = this.buildComboBox(group, this.buildSchemaComboBoxSelectionListener());
+			
+			String message = (this.projectHasAConnection()) ?
+				JptUiMessages.DatabaseSchemaWizardPage_schemaInfo :
+				JptUiMessages.DatabaseSchemaWizardPage_connectionInfo;
+			
+			this.buildLabel(group, 2, message);
+
+			// add project's connection link
+			if( ! this.projectHasAConnection()) {
+				this.addJpaProjectConnectionLink = this.buildLink(group, 
+							JptUiMessages.DatabaseSchemaWizardPage_addConnectionToProject, 
+							this.buildAddJpaProjectConnectionLinkListener());
+			}
+
+			// reconnect link
+			this.reconnectLink = this.buildLink(group, JptUiMessages.DatabaseSchemaWizardPage_connectLink, this.buildReconnectLinkSelectionListener());
+			this.reconnectLink.setEnabled(true);
+
+			this.selectedSchema = this.getDefaultSchema();
+
+			if (this.selectedSchema != null) {
+				DatabaseSchemaWizardPage.this.fireSchemaChanged(this.selectedSchema);
+			}
+
+			this.connectionListener = this.buildConnectionListener();
+			this.addJpaProjectConnectionProfileListener(this.connectionListener);
+
+			this.updateSchemaComboBox();
+			this.updateReconnectLink();
+		}
+
+
+		// ********** intra-wizard methods **********
+
+		Schema getSelectedSchema() {
+			return this.selectedSchema;
+		}
+
+		void dispose() {
+			if(this.projectHasAConnection()) {
+				this.getJpaProjectConnectionProfile().removeConnectionListener(this.connectionListener);
+			}
+		}
+
+
+		// ********** internal methods **********
+
+		void addJpaProjectConnectionListener() {
+			this.addJpaProjectConnectionProfileListener(this.connectionListener);
+		}
+		
+		
+		private void addJpaProjectConnectionProfileListener(ConnectionListener listener) {
+			if(this.projectHasAConnection()) {
+				this.getJpaProjectConnectionProfile().addConnectionListener(listener);
+			}
+		}
+
+		private boolean projectHasAConnection() {
+			return this.getJpaProjectConnectionProfile() != null;
+		}
+		
+		/**
+		 * this can return null;
+		 * called at start-up and when the selected connection profile changes
+		 */
+		private ConnectionProfile getJpaProjectConnectionProfile() {
+			return DatabaseSchemaWizardPage.this.jpaProject.getConnectionProfile();
+		}
+
+		/**
+		 * this can return null;
+		 * called at start-up and when the selected connection profile changes
+		 */
+		private Schema getDefaultSchema() {
+			return DatabaseSchemaWizardPage.this.jpaProject.getDefaultDbSchema();
+		}
+
+		private SchemaContainer getDefaultSchemaContainer() {
+			return DatabaseSchemaWizardPage.this.jpaProject.getDefaultDbSchemaContainer();
+		}
+
+		/**
+		 * called at start-up and when the selected connection profile changes
+		 */
+		private void updateReconnectLink() {
+			this.reconnectLink.setEnabled(this.reconnectLinkCanBeEnabled());
+		}
+
+		void updateAddJpaProjectConnectionLink() {
+			this.addJpaProjectConnectionLink.setEnabled(this.addJpaProjectConnectionLinkCanBeEnabled());
+		}
+
+		private boolean reconnectLinkCanBeEnabled() {
+			if(this.projectHasAConnection()) {
+				return this.getJpaProjectConnectionProfile().isInactive();
+			}
+			return false;
+		}
+
+		private boolean addJpaProjectConnectionLinkCanBeEnabled() {
+			return ! this.projectHasAConnection();
+		}
+
+		/**
+		 * the schema combo-box is updated at start-up and
+		 * when the selected connection profile changes
+		 */
+		private void updateSchemaComboBox() {
+			this.schemaComboBox.removeAll();
+			for (String name : this.getSchemaNames()) {
+				this.schemaComboBox.add(name);
+			}
+			// the current schema *should* be in the current connection profile
+			if (this.selectedSchema != null) {
+				this.schemaComboBox.select(this.schemaComboBox.indexOf(this.selectedSchema.getName()));
+			}
+		}
+
+		private Iterable<String> getSchemaNames() {
+			SchemaContainer sc = this.getDefaultSchemaContainer();
+			// use schema *names* since the combo-box is read-only
+			return (sc != null) ? sc.getSortedSchemaNames() : EmptyIterable.<String>instance();
+		}
+
+		// ********** listener callbacks **********
+
+		void selectedSchemaChanged() {
+			Schema old = this.selectedSchema;
+			this.selectedSchema = this.getDefaultSchemaContainer().getSchemaNamed(this.schemaComboBox.getText());
+			if (this.selectedSchema != old) {
+				DatabaseSchemaWizardPage.this.fireSchemaChanged(this.selectedSchema);
+			}
+		}
+
+		void reconnect() {
+			this.getJpaProjectConnectionProfile().connect();
+			// everything should be synchronized when we get the resulting open event
+		}
+
+		/**
+		 * called when
+		 *     - a connection is set to the Jpa project
+		 *     - the connection was opened
+		 *     - the connection was closed (never happens?)
+		 * we need to update the schema stuff and the reconnect link
+		 */
+		void connectionChanged() {
+			Schema old = this.selectedSchema;
+			this.selectedSchema = this.getDefaultSchema();
+			if (this.selectedSchema != old) {
+				DatabaseSchemaWizardPage.this.fireSchemaChanged(this.selectedSchema);
+			}
+			this.updateSchemaComboBox();
+			this.updateReconnectLink();
+		}
+
+
+		// ********** listeners **********
+
+		private SelectionListener buildSchemaComboBoxSelectionListener() {
+			return new SelectionListener() {
+				public void widgetDefaultSelected(SelectionEvent event) {
+					// nothing special for "default" (double-click?)
+					this.widgetSelected(event);
+				}
+				public void widgetSelected(SelectionEvent event) {
+					DatabaseGroup.this.selectedSchemaChanged();
+				}
+				@Override
+				public String toString() {
+					return "DatabaseSchemaWizardPage schema combo-box selection listener"; //$NON-NLS-1$
+				}
+			};
+		}
+
+		private SelectionListener buildReconnectLinkSelectionListener() {
+			return new SelectionAdapter() {
+				@Override
+				public void widgetSelected(SelectionEvent event) {
+					DatabaseGroup.this.reconnect();
+				}
+				@Override
+				public String toString() {
+					return "DatabaseSchemaWizardPage reconnect link selection listener"; //$NON-NLS-1$
+				}
+			};
+		}
+
+		private ConnectionListener buildConnectionListener() {
+			return new ConnectionAdapter() {
+				@Override
+				public void opened(ConnectionProfile cp) {
+					this.connectionChanged();
+				}
+				@Override  // this probably won't ever get called...
+				public void closed(ConnectionProfile cp) {
+					this.connectionChanged();
+				}
+				private void connectionChanged() {
+					Display.getDefault().asyncExec(
+						new Runnable() {
+							public void run() {
+								DatabaseGroup.this.connectionChanged();
+							}
+						}
+					);
+				}
+				@Override
+				public String toString() {
+					return "DatabaseSchemaWizardPage connection listener"; //$NON-NLS-1$
+				}
+			};
+		}
+
+		private SelectionListener buildAddJpaProjectConnectionLinkListener() {
+			return new SelectionAdapter() {
+				@Override
+				public void widgetSelected(SelectionEvent e) {
+					DatabaseGroup.this.promptToConfigJpaProjectConnection();
+					
+					DatabaseGroup.this.addJpaProjectConnectionListener();
+					DatabaseGroup.this.updateAddJpaProjectConnectionLink();
+					DatabaseGroup.this.connectionChanged();
+				}
+				@Override
+				public String toString() {
+					return "DatabaseSchemaWizardPage AddProjectConnection link selection listener"; //$NON-NLS-1$
+				}
+			};
+		}
+
+		void promptToConfigJpaProjectConnection() {
+			PreferenceDialog dialog =
+				PreferencesUtil.createPropertyDialogOn(
+					getShell(), DatabaseSchemaWizardPage.this.jpaProject.getProject(),
+					JpaProjectPropertiesPage.PROP_ID,
+					null,
+					null);
+			dialog.open();
+		}
+
+		// ********** UI components **********
+
+		/**
+		 * build and return a label
+		 */
+		private Label buildLabel(Composite parent, int span, String text) {
+			Label label = new Label(parent, SWT.NONE);
+			label.setText(text);
+			GridData gd = new GridData();
+			gd.horizontalSpan = span;
+			label.setLayoutData(gd);
+			return label;
+		}
+
+		/**
+		 * build and return a combo-box
+		 */
+		private Combo buildComboBox(Composite parent, SelectionListener listener) {
+			Combo combo = new Combo(parent, SWT.BORDER | SWT.READ_ONLY);
+			combo.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+			combo.addSelectionListener(listener);
+			return combo;
+		}
+
+		/**
+		 * build and return a link
+		 */
+		private Link buildLink(Composite parent, String text, SelectionListener listener) {
+			Link link = new Link(parent, SWT.NONE);
+			GridData data = new GridData(GridData.END, GridData.CENTER, false, false);
+			data.horizontalSpan = 2;
+			link.setLayoutData(data);
+			link.setText(text);
+			link.addSelectionListener(listener);
+			return link;
+		}
+
+	}
+
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/JpaFacetActionPage.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/JpaFacetActionPage.java
new file mode 100644
index 0000000..950d2e7
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/JpaFacetActionPage.java
@@ -0,0 +1,203 @@
+/*******************************************************************************
+ *  Copyright (c) 2009  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.ui.internal.wizards;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jpt.core.internal.facet.JpaFacetDataModelProperties;
+import org.eclipse.jpt.ui.JptUiPlugin;
+import org.eclipse.jpt.ui.internal.JpaHelpContextIds;
+import org.eclipse.jpt.ui.internal.JptUiIcons;
+import org.eclipse.jpt.ui.internal.JptUiMessages;
+import org.eclipse.jst.common.project.facet.core.libprov.LibraryInstallDelegate;
+import org.eclipse.jst.common.project.facet.ui.libprov.LibraryProviderFrameworkUi;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Group;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.help.IWorkbenchHelpSystem;
+import org.eclipse.wst.common.project.facet.core.IFacetedProjectWorkingCopy;
+import org.eclipse.wst.common.project.facet.core.events.IFacetedProjectEvent;
+import org.eclipse.wst.common.project.facet.core.events.IFacetedProjectListener;
+import org.eclipse.wst.common.project.facet.ui.ModifyFacetedProjectWizard;
+import org.eclipse.wst.web.ui.internal.wizards.DataModelFacetInstallPage;
+
+public abstract class JpaFacetActionPage
+	extends DataModelFacetInstallPage
+	implements JpaFacetDataModelProperties
+{
+	protected JpaFacetActionPage(String pageName) {
+		super(pageName);
+		setTitle(JptUiMessages.JpaFacetWizardPage_title);
+		setDescription(JptUiMessages.JpaFacetWizardPage_description);
+		setImageDescriptor(JptUiPlugin.getImageDescriptor(JptUiIcons.JPA_WIZ_BANNER));
+	}
+	
+	
+	@Override
+	protected Composite createTopLevelComposite(Composite parent) {
+		Composite composite = new Composite(parent, SWT.NULL);
+		GridLayout layout = new GridLayout();
+		composite.setLayout(layout);
+		
+		addSubComposites(composite);
+		
+		setUpRuntimeListener();
+		
+		Dialog.applyDialogFont(parent);
+		PlatformUI.getWorkbench().getHelpSystem().setHelp(parent, JpaHelpContextIds.DIALOG_JPA_FACET);
+		
+		return composite;
+	}
+	
+	protected abstract void  addSubComposites(Composite composite);
+	
+	private void setUpRuntimeListener() {
+	    final IFacetedProjectWorkingCopy wc = ( (ModifyFacetedProjectWizard) getWizard() ).getFacetedProjectWorkingCopy();
+		// must do it manually the first time
+		model.setProperty(RUNTIME, wc.getPrimaryRuntime());
+		wc.addListener(
+			new IFacetedProjectListener() {
+				public void handleEvent( final IFacetedProjectEvent event ) {
+					model.setProperty(RUNTIME, wc.getPrimaryRuntime());
+				}
+			},
+			IFacetedProjectEvent.Type.PRIMARY_RUNTIME_CHANGED
+		);
+	}
+	
+	protected Button createButton(Composite container, int span, String text, int style) {
+		Button button = new Button(container, SWT.NONE | style);
+		button.setText(text);
+		GridData gd = new GridData();
+		gd.horizontalSpan = span;
+		button.setLayoutData(gd);
+		return button;
+	}
+	
+	protected Combo createCombo(Composite container, int span, boolean fillHorizontal) {
+		Combo combo = new Combo(container, SWT.BORDER | SWT.SINGLE | SWT.READ_ONLY);
+		GridData gd;
+		if (fillHorizontal) {
+			gd = new GridData(GridData.FILL_HORIZONTAL);
+		}
+		else {
+			gd = new GridData();
+		}
+		gd.horizontalSpan = span;
+		combo.setLayoutData(gd);
+		return combo;
+	}
+	
+	@Override
+	protected String[] getValidationPropertyNames() {
+		return new String[] {
+			PLATFORM_ID,
+			CONNECTION,
+			USER_WANTS_TO_OVERRIDE_DEFAULT_CATALOG,
+			USER_OVERRIDE_DEFAULT_CATALOG,
+			USER_WANTS_TO_OVERRIDE_DEFAULT_SCHEMA,
+			USER_OVERRIDE_DEFAULT_SCHEMA,
+			DISCOVER_ANNOTATED_CLASSES,
+			LIBRARY_PROVIDER_DELEGATE
+		};
+	}
+	
+	@Override
+	public boolean isPageComplete() {
+		if (! super.isPageComplete()) {
+			return false;
+		}
+		else {
+			IStatus status = model.validate(); 
+			if (status.getSeverity() == IStatus.ERROR) {
+				setErrorMessage(status.getMessage());
+				return false;
+			};
+			setErrorMessage(null);
+			return true;
+		}
+	}
+	
+	@Override
+	public void setVisible(boolean visible) {
+		super.setVisible(visible);
+		if (visible) {
+			setErrorMessage();
+		}
+	}
+	
+	protected final IWorkbenchHelpSystem getHelpSystem() {
+		return PlatformUI.getWorkbench().getHelpSystem();
+	}
+	
+	
+	protected final class PlatformGroup
+	{
+		private final Combo platformCombo;
+		
+		
+		public PlatformGroup(Composite composite) {
+			Group group = new Group(composite, SWT.NONE);
+			group.setText(JptUiMessages.JpaFacetWizardPage_platformLabel);
+			group.setLayout(new GridLayout());
+			group.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+			PlatformUI.getWorkbench().getHelpSystem().setHelp(group, JpaHelpContextIds.DIALOG_JPA_PLATFORM);
+
+			platformCombo = createCombo(group, 1, true);
+			synchHelper.synchCombo(platformCombo, PLATFORM_ID, null);
+		}
+	}
+	
+	
+	protected final class ClasspathConfigGroup
+	{
+		public ClasspathConfigGroup(Composite composite) {
+			
+			final LibraryInstallDelegate librariesInstallDelegate
+				= (LibraryInstallDelegate) getDataModel().getProperty(LIBRARY_PROVIDER_DELEGATE);
+			
+			final Composite librariesComposite 
+				= (Composite) LibraryProviderFrameworkUi.createInstallLibraryPanel(
+					composite, librariesInstallDelegate, 
+					JptUiMessages.JpaFacetWizardPage_jpaImplementationLabel );
+			librariesComposite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+			PlatformUI.getWorkbench().getHelpSystem().setHelp(librariesComposite, JpaHelpContextIds.NEW_JPA_PROJECT_CONTENT_PAGE_CLASSPATH);			
+		}
+	}
+	
+	
+	protected final class PersistentClassManagementGroup
+	{
+		private final Button discoverClassesButton;
+		
+		private final Button listClassesButton;
+		
+		
+		public PersistentClassManagementGroup(Composite composite) {
+			Group group = new Group(composite, SWT.NONE);
+			group.setText(JptUiMessages.JpaFacetWizardPage_persistentClassManagementLabel);
+			group.setLayout(new GridLayout());
+			group.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+			PlatformUI.getWorkbench().getHelpSystem().setHelp(group, JpaHelpContextIds.NEW_JPA_PROJECT_CONTENT_PAGE_CLASSPATH);
+			
+			discoverClassesButton = createButton(group, 1, JptUiMessages.JpaFacetWizardPage_discoverClassesButton, SWT.RADIO);
+			synchHelper.synchRadio(discoverClassesButton, DISCOVER_ANNOTATED_CLASSES, null);
+			
+			listClassesButton = createButton(group, 1, JptUiMessages.JpaFacetWizardPage_listClassesButton, SWT.RADIO);
+			synchHelper.synchRadio(listClassesButton, LIST_ANNOTATED_CLASSES, null);
+		}
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/JpaFacetInstallPage.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/JpaFacetInstallPage.java
new file mode 100644
index 0000000..973ecbd
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/JpaFacetInstallPage.java
@@ -0,0 +1,231 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2009 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.ui.internal.wizards;
+
+import org.eclipse.jpt.core.internal.facet.JpaFacetInstallDataModelProperties;
+import org.eclipse.jpt.db.ConnectionProfile;
+import org.eclipse.jpt.db.JptDbPlugin;
+import org.eclipse.jpt.db.ui.internal.DTPUiTools;
+import org.eclipse.jpt.ui.internal.JpaHelpContextIds;
+import org.eclipse.jpt.ui.internal.JptUiMessages;
+import org.eclipse.jpt.utility.internal.ArrayTools;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Group;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Link;
+import org.eclipse.ui.PlatformUI;
+
+public class JpaFacetInstallPage
+	extends JpaFacetActionPage
+	implements JpaFacetInstallDataModelProperties
+{
+	public JpaFacetInstallPage() {
+		super("jpt.jpa.facet.install.page"); //$NON-NLS-1$
+	}
+	
+	
+	@Override
+	protected Composite createTopLevelComposite(Composite parent) {
+		Composite composite = super.createTopLevelComposite(parent);
+		this.getHelpSystem().setHelp(composite, JpaHelpContextIds.NEW_JPA_PROJECT_JPA_FACET);
+		return composite;
+	}
+	
+	@Override
+	protected void addSubComposites(Composite composite) {
+		new PlatformGroup(composite);
+		new ClasspathConfigGroup(composite);
+		new ConnectionGroup(composite);
+		new PersistentClassManagementGroup(composite);
+		new OrmXmlGroup(composite);
+	}
+	
+	@Override
+	protected String[] getValidationPropertyNames() {
+		String[] validationPropertyNames = super.getValidationPropertyNames();
+		return ArrayTools.addAll(
+				validationPropertyNames,
+				USER_WANTS_TO_ADD_DB_DRIVER_JARS_TO_CLASSPATH,
+				DB_DRIVER_NAME);
+	}
+	
+	
+	protected final class ConnectionGroup
+	{
+		private final Combo connectionCombo;
+		
+		private Link connectionLink;
+		
+		private Link connectLink;
+		
+		private final Button addDriverLibraryButton;
+		
+		private final Label driverLibraryLabel;
+		
+		private final Combo driverLibraryCombo;
+		
+		private final Button overrideDefaultCatalogButton;
+		
+		private final Label defaultCatalogLabel;
+		
+		private final Combo defaultCatalogCombo;
+		
+		private final Button overrideDefaultSchemaButton;
+		
+		private final Label defaultSchemaLabel;
+		
+		private final Combo defaultSchemaCombo;
+		
+		
+		public ConnectionGroup(Composite composite) {
+			Group group = new Group(composite, SWT.NONE);
+			group.setText(JptUiMessages.JpaFacetWizardPage_connectionLabel);
+			group.setLayout(new GridLayout(3, false));
+			group.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+			PlatformUI.getWorkbench().getHelpSystem().setHelp(group, JpaHelpContextIds.NEW_JPA_PROJECT_CONTENT_PAGE_DATABASE);
+			
+			connectionCombo = createCombo(group, 3, true);
+			synchHelper.synchCombo(connectionCombo, CONNECTION, null);
+			connectionCombo.addSelectionListener(
+				new SelectionAdapter() {
+					@Override
+					public void widgetSelected(SelectionEvent e) {
+						updateConnectLink();
+					}
+				});
+			
+			connectionLink = new Link(group, SWT.NONE);
+			GridData data = new GridData(GridData.END, GridData.CENTER, false, false);
+			data.horizontalSpan = 2;
+			connectionLink.setLayoutData(data);
+			connectionLink.setText(JptUiMessages.JpaFacetWizardPage_connectionLink);
+			connectionLink.addSelectionListener(
+				new SelectionAdapter() {
+					@Override
+					public void widgetSelected(SelectionEvent e) {
+						openNewConnectionWizard();
+					}
+				}
+			);
+			
+			connectLink = new Link(group, SWT.NONE);
+			data = new GridData(GridData.END, GridData.CENTER, false, false);
+			data.horizontalSpan = 2;
+			connectLink.setLayoutData(data);
+			connectLink.setText(JptUiMessages.JpaFacetWizardPage_connectLink);
+			connectLink.setEnabled(false);
+			connectLink.addSelectionListener(
+				new SelectionAdapter() {
+					@Override
+					public void widgetSelected(SelectionEvent e) {
+						openConnectionProfile();
+					}
+				});
+			
+			addDriverLibraryButton = createButton(group, 3, JptUiMessages.JpaFacetWizardPage_addDriverLibraryLabel, SWT.CHECK);
+			addDriverLibraryButton.setSelection(false);
+			synchHelper.synchCheckbox(addDriverLibraryButton, USER_WANTS_TO_ADD_DB_DRIVER_JARS_TO_CLASSPATH, null);
+			
+			driverLibraryLabel = new Label(group, SWT.LEFT);
+			driverLibraryLabel.setText(JptUiMessages.JpaFacetWizardPage_driverLibraryLabel);
+			GridData gd = new GridData();
+			gd.horizontalSpan = 1;
+			driverLibraryLabel.setLayoutData(gd);
+			
+			driverLibraryCombo = createCombo(group, 1, true);
+			synchHelper.synchCombo(
+				driverLibraryCombo, DB_DRIVER_NAME, 
+				new Control[] {driverLibraryLabel});
+			
+			overrideDefaultCatalogButton = createButton(group, 3, JptUiMessages.JpaFacetWizardPage_overrideDefaultCatalogLabel, SWT.CHECK);
+			overrideDefaultCatalogButton.setSelection(false);
+			synchHelper.synchCheckbox(overrideDefaultCatalogButton, USER_WANTS_TO_OVERRIDE_DEFAULT_CATALOG, null);
+			
+			defaultCatalogLabel = new Label(group, SWT.LEFT);
+			defaultCatalogLabel.setText(JptUiMessages.JpaFacetWizardPage_defaultCatalogLabel);
+			gd = new GridData();
+			gd.horizontalSpan = 1;
+			defaultCatalogLabel.setLayoutData(gd);
+			
+			defaultCatalogCombo = createCombo(group, 1, true);
+			synchHelper.synchCombo(
+				defaultCatalogCombo, USER_OVERRIDE_DEFAULT_CATALOG, 
+				new Control[] {defaultCatalogLabel});
+			
+			overrideDefaultSchemaButton = createButton(group, 3, JptUiMessages.JpaFacetWizardPage_overrideDefaultSchemaLabel, SWT.CHECK);
+			overrideDefaultSchemaButton.setSelection(false);
+			synchHelper.synchCheckbox(overrideDefaultSchemaButton, USER_WANTS_TO_OVERRIDE_DEFAULT_SCHEMA, null);
+			
+			defaultSchemaLabel = new Label(group, SWT.LEFT);
+			defaultSchemaLabel.setText(JptUiMessages.JpaFacetWizardPage_defaultSchemaLabel);
+			gd = new GridData();
+			gd.horizontalSpan = 1;
+			defaultSchemaLabel.setLayoutData(gd);
+			
+			defaultSchemaCombo = createCombo(group, 1, true);
+			synchHelper.synchCombo(
+				defaultSchemaCombo, USER_OVERRIDE_DEFAULT_SCHEMA, 
+				new Control[] {defaultSchemaLabel});
+		}
+		
+		private void openNewConnectionWizard() {
+			String connectionName = DTPUiTools.createNewConnectionProfile();
+			if (connectionName != null) {
+				model.setProperty(CONNECTION, connectionName);
+			}
+		}
+		
+		private void openConnectionProfile() {
+			ConnectionProfile cp = getConnectionProfile();
+			if (cp != null) {
+				cp.connect();
+				model.setBooleanProperty(CONNECTION_ACTIVE, cp.isActive());
+				updateConnectLink();
+			}
+		}
+		
+		private void updateConnectLink() {
+			ConnectionProfile cp = this.getConnectionProfile();
+			connectLink.setEnabled((cp != null) && cp.isDisconnected());
+			addDriverLibraryButton.setEnabled(cp != null);
+		}
+		
+		private ConnectionProfile getConnectionProfile() {
+			// we just use the connection profile to log in, so go to the the db plug-in
+			return JptDbPlugin.instance().getConnectionProfileFactory().buildConnectionProfile(model.getStringProperty(CONNECTION));
+		}
+	}
+	
+	
+	protected final class OrmXmlGroup
+	{
+		private final Button createOrmXmlButton;
+
+
+		public OrmXmlGroup(Composite composite) {
+			Composite group = new Composite(composite, SWT.NONE);
+			group.setLayout(new GridLayout());
+			group.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+			PlatformUI.getWorkbench().getHelpSystem().setHelp(group, JpaHelpContextIds.DIALOG_CREATE_ORM);
+
+			createOrmXmlButton = new Button(group, SWT.CHECK);
+			createOrmXmlButton.setText(JptUiMessages.JpaFacetWizardPage_createOrmXmlButton);
+			synchHelper.synchCheckbox(createOrmXmlButton, CREATE_ORM_XML, null);
+		}
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/JpaFacetVersionChangePage.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/JpaFacetVersionChangePage.java
new file mode 100644
index 0000000..9be0ce0
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/JpaFacetVersionChangePage.java
@@ -0,0 +1,44 @@
+/*******************************************************************************
+ *  Copyright (c) 2009  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.ui.internal.wizards;
+
+import org.eclipse.swt.widgets.Composite;
+
+public class JpaFacetVersionChangePage
+	extends JpaFacetActionPage
+{
+	public JpaFacetVersionChangePage() {
+		super("jpt.jpa.facet.version-change.page"); //$NON-NLS-1$
+	}
+	
+	
+	@Override
+	protected Composite createTopLevelComposite(Composite parent) {
+		Composite composite = super.createTopLevelComposite(parent);
+		// TODO
+		//this.getHelpSystem().setHelp(composite, JpaHelpContextIds.NEW_JPA_PROJECT_JPA_FACET);
+		return composite;
+	}
+	
+	@Override
+	protected void addSubComposites(Composite composite) {
+		new PlatformGroup(composite);
+		new ClasspathConfigGroup(composite);
+		//new ConnectionGroup(composite);
+		//new PersistentClassManagementGroup(composite);
+	}
+	
+	@Override
+	protected String[] getValidationPropertyNames() {
+		// nothing new here *just* yet
+		return super.getValidationPropertyNames();
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/NewEntityDropDownAction.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/NewEntityDropDownAction.java
new file mode 100644
index 0000000..1185fc2
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/NewEntityDropDownAction.java
@@ -0,0 +1,261 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2010 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Oracle - copied and modified from NewJavaEEDropDownAction and NewTypeDropDownAction
+ *******************************************************************************/
+package org.eclipse.jpt.ui.internal.wizards;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IExtensionPoint;
+import org.eclipse.core.runtime.Platform;
+
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Menu;
+import org.eclipse.swt.widgets.Shell;
+
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.action.ActionContributionItem;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.action.IMenuCreator;
+import org.eclipse.jface.layout.PixelConverter;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.resource.JFaceResources;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.window.Window;
+import org.eclipse.jface.wizard.WizardDialog;
+import org.eclipse.jpt.ui.JptUiPlugin;
+import org.eclipse.ui.INewWizard;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.IWorkbenchWindowPulldownDelegate2;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+
+import org.eclipse.jdt.ui.actions.AbstractOpenWizardAction;
+import org.eclipse.jdt.internal.ui.util.CoreUtility;
+
+
+/**
+ * A type wizard is added to the type drop down if it has a paramater 'javatype':
+ *     <wizard
+ *         name="My JPT Wizard"
+ *         icon="icons/wiz.gif"
+ *         category="mycategory"
+ *         id="xx.MyWizard">
+ *         <class class="org.xx.MyWizard">
+ *             <parameter name="jptartifact" value="true"/>
+ *         </class> 
+ *         <description>
+ *             My JPT Wizard
+ *         </description>
+ *      </wizard>
+ */
+public class NewEntityDropDownAction extends Action implements IMenuCreator, IWorkbenchWindowPulldownDelegate2 {
+
+	public static class OpenJptWizardAction extends AbstractOpenWizardAction implements Comparable<Object>  {
+
+		private final static String ATT_NAME = "name";//$NON-NLS-1$
+		private final static String ATT_CLASS = "class";//$NON-NLS-1$
+		private final static String ATT_ICON = "icon";//$NON-NLS-1$
+		private static final String TAG_DESCRIPTION = "description";	//$NON-NLS-1$
+		
+		private IConfigurationElement fConfigurationElement;
+		private int menuIndex;
+
+		public OpenJptWizardAction(IConfigurationElement element) {
+			this.fConfigurationElement= element;
+			setText(element.getAttribute(ATT_NAME));
+			
+			String description= getDescriptionFromConfig(this.fConfigurationElement);
+			setDescription(description);
+			setToolTipText(description);
+			setImageDescriptor(getIconFromConfig(this.fConfigurationElement));
+			setMenuIndex(getMenuIndexFromConfig(this.fConfigurationElement));
+		}
+		
+		private String getDescriptionFromConfig(IConfigurationElement config) {
+			IConfigurationElement [] children = config.getChildren(TAG_DESCRIPTION);
+			if (children.length>=1) {
+				return children[0].getValue();
+			}
+			return ""; //$NON-NLS-1$
+		}
+
+		private ImageDescriptor getIconFromConfig(IConfigurationElement config) {
+			String iconName = config.getAttribute(ATT_ICON);
+			if (iconName != null) {
+				return AbstractUIPlugin.imageDescriptorFromPlugin(config.getContributor().getName(), iconName);
+			}
+			return null;
+		}
+		
+		private int getMenuIndexFromConfig(IConfigurationElement config) {
+			IConfigurationElement[] classElements = config.getChildren(TAG_CLASS);
+			if (classElements.length > 0) {
+				for (IConfigurationElement classElement : classElements) {
+					IConfigurationElement[] paramElements = classElement.getChildren(TAG_PARAMETER);
+					for (IConfigurationElement paramElement : paramElements) {
+						if (ATT_MENUINDEX.equals(paramElement.getAttribute(TAG_NAME))) {
+							return Integer.parseInt(paramElement.getAttribute(TAG_VALUE));
+						}
+					}
+				}
+			}
+			return Integer.MAX_VALUE;
+		}
+		
+		@Override
+		public void run() {
+			Shell shell = getShell();
+			try {
+				INewWizard wizard = createWizard();
+				wizard.init(PlatformUI.getWorkbench(), getSelection());
+				
+				WizardDialog dialog = new WizardDialog(shell, wizard);
+				PixelConverter converter = new PixelConverter(JFaceResources.getDialogFont());
+				dialog.setMinimumPageSize(converter.convertWidthInCharsToPixels(70), converter.convertHeightInCharsToPixels(20));
+				dialog.create();
+				int res = dialog.open();
+				
+				notifyResult(res == Window.OK);
+			} catch (CoreException e) {
+				JptUiPlugin.log(e);
+			}
+		}
+
+		@Override
+		protected INewWizard createWizard() throws CoreException {
+			return (INewWizard) CoreUtility.createExtension(fConfigurationElement, ATT_CLASS);
+		}
+
+		public int getMenuIndex() {
+			return this.menuIndex;
+		}
+
+		public void setMenuIndex(int menuIndex) {
+			this.menuIndex = menuIndex;
+		}
+
+		public int compareTo(Object o) {
+			OpenJptWizardAction action = (OpenJptWizardAction) o;
+			return getMenuIndex() - action.getMenuIndex();
+		}
+
+	}
+	
+	
+	
+	private final static String TAG_WIZARD = "wizard";//$NON-NLS-1$
+	private final static String ATT_JPTARTIFACT = "jptartifact";//$NON-NLS-1$
+	
+	private final static String TAG_PARAMETER = "parameter";//$NON-NLS-1$
+	private final static String TAG_NAME = "name";//$NON-NLS-1$
+	private final static String TAG_VALUE = "value";//$NON-NLS-1$
+	protected final static String ATT_MENUINDEX = "menuIndex";//$NON-NLS-1$
+	
+	private static final String PL_NEW = "newWizards"; //$NON-NLS-1$
+	private static final String TAG_CLASS = "class"; //$NON-NLS-1$
+	
+	private Menu fMenu;
+	
+	private Shell fWizardShell;
+	
+	public NewEntityDropDownAction() {
+		this.fMenu= null;
+		setMenuCreator(this);
+		//PlatformUI.getWorkbench().getHelpSystem().setHelp(this, IJavaHelpContextIds.OPEN_CLASS_WIZARD_ACTION);
+	}
+
+	public void dispose() {
+		if (this.fMenu != null) {
+			this.fMenu.dispose();
+			this.fMenu= null;
+		}
+	}
+
+	public Menu getMenu(Menu parent) {
+		return null;
+	}
+
+	public Menu getMenu(Control parent) {
+		if (this.fMenu == null) {
+			this.fMenu = new Menu(parent);
+			OpenJptWizardAction[] actions = getActionFromDescriptors();
+			for (int i = 0; i < actions.length; i++) {
+				OpenJptWizardAction curr = actions[i];
+				curr.setShell(this.fWizardShell);
+				ActionContributionItem item = new ActionContributionItem(curr);
+				item.fill(this.fMenu, -1);				
+			}			
+		
+		}
+		return this.fMenu;
+	}
+	
+	@Override
+	public void run() {
+		getDefaultAction().run();
+	}
+	
+	public Action getDefaultAction() {
+		Action[] actions = getActionFromDescriptors();
+		if (actions.length > 0)
+			return actions[0];
+		return null;
+	}
+	
+	public static OpenJptWizardAction[] getActionFromDescriptors() {
+		ArrayList<OpenJptWizardAction> containers= new ArrayList<OpenJptWizardAction>();
+		
+		IExtensionPoint extensionPoint = Platform.getExtensionRegistry().getExtensionPoint(PlatformUI.PLUGIN_ID, PL_NEW);
+		if (extensionPoint != null) {
+			IConfigurationElement[] elements = extensionPoint.getConfigurationElements();
+			for (int i = 0; i < elements.length; i++) {
+				IConfigurationElement element= elements[i];
+				if (element.getName().equals(TAG_WIZARD) && isJptArtifactWizard(element)) {
+					containers.add(new OpenJptWizardAction(element));
+				}
+			}
+		}
+		OpenJptWizardAction[] actions = containers.toArray(new OpenJptWizardAction[containers.size()]);
+		Arrays.sort(actions);
+		return actions;
+	}
+		
+	private static boolean isJptArtifactWizard(IConfigurationElement element) {
+		IConfigurationElement[] classElements= element.getChildren(TAG_CLASS);
+		if (classElements.length > 0) {
+			for (int i= 0; i < classElements.length; i++) {
+				IConfigurationElement[] paramElements= classElements[i].getChildren(TAG_PARAMETER);
+				for (int k = 0; k < paramElements.length; k++) {
+					IConfigurationElement curr= paramElements[k];
+					if (ATT_JPTARTIFACT.equals(curr.getAttribute(TAG_NAME))) {
+						return Boolean.valueOf(curr.getAttribute(TAG_VALUE)).booleanValue();
+					}
+				}
+			}
+		}
+		return false;
+	}
+		
+	public void init(IWorkbenchWindow window) {
+		fWizardShell= window.getShell();
+	}
+	
+	public void run(IAction action) {
+		run();
+	}
+	
+	public void selectionChanged(IAction action, ISelection selection) {
+	}
+
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/NewJpaProjectFirstPage.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/NewJpaProjectFirstPage.java
new file mode 100644
index 0000000..437a2c4
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/NewJpaProjectFirstPage.java
@@ -0,0 +1,24 @@
+/*******************************************************************************
+ *  Copyright (c) 2006, 2008 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.ui.internal.wizards;
+
+import org.eclipse.jpt.ui.internal.JpaHelpContextIds;
+import org.eclipse.jpt.ui.internal.JptUiMessages;
+import org.eclipse.jst.j2ee.ui.project.facet.UtilityProjectFirstPage;
+import org.eclipse.wst.common.frameworks.datamodel.IDataModel;
+
+public class NewJpaProjectFirstPage extends UtilityProjectFirstPage 
+{
+	public NewJpaProjectFirstPage(IDataModel dataModel, String pageName) {
+		super(dataModel, pageName);
+		setTitle(JptUiMessages.NewJpaProjectWizard_firstPage_title);
+		setDescription(JptUiMessages.NewJpaProjectWizard_firstPage_description);
+		setInfopopID(JpaHelpContextIds.NEW_JPA_PROJECT);
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/NewJpaProjectWizard.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/NewJpaProjectWizard.java
new file mode 100644
index 0000000..53d3495
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/NewJpaProjectWizard.java
@@ -0,0 +1,57 @@
+/*******************************************************************************
+ *  Copyright (c) 2006, 2008 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.ui.internal.wizards;
+
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.wizard.IWizardPage;
+import org.eclipse.jpt.ui.JptUiPlugin;
+import org.eclipse.jpt.ui.internal.JptUiIcons;
+import org.eclipse.jpt.ui.internal.JptUiMessages;
+import org.eclipse.jst.j2ee.ui.project.facet.UtilityProjectWizard;
+import org.eclipse.wst.common.frameworks.datamodel.IDataModel;
+import org.eclipse.wst.common.project.facet.core.IFacetedProjectTemplate;
+import org.eclipse.wst.common.project.facet.core.ProjectFacetsManager;
+
+public class NewJpaProjectWizard extends UtilityProjectWizard {
+
+	public NewJpaProjectWizard() {
+		super();
+		setWindowTitle(JptUiMessages.NewJpaProjectWizard_title);
+	}
+
+	public NewJpaProjectWizard(IDataModel model) {
+		super(model);
+		setWindowTitle(JptUiMessages.NewJpaProjectWizard_title);
+	}
+	
+	// TODO - when we have a data model to add
+//	protected IDataModel createDataModel() {
+//		return DataModelFactory.createDataModel(new UtilityProjectCreationDataModelProvider());
+//	}
+	
+	@Override
+	protected ImageDescriptor getDefaultPageImageDescriptor() {
+		return JptUiPlugin.getImageDescriptor(JptUiIcons.JPA_WIZ_BANNER);
+	}
+	
+	@Override
+	protected IFacetedProjectTemplate getTemplate() {
+		return ProjectFacetsManager.getTemplate("jpt.jpa.template");
+	}
+	
+	@Override
+	protected IWizardPage createFirstPage() {
+		return new NewJpaProjectFirstPage(model, "first.page"); //$NON-NLS-1$ 
+	}
+	
+	@Override
+	protected String getFinalPerspectiveID() {
+		return "org.eclipse.jpt.ui.jpaPerspective";
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/entity/AnnotatedEntityTemplate.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/entity/AnnotatedEntityTemplate.java
new file mode 100644
index 0000000..b75be4e
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/entity/AnnotatedEntityTemplate.java
@@ -0,0 +1,166 @@
+package org.eclipse.jpt.ui.internal.wizards.entity;

+

+import org.eclipse.jpt.ui.internal.wizards.entity.data.model.*;

+import java.util.*;

+

+public class AnnotatedEntityTemplate

+{

+  protected static String nl;

+  public static synchronized AnnotatedEntityTemplate create(String lineSeparator)

+  {

+    nl = lineSeparator;

+    AnnotatedEntityTemplate result = new AnnotatedEntityTemplate();

+    nl = null;

+    return result;

+  }

+

+  public final String NL = nl == null ? (System.getProperties().getProperty("line.separator")) : nl;

+  protected final String TEXT_1 = "package ";

+  protected final String TEXT_2 = ";";

+  protected final String TEXT_3 = NL;

+  protected final String TEXT_4 = NL + "import ";

+  protected final String TEXT_5 = ";";

+  protected final String TEXT_6 = NL + NL + "/**" + NL + " * Entity implementation class for Entity: ";

+  protected final String TEXT_7 = NL + " *" + NL + " */";

+  protected final String TEXT_8 = NL;

+  protected final String TEXT_9 = "(name=\"";

+  protected final String TEXT_10 = "\")";

+  protected final String TEXT_11 = NL + "@Table(name=\"";

+  protected final String TEXT_12 = "\")";

+  protected final String TEXT_13 = NL;

+  protected final String TEXT_14 = NL + "@IdClass(";

+  protected final String TEXT_15 = ".class)";

+  protected final String TEXT_16 = NL + "public class ";

+  protected final String TEXT_17 = " extends ";

+  protected final String TEXT_18 = " implements ";

+  protected final String TEXT_19 = ", ";

+  protected final String TEXT_20 = " {" + NL + "" + NL + "\t";

+  protected final String TEXT_21 = "   " + NL + "\t@Id";

+  protected final String TEXT_22 = NL + "\tprivate ";

+  protected final String TEXT_23 = " ";

+  protected final String TEXT_24 = ";";

+  protected final String TEXT_25 = NL + "\tprivate static final long serialVersionUID = 1L;" + NL + "" + NL + "\tpublic ";

+  protected final String TEXT_26 = "() {" + NL + "\t\tsuper();" + NL + "\t}";

+  protected final String TEXT_27 = "   " + NL + "\t@Id ";

+  protected final String TEXT_28 = "   " + NL + "\tpublic ";

+  protected final String TEXT_29 = " get";

+  protected final String TEXT_30 = "() {" + NL + "\t\treturn this.";

+  protected final String TEXT_31 = ";" + NL + "\t}" + NL + "" + NL + "\tpublic void set";

+  protected final String TEXT_32 = "(";

+  protected final String TEXT_33 = " ";

+  protected final String TEXT_34 = ") {" + NL + "\t\tthis.";

+  protected final String TEXT_35 = " = ";

+  protected final String TEXT_36 = ";" + NL + "\t}";

+  protected final String TEXT_37 = NL + "   " + NL + "}";

+  protected final String TEXT_38 = NL;

+

+  public String generate(Object argument)

+  {

+    final StringBuffer stringBuffer = new StringBuffer();

+     CreateEntityTemplateModel model = (CreateEntityTemplateModel) argument; 

+if (model.getJavaPackageName()!=null && model.getJavaPackageName()!="") { 

+    stringBuffer.append(TEXT_1);

+    stringBuffer.append(model.getJavaPackageName());

+    stringBuffer.append(TEXT_2);

+    }

+    stringBuffer.append(TEXT_3);

+     Collection<String> imports = model.getImports(false);

+for (String anImport : imports) { 

+    stringBuffer.append(TEXT_4);

+    stringBuffer.append(anImport);

+    stringBuffer.append(TEXT_5);

+     } 

+    stringBuffer.append(TEXT_6);

+    stringBuffer.append(model.getEntityName());

+    stringBuffer.append(TEXT_7);

+    stringBuffer.append(TEXT_8);

+    stringBuffer.append(model.getArtifactType());

+    String ENTITY_NAME = model.getEntityName();

+if (model.isEntityNameSet()) {

+    stringBuffer.append(TEXT_9);

+    stringBuffer.append(ENTITY_NAME);

+    stringBuffer.append(TEXT_10);

+    }

+    if (model.isTableNameSet()) {

+    stringBuffer.append(TEXT_11);

+    stringBuffer.append(model.getTableName());

+    stringBuffer.append(TEXT_12);

+    }

+    stringBuffer.append(TEXT_13);

+    stringBuffer.append(model.getInheritanceStrategy());

+    if (model.isCompositePK()) {

+    stringBuffer.append(TEXT_14);

+    stringBuffer.append(model.getIdClassName());

+    stringBuffer.append(TEXT_15);

+    }

+    stringBuffer.append(TEXT_16);

+    stringBuffer.append(model.getClassName());

+    String superClass = model.getSuperclassName();

+	if (! "".equals(superClass)) {

+    stringBuffer.append(TEXT_17);

+    stringBuffer.append(superClass);

+    }

+    

+	List<String> interfaces = model.getInterfaces(); 

+	if (interfaces.size()>0) {

+    stringBuffer.append(TEXT_18);

+     }

+	for (int i=0; i<interfaces.size(); i++) {

+ 		String INTERFACE = (String) interfaces.get(i);

+		if (i>0) { 

+    stringBuffer.append(TEXT_19);

+    }

+    stringBuffer.append(INTERFACE);

+    }

+    stringBuffer.append(TEXT_20);

+     List<EntityRow> fields = model.getEntityFields();

+	List<String> pkFields = model.getPKFields(); 

+ 	for (EntityRow entity : fields) {

+		String NAME = entity.getName();

+		if (pkFields.contains(NAME) && model.isFieldAccess()) {

+    

+    stringBuffer.append(TEXT_21);

+    }

+    stringBuffer.append(TEXT_22);

+    stringBuffer.append(entity.getType());

+    stringBuffer.append(TEXT_23);

+    stringBuffer.append(entity.getName());

+    stringBuffer.append(TEXT_24);

+    }

+    stringBuffer.append(TEXT_25);

+    stringBuffer.append(model.getClassName());

+    stringBuffer.append(TEXT_26);

+    

+	fields = model.getEntityFields();

+	if (fields != null) for (int i=0; i<fields.size(); i++) {

+		EntityRow field = (EntityRow) fields.get(i);

+		String TYPE = field.getType();

+		String NAME = field.getName();

+		String METHOD = NAME.substring(0,1).toUpperCase() + NAME.substring(1);

+	if (pkFields.contains(NAME) && !model.isFieldAccess()) {

+    

+    stringBuffer.append(TEXT_27);

+    }

+    stringBuffer.append(TEXT_28);

+    stringBuffer.append(TYPE);

+    stringBuffer.append(TEXT_29);

+    stringBuffer.append(METHOD);

+    stringBuffer.append(TEXT_30);

+    stringBuffer.append(NAME);

+    stringBuffer.append(TEXT_31);

+    stringBuffer.append(METHOD);

+    stringBuffer.append(TEXT_32);

+    stringBuffer.append(TYPE);

+    stringBuffer.append(TEXT_33);

+    stringBuffer.append(NAME);

+    stringBuffer.append(TEXT_34);

+    stringBuffer.append(NAME);

+    stringBuffer.append(TEXT_35);

+    stringBuffer.append(NAME);

+    stringBuffer.append(TEXT_36);

+    }

+    stringBuffer.append(TEXT_37);

+    stringBuffer.append(TEXT_38);

+    return stringBuffer.toString();

+  }

+}

diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/entity/EntityClassWizardPage.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/entity/EntityClassWizardPage.java
new file mode 100644
index 0000000..8fa052b
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/entity/EntityClassWizardPage.java
@@ -0,0 +1,393 @@
+/***********************************************************************
+ * Copyright (c) 2008, 2009 by SAP AG, Walldorf. 
+ * 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:
+ *     SAP AG - initial API and implementation
+ *     Dimiter Dimitrov, d.dimitrov@sap.com - initial API and implementation
+ ***********************************************************************/
+package org.eclipse.jpt.ui.internal.wizards.entity;
+
+import java.io.File;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.jface.viewers.ITreeContentProvider;
+import org.eclipse.jface.viewers.TreeSelection;
+import org.eclipse.jface.viewers.ViewerFilter;
+import org.eclipse.jface.window.Window;
+import org.eclipse.jpt.core.JpaProject;
+import org.eclipse.jpt.core.JptCorePlugin;
+import org.eclipse.jpt.core.resource.xml.JpaXmlResource;
+import org.eclipse.jpt.ui.JptUiPlugin;
+import org.eclipse.jpt.ui.internal.JpaHelpContextIds;
+import org.eclipse.jpt.ui.internal.jface.XmlMappingFileViewerFilter;
+import org.eclipse.jpt.ui.internal.wizards.entity.data.model.IEntityDataModelProperties;
+import org.eclipse.jpt.utility.internal.ArrayTools;
+import org.eclipse.jst.j2ee.internal.common.operations.INewJavaClassDataModelProperties;
+import org.eclipse.jst.j2ee.internal.wizard.NewJavaClassWizardPage;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Group;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.dialogs.ElementTreeSelectionDialog;
+import org.eclipse.ui.help.IWorkbenchHelpSystem;
+import org.eclipse.ui.model.WorkbenchContentProvider;
+import org.eclipse.ui.model.WorkbenchLabelProvider;
+import org.eclipse.wst.common.frameworks.datamodel.IDataModel;
+import org.eclipse.wst.common.project.facet.core.IFacetedProject;
+import org.eclipse.wst.common.project.facet.core.IProjectFacet;
+import org.eclipse.wst.common.project.facet.core.ProjectFacetsManager;
+
+public class EntityClassWizardPage extends NewJavaClassWizardPage{
+
+	private static final String JPA_FACET = JptCorePlugin.FACET_ID;
+	private static final String META_INF = "META-INF";//$NON-NLS-1$
+	private static final String EMPTY = "";//$NON-NLS-1$
+	private static final char SLASH = '/';
+	private static final String SINGLE_TABLE = "SINGLE_TABLE";//$NON-NLS-1$
+	private static final String TABLE_PER_CLASS = "TABLE_PER_CLASS";//$NON-NLS-1$
+	private static final String JOINED = "JOINED";//$NON-NLS-1$
+	private static final String[] INHERITANCE_STRATEGIES = new String[] {
+											EMPTY, 
+											SINGLE_TABLE,
+											TABLE_PER_CLASS,
+											JOINED };
+	private Combo inheritanceStrategyCombo;
+	private Button entityButton;
+	private Button mapedAsSuperclassButton;
+	private Button inheritanceButton;
+	private Label displayNameLabel;
+	private Button xmlSupportButton;	
+	private boolean isFirstCheck = true;
+	private Text ormXmlName;
+	private Button browseButton;	
+	
+	public EntityClassWizardPage(IDataModel model, String pageName,
+			String pageDesc, String pageTitle, String moduleType) {
+		super(model, pageName, pageDesc, pageTitle, moduleType);
+	}
+	
+	
+	@Override
+	protected String[] getValidationPropertyNames() {
+		return ArrayTools.addAll(
+				super.getValidationPropertyNames(), 
+				new String[] {IEntityDataModelProperties.XML_NAME, IEntityDataModelProperties.XML_SUPPORT});
+	}
+
+	/* Create top level composite (class properties) and add the entity's specific inheritance group
+	 * @see org.eclipse.jst.j2ee.internal.wizard.NewJavaClassWizardPage#createTopLevelComposite(org.eclipse.swt.widgets.Composite)
+	 */
+	@Override
+	protected Composite createTopLevelComposite(Composite parent) {
+		Composite composite = super.createTopLevelComposite(parent);
+		this.getHelpSystem().setHelp(composite, JpaHelpContextIds.NEW_JPA_ENTITY_ENTITY_CLASS);
+		
+		createInheritanceControl(composite);
+		inheritanceButton.addSelectionListener(new SelectionAdapter() {
+			@Override
+			public void widgetSelected(SelectionEvent e) {
+				boolean isChecked = inheritanceButton.getSelection();
+				if (isChecked) {
+					entityButton.setSelection(true);
+					mapedAsSuperclassButton.setSelection(false);
+				}
+				inheritanceStrategyCombo.setEnabled(isChecked);
+				model.setBooleanProperty(IEntityDataModelProperties.ENTITY, true);
+				model.setBooleanProperty(IEntityDataModelProperties.MAPPED_AS_SUPERCLASS, false);				
+				entityButton.setEnabled(!isChecked);
+				mapedAsSuperclassButton.setEnabled(!isChecked);				
+			}
+		});		
+		createXMLstorageControl(composite);
+		xmlSupportButton.addSelectionListener(new SelectionAdapter() {
+			@Override
+			public void widgetSelected(SelectionEvent e) {
+				boolean isChecked = xmlSupportButton.getSelection();
+				enableMappingXMLChooseGroup(isChecked);
+				if (isFirstCheck) {
+					ormXmlName.setText(JptCorePlugin.DEFAULT_ORM_XML_FILE_PATH);
+					isFirstCheck = false;
+				}
+			}
+		});		
+		return composite;
+	}
+	
+	/**
+	 * Create the inheritance group
+	 * @param parent the main composite
+	 */
+	private void createInheritanceControl(Composite parent) {
+		Group group = createGroup(parent, EntityWizardMsg.INHERITANCE_GROUP);
+		entityButton = createRadioButton(group, EntityWizardMsg.ENTITY, IEntityDataModelProperties.ENTITY);
+		mapedAsSuperclassButton = createRadioButton(group, EntityWizardMsg.MAPPED_AS_SUPERCLASS, IEntityDataModelProperties.MAPPED_AS_SUPERCLASS);
+		inheritanceButton = createCheckButton(group, GridData.HORIZONTAL_ALIGN_FILL, 1/*horizontal span*/, EntityWizardMsg.INHERITANCE_CHECK_BOX, IEntityDataModelProperties.INHERITANCE);
+		createComboBox(group, IEntityDataModelProperties.INHERITANCE_STRATEGY);
+	}
+	
+	/**
+	 * Create the group, which manage entity mapping registration
+	 * @param parent the main composite
+	 */
+	private void createXMLstorageControl(Composite parent) {
+		Group group = createGroup(parent, EntityWizardMsg.XML_STORAGE_GROUP);
+		xmlSupportButton = createCheckButton(group, GridData.FILL_HORIZONTAL, 3/*horizontal span*/, EntityWizardMsg.XML_SUPPORT, IEntityDataModelProperties.XML_SUPPORT);				
+		createBrowseGroup(group, EntityWizardMsg.CHOOSE_XML, IEntityDataModelProperties.XML_NAME);
+		ormXmlName.setEnabled(false);		
+		browseButton.setEnabled(false);		
+	}
+	
+	/**
+	 * @param parent the main composite
+	 * @param text the name/title of the group
+	 * @return the created group
+	 */
+	private Group createGroup(Composite parent, String text) {
+		Group group = new Group(parent, SWT.NONE);		
+		GridData groupGridData = new GridData(GridData.FILL_HORIZONTAL);
+		groupGridData.horizontalSpan = 3;
+		group.setLayoutData(groupGridData);
+		group.setLayout(new GridLayout(3, false));
+		group.setText(text);		
+		return group;
+	}
+	
+	/**
+	 * Create radio button
+	 * @param parent the main composite - inheritance group
+	 * @param text the label of the button
+	 * @param property the related property to which this button will be synchronized
+	 * @return the created button
+	 */
+	private Button createRadioButton(Composite parent, String text, String property) {
+		Button button = new Button(parent, SWT.RADIO);		
+		GridData groupGridData = new GridData(GridData.FILL_HORIZONTAL);
+		groupGridData.horizontalSpan = 3;
+		button.setLayoutData(groupGridData);
+		button.setText(text);
+		synchHelper.synchRadio(button, property, /*dependentControls*/ null);		
+		return button;
+	}
+	
+	/**
+	 * Create check button
+	 * @param parent the main composite - inheritance group
+	 * @param text the label of the button
+	 * @param property the related property to which this button will be synchronized
+	 * @return the created button
+	 */
+	private Button createCheckButton(Composite parent, int fillStrategy, int horizontalSpan, String text, String property) {
+		final Button button = new Button(parent, SWT.CHECK);		
+		GridData groupGridData = new GridData(fillStrategy);
+		groupGridData.horizontalSpan = horizontalSpan;
+		button.setLayoutData(groupGridData);
+		button.setText(text);		
+		synchHelper.synchCheckbox(button, property, /*dependentControls*/ null);
+		return button;
+	}
+
+	/**
+	 * Create combo box, which presents the set of possible inheritance strategies
+	 * @param parent the main composite - inheritance group
+	 * @param property the related property to which this button will be synchronized
+	 * @return
+	 */
+	private Combo createComboBox(Composite parent, String property) {
+		inheritanceStrategyCombo = new Combo(parent, SWT.BORDER | SWT.READ_ONLY);
+		GridData groupGridData = new GridData(GridData.FILL_HORIZONTAL);		
+		groupGridData.horizontalSpan = 2;
+		inheritanceStrategyCombo.setLayoutData(groupGridData);
+		inheritanceStrategyCombo.setItems(INHERITANCE_STRATEGIES);		
+		synchHelper.synchCombo(inheritanceStrategyCombo, property, /*dependentControls*/ null);
+		inheritanceStrategyCombo.setEnabled(false);
+		return inheritanceStrategyCombo;		
+		
+	}	
+	
+	/**
+	 * Create XML group
+	 * @param parent the main composite
+	 * @param label the name of the group
+	 * @param property the related property to which this group will be synchronized
+	 * @return the created group
+	 */
+	private void createBrowseGroup(Composite parent, String label, String property) {
+		Composite composite = new Composite(parent, SWT.NULL);
+		composite.setLayout(new GridLayout(3, false));
+		composite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));	
+		displayNameLabel = new Label(composite, SWT.LEFT);
+		displayNameLabel.setText(label);
+		displayNameLabel.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING));
+		ormXmlName = new Text(composite, SWT.SINGLE | SWT.BORDER);
+		ormXmlName.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+		browseButton = new Button(composite, SWT.PUSH);
+		browseButton.setText(EntityWizardMsg.BROWSE_BUTTON_LABEL);
+		GridData browseButtonData = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
+		browseButtonData.horizontalSpan = 1;
+		browseButton.setLayoutData(browseButtonData);		
+		browseButton.addSelectionListener(new SelectionListener() {
+			public void widgetSelected(SelectionEvent e) {
+				handleChooseXmlButtonPressed();
+			}
+
+			public void widgetDefaultSelected(SelectionEvent e) {
+				// Do nothing
+			}
+		});
+		synchHelper.synchText(ormXmlName, property, /*dependentControls*/null);
+		
+		enableMappingXMLChooseGroup(false);		
+	}
+	
+	/**
+	 * Process browsing when the Browse... button have been pressed. Allow choosing of 
+	 * XML for entity mapping registration
+	 *  
+	 */
+	private void handleChooseXmlButtonPressed() {		
+		IProject project = (IProject) getDataModel().getProperty(INewJavaClassDataModelProperties.PROJECT);
+		if (project == null) {
+			return;
+		}
+		JpaProject jpaProject = JptCorePlugin.getJpaProject(project);
+		ViewerFilter filter = getDialogViewerFilter(jpaProject);
+		ITreeContentProvider contentProvider = new WorkbenchContentProvider();
+		ILabelProvider labelProvider = new WorkbenchLabelProvider();
+		SelectMappingXMLDialog dialog = new SelectMappingXMLDialog(getShell(), labelProvider, contentProvider);
+		dialog.setTitle(EntityWizardMsg.MAPPING_XML_TITLE);
+		dialog.setMessage(EntityWizardMsg.CHOOSE_MAPPING_XML_MESSAGE);
+		dialog.addFilter(filter);
+			
+		String ormFileName = this.ormXmlName.getText();
+		JpaXmlResource resource = jpaProject.getMappingFileXmlResource(ormFileName);
+		IFile initialSelection = (resource != null) ? resource.getFile() : null;
+		dialog.setInput(project);
+
+		if (initialSelection != null) {
+			dialog.setInitialSelection(initialSelection);
+		}
+		if (dialog.open() == Window.OK) {
+			this.ormXmlName.setText(dialog.getChosenName());
+			this.model.validateProperty(IEntityDataModelProperties.XML_NAME);
+		}		
+	}
+	
+	/**
+	 * This method create filter for the browse/add alternative mapping XML 
+	 * @return new instance of viewer filter for the SelectMappingXMLDialog
+	 */
+	protected ViewerFilter getDialogViewerFilter(JpaProject jpaProject) {
+		return new XmlMappingFileViewerFilter(jpaProject);
+	}
+	
+	private void enableMappingXMLChooseGroup(boolean enabled) {
+		displayNameLabel.setEnabled(enabled);
+		ormXmlName.setEnabled(enabled);
+		browseButton.setEnabled(enabled);
+
+	}
+	
+	/**
+	 * This method is used by the project list initializer. The method checks 
+	 * if the specified project is valid to include it in the project list.
+	 * 
+	 * <p>Subclasses of this wizard page should override this method to 
+	 * adjust filtering of the projects to their needs. </p>
+	 * 
+	 * @param project reference to the project to be checked
+	 * 
+	 * @return <code>true</code> if the project is valid to be included in 
+	 * 		   the project list, <code>false</code> - otherwise. 
+	 */
+	@Override
+	protected boolean isProjectValid(IProject project) {		
+		IProjectFacet jpaFacet = ProjectFacetsManager.getProjectFacet(JPA_FACET);
+		IFacetedProject fProject = null; 
+		try {
+			fProject = ProjectFacetsManager.create(project);
+		} catch (CoreException e) {
+			return false;
+		}		
+		return (project.isAccessible() && fProject != null && fProject.hasProjectFacet(jpaFacet));	
+	}
+	
+	private class SelectMappingXMLDialog extends ElementTreeSelectionDialog
+	{	
+		private String xmlName = EMPTY;
+		
+		
+		public SelectMappingXMLDialog(Shell parent, ILabelProvider labelProvider, ITreeContentProvider contentProvider) {
+			super(parent, labelProvider, contentProvider);			
+		}
+		
+		
+		/**
+	     * @return the name of the alternative mapping XML
+	     */
+	    public String getChosenName() {
+	    	String result = EMPTY;
+			Object element = getFirstResult();
+			if (element instanceof IContainer) {
+				IContainer container = (IContainer) element;
+				result = container.getFullPath().toString() + File.separatorChar + xmlName;					
+			} else {
+				IFile f = (IFile) element;
+				result = f.getFullPath().toOSString();
+			}
+			result = removeRedundantSegmentFromName(result);
+			return result;
+	    }
+
+		@Override
+	    /*
+	     * @see ElementTreeSelectionDialog#updateOKStatus(Composite)
+	     */
+		protected void updateOKStatus() {
+			super.updateOKStatus();
+			TreeSelection selection = (TreeSelection)getTreeViewer().getSelection();
+			IResource selectedResource = (IResource) selection.getFirstElement();
+			if (selectedResource instanceof IFile) {
+				updateStatus(new Status(IStatus.OK, JptUiPlugin.PLUGIN_ID, ""));
+			}
+			else {
+				updateStatus(new Status(IStatus.ERROR, JptUiPlugin.PLUGIN_ID, ""));
+			}
+		}
+		
+		/** 
+		 * This method is for internal purposes only
+		 * @param input non formated path to the mapping XML
+		 * @return the formated path to the mapping XML
+		 */
+		private String removeRedundantSegmentFromName(String input) {
+			String output = input.substring(input.indexOf(META_INF));			 
+			output = output.replace(File.separatorChar, SLASH);
+			return output;
+		}
+	}
+	
+	protected final IWorkbenchHelpSystem getHelpSystem() {
+		return PlatformUI.getWorkbench().getHelpSystem();
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/entity/EntityFieldsWizardPage.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/entity/EntityFieldsWizardPage.java
new file mode 100644
index 0000000..55c0ff0
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/entity/EntityFieldsWizardPage.java
@@ -0,0 +1,234 @@
+/***********************************************************************
+ * Copyright (c) 2008, 2010 by SAP AG, Walldorf. 
+ * 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:
+ *     SAP AG - initial API and implementation
+ *     Dimiter Dimitrov, d.dimitrov@sap.com - initial API and implementation
+ ***********************************************************************/
+package org.eclipse.jpt.ui.internal.wizards.entity;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jpt.ui.internal.JpaHelpContextIds;
+import org.eclipse.jpt.ui.internal.wizards.entity.data.model.IEntityDataModelProperties;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Group;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.help.IWorkbenchHelpSystem;
+import org.eclipse.wst.common.componentcore.internal.operation.IArtifactEditOperationDataModelProperties;
+import org.eclipse.wst.common.frameworks.datamodel.DataModelEvent;
+import org.eclipse.wst.common.frameworks.datamodel.IDataModel;
+import org.eclipse.wst.common.frameworks.internal.datamodel.ui.DataModelWizardPage;
+import org.eclipse.wst.common.frameworks.internal.plugin.WTPCommonPlugin;
+
+public class EntityFieldsWizardPage extends DataModelWizardPage {
+
+	private Text entityNameText;
+	private Text tableNameText;
+	private Button tableNameCheckButton;	
+	private Button fieldAccessButton;
+	private Button propertyAccessButton;
+	private boolean isNonEntity = true;
+	private boolean isButtonsCreated = false;
+
+	public EntityFieldsWizardPage(IDataModel model, String pageName) {
+		super(model, pageName);
+		this.setTitle(EntityWizardMsg.ENTITY_PROPERTIES_TITLE);
+		this.setDescription(EntityWizardMsg.ENTITY_PROPERTIES_DESCRIPTION);
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.jem.util.ui.wizard.WTPWizardPage#getValidationPropertyNames()
+	 */
+	@Override
+	protected String[] getValidationPropertyNames() {
+		return new String[]{IEntityDataModelProperties.ENTITY_FIELDS, 
+							IEntityDataModelProperties.PK_FIELDS};
+	}
+	
+	/* Create the main composite and add to it the entity properties
+	 * @see org.eclipse.wst.common.frameworks.internal.datamodel.ui.DataModelWizardPage#createTopLevelComposite(org.eclipse.swt.widgets.Composite)
+	 */
+	@Override
+	protected Composite createTopLevelComposite(Composite parent) {
+		Composite composite = new Composite(parent, SWT.NULL);
+		composite.setLayout(new GridLayout());
+		this.getHelpSystem().setHelp(composite, JpaHelpContextIds.NEW_JPA_ENTITY_ENTITY_PROPERTIES);
+		
+		GridData data = new GridData(GridData.FILL_BOTH);
+		data.widthHint = 300;
+		data.heightHint = 450;
+		composite.setLayoutData(data);
+		composite.pack();
+				
+		entityNameText = createNameGroup(composite, EntityWizardMsg.ENTITY_NAME, IEntityDataModelProperties.ENTITY_NAME);		
+		Group group = createGroup(composite, EntityWizardMsg.TABLE_NAME_GROUP);
+		tableNameCheckButton= createCheckButton(group, EntityWizardMsg.USE_DEFAULT, IEntityDataModelProperties.TABLE_NAME_DEFAULT);		
+		tableNameText = createNameGroup(group, EntityWizardMsg.TABLE_NAME, IEntityDataModelProperties.TABLE_NAME);
+		tableNameText.setEnabled(!tableNameCheckButton.getSelection());
+		isButtonsCreated = true;
+		initNameGroup();
+		createEntityFieldsGroup(composite);
+
+		Group accessTypeGroup = createGroup(composite, EntityWizardMsg.ACCESS_TYPE);
+		fieldAccessButton = createRadioButton(accessTypeGroup, EntityWizardMsg.FIELD_BASED, IEntityDataModelProperties.FIELD_ACCESS_TYPE);
+		propertyAccessButton = createRadioButton(accessTypeGroup, EntityWizardMsg.PROPERTY_BASED, IEntityDataModelProperties.PROPERTY_ACCESS_TYPE);
+		
+		
+		IStatus projectStatus = validateProjectName();
+		if (!projectStatus.isOK()) {
+			setErrorMessage(projectStatus.getMessage());
+			composite.setEnabled(false);
+		}
+	    Dialog.applyDialogFont(parent);
+		return composite;
+	}
+
+	/**
+	 * @return the status of the project name correctness
+	 */
+	protected IStatus validateProjectName() {
+		// check for empty
+		if (model.getStringProperty(IArtifactEditOperationDataModelProperties.PROJECT_NAME) == null || model.getStringProperty(IArtifactEditOperationDataModelProperties.PROJECT_NAME).trim().length() == 0) {
+			return WTPCommonPlugin.createErrorStatus(EntityWizardMsg.NO_JPA_PROJECTS);
+		}
+		return WTPCommonPlugin.OK_STATUS;
+	}
+	
+	protected void createEntityFieldsGroup(Composite parent) {
+		Group group = new Group(parent, SWT.NONE);		
+		GridData groupGridData = new GridData(GridData.FILL_BOTH);
+		groupGridData.horizontalSpan = 3;
+		group.setLayoutData(groupGridData);
+		group.setLayout(new GridLayout(3, false));
+		group.setText(EntityWizardMsg.ENTITY_FIELDS_GROUP);
+		new EntityRowTableWizardSection(group, model, IEntityDataModelProperties.ENTITY_FIELDS);
+	}
+	
+	/**
+	 * Create named group
+	 * @param parent the main composite
+	 * @param label the name of the group
+	 * @param property the related property to which this group will be synchronized
+	 * @return the created group
+	 */
+	protected Text createNameGroup(Composite parent, String label, String property) {
+		Composite composite = new Composite(parent, SWT.NULL);
+		composite.setLayout(new GridLayout(3, false));
+		composite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));	
+		Label displayNameLabel = new Label(composite, SWT.LEFT);
+		displayNameLabel.setText(label);
+		displayNameLabel.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING));
+		Text nameText = new Text(composite, SWT.SINGLE | SWT.BORDER);
+		nameText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+		synchHelper.synchText(nameText, property, /*dependentControls*/null);		
+		return nameText;
+	}
+	
+	/**
+	 * Create group
+	 * @param parent the main composite
+	 * @param text the name of the group	 
+	 * @return the created group
+	 */	
+	private Group createGroup(Composite parent, String text) {
+		Group group = new Group(parent, SWT.NONE);		
+		GridData groupGridData = new GridData(GridData.FILL_HORIZONTAL);
+		groupGridData.horizontalSpan = 3;
+		group.setLayoutData(groupGridData);
+		group.setLayout(new GridLayout(3, false));
+		group.setText(text);		
+		return group;
+	}
+	
+	/**
+	 * Create check button
+	 * @param parent the main composite - inheritance group
+	 * @param text the label of the button
+	 * @param property the related property to which this button will be synchronized
+	 * @return the created button
+	 */	
+	private Button createCheckButton(Composite parent, String text, String property) {
+		final Button button = new Button(parent, SWT.CHECK);
+		GridData groupGridData = new GridData(GridData.FILL_HORIZONTAL);
+		groupGridData.horizontalSpan = 3;
+		button.setLayoutData(groupGridData);
+		button.setText(text);
+		button.addSelectionListener(new SelectionAdapter() {
+			@Override
+			public void widgetSelected(SelectionEvent e) {
+				boolean isChecked = button.getSelection();
+				if (tableNameText != null) {
+					tableNameText.setEnabled(!isChecked);
+				}
+			}
+		});		
+		synchHelper.synchCheckbox(button, property, /*dependentControls*/ null);		
+		return button;
+	}		
+	
+	/**
+	 * Create radio button
+	 * @param parent the main composite - inheritance group
+	 * @param text the label of the button
+	 * @param property the related property to which this button will be synchronized
+	 * @return the created button
+	 */
+	private Button createRadioButton(Composite parent, String text, String property) {
+		Button button = new Button(parent, SWT.RADIO);		
+		GridData groupGridData = new GridData(GridData.FILL_HORIZONTAL);
+		groupGridData.horizontalSpan = 3;
+		button.setLayoutData(groupGridData);
+		button.setText(text);
+		synchHelper.synchRadio(button, property, /*dependentControls*/ null);		
+		return button;
+	}
+
+	/*
+	 * If a property changes that we want to validate, force validation on this page.
+	 * 
+	 * @see org.eclipse.wst.common.frameworks.internal.operation.WTPOperationDataModelListener#propertyChanged(java.lang.String,
+	 *      java.lang.Object, java.lang.Object)
+	 */
+	@Override
+	public void propertyChanged(DataModelEvent event) {
+		String propertyName = event.getPropertyName();
+		if (IEntityDataModelProperties.MAPPED_AS_SUPERCLASS.equals(propertyName)) {
+			initNameGroup();
+		}		
+		super.propertyChanged(event);
+	}
+	
+	/**
+	 * The methods is for the internal use only. It will set the entity and table name
+	 * group to be disabled if the created artifact is not entity
+	 */
+	private void initNameGroup() {		
+		isNonEntity = model.getBooleanProperty(IEntityDataModelProperties.MAPPED_AS_SUPERCLASS);		
+		if (isButtonsCreated) {
+			entityNameText.setEnabled(!isNonEntity);
+			tableNameCheckButton.setEnabled(!isNonEntity);
+			tableNameText.setEnabled(!tableNameCheckButton.getSelection());
+		}		
+	}
+	
+	protected final IWorkbenchHelpSystem getHelpSystem() {
+		return PlatformUI.getWorkbench().getHelpSystem();
+	}
+}
+
+
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/entity/EntityRowTableWizardSection.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/entity/EntityRowTableWizardSection.java
new file mode 100644
index 0000000..55b12f1
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/entity/EntityRowTableWizardSection.java
@@ -0,0 +1,822 @@
+/***********************************************************************
+ * Copyright (c) 2008, 2009 by SAP AG, Walldorf. 
+ * 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:
+ *     SAP AG - initial API and implementation
+ *     Dimiter Dimitrov, d.dimitrov@sap.com - initial API and implementation
+ ***********************************************************************/
+package org.eclipse.jpt.ui.internal.wizards.entity;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import org.eclipse.jdt.ui.IJavaElementSearchConstants;
+import org.eclipse.jdt.ui.JavaUI;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.jdt.core.IPackageFragmentRoot;
+import org.eclipse.jdt.core.IType;
+import org.eclipse.jdt.core.JavaConventions;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.core.search.IJavaSearchScope;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jface.bindings.keys.KeyStroke;
+import org.eclipse.jface.bindings.keys.ParseException;
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.fieldassist.ContentProposalAdapter;
+import org.eclipse.jface.fieldassist.IContentProposalProvider;
+import org.eclipse.jface.fieldassist.SimpleContentProposalProvider;
+import org.eclipse.jface.fieldassist.TextContentAdapter;
+import org.eclipse.jface.viewers.CheckStateChangedEvent;
+import org.eclipse.jface.viewers.CheckboxTableViewer;
+import org.eclipse.jface.viewers.DoubleClickEvent;
+import org.eclipse.jface.viewers.ICheckStateListener;
+import org.eclipse.jface.viewers.IDoubleClickListener;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.IStructuredContentProvider;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.ITableLabelProvider;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jface.viewers.TableViewer;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.window.Window;
+import org.eclipse.jpt.ui.JptUiPlugin;
+import org.eclipse.jpt.ui.internal.wizards.entity.data.model.EntityRow;
+import org.eclipse.jpt.ui.internal.wizards.entity.data.model.IEntityDataModelProperties;
+import org.eclipse.jst.j2ee.internal.common.operations.INewJavaClassDataModelProperties;
+import org.eclipse.jst.j2ee.internal.dialogs.TypeSearchEngine;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.ControlAdapter;
+import org.eclipse.swt.events.ControlEvent;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.TableColumn;
+import org.eclipse.swt.widgets.TableItem;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.ui.dialogs.SelectionDialog;
+import org.eclipse.wst.common.frameworks.datamodel.IDataModel;
+
+/**
+ * The class presents the table with entity fields. In the java file are included also content
+ * and label provider, add and edit entity dialogs as well as help internal objects - listener 
+ * and callback from the dialog to the main composite (table). 
+ *
+ */
+public class EntityRowTableWizardSection extends Composite {
+	
+	/**
+	 * The possible entity types, mentioned in the specification (Chapter 2.1.1 Persistent Fields and Properties p.20)
+	 */
+	protected final static String[] VALID_TYPES = {"int", 
+												   "long", 
+												   "short", 
+												   "char", 
+												   "boolean", 
+												   "byte", 
+												   "double", 
+												   "float", 
+												   "java.lang.String", 
+												   "java.lang.Integer", 
+												   "java.lang.Long", 
+												   "java.lang.Short",
+												   "java.lang.Character", 
+												   "java.lang.Boolean", 
+												   "java.lang.Byte", 
+												   "java.lang.Double", 
+												   "java.lang.Float", 
+												   "java.math.BigDecimal", 
+												   "java.math.BigInteger", 
+												   "java.util.Date", 
+												   "java.util.Calendar",
+												   "java.sql.Date", 
+												   "java.sql.Time", 
+												   "java.sql.Timestamp",
+												   "String", 
+												   "Integer", 
+												   "Long", 
+												   "Short",
+												   "Character", 
+												   "Boolean", 
+												   "Byte", 
+												   "Double", 
+												   "Float" };	
+	
+	  private CheckboxTableViewer mTableViewer = null;
+	  private Table mTableWidget = null;
+	  private final int NAME_COLUMN = 1;
+	  private final int TYPE_COLUMN = 2;
+	
+	  
+
+	
+	private Button addButton;
+	private Button editButton;
+	private Button removeButton;
+	private String title = EntityWizardMsg.ENTITY_FIELDS_DIALOG_TITLE;
+	private String[] typeProposals = VALID_TYPES;
+	private String[] labelsForText = new String[]{EntityWizardMsg.TYPE_TEXT_FIELD, EntityWizardMsg.NAME_TEXT_FIELD};
+	private IDataModel model;
+	private String propertyName;
+	private Image labelProviderImage = null;
+	private DialogCallback callback;	
+	private static KeyStroke ks = null;
+	static {
+		try {
+			ks = KeyStroke.getInstance("Ctrl+Space");			
+		} catch (ParseException e1) {
+			JptUiPlugin.log(e1);
+		} 
+	}
+
+
+	/**
+	 * @param parent the main composite - Entity fields page
+	 * @param model the data model representation
+	 * @param propertyName data property name
+	 */
+	public EntityRowTableWizardSection(Composite parent, IDataModel model, String propertyName) {
+		super(parent, SWT.NONE);	
+		this.model = model;
+		this.propertyName = propertyName;		
+
+		GridLayout layout = new GridLayout(2, false);
+		layout.marginHeight = 4;
+		layout.marginWidth = 0;
+		this.setLayout(layout);
+		this.setLayoutData(new GridData(GridData.FILL_BOTH));
+
+		mTableWidget = new Table(this, SWT.CHECK | SWT.FULL_SELECTION | SWT.BORDER);
+        mTableWidget.setHeaderVisible(true);
+        mTableWidget.setLinesVisible(true);
+
+        mTableViewer = new CheckboxTableViewer(mTableWidget);
+        GridData data = new GridData(GridData.FILL_BOTH);
+        data.verticalSpan = 2;
+		mTableWidget.setLayoutData(data);
+		mTableViewer.setContentProvider(new EntityRowContentProvider());
+		mTableViewer.setLabelProvider(new EntityRowLabelProvider());
+		
+		final Composite buttonComposition = new Composite(this, SWT.NULL);
+		layout = new GridLayout();
+		layout.marginHeight = 0;
+		buttonComposition.setLayout(layout);
+		buttonComposition.setLayoutData(new GridData(GridData.FILL_VERTICAL | GridData.VERTICAL_ALIGN_BEGINNING));
+
+		addButton = new Button(buttonComposition, SWT.PUSH);
+		addButton.setText(EntityWizardMsg.ADD_BUTTON_LABEL); 
+		addButton.setLayoutData(new GridData(GridData.VERTICAL_ALIGN_BEGINNING | GridData.HORIZONTAL_ALIGN_FILL));
+		addButton.addSelectionListener(new SelectionListener() {
+			public void widgetSelected(SelectionEvent event) {
+				handleAddButtonSelected();
+			}
+			public void widgetDefaultSelected(SelectionEvent event) {
+				//Do nothing
+			}
+		});
+
+		editButton = new Button(buttonComposition, SWT.PUSH);
+		editButton.setText(EntityWizardMsg.EDIT_BUTTON_LABEL);
+		editButton.setLayoutData(new GridData(GridData.VERTICAL_ALIGN_BEGINNING | GridData.HORIZONTAL_ALIGN_FILL));
+		editButton.addSelectionListener(new SelectionListener() {
+			public void widgetSelected(SelectionEvent event) {
+				handleEditButtonSelected();
+			}
+			public void widgetDefaultSelected(SelectionEvent event) {
+				//Do nothing
+			}
+		});
+		editButton.setEnabled(false);
+		mTableViewer.addDoubleClickListener(new IDoubleClickListener() {
+			public void doubleClick(DoubleClickEvent event) {
+				handleEditButtonSelected();
+			}
+		});
+
+		removeButton = new Button(buttonComposition, SWT.PUSH);
+		removeButton.setText(EntityWizardMsg.REMOVE_BUTTON_LABEL);
+		removeButton.setLayoutData(new GridData(GridData.VERTICAL_ALIGN_BEGINNING | GridData.HORIZONTAL_ALIGN_FILL));
+		removeButton.addSelectionListener(new SelectionListener() {
+			public void widgetSelected(SelectionEvent event) {
+				handleRemoveButtonSelected();
+			}
+			public void widgetDefaultSelected(SelectionEvent event) {
+				//Do nothing
+			}
+		});
+		removeButton.setEnabled(false);
+
+		mTableViewer.addSelectionChangedListener(new ISelectionChangedListener() {
+			public void selectionChanged(SelectionChangedEvent event) {
+				ISelection selection = event.getSelection();
+				if (editButton != null) {
+					boolean enabled = ((IStructuredSelection) selection).size() == 1;
+					editButton.setEnabled(enabled);
+				}
+				removeButton.setEnabled(!selection.isEmpty());
+			}
+		});
+		
+		
+		final TableColumn pkColumn = new TableColumn(mTableWidget, SWT.CHECK);
+        pkColumn.setText(EntityWizardMsg.KEY);
+		pkColumn.pack();
+		pkColumn.setResizable(false);
+
+        TableColumn nameColumn = new TableColumn(mTableWidget, SWT.NONE);
+        nameColumn.setText(EntityWizardMsg.NAME_COLUMN);
+
+        TableColumn typeColumn = new TableColumn(mTableWidget, SWT.NONE);
+        typeColumn.setText(EntityWizardMsg.TYPE_COLUMN);
+
+        this.addControlListener(new ControlAdapter() {
+        	@Override
+			public void controlResized(ControlEvent e) {
+        		Table table = mTableViewer.getTable();
+                    TableColumn[] columns = table.getColumns();
+				Point buttonArea = buttonComposition.computeSize(SWT.DEFAULT, SWT.DEFAULT);
+				Rectangle area = table.getParent().getClientArea();
+				Point preferredSize = mTableViewer.getTable().computeSize(SWT.DEFAULT, SWT.DEFAULT);
+				int width = area.width - 2 * table.getBorderWidth()- buttonArea.x - columns.length * 2 - pkColumn.getWidth();
+				if (preferredSize.y > area.height + table.getHeaderHeight()) {
+					// Subtract the scrollbar width from the total column width
+					// if a vertical scrollbar will be required
+					Point vBarSize = table.getVerticalBar().getSize();
+					width -= vBarSize.x;
+				}
+				Point oldSize = table.getSize();
+				int consumeWidth = 0;
+				int col = columns.length - 1;
+				for (int i = 1; i < columns.length; i++) {
+					if (oldSize.x > area.width) {
+						// table is getting smaller so make the columns
+						// smaller first and then resize the table to
+						// match the client area width
+						consumeWidth = setColumntWidth(width, columns, consumeWidth, i);
+						table.setSize(area.width - buttonArea.x	- (col * 2 + pkColumn.getWidth()), area.height);
+					} else {
+						// table is getting bigger so make the table
+						// bigger first and then make the columns wider
+						// to match the client area width
+						consumeWidth = setColumntWidth(width, columns, 	consumeWidth, i);
+						table.setSize(area.width - buttonArea.x - (col * 2 + pkColumn.getWidth()), area.height);
+					}
+				}
+			}
+
+			private int setColumntWidth(int width, TableColumn[] columns,
+					int consumeWidth, int i) {
+				if (i < columns.length - 1) {
+					columns[i].setWidth(width / (columns.length - 1));
+					consumeWidth += columns[i].getWidth();
+				} else {
+					columns[i].setWidth(width - consumeWidth);
+				}
+				return consumeWidth;
+			}
+		});
+        
+		mTableViewer.addCheckStateListener(new PKFieldCheckStateListener());
+		callback = new FieldDialogCallback();
+	}
+
+	/**
+	 * This method process the Add... button pressed event. It opens dialog to
+	 * add new entity field
+	 */
+	private void handleAddButtonSelected() {
+		AddFieldDialog dialog = new AddFieldDialog(getShell(), title, typeProposals, labelsForText);
+		int result = dialog.open();
+		if (result == Window.CANCEL) {
+			return;
+		}
+		EntityRow entityRow = dialog.getEntityRow();
+		addEntityRow(entityRow);
+	}
+	
+	/**
+	 * Add new entity to the table input
+	 * 
+	 * @param entity
+	 *            the entity which have to be added to the table
+	 */
+	private void addEntityRow(EntityRow entity) {
+		if (entity == null)
+			return;
+		List<EntityRow> valueList = (ArrayList<EntityRow>) mTableViewer.getInput();		
+		if (valueList == null)
+			valueList = new ArrayList<EntityRow>();		
+		valueList.add(entity);
+		setInput(valueList);
+	}
+	
+	/**
+	 * This method process the Edit... button pressed event. It opens dialog to edit chosen entity field
+	 */
+	private void handleEditButtonSelected() {
+		ISelection s = mTableViewer.getSelection();
+		if (!(s instanceof IStructuredSelection))
+			return;
+		IStructuredSelection selection = (IStructuredSelection) s;
+		if (selection.size() != 1)
+			return;
+		
+		Object selectedObj = selection.getFirstElement();
+		EntityRow entityForEdit = (EntityRow) selectedObj;
+		int index = mTableWidget.getSelectionIndex();
+		boolean isChecked = mTableViewer.getChecked(entityForEdit);
+		
+		EditFieldDialog dialog = new EditFieldDialog(getShell(), title, typeProposals, labelsForText, entityForEdit);
+		dialog.open();
+		EntityRow entityRow = dialog.getEntityRow();
+		if (entityRow != null) {			
+			editEntityRow(index, entityRow);
+			mTableViewer.setChecked(entityRow, isChecked);
+			mTableViewer.setGrayed(entityRow, false);
+		}
+	}
+	
+	/**
+	 * Edit chosen entity from the table
+	 * @param index the index of the entity in the table
+	 * @param newEntity the edited entity field
+	 */
+	private void editEntityRow(int index, EntityRow newEntity) {
+		if (newEntity == null)
+			return;
+		
+		List<EntityRow> valueList = (ArrayList<EntityRow>) mTableViewer.getInput();		
+		if (valueList == null) {
+			valueList = new ArrayList();
+		}
+				
+		if (index == -1) {
+			valueList.add(newEntity);
+		} else {
+			valueList.set(index, newEntity);
+		}
+		
+		setInput(valueList);		
+	}
+
+	/**
+	 * This method process the Remove button pressed event.
+	 */
+	private void handleRemoveButtonSelected() {
+		ISelection selection = mTableViewer.getSelection();
+		if (selection.isEmpty() || !(selection instanceof IStructuredSelection))
+			return;
+		List selectedObject = ((IStructuredSelection) selection).toList();
+		removeEntityRow(selectedObject);		
+	}
+	
+	/**
+	 * Removes the selected entities from the table 
+	 * @param entities list with entities, which should be removed
+	 */
+	private void removeEntityRow(Collection entities) {
+		List<EntityRow> valueList = (ArrayList<EntityRow>) mTableViewer.getInput();
+		valueList.removeAll(entities);
+		setInput(valueList);
+	}
+
+	/**
+	 * Set the input of the table
+	 * @param input the list with entities which have to be presented in the table
+	 */
+	private void setInput(List input) {
+		mTableViewer.setInput(input);
+		// Create a new list to trigger property change
+		ArrayList<EntityRow> newInput = new ArrayList<EntityRow>();
+		newInput.addAll(input);
+		model.setProperty(propertyName, newInput);		
+	}
+
+	/**
+	 * @return the TableViewer of the table
+	 */
+	public TableViewer getTableViewer() {
+		return mTableViewer;
+	}
+	
+	// PROVIDERS FOR THE FIELD TABLE
+	
+	/**
+	 * The content provider for the table items
+	 */
+	protected class EntityRowContentProvider implements IStructuredContentProvider {
+		public boolean isDeleted(Object element) {
+			return false;
+		}
+		public Object[] getElements(Object element) {
+			if (element instanceof List) {
+				return ((List) element).toArray();
+			}
+			return new Object[0];
+		}
+		public void inputChanged(Viewer aViewer, Object oldInput, Object newInput) {
+			//Default nothing
+		}
+		public void dispose() {
+			//Default nothing
+		}
+	}
+	
+	/**
+	 * The label provider for the table items
+	 */
+	protected class EntityRowLabelProvider extends LabelProvider implements ITableLabelProvider {
+		public Image getColumnImage(Object element, int columnIndex) {
+		    if (columnIndex == 0) {
+		        return labelProviderImage;       
+		    }
+			return null;
+		}
+		
+		public String getColumnText(Object element, int columnIndex) {
+			EntityRow entity = (EntityRow) element;
+			if (columnIndex == NAME_COLUMN) {
+				return entity.getName();
+			}
+			if (columnIndex == TYPE_COLUMN) {
+				return entity.getFqnTypeName();
+			}		
+			mTableViewer.setChecked(entity, entity.isKey());
+			return "";
+		}
+
+        @Override
+        public Image getImage(Object element) {
+            return labelProviderImage;
+        }
+
+        @Override
+        public String getText(Object element) {
+			String[] array = (String[]) element;
+			if (array.length > 0) {
+				return array[0];
+			} else {
+				return super.getText(element);
+			}
+		}
+	}	
+	// END - PROVIDERS FOR THE FIELD TABLE	
+
+	/**
+	 * Listener for the Primary Key check box in the table item
+	 */
+	private class PKFieldCheckStateListener implements ICheckStateListener {
+
+		public void checkStateChanged(CheckStateChangedEvent event) {
+			List<String> pkFields = new ArrayList<String>();
+	        TableItem[] children = mTableViewer.getTable().getItems();
+	        for (int i = 0; i < children.length; i++) {
+	            TableItem item = children[i];
+	            EntityRow entityRow = (EntityRow)item.getData(); 
+	            entityRow.setKey(item.getChecked());
+				if (item.getChecked())
+					pkFields.add(entityRow.getName());
+	        }
+	        model.setProperty(IEntityDataModelProperties.PK_FIELDS, pkFields);
+		}
+		
+	}
+	
+	// CALLBACK MECHANISM
+	/**
+	 * Callback interface used by the Add/Edit-FieldDialog classes. 
+	 */
+	public interface DialogCallback {
+		
+		/**	
+		 * Validates the text fields. 
+		 * <p>Used to decide whether to enable the OK button of the dialog. 
+		 * If the method returns <code>true</code> the OK button is enabled, 
+		 * otherwise the OK button is disabled.</p> 
+		 * @param combo contains the predefined types
+		 * @param texts	the name of the entity field	
+		 * @return <code>true</code> if the values in the text fields are 
+		 *         valid, <code>false</code> otherwise.	 
+		 */
+		public boolean validate(Text type, Text[] texts);
+		
+		/**
+		 * Retrieves the entity presentation object from the fields of the dialog. 
+		 * <p>Implementers of the callback can use these method to do some 
+		 * preprocessing (like trimming) of the data in the text fields before 
+		 * using it. The returned values will be the actual data that will be 
+		 * put in the table viewer.</p> 
+		 * @param combo contains the predefined types
+		 * @param texts	the name of the entity field	
+		 * @return the entity presentation object retrieved from the dialog
+		 */
+		public EntityRow retrieveResultStrings(Text type, Text[] texts);
+		
+	}
+	
+	/**
+	 * Implementation of the <code>FieldDialogCallback</code> interface for 
+	 * both "Name" and "Types" table columns. 
+	 */
+	public class FieldDialogCallback implements DialogCallback {
+
+		/**
+		 * The first text field should not be empty. 
+		 */
+		public boolean validate(Text type, Text[] texts) {
+			if (texts.length > 0) {
+				IStatus validateFieldNameStatus = JavaConventions
+						.validateFieldName(texts[0].getText(),
+								JavaCore.VERSION_1_5,
+								JavaCore.VERSION_1_5);
+				if (!validateFieldNameStatus.isOK()) {
+					return false;
+				}
+			}
+			if (type.getText().equals("")) {
+				return false;
+			}
+			return true;
+		}
+		
+		/**
+		 * Just retrieves the unmodified values of the text fields as a 
+		 * entity field presentation
+		 * @see org.eclipse.jpt.ui.internal.wizards.entity.data.model.EntityRow
+		 */
+		public EntityRow retrieveResultStrings(Text type, Text[] texts) {
+			EntityRow entity = new EntityRow();			
+			entity.setFqnTypeName(type.getText());
+			entity.setName(texts[0].getText());
+			return entity;
+		}
+	}
+	
+	// THE DIALOGS USED FOR ADD/EDIT OF ENTITY FIELDS - BEGIN
+	
+	/**
+	 * The dialog which collect the information (name and type) for the new entity field
+	 */
+	private class AddFieldDialog extends Dialog implements ModifyListener, SelectionListener {
+		protected String windowTitle;
+		protected String[] typeProposals;
+		protected String[] labelsForText;
+		protected Text[] texts;		
+		protected EntityRow entityRow;
+		protected Text attributeType;
+		protected ContentProposalAdapter contentProposalAdapter; 		
+		
+		/**
+		 * Constructs AddFieldDialog
+		 * @param shell
+		 * @param windowTitle dialog label
+		 * @param typeProposals the elements for the combo
+		 * @param labelsForText name text
+		 */
+		public AddFieldDialog(Shell shell, String windowTitle, String[] typeProposals, String[] labelsForText) {
+			super(shell);
+			this.windowTitle = windowTitle;
+			this.typeProposals = typeProposals;
+			this.labelsForText  = labelsForText;
+		}
+		
+		/* Create the area of dialog
+		 * @see org.eclipse.jface.dialogs.Dialog#createDialogArea(org.eclipse.swt.widgets.Composite)
+		 */
+		@Override
+		public Control createDialogArea(Composite parent) {
+
+			Composite composite = (Composite) super.createDialogArea(parent);
+			getShell().setText(windowTitle);
+
+			GridLayout layout = new GridLayout();
+			layout.numColumns = 4;
+			composite.setLayout(layout);
+			GridData data = new GridData();
+			data.verticalAlignment = GridData.FILL;
+			data.horizontalAlignment = GridData.FILL;
+			data.widthHint = 300;
+			composite.setLayoutData(data);
+			
+			Label label = new Label(composite, SWT.LEFT);
+			label.setText(labelsForText[0]);
+			label.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING));
+			
+			
+			attributeType = new Text(composite, SWT.SINGLE | SWT.BORDER);// | SWT.READ_ONLY);		
+			//combo.setItems(labelsForCombo);
+			data = new GridData(GridData.FILL_HORIZONTAL);
+			data.horizontalSpan = 2;			
+			attributeType.setLayoutData(data);
+			
+			Button browseButton = new Button(composite, SWT.PUSH);
+			browseButton.setText(EntityWizardMsg.BROWSE_BUTTON_LABEL);
+			GridData browseButtonData = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
+			browseButtonData.horizontalSpan = 1;
+			browseButton.setLayoutData(browseButtonData);
+			browseButton.addSelectionListener(new SelectionListener() {
+				public void widgetSelected(SelectionEvent e) {
+					handleChooseEntityTypeButtonPressed();
+				}
+
+				public void widgetDefaultSelected(SelectionEvent e) {
+					// Do nothing
+				}
+			});
+
+			int n = labelsForText.length;
+			texts = new Text[n-1];
+			for (int i = 1; i < n; i++) {
+				Label labelI = new Label(composite, SWT.LEFT);
+				labelI.setText(labelsForText[i]);
+				labelI.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING));
+				texts[i-1] = new Text(composite, SWT.SINGLE | SWT.BORDER);
+				data = new GridData(GridData.FILL_HORIZONTAL);
+				data.horizontalSpan = 2;		
+				texts[i-1].setLayoutData(data);
+			}
+
+			attributeType.setFocus();
+			Dialog.applyDialogFont(parent);
+			createContentProposalProvider();			
+			return composite;
+		}
+		
+		private IContentProposalProvider createContentProposalProvider() {
+			SimpleContentProposalProvider contProvider = new SimpleContentProposalProvider(typeProposals);
+			contProvider.setFiltering(true);
+			
+			contentProposalAdapter = new ContentProposalAdapter(
+					attributeType,
+					new TextContentAdapter(), 
+					contProvider,
+					ks,
+					new char[] {'b', 'c', 'd', 'i', 'f', 'l', 's', 'j', 'B', 'C', 'D', 'F', 'S', 'L', 'I'});
+			contentProposalAdapter.setEnabled(true);
+			contentProposalAdapter.setProposalAcceptanceStyle(ContentProposalAdapter.PROPOSAL_REPLACE);
+			return contProvider;
+		}
+		
+
+		/**
+		 * Process browsing when the Browse... button have been pressed. Allow adding of entity field
+		 * with arbitrary type.
+		 */
+		private void handleChooseEntityTypeButtonPressed() {
+			//getControl().setCursor(new Cursor(getShell().getDisplay(), SWT.CURSOR_WAIT));
+			IPackageFragmentRoot packRoot = (IPackageFragmentRoot) model.getProperty(INewJavaClassDataModelProperties.JAVA_PACKAGE_FRAGMENT_ROOT);
+			if (packRoot == null) {
+				return;
+			}
+
+			// this eliminates the non-exported classpath entries
+			final IJavaSearchScope scope = TypeSearchEngine.createJavaSearchScopeForAProject(packRoot.getJavaProject(), true, true); 
+			
+			// This includes all entries on the classpath.
+			SelectionDialog dialog=null;
+			try{
+				dialog = JavaUI
+						.createTypeDialog(
+								getShell(),
+								null,
+								scope,
+								IJavaElementSearchConstants.CONSIDER_ALL_TYPES,
+								false);
+			} catch (JavaModelException e) {
+				JptUiPlugin.instance().getLog().log(e.getStatus());
+				return;
+			}
+			
+			dialog.setTitle(EntityWizardMsg.TYPE_DIALOG_TITLE);
+			dialog.setMessage(EntityWizardMsg.TYPE_DIALOG_DESCRIPTION);
+
+			if (dialog.open() == Window.OK) {
+				IType type;
+				Object[] result = dialog.getResult();
+		        if (result == null || result.length == 0) {
+		        	type = null;
+				}
+		        else type = (IType) result[0];
+				String superclassFullPath = IEntityDataModelProperties.EMPTY_STRING;
+				if (type != null) {
+					superclassFullPath = type.getFullyQualifiedName();
+				}
+				attributeType.setText(superclassFullPath);
+				//getControl().setCursor(null);
+				return;
+			}
+			//getControl().setCursor(null);
+		}
+		
+		
+		/* Create the content of the dialog
+		 * @see org.eclipse.jface.dialogs.Dialog#createContents(org.eclipse.swt.widgets.Composite)
+		 */
+		@Override
+		protected Control createContents(Composite parent) {
+			Composite composite = (Composite) super.createContents(parent);
+			
+			attributeType.addSelectionListener(this);
+			attributeType.addModifyListener(this);
+			for (int i = 0; i < texts.length; i++) {
+				texts[i].addModifyListener(this);
+			}
+			
+			updateOKButton();
+			
+			return composite;
+		}
+
+		/* Processes OK button pressed event.
+		 * @see org.eclipse.jface.dialogs.Dialog#okPressed()
+		 */
+		@Override
+		protected void okPressed() {
+			entityRow = callback.retrieveResultStrings(attributeType, texts);
+			super.okPressed();
+		}
+
+		/**
+		 * @return the entity representation with the information collected from the dialog
+		 */
+		public EntityRow getEntityRow() {
+			return entityRow;
+		}
+		
+		/* Processes text modifying event
+		 * @see org.eclipse.swt.events.ModifyListener#modifyText(org.eclipse.swt.events.ModifyEvent)
+		 */
+		public void modifyText(ModifyEvent e) {
+			updateOKButton();
+		}
+		
+		/**
+		 * Sets state of the OK button in accordance with validate method of the callback object
+		 * @see DialogCallback
+		 */
+		private void updateOKButton() {
+			getButton(IDialogConstants.OK_ID).setEnabled(callback.validate(attributeType, texts));
+		}
+		/* (non-Javadoc)
+		 * @see org.eclipse.swt.events.SelectionListener#widgetDefaultSelected(org.eclipse.swt.events.SelectionEvent)
+		 */
+		public void widgetDefaultSelected(SelectionEvent e) {
+			// TODO Auto-generated method stub
+			
+		}
+		/* Update OK button when the appropriate event occurs
+		 * @see org.eclipse.swt.events.SelectionListener#widgetSelected(org.eclipse.swt.events.SelectionEvent)
+		 */
+		public void widgetSelected(SelectionEvent e) {
+			updateOKButton();			
+		}
+	}
+	
+	/**
+	 * Constructs EditFieldDialog
+	 */
+	private class EditFieldDialog extends AddFieldDialog {
+		protected EntityRow entityRow;
+		/**
+		 * EditFieldDialog constructor comment.
+		 */
+		public EditFieldDialog(Shell shell, String windowTitle, String[] labelsForCombo, String[] labelsForText, EntityRow entity) {
+			super(shell, windowTitle, labelsForCombo, labelsForText);
+			this.entityRow = entity;		
+		}
+
+		/* Create the area of the dialog
+		 * @see org.eclipse.jpt.ui.internal.wizards.entity.EntityRowTableWizardSection.AddFieldDialog#createDialogArea(org.eclipse.swt.widgets.Composite)
+		 */
+		@Override
+		public Control createDialogArea(Composite parent) {
+
+			Composite composite = (Composite) super.createDialogArea(parent);
+
+			attributeType.setText(entityRow.getFqnTypeName());
+			texts[0].setText(entityRow.getName());
+			
+			return composite;
+		}
+	}	
+
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/entity/EntityTemplate.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/entity/EntityTemplate.java
new file mode 100644
index 0000000..f17af6b
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/entity/EntityTemplate.java
@@ -0,0 +1,126 @@
+package org.eclipse.jpt.ui.internal.wizards.entity;

+

+import org.eclipse.jpt.ui.internal.wizards.entity.data.model.*;

+import java.util.*;

+

+public class EntityTemplate

+{

+  protected static String nl;

+  public static synchronized EntityTemplate create(String lineSeparator)

+  {

+    nl = lineSeparator;

+    EntityTemplate result = new EntityTemplate();

+    nl = null;

+    return result;

+  }

+

+  public final String NL = nl == null ? (System.getProperties().getProperty("line.separator")) : nl;

+  protected final String TEXT_1 = "package ";

+  protected final String TEXT_2 = ";";

+  protected final String TEXT_3 = NL;

+  protected final String TEXT_4 = NL + "import ";

+  protected final String TEXT_5 = ";";

+  protected final String TEXT_6 = NL + NL + "/**" + NL + " * Entity implementation class for Entity: ";

+  protected final String TEXT_7 = NL + " *" + NL + " */" + NL + "public class ";

+  protected final String TEXT_8 = " extends ";

+  protected final String TEXT_9 = " implements ";

+  protected final String TEXT_10 = ", ";

+  protected final String TEXT_11 = " {" + NL + "" + NL + "\t";

+  protected final String TEXT_12 = " " + NL + "\tprivate ";

+  protected final String TEXT_13 = " ";

+  protected final String TEXT_14 = ";";

+  protected final String TEXT_15 = NL + "\tprivate static final long serialVersionUID = 1L;\t" + NL + "\tpublic ";

+  protected final String TEXT_16 = "() {" + NL + "\t\tsuper();" + NL + "\t} " + NL + "\t";

+  protected final String TEXT_17 = "   " + NL + "\tpublic ";

+  protected final String TEXT_18 = " get";

+  protected final String TEXT_19 = "() {" + NL + " \t\treturn this.";

+  protected final String TEXT_20 = ";" + NL + "\t}" + NL + "" + NL + "\tpublic void set";

+  protected final String TEXT_21 = "(";

+  protected final String TEXT_22 = " ";

+  protected final String TEXT_23 = ") {" + NL + "\t\tthis.";

+  protected final String TEXT_24 = " = ";

+  protected final String TEXT_25 = ";" + NL + "\t}" + NL + "\t";

+  protected final String TEXT_26 = NL + "   " + NL + "}";

+  protected final String TEXT_27 = NL;

+

+  public String generate(Object argument)

+  {

+    final StringBuffer stringBuffer = new StringBuffer();

+     CreateEntityTemplateModel model = (CreateEntityTemplateModel) argument; 

+if (model.getJavaPackageName()!=null && model.getJavaPackageName()!="") { 

+    stringBuffer.append(TEXT_1);

+    stringBuffer.append(model.getJavaPackageName());

+    stringBuffer.append(TEXT_2);

+    }

+    stringBuffer.append(TEXT_3);

+     Collection<String> imports = model.getImports(false);

+for (String anImport : imports) { 

+    stringBuffer.append(TEXT_4);

+    stringBuffer.append(anImport);

+    stringBuffer.append(TEXT_5);

+     } 

+    stringBuffer.append(TEXT_6);

+    stringBuffer.append(model.getEntityName());

+    stringBuffer.append(TEXT_7);

+    stringBuffer.append(model.getClassName());

+    String superClass = model.getSuperclassName();

+	if (! "".equals(superClass)) {

+    stringBuffer.append(TEXT_8);

+    stringBuffer.append(superClass);

+    }

+    

+	List<String> interfaces = model.getInterfaces(); 

+	if (interfaces.size()>0) {

+    stringBuffer.append(TEXT_9);

+     }

+	for (int i=0; i<interfaces.size(); i++) {

+		String INTERFACE = (String) interfaces.get(i);

+		if (i>0) { 

+    stringBuffer.append(TEXT_10);

+    }

+    stringBuffer.append(INTERFACE);

+    }

+    stringBuffer.append(TEXT_11);

+     List<EntityRow> fields = model.getEntityFields(); 

+	for (EntityRow entity : fields) {     

+	

+    stringBuffer.append(TEXT_12);

+    stringBuffer.append(entity.getType());

+    stringBuffer.append(TEXT_13);

+    stringBuffer.append(entity.getName());

+    stringBuffer.append(TEXT_14);

+    }

+    stringBuffer.append(TEXT_15);

+    stringBuffer.append(model.getClassName());

+    stringBuffer.append(TEXT_16);

+    

+	fields = model.getEntityFields();

+	if (fields != null) for (int i=0; i<fields.size(); i++) {

+		EntityRow field = (EntityRow) fields.get(i);

+		String TYPE = field.getType();

+		String NAME = field.getName();

+		String METHOD = NAME.substring(0,1).toUpperCase() + NAME.substring(1);

+	

+    stringBuffer.append(TEXT_17);

+    stringBuffer.append(TYPE);

+    stringBuffer.append(TEXT_18);

+    stringBuffer.append(METHOD);

+    stringBuffer.append(TEXT_19);

+    stringBuffer.append(NAME);

+    stringBuffer.append(TEXT_20);

+    stringBuffer.append(METHOD);

+    stringBuffer.append(TEXT_21);

+    stringBuffer.append(TYPE);

+    stringBuffer.append(TEXT_22);

+    stringBuffer.append(NAME);

+    stringBuffer.append(TEXT_23);

+    stringBuffer.append(NAME);

+    stringBuffer.append(TEXT_24);

+    stringBuffer.append(NAME);

+    stringBuffer.append(TEXT_25);

+    }

+    stringBuffer.append(TEXT_26);

+    stringBuffer.append(TEXT_27);

+    return stringBuffer.toString();

+  }

+}

diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/entity/EntityWizard.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/entity/EntityWizard.java
new file mode 100644
index 0000000..59fea4b
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/entity/EntityWizard.java
@@ -0,0 +1,137 @@
+/***********************************************************************
+ * Copyright (c) 2008, 2010 by SAP AG, Walldorf. 
+ * 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:
+ *     SAP AG - initial API and implementation
+ *     Dimiter Dimitrov, d.dimitrov@sap.com - initial API and implementation     
+ ***********************************************************************/
+package org.eclipse.jpt.ui.internal.wizards.entity;
+
+import static org.eclipse.jst.j2ee.internal.common.operations.INewJavaClassDataModelProperties.*;
+import java.lang.reflect.InvocationTargetException;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jpt.ui.JptUiPlugin;
+import org.eclipse.jpt.ui.internal.JptUiIcons;
+import org.eclipse.jpt.ui.internal.wizards.entity.data.model.EntityDataModelProvider;
+import org.eclipse.jst.j2ee.internal.plugin.J2EEEditorUtility;
+import org.eclipse.jst.j2ee.internal.project.J2EEProjectUtilities;
+import org.eclipse.ui.INewWizard;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.ide.IDE;
+import org.eclipse.wst.common.frameworks.datamodel.IDataModel;
+import org.eclipse.wst.common.frameworks.datamodel.IDataModelProvider;
+import org.eclipse.wst.common.frameworks.internal.datamodel.ui.DataModelWizard;
+
+public class EntityWizard extends DataModelWizard implements INewWizard {
+
+	
+	private static final String PAGE_ONE = "pageOne"; //$NON-NLS-1$
+    private static final String PAGE_TWO = "pageTwo"; //$NON-NLS-1$
+    
+    /**
+     * Constructs the Entity wizard
+     * @param model the data model
+     */
+    public EntityWizard(IDataModel model) {
+		super(model);
+        setWindowTitle(EntityWizardMsg.ENTITY_WIZARD_TITLE);
+        setDefaultPageImageDescriptor(JptUiPlugin.getImageDescriptor(JptUiIcons.ENTITY_WIZ_BANNER));        
+	}    
+ 
+	/**
+	 * Empty constructor
+	 */
+	public EntityWizard(){
+    	this(null);
+    }
+	
+	/* Adds the two pages of the entity wizard 
+	 * @see org.eclipse.wst.common.frameworks.internal.datamodel.ui.DataModelWizard#doAddPages()
+	 */
+	@Override
+	protected void doAddPages() {
+		EntityClassWizardPage page1 = new EntityClassWizardPage(
+		        getDataModel(),
+		        PAGE_ONE,
+		        EntityWizardMsg.ENTITY_WIZARD_PAGE_DESCRIPTION,
+		        EntityWizardMsg.ENTITY_WIZARD_PAGE_TITLE, 
+				J2EEProjectUtilities.EJB);
+		addPage(page1);
+		EntityFieldsWizardPage page2 = new EntityFieldsWizardPage(getDataModel(), PAGE_TWO);
+		addPage(page2);
+	}
+
+	/* Return the default data model provider (EntityDataModelProvider in our case)
+	 * @see org.eclipse.wst.common.frameworks.internal.datamodel.ui.DataModelWizard#getDefaultProvider()
+	 */
+	@Override
+	protected IDataModelProvider getDefaultProvider() {
+		return new EntityDataModelProvider();
+	}
+
+	/* Check whether the mandatory information is set and wizard could finish
+	 * @see org.eclipse.wst.common.frameworks.internal.datamodel.ui.DataModelWizard#canFinish()
+	 */
+	@Override
+	public boolean canFinish() {
+		 return getDataModel().isValid();
+	}
+	
+	/* 
+	 * Override the parent method in order to open the generated entity class in java editor
+	 * @see org.eclipse.wst.common.frameworks.internal.datamodel.ui.DataModelWizard#postPerformFinish()
+	 */
+	@Override
+    protected void postPerformFinish() throws InvocationTargetException {      
+        try {
+            String className = getDataModel().getStringProperty(QUALIFIED_CLASS_NAME);
+            IProject p = (IProject) getDataModel().getProperty(PROJECT);
+            IJavaProject javaProject = J2EEEditorUtility.getJavaProject(p);
+            IFile file = (IFile) javaProject.findType(className).getResource();
+            openEditor(file);
+        } catch (Exception cantOpen) {
+        	JptUiPlugin.log(cantOpen);
+        } 
+    }
+	
+    /**
+     * This method is intended for internal use only. It will open the file, sent as parameter
+     * in its own java editor
+     * @param file who should be opened
+     */
+    private void openEditor(final IFile file) {
+    	if (getDataModel().getBooleanProperty(OPEN_IN_EDITOR)) {
+    		if (file != null) {
+    			getShell().getDisplay().asyncExec(new Runnable() {
+    				public void run() {
+    					try {
+    						IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
+    						IDE.openEditor(page, file, true);
+    					}
+    					catch (PartInitException e) {
+    						JptUiPlugin.log(e);
+    					}
+    				}
+    			});
+    		}
+    	}
+    }
+    
+    /* Implement the abstract method from IWorkbenchWizard
+     * @see org.eclipse.ui.IWorkbenchWizard#init(org.eclipse.ui.IWorkbench, org.eclipse.jface.viewers.IStructuredSelection)
+     */
+    public void init(IWorkbench workbench, IStructuredSelection selection) {
+		getDataModel();
+	}
+    
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/entity/EntityWizardMsg.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/entity/EntityWizardMsg.java
new file mode 100644
index 0000000..38c17bf
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/entity/EntityWizardMsg.java
@@ -0,0 +1,126 @@
+/***********************************************************************
+ * Copyright (c) 2008, 2010 by SAP AG, Walldorf. 
+ * 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:
+ *     SAP AG - initial API and implementation
+ *     Dimiter Dimitrov, d.dimitrov@sap.com - initial API and implementation     
+ ***********************************************************************/
+package org.eclipse.jpt.ui.internal.wizards.entity;
+
+import com.ibm.icu.text.MessageFormat;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+import org.eclipse.osgi.util.NLS;
+
+public class EntityWizardMsg extends NLS {	
+	
+    private static final String BUNDLE_NAME = "jpt_ui_entity_wizard";//$NON-NLS-1$
+    private static ResourceBundle resourceBundle;
+
+    public static String ENTITY_WIZARD_TITLE;
+    public static String ENTITY_WIZARD_PAGE_TITLE;    
+    public static String ENTITY_WIZARD_PAGE_DESCRIPTION;
+    public static String DEFAULT_PACKAGE_WARNING;
+    public static String ENTITY_PROPERTIES_TITLE;
+    public static String ENTITY_PROPERTIES_DESCRIPTION;
+    public static String ENTITY;
+    public static String MAPPED_AS_SUPERCLASS;
+    public static String INHERITANCE_GROUP;
+    public static String INHERITANCE_CHECK_BOX;
+    public static String XML_STORAGE_GROUP;
+    public static String XML_SUPPORT;    
+    public static String CHOOSE_XML;
+    public static String MAPPING_XML_TITLE;
+    public static String XML_NAME_TITLE;
+    public static String INVALID_XML_NAME;
+    public static String CHOOSE_MAPPING_XML_MESSAGE;
+    public static String TYPE_DIALOG_TITLE;
+    public static String TYPE_DIALOG_DESCRIPTION;
+    public static String ENTITY_NAME;
+    public static String TABLE_NAME;
+    public static String TABLE_NAME_GROUP;
+    public static String USE_DEFAULT;
+    public static String ENTITY_FIELDS_DIALOG_TITLE;
+    public static String ENTITY_FIELDS_GROUP;
+    public static String KEY;
+    public static String NAME_COLUMN;
+    public static String TYPE_COLUMN;
+	public static String NAME_TEXT_FIELD;
+    public static String TYPE_TEXT_FIELD;
+    public static String BROWSE_BUTTON_LABEL;
+    public static String ADD_BUTTON_LABEL;
+    public static String EDIT_BUTTON_LABEL;
+	public static String EntityDataModelProvider_typeNotInProjectClasspath;
+	public static String EntityDataModelProvider_invalidPKType;
+	public static String EntityDataModelProvider_invalidArgument;
+	public static String REMOVE_BUTTON_LABEL;
+    public static String DUPLICATED_ENTITY_NAMES_MESSAGE;
+    public static String ACCESS_TYPE;
+    public static String FIELD_BASED;
+    public static String PROPERTY_BASED;
+    public static String NO_JPA_PROJECTS;      
+    public static String APPLY_CHANGES_TO_PERSISTENCE_XML;
+    public static String ADD_MAPPED_SUPERCLASS_TO_XML;
+    public static String ADD_ENTITY_TO_XML;
+    private EntityWizardMsg() {
+        // prevent instantiation of class
+    }    
+    
+	static {
+		NLS.initializeMessages(BUNDLE_NAME, EntityWizardMsg.class);
+	}
+
+    /**
+     * Returns the resource bundle used by all classes in this Project
+     */
+    public static ResourceBundle getResourceBundle() {
+        try {
+            return ResourceBundle.getBundle(BUNDLE_NAME);//$NON-NLS-1$
+        } catch (MissingResourceException e) {
+            // does nothing - this method will return null and getString(String) will return 
+        	// the key it was called with
+        }
+        return null;
+    }
+
+    /**
+     * Returns the externalized string, mapped to this key
+     * @param key 
+     * @return the text mapped to the key parameter
+     */
+    public static String getString(String key) {
+        if (resourceBundle == null) {
+            resourceBundle = getResourceBundle();
+        }
+
+        if (resourceBundle != null) {
+            try {
+                return resourceBundle.getString(key);
+            } catch (MissingResourceException e) {
+            	//exception during string obtaining
+                return "-" + key + "-";//$NON-NLS-2$//$NON-NLS-1$
+            }
+        }
+        //return key, because the relevant string missing in the bundle
+        return "+" + key + "+";//$NON-NLS-2$//$NON-NLS-1$
+    }
+
+    /**
+     * Returns the formated string, mapped to this key
+     * @param key
+     * @param arguments
+     * @return the formated text, mapped to this key, with substituted arguments 
+     */
+    public static String getString(String key, Object[] arguments) {
+        try {
+            return MessageFormat.format(getString(key), arguments);
+        } catch (IllegalArgumentException e) {
+            return getString(key);
+        }
+    } 
+	
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/entity/IdClassTemplate.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/entity/IdClassTemplate.java
new file mode 100644
index 0000000..89c2b63
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/entity/IdClassTemplate.java
@@ -0,0 +1,255 @@
+package org.eclipse.jpt.ui.internal.wizards.entity;

+

+import org.eclipse.jpt.ui.internal.wizards.entity.data.model.*;

+import java.util.*;

+

+public class IdClassTemplate

+{

+  protected static String nl;

+  public static synchronized IdClassTemplate create(String lineSeparator)

+  {

+    nl = lineSeparator;

+    IdClassTemplate result = new IdClassTemplate();

+    nl = null;

+    return result;

+  }

+

+  public final String NL = nl == null ? (System.getProperties().getProperty("line.separator")) : nl;

+  protected final String TEXT_1 = "package ";

+  protected final String TEXT_2 = ";";

+  protected final String TEXT_3 = NL;

+  protected final String TEXT_4 = NL + "import ";

+  protected final String TEXT_5 = ";";

+  protected final String TEXT_6 = NL + NL + "/**" + NL + " * ID class for entity: ";

+  protected final String TEXT_7 = NL + " *" + NL + " */ " + NL + "public class ";

+  protected final String TEXT_8 = " ";

+  protected final String TEXT_9 = " implements ";

+  protected final String TEXT_10 = ", ";

+  protected final String TEXT_11 = " {   " + NL + "   " + NL + "\t";

+  protected final String TEXT_12 = "         " + NL + "\tprivate ";

+  protected final String TEXT_13 = " ";

+  protected final String TEXT_14 = ";";

+  protected final String TEXT_15 = NL + "\tprivate static final long serialVersionUID = 1L;" + NL + "" + NL + "\tpublic ";

+  protected final String TEXT_16 = "() {}" + NL + "" + NL + "\t";

+  protected final String TEXT_17 = NL + NL + "\tpublic ";

+  protected final String TEXT_18 = " get";

+  protected final String TEXT_19 = "() {" + NL + "\t\treturn this.";

+  protected final String TEXT_20 = ";" + NL + "\t}" + NL + "" + NL + "\tpublic void set";

+  protected final String TEXT_21 = "(";

+  protected final String TEXT_22 = " ";

+  protected final String TEXT_23 = ") {" + NL + "\t\tthis.";

+  protected final String TEXT_24 = " = ";

+  protected final String TEXT_25 = ";" + NL + "\t}" + NL + "\t";

+  protected final String TEXT_26 = NL + "   " + NL + "\t/*" + NL + "\t * @see java.lang.Object#equals(Object)" + NL + "\t */\t" + NL + "\tpublic boolean equals(Object o) {" + NL + "\t\tif (o == this) {" + NL + "\t\t\treturn true;" + NL + "\t\t}" + NL + "\t\tif (!(o instanceof ";

+  protected final String TEXT_27 = ")) {" + NL + "\t\t\treturn false;" + NL + "\t\t}" + NL + "\t\t";

+  protected final String TEXT_28 = " other = (";

+  protected final String TEXT_29 = ") o;" + NL + "\t\treturn true";

+  protected final String TEXT_30 = NL + "\t\t\t&& ";

+  protected final String TEXT_31 = "() == other.";

+  protected final String TEXT_32 = "()";

+  protected final String TEXT_33 = NL + "\t\t\t&& (Double.doubleToLongBits(";

+  protected final String TEXT_34 = "()) == Double.doubleToLongBits(other.";

+  protected final String TEXT_35 = "()))";

+  protected final String TEXT_36 = NL + "\t\t\t&& (Float.floatToIntBits(";

+  protected final String TEXT_37 = "()) == Float.floatToIntBits(other.";

+  protected final String TEXT_38 = "()))";

+  protected final String TEXT_39 = NL + "\t\t\t&& (";

+  protected final String TEXT_40 = "() == null ? other.";

+  protected final String TEXT_41 = "() == null : ";

+  protected final String TEXT_42 = "().equals(other.";

+  protected final String TEXT_43 = "()))";

+  protected final String TEXT_44 = ";" + NL + "\t}" + NL + "\t" + NL + "\t/*\t " + NL + "\t * @see java.lang.Object#hashCode()" + NL + "\t */\t" + NL + "\tpublic int hashCode() {" + NL + "\t\tfinal int prime = 31;" + NL + "\t\tint result = 1;";

+  protected final String TEXT_45 = NL + "\t\tresult = prime * result + (";

+  protected final String TEXT_46 = "() ? 1 : 0);";

+  protected final String TEXT_47 = NL + "\t\tresult = prime * result + ";

+  protected final String TEXT_48 = "();";

+  protected final String TEXT_49 = NL + "\t\tresult = prime * result + ((int) ";

+  protected final String TEXT_50 = "());";

+  protected final String TEXT_51 = NL + "\t\tresult = prime * result + ((int) (";

+  protected final String TEXT_52 = "() ^ (";

+  protected final String TEXT_53 = "() >>> 32)));";

+  protected final String TEXT_54 = NL + "\t\tresult = prime * result + ((int) (Double.doubleToLongBits(";

+  protected final String TEXT_55 = "() ) ^ (Double.doubleToLongBits(";

+  protected final String TEXT_56 = "()) >>> 32)));";

+  protected final String TEXT_57 = NL + "\t\tresult = prime * result + Float.floatToIntBits(";

+  protected final String TEXT_58 = "());";

+  protected final String TEXT_59 = NL + "\t\tresult = prime * result + (";

+  protected final String TEXT_60 = "() == null ? 0 : ";

+  protected final String TEXT_61 = "().hashCode());";

+  protected final String TEXT_62 = NL + "\t\treturn result;" + NL + "\t}" + NL + "   " + NL + "   " + NL + "}";

+  protected final String TEXT_63 = NL;

+

+  public String generate(Object argument)

+  {

+    final StringBuffer stringBuffer = new StringBuffer();

+     CreateEntityTemplateModel model = (CreateEntityTemplateModel) argument; 

+if (model.getJavaPackageName()!=null && model.getJavaPackageName()!="") { 

+    stringBuffer.append(TEXT_1);

+    stringBuffer.append(model.getJavaPackageName());

+    stringBuffer.append(TEXT_2);

+    }

+    stringBuffer.append(TEXT_3);

+     Collection<String> imports = model.getImports(true);

+for (String anImport : imports) { 

+    stringBuffer.append(TEXT_4);

+    stringBuffer.append(anImport);

+    stringBuffer.append(TEXT_5);

+     } 

+    stringBuffer.append(TEXT_6);

+    stringBuffer.append(model.getClassName());

+    stringBuffer.append(TEXT_7);

+    stringBuffer.append(model.getIdClassName());

+    stringBuffer.append(TEXT_8);

+     List<String> interfaces = model.getInterfaces(); 

+	if (interfaces.size()>0) {

+    stringBuffer.append(TEXT_9);

+     }

+	for (int i=0; i<interfaces.size(); i++) {

+		String INTERFACE = (String) interfaces.get(i);

+		if (i>0) { 

+    stringBuffer.append(TEXT_10);

+    }

+    stringBuffer.append(INTERFACE);

+    }

+    stringBuffer.append(TEXT_11);

+     List<EntityRow> fields = model.getEntityFields();

+	List<String> pkFields = model.getPKFields(); 

+	for (int i=0; i<fields.size(); i++) {

+		EntityRow entity = (EntityRow) fields.get(i);

+		if (!pkFields.contains(entity.getName())) {

+			continue;

+		}

+	

+    stringBuffer.append(TEXT_12);

+    stringBuffer.append(entity.getType());

+    stringBuffer.append(TEXT_13);

+    stringBuffer.append(entity.getName());

+    stringBuffer.append(TEXT_14);

+    }

+    stringBuffer.append(TEXT_15);

+    stringBuffer.append(model.getIdClassName());

+    stringBuffer.append(TEXT_16);

+    

+	fields = model.getEntityFields();

+	if (fields != null) for (int i=0; i<fields.size(); i++) {

+		EntityRow field = (EntityRow) fields.get(i);

+		String TYPE = field.getType();

+		String NAME = field.getName();

+		if (!pkFields.contains(NAME)) {

+			continue;

+		} 		

+		String METHOD = NAME.substring(0,1).toUpperCase() + NAME.substring(1);        

+	

+    stringBuffer.append(TEXT_17);

+    stringBuffer.append(TYPE);

+    stringBuffer.append(TEXT_18);

+    stringBuffer.append(METHOD);

+    stringBuffer.append(TEXT_19);

+    stringBuffer.append(NAME);

+    stringBuffer.append(TEXT_20);

+    stringBuffer.append(METHOD);

+    stringBuffer.append(TEXT_21);

+    stringBuffer.append(TYPE);

+    stringBuffer.append(TEXT_22);

+    stringBuffer.append(NAME);

+    stringBuffer.append(TEXT_23);

+    stringBuffer.append(NAME);

+    stringBuffer.append(TEXT_24);

+    stringBuffer.append(NAME);

+    stringBuffer.append(TEXT_25);

+    }

+    stringBuffer.append(TEXT_26);

+    stringBuffer.append(model.getIdClassName());

+    stringBuffer.append(TEXT_27);

+    stringBuffer.append(model.getIdClassName());

+    stringBuffer.append(TEXT_28);

+    stringBuffer.append(model.getIdClassName());

+    stringBuffer.append(TEXT_29);

+     if (fields != null) for (int i=0; i<fields.size(); i++) {

+	EntityRow field = (EntityRow) fields.get(i); 

+	String NAME = field.getName();

+	if (!pkFields.contains(NAME)) {

+       	continue;

+    }

+     	String TYPE = field.getType(); 

+	String GET_METHOD = "get" + NAME.substring(0,1).toUpperCase() + NAME.substring(1); 

+    	if (TYPE.equals("boolean") || TYPE.equals("byte") || TYPE.equals("char") || TYPE.equals("short") || TYPE.equals("int") || TYPE.equals("long")) { 

+    stringBuffer.append(TEXT_30);

+    stringBuffer.append(GET_METHOD);

+    stringBuffer.append(TEXT_31);

+    stringBuffer.append(GET_METHOD);

+    stringBuffer.append(TEXT_32);

+     	} else if (TYPE.equals("double")) { 

+    stringBuffer.append(TEXT_33);

+    stringBuffer.append(GET_METHOD);

+    stringBuffer.append(TEXT_34);

+    stringBuffer.append(GET_METHOD);

+    stringBuffer.append(TEXT_35);

+     	} else if (TYPE.equals("float")) { 

+    stringBuffer.append(TEXT_36);

+    stringBuffer.append(GET_METHOD);

+    stringBuffer.append(TEXT_37);

+    stringBuffer.append(GET_METHOD);

+    stringBuffer.append(TEXT_38);

+     	} else { 

+    stringBuffer.append(TEXT_39);

+    stringBuffer.append(GET_METHOD);

+    stringBuffer.append(TEXT_40);

+    stringBuffer.append(GET_METHOD);

+    stringBuffer.append(TEXT_41);

+    stringBuffer.append(GET_METHOD);

+    stringBuffer.append(TEXT_42);

+    stringBuffer.append(GET_METHOD);

+    stringBuffer.append(TEXT_43);

+     	} 

+     } 

+    stringBuffer.append(TEXT_44);

+     if (fields != null) for (int i=0; i<fields.size(); i++) { 

+	EntityRow field = (EntityRow) fields.get(i);

+	String NAME = field.getName();

+	if (!pkFields.contains(NAME)) {

+       	continue;

+    }

+     	String TYPE = field.getType(); 

+	String GET_METHOD = "get" + NAME.substring(0,1).toUpperCase() + NAME.substring(1); 

+    	if (TYPE.equals("boolean")) { 

+    stringBuffer.append(TEXT_45);

+    stringBuffer.append(GET_METHOD);

+    stringBuffer.append(TEXT_46);

+     	} else if (TYPE.equals("int")) { 

+    stringBuffer.append(TEXT_47);

+    stringBuffer.append(GET_METHOD);

+    stringBuffer.append(TEXT_48);

+     	} else if (TYPE.equals("byte") || TYPE.equals("char") || TYPE.equals("short")) { 

+    stringBuffer.append(TEXT_49);

+    stringBuffer.append(GET_METHOD);

+    stringBuffer.append(TEXT_50);

+     	} else if (TYPE.equals("long")) { 

+    stringBuffer.append(TEXT_51);

+    stringBuffer.append(GET_METHOD);

+    stringBuffer.append(TEXT_52);

+    stringBuffer.append(GET_METHOD);

+    stringBuffer.append(TEXT_53);

+     	} else if (TYPE.equals("double")) { 

+    stringBuffer.append(TEXT_54);

+    stringBuffer.append(GET_METHOD);

+    stringBuffer.append(TEXT_55);

+    stringBuffer.append(GET_METHOD);

+    stringBuffer.append(TEXT_56);

+     	} else if (TYPE.equals("float")) { 

+    stringBuffer.append(TEXT_57);

+    stringBuffer.append(GET_METHOD);

+    stringBuffer.append(TEXT_58);

+     	} else { 

+    stringBuffer.append(TEXT_59);

+    stringBuffer.append(GET_METHOD);

+    stringBuffer.append(TEXT_60);

+    stringBuffer.append(GET_METHOD);

+    stringBuffer.append(TEXT_61);

+     	} 

+     } 

+    stringBuffer.append(TEXT_62);

+    stringBuffer.append(TEXT_63);

+    return stringBuffer.toString();

+  }

+}

diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/entity/data/model/CreateEntityTemplateModel.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/entity/data/model/CreateEntityTemplateModel.java
new file mode 100644
index 0000000..5937f91
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/entity/data/model/CreateEntityTemplateModel.java
@@ -0,0 +1,384 @@
+/***********************************************************************
+ * Copyright (c) 2008 by SAP AG, Walldorf. 
+ * 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:
+ *     SAP AG - initial API and implementation
+ *     Dimiter Dimitrov, d.dimitrov@sap.com - initial API and implementation     
+ ***********************************************************************/
+package org.eclipse.jpt.ui.internal.wizards.entity.data.model;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.TreeSet;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.jdt.core.IPackageFragmentRoot;
+import org.eclipse.jdt.core.Signature;
+import org.eclipse.jem.util.emf.workbench.ProjectUtilities;
+import org.eclipse.jpt.core.JptCorePlugin;
+import org.eclipse.jst.j2ee.internal.common.operations.INewJavaClassDataModelProperties;
+import org.eclipse.jst.j2ee.internal.project.J2EEProjectUtilities;
+import org.eclipse.wst.common.componentcore.internal.operation.IArtifactEditOperationDataModelProperties;
+import org.eclipse.wst.common.frameworks.datamodel.IDataModel;
+
+public class CreateEntityTemplateModel {
+	
+	protected IDataModel dataModel;
+	
+	private static final String DOT = "."; //$NON-NLS-1$
+	private static final String BRACKET = "["; //$NON-NLS-1$
+	private static final String PK_SUFFIX = "PK"; //$NON-NLS-1$
+	private static final String QUALIFIED_SERIALIZABLE = "java.io.Serializable"; //$NON-NLS-1$
+	private static final String PERSISTENCE_PACKAGE = "javax.persistence.*"; //$NON-NLS-1$
+	private static final String ENTITY_ANNOTATION = "@Entity"; //$NON-NLS-1$
+	private static final String MAPPED_AS_SUPERCLASS_TYPE = "@MappedSuperclass"; //$NON-NLS-1$
+	private static final String INHERITANCE_TYPE = "@Inheritance"; //$NON-NLS-1$	
+		
+	/**
+	 * Constructs entity model as expansion of the data model
+	 * @param dataModel
+	 */
+	public CreateEntityTemplateModel(IDataModel dataModel) {
+		this.dataModel = dataModel;
+	}
+	
+	/**
+	 * Returns the necessary imports on depends of entity (primary keys) fields. It is used from 
+	 * JET emmiter when it generates entity (IdClass)
+	 * @param isIdClass flag, which indicates the case. When it is false, the result is 
+	 * the import list for the entity class, in other case the results is the set for the IdClass 
+	 * generation
+	 * @return the imports collection with the imports for the generated java class
+	 */
+	public Collection<String> getImports(boolean isIdClass) {
+		Collection<String> collection = new TreeSet<String>();
+		
+		String className = getClassName();
+		String superclassName = getQualifiedSuperclassName();
+
+		if (superclassName != null && superclassName.length() > 0 && 
+				!equalSimpleNames(className, superclassName)) {
+			collection.add(superclassName);
+		}
+		
+		List interfaces = getQualifiedInterfaces();
+		if (interfaces != null) {
+			Iterator iterator = interfaces.iterator();
+			while (iterator.hasNext()) {
+				String iface = (String) iterator.next();
+				if (!equalSimpleNames(getClassName(), iface)) {
+					collection.add(iface);
+				}
+			}
+		}
+		if (isIdClass) {
+			collection.addAll(getIdClassImportList());
+		} else {			
+			collection.add(PERSISTENCE_PACKAGE);
+			collection.addAll(getFieldImportList());
+			
+		}
+		return collection;
+	}	
+
+	/**
+	 * @return class name of the entity
+	 */
+	public String getClassName() {
+		return getProperty(INewJavaClassDataModelProperties.CLASS_NAME).trim();
+	}
+
+	/**
+	 * @return package name when the entity will be generated
+	 */
+	public String getJavaPackageName() {
+		return getProperty(INewJavaClassDataModelProperties.JAVA_PACKAGE).trim();
+	}
+
+	/**
+	 * @return fully qualified java class name
+	 */
+	public String getQualifiedJavaClassName() {
+		if (!getJavaPackageName().equals(IEntityDataModelProperties.EMPTY_STRING)) {
+			return getJavaPackageName() + DOT + getClassName();
+		} 
+		return getClassName();
+	}
+
+	/**
+	 * @return the name 
+	 */
+	public String getSuperclassName() {
+		String qualified = getQualifiedSuperclassName();
+		if (equalSimpleNames(getClassName(), qualified)) {
+			return qualified;
+		} else {
+			return Signature.getSimpleName(qualified);
+		}
+	}
+	
+	/**
+	 * @return fully qualified name of the entity's super class
+	 */
+	public String getQualifiedSuperclassName() {
+		return getProperty(INewJavaClassDataModelProperties.SUPERCLASS).trim();
+	}
+	
+	/**
+	 * @return list with the interfaces implemented from entity class 
+	 */
+	public List<String> getInterfaces() {
+		List qualifiedInterfaces = getQualifiedInterfaces();
+		List<String> interfaces = new ArrayList<String>(qualifiedInterfaces.size());
+		
+		Iterator iter = qualifiedInterfaces.iterator();
+		while (iter.hasNext()) {
+			String qualified = (String) iter.next();
+			if (equalSimpleNames(getClassName(), qualified)) {
+				interfaces.add(qualified);
+			} else {
+				interfaces.add(Signature.getSimpleName(qualified));
+			}
+		}
+		
+		return interfaces;
+	}
+
+	/**
+	 * @return list with the interfaces (fully qualified named) implemented from entity class
+	 */
+	public List getQualifiedInterfaces() {
+		List interfaces = (List) this.dataModel.getProperty(INewJavaClassDataModelProperties.INTERFACES);		
+		if (interfaces == null){
+			interfaces = new ArrayList();
+		} 
+		interfaces.add(QUALIFIED_SERIALIZABLE);
+		return interfaces;
+	}
+
+	/**
+	 * Returns the value of the specified string property
+	 * @param propertyName
+	 * @return string value of teh specified propert
+	 */
+	protected String getProperty(String propertyName) {
+		return dataModel.getStringProperty(propertyName);
+	}
+	
+	/**
+	 * This methods is used for the comparison of fully qualified types 
+	 * @param name1 first type name
+	 * @param name2 second type name
+	 * @return whether the simple names of the types are equal
+	 */
+	protected boolean equalSimpleNames(String name1, String name2) {
+		String simpleName1 = Signature.getSimpleName(name1);
+		String simpleName2 = Signature.getSimpleName(name2);
+		return simpleName1.equals(simpleName2);
+	}
+	
+	/**
+	 * @return the type of the artifact - Entity or Mapped superclass
+	 */
+	public String getArtifactType() {
+		if(dataModel.getBooleanProperty(IEntityDataModelProperties.MAPPED_AS_SUPERCLASS)) {
+			return MAPPED_AS_SUPERCLASS_TYPE;
+		} 
+		return ENTITY_ANNOTATION;
+	}
+
+	/**
+	 * @return whether entity set inheritance strategy
+	 */
+	public boolean isInheritanceSet() {
+		return dataModel.getBooleanProperty(IEntityDataModelProperties.INHERITANCE);
+	}
+	
+	/**
+	 * @return the name of the inheritance strategy, as it is defined in the specification
+	 */
+	public String getInheritanceStrategyName() {		
+		return getProperty(IEntityDataModelProperties.INHERITANCE_STRATEGY);
+	}
+	
+	/**
+	 * @return the constructed @Inheritance annotation with the relevant strategy
+	 * if it is chosen
+	 */
+	public String getInheritanceStrategy() {
+		String result = IEntityDataModelProperties.EMPTY_STRING;
+		if (isInheritanceSet()) {	
+			result = INHERITANCE_TYPE;
+			if (!getProperty(IEntityDataModelProperties.INHERITANCE_STRATEGY).equals(IEntityDataModelProperties.EMPTY_STRING)) { //$NON-NLS-1$
+				result += "(strategy=InheritanceType." + getProperty(IEntityDataModelProperties.INHERITANCE_STRATEGY) + ")"; //$NON-NLS-1$ $NON-NLS-2$
+			
+			}		
+		}
+		return result;
+	}	
+	
+	/**
+	 * @return whether the generated artifact is not entity 
+	 */
+	public boolean isNonEntitySuperclass() {
+		return !dataModel.getBooleanProperty(IEntityDataModelProperties.ENTITY);
+	}
+
+	/**
+	 * @return true the created artifact will be annotated
+	 * @return false the entity mappings will be registered in XML
+	 */
+	public boolean isArtifactsAnnotated() {
+		return !dataModel.getBooleanProperty(IEntityDataModelProperties.XML_SUPPORT);
+	}
+	
+	public boolean isMappingXMLDefault() {
+		if (getMappingXMLName().equals(IEntityDataModelProperties.EMPTY_STRING)) {
+			return true;
+		}
+		return getMappingXMLName().equals(JptCorePlugin.getDefaultOrmXmlDeploymentURI(getProject()));
+	}
+	
+	public String getMappingXMLName() {
+		return dataModel.getStringProperty(IEntityDataModelProperties.XML_NAME).trim();
+	}
+	
+	public IFile getMappingXmlFile() {
+		IFile ormFile = null;
+		IProject project = getProject();
+		IPackageFragmentRoot[] sourceFragments = J2EEProjectUtilities.getSourceContainers(project);
+		for (IPackageFragmentRoot packageFragmentRoot : sourceFragments) {
+			ormFile = project.getFile(packageFragmentRoot.getResource().getName() + File.separator + getMappingXMLName());
+			if (ormFile.exists()) {
+				break;
+			}
+		}		
+		return ormFile;
+	}
+	
+	/**
+	 * @return the entity name (could be different from the class name)
+	 * See <code>isEntityNameSet()<code>
+	 */
+	public String getEntityName() {
+		return getProperty(IEntityDataModelProperties.ENTITY_NAME).trim();
+	}
+	
+	/**
+	 * @return whether the entity name is different than class name
+	 */
+	public boolean isEntityNameSet() {
+		boolean result = false;
+		if (!getClassName().equals(getEntityName())) {
+			result = true;
+		}
+		return result;
+	}
+	
+	/**
+	 * @return whether the table name is specified explicitly
+	 */
+	public boolean isTableNameSet() {
+		return !dataModel.getBooleanProperty(IEntityDataModelProperties.TABLE_NAME_DEFAULT);
+	}
+	
+	/**
+	 * @return the table name (if it is specified)
+	 * See <code>isTableNameSet()<code>
+	 */
+	public String getTableName() {
+		return getProperty(IEntityDataModelProperties.TABLE_NAME).trim();
+	}
+
+	/**
+	 * @return list with the entity fields
+	 */
+	public List<EntityRow> getEntityFields() {
+		ArrayList<EntityRow> fields = (ArrayList<EntityRow>) dataModel.getProperty(IEntityDataModelProperties.ENTITY_FIELDS);
+		if (fields == null){
+			return new ArrayList<EntityRow>();
+		} else
+			return fields;
+	}
+
+	/**
+	 * @return list with the imports necessary for the entity (based on its fields)
+	 */
+	public List<String> getFieldImportList() {
+		List<String> imports = new ArrayList<String>();
+		List<EntityRow> entities = getEntityFields();
+		for (EntityRow entityRow : entities) {
+			if (!imports.contains(entityRow.getFqnTypeName()) && !entityRow.getType().equals(entityRow.getFqnTypeName())) {
+				String fqnTypeName = entityRow.getFqnTypeName();
+				//remove the array brackets [] for the java.lang.Byte[] & java.lang.Character[]
+				if (fqnTypeName.indexOf(BRACKET) != -1) {
+					fqnTypeName = fqnTypeName.substring(0, fqnTypeName.indexOf("["));
+				}
+				imports.add(fqnTypeName);
+			}
+		}
+		return imports;		
+	}
+	/**
+	 * @return list with the imports necessary for the id class (based on its fields - primary keys of the entity)
+	 */
+	public List<String> getIdClassImportList() {
+		List<String> imports = new ArrayList<String>();
+		List<EntityRow> entities = getEntityFields();
+		List<String> pkFields = getPKFields();
+		for (EntityRow entityRow : entities) {
+			String name = entityRow.getName();
+			if (pkFields.contains(name)) {			
+				if (!imports.contains(entityRow.getFqnTypeName()) && !entityRow.getType().equals(entityRow.getFqnTypeName())) {
+					imports.add(entityRow.getFqnTypeName());
+				}
+			}
+		}
+		return imports;		
+	}
+	
+	/**
+	 * @return whether the access type is field based
+	 */
+	public boolean isFieldAccess() {
+		return dataModel.getBooleanProperty(IEntityDataModelProperties.FIELD_ACCESS_TYPE);
+	}	
+	
+	/**
+	 * @return the primary key is composite (more than one annotated as primary key field)
+	 */
+	public boolean isCompositePK() {
+		return getPKFields().size() > 1;
+	}
+
+	/**
+	 * @return list with primary key name(s)
+	 */
+	public List<String> getPKFields() {
+		return (ArrayList<String>)dataModel.getProperty(IEntityDataModelProperties.PK_FIELDS);
+	}	
+	
+	/**
+	 * @return constructed name of the id class (entity name + PK as suffix)
+	 */
+	public String getIdClassName() {
+		return getClassName() + PK_SUFFIX;
+	}
+	
+	/**
+	 * @return IProject presentation of JPA project
+	 */
+	public IProject getProject() {
+		String projectName = dataModel.getStringProperty(IArtifactEditOperationDataModelProperties.PROJECT_NAME);
+		return ProjectUtilities.getProject(projectName);
+	}	
+
+	
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/entity/data/model/EntityDataModelProvider.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/entity/data/model/EntityDataModelProvider.java
new file mode 100644
index 0000000..60d9ec9
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/entity/data/model/EntityDataModelProvider.java
@@ -0,0 +1,363 @@
+/***********************************************************************
+ * Copyright (c) 2008, 2009 by SAP AG, Walldorf. 
+ * 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:
+ *     SAP AG - initial API and implementation
+ *     Dimiter Dimitrov, d.dimitrov@sap.com - initial API and implementation
+ ***********************************************************************/
+package org.eclipse.jpt.ui.internal.wizards.entity.data.model;
+
+import com.ibm.icu.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.IType;
+import org.eclipse.jdt.core.JavaConventions;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.core.Signature;
+import org.eclipse.jem.util.emf.workbench.ProjectUtilities;
+import org.eclipse.jpt.core.JpaFile;
+import org.eclipse.jpt.core.JptCorePlugin;
+import org.eclipse.jpt.ui.JptUiPlugin;
+import org.eclipse.jpt.ui.internal.wizards.entity.EntityWizardMsg;
+import org.eclipse.jpt.ui.internal.wizards.entity.data.operation.NewEntityClassOperation;
+import org.eclipse.jst.j2ee.internal.common.J2EECommonMessages;
+import org.eclipse.jst.j2ee.internal.common.operations.INewJavaClassDataModelProperties;
+import org.eclipse.jst.j2ee.internal.common.operations.NewJavaClassDataModelProvider;
+import org.eclipse.wst.common.frameworks.datamodel.IDataModel;
+import org.eclipse.wst.common.frameworks.datamodel.IDataModelOperation;
+import org.eclipse.wst.common.frameworks.datamodel.IDataModelProvider;
+import org.eclipse.wst.common.frameworks.internal.plugin.WTPCommonPlugin;
+
+public class EntityDataModelProvider extends NewJavaClassDataModelProvider implements IEntityDataModelProperties{
+
+	@Override
+	public IDataModelOperation getDefaultOperation() {
+		return new NewEntityClassOperation(getDataModel());
+	}
+	
+	/**
+	 * Extends: <code>IDataModelProvider#getPropertyNames()</code>
+	 * and add own data model's properties specific for the entity model
+	 * 
+	 * @see org.eclipse.wst.common.frameworks.datamodel.IDataModelProvider#getPropertyNames()
+	 */
+	@Override
+	public Set getPropertyNames() {		
+		Set propertyNames = super.getPropertyNames();
+		propertyNames.add(INHERITANCE);
+		propertyNames.add(ENTITY);
+		propertyNames.add(MAPPED_AS_SUPERCLASS);
+		propertyNames.add(INHERITANCE_STRATEGY);
+		propertyNames.add(XML_SUPPORT);
+		propertyNames.add(XML_NAME);
+		propertyNames.add(ENTITY_NAME);
+		propertyNames.add(TABLE_NAME_DEFAULT);		
+		propertyNames.add(TABLE_NAME);
+		propertyNames.add(ENTITY_FIELDS);
+		propertyNames.add(PK_FIELDS);
+		propertyNames.add(FIELD_ACCESS_TYPE);
+		propertyNames.add(PROPERTY_ACCESS_TYPE);
+		return propertyNames;
+	}
+	
+	/**
+	 * Returns the default value of the parameter (which should present a valid data model property).  
+	 * This method does not accept a null parameter. It may return null. 
+	 * 
+	 * @see NewJavaClassDataModelProvider#getDefaultProperty(String)
+	 * @see IDataModelProvider#getDefaultProperty(String)
+	 * 
+	 * @param propertyName
+	 * @return Object default value of property
+	 */
+	@Override
+	public Object getDefaultProperty(String propertyName) {
+		if (propertyName.equals(INHERITANCE)) {
+			return Boolean.FALSE;
+		} else if (propertyName.equals(ENTITY)) {
+			return Boolean.TRUE;
+		} else if (propertyName.equals(MAPPED_AS_SUPERCLASS)) {
+			return Boolean.FALSE;
+		} else if (propertyName.equals(XML_SUPPORT)) {
+			return Boolean.FALSE;
+		} else if (propertyName.equals(XML_NAME)) {
+			return EMPTY_STRING;			
+		} else if (propertyName.equals(ENTITY_NAME)) {
+			return getStringProperty(CLASS_NAME);			
+		} else if (propertyName.equals(TABLE_NAME_DEFAULT)) {
+			return Boolean.TRUE;
+		} else if (propertyName.equals(TABLE_NAME)) {
+			return getStringProperty(CLASS_NAME);			
+		} else if (propertyName.equals(INHERITANCE_STRATEGY)) {
+			return EMPTY_STRING; 
+		} else if (propertyName.equals(SUPERCLASS)) {
+			return EMPTY_STRING;
+		} else if (propertyName.equals(ENTITY_FIELDS)) {
+			return new ArrayList<EntityRow>();
+		} else if (propertyName.equals(PK_FIELDS)) {
+			return new ArrayList<String>();
+		} else if (propertyName.equals(FIELD_ACCESS_TYPE)) {
+			return Boolean.TRUE;
+		} else if (propertyName.equals(PROPERTY_ACCESS_TYPE)) {
+			return Boolean.FALSE;			
+		} 
+		// Otherwise check super for default value for property
+		return super.getDefaultProperty(propertyName);
+	}
+	
+	@Override
+	public boolean propertySet(String propertyName, Object propertyValue) {
+		boolean ok = super.propertySet(propertyName, propertyValue);
+		if (propertyName.equals(PROJECT_NAME) || propertyName.equals(XML_SUPPORT)) {
+			this.model.notifyPropertyChange(XML_NAME, IDataModel.VALID_VALUES_CHG);
+		}
+		return ok;
+	}
+
+	/* Adds additional check to the model validation
+	 * @see org.eclipse.jst.j2ee.internal.common.operations.NewJavaClassDataModelProvider#validate(java.lang.String)
+	 */
+	@Override
+	public IStatus validate(String propertyName) {
+		IStatus result = super.validate(propertyName);
+		if (propertyName.equals(JAVA_PACKAGE)) {
+			return validateJavaPackage(getStringProperty(propertyName));
+		}
+		if (propertyName.equals(SUPERCLASS) && EMPTY_STRING.equals(getStringProperty(propertyName))) {
+			return WTPCommonPlugin.OK_STATUS;
+		}
+		if (propertyName.equals(XML_NAME)) {
+			return validateXmlName(getStringProperty(propertyName));
+		}
+		if (propertyName.equals(ENTITY_FIELDS)) {
+			return validateFieldsList((ArrayList<EntityRow>) getProperty(propertyName));
+		}
+		return result;		
+	}
+	
+	/**
+	 * This method is intended for internal use only. It will be used to validate the correctness of entity package
+	 * in accordance with Java convention requirements. This method will accept a null parameter. 
+	 * 
+	 * @see NewFilterClassDataModelProvider#validate(String)
+	 * 
+	 * @param packName
+	 * @return IStatus is the package name satisfies Java convention requirements
+	 */
+	
+	private IStatus validateJavaPackage(String packName) {		
+		if (packName == null || packName.equals(EMPTY_STRING)) {
+			return WTPCommonPlugin.createWarningStatus(EntityWizardMsg.DEFAULT_PACKAGE_WARNING);
+		}			
+		// Use standard java conventions to validate the package name
+		IStatus javaStatus = JavaConventions.validatePackageName(packName, JavaCore.VERSION_1_5, JavaCore.VERSION_1_5);
+		if (javaStatus.getSeverity() == IStatus.ERROR) {
+			String msg = J2EECommonMessages.ERR_JAVA_PACAKGE_NAME_INVALID + javaStatus.getMessage();				
+			return WTPCommonPlugin.createErrorStatus(msg);
+		} else if (javaStatus.getSeverity() == IStatus.WARNING) {
+			String msg = J2EECommonMessages.ERR_JAVA_PACKAGE_NAME_WARNING + javaStatus.getMessage();
+			return WTPCommonPlugin.createWarningStatus(msg);
+		}		
+		// java package name is valid
+		return WTPCommonPlugin.OK_STATUS;
+	}
+	
+	/**
+	 * This method is intended for internal use only.  It will be used to validate 
+	 * the correctness of xml file location. 
+	 * This method will accept a null parameter. 
+	 * 
+	 * @see NewFilterClassDataModelProvider#validate(String)
+	 * 
+	 * @param xmlName
+	 * @return IStatus is the package name satisfies Java convention requirements
+	 */
+	private IStatus validateXmlName(String xmlName) {
+		if (getBooleanProperty(XML_SUPPORT)) {
+			String projectName = this.model.getStringProperty(PROJECT_NAME);
+			IProject project = ProjectUtilities.getProject(projectName);
+			if (project != null) {
+				//TODO need to check content type as well since user can type in a file name, should have a different error message for invalid content type
+				JpaFile jpaFile = JptCorePlugin.getJpaFile(project, xmlName);
+				if (jpaFile == null) {
+					return new Status(
+						IStatus.ERROR, JptUiPlugin.PLUGIN_ID,
+							EntityWizardMsg.INVALID_XML_NAME);
+				}
+			}
+		}
+		return Status.OK_STATUS;
+	}
+	
+	
+	/**
+	 * This method is intended for internal use only. It will be used to validate the entity fields
+	 * list to ensure there are not any duplicates. This method will accept a null parameter. 
+	 * 
+	 * @see NewFilterClassDataModelProvider#validate(String)
+	 * 
+	 * @param entities
+	 * @return IStatus is the fields names are unique
+	 */
+	private IStatus validateFieldsList(ArrayList<EntityRow> entities) {
+		if (entities != null && !entities.isEmpty()) {
+			// Ensure there are not duplicate entries in the list
+			boolean dup = hasDuplicatesInEntityFields(entities);
+			if (dup) {
+				String msg = EntityWizardMsg.DUPLICATED_ENTITY_NAMES_MESSAGE;				
+				return WTPCommonPlugin.createErrorStatus(msg);
+			}
+			// Ensure that the entries in the list are valid
+			String errorMsg = checkInputElementsTypeValidation(entities);
+			if (errorMsg != null) {
+				return WTPCommonPlugin.createErrorStatus(errorMsg);
+			}
+			String warningMsg = checkInputElementsTypeExistence(entities);
+			if (warningMsg != null) {
+				return WTPCommonPlugin.createWarningStatus(warningMsg);
+			}
+		}
+		return WTPCommonPlugin.OK_STATUS;
+	}
+	
+	private String checkInputElementsTypeValidation(List<EntityRow> inputElements) {
+		IStatus validateFieldTypeStatus = Status.OK_STATUS;
+		for (EntityRow entityRow: inputElements) {
+			if (entityRow.isKey() && !entityRow.couldBeKey()) {
+				String message = MessageFormat.format(
+						EntityWizardMsg.EntityDataModelProvider_invalidPKType, new Object[]{entityRow.getFqnTypeName()});
+				validateFieldTypeStatus = new Status(IStatus.ERROR,
+						JptUiPlugin.PLUGIN_ID, message);
+				break;				
+			}			
+			String sig = null;
+			try {
+				sig = Signature.createTypeSignature(entityRow.getFqnTypeName(), true);
+			} catch (IllegalArgumentException e) {
+				String message = MessageFormat.format(EntityWizardMsg.EntityDataModelProvider_invalidArgument, new Object[]{e.getLocalizedMessage()});
+				validateFieldTypeStatus = new Status(IStatus.ERROR, JptUiPlugin.PLUGIN_ID, message);
+				break;
+			}
+			if (sig == null){
+				validateFieldTypeStatus = JavaConventions.validateJavaTypeName(entityRow.getType(), JavaCore.VERSION_1_5, JavaCore.VERSION_1_5);
+				break;
+			}
+			int sigType = Signature.getTypeSignatureKind(sig);
+			if (sigType == Signature.BASE_TYPE_SIGNATURE) {
+				continue;
+			}
+			else if (sigType == Signature.ARRAY_TYPE_SIGNATURE) {
+				String elementSignature = Signature.getElementType(sig);
+				if (Signature.getTypeSignatureKind(elementSignature) == Signature.BASE_TYPE_SIGNATURE) {
+					continue;
+				}
+			}
+		}
+		if (!validateFieldTypeStatus.isOK()) {
+			return validateFieldTypeStatus.getMessage();
+		}
+		return null;
+	}
+	
+	private String checkInputElementsTypeExistence(List<EntityRow> inputElements) {
+		IStatus validateFieldTypeStatus=Status.OK_STATUS;
+		for (EntityRow entityRow: inputElements) {
+			String sig = Signature.createTypeSignature(entityRow.getFqnTypeName() ,true);
+			if (sig == null) {
+				String message = MessageFormat.format(
+						EntityWizardMsg.EntityDataModelProvider_typeNotInProjectClasspath, new Object[]{entityRow.getFqnTypeName()});
+				validateFieldTypeStatus = new Status(IStatus.ERROR,
+						JptUiPlugin.PLUGIN_ID, message);
+				break;
+			}
+			int sigType = Signature.getTypeSignatureKind(sig);
+			if (sigType == Signature.BASE_TYPE_SIGNATURE){
+				continue;
+			}
+			else if (sigType == Signature.ARRAY_TYPE_SIGNATURE) {
+				String elementSignature = Signature.getElementType(sig);
+				if(Signature.getTypeSignatureKind(elementSignature) == Signature.BASE_TYPE_SIGNATURE){
+					continue;
+				}
+				String qualifiedName = Signature.toString(elementSignature);
+				IProject project = (IProject) getProperty(INewJavaClassDataModelProperties.PROJECT);
+				IJavaProject javaProject = JavaCore.create(project);
+				IType type = null;
+				try {
+					type = javaProject.findType(qualifiedName);
+				} catch (JavaModelException e) {
+					validateFieldTypeStatus = e.getStatus();
+					break;
+				}
+				if (type == null) {
+					String message = MessageFormat.format(
+							EntityWizardMsg.EntityDataModelProvider_typeNotInProjectClasspath, new Object[]{entityRow.getFqnTypeName()});
+					validateFieldTypeStatus = new Status(IStatus.ERROR,
+							JptUiPlugin.PLUGIN_ID, message);
+					break;
+				}
+			}
+			else {
+				IProject project = (IProject) getProperty(INewJavaClassDataModelProperties.PROJECT);
+				IJavaProject javaProject = JavaCore.create(project);
+				IType type = null;
+				try {
+					type = javaProject.findType(entityRow.getFqnTypeName());
+				} catch (JavaModelException e) {
+					validateFieldTypeStatus = e.getStatus();
+					break;
+				}
+				if (type == null) {
+					String message = MessageFormat.format(
+							EntityWizardMsg.EntityDataModelProvider_typeNotInProjectClasspath, new Object[]{entityRow.getFqnTypeName()});
+					validateFieldTypeStatus = new Status(IStatus.ERROR,
+							JptUiPlugin.PLUGIN_ID, message);
+					break;
+				}
+			}
+		}
+		if(!validateFieldTypeStatus.isOK()) {
+			return validateFieldTypeStatus.getMessage();
+		}
+		return null;
+	}
+			
+			
+	
+	/**
+	 * This method is intended for internal use only. It provides a simple algorithm for detecting
+	 * if there are duplicate entries in a list. It will accept a null parameter. It will return
+	 * boolean.
+	 * 
+	 * @param input
+	 * @return boolean are there duplications in the list
+	 */
+	private boolean hasDuplicatesInEntityFields(ArrayList<EntityRow> input) {
+		if (input == null) {
+			return false;
+		}
+		int n = input.size();
+		// nested for loops to check each element to see if other elements are the same
+		for (int i = 0; i < n; i++) {
+			EntityRow entity = input.get(i);
+			for (int j = i + 1; j < n; j++) {
+				EntityRow intEntity = input.get(j);
+				if (intEntity.getName().equals(entity.getName())) {
+					return true;
+				}
+			}
+		}		
+		return false;
+	}		
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/entity/data/model/EntityRow.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/entity/data/model/EntityRow.java
new file mode 100644
index 0000000..d6ad5ce
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/entity/data/model/EntityRow.java
@@ -0,0 +1,206 @@
+/***********************************************************************
+ * Copyright (c) 2008, 2009 by SAP AG, Walldorf. 
+ * 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:
+ *     SAP AG - initial API and implementation
+ *     Dimiter Dimitrov, d.dimitrov@sap.com - initial API and implementation
+ ***********************************************************************/
+package org.eclipse.jpt.ui.internal.wizards.entity.data.model;
+
+import java.util.Arrays;
+import java.util.List;
+
+public class EntityRow {
+
+	private static final String DOT = ".";
+	private static final char BRACKET_SQUARE = '[';
+	private static final char BRACKET_ANGULAR = '<';
+	private static final String PACKAGE_JAVA_LANG = "java.lang.";
+	private boolean key = false;
+	private String name = "";
+	private String type = "";
+	private String fqnTypeName = "";
+
+	private final static String[] PK_TYPES = {"int", "long", "short", "char", "boolean", "byte", "double", "float", 
+		"java.lang.String", "java.sql.Date", "java.util.Date", "java.lang.Integer", "java.lang.Long", "java.lang.Short",
+		"java.lang.Character", "java.lang.Boolean", "java.lang.Byte", "java.lang.Double", "java.lang.Float"};
+	
+	private final static String[] PK_TYPES_SHORT = { "String", "Integer", "Long", "Short", "Character", "Boolean", 
+		 "Byte", "Double", "Float" };
+
+	private final static List<String> VALID_PK_TYPES = Arrays.asList(PK_TYPES);
+	private final static List<String> VALID_PK_TYPES_SHORT = Arrays.asList(PK_TYPES_SHORT);
+	
+	/**
+	 * @return whether the presented entity field is primary key or part of composite primary key
+	 */
+	public boolean isKey() {
+		return key;
+	}
+
+	/**
+	 * Sets the presented entity field to be primary key (or part of composite primari key)
+	 * 
+	 * @param key 
+	 */
+	public void setKey(boolean key) {
+		this.key = key;
+	}
+		
+	/**
+	 * Check whether the type of the entity is allowed to be primary key.
+	 * The limitation in the current implementation is that Embedded PK are not checked
+	 * @return whether the type of field could be used as primary key
+	 */
+	public boolean couldBeKey() {
+		boolean result = false;
+		result = VALID_PK_TYPES.contains(getFqnTypeName());		
+		return result;
+	}
+
+	/**
+	 * @return the name of the entity field
+	 */
+	public String getName() {
+		return name;
+	}
+
+	/**
+	 * Sets the name of the presented entity field
+	 * @param name
+	 */
+	public void setName(String name) {
+		this.name = name;
+	}
+
+	/**
+	 * @return the type (as a simple name) of the entity field
+	 */
+	public String getType() {
+		return type;
+	}
+
+	/**
+	 * Sets the type (as a simple name) of the entity field
+	 * 
+	 * @param type
+	 */
+	public void setType(String type) {
+		this.type = type;
+	}
+
+	/**
+	 * @return the type (as fully qualified name) of the entity field
+	 */
+	public String getFqnTypeName() {
+		return fqnTypeName;
+	}
+	
+	private String removeSpaces(String str) {
+		str = str.trim();
+		StringBuffer sb = new StringBuffer();
+		for (int i = 0; i < str.length(); i++) {
+			char c = str.charAt(i);
+			if (!Character.isWhitespace(c)) 
+				sb.append(c);
+		}
+		return sb.toString();
+	}
+	
+	private String getBasicFQN(String fqn) {
+		String res;
+		int bsIndex = fqn.indexOf(BRACKET_SQUARE);
+		int baIndex = fqn.indexOf(BRACKET_ANGULAR);
+		if (bsIndex == -1) {
+			if (baIndex == -1) res = fqn;
+			else res = fqn.substring(0, baIndex);
+		} else {
+			if (baIndex == -1) res = fqn.substring(0, bsIndex);
+			else res = fqn.substring(0, Math.max(bsIndex, baIndex));
+		}
+		return res;
+	}
+
+	/**
+	 * Sets the fully qualified type name of the entity field
+	 * 
+	 * @param fqnTypeName
+	 */
+	public void setFqnTypeName(String fqnTypeName) {
+		fqnTypeName = removeSpaces(fqnTypeName);
+		String fqnBasicTypeName = getBasicFQN(fqnTypeName);
+		if (fqnBasicTypeName.indexOf(DOT) == -1) {
+			if (VALID_PK_TYPES_SHORT.contains(fqnBasicTypeName)) {
+				this.fqnTypeName = PACKAGE_JAVA_LANG + fqnTypeName;
+				setType(fqnTypeName);
+			} else {
+				this.fqnTypeName = fqnTypeName;
+				setType(fqnTypeName);
+			}			
+		} else {
+			this.fqnTypeName = fqnTypeName;
+			setType(getSimpleName(fqnTypeName));
+		}		
+	}
+
+	/**
+	 * @return whether the type of the entity field is boolean. The information could be used 
+	 * when the name of getter should be constructed
+	 */
+	public boolean isBoolean() {
+		return "boolean".equals(getType());
+	}
+	
+	/**
+	 * For internal purpose only
+	 * Convert fully qualified name to the simple one
+	 * @param fullyName
+	 * @return the simple name form the fully qualified name parameter(last segment)
+	 */
+	private String getSimpleName(String fullyName) {
+		return fullyName.substring(fullyName.lastIndexOf(DOT) + 1);
+	}
+
+	@Override
+	public int hashCode() {
+		final int prime = 31;
+		int result = 1;
+		result = prime * result
+				+ ((fqnTypeName == null) ? 0 : fqnTypeName.hashCode());
+		result = prime * result + ((name == null) ? 0 : name.hashCode());
+		return result;
+	}
+
+	/*
+	 * Implement equals, depending from name of the entity field and its type.
+	 * The type is presented from the fully qualified name
+	 * @see java.lang.Object#equals(java.lang.Object)
+	 */
+	@Override
+	public boolean equals(Object obj) {
+		if (this == obj)
+			return true;
+		if (obj == null)
+			return false;
+		if (getClass() != obj.getClass())
+			return false;
+		final EntityRow other = (EntityRow) obj;
+		if (fqnTypeName == null) {
+			if (other.fqnTypeName != null)
+				return false;
+		} else if (!fqnTypeName.equals(other.fqnTypeName))
+			return false;
+		if (name == null) {
+			if (other.name != null)
+				return false;
+		} else if (!name.equals(other.name))
+			return false;
+		return true;
+	}
+	
+	
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/entity/data/model/IEntityDataModelProperties.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/entity/data/model/IEntityDataModelProperties.java
new file mode 100644
index 0000000..9a03daa
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/entity/data/model/IEntityDataModelProperties.java
@@ -0,0 +1,33 @@
+/***********************************************************************
+ * Copyright (c) 2008 by SAP AG, Walldorf. 
+ * 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:
+ *     SAP AG - initial API and implementation
+ *     Dimiter Dimitrov, d.dimitrov@sap.com - initial API and implementation     
+ ***********************************************************************/
+package org.eclipse.jpt.ui.internal.wizards.entity.data.model;
+
+import org.eclipse.jst.j2ee.application.internal.operations.IAnnotationsDataModel;
+import org.eclipse.jst.j2ee.internal.common.operations.INewJavaClassDataModelProperties;
+
+public interface IEntityDataModelProperties extends INewJavaClassDataModelProperties, IAnnotationsDataModel {
+	
+	public static final String ENTITY = "IEntityDataModelProperties.ENTITY"; //$NON-NLS-1$
+	public static final String MAPPED_AS_SUPERCLASS = "IEntityDataModelProperties.MAPPED_AS_SUPERCLASS"; //$NON-NLS-1$
+	public static final String INHERITANCE = "IEntityDataModelProperties.INHERITANCE"; //$NON-NLS-1$
+	public static final String INHERITANCE_STRATEGY = "IEntityDataModelProperties.INHERITANCE_STRATEGY"; //$NON-NLS-1$
+	public static final String XML_SUPPORT = "IEntityDataModelProperties.XML_SUPPORT"; //$NON-NLS-1$XML_SUPPORT	
+	public static final String XML_NAME = "IEntityDataModelProperties.XML_NAME"; //$NON-NLS-1$XML_SUPPORT
+	public static final String ENTITY_NAME = "IEntityDataModelProperties.ENTITY_NAME"; //$NON-NLS-1$
+	public static final String TABLE_NAME_DEFAULT = "IEntityDataModelProperties.TABLE_NAME_DEFAULT"; //$NON-NLS-1$
+	public static final String TABLE_NAME = "IEntityDataModelProperties.TABLE_NAME"; //$NON-NLS-1$
+	public static final String ENTITY_FIELDS = "IEntityDataModelProperties.ENTITY_FIELDS"; //$NON-NLS-1$	
+	public static final String PK_FIELDS = "IEntityDataModelProperties.PK_FIELDS"; //$NON-NLS-1$
+	public static final String FIELD_ACCESS_TYPE = "IEntityDataModelProperties.FIELD_ACCESS_TYPE"; //$NON-NLS-1$
+	public static final String PROPERTY_ACCESS_TYPE = "IEntityDataModelProperties.PROPERTY_ACCESS_TYPE"; //$NON-NLS-1$
+	public static final String EMPTY_STRING = ""; //$NON-NLS-1$	
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/entity/data/operation/NewEntityClassOperation.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/entity/data/operation/NewEntityClassOperation.java
new file mode 100644
index 0000000..904ea25
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/entity/data/operation/NewEntityClassOperation.java
@@ -0,0 +1,535 @@
+/***********************************************************************
+ * Copyright (c) 2008, 2010 by SAP AG, Walldorf. 
+ * 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:
+ *     SAP AG - initial API and implementation
+ *     Dimiter Dimitrov, d.dimitrov@sap.com - initial API and implementation
+ ***********************************************************************/
+package org.eclipse.jpt.ui.internal.wizards.entity.data.operation;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.net.URL;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IWorkspaceRoot;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.FileLocator;
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.Preferences;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.jobs.Job;
+import org.eclipse.emf.codegen.jet.JETEmitter;
+import org.eclipse.emf.codegen.jet.JETException;
+import org.eclipse.emf.common.util.EList;
+import org.eclipse.jdt.core.ICompilationUnit;
+import org.eclipse.jdt.core.IJavaModelMarker;
+import org.eclipse.jdt.core.IPackageFragment;
+import org.eclipse.jdt.core.IPackageFragmentRoot;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jem.util.emf.workbench.ProjectUtilities;
+import org.eclipse.jpt.core.JpaProject;
+import org.eclipse.jpt.core.JptCorePlugin;
+import org.eclipse.jpt.core.MappingKeys;
+import org.eclipse.jpt.core.context.AccessType;
+import org.eclipse.jpt.core.context.Entity;
+import org.eclipse.jpt.core.context.InheritanceType;
+import org.eclipse.jpt.core.context.MappedSuperclass;
+import org.eclipse.jpt.core.context.orm.EntityMappings;
+import org.eclipse.jpt.core.context.orm.OrmPersistentType;
+import org.eclipse.jpt.core.resource.orm.OrmFactory;
+import org.eclipse.jpt.core.resource.persistence.PersistenceFactory;
+import org.eclipse.jpt.core.resource.persistence.XmlJavaClassRef;
+import org.eclipse.jpt.core.resource.persistence.XmlPersistence;
+import org.eclipse.jpt.core.resource.persistence.XmlPersistenceUnit;
+import org.eclipse.jpt.core.resource.xml.JpaXmlResource;
+import org.eclipse.jpt.ui.JptUiPlugin;
+import org.eclipse.jpt.ui.internal.wizards.entity.AnnotatedEntityTemplate;
+import org.eclipse.jpt.ui.internal.wizards.entity.EntityTemplate;
+import org.eclipse.jpt.ui.internal.wizards.entity.EntityWizardMsg;
+import org.eclipse.jpt.ui.internal.wizards.entity.IdClassTemplate;
+import org.eclipse.jpt.ui.internal.wizards.entity.data.model.CreateEntityTemplateModel;
+import org.eclipse.jst.common.internal.annotations.controller.AnnotationsController;
+import org.eclipse.jst.common.internal.annotations.controller.AnnotationsControllerManager;
+import org.eclipse.jst.j2ee.internal.common.operations.INewJavaClassDataModelProperties;
+import org.eclipse.jst.j2ee.internal.plugin.J2EEPlugin;
+import org.eclipse.jst.j2ee.internal.project.WTPJETEmitter;
+import org.eclipse.wst.common.componentcore.internal.operation.ArtifactEditProviderOperation;
+import org.eclipse.wst.common.componentcore.internal.operation.IArtifactEditOperationDataModelProperties;
+import org.eclipse.wst.common.frameworks.datamodel.AbstractDataModelOperation;
+import org.eclipse.wst.common.frameworks.datamodel.IDataModel;
+import org.eclipse.wst.common.frameworks.internal.enablement.nonui.WFTWrappedException;
+import org.eclipse.wst.common.frameworks.internal.plugin.WTPCommonPlugin;
+
+/**
+ * The NewEntityClassOperation is IDataModelOperation following the
+ * IDataModel wizard and operation framework.
+ * 
+ * @see org.eclipse.wst.common.frameworks.datamodel.IDataModelOperation
+ * @see org.eclipse.wst.common.frameworks.datamodel.IDataModelProvider
+ * 
+ * This operation is used to generate java classes for the new JPA entity. It uses 
+ * EntityDataModelProvider to store the appropriate properties required to generate the new entity. 
+ * @see org.eclipse.jpt.ui.internal.wizards.entity.data.modelEntityDataModelProvider
+ * 
+ * A WTPJetEmitter entity template is used to create the class with the entity template. 
+ * @see org.eclipse.jst.j2ee.internal.project.WTPJETEmitter
+ * @see org.eclipse.jpt.ui.internal.wizards.entity.data.model.CreateEntityTemplateModel
+ * 
+ * The use of this class is EXPERIMENTAL and is subject to substantial changes.
+ */
+public class NewEntityClassOperation extends AbstractDataModelOperation {
+
+	private static final String DOT_JAVA = ".java"; //$NON-NLS-1$
+	private static final String SEPARATOR = "/";//$NON-NLS-1$
+	private static final String VERSION_STRING = "1.0";//$NON-NLS-1$
+	private static final String FIELD = "FIELD";//$NON-NLS-1$
+	private static final String PROPERTY = "PROPERTY";//$NON-NLS-1$	
+	protected static final String WTP_CUSTOMIZATION_PLUGIN = "WTP_CUSTOMIZATION_PLUGIN"; //$NON-NLS-1$
+	protected static final String ANNOTATED_ENTITY_TEMPLATE_FILE = "/templates/annotated_entity.javajet"; //$NON-NLS-1$	
+	protected static final String ENTITY_TEMPLATE_FILE = "/templates/entity.javajet"; //$NON-NLS-1$
+	protected static final String IDCLASS_TEMPLATE_FILE = "/templates/idClass.javajet"; //$NON-NLS-1$	
+	protected static final String BUILDER_ID = "builderId"; //$NON-NLS-1$
+	private static final String EMPTY_STRING = "";//$NON-NLS-1$
+	private static final String SINGLE_TABLE = "SINGLE_TABLE";//$NON-NLS-1$
+	
+	/**
+	 * Method name of template implementation classes. 
+	 */
+	protected static final String GENERATE_METHOD = "generate"; //$NON-NLS-1$
+
+	/**
+	 * This is the constructor which should be used when creating a NewEntityClassOperation. 
+	 * An instance of the CreateEntityTemplateModel should be passed in. This does not accept
+	 * null parameter. It will not return null.
+	 * 
+	 * @see ArtifactEditProviderOperation#ArtifactEditProviderOperation(IDataModel)
+	 * @see CreateEntityTemplateModel
+	 * 
+	 * @param dataModel
+	 * @return NewFilterClassOperation
+	 */
+	public NewEntityClassOperation(IDataModel dataModel) {
+		super(dataModel);
+	}
+
+	/**
+	 * The implementation of the execute method drives the running of the operation. 
+	 * This implementation will create the java source folder, create the java package, and then 
+	 * the entity (or mapped as superclass) and ID class files will be created using templates. 
+	 * 
+	 * @see org.eclipse.wst.common.frameworks.internal.operation.WTPOperation#execute(org.eclipse.core.runtime.IProgressMonitor)
+	 * @see NewEntityClassOperation#generateUsingTemplates(IProgressMonitor,
+	 *      IPackageFragment)
+	 * 
+	 * @param monitor
+	 * @throws CoreException
+	 * @throws InterruptedException
+	 * @throws InvocationTargetException
+	 */
+	public IStatus doExecute(IProgressMonitor monitor, IAdaptable info) throws ExecutionException {
+		// Create source folder if it does not exist
+		createJavaSourceFolder();
+		// Create java package if it does not exist
+		IPackageFragment pack = createJavaPackage();
+		// Generate filter class using templates
+		try {
+			generateUsingTemplates(monitor, pack);
+		} catch (Exception e) {
+			return WTPCommonPlugin.createErrorStatus(e.toString());
+		}
+		return OK_STATUS;
+	}
+
+	/**
+	 * This method will return the java package as specified by the new java
+	 * class data model. If the package does not exist, it will create the
+	 * package. This method should not return null.
+	 * 
+	 * @see INewJavaClassDataModelProperties#JAVA_PACKAGE
+	 * @see IPackageFragmentRoot#createPackageFragment(java.lang.String,
+	 *      boolean, org.eclipse.core.runtime.IProgressMonitor)
+	 * 
+	 * @return IPackageFragment the java package
+	 */
+	protected final IPackageFragment createJavaPackage() {
+		// Retrieve the package name from the java class data model
+		String packageName = model.getStringProperty(INewJavaClassDataModelProperties.JAVA_PACKAGE);
+		IPackageFragmentRoot packRoot = (IPackageFragmentRoot) model
+				.getProperty(INewJavaClassDataModelProperties.JAVA_PACKAGE_FRAGMENT_ROOT);
+		IPackageFragment pack = packRoot.getPackageFragment(packageName);
+		// Handle default package
+		if (pack == null) {
+			pack = packRoot.getPackageFragment(""); //$NON-NLS-1$
+		}		
+		
+		// Create the package fragment if it does not exist
+		if (!pack.exists()) {
+			String packName = pack.getElementName();
+			try {
+				pack = packRoot.createPackageFragment(packName, true, null);
+			} catch (JavaModelException e) {
+				JptUiPlugin.log(e);
+			}
+		}
+		// Return the package
+		return pack;
+	}
+
+	/**
+	 * This implementation uses the creation of a CreateEntityTemplateModel and the WTPJETEmitter
+	 * to create the java class with the annotated tags. This method accepts null for monitor, it does not accept null 
+	 * for fragment. If annotations are not being used the tags will be omitted from the class.
+	 * 
+	 * @see CreateEntityTemplateModel
+	 * @see NewEntityClassOperation#generateTemplateSource(CreateEntityTemplateModel,
+	 *      IProgressMonitor)
+	 * 
+	 * @param monitor
+	 * @param fragment
+	 * @throws CoreException
+	 * @throws WFTWrappedException
+	 */
+	protected void generateUsingTemplates(IProgressMonitor monitor, IPackageFragment fragment) throws WFTWrappedException, CoreException {
+	    // Create the entity template model
+	    CreateEntityTemplateModel tempModel = createTemplateModel();
+        IProject project = getTargetProject();
+        String entityClassSource = null;
+        String idClassSource = null;
+        // Generate the java source based on the entity template models
+        try {
+        	if (tempModel.isArtifactsAnnotated()) {
+        		AnnotatedEntityTemplate tempImpl = AnnotatedEntityTemplate.create(null);
+        		entityClassSource = generateTemplateSource(tempModel, ANNOTATED_ENTITY_TEMPLATE_FILE, tempImpl, monitor);
+        	} else {
+        		EntityTemplate tempImpl = EntityTemplate.create(null);
+        		entityClassSource = generateTemplateSource(tempModel, ENTITY_TEMPLATE_FILE, tempImpl, monitor);
+        	}
+            if (tempModel.isCompositePK()) {
+            	IdClassTemplate tempImpl = IdClassTemplate.create(null);
+            	idClassSource = generateTemplateSource(tempModel, IDCLASS_TEMPLATE_FILE, tempImpl, monitor);
+            }
+        } catch (Exception e) {
+            throw new WFTWrappedException(e);
+        }
+        if (fragment != null) {
+            // Create the java file
+            String javaFileName = tempModel.getClassName() + DOT_JAVA;
+            ICompilationUnit cu = fragment.getCompilationUnit(javaFileName);
+            // Add the compilation unit to the java file
+            if (cu == null || !cu.exists()) {
+                cu = fragment.createCompilationUnit(javaFileName, entityClassSource, true, monitor);
+            }
+            IFile aFile = (IFile) cu.getResource();
+            // Let the annotations controller process the annotated resource
+            if (tempModel.isArtifactsAnnotated()) {
+            	AnnotationsController controller = AnnotationsControllerManager.INSTANCE.getAnnotationsController(project);
+            	if (controller != null) {
+            		controller.process(aFile);
+            	}
+            }
+            //Create IdClass if the primary key is complex
+            if (idClassSource != null) {
+                String entityPKName = tempModel.getIdClassName() + DOT_JAVA;
+                ICompilationUnit cu1 = fragment.getCompilationUnit(entityPKName);
+                // Add the compilation unit to the java file
+                if (cu1 == null || !cu1.exists()) {
+                    cu1 = fragment.createCompilationUnit(entityPKName, idClassSource, true, monitor);
+                }           	
+            }            
+        }
+                       
+        if (!tempModel.isArtifactsAnnotated()) {
+        	if (tempModel.isNonEntitySuperclass()) { 
+        		addMappedSuperclassToXML(tempModel, project).schedule();
+        	} else {
+        		addEntityToXML(tempModel, project).schedule();
+        	}
+        }
+        if (tempModel.isArtifactsAnnotated() && !JptCorePlugin.discoverAnnotatedClasses(project)) {
+        	registerClassInPersistenceXml(tempModel, project).schedule();
+        }
+	}
+
+	/**
+     * This method is intended for internal use only. This method will create an
+     * instance of the CreateEntityTemplateModel model to be used in conjunction
+     * with the WTPJETEmitter. This method will not return null.
+     * 
+     * @see CreateEntityTemplateModel
+     * @see NewEntityClassOperation#generateUsingTemplates(IProgressMonitor,
+     *      IPackageFragment)
+     * 
+     * @return CreateFilterTemplateModel
+     */
+    private CreateEntityTemplateModel createTemplateModel() {
+        CreateEntityTemplateModel templateModel = new CreateEntityTemplateModel(model);
+        return templateModel;
+    }
+    
+    /**
+     * This method is intended for internal use only. This will use the
+     * WTPJETEmitter to create an annotated java file based on the passed template model. 
+     * This method does not accept null parameters. It will not return null. 
+     * If annotations are not used, it will use the non annotated template to omit the annotated tags.
+     * 
+     * @see NewEntityClassOperation#generateUsingTemplates(IProgressMonitor,
+     *      IPackageFragment)
+     * @see JETEmitter#generate(org.eclipse.core.runtime.IProgressMonitor,
+     *      java.lang.Object[])
+     * @see CreateEntityTemplateModel
+     * 
+     * @param templateModel
+     * @param monitor
+     * @param template_file 
+     * @return String the source for the java file
+     * @throws JETException
+     * @throws NoSuchMethodException 
+     * @throws SecurityException 
+     * @throws InvocationTargetException 
+     * @throws IllegalAccessException  
+     */
+    private String generateTemplateSource(CreateEntityTemplateModel templateModel, String templateFile, Object templateImpl, IProgressMonitor monitor) 
+    		throws JETException, SecurityException, NoSuchMethodException, IllegalAccessException, InvocationTargetException {
+    	Preferences preferences = J2EEPlugin.getDefault().getPluginPreferences();
+		boolean dynamicTranslation = preferences.getBoolean(J2EEPlugin.DYNAMIC_TRANSLATION_OF_JET_TEMPLATES_PREF_KEY);
+		if (dynamicTranslation) {
+	        URL templateURL = FileLocator.find(JptUiPlugin.instance().getBundle(), new Path(templateFile), null);
+	        cleanUpOldEmitterProject();
+	        WTPJETEmitter emitter = new WTPJETEmitter(templateURL.toString(), this.getClass().getClassLoader());
+	        emitter.setIntelligentLinkingEnabled(true);
+	        emitter.addVariable(WTP_CUSTOMIZATION_PLUGIN, JptUiPlugin.PLUGIN_ID);
+	        return emitter.generate(monitor, new Object[] { templateModel });
+		} else {
+			Method method = templateImpl.getClass().getMethod(GENERATE_METHOD, new Class[] { Object.class });
+			return (String) method.invoke(templateImpl, templateModel);
+		}
+    }
+    
+	/**
+	 * This method is intended for internal use only. It will clean up the old emmiter project 
+	 * in order to prevent generation issues 
+	 */
+	private void cleanUpOldEmitterProject() {
+		IProject project = ProjectUtilities.getProject(WTPJETEmitter.PROJECT_NAME);
+		if (project == null || !project.exists())
+			return;
+		try {
+			IMarker[] markers = project.findMarkers(IJavaModelMarker.BUILDPATH_PROBLEM_MARKER, false, IResource.DEPTH_ZERO);
+			for (int i = 0, l = markers.length; i < l; i++) {
+				if (((Integer) markers[i].getAttribute(IMarker.SEVERITY)).intValue() == IMarker.SEVERITY_ERROR) {
+					project.delete(true, new NullProgressMonitor());
+					break;
+				}
+			}
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
+	}
+
+	/**
+	 * This method will return the java source folder as specified in the java
+	 * class data model. It will create the java source folder if it does not
+	 * exist. This method may return null.
+	 * 
+	 * @see INewJavaClassDataModelProperties#SOURCE_FOLDER
+	 * @see IFolder#create(boolean, boolean,
+	 *      org.eclipse.core.runtime.IProgressMonitor)
+	 * 
+	 * @return IFolder the java source folder
+	 */
+	protected final IFolder createJavaSourceFolder() {
+		// Get the source folder name from the data model
+		String folderFullPath = model.getStringProperty(INewJavaClassDataModelProperties.SOURCE_FOLDER);
+		IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
+		IFolder folder = root.getFolder(new Path(folderFullPath));
+		// If folder does not exist, create the folder with the specified path
+		if (!folder.exists()) {
+			try {
+				folder.create(true, true, null);
+			} catch (CoreException e) {
+				JptUiPlugin.log(e);
+			}
+		}
+		// Return the source folder
+		return folder;
+	}
+
+	@Override
+	public IStatus execute(IProgressMonitor monitor, IAdaptable info)
+			throws ExecutionException {
+		return doExecute(monitor, info);
+	}
+	
+	public IProject getTargetProject() {
+		String projectName = model.getStringProperty(IArtifactEditOperationDataModelProperties.PROJECT_NAME);
+		return ProjectUtilities.getProject(projectName);
+	}	
+		
+	/**
+	 * Adds entity to ORM XML in separate job
+	 * @param model entity data model
+	 * @param project JPA project in which the entity will be created
+	 * @return
+	 */
+	private Job addEntityToXML(final CreateEntityTemplateModel model, final IProject project) {
+		Job job = new Job(EntityWizardMsg.ADD_ENTITY_TO_XML) {
+			@Override
+			protected IStatus run(IProgressMonitor monitor) {
+				final JpaXmlResource xmlResource = getOrmXmlResource(model, project);
+				EntityMappings entityMappings = (EntityMappings) JptCorePlugin.getJpaProject(project).getJpaFile(xmlResource.getFile()).rootStructureNodes().next();
+				OrmPersistentType persistentType = entityMappings.addPersistentType(MappingKeys.ENTITY_TYPE_MAPPING_KEY, model.getQualifiedJavaClassName());
+				Entity entity = (Entity) persistentType.getMapping();
+				if (model.isInheritanceSet()) {
+					entity.setSpecifiedInheritanceStrategy(getModelInheritanceType(model));
+				}
+				
+				if (model.isEntityNameSet()) {
+					entity.setSpecifiedName(model.getEntityName());
+				}
+				if (model.isTableNameSet()) {
+					entity.getTable().setSpecifiedName(model.getTableName());
+				}
+				if (model.isCompositePK()) {
+					entity.getIdClassReference().setSpecifiedIdClassName(model.getIdClassName());
+				}
+				for (String fieldName : model.getPKFields()) {
+					persistentType.addSpecifiedAttribute(MappingKeys.ID_ATTRIBUTE_MAPPING_KEY, fieldName);
+				}
+
+				persistentType.setSpecifiedAccess(getModelAccessType(model));
+				
+				try {
+					xmlResource.saveIfNecessary();
+				}
+				catch (Exception e) {
+					JptUiPlugin.log(e);
+				}
+				return Status.OK_STATUS;
+			}
+		};
+		return job;
+	}
+
+	protected JpaXmlResource getOrmXmlResource(CreateEntityTemplateModel model, IProject project) {
+		if (model.isMappingXMLDefault()) {
+			return JptCorePlugin.getJpaProject(project).getDefaultOrmXmlResource();
+		}
+		return JptCorePlugin.getJpaProject(project).getMappingFileXmlResource(model.getMappingXMLName());
+	}
+	
+	/**
+	 * Adds mapped superclass to ORM XML in separate job
+	 * 
+	 * @param model entity data model
+	 * @param project JPA project in which the entity will be created
+	 * @return the created job
+	 */
+	private Job addMappedSuperclassToXML(final CreateEntityTemplateModel model, final IProject project) {
+		Job job = new Job(EntityWizardMsg.ADD_MAPPED_SUPERCLASS_TO_XML) {
+			@Override
+			protected IStatus run(IProgressMonitor monitor) {
+				final JpaXmlResource xmlResource = getOrmXmlResource(model, project);
+				EntityMappings entityMappings = (EntityMappings) JptCorePlugin.getJpaProject(project).getJpaFile(xmlResource.getFile()).rootStructureNodes().next();
+				OrmPersistentType persistentType = entityMappings.addPersistentType(MappingKeys.MAPPED_SUPERCLASS_TYPE_MAPPING_KEY, model.getQualifiedJavaClassName());
+				MappedSuperclass mappedSuperclass = (MappedSuperclass) persistentType.getMapping();
+				
+				if (model.isCompositePK()) {
+					mappedSuperclass.getIdClassReference().setSpecifiedIdClassName(model.getIdClassName());
+				}
+				
+				for (String fieldName : model.getPKFields()) {
+					persistentType.addSpecifiedAttribute(MappingKeys.ID_ATTRIBUTE_MAPPING_KEY, fieldName);
+				}
+
+				persistentType.setSpecifiedAccess(getModelAccessType(model));
+				
+				try {
+					xmlResource.saveIfNecessary();
+				}
+				catch (Exception e) {
+					JptUiPlugin.log(e);
+				}
+				return Status.OK_STATUS;
+			}
+		};
+		return job;		
+	}
+	
+	protected AccessType getModelAccessType(CreateEntityTemplateModel model) {
+		String accessTypeString = FIELD;
+		if (!model.isFieldAccess()) {
+			accessTypeString = PROPERTY;
+		}
+		return AccessType.fromOrmResourceModel(OrmFactory.eINSTANCE.createAccessTypeFromString(null, accessTypeString));// TODO
+	}
+
+	protected InheritanceType getModelInheritanceType(CreateEntityTemplateModel model) {
+		String inheritanceStrategy = model.getInheritanceStrategyName();
+		if (inheritanceStrategy.equals(EMPTY_STRING)) {
+			inheritanceStrategy = SINGLE_TABLE;
+		}
+		return InheritanceType.fromOrmResourceModel(OrmFactory.eINSTANCE.createInheritanceTypeFromString(null, inheritanceStrategy));//TODO
+	}
+
+	/**
+	 * Regist the class in the persistence.xml
+	 * 
+	 * @param model entity data model
+	 * @param project JPA project in which the entity will be created
+	 * @return the created job
+	 */
+	private Job registerClassInPersistenceXml(final CreateEntityTemplateModel model, final IProject project) {
+		Job job = new Job(EntityWizardMsg.APPLY_CHANGES_TO_PERSISTENCE_XML) {
+			@Override
+			protected IStatus run(IProgressMonitor monitor) {
+				final JpaProject jpaProject = JptCorePlugin.getJpaProject(project);
+				final JpaXmlResource resource = jpaProject.getPersistenceXmlResource();
+				resource.modify(new Runnable() {
+						public void run() {
+							XmlPersistence xmlPersistence = (XmlPersistence) resource.getRootObject();
+							EList<XmlPersistenceUnit> persistenceUnits = xmlPersistence.getPersistenceUnits();
+							XmlPersistenceUnit persistenceUnit = persistenceUnits.get(0);// Multiply persistence unit support
+							
+							if (!model.isNonEntitySuperclass()) {
+								XmlJavaClassRef classRef = PersistenceFactory.eINSTANCE.createXmlJavaClassRef();
+								classRef.setJavaClass(model.getQualifiedJavaClassName());
+								persistenceUnit.getClasses().add(classRef);
+							}
+						}
+					});
+				
+				return Status.OK_STATUS;
+			}
+		};
+		return job;
+
+	}
+	
+	/**
+	 * @param input the name of mapping XML from the class wizard page. It is relative path from the source folder
+	 * and includes META-INF folder
+	 * @return the simple name of the mapping XML
+	 */
+	private String getLastSegment(String input) {
+		String output = input;
+		if (input.indexOf(SEPARATOR) != -1) {
+			output = input.substring(input.lastIndexOf(SEPARATOR) + 1);
+		}
+		return output;
+	}
+	
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/gen/AssociationFigure.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/gen/AssociationFigure.java
new file mode 100644
index 0000000..30518de
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/gen/AssociationFigure.java
@@ -0,0 +1,227 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 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.ui.internal.wizards.gen;
+
+import org.eclipse.draw2d.Button;
+import org.eclipse.draw2d.ChopboxAnchor;
+import org.eclipse.draw2d.ColorConstants;
+import org.eclipse.draw2d.ConnectionEndpointLocator;
+import org.eclipse.draw2d.Graphics;
+import org.eclipse.draw2d.Label;
+import org.eclipse.draw2d.LineBorder;
+import org.eclipse.draw2d.PolygonDecoration;
+import org.eclipse.draw2d.PolylineConnection;
+import org.eclipse.draw2d.XYLayout;
+import org.eclipse.draw2d.geometry.Rectangle;
+import org.eclipse.jface.resource.ResourceManager;
+import org.eclipse.jpt.gen.internal.Association;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Font;
+
+
+class AssociationFigure extends Button {
+	
+	Color enabledColor = new Color( null, 14,66,115);
+	Color disabledLineColor = new Color( null, 192,215,231);
+	Color selectedColor = new Color( null, 232,232,232 );
+
+	Color selectedBorderColor = new Color( null, 14,66,115 );
+	LineBorder selectedBorder = new LineBorder( selectedBorderColor, 2 );
+	LineBorder unselectedBorder = new LineBorder( ColorConstants.lightGray, 1 );
+	Font descriptionFont = new Font(null, "Arial", 8, SWT.NONE);
+	
+	/**
+	 * The model behind the the view object
+	 */
+	Association association;
+	TableFigure tableFig1;
+	TableFigure tableFig2;
+	PolylineConnection connection ;
+	
+	PolygonDecoration referrerDecoration ;	
+	PolygonDecoration referencedDecoration ;
+
+	Label referencedLabel ;
+	Label referrerLabel ;
+	Label descriptionLabel ;
+	
+	AssociationFigure(Association association, ResourceManager resourceManager) {
+		this.association = association;
+		
+		XYLayout contentsLayout = new XYLayout();
+		setLayoutManager(contentsLayout);
+		setBorder( unselectedBorder );
+
+		//Create the figures for referrer table and referenced table
+		tableFig1 = new TableFigure( association.getReferrerTable().getName(), resourceManager); 
+		tableFig2 = new TableFigure( association.getReferencedTable().getName(), resourceManager); 
+		
+		contentsLayout.setConstraint(tableFig1, new Rectangle(10,10,150,20));
+		contentsLayout.setConstraint(tableFig2, new Rectangle(280, 10, 150, 20));
+
+		connection = drawConnection(tableFig1, tableFig2);
+
+		add(tableFig1);
+		add(tableFig2);
+		add(connection);
+		
+
+		descriptionLabel = new Label("");
+		contentsLayout.setConstraint(descriptionLabel, new Rectangle(10,30,-1,-1));
+		descriptionLabel.setFont( descriptionFont ); 
+		add(descriptionLabel);
+
+		//set white background
+		this.setBackgroundColor(ColorConstants.white);
+		
+		update();
+		
+	}
+
+	private PolylineConnection drawConnection(TableFigure tableFig1,
+			TableFigure tableFig2) {
+		/* Creating the connection */
+		PolylineConnection connection = new PolylineConnection();
+		ChopboxAnchor sourceAnchor = new ChopboxAnchor(tableFig1);
+		ChopboxAnchor targetAnchor = new ChopboxAnchor(tableFig2);
+		connection.setSourceAnchor(sourceAnchor);
+		connection.setTargetAnchor(targetAnchor);
+		
+		/* Creating the decoration */
+		referrerDecoration = new SmoothPolygonDecoration();
+		connection.setSourceDecoration(referrerDecoration);
+
+		referencedDecoration = new SmoothPolygonDecoration();
+		connection.setTargetDecoration(referencedDecoration);
+		
+		
+		/* Adding labels to the connection */
+		ConnectionEndpointLocator sourceEndpointLocator = 
+			new ConnectionEndpointLocator(connection, false);
+		sourceEndpointLocator.setVDistance(-5);
+		referrerLabel = new Label("");
+		connection.add(referrerLabel, sourceEndpointLocator);
+
+		ConnectionEndpointLocator targetEndpointLocator = 
+		        new ConnectionEndpointLocator(connection, true);
+		targetEndpointLocator.setVDistance(-5);
+		referencedLabel = new Label("");
+		connection.add(referencedLabel, targetEndpointLocator);
+
+		ConnectionEndpointLocator relationshipLocator = 
+			new ConnectionEndpointLocator(connection,true);
+		relationshipLocator.setUDistance(10);
+		relationshipLocator.setVDistance(-20);
+		Label relationshipLabel = new Label("contains");
+		connection.add(relationshipLabel,relationshipLocator);
+		return connection;
+	}
+
+	public Association getAssociation() {
+		return this.association;
+	} 
+	
+	@Override
+	public void setSelected ( boolean isSelected ){
+		this.setBackgroundColor( isSelected ? selectedColor : ColorConstants.white );
+		this.setBorder(isSelected? selectedBorder : unselectedBorder);
+	}
+	
+	/**
+	 * Update the view with the changes user made on the model
+	 */
+	public void update(){
+		boolean isGenerated = association.isGenerated();
+		
+		connection.setForegroundColor( isGenerated? enabledColor: disabledLineColor );
+		
+		tableFig1.setEnabled(isGenerated);
+		tableFig2.setEnabled(isGenerated);
+		descriptionLabel.setForegroundColor(isGenerated? enabledColor: disabledLineColor);
+
+		//paintDirectionalityAndCardinality 
+		String cardinalityStr;
+		String directionality = association.getDirectionality();
+		String cardinality = association.getCardinality();
+		//Draw referrerRole
+		if (cardinality.equals(Association.MANY_TO_ONE) || cardinality.equals(Association.MANY_TO_MANY)) {
+			cardinalityStr = "*";
+		} else {
+			cardinalityStr = "1";
+		}
+		if (directionality.equals(Association.BI_DI) || directionality.equals(Association.OPPOSITE_DI)) {
+			connection.setSourceDecoration(this.referrerDecoration);
+		}else{
+			connection.setSourceDecoration(null);
+		}
+		
+		this.referrerLabel.setText( cardinalityStr );
+			
+		//Draw referencedRole
+		if (cardinality.equals(Association.MANY_TO_ONE) || cardinality.equals(Association.ONE_TO_ONE)) {
+			cardinalityStr = "1";
+		} else {
+			cardinalityStr = "*";
+		}
+		if (directionality.equals(Association.BI_DI) || directionality.equals(Association.NORMAL_DI)) {
+			connection.setTargetDecoration(this.referencedDecoration);
+		}else{
+			connection.setTargetDecoration(null);
+		}
+		this.referencedLabel.setText(cardinalityStr);
+		
+		String text = "";
+		String referrerTableName = association.getReferrerTableName();
+		String referencedTable = association.getReferencedTableName();
+		if( cardinality.equals(Association.MANY_TO_ONE ) ){
+			text = String.format( JptUiEntityGenMessages.manyToOneDesc, referencedTable , referrerTableName ); 
+		}else if( cardinality.equals(Association.ONE_TO_ONE ) ){
+			text = String.format( JptUiEntityGenMessages.oneToOneDesc, referrerTableName, referencedTable );
+		}else if( cardinality.equals(Association.MANY_TO_MANY) ){
+			text = String.format( JptUiEntityGenMessages.manyToManyDesc, referrerTableName, referencedTable, referencedTable, referrerTableName );			
+		}
+		
+		if( association.isCustom() ){
+			connection.setLineStyle( SWT.LINE_DOT);
+		}
+		
+		this.descriptionLabel.setText(text);
+		
+	}
+
+	public void dispose() {
+		this.descriptionFont.dispose();
+		this.selectedBorderColor.dispose();
+		this.selectedColor.dispose();
+		this.disabledLineColor.dispose();
+		this.enabledColor.dispose();
+		this.tableFig1.dispose();
+		this.tableFig2.dispose();
+	}
+
+	public class SmoothPolygonDecoration extends PolygonDecoration
+	{
+		public SmoothPolygonDecoration()
+		{
+			super();
+		}
+		
+		@Override
+		public void paintFigure(Graphics graphics)
+		{
+			int savedAntialias = graphics.getAntialias();
+			graphics.setAntialias(SWT.ON);
+			super.paintFigure(graphics);
+			graphics.setAntialias(savedAntialias);
+		}
+	}
+} 
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/gen/AssociationTablesPage.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/gen/AssociationTablesPage.java
new file mode 100644
index 0000000..c2af6ae
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/gen/AssociationTablesPage.java
@@ -0,0 +1,194 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 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.ui.internal.wizards.gen;
+
+import static org.eclipse.jpt.ui.internal.wizards.gen.SWTUtil.createButton;
+import static org.eclipse.jpt.ui.internal.wizards.gen.SWTUtil.createLabel;
+import static org.eclipse.jpt.ui.internal.wizards.gen.SWTUtil.createText;
+
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.resource.ResourceManager;
+import org.eclipse.jpt.gen.internal.Association;
+import org.eclipse.jpt.gen.internal.ORMGenCustomizer;
+import org.eclipse.jpt.ui.internal.ImageRepository;
+import org.eclipse.jpt.ui.internal.JpaHelpContextIds;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Group;
+import org.eclipse.swt.widgets.Text;
+
+
+
+public class AssociationTablesPage extends NewAssociationWizardPage {
+
+	private Button simpleAssoBtn;
+	private Button mtmAssoBtn; 
+	private Text table1TextField ;
+	private Text table2TextField ;
+	private Text joinTableTextField; 
+	private Button joinTableBrowse;
+	
+	protected final ResourceManager resourceManager;
+	
+	public AssociationTablesPage(ORMGenCustomizer customizer, ResourceManager resourceManager) {
+		super(customizer,  "AssociationTablesPage");
+		this.resourceManager = resourceManager;
+		setTitle( JptUiEntityGenMessages.GenerateEntitiesWizard_newAssoc_tablesPage_title);
+		setDescription(JptUiEntityGenMessages.GenerateEntitiesWizard_newAssoc_tablesPage_desc);
+	}
+
+	public void createControl(Composite composite) {
+		initializeDialogUnits(composite);
+		Composite parent = new Composite(composite, SWT.NONE);
+		parent.setLayout(new GridLayout(1, true));
+		
+		Group assocKindGroup = new Group(parent, SWT.NULL);
+		int nColumns= 3 ;
+		GridLayout layout = new GridLayout();
+		layout.numColumns = nColumns;
+		assocKindGroup.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+		assocKindGroup.setLayout(layout);
+		this.getHelpSystem().setHelp(composite, JpaHelpContextIds.GENERATE_ENTITIES_WIZARD_ASSOCIATION_TABLES);
+		assocKindGroup.setText( JptUiEntityGenMessages.GenerateEntitiesWizard_newAssoc_tablesPage_assocKind);
+
+		simpleAssoBtn = createButton(assocKindGroup, 3, JptUiEntityGenMessages.GenerateEntitiesWizard_newAssoc_tablesPage_simpleAssoc, SWT.RADIO);
+		mtmAssoBtn = createButton(assocKindGroup, 3, JptUiEntityGenMessages.GenerateEntitiesWizard_newAssoc_tablesPage_m2mAssoc, SWT.RADIO);
+
+		
+		Group assocTablesGroup = new Group(parent, SWT.NULL);
+		nColumns= 3 ;
+		layout = new GridLayout();
+		layout.numColumns = nColumns;
+		assocTablesGroup.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+		assocTablesGroup.setLayout(layout);
+		
+		
+		assocTablesGroup.setText( JptUiEntityGenMessages.GenerateEntitiesWizard_newAssoc_tablesPage_assocTables );
+		
+		createLabel(assocTablesGroup, 1, JptUiEntityGenMessages.GenerateEntitiesWizard_newAssoc_tablesPage_table1);
+		table1TextField = createText(assocTablesGroup, 1);
+		
+		Button browser1 = createButton(assocTablesGroup, 1, "", SWT.NONE);
+		browser1.setImage( ImageRepository.getBrowseButtonImage(this.resourceManager)); 
+
+		browser1.addSelectionListener(new SelectionListener(){
+			public void widgetDefaultSelected(SelectionEvent e) {}
+			public void widgetSelected(SelectionEvent e) {
+				SelectTableDialog dlg = new SelectTableDialog(Display.getDefault().getActiveShell(), resourceManager, customizer.getTableNames());
+				if( dlg.open() ==Dialog.OK ){
+					table1TextField.setText( dlg.getSelectedTable() );
+					getWizardDataModel().put( NewAssociationWizard.ASSOCIATION_REFERRER_TABLE, table1TextField.getText());
+					getWizard().getContainer().updateButtons();
+					((NewAssociationWizard)getWizard()).updateTableNames();
+				}
+			}
+		});
+
+		createLabel(assocTablesGroup, 1, JptUiEntityGenMessages.GenerateEntitiesWizard_newAssoc_tablesPage_table2);
+		table2TextField = createText(assocTablesGroup, 1);
+		
+		Button browser2 = createButton(assocTablesGroup, 1, "", SWT.NONE);
+		browser2.setImage( ImageRepository.getBrowseButtonImage(this.resourceManager)); 
+
+		browser2.addSelectionListener(new SelectionListener(){
+			public void widgetDefaultSelected(SelectionEvent e) {}
+			public void widgetSelected(SelectionEvent e) {
+				SelectTableDialog dlg = new SelectTableDialog( Display.getDefault().getActiveShell(), resourceManager, customizer.getSchema() );
+				if( dlg.open() == Dialog.OK){
+					table2TextField.setText( dlg.getSelectedTable() );
+					getWizardDataModel().put( NewAssociationWizard.ASSOCIATION_REFERENCED_TABLE, table2TextField.getText());
+					((NewAssociationWizard)getWizard()).updateTableNames();
+				}
+				updatePageComplete();
+			}
+		});
+		
+		createLabel(assocTablesGroup, 1, JptUiEntityGenMessages.GenerateEntitiesWizard_newAssoc_tablesPage_intermediateTable );
+		joinTableTextField = createText(assocTablesGroup, 1);
+		joinTableTextField.setEnabled(false);
+
+		joinTableBrowse = createButton(assocTablesGroup, 1, "", SWT.NONE);
+		joinTableBrowse.setImage( ImageRepository.getBrowseButtonImage(this.resourceManager)); 
+		joinTableBrowse.setEnabled(false);
+		
+		joinTableBrowse.addSelectionListener(new SelectionListener(){
+			public void widgetDefaultSelected(SelectionEvent e) {}
+
+			public void widgetSelected(SelectionEvent e) {
+				SelectTableDialog dlg = new SelectTableDialog( Display.getDefault().getActiveShell(), resourceManager, customizer.getSchema() );
+				if( dlg.open() == Dialog.OK){
+					joinTableTextField.setText( dlg.getSelectedTable() );
+					getWizardDataModel().put( NewAssociationWizard.ASSOCIATION_JOIN_TABLE, joinTableTextField.getText() );
+					((NewAssociationWizard)getWizard()).updateTableNames();
+					getWizard().getContainer().updateButtons();
+				}
+				updatePageComplete();
+			}
+		});
+		
+		setControl(parent);
+
+		simpleAssoBtn.addSelectionListener(new SelectionListener(){
+			public void widgetDefaultSelected(SelectionEvent e) {}
+			public void widgetSelected(SelectionEvent e) {
+				joinTableTextField.setEnabled(false);
+				joinTableTextField.clearSelection();
+				joinTableTextField.setText("");
+				joinTableBrowse.setEnabled(false);
+				getWizardDataModel().put( NewAssociationWizard.ASSOCIATION_CADINALITY, Association.MANY_TO_ONE);
+				getWizardDataModel().remove( NewAssociationWizard.ASSOCIATION_JOIN_TABLE );
+				((NewAssociationWizard)getWizard()).updateTableNames();
+				updatePageComplete();
+			}
+			
+		});
+
+		mtmAssoBtn.addSelectionListener(new SelectionListener(){
+			public void widgetDefaultSelected(SelectionEvent e) {}
+			public void widgetSelected(SelectionEvent e) {
+				joinTableTextField.setEnabled(true);
+				joinTableBrowse.setEnabled(true);
+				getWizardDataModel().put( NewAssociationWizard.ASSOCIATION_CADINALITY, Association.MANY_TO_MANY);
+				((NewAssociationWizard)getWizard()).updateTableNames();
+				updatePageComplete();
+			}
+		});		
+		
+		this.setPageComplete( false);
+		table1TextField.setFocus(); 
+	}
+
+	@Override
+	public boolean canFlipToNextPage() {
+		return isPageComplete();
+	}
+	
+	public void updatePageComplete() {
+		if( this.table1TextField.getText().length() <= 0){
+			setPageComplete(false);
+			return;
+		}
+		if( mtmAssoBtn.getSelection() ){
+			if( this.joinTableTextField.getText().length() <= 0 ){
+				setPageComplete(false);
+				return;
+			}
+		}
+		setPageComplete(true);
+	}
+	
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/gen/AssociationsListComposite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/gen/AssociationsListComposite.java
new file mode 100644
index 0000000..5662bf1
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/gen/AssociationsListComposite.java
@@ -0,0 +1,137 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 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.ui.internal.wizards.gen;
+
+import java.util.List;
+
+import org.eclipse.draw2d.ActionEvent;
+import org.eclipse.draw2d.ActionListener;
+import org.eclipse.draw2d.Figure;
+import org.eclipse.draw2d.FigureCanvas;
+import org.eclipse.draw2d.LineBorder;
+import org.eclipse.draw2d.ToolbarLayout;
+import org.eclipse.jface.resource.ResourceManager;
+import org.eclipse.jpt.gen.internal.Association;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+
+/**
+ * A Draw2d figure representing list of associations between two database tables
+ *
+ */
+public class AssociationsListComposite extends FigureCanvas {
+
+	List<Association> associations;  
+	AssociationToggleSelectionListener listener ;
+	TableAssociationsWizardPage tableAssociationsWizardPage; //the parent wizard page
+	AssociationFigure selectedAssociationFigure ;
+	
+	protected final ResourceManager resourceManager;
+	
+	public AssociationsListComposite(Composite parent, TableAssociationsWizardPage tableAssociationsWizardPage, ResourceManager resourceManager){
+		super(parent);
+		this.tableAssociationsWizardPage = tableAssociationsWizardPage;
+		this.resourceManager = resourceManager;
+		
+		setBounds(10, 10 , 500, 200);
+		Color backgroundColor = new Color(Display.getDefault(), 255,255,255);
+		setBackground(backgroundColor);
+		backgroundColor.dispose();
+		
+		Figure figure = new Figure();
+		figure.setLayoutManager(new ToolbarLayout());
+		figure.setBorder(new LineBorder(1));
+		this.listener = new AssociationToggleSelectionListener(); 
+		
+		this.setContents(figure);
+	}
+
+	public void updateAssociations(List<Association> associations){
+		Figure figure = (Figure)this.getContents();
+		this.disposeFigure(figure);
+		
+		this.associations = associations;
+		if( associations != null ){
+			for( int i = 0; i <associations.size(); i ++ ){
+				Association association = associations.get(i);
+				AssociationFigure assocFigure = new AssociationFigure(association, this.resourceManager);
+				assocFigure.addActionListener( listener );
+				figure.add(assocFigure);
+			}
+		}
+	}
+	
+	public Association getSelectedAssociation(){
+		return this.selectedAssociationFigure.getAssociation();
+	}
+
+	@SuppressWarnings("unchecked")
+	public void updateSelectedAssociation(){
+		Figure figure = (Figure)this.getContents();
+		List<AssociationFigure> associationFigures = figure.getChildren();
+		for(AssociationFigure assocFig : associationFigures){
+			if( assocFig == this.selectedAssociationFigure){
+				assocFig.update(); 
+			}
+		}
+	}
+	
+	/**
+	 * Get the association just before the selected one in UI
+	 * @return
+	 */
+	@SuppressWarnings("unchecked")
+	public Association getPreviousAssociation(){
+		Figure figure = (Figure)this.getContents();
+		List<AssociationFigure> associationFigures = figure.getChildren();
+		AssociationFigure ret = null;
+		for(AssociationFigure assocFig : associationFigures){
+			if( assocFig.isSelected() ){
+				break; 
+			}
+			ret = assocFig;
+		}
+		return ret==null?null:ret.getAssociation();
+	}
+	
+	@Override
+	public void dispose() {
+		this.disposeFigure((Figure) getContents());
+		super.dispose();
+	}
+
+	@SuppressWarnings("unchecked")
+	protected void disposeFigure(Figure figure) {
+		for (AssociationFigure associationFigure : (List<AssociationFigure>) figure.getChildren()) {
+			associationFigure.removeActionListener(this.listener);
+			associationFigure.dispose();
+		}
+		figure.removeAll();
+		this.selectedAssociationFigure = null;
+	}
+
+	class AssociationToggleSelectionListener implements ActionListener {
+		public void actionPerformed(ActionEvent event) {
+			AssociationFigure figure = (AssociationFigure )event.getSource() ;
+			figure.setSelected(true);
+			Association association = figure.getAssociation();
+			tableAssociationsWizardPage.updateAssociationEditPanel(association);
+			//un-select the previous selected
+			if( selectedAssociationFigure != null  && selectedAssociationFigure!= figure ){
+				selectedAssociationFigure.setSelected( false );
+			}
+			//Highlight new selection
+			selectedAssociationFigure = figure;
+			selectedAssociationFigure.setSelected( true );
+		}
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/gen/CardinalityPage.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/gen/CardinalityPage.java
new file mode 100644
index 0000000..45c9aad
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/gen/CardinalityPage.java
@@ -0,0 +1,161 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2009 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.ui.internal.wizards.gen;
+
+import org.eclipse.jpt.gen.internal.Association;
+import org.eclipse.jpt.gen.internal.ORMGenCustomizer;
+import org.eclipse.jpt.ui.internal.JpaHelpContextIds;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Label;
+
+
+public class CardinalityPage extends NewAssociationWizardPage {
+
+	private Label mtoDescLabel;
+	private Label otmDescLabel;
+	private Label otoDescLabel;
+	private Label mtmDescLabel;
+	
+	private Button[] cardinalityButtons = new Button[4];
+	
+	protected CardinalityPage(ORMGenCustomizer customizer) {
+		super( customizer , "CardinalityPage" );
+		setTitle(JptUiEntityGenMessages.GenerateEntitiesWizard_newAssoc_cardinalityPage_title);
+		setDescription( JptUiEntityGenMessages.GenerateEntitiesWizard_newAssoc_cardinalityPage_desc);
+	}
+
+	public void createControl(Composite parent) {
+		initializeDialogUnits(parent);
+		
+		Composite composite = new Composite(parent, SWT.NULL);
+		int nColumns= 1 ;
+		GridLayout layout = new GridLayout();
+		layout.numColumns = nColumns;
+		composite.setLayout(layout);
+		this.getHelpSystem().setHelp(composite, JpaHelpContextIds.GENERATE_ENTITIES_WIZARD_ASSOCIATION_CARDINALITY);
+
+		CardinalitySelectionListener selectionListener = new CardinalitySelectionListener();
+		cardinalityButtons[0] = createRadioButton( composite, 1, JptUiEntityGenMessages.manyToOne);
+		cardinalityButtons[0].addSelectionListener( selectionListener );
+		//Default cardinality is MTO
+		cardinalityButtons[0].setSelection(true);
+		getWizardDataModel().put(NewAssociationWizard.ASSOCIATION_CADINALITY, Association.MANY_TO_ONE);		
+
+		mtoDescLabel = createLabel(composite,1, JptUiEntityGenMessages.manyToOneDesc);
+		
+		cardinalityButtons[1] = createRadioButton( composite, 1, JptUiEntityGenMessages.oneToMany);
+		cardinalityButtons[1].addSelectionListener( selectionListener );
+		
+		otmDescLabel = createLabel(composite,1, JptUiEntityGenMessages.manyToOneDesc);
+
+		cardinalityButtons[2] = createRadioButton( composite, 1, JptUiEntityGenMessages.oneToOne);
+		cardinalityButtons[2].addSelectionListener( selectionListener );
+
+		otoDescLabel = createLabel(composite,1, JptUiEntityGenMessages.oneToOneDesc);
+
+		cardinalityButtons[3] = createRadioButton( composite, 1, JptUiEntityGenMessages.manyToMany);
+		mtmDescLabel= createLabel(composite,1, JptUiEntityGenMessages.manyToManyDesc);
+		
+		setControl(composite);
+		this.setPageComplete( true );
+
+		cardinalityButtons[0].setFocus();
+
+	}
+
+	public void updateWithNewTables() {
+		String s1 = getReferrerTableName() ;
+		String s2 = getReferencedTableName() ;
+		String joinTableName = getJoinTableName();
+		if( s1 == null || s2 == null )
+			return ;
+		
+		updateDescriptionText(s1, s2);
+		if( joinTableName == null ){
+			cardinalityButtons[0].setEnabled(true);
+			cardinalityButtons[1].setEnabled(true);
+			cardinalityButtons[2].setEnabled(true);
+			cardinalityButtons[3].setEnabled(false);
+			mtmDescLabel.setEnabled(false);
+		}else{
+			cardinalityButtons[0].setEnabled(false);
+			cardinalityButtons[1].setEnabled(false);
+			cardinalityButtons[2].setEnabled(false);
+			cardinalityButtons[3].setEnabled(true);
+			cardinalityButtons[3].setSelection(true);
+			mtmDescLabel.setEnabled(true);
+		}
+		((Composite)this.getControl()).layout() ;
+	}
+
+	private void updateDescriptionText(String s1, String s2) {
+		//MTO
+		String msg = String.format(JptUiEntityGenMessages.manyToOneDesc, s2, s1);
+		mtoDescLabel.setText( msg );
+		//OTM
+		msg = String.format(JptUiEntityGenMessages.manyToOneDesc, s1, s2);
+		otmDescLabel.setText( msg );
+		msg = String.format(JptUiEntityGenMessages.oneToOneDesc, s1, s2);
+		otoDescLabel.setText( msg );
+		msg = String.format(JptUiEntityGenMessages.manyToManyDesc, s1, s2, s2, s1);
+		mtmDescLabel.setText( msg );
+	}
+
+	public boolean canFlipToNextPage() {
+		return false;
+	}
+	
+	private Label createLabel(Composite container, int span, String text) {
+		Label label = new Label(container, SWT.NONE);
+		label.setText(text);
+		GridData gd = new GridData();
+		gd.horizontalSpan = span;
+		gd.horizontalIndent = 30;
+		label.setLayoutData(gd);
+		return label;
+	}
+	
+	
+	private Button createRadioButton(Composite container, int span, String text ) {
+		Button btn = new Button(container, SWT.RADIO );
+		btn.setText(text);
+		GridData gd = new GridData();
+		gd.horizontalSpan = span;
+		btn.setLayoutData(gd);
+		return btn;
+	}
+	
+
+	private class CardinalitySelectionListener implements SelectionListener {
+		public void widgetDefaultSelected(SelectionEvent e) {}
+	
+		public void widgetSelected(SelectionEvent e) {
+			if( e.getSource() == cardinalityButtons[0]){
+				getWizardDataModel().put(NewAssociationWizard.ASSOCIATION_CADINALITY, Association.MANY_TO_ONE);
+			}else if( e.getSource() == cardinalityButtons[1]){
+				getWizardDataModel().put(NewAssociationWizard.ASSOCIATION_CADINALITY, Association.ONE_TO_MANY );
+			}else if( e.getSource() == cardinalityButtons[2]){
+				getWizardDataModel().put(NewAssociationWizard.ASSOCIATION_CADINALITY, Association.ONE_TO_ONE);
+			}else{
+				getWizardDataModel().put(NewAssociationWizard.ASSOCIATION_CADINALITY, Association.MANY_TO_MANY);
+			}
+			CardinalityPage.this.setPageComplete(true);
+			
+		}
+	}
+	
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/gen/CascadeDialog.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/gen/CascadeDialog.java
new file mode 100644
index 0000000..f4b6a1b
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/gen/CascadeDialog.java
@@ -0,0 +1,191 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2009 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.ui.internal.wizards.gen;
+
+import java.util.Collections;
+import java.util.List;
+
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.dialogs.TrayDialog;
+import org.eclipse.jpt.gen.internal.AssociationRole;
+import org.eclipse.jpt.gen.internal.util.StringUtil;
+import org.eclipse.jpt.ui.internal.JpaHelpContextIds;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Group;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.help.IWorkbenchHelpSystem;
+
+/**
+ * Simple dialog allows user to set the cascade property of an associationRole.
+ * The value of cascade can be "all", or any combination of other selections.
+ * 
+ */
+public class CascadeDialog extends TrayDialog {
+
+	private static String[] ALL_CASCADES = new String[] {TagNames.ALL_CASCADE, TagNames.PERSIST_CASCADE, TagNames.MERGE_CASCADE
+			, TagNames.REMOVE_CASCADE, TagNames.REFRESH_CASCADE};
+
+	private static String[] ALL_CASCADES_LABELS 
+		= new String[] { "&all", 		//$NON-NLS-1$
+						"&persist",		//$NON-NLS-1$
+						"&merge",		//$NON-NLS-1$
+						"&remove",		//$NON-NLS-1$
+						"r&efresh"};	//$NON-NLS-1$
+
+	
+	private Button[] allButtons = new Button[ALL_CASCADES.length];
+
+	private AssociationRole associationRole;
+	private List<String> cascades;
+	
+	protected CascadeDialog(Shell parentShell) {
+		super(parentShell);
+	}
+
+	public static CascadeDialog create(AssociationRole role) {
+		CascadeDialog dlg = new CascadeDialog(Display.getDefault().getActiveShell() );
+		dlg.setAssociationRole(role);
+		return dlg;
+	}
+
+    /*
+     * (non-Javadoc) Method declared on Window.
+     */
+    protected void configureShell(Shell newShell) {
+        super.configureShell(newShell);
+        newShell.setText(JptUiEntityGenMessages.selectCascadeDlgTitle);
+		this.getHelpSystem().setHelp(newShell, JpaHelpContextIds.GENERATE_ENTITIES_WIZARD_SELECT_CASCADE);
+    }
+	
+	private void setAssociationRole(AssociationRole role) {
+		this.associationRole = role;
+		List<String> list = StringUtil.strToList(associationRole.getCascade(), ',', true/*trim*/); //role.getCascade() contains the comma separed cascades (see below)
+		if (list == null) {
+			list = Collections.emptyList();
+		}
+		cascades = list;
+		
+	}
+
+	protected void createButtonsForButtonBar(Composite parent) {
+		createButton(parent, IDialogConstants.OK_ID, IDialogConstants.OK_LABEL, true);
+		createButton(parent, IDialogConstants.CANCEL_ID, IDialogConstants.CANCEL_LABEL, false);
+	}
+	
+	protected Control createDialogArea(Composite parent) {
+		Composite container = (Composite) super.createDialogArea(parent);
+		createCascadeTypesGroup(container);
+		Dialog.applyDialogFont(container);
+		return container;
+	}
+
+	private void createCascadeTypesGroup(Composite parent) {
+		Group group = new Group(parent, SWT.NONE);
+		group.setLayout(new GridLayout());
+		GridData gd = new GridData(GridData.FILL_HORIZONTAL);
+		gd.widthHint = 275;
+		group.setLayoutData(gd);
+		group.setText(JptUiEntityGenMessages.cascade);
+
+		for( int i=0; i< ALL_CASCADES.length; i ++ ){
+			Button checkbox = new Button(group, SWT.CHECK);
+			checkbox.setText( ALL_CASCADES_LABELS[i] );
+			checkbox.setSelection( isInList(ALL_CASCADES[i]) ); //$NON-NLS-1$
+			checkbox.setData(ALL_CASCADES[i]);
+			allButtons[i] = checkbox;
+			/*if <code>all</code> is selected then deselect all others*/
+			checkbox.addSelectionListener( new SelectionListener(){
+				public void widgetDefaultSelected(SelectionEvent e) {}
+				public void widgetSelected(SelectionEvent e) {
+					Button b = (Button)e.getSource();
+					if( b.getSelection() ){
+						if( b == allButtons[0] ){
+							for( Button btn : allButtons ){
+								if( btn != e.getSource() ) btn.setSelection(false);
+							}
+						}else{
+							allButtons[0].setSelection(false); 
+						}
+					}
+				}
+			});
+		}
+	}
+
+	protected void okPressed() {
+		StringBuilder builder = new StringBuilder();
+		for( Button b : allButtons ){
+			if( b.getSelection() ){
+				if( builder.length()>0 ){
+					builder.append( ',');
+				}
+				builder.append( b.getData() );
+			}
+		}
+		this.associationRole.setCascade( builder.toString() );
+		super.okPressed();
+	}	
+
+	private boolean isInList(String cascade) {
+		for( String s : cascades ){
+			if( s.equals(cascade )){
+				return true;
+			}
+		}
+		return false;
+	}
+	
+	protected final IWorkbenchHelpSystem getHelpSystem() {
+		return PlatformUI.getWorkbench().getHelpSystem();
+	}
+
+}
+
+class TagNames
+{
+	public static final String BASIC_TAG = "basic";
+	public static final String CASCADE_TAG = "cascade";
+	public static final String COLUMN_TAG = "column";
+	public static final String EMBEDDED_TAG = "embedded";
+	public static final String EMBEDDED_ID_TAG = "embedded-id";
+	public static final String GENERATED_VALUE_TAG = "generated-value";
+	public static final String ID_TAG = "id";
+	public static final String ID_CLASS_TAG = "id";
+	public static final String JOIN_COLUMN_TAG = "join-column";
+	public static final String INVERSE_JOIN_COLUMN_TAG = "inverse-join-column";
+	public static final String LOB_TAG = "lob";
+	public static final String MANY_TO_MANY_TAG = "many-to-many";
+	public static final String MANY_TO_ONE_TAG = "many-to-one";
+	public static final String MAPPED_BY_TAG = "mapped-by";
+	public static final String ONE_TO_MANY_TAG = "one-to-many";
+	public static final String ONE_TO_ONE_TAG = "one-to-one";
+	public static final String PK_JOIN_COLUMN_TAG = "primary-key-join-column";
+	public static final String TABLE_TAG = "table";
+	public static final String VERSION_TAG = "version";
+	public static final String JOIN_TABLE_TAG = "join-table";
+
+	/*cascade tags*/
+	public static final String ALL_CASCADE = "all";
+	public static final String PERSIST_CASCADE = "persist";
+	public static final String MERGE_CASCADE = "merge";
+	public static final String REMOVE_CASCADE = "remove";
+	public static final String REFRESH_CASCADE = "refresh";
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/gen/ColumnGenPanel.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/gen/ColumnGenPanel.java
new file mode 100644
index 0000000..1ab70f4
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/gen/ColumnGenPanel.java
@@ -0,0 +1,360 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 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.ui.internal.wizards.gen;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.jdt.core.JavaConventions;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jface.wizard.WizardPage;
+import org.eclipse.jpt.gen.internal.ORMGenColumn;
+import org.eclipse.jpt.gen.internal.ORMGenCustomizer;
+import org.eclipse.jpt.ui.JptUiPlugin;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Group;
+import org.eclipse.swt.widgets.Text;
+
+/**
+ * The panel used in the <code>TablesAndColumnsPage</code> wizard page 
+ * to edit the column generation properties.
+ * An instance of this class is created by the <code>ORMGenWizard</code> 
+ * implementation.
+
+ */
+public class ColumnGenPanel 
+{
+	WizardPage wizardPage ; 
+	Composite parent;	//parent control with grid layout
+	int columns; 		//total columns in the parent composite
+	
+	ORMGenCustomizer customizer;
+	
+	private ORMGenColumn mColumn;
+	private boolean mPanelInited;
+	private boolean mIsUpdatingControls;
+	
+	private Group columnMappingGroup;
+	private Button mGeneratedCheckbox;
+	private Text mPropNameField;
+	private Combo mMappingKindCombo;
+	private Combo mPropTypeCombo;
+	private Button mUpdateableCheckBox;
+	private Button mInsertableCheckBox;
+	
+	private Group domainClassGroup ;
+	private ScopePanel mPropGetScopePanel;
+	private ScopePanel mPropSetScopePanel;
+	
+	public ColumnGenPanel(Composite parent, int columns, ORMGenCustomizer customizer, WizardPage wizardPage ) {
+		this.wizardPage = wizardPage;
+		this.customizer = customizer;
+		this.parent =parent;
+		this.columns = columns;
+		
+		initPanel();
+	}
+	/**
+	 * Changes the table edited by the panel.
+	 * This is supposed to update the panel editing controls 
+	 * using the column values.
+	 */
+	public void setColumn(ORMGenColumn column) {
+		mColumn = column;
+		
+		/*lazy init panel because it uses mColumn*/
+		if (!mPanelInited) {
+			initPanel();
+			mPanelInited = true;
+		}
+		
+		updateControls();
+	}
+	private void updateControls() {
+		if (mIsUpdatingControls) {
+			return;
+		}
+		
+		mIsUpdatingControls = true;
+		boolean isGenerated = mColumn.isGenerated();
+		mGeneratedCheckbox.setSelection( isGenerated);
+		mGeneratedCheckbox.setEnabled(true);
+		enableControls(isGenerated);
+		try {
+			mPropNameField.setText(mColumn.getPropertyName());
+
+			mPropTypeCombo.setText( mColumn.getPropertyType());
+			
+			mMappingKindCombo.setText( mColumn.getMappingKind());
+			
+			mUpdateableCheckBox.setSelection( mColumn.isUpdateable());
+			
+			mInsertableCheckBox.setSelection(mColumn.isInsertable());
+			
+			mPropGetScopePanel.enableComponents(isGenerated);
+			mPropGetScopePanel.setScope(mColumn.getPropertyGetScope());
+			
+			mPropSetScopePanel.enableComponents( isGenerated );
+			mPropSetScopePanel.setScope(mColumn.getPropertySetScope());
+
+			if( mColumn.isPartOfCompositePrimaryKey()){
+				enableControls(false);
+				mPropNameField.setEnabled(true);
+				mGeneratedCheckbox.setEnabled(false);
+			}
+			
+		} catch (Exception e) {
+			JptUiPlugin.log(e);
+		}
+
+		mIsUpdatingControls = false;
+	}
+	private void enableControls(boolean isGenerated) {
+		Control[] controls = this.domainClassGroup.getChildren();
+		for( Control c: controls){
+			c.setEnabled( isGenerated );
+		}
+
+		controls = this.columnMappingGroup.getChildren();
+		for( Control c: controls){
+			c.setEnabled( isGenerated );
+		}
+	}
+	/**
+	 * Initializes the panel by adding the editing controls.
+	 * @param columns 
+	 * @param parent 
+	 */
+	protected void initPanel() {
+		createControls(parent, columns);
+		this.mPanelInited = true;
+	}
+	
+	//-------------------------------------------
+	//----- ScopePanel class --------------------
+	//-------------------------------------------
+	/**
+	 * A panel containing 3 radios (public, protected, private)
+	 */
+	private class ScopePanel 
+	{
+		private Button mPublicRadio;
+		private Button mProtectedRadio;
+		private Button mPrivateRadio;
+		
+		public ScopePanel(Composite comp, SelectionListener listener) {
+			//super(3, 20/*hspacing*/, 0/*vspacing*/);
+			
+			Composite radioGroup = new Composite( comp, SWT.NONE);
+			radioGroup.setLayout(new GridLayout(3, true));
+			GridData gd = new GridData();
+			gd.horizontalSpan = 3;
+			radioGroup.setLayoutData(gd);
+			
+			/*string not localized intentionally, they are used as the actual 
+			 * scope value (see getText() usage)*/
+			mPublicRadio = new Button( radioGroup, SWT.RADIO );
+			mPublicRadio.setText( "public");
+			mPublicRadio.setLayoutData(new GridData());
+			mProtectedRadio = new Button( radioGroup, SWT.RADIO );
+			mProtectedRadio.setText("protected");
+			mProtectedRadio.setLayoutData(new GridData());
+			mPrivateRadio = new Button(radioGroup, SWT.RADIO );
+			mPrivateRadio.setText( "private");
+			mPrivateRadio.setLayoutData(new GridData());
+			
+			mPublicRadio.addSelectionListener(listener);
+			mProtectedRadio.addSelectionListener(listener);
+			mPrivateRadio.addSelectionListener(listener);
+				
+		}
+		public void enableComponents(boolean b) {
+			mPublicRadio.setEnabled(b);
+			mProtectedRadio.setEnabled(b);
+			mPrivateRadio.setEnabled(b);
+		}
+		/**
+		 * Returns the currently selected scope.
+		 */
+		public String getScope() {
+			Button radio = null;
+			if (mPublicRadio.getSelection()) {
+				radio = mPublicRadio;
+			} else if (mProtectedRadio.getSelection() ) {
+				radio = mProtectedRadio;
+			} else if (mPrivateRadio.getSelection() ) {
+				radio = mPrivateRadio;
+			}
+			return radio != null ? radio.getText() : null;
+		}
+		public void setScope(String scope) {
+			mPublicRadio.setSelection(false);
+			mProtectedRadio.setSelection(false);
+			mPrivateRadio.setSelection(false);
+			if( scope == null )
+				return;
+			if (scope.equals(ORMGenColumn.PUBLIC_SCOPE)) {
+				mPublicRadio.setSelection(true);
+			} else if (scope.equals(ORMGenColumn.PROTECTED_SCOPE)) {
+				mProtectedRadio.setSelection(true);
+			} else if (scope.equals(ORMGenColumn.PRIVATE_SCOPE)) {
+				mPrivateRadio.setSelection(true);
+			}
+		}
+	}
+	
+	//-------------------------------------------
+	//----- private methods ---------------------
+	//-------------------------------------------
+	private void createControls(Composite composite, int columns) {
+		mGeneratedCheckbox = new Button(composite, SWT.CHECK);
+		mGeneratedCheckbox.setText( JptUiEntityGenMessages.GenerateEntitiesWizard_colPanel_genProp);
+		mGeneratedCheckbox.addSelectionListener(new SelectionListener() {
+			public void widgetDefaultSelected(SelectionEvent e) {}
+			public void widgetSelected(SelectionEvent e) {
+				if (!mIsUpdatingControls) {
+					mColumn.setGenerated(mGeneratedCheckbox.getSelection() );
+					updateControls();
+				}
+			}});
+		SWTUtil.fillColumns(mGeneratedCheckbox, columns);
+		
+		columnMappingGroup = new Group( composite, SWT.NONE);
+		columnMappingGroup.setText( JptUiEntityGenMessages.GenerateEntitiesWizard_colPanel_colMapping);
+		columnMappingGroup.setLayout(new GridLayout(columns, false));
+		GridData layoutData = new GridData();
+		layoutData.horizontalSpan = columns;
+		layoutData.verticalAlignment = SWT.FILL;
+		layoutData.horizontalAlignment = SWT.FILL;
+		layoutData.grabExcessHorizontalSpace = true;
+		layoutData.grabExcessVerticalSpace = false;
+		layoutData.horizontalIndent = 20 ;
+		columnMappingGroup.setLayoutData(layoutData);
+		
+		SWTUtil.createLabel(columnMappingGroup, 1, JptUiEntityGenMessages.GenerateEntitiesWizard_colPanel_propName );
+		mPropNameField = new Text(columnMappingGroup, SWT.BORDER | SWT.SINGLE );
+		mPropNameField.addModifyListener(new ModifyListener(){
+			@SuppressWarnings("restriction")
+			public void modifyText(ModifyEvent e) {
+				if (!mIsUpdatingControls) {
+					String fldName = mPropNameField.getText();
+					IStatus status = JavaConventions.validateIdentifier( fldName, 
+						JavaCore.VERSION_1_3, JavaCore.VERSION_1_3 );
+					if( !status.matches(IStatus.ERROR)){
+						mColumn.setPropertyName(fldName);
+						wizardPage.setErrorMessage(null);
+					}else{
+						wizardPage.setErrorMessage(status.getMessage());
+					}
+				}
+			}			
+		});
+		SWTUtil.fillColumns(mPropNameField ,3);
+		
+		SWTUtil.createLabel(columnMappingGroup, 1, JptUiEntityGenMessages.GenerateEntitiesWizard_colPanel_propType );
+		mPropTypeCombo = new Combo(columnMappingGroup, SWT.SINGLE | SWT.READ_ONLY);
+		mPropTypeCombo.setItems( this.customizer.getAllPropertyTypes());
+		mPropTypeCombo.addModifyListener( new ModifyListener(){
+			public void modifyText(ModifyEvent e) {
+				if (!mIsUpdatingControls) {
+					mColumn.setPropertyType(mPropTypeCombo.getText());
+				}
+			}
+		});
+		SWTUtil.fillColumns(mPropTypeCombo,3);
+		
+		SWTUtil.createLabel(columnMappingGroup, 1, JptUiEntityGenMessages.GenerateEntitiesWizard_colPanel_mapKind );
+		mMappingKindCombo = new Combo(columnMappingGroup, SWT.SINGLE | SWT.READ_ONLY);
+		mMappingKindCombo.setItems( this.customizer.getAllMappingKinds());
+		mMappingKindCombo.addSelectionListener(new SelectionListener() {
+			public void widgetDefaultSelected(SelectionEvent e) {}
+			public void widgetSelected(SelectionEvent e) {
+				if (!mIsUpdatingControls) {
+					mColumn.setMappingKind((String)mMappingKindCombo.getText());
+				}
+				
+			}});
+		SWTUtil.fillColumns(mMappingKindCombo ,3);
+		
+		mUpdateableCheckBox = new Button(columnMappingGroup, SWT.CHECK);
+		mUpdateableCheckBox.setText( JptUiEntityGenMessages.GenerateEntitiesWizard_colPanel_colUpdateable);
+		mUpdateableCheckBox.addSelectionListener(new SelectionListener() {
+			public void widgetDefaultSelected(SelectionEvent e) {}
+			public void widgetSelected(SelectionEvent e) {
+				if (!mIsUpdatingControls) {
+					mColumn.setUpdateable(mUpdateableCheckBox.getSelection() );
+				}
+			}});
+		SWTUtil.fillColumns(mUpdateableCheckBox ,4);
+		
+		mInsertableCheckBox = new Button(columnMappingGroup, SWT.CHECK);
+		mInsertableCheckBox.setText( JptUiEntityGenMessages.GenerateEntitiesWizard_colPanel_colInsertable);
+		mInsertableCheckBox.addSelectionListener(new SelectionListener() {
+			public void widgetDefaultSelected(SelectionEvent e) {}
+			public void widgetSelected(SelectionEvent e) {
+				if (!mIsUpdatingControls) {
+					mColumn.setInsertable(mInsertableCheckBox.getSelection());
+				}
+			}});
+		SWTUtil.fillColumns(mInsertableCheckBox ,4);
+		
+		SWTUtil.createLabel(composite, 4,""); 
+		
+		createJavaBeanPropertyControls(composite, columns);
+	}
+	
+	void createJavaBeanPropertyControls(Composite composite, int columns){
+		//Java class generation properties 
+		domainClassGroup = new Group(composite, SWT.NONE);
+		domainClassGroup.setText( JptUiEntityGenMessages.GenerateEntitiesWizard_colPanel_beanProp );
+		domainClassGroup.setLayout(new GridLayout(columns, false));
+		GridData layoutData = new GridData();
+		layoutData.horizontalSpan = columns;
+		layoutData.verticalAlignment = SWT.FILL;
+		layoutData.horizontalAlignment = SWT.FILL;
+		layoutData.grabExcessHorizontalSpace = true;
+		layoutData.grabExcessVerticalSpace = false;
+		layoutData.horizontalIndent = 20;
+		domainClassGroup.setLayoutData(layoutData);
+
+		SWTUtil.createLabel(domainClassGroup, 1, JptUiEntityGenMessages.GenerateEntitiesWizard_colPanel_getterScope );
+		mPropGetScopePanel = new ScopePanel(domainClassGroup, new SelectionListener() {
+			public void widgetDefaultSelected(SelectionEvent e) {}
+
+			public void widgetSelected(SelectionEvent e) {
+				if (!mIsUpdatingControls) {
+					if( ((Button)e.getSource()).getSelection() )
+						mColumn.setPropertyGetScope(mPropGetScopePanel.getScope());
+				}
+				
+			}});
+		
+		SWTUtil.createLabel(domainClassGroup, 1, JptUiEntityGenMessages.GenerateEntitiesWizard_colPanel_setterScope );
+		mPropSetScopePanel = new ScopePanel(domainClassGroup, new SelectionListener() {
+			public void widgetDefaultSelected(SelectionEvent e) {}
+
+			public void widgetSelected(SelectionEvent e) {
+				if (!mIsUpdatingControls) {
+					if( ((Button)e.getSource()).getSelection() )
+						mColumn.setPropertySetScope(mPropSetScopePanel.getScope());
+				}
+			}});
+		
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/gen/DatabaseGroup.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/gen/DatabaseGroup.java
new file mode 100644
index 0000000..99cd0c4
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/gen/DatabaseGroup.java
@@ -0,0 +1,526 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 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.ui.internal.wizards.gen;
+
+import java.lang.reflect.InvocationTargetException;
+import java.util.Collections;
+import java.util.EventListener;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+import java.util.SortedSet;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.jface.operation.IRunnableWithProgress;
+import org.eclipse.jface.resource.ResourceManager;
+import org.eclipse.jface.wizard.IWizardContainer;
+import org.eclipse.jpt.core.JpaProject;
+import org.eclipse.jpt.db.ConnectionAdapter;
+import org.eclipse.jpt.db.ConnectionListener;
+import org.eclipse.jpt.db.ConnectionProfile;
+import org.eclipse.jpt.db.JptDbPlugin;
+import org.eclipse.jpt.db.Schema;
+import org.eclipse.jpt.db.SchemaContainer;
+import org.eclipse.jpt.db.ui.internal.DTPUiTools;
+import org.eclipse.jpt.ui.JptUiPlugin;
+import org.eclipse.jpt.ui.internal.ImageRepository;
+import org.eclipse.jpt.utility.internal.CollectionTools;
+import org.eclipse.jpt.utility.internal.SynchronizedBoolean;
+import org.eclipse.jpt.utility.internal.iterables.EmptyIterable;
+import org.eclipse.jpt.utility.internal.iterators.CloneIterator;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Label;
+
+/**
+ * A composite used to connect to database, includes following UI controls:
+ * - connection combo-box
+ * - schema combo-box
+ * - add connection button
+ * - reconnect button
+ */
+public class DatabaseGroup
+{
+	private final JpaProject jpaProject;
+	private final Set<Listener> listeners = Collections.synchronizedSet(new HashSet<Listener>());
+
+	// these are kept in synch with the selection
+	ConnectionProfile selectedConnectionProfile;
+	private Schema selectedSchema;
+
+	private final Combo connectionComboBox;
+
+	private final Combo schemaComboBox;
+
+	private final Button reconnectButton;
+
+	private final ConnectionListener connectionListener;
+
+	private IWizardContainer wizardContainer;
+
+	protected final ResourceManager resourceManager;
+
+	// ********** construction **********
+
+	DatabaseGroup(IWizardContainer wizardContainer, JpaProject jpaProject, Composite parent, ResourceManager resourceManager, int widthHint) {
+		super();
+		this.wizardContainer = wizardContainer;
+		this.jpaProject = jpaProject;
+		this.resourceManager = resourceManager;
+
+		// connection combo-box
+		this.buildLabel(parent, 1, JptUiEntityGenMessages.connection);
+		this.connectionComboBox = this.buildComboBox(parent, widthHint, this.buildConnectionComboBoxSelectionListener());
+
+		// add connection button
+		Button addConnectionButton = this.buildButton(parent, JptUiEntityGenMessages.addConnectionLink, ImageRepository.getAddConnectionButtonImage(this.resourceManager), this.buildAddConnectionLinkSelectionListener());
+		GridData data = new GridData();
+		addConnectionButton.setLayoutData(data);
+
+
+		// A composite holds the reconnect button & text
+		this.buildLabel(parent, 1, ""); //$NON-NLS-1$
+		Composite comp = new Composite( parent , SWT.NONE );
+		GridData gd = new GridData();
+		gd.grabExcessHorizontalSpace = true ;
+		gd.horizontalSpan = 2;
+		comp.setLayoutData( gd );
+		GridLayout gl = new GridLayout(2, false);
+		// Make the reconnect button to be closer to the connection combo.
+		gl.marginTop = -5;
+		comp.setLayout(gl);
+		this.reconnectButton = this.buildButton(comp, JptUiEntityGenMessages.connectLink, ImageRepository.getReconnectButtonImage(this.resourceManager),  this.buildReconnectLinkSelectionListener());
+		this.buildLabel(comp, 1, JptUiEntityGenMessages.schemaInfo);
+
+		// schema combo-box
+		this.buildLabel(parent, 1, JptUiEntityGenMessages.schema);
+		this.schemaComboBox = new Combo(parent, SWT.BORDER | SWT.READ_ONLY);
+		data = new GridData(SWT.BEGINNING, SWT.CENTER, true, false);
+		data.horizontalAlignment = SWT.FILL;
+		data.horizontalSpan = 1;
+		data.grabExcessHorizontalSpace = true ;
+		this.schemaComboBox.setLayoutData(data);
+		this.schemaComboBox.addSelectionListener(this.buildSchemaComboBoxSelectionListener());
+		// filler
+		new Label(parent, SWT.NULL);
+
+		this.connectionListener = this.buildConnectionListener();
+	}
+
+
+	public void init()
+	{
+		// initialize state, based on JPA project
+		this.selectedConnectionProfile = this.getJpaProjectConnectionProfile();
+		this.selectedSchema = this.getDefaultSchema();
+
+		if (this.selectedSchema != null) {
+			this.fireSchemaChanged(this.selectedSchema);
+		}
+		if (this.selectedConnectionProfile != null) {
+			this.selectedConnectionProfile.addConnectionListener(this.connectionListener);
+			this.fireConnectionProfileChanged(this.selectedConnectionProfile);
+		}
+
+		this.updateConnectionComboBox();
+		this.updateSchemaComboBox();
+		this.updateReconnectLink();
+
+	}
+	// ********** intra-wizard methods **********
+
+	Schema getSelectedSchema() {
+		return this.selectedSchema;
+	}
+
+	void dispose() {
+		if (this.selectedConnectionProfile != null) {
+			this.selectedConnectionProfile.removeConnectionListener(this.connectionListener);
+		}
+	}
+
+
+	// ********** internal methods **********
+
+	/**
+	 * this can return null;
+	 * called at start-up and when the selected connection profile changes
+	 */
+	private ConnectionProfile getJpaProjectConnectionProfile() {
+		return this.jpaProject.getConnectionProfile();
+	}
+
+	/**
+	 * this can return null;
+	 * called at start-up and when the selected connection profile changes
+	 */
+	private Schema getDefaultSchema() {
+		return (this.selectedConnectionProfile == this.getJpaProjectConnectionProfile()) ?
+						jpaProject.getDefaultDbSchema()	: null;
+	}
+
+	/**
+	 * the connection combo-box is updated at start-up and when the user
+	 * adds a connection profile
+	 */
+	private void updateConnectionComboBox() {
+		this.connectionComboBox.removeAll();
+		for (String cpName : this.buildSortedConnectionProfileNames()) {
+			this.connectionComboBox.add(cpName);
+		}
+		if (this.selectedConnectionProfile != null) {
+			this.connectionComboBox.select(this.connectionComboBox.indexOf(this.selectedConnectionProfile.getName()));
+		}
+	}
+
+	private SortedSet<String> buildSortedConnectionProfileNames() {
+		return CollectionTools.sortedSet(JptDbPlugin.instance().getConnectionProfileFactory().getConnectionProfileNames());
+	}
+
+	/**
+	 * called at start-up and when the selected connection profile changes
+	 */
+	private void updateReconnectLink() {
+		this.reconnectButton.setEnabled(this.reconnectLinkCanBeEnabled());
+	}
+
+	private boolean reconnectLinkCanBeEnabled() {
+		return (this.selectedConnectionProfile != null) && !(this.selectedConnectionProfile.isActive());
+	}
+
+	/**
+	 * the schema combo-box is updated at start-up and
+	 * when the selected connection profile changes
+	 */
+	private void updateSchemaComboBox() {
+		this.schemaComboBox.removeAll();
+		for (String name : this.getSchemaNames()) {
+			this.schemaComboBox.add(name);
+		}
+		// the current schema *should* be in the current connection profile
+		if (this.selectedSchema != null) {
+			this.schemaComboBox.select(this.schemaComboBox.indexOf(this.selectedSchema.getName()));
+		}
+	}
+
+	private Iterable<String> getSchemaNames() {
+		SchemaContainer sc = this.jpaProject.getDefaultDbSchemaContainer();
+		// use schema *names* since the combo-box is read-only
+		return (sc != null) ? sc.getSortedSchemaNames() : EmptyIterable.<String>instance();
+	}
+
+	/**
+	 * If the specified name matches the name of the JPA project's
+	 * connection profile, return it; otherwise, build a new connection
+	 * profile.
+	 */
+	private ConnectionProfile checkJpaProjectConnectionProfile(String cpName) {
+		ConnectionProfile cp = this.getJpaProjectConnectionProfile();
+		if ((cp != null) && cp.getName().equals(cpName)) {
+			return cp;
+		}
+		return this.buildConnectionProfile(cpName);
+	}
+
+	private ConnectionProfile buildConnectionProfile(String name) {
+		return JptDbPlugin.instance().getConnectionProfileFactory().buildConnectionProfile(name);
+	}
+
+
+	// ********** listener callbacks **********
+
+	void selectedConnectionChanged() {
+		String text = this.connectionComboBox.getText();
+		if (text.length() == 0) {
+			if (this.selectedConnectionProfile == null) {
+				return;  // no change
+			}
+			this.selectedConnectionProfile.removeConnectionListener(this.connectionListener);
+			this.selectedConnectionProfile = null;
+		} else {
+			if (this.selectedConnectionProfile == null) {
+				this.selectedConnectionProfile = this.checkJpaProjectConnectionProfile(text);
+			} else {
+				if (text.equals(this.selectedConnectionProfile.getName())) {
+					return;  // no change
+				}
+				this.selectedConnectionProfile.removeConnectionListener(this.connectionListener);
+				this.selectedConnectionProfile = this.checkJpaProjectConnectionProfile(text);
+			}
+			this.selectedConnectionProfile.addConnectionListener(this.connectionListener);
+		}
+		this.fireConnectionProfileChanged(this.selectedConnectionProfile);
+		this.connectionChanged();
+	}
+
+	void selectedSchemaChanged() {
+		Schema old = this.selectedSchema;
+		this.selectedSchema = this.jpaProject.getDefaultDbSchemaContainer().getSchemaNamed(this.schemaComboBox.getText());
+		if (this.selectedSchema != old) {
+			fireSchemaChanged(this.selectedSchema);
+		}
+	}
+
+	/**
+	 * Open the DTP New Connection Profile wizard.
+	 * If the user creates a new connection profile, start using it and
+	 * connect it
+	 */
+	void addConnection() {
+		String addedProfileName = DTPUiTools.createNewConnectionProfile();
+		if (addedProfileName == null) {
+			return;  // user pressed "Cancel"
+		}
+		if (this.selectedConnectionProfile != null) {
+			this.selectedConnectionProfile.removeConnectionListener(this.connectionListener);
+		}
+		this.selectedConnectionProfile = this.buildConnectionProfile(addedProfileName);
+		this.selectedConnectionProfile.addConnectionListener(this.connectionListener);
+		this.updateConnectionComboBox();
+		this.selectedConnectionProfile.connect();
+		// everything else should be synchronized when we get the resulting open event
+		this.fireConnectionProfileChanged(this.selectedConnectionProfile);
+		this.updateSchemaComboBox();
+	}
+
+	void reconnect() {
+		try {
+			wizardContainer.run(true, true, new IRunnableWithProgress(){
+				public void run( final IProgressMonitor monitor ) 
+			    	throws InvocationTargetException, InterruptedException
+			    {
+					monitor.beginTask(JptUiEntityGenMessages.connectingToDatabase, 10);
+					final SynchronizedBoolean finished = new SynchronizedBoolean(false);
+					Thread t = new Thread(){
+						@Override
+						public void run() {
+							try {
+								DatabaseGroup.this.selectedConnectionProfile.connect();
+							} catch (Exception ex) {
+								JptUiPlugin.log(ex);
+							} finally {
+								finished.setTrue();
+							}
+						}						
+					};
+					t.start();
+					while (finished.isFalse()){
+						Thread.sleep(1000);
+						monitor.worked(1);
+					}
+			        // everything should be synchronized when we get the resulting open event
+					monitor.done();
+			    }
+			});
+		} catch (Exception e) {
+			JptUiPlugin.log(e);
+		}
+		wizardContainer.updateButtons();
+	}
+
+	/**
+	 * called when
+	 *     - the user selects a new connection
+	 *     - the connection was opened
+	 *     - the connection was closed (never happens?)
+	 * we need to update the schema stuff and the reconnect link
+	 */
+	void connectionChanged() {
+		Schema old = this.selectedSchema;
+		this.selectedSchema = this.getDefaultSchema();
+		if (this.selectedSchema != old) {
+			this.fireSchemaChanged(this.selectedSchema);
+		}
+		this.updateSchemaComboBox();
+		this.updateReconnectLink();
+	}
+
+
+	// ********** listeners **********
+
+	private SelectionListener buildConnectionComboBoxSelectionListener() {
+		return new SelectionListener() {
+			public void widgetDefaultSelected(SelectionEvent event) {
+				// nothing special for "default" (double-click?)
+				this.widgetSelected(event);
+			}
+			public void widgetSelected(SelectionEvent event) {
+				DatabaseGroup.this.selectedConnectionChanged();
+			}
+			@Override
+			public String toString() {
+				return "DatabaseConnectionWizardPage connection combo-box selection listener"; //$NON-NLS-1$
+			}
+		};
+	}
+
+	private SelectionListener buildSchemaComboBoxSelectionListener() {
+		return new SelectionListener() {
+			public void widgetDefaultSelected(SelectionEvent event) {
+				// nothing special for "default" (double-click?)
+				this.widgetSelected(event);
+			}
+			public void widgetSelected(SelectionEvent event) {
+				DatabaseGroup.this.selectedSchemaChanged();
+			}
+			@Override
+			public String toString() {
+				return "DatabaseConnectionWizardPage schema combo-box selection listener"; //$NON-NLS-1$
+			}
+		};
+	}
+
+	private SelectionListener buildAddConnectionLinkSelectionListener() {
+		return new SelectionAdapter() {
+			@Override
+			public void widgetSelected(SelectionEvent event) {
+				DatabaseGroup.this.addConnection();
+			}
+			@Override
+			public String toString() {
+				return "DatabaseConnectionWizardPage add connection link selection listener"; //$NON-NLS-1$
+			}
+		};
+	}
+
+	private SelectionListener buildReconnectLinkSelectionListener() {
+		return new SelectionAdapter() {
+			@Override
+			public void widgetSelected(SelectionEvent event) {
+				DatabaseGroup.this.reconnect();
+			}
+			@Override
+			public String toString() {
+				return "DatabaseConnectionWizardPage reconnect link selection listener"; //$NON-NLS-1$
+			}
+		};
+	}
+
+	private ConnectionListener buildConnectionListener() {
+		return new ConnectionAdapter() {
+			@Override
+			public void opened(ConnectionProfile cp) {
+				this.connectionChanged();
+			}
+			@Override  // this probably won't ever get called...
+			public void closed(ConnectionProfile cp) {
+				this.connectionChanged();
+			}
+			private void connectionChanged() {
+				Display.getDefault().asyncExec(
+					new Runnable() {
+						public void run() {
+							DatabaseGroup.this.connectionChanged();
+						}
+					}
+				);
+			}
+			@Override
+			public String toString() {
+				return "DatabaseConnectionWizardPage connection listener"; //$NON-NLS-1$
+			}
+		};
+	}
+
+
+	// ********** listeners **********
+
+	public void addListener(Listener listener) {
+		if ( ! this.listeners.add(listener)) {
+			throw new IllegalArgumentException("duplicate listener: " + listener); //$NON-NLS-1$
+		}
+	}
+
+	public void removeListener(Listener listener) {
+		if ( ! this.listeners.remove(listener)) {
+			throw new IllegalArgumentException("missing listener: " + listener); //$NON-NLS-1$
+		}
+	}
+
+	private Iterator<Listener> listeners() {
+		return new CloneIterator<Listener>(this.listeners);
+	}
+
+	void fireConnectionProfileChanged(ConnectionProfile connectionProfile) {
+		for (Iterator<Listener> stream = this.listeners(); stream.hasNext(); ) {
+			stream.next().selectedConnectionProfileChanged(connectionProfile);
+		}
+	}
+
+	void fireSchemaChanged(Schema schema) {
+		for (Iterator<Listener> stream = this.listeners(); stream.hasNext(); ) {
+			stream.next().selectedSchemaChanged(schema);
+		}
+	}
+
+	// ********** UI components **********
+
+	/**
+	 * build and return a label
+	 */
+	private Label buildLabel(Composite parent, int span, String text) {
+		Label label = new Label(parent, SWT.NONE);
+		label.setText(text);
+		GridData gd = new GridData();
+		gd.horizontalSpan = span;
+		label.setLayoutData(gd);
+		return label;
+	}
+
+	/**
+	 * build and return a combo-box
+	 */
+	private Combo buildComboBox(Composite parent, int widthHint, SelectionListener listener) {
+		Combo combo = new Combo(parent, SWT.BORDER | SWT.READ_ONLY);
+		combo.addSelectionListener(listener);
+		GridData data = new GridData(SWT.FILL, SWT.CENTER, true, false);
+		//data.grabExcessHorizontalSpace = true ;
+		data.widthHint = widthHint;
+		combo.setLayoutData(data);
+		return combo;
+	}
+
+	/**
+	 * build and return a link
+	 */
+	private Button buildButton(Composite parent, String toolTipText, Image image, SelectionListener listener) {
+		Button button = new Button(parent, SWT.NONE);
+		GridData data = new GridData(GridData.END, GridData.CENTER, false, false);
+		data.horizontalSpan = 1;
+		button.setLayoutData(data);
+		button.setImage( image );
+		button.setToolTipText( toolTipText);
+		button.addSelectionListener(listener);
+		return button;
+	}
+
+	// ********** listener interface **********
+
+	/**
+	 * Allows clients to listen for changes to the selected connection profile
+	 * and schema.
+	 */
+	public interface Listener extends EventListener
+	{
+		void selectedConnectionProfileChanged(ConnectionProfile connectionProfile);
+		void selectedSchemaChanged(Schema schema);
+	}
+
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/gen/DefaultTableGenerationWizardPage.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/gen/DefaultTableGenerationWizardPage.java
new file mode 100644
index 0000000..a93bec7
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/gen/DefaultTableGenerationWizardPage.java
@@ -0,0 +1,328 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 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.ui.internal.wizards.gen;
+
+import java.util.List;
+
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.IJavaModel;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.IPackageFragment;
+import org.eclipse.jdt.core.IPackageFragmentRoot;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.internal.ui.wizards.NewWizardMessages;
+import org.eclipse.jdt.internal.ui.wizards.TypedElementSelectionValidator;
+import org.eclipse.jdt.internal.ui.wizards.TypedViewerFilter;
+import org.eclipse.jdt.ui.JavaElementComparator;
+import org.eclipse.jdt.ui.JavaElementLabelProvider;
+import org.eclipse.jdt.ui.StandardJavaElementContentProvider;
+import org.eclipse.jdt.ui.wizards.NewTypeWizardPage;
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerFilter;
+import org.eclipse.jface.window.Window;
+import org.eclipse.jpt.core.JpaProject;
+import org.eclipse.jpt.core.internal.utility.jdt.JDTTools;
+import org.eclipse.jpt.gen.internal.ORMGenCustomizer;
+import org.eclipse.jpt.gen.internal.ORMGenTable;
+import org.eclipse.jpt.ui.JptUiPlugin;
+import org.eclipse.jpt.ui.internal.JpaHelpContextIds;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Group;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.dialogs.ElementTreeSelectionDialog;
+import org.eclipse.ui.help.IWorkbenchHelpSystem;
+
+/**
+ * A wizard page allowing the entry of the default table generation 
+ * properties (Java classes package, base class, etc).
+ * These properties apply to all tables unless explicitly overridden (in the table generation page).
+ * 
+ * @author Danny Ju
+ */
+@SuppressWarnings("restriction")
+public class DefaultTableGenerationWizardPage extends NewTypeWizardPage {
+
+	private JpaProject jpaProject;
+
+	/*the instance used to get/set the default properties.*/
+	private ORMGenTable defaultsTable;
+
+	private ORMGenCustomizer customizer;
+	
+	private TableGenPanel defaultTableGenPanel ;
+
+	protected DefaultTableGenerationWizardPage(JpaProject jpaProject) {
+		super(true, "DefaultTableGenerationWizardPage"); //$NON-NLS-1$
+		this.jpaProject = jpaProject;
+		setTitle(JptUiEntityGenMessages.GenerateEntitiesWizard_defaultTablePage_title);
+		setDescription( JptUiEntityGenMessages.GenerateEntitiesWizard_defaultTablePage_desc);
+	}
+	
+	
+	// -------- Initialization ---------
+	/**
+	 * The wizard owning this page is responsible for calling this method with the
+	 * current selection. The selection is used to initialize the fields of the wizard 
+	 * page.
+	 * 
+	 * @param selection used to initialize the fields
+	 */
+	void init(IStructuredSelection selection) {
+		IJavaElement jelem = null;
+		if ( selection!=null && selection.getFirstElement() instanceof IJavaElement ) {
+			jelem = (IJavaElement) selection.getFirstElement();
+		}else{
+			jelem = this.jpaProject.getJavaProject();			
+		}
+		if( jelem !=null ){
+			initContainerPage(jelem);
+			initTypePage(jelem);
+		}
+		
+	}
+	
+	public void createControl(Composite parent) {
+		initializeDialogUnits(parent);
+		Composite composite = new Composite(parent, SWT.NULL);
+		int nColumns= 4		;
+		GridLayout layout = new GridLayout();
+		layout.numColumns = nColumns;
+		composite.setLayout(layout);
+		this.getHelpSystem().setHelp(composite, JpaHelpContextIds.GENERATE_ENTITIES_WIZARD_CUSTOMIZE_DEFAULT_ENTITY_GENERATION);
+
+		//Create entity access, collection type, etc 
+		defaultTableGenPanel = new TableGenPanel(composite, 4, true, this);
+		
+		createDomainJavaClassesPropertiesGroup(composite, 4);
+		setControl(composite);
+
+		
+		this.setPageComplete( true );
+	}
+
+	@Override
+	public void setVisible(boolean visible) {
+		super.setVisible(visible);
+		if (visible) {
+			ORMGenCustomizer customizer = getCustomizer();
+			//If user changed the connection or schema
+			if ( this.customizer != customizer ) {
+				this.customizer = customizer; 
+				defaultsTable=customizer.createGenTable(null);
+				defaultTableGenPanel.setORMGenTable(defaultsTable);
+				//set the super class and implemented interfaces value
+				String baseClass = defaultsTable.getExtends() == null ?"" : defaultsTable.getExtends();
+				setSuperClass(baseClass, true);
+				setSuperInterfaces(defaultsTable.getImplements(), true);
+				IPackageFragmentRoot root = getSourceFolder( defaultsTable.getSourceFolder());
+				String initPackageName = this.getPackageText();
+				if( initPackageName.length()==0 ){
+					setPackageName( root, defaultsTable.getPackage() );
+				}
+				setPackageFragmentRoot(root, true/*canBeModified*/);
+			}
+		}
+	}
+	
+	//search for the source folder with the given name or return the first
+	//source folder if not found.
+	private IPackageFragmentRoot getSourceFolder(String srcFolder) {
+		IPackageFragmentRoot packageFragmentRoot = null;
+		srcFolder = '/' + srcFolder;
+		IJavaProject javaProject = this.jpaProject.getJavaProject();
+
+		for (IPackageFragmentRoot root : JDTTools.getJavaSourceFolders(javaProject)) {
+			//Save the first source root in case we don't find one that matches the saved value
+			if (packageFragmentRoot == null) {
+				packageFragmentRoot = root;
+			}
+			//check for alternative source root that matches the saved value
+			if (root.getPath().toString().equals(srcFolder)){
+				packageFragmentRoot = root;
+				break;
+			}
+		}
+		return packageFragmentRoot;
+	}
+	
+	private void setPackageName(IPackageFragmentRoot packageFragmentRoot, String packageName) {
+		if( packageName == null || packageName.length() == 0 || packageFragmentRoot==null) {
+			return;
+		}
+		IPackageFragment packageFragment = packageFragmentRoot.getPackageFragment(packageName);
+		setPackageFragment(packageFragment, true/*canBeModified*/);
+	}
+
+
+	protected void createDomainJavaClassesPropertiesGroup(Composite composite, int columns) {
+		Group parent = new Group( composite, SWT.NONE);
+		parent.setText( JptUiEntityGenMessages.GenerateEntitiesWizard_defaultTablePage_domainJavaClass);
+		parent.setLayout(new GridLayout( columns, false));
+		GridData layoutData = new GridData();
+		layoutData.horizontalSpan = columns;
+		layoutData.verticalAlignment = SWT.FILL;
+		layoutData.horizontalAlignment = SWT.FILL;
+		layoutData.grabExcessHorizontalSpace = true;
+		layoutData.grabExcessVerticalSpace = true;
+		parent.setLayoutData(layoutData);
+		
+		//default Java package name only available for default table generation
+		createContainerControls(parent, columns);
+		createPackageControls(parent, columns);
+		createSuperClassControls(parent, columns);
+		createSuperInterfacesControls(parent, columns);
+	}
+	
+	@Override
+	protected IStatus packageChanged() {
+		IStatus status = super.packageChanged(); 
+		IPackageFragment packageFragment = getPackageFragment();
+		//String srcFolder = packageFragment.getPath().toPortableString();
+		if (defaultsTable != null && !status.matches(IStatus.ERROR)) {
+			defaultsTable.setPackage(packageFragment.getElementName());
+		}
+		return status;
+	}	
+
+	@Override
+	protected IStatus superClassChanged() {
+		IStatus status = super.superClassChanged();
+		String baseClass = getSuperClass();
+		if (baseClass != null && defaultsTable != null && !status.matches(IStatus.ERROR)) {
+			String oldBaseClass = defaultsTable.getExtends();
+			if ( !baseClass.equals(oldBaseClass)) {
+				defaultsTable.setExtends(baseClass);
+			}
+		}
+		return status; 
+	}	
+	@Override
+	protected IStatus containerChanged() {
+		IStatus status = super.containerChanged();
+		String srcFolder = getPackageFragmentRootText();
+		if( !status.matches(IStatus.ERROR) ){
+			if (defaultsTable != null ) {
+				defaultsTable.setSourceFolder( srcFolder );
+			}
+		}
+		return status;
+	}
+
+	/** Override to allow select source folder in current project only
+	 * @see org.eclipse.jdt.ui.wizards.NewContainerWizardPage#chooseContainer()
+	 */
+	@Override
+	protected IPackageFragmentRoot chooseContainer() {
+		Class<?>[] acceptedClasses = new Class[] { IPackageFragmentRoot.class, IJavaProject.class };
+		TypedElementSelectionValidator validator= new TypedElementSelectionValidator(acceptedClasses, false) {
+			@Override
+			public boolean isSelectedValid(Object element) {
+				try {
+					if (element instanceof IJavaProject) {
+						IJavaProject jproject= (IJavaProject)element;
+						IPath path= jproject.getProject().getFullPath();
+						return (jproject.findPackageFragmentRoot(path) != null);
+					} else if (element instanceof IPackageFragmentRoot) {
+						return JDTTools.packageFragmentRootIsSourceFolder((IPackageFragmentRoot) element);
+					}
+					return true;
+				} catch (JavaModelException e) {
+					JptUiPlugin.log(e); // just log, no UI in validation
+				}
+				return false;
+			}
+		};
+
+		acceptedClasses= new Class[] { IJavaModel.class, IPackageFragmentRoot.class, IJavaProject.class };
+		ViewerFilter filter= new TypedViewerFilter(acceptedClasses) {
+			@Override
+			public boolean select(Viewer viewer, Object parent, Object element) {
+				if (element instanceof IPackageFragmentRoot) {
+					return JDTTools.packageFragmentRootIsSourceFolder((IPackageFragmentRoot) element);
+				}
+				return super.select(viewer, parent, element);
+			}
+		};
+
+		StandardJavaElementContentProvider provider= new StandardJavaElementContentProvider();
+		ILabelProvider labelProvider= new JavaElementLabelProvider(JavaElementLabelProvider.SHOW_DEFAULT);
+		ElementTreeSelectionDialog dialog= new ElementTreeSelectionDialog(getShell(), labelProvider, provider);
+		dialog.setValidator(validator);
+		dialog.setComparator(new JavaElementComparator());
+		dialog.setTitle(NewWizardMessages.NewContainerWizardPage_ChooseSourceContainerDialog_title);
+		dialog.setMessage(NewWizardMessages.NewContainerWizardPage_ChooseSourceContainerDialog_description);
+		dialog.addFilter(filter);
+		dialog.setInput(jpaProject.getJavaProject());
+		dialog.setInitialSelection(getPackageFragmentRoot());
+		dialog.setHelpAvailable(false);
+
+		if (dialog.open() == Window.OK) {
+			Object element= dialog.getFirstResult();
+			if (element instanceof IJavaProject) {
+				IJavaProject jproject= (IJavaProject)element;
+				return jproject.getPackageFragmentRoot(jproject.getProject());
+			} else if (element instanceof IPackageFragmentRoot) {
+				return (IPackageFragmentRoot)element;
+			}
+			return null;
+		}
+		return null;
+	}
+	
+	@Override
+	protected void handleFieldChanged(String fieldName) {
+		super.handleFieldChanged(fieldName);
+		if (this.fContainerStatus.matches(IStatus.ERROR)) {
+			updateStatus(fContainerStatus);
+		}else if( ! this.fPackageStatus.matches(IStatus.OK) ) {
+			updateStatus(fPackageStatus);
+		} else if (this.fSuperClassStatus.matches(IStatus.ERROR)) {
+			updateStatus(fSuperClassStatus);
+		} else {
+			updateStatus(Status.OK_STATUS);
+		}
+	}
+	
+	@Override
+	@SuppressWarnings({ "unchecked", "rawtypes" })
+	protected IStatus superInterfacesChanged() {
+		IStatus ret = super.superInterfacesChanged();
+		if ( ret.isOK() ) {
+			List interfaces = getSuperInterfaces();
+			if(defaultsTable!=null)
+				defaultsTable.setImplements(interfaces);
+		}
+		return ret;
+	}	
+
+	private ORMGenCustomizer getCustomizer() {
+		GenerateEntitiesFromSchemaWizard wizard = (GenerateEntitiesFromSchemaWizard) this.getWizard();
+		return wizard.getCustomizer();
+	}	
+
+    @Override
+    public final void performHelp() {
+        this.getHelpSystem().displayHelp( GenerateEntitiesFromSchemaWizard.HELP_CONTEXT_ID );
+    }
+    
+	protected final IWorkbenchHelpSystem getHelpSystem() {
+		return PlatformUI.getWorkbench().getHelpSystem();
+	}
+}
+
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/gen/GenerateEntitiesFromSchemaWizard.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/gen/GenerateEntitiesFromSchemaWizard.java
new file mode 100644
index 0000000..e4f3b5e
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/gen/GenerateEntitiesFromSchemaWizard.java
@@ -0,0 +1,545 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 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.ui.internal.wizards.gen;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IResourceRuleFactory;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.resources.WorkspaceJob;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.OperationCanceledException;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.preferences.IEclipsePreferences;
+import org.eclipse.core.runtime.preferences.InstanceScope;
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.IPackageFragment;
+import org.eclipse.jdt.core.IPackageFragmentRoot;
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.resource.JFaceResources;
+import org.eclipse.jface.resource.LocalResourceManager;
+import org.eclipse.jface.resource.ResourceManager;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.window.Window;
+import org.eclipse.jface.wizard.IWizardPage;
+import org.eclipse.jface.wizard.Wizard;
+import org.eclipse.jpt.core.EntityGeneratorDatabaseAnnotationNameBuilder;
+import org.eclipse.jpt.core.JpaPlatform;
+import org.eclipse.jpt.core.JpaProject;
+import org.eclipse.jpt.core.JptCorePlugin;
+import org.eclipse.jpt.core.internal.utility.jdt.JDTTools;
+import org.eclipse.jpt.db.Column;
+import org.eclipse.jpt.db.ConnectionProfile;
+import org.eclipse.jpt.db.ForeignKey;
+import org.eclipse.jpt.db.Schema;
+import org.eclipse.jpt.db.Table;
+import org.eclipse.jpt.gen.internal.BaseEntityGenCustomizer;
+import org.eclipse.jpt.gen.internal.DatabaseAnnotationNameBuilder;
+import org.eclipse.jpt.gen.internal.ORMGenCustomizer;
+import org.eclipse.jpt.gen.internal.ORMGenTable;
+import org.eclipse.jpt.gen.internal.PackageGenerator;
+import org.eclipse.jpt.ui.JptUiPlugin;
+import org.eclipse.jpt.ui.internal.JptUiIcons;
+import org.eclipse.jpt.ui.internal.JptUiMessages;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.INewWizard;
+import org.eclipse.ui.IWorkbench;
+
+public class GenerateEntitiesFromSchemaWizard extends Wizard 
+	implements INewWizard  {	
+	
+	public static final String HELP_CONTEXT_ID = JptUiPlugin.PLUGIN_ID + ".GenerateEntitiesFromSchemaWizard"; //$NON-NLS-1$
+
+	private static final String DONT_SHOW_OVERWRITE_WARNING_DIALOG = "DONT_SHOW_OVERWRITE_WARNING_DIALOG"; //$NON-NLS-1$
+
+	private JpaProject jpaProject;
+
+	private IStructuredSelection selection;
+
+	private ORMGenCustomizer customizer = null;	
+
+	private PromptJPAProjectWizardPage projectPage;	
+
+	private TablesSelectorWizardPage tablesSelectorPage;
+
+	private TableAssociationsWizardPage tableAssociationsPage;
+	
+	private DefaultTableGenerationWizardPage defaultTableGenerationPage;
+	
+	private TablesAndColumnsCustomizationWizardPage tablesAndColumnsCustomizationPage;
+	
+	protected final ResourceManager resourceManager;
+	
+	public GenerateEntitiesFromSchemaWizard() {
+		this.resourceManager = new LocalResourceManager(JFaceResources.getResources());
+		this.setWindowTitle( JptUiEntityGenMessages.GenerateEntitiesWizard_generateEntities);
+	}
+	
+	public GenerateEntitiesFromSchemaWizard( JpaProject jpaProject, IStructuredSelection selection) {
+		super();
+		this.jpaProject = jpaProject;
+		this.selection = selection;
+		this.resourceManager = new LocalResourceManager(JFaceResources.getResources());
+		this.setWindowTitle( JptUiEntityGenMessages.GenerateEntitiesWizard_generateEntities);
+		this.setDefaultPageImageDescriptor(JptUiPlugin.getImageDescriptor(JptUiIcons.ENTITY_WIZ_BANNER));
+	}
+	
+	@Override
+	public void addPages() {
+		setForcePreviousAndNextButtons(true);
+		
+		//If this.jpaProject is not initialized because user didn't select a JPA project
+		if( this.jpaProject == null ){
+			this.projectPage = new PromptJPAProjectWizardPage(HELP_CONTEXT_ID);
+			this.addPage(this.projectPage);
+			return;
+		}
+		addMainPages();
+	}
+
+	private void addMainPages() {
+		this.tablesSelectorPage = new TablesSelectorWizardPage(this.jpaProject, this.resourceManager);
+		this.addPage(this.tablesSelectorPage);
+		
+		this.tableAssociationsPage = new TableAssociationsWizardPage(this.jpaProject, this.resourceManager);
+		this.addPage(this.tableAssociationsPage);
+
+		this.defaultTableGenerationPage = new DefaultTableGenerationWizardPage(this.jpaProject);
+		this.addPage(this.defaultTableGenerationPage);
+		this.defaultTableGenerationPage.init(this.selection);
+		
+		this.tablesAndColumnsCustomizationPage = new TablesAndColumnsCustomizationWizardPage(this.jpaProject, this.resourceManager);
+		this.addPage(this.tablesAndColumnsCustomizationPage);
+		this.tablesAndColumnsCustomizationPage.init(this.selection);		
+	}
+	
+	public ORMGenCustomizer getORMGenCustomizer(){
+		return this.customizer;
+	}
+
+	/**
+	 * Create the ORMGenCustomizer when user selects a new connection profile and schema 
+	 * 
+	 * JpaPlatform implementor can provide a custom ORMGenCustomizer specific to a platform
+	 * with AdapterFactory through Eclipse org.eclipse.core.runtime.adapters extension point:
+	 * <pre> 
+	 *  
+	 *<extension
+     *    point="org.eclipse.core.runtime.adapters">
+     * <factory
+     *       adaptableType="org.eclipse.jpt.eclipselink.core.internal.EclipseLinkPlatform"
+     *       class="oracle.eclipse.tools.orm.internal.EclipseLinkORMGenCustomizerAdapterFactory">
+     *    <adapter
+     *          type="oracle.eclipse.tools.orm.internal.ORMGenCustomizer">
+     *    </adapter>
+     * </factory>
+     *</extension>
+	 *</pre> 
+	 * 
+	 * @param schema 
+	 */
+	public ORMGenCustomizer createORMGenCustomizer(Schema schema){
+		JpaPlatform jpaPlatform = this.jpaProject.getJpaPlatform();
+		Object obj = Platform.getAdapterManager().getAdapter( jpaPlatform, ORMGenCustomizer.class );
+		if (obj != null  && obj instanceof ORMGenCustomizer) {
+			this.customizer = (ORMGenCustomizer) obj; 
+			this.customizer.init(getCustomizationFile(), schema);  
+		} else{
+			this.customizer = new BaseEntityGenCustomizer( );
+			this.customizer.init(getCustomizationFile(), schema);  
+		}
+
+		ORMGenTable newDefaultTable = getCustomizer().createGenTable(null);
+		if ( selection!=null && selection.getFirstElement() instanceof IPackageFragment ) {
+			IPackageFragment packageFrag = (IPackageFragment)selection.getFirstElement();
+			newDefaultTable.setPackage( packageFrag.getElementName() );
+			for (IPackageFragmentRoot root : JDTTools.getJavaSourceFolders(this.jpaProject.getJavaProject())) {
+				String srcFolder = root.getPath().toPortableString();
+				if( packageFrag.getPath().toPortableString().startsWith( srcFolder +'/' )){
+					newDefaultTable.setSourceFolder(srcFolder.substring(1));
+				}
+			}
+		}		
+		return this.customizer;
+	} 
+	
+	protected String getCustomizationFileName() {
+		ConnectionProfile profile = getProjectConnectionProfile();
+		String connection = profile == null ? "" : profile.getName();
+		String name = "org.eclipse.jpt.entitygen." + (connection == null ? "" :connection.replace(' ', '-'));  //$NON-NLS-1$
+		Schema schema = getDefaultSchema();
+		if ( schema!= null  ) {
+			name += "." + schema.getName();//$NON-NLS-1$
+		}
+		return name.toLowerCase();
+	}
+	
+	/**
+	 * Returns the nodes state file. 
+	 */
+	private File getCustomizationFile() {
+		String projectPath = this.jpaProject.getProject().getLocation().toPortableString();
+		File genDir = new File(projectPath + "/.settings");//$NON-NLS-1$
+        genDir.mkdirs();
+		return new File(genDir, getCustomizationFileName());
+	}
+
+	@Override
+	public boolean performFinish() {
+		if (this.jpaProject == null) {
+			return true;
+		}
+		try {
+			this.customizer.setDatabaseAnnotationNameBuilder( buildDatabaseAnnotationNameBuilder() );
+			this.customizer.save();
+		} catch (IOException e) {
+			JptUiPlugin.log(e);
+		}
+		if (shouldShowOverwriteWarning()) {
+			PackageGenerator.setOverwriteConfirmer(new OverwriteConfirmer());
+		}
+		
+		WorkspaceJob genEntitiesJob = new GenerateEntitiesJob(this.jpaProject, getCustomizer());
+		genEntitiesJob.schedule();
+		return true;
+	}
+	
+	// ********** generate entities job **********
+
+	static class GenerateEntitiesJob extends WorkspaceJob {
+		JpaProject jpaProject;
+		ORMGenCustomizer customizer;
+		GenerateEntitiesJob(JpaProject jpaProject, ORMGenCustomizer customizer) {
+			super(JptUiMessages.EntitiesGenerator_jobName);
+			this.customizer = customizer;
+			this.jpaProject = jpaProject ;
+			IResourceRuleFactory ruleFactory = ResourcesPlugin.getWorkspace().getRuleFactory();
+			this.setRule(ruleFactory.modifyRule(jpaProject.getProject()));
+		}
+
+		@Override
+		public IStatus runInWorkspace(IProgressMonitor monitor) throws CoreException {
+			try{
+				PackageGenerator.generate(this.jpaProject,this.customizer, monitor);
+			}catch(OperationCanceledException e){
+				//user canceled generation
+			}
+			return Status.OK_STATUS;
+		}
+
+	}	
+    public static boolean shouldShowOverwriteWarning(){
+    	IEclipsePreferences pref = new InstanceScope().getNode(JptUiPlugin.PLUGIN_ID); 
+    	boolean ret = ! pref.getBoolean( DONT_SHOW_OVERWRITE_WARNING_DIALOG, false) ;
+    	return ret;
+    }
+    
+    // ********** overwrite confirmer **********
+
+	static class OverwriteConfirmer implements org.eclipse.jpt.gen.internal.OverwriteConfirmer {
+		private boolean overwriteAll = false;
+		private boolean skipAll = false;
+
+		OverwriteConfirmer() {
+		}
+
+		public boolean overwrite(final String className) {
+			if (this.overwriteAll) {
+				return true;
+			}
+			if (this.skipAll) {
+				return false;
+			}
+			return this.promptUser(className);
+		}
+
+		private boolean promptUser(final String className) {
+			// get on the UI thread synchronously, need feedback before continuing
+			final boolean ret[]=new boolean[1];
+			Display.getDefault().syncExec(new Runnable() {
+				public void run() {
+					final OverwriteConfirmerDialog dialog = new OverwriteConfirmerDialog(Display.getCurrent().getActiveShell(), className);
+					dialog.open();
+					if (dialog.getReturnCode() == Window.CANCEL) {
+						//throw new OperationCanceledException();
+						skipAll = true;
+						ret[0] = false;
+						return;
+					}
+					if (dialog.yes()) {
+						ret[0] = true;
+					}
+					if (dialog.yesToAll()) {
+						overwriteAll = true;
+						ret[0] = true;
+					}
+					if (dialog.no()) {
+						ret[0] = false;
+					}
+					if (dialog.noToAll()) {
+						skipAll = true;
+						ret[0] = false;
+					}
+				}
+			});
+			return ret[0];
+		}
+
+	}
+
+
+	// ********** overwrite dialog **********
+
+	static class OverwriteConfirmerDialog extends Dialog {
+		private final String className;
+		private boolean yes = false;
+		private boolean yesToAll = false;
+		private boolean no = false;
+		private boolean noToAll = false;
+
+		OverwriteConfirmerDialog(Shell parent, String className) {
+			super(parent);
+			this.className = className;
+		}
+
+		@Override
+		protected void configureShell(Shell shell) {
+			super.configureShell(shell);
+			shell.setText(JptUiMessages.OverwriteConfirmerDialog_title);
+		}
+
+		@Override
+		protected Control createDialogArea(Composite parent) {
+			Composite composite = (Composite) super.createDialogArea(parent);
+			GridLayout gridLayout = (GridLayout) composite.getLayout();
+			gridLayout.numColumns = 1;
+
+			Label text = new Label(composite, SWT.LEFT);
+			text.setText(NLS.bind(JptUiMessages.OverwriteConfirmerDialog_text, this.className));
+			text.setLayoutData(new GridData());
+			
+			createDontShowControl(composite);
+			
+			return composite;
+		}
+	    
+	    protected Control createDontShowControl(Composite composite) {
+	    	final Button checkbox = new Button( composite, SWT.CHECK );
+	    	checkbox.setText( JptUiEntityGenMessages.GenerateEntitiesWizard_doNotShowWarning );
+	    	checkbox.setSelection(false);
+	    	final IEclipsePreferences pref = new InstanceScope().getNode( JptUiPlugin.PLUGIN_ID); 
+	    	checkbox.setLayoutData( new GridData(GridData.FILL_BOTH) );
+	    	checkbox.addSelectionListener(new SelectionListener (){
+	    		public void widgetDefaultSelected(SelectionEvent e) {}
+				public void widgetSelected(SelectionEvent e) {
+					boolean b = checkbox.getSelection();
+	                pref.putBoolean( DONT_SHOW_OVERWRITE_WARNING_DIALOG, b);
+				}
+	    	});
+	    	return checkbox;
+	    }
+	    
+		@Override
+		protected void createButtonsForButtonBar(Composite parent) {
+			this.createButton(parent, IDialogConstants.YES_ID, IDialogConstants.YES_LABEL, false);
+			this.createButton(parent, IDialogConstants.YES_TO_ALL_ID, IDialogConstants.YES_TO_ALL_LABEL, false);
+			this.createButton(parent, IDialogConstants.NO_ID, IDialogConstants.NO_LABEL, true);
+			this.createButton(parent, IDialogConstants.NO_TO_ALL_ID, IDialogConstants.NO_TO_ALL_LABEL, false);
+			this.createButton(parent, IDialogConstants.CANCEL_ID, IDialogConstants.CANCEL_LABEL, false);
+		}
+
+		@Override
+		protected void buttonPressed(int buttonId) {
+			switch (buttonId) {
+				case IDialogConstants.YES_ID :
+					this.yesPressed();
+					break;
+				case IDialogConstants.YES_TO_ALL_ID :
+					this.yesToAllPressed();
+					break;
+				case IDialogConstants.NO_ID :
+					this.noPressed();
+					break;
+				case IDialogConstants.NO_TO_ALL_ID :
+					this.noToAllPressed();
+					break;
+				case IDialogConstants.CANCEL_ID :
+					this.cancelPressed();
+					break;
+				default :
+					break;
+			}
+		}
+
+		private void yesPressed() {
+			this.yes = true;
+			this.setReturnCode(OK);
+			this.close();
+		}
+
+		private void yesToAllPressed() {
+			this.yesToAll = true;
+			this.setReturnCode(OK);
+			this.close();
+		}
+
+		private void noPressed() {
+			this.no = true;
+			this.setReturnCode(OK);
+			this.close();
+		}
+
+		private void noToAllPressed() {
+			this.noToAll = true;
+			this.setReturnCode(OK);
+			this.close();
+		}
+
+		boolean yes() {
+			return this.yes;
+		}
+
+		boolean yesToAll() {
+			return this.yesToAll;
+		}
+
+		boolean no() {
+			return this.no;
+		}
+
+		boolean noToAll() {
+			return this.noToAll;
+		}
+	}
+
+
+	private DatabaseAnnotationNameBuilder buildDatabaseAnnotationNameBuilder() {
+		return new LocalDatabaseAnnotationNameBuilder(this.jpaProject.getJpaPlatform().getEntityGeneratorDatabaseAnnotationNameBuilder());
+	}
+
+	// ********** name builder adapter **********
+
+	/**
+	 * adapt the JPA platform-supplied builder to the builder interface
+	 * expected by the entity generator
+	 */
+	static class LocalDatabaseAnnotationNameBuilder implements DatabaseAnnotationNameBuilder {
+		private EntityGeneratorDatabaseAnnotationNameBuilder builder;
+		LocalDatabaseAnnotationNameBuilder(EntityGeneratorDatabaseAnnotationNameBuilder builder) {
+			super();
+			this.builder = builder;
+		}
+		public String buildTableAnnotationName(String entityName, Table table) {
+			return this.builder.buildTableAnnotationName(entityName, table);
+		}
+		public String buildColumnAnnotationName(String attributeName, Column column) {
+			return this.builder.buildColumnAnnotationName(attributeName, column);
+		}
+		public String buildJoinColumnAnnotationName(String attributeName, ForeignKey foreignKey) {
+			return this.builder.buildJoinColumnAnnotationName(attributeName, foreignKey);
+		}
+		public String buildJoinColumnAnnotationName(Column column) {
+			return this.builder.buildJoinColumnAnnotationName(column);
+		}
+		public String buildJoinTableAnnotationName(Table table) {
+			return this.builder.buildJoinTableAnnotationName(table);
+		}
+	}
+	
+	@Override
+    public IWizardPage getStartingPage() {
+		if (this.projectPage != null) {
+			if (this.tablesSelectorPage != null) {
+				return this.tablesSelectorPage;
+			}
+			return this.projectPage;
+		}
+		return super.getStartingPage();
+    }
+	
+	public ORMGenCustomizer getCustomizer (){
+		return customizer;
+	} 
+//	Collection<Table> getPossibleTables() {
+//		if ( this.tablesSelectorPage != null) {
+//			return this.tablesSelectorPage.getTables();
+//		}
+//		return ( this.projectDefaultSchemaExists()) ? CollectionTools.collection( this.getDefaultSchema().tables()) : Collections.<Table>emptyList();
+//	}
+	
+	public ConnectionProfile getProjectConnectionProfile() {
+		return this.jpaProject.getConnectionProfile();
+	}
+	
+	public JpaProject getJpaProject(){
+		return this.jpaProject;
+	}
+	
+	public void setJpaProject(JpaProject jpaProject) {
+		if (this.jpaProject == null) {
+			this.jpaProject = jpaProject;
+			IWizardPage currentPage = getContainer().getCurrentPage();
+			if (this.projectPage != null && currentPage.equals(this.projectPage)) {
+				addMainPages();
+			}
+		}
+	}
+
+	public Schema getDefaultSchema() {
+		return getJpaProject().getDefaultDbSchema();
+	}
+
+	public void init(IWorkbench workbench, IStructuredSelection selection) {
+		Object sel = selection.getFirstElement();
+		if ( sel instanceof IResource ) {
+			IProject proj = ((IResource) sel).getProject();
+			JpaProject jpaProj = JptCorePlugin.getJpaProject(proj);
+			this.jpaProject = jpaProj;
+		} else if( sel instanceof org.eclipse.jdt.core.IPackageFragmentRoot ) {
+			org.eclipse.jdt.core.IPackageFragmentRoot root = (org.eclipse.jdt.core.IPackageFragmentRoot) sel;
+			IProject proj = root.getJavaProject().getProject();
+			JpaProject jpaProj = JptCorePlugin.getJpaProject(proj);
+			this.jpaProject = jpaProj;
+		} else if( sel instanceof org.eclipse.jdt.core.IPackageFragment) {
+			org.eclipse.jdt.core.IPackageFragment frag = (org.eclipse.jdt.core.IPackageFragment) sel;
+			IProject proj = frag.getJavaProject().getProject();
+			JpaProject jpaProj = JptCorePlugin.getJpaProject(proj);
+			this.jpaProject = jpaProj;
+		}
+		
+		this.selection = selection;
+		this.setWindowTitle(JptUiEntityGenMessages.GenerateEntitiesWizard_generateEntities);
+	}
+
+	@Override
+	public void dispose() {
+		this.resourceManager.dispose();
+		super.dispose();
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/gen/JoinColumnsPage.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/gen/JoinColumnsPage.java
new file mode 100644
index 0000000..ec3ce3a
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/gen/JoinColumnsPage.java
@@ -0,0 +1,629 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 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.ui.internal.wizards.gen;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.TreeMap;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.jface.dialogs.IPageChangedListener;
+import org.eclipse.jface.dialogs.PageChangedEvent;
+import org.eclipse.jface.viewers.ColumnWeightData;
+import org.eclipse.jface.viewers.ComboBoxCellEditor;
+import org.eclipse.jface.viewers.IBaseLabelProvider;
+import org.eclipse.jface.viewers.ICellModifier;
+import org.eclipse.jface.viewers.IContentProvider;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.IStructuredContentProvider;
+import org.eclipse.jface.viewers.ITableLabelProvider;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.jface.viewers.TableViewer;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerSorter;
+import org.eclipse.jface.wizard.WizardDialog;
+import org.eclipse.jpt.db.Column;
+import org.eclipse.jpt.db.Schema;
+import org.eclipse.jpt.db.Table;
+import org.eclipse.jpt.gen.internal.Association;
+import org.eclipse.jpt.gen.internal.ORMGenCustomizer;
+import org.eclipse.jpt.ui.internal.JpaHelpContextIds;
+import org.eclipse.jpt.ui.internal.util.SWTUtil;
+import org.eclipse.jpt.ui.internal.util.TableLayoutComposite;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.TableColumn;
+import org.eclipse.swt.widgets.TableItem;
+
+
+public class JoinColumnsPage extends NewAssociationWizardPage {
+
+	private Label joinColumnsDescLabel1;
+	/*the table containing the association columns between table1 and table2
+	 * , or table1 and join table if many to many*/
+	private TableViewer joinColumnsTable1;
+	private ArrayList<SimpleJoin> tableDataModel1 = new ArrayList<SimpleJoin>();  
+	private Composite tablesGroup1;
+	
+	private Label joinColumnsDescLabel2;
+	/*the table containing the association columns between join table and table2
+	 * if many to many*/
+	private TableViewer joinColumnsTable2;
+	private ArrayList<SimpleJoin> tableDataModel2 = new ArrayList<SimpleJoin>();  
+	private Composite tablesGroup2;
+	
+	static final String[] JOINCOLUMNS_TABLE_COLUMN_PROPERTIES = { "referrerColumn", "referencedColumn" };
+	
+	private static final int JOINCOLUMN1_COLUMN_INDEX = 0;
+	private static final int JOINCOLUMN2_COLUMN_INDEX = 1;
+
+	protected JoinColumnsPage(ORMGenCustomizer customizer ) {
+		super(customizer, "JoinColumnsPage");
+		setTitle( JptUiEntityGenMessages.GenerateEntitiesWizard_newAssoc_colsPage_title);
+		setDescription(JptUiEntityGenMessages.GenerateEntitiesWizard_newAssoc_colsPage_desc);
+	}
+
+	public void createControl(Composite parent) {
+		initializeDialogUnits(parent);
+		
+		Composite composite = new Composite(parent, SWT.NONE);
+		GridLayout layout = new GridLayout();
+		layout.numColumns = 1;
+		composite.setLayout(layout);
+		this.getHelpSystem().setHelp(composite, JpaHelpContextIds.GENERATE_ENTITIES_WIZARD_JOIN_COLUMNS);
+
+		tablesGroup1 = new Composite(composite, SWT.SHADOW_ETCHED_IN);
+		tablesGroup1.setLayoutData(new GridData());
+		tablesGroup1.setLayout(new GridLayout(2, false));
+		createJoinColumnsTableControl1(tablesGroup1);
+
+		//createMtmJoinColumnsTable2(composite);
+		
+		setControl(composite);
+		this.setPageComplete( false);
+		
+		((WizardDialog)getContainer()).addPageChangedListener(new IPageChangedListener(){
+			public void pageChanged(PageChangedEvent event) {
+				if( event.getSelectedPage() == JoinColumnsPage.this ){
+					((Composite)JoinColumnsPage.this.getControl()).getParent().layout() ;		
+					
+				}
+			}			
+		});
+	}
+
+	private void createMtmJoinColumnsTable2(Composite composite) {
+		tablesGroup2 = new Composite(composite, SWT.SHADOW_ETCHED_IN);
+		tablesGroup2.setLayoutData(new GridData());
+		tablesGroup2.setLayout(new GridLayout(2, false));
+		createJoinColumnsTableControl2(tablesGroup2);
+	}
+
+	/**
+	 * Update wizard page UI with new table names
+	 */
+	@Override
+	public void updateWithNewTables() {
+		String cardinality = this.getCardinality() ;
+		if( Association.MANY_TO_MANY.equals( cardinality ) ){
+			updateWithMtmTables();
+		}else{
+			updateWithOtmTables();
+		}
+	}
+
+	/**
+	 * Update Wizard UI with a single TableViewer with columns from the two associated database tables
+	 */
+	public void updateWithOtmTables() {
+		TableColumn[] columns = joinColumnsTable1.getTable().getColumns();
+		String table1Name = this.getReferrerTableName() ;
+		String table2Name = this.getReferencedTableName() ;
+		
+		if( table1Name ==null || table2Name == null )
+			return;
+		
+		columns[0].setText( table1Name );
+		columns[1].setText( table2Name );
+
+		//Hide the Join column table 2
+		if( tablesGroup2 !=null )
+			tablesGroup2.setVisible(false);
+		
+		tableDataModel1.clear();
+		joinColumnsTable1.refresh();
+		
+		String msg = String.format(JptUiEntityGenMessages.GenerateEntitiesWizard_newAssoc_colsPage_label, table1Name, table2Name); 
+		joinColumnsDescLabel1.setText(msg);
+		joinColumnsDescLabel1.setToolTipText( msg );
+		tablesGroup1.layout();
+		
+		String[] referrerColumnValues = getTableColumns(table1Name);
+		String[] referencedColumnValues = getTableColumns(table2Name);
+		
+		updateCellEditors(joinColumnsTable1, referrerColumnValues, referencedColumnValues);		
+
+		
+		((Composite)this.getControl()).layout() ;
+	}
+
+	/**
+	 * Update Wizard UI with a two TableViewers with the first with columns from table1 to the MTM join table
+	 * and the second one with columns from the MTM join table to table2
+	 */
+	public void updateWithMtmTables() {
+		TableColumn[] columns = joinColumnsTable1.getTable().getColumns();
+		String table1Name = this.getReferrerTableName() ;
+		String table2Name = this.getReferencedTableName() ;
+		String joinTableName = this.getJoinTableName() ;
+		if( table1Name==null || table2Name==null || joinTableName==null ){
+			return;
+		}
+		if( tablesGroup2 == null ){
+			createMtmJoinColumnsTable2( tablesGroup1.getParent());
+		} 
+
+		columns[0].setText( table1Name==null?"":table1Name );
+		columns[1].setText( table2Name==null?"":joinTableName );
+		
+		//Update join column TableViewer 1
+		tableDataModel1.clear();
+		joinColumnsTable1.refresh();
+		
+		String msg = String.format(JptUiEntityGenMessages.GenerateEntitiesWizard_newAssoc_colsPage_label, table1Name, joinTableName); 
+		joinColumnsDescLabel1.setText(msg);
+		joinColumnsDescLabel1.setToolTipText( msg );
+		String[] referrerColumnValues = getTableColumns(table1Name);
+		String[] referencedColumnValues = getTableColumns(joinTableName);
+		
+		updateCellEditors(joinColumnsTable1, referrerColumnValues, referencedColumnValues );
+
+		//Update join column TableViewer 2
+		columns = joinColumnsTable2.getTable().getColumns();
+		columns[0].setText( joinTableName==null?"":joinTableName );
+		columns[1].setText( table2Name==null?"":table2Name );
+		tablesGroup1.layout();
+
+		tableDataModel2.clear();
+		joinColumnsTable2.refresh();
+		msg = String.format(JptUiEntityGenMessages.GenerateEntitiesWizard_newAssoc_colsPage_label, joinTableName, table2Name); 
+		joinColumnsDescLabel2.setText(msg);
+		joinColumnsDescLabel2.setToolTipText( msg );
+		referrerColumnValues = getTableColumns(joinTableName);
+		referencedColumnValues = getTableColumns(table2Name);
+		updateCellEditors(joinColumnsTable2, referrerColumnValues, referencedColumnValues );
+		
+		tablesGroup2.layout();
+
+		//Show the Join column TableViewer 2
+		tablesGroup2.setVisible(true);
+		
+		
+		((Composite)this.getControl()).layout(new Control[]{this.tablesGroup1, this.tablesGroup2});		
+	}
+	
+	
+	private void createAddRemoveButtonComposite(Composite tablesGroup, final TableViewer joinColumnsTable,  final ArrayList<SimpleJoin> tableDataModel) {
+		//Add and Remove JoinColumns buttons
+		Composite buttonComposite = new Composite(tablesGroup, SWT.NULL);
+		GridLayout buttonLayout = new GridLayout(1, false);
+		buttonComposite.setLayout(buttonLayout);
+		GridData data =  new GridData();
+		data.horizontalAlignment = GridData.FILL;
+		data.verticalAlignment = GridData.BEGINNING;
+		buttonComposite.setLayoutData(data);
+		
+		Button addButton = new Button(buttonComposite, SWT.PUSH);
+		addButton.setText( JptUiEntityGenMessages.add );
+		GridData gridData =  new GridData();
+		gridData.horizontalAlignment = GridData.FILL;
+		addButton.setLayoutData(gridData);
+		addButton.addSelectionListener(new SelectionListener() {
+			public void widgetDefaultSelected(SelectionEvent e) {}
+		
+			@SuppressWarnings("unchecked")
+			public void widgetSelected(SelectionEvent e) {
+				
+				SimpleJoin join = getDefaultNewJoin(joinColumnsTable);
+				tableDataModel.add(join);
+				joinColumnsTable.refresh();
+				
+				//Update Wizard model
+				TreeMap<String, String> joins = null;
+				if( joinColumnsTable == joinColumnsTable1 ){
+					joins = (TreeMap<String, String>)getWizardDataModel().get(NewAssociationWizard.ASSOCIATION_JOIN_COLUMNS1 );
+				}else{
+					joins = (TreeMap<String, String>)getWizardDataModel().get(NewAssociationWizard.ASSOCIATION_JOIN_COLUMNS2 );
+				}
+				joins.put( join.foreignKey, join.primaryKey);
+				
+				updatePageComplete();
+			}
+		});
+		
+		Button removeButton = new Button(buttonComposite, SWT.PUSH);
+		removeButton.setText( JptUiEntityGenMessages.remove );
+		gridData =  new GridData();
+		gridData.horizontalAlignment = GridData.FILL;
+		removeButton.setLayoutData(gridData);
+		removeButton.addSelectionListener(new SelectionListener() {
+			public void widgetDefaultSelected(SelectionEvent e) {}
+		
+			@SuppressWarnings("unchecked")
+			public void widgetSelected(SelectionEvent e) {
+				StructuredSelection selection = (StructuredSelection)joinColumnsTable.getSelection();
+				if( selection.isEmpty())
+					return;
+				SimpleJoin join = (SimpleJoin)selection.getFirstElement();
+
+				//Update TableViewer model
+				tableDataModel.remove( join );
+				//Update Wizard model
+				
+				TreeMap<String, String> joins = null;
+				if( joinColumnsTable == joinColumnsTable1 ){
+					joins = (TreeMap<String, String>)getWizardDataModel().get(NewAssociationWizard.ASSOCIATION_JOIN_COLUMNS1 );
+				}else{
+					joins = (TreeMap<String, String>)getWizardDataModel().get(NewAssociationWizard.ASSOCIATION_JOIN_COLUMNS2 );
+				}
+				joins.remove(join.foreignKey);
+
+				joinColumnsTable.refresh();
+			}
+		});
+		
+		addButton.setFocus();
+		
+	}
+
+	protected SimpleJoin getDefaultNewJoin(TableViewer joinColumnsTable) {
+		String table1Name = "";
+		String table2Name = "";
+
+		TreeMap<String, String> existingJoins = null;
+		if( joinColumnsTable == this.joinColumnsTable1 ){
+			existingJoins = (TreeMap<String, String>)getWizardDataModel().get(NewAssociationWizard.ASSOCIATION_JOIN_COLUMNS1 );
+			if( this.getJoinTableName() == null) {
+				table1Name = this.getReferrerTableName();
+				table2Name = this.getReferencedTableName() ;
+			}else{
+				table1Name = this.getReferrerTableName();
+				table2Name = this.getJoinTableName()  ;
+			}
+		}else{
+			existingJoins = (TreeMap<String, String>)getWizardDataModel().get(NewAssociationWizard.ASSOCIATION_JOIN_COLUMNS2 );
+			table1Name = this.getJoinTableName();
+			table2Name = this.getReferencedTableName() ;
+		}
+		//find next available column
+		String[] table1ColumnValues = getTableColumns(table1Name);
+		String nextCol1 = "";
+		for( String s: table1ColumnValues ){
+			if( !existingJoins.keySet().contains(s)){
+				nextCol1 = s;
+				break;
+			}
+		}
+		
+		String[] table2ColumnValues = getTableColumns(table2Name);
+		String nextCol2 = "";
+		for( String s: table2ColumnValues ){
+			if( !existingJoins.values().contains(s)){
+				nextCol2 = s;
+				break;
+			}
+		}
+		return new SimpleJoin( nextCol1, nextCol2);
+	}
+
+	@Override
+	public boolean canFlipToNextPage() {
+		return isPageComplete();
+	}
+	
+	public void updatePageComplete() {
+		boolean ret = tableDataModel1.size()> 0 ;
+		setPageComplete( ret );
+	}	
+	
+	private Label createLabel(Composite container, int span, String text) {
+		Label label = new Label(container, SWT.NONE);
+		label.setText(text);
+		GridData gd = new GridData();
+		gd.horizontalSpan = span;
+		label.setLayoutData(gd);
+		return label;
+	}
+
+	private void createJoinColumnsTableControl1(Composite tablesGroup) {
+		joinColumnsDescLabel1 = createLabel(tablesGroup, 2, JptUiEntityGenMessages.GenerateEntitiesWizard_newAssoc_colsPage_label );
+		joinColumnsTable1 = createJoinColumnsTableControl(tablesGroup, this.tableDataModel1);
+		createAddRemoveButtonComposite(tablesGroup, joinColumnsTable1, tableDataModel1);
+	}
+	
+	private void createJoinColumnsTableControl2(Composite tablesGroup) {
+		joinColumnsDescLabel2 = createLabel(tablesGroup, 2, JptUiEntityGenMessages.GenerateEntitiesWizard_newAssoc_colsPage_label );
+		joinColumnsTable2 = createJoinColumnsTableControl(tablesGroup, this.tableDataModel2);
+		createAddRemoveButtonComposite(tablesGroup, joinColumnsTable2, tableDataModel2);
+	}
+	
+	private TableViewer createJoinColumnsTableControl(Composite parent, ArrayList<SimpleJoin> tableDataModel ){	
+	
+		TableLayoutComposite layout= new TableLayoutComposite(parent, SWT.NONE);
+		addColumnLayoutData(layout);
+		
+		final org.eclipse.swt.widgets.Table table = new org.eclipse.swt.widgets.Table(layout, SWT.H_SCROLL | SWT.V_SCROLL | SWT.SINGLE | SWT.FULL_SELECTION | SWT.BORDER );
+		table.setHeaderVisible(true);
+		table.setLinesVisible(true);
+		
+		TableColumn referrerColumn = new TableColumn(table, SWT.NONE, JOINCOLUMN1_COLUMN_INDEX);
+		referrerColumn.setText("%table1");
+		referrerColumn.setResizable(true);
+
+		TableColumn referencedColumn = new TableColumn(table, SWT.NONE, JOINCOLUMN2_COLUMN_INDEX);
+		referencedColumn.setText("%table2");
+		referencedColumn.setResizable(true);
+		
+		GridData gd= new GridData(GridData.FILL_BOTH);
+		gd.heightHint= SWTUtil.getTableHeightHint(table, 3);
+		gd.widthHint = 300;
+		layout.setLayoutData(gd);
+
+		TableViewer newJoinColumnsTable = new TableViewer(table);
+		newJoinColumnsTable.setUseHashlookup(true);
+		newJoinColumnsTable.setLabelProvider(this.buildTableTableLabelProvider());
+		newJoinColumnsTable.setContentProvider(this.buildTableTableContentProvider());
+		newJoinColumnsTable.setSorter(new ViewerSorter() {
+			@Override
+			public int compare(Viewer viewer, Object e1, Object e2) {
+				return ((SimpleJoin) e1).foreignKey.compareTo(((SimpleJoin) e2).foreignKey);
+			}
+		});
+		
+		newJoinColumnsTable.addPostSelectionChangedListener(new ISelectionChangedListener() {
+			public void selectionChanged(SelectionChangedEvent event) {
+				//handleTablesListSelectionChanged(event);
+			}
+		});
+		populateTableDataModel();
+		newJoinColumnsTable.setInput( tableDataModel );
+		return newJoinColumnsTable;
+	}
+
+	@SuppressWarnings("unchecked")
+	public void populateTableDataModel(){
+		HashMap<String, Object> dataModel = getWizardDataModel();
+		TreeMap<String, String> joinColumns = (TreeMap<String, String>)dataModel.get(NewAssociationWizard.ASSOCIATION_JOIN_COLUMNS1);
+		if( joinColumns!= null ){
+			for( String referrerColumn : joinColumns.keySet() ){
+				tableDataModel1.add(new SimpleJoin(referrerColumn, joinColumns.get(referrerColumn) ));
+			}
+		}
+		
+		TreeMap<String, String> joinColumns2 = (TreeMap<String, String>)dataModel.get(NewAssociationWizard.ASSOCIATION_JOIN_COLUMNS2);
+		if( joinColumns2!= null ){
+			for( String referrerColumn : joinColumns2.keySet() ){
+				tableDataModel2.add(new SimpleJoin(referrerColumn, joinColumns2.get(referrerColumn) ));
+			}
+		}
+		
+	}
+	
+	private IContentProvider buildTableTableContentProvider() {
+		return new JoinColumnsContentProvider();
+	}
+
+	
+	private IBaseLabelProvider buildTableTableLabelProvider() {
+		return new JoinColumnsTableLabelProvider();
+	}
+	
+	
+	private void addColumnLayoutData(TableLayoutComposite layout) {
+		layout.addColumnData(new ColumnWeightData(50, true));
+		layout.addColumnData(new ColumnWeightData(50, true));
+	}
+	
+	
+	private void updateCellEditors(TableViewer joinColumnsTable, String[] referrerColumnValues, String[] referencedColumnValues ){
+		joinColumnsTable.setColumnProperties(JOINCOLUMNS_TABLE_COLUMN_PROPERTIES);
+		ComboBoxCellEditor[] editors = new ComboBoxCellEditor[JOINCOLUMNS_TABLE_COLUMN_PROPERTIES.length];
+
+		editors[JOINCOLUMN1_COLUMN_INDEX]= new ComboBoxCellEditor(joinColumnsTable.getTable(), referrerColumnValues, SWT.SINGLE);
+		editors[JOINCOLUMN2_COLUMN_INDEX]= new ComboBoxCellEditor(joinColumnsTable.getTable(), referencedColumnValues, SWT.SINGLE);
+		
+		joinColumnsTable.setCellEditors(editors);
+		joinColumnsTable.setCellModifier(this.buildTableTableCellModifier(joinColumnsTable, referrerColumnValues, referencedColumnValues ));
+	}
+
+	public String[] getTableColumns(String tableName){
+		Schema schema = (Schema)getWizardDataModel().get(NewAssociationWizard.ASSOCIATION_SCHEMA);
+		Table table = schema.getTableNamed(tableName);
+		List<String> list = new ArrayList<String>();
+		for (Column column : table.getColumns()) {
+			list.add(column.getName());
+		}
+		String[] ret = new String[list.size()];
+		list.toArray(ret);
+		return ret;
+	}
+	
+	private ICellModifier buildTableTableCellModifier(TableViewer joinColumnsTable, String[] referrerColumnValues, String[] referencedColumnValues) {
+		return new JoinColumnsCellModifier(joinColumnsTable, referrerColumnValues, referencedColumnValues);
+	}	
+	
+	/**
+	 * A ContentProvider translates the SimpleJoin list into a Collection for display 
+	 *
+	 */
+	private class JoinColumnsContentProvider implements IStructuredContentProvider {
+
+		JoinColumnsContentProvider() {
+			super();
+		}
+
+		public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {}	
+		public void dispose() {}
+		public Object[] getElements(Object inputElement) {
+			return ((Collection<?>) inputElement).toArray();
+		}
+	}
+	
+	/**
+	 * Simple value object used as model backing the JFace table 
+	 *
+	 */
+	private class SimpleJoin {
+		public SimpleJoin(String foreignKey, String primaryKey) {
+			this.foreignKey = foreignKey;
+			this.primaryKey = primaryKey; 
+		}
+		public String foreignKey;
+		public String primaryKey;
+		
+		@Override
+		public String toString(){
+			return "["+ this.foreignKey + " = " + this.primaryKey + "]";
+		}
+	}
+	
+	/**
+	 *	A CellModifier to update the join columns in the wizard data model
+	 */
+	private class JoinColumnsCellModifier implements ICellModifier {
+		private TableViewer joinColumnsTable;
+		private String[] referrerColumnValues;
+		private String[] referencedColumnValues;
+		JoinColumnsCellModifier(TableViewer joinColumnsTable, String[] referrerColumnValues, String[] referencedColumnValues) {
+			super();
+			this.joinColumnsTable = joinColumnsTable;
+			this.referrerColumnValues = referrerColumnValues;
+			this.referencedColumnValues = referencedColumnValues;
+		}
+
+		public boolean canModify(Object element, String property) {
+			return true;
+		}
+
+		@SuppressWarnings("unchecked")
+		public Object getValue(Object element, String property) {
+//			SimpleJoin join = (SimpleJoin) element;
+//			if (property.equals(JOINCOLUMNS_TABLE_COLUMN_PROPERTIES[JOINCOLUMN2_COLUMN_INDEX])) {
+//				return join.primaryKey;
+//			}
+//			return join.foreignKey;
+			// returnt the index of the value in the ComboxCellEditor
+			ArrayList<SimpleJoin> tableDataModel = (ArrayList<SimpleJoin>) joinColumnsTable.getInput();
+			for(int i=0; i< tableDataModel.size(); i ++ ){
+				if( tableDataModel.get(i) == element )
+					return new Integer(i);
+			}
+			return new Integer(0);
+			
+		}
+
+		/** 
+		 * element is the selected TableItem
+		 * value is the selected item index in the comboCellEditor 
+		 */
+		@SuppressWarnings("unchecked")
+		public void modify(Object element, String property, Object value) {
+			if ( ! (element instanceof TableItem)) {
+				return;
+			}
+			Integer index = (Integer)value;
+			TableItem item = (TableItem)element;
+			boolean unchanged = false;
+			SimpleJoin join = (SimpleJoin) item.getData();
+			if (property.equals(JOINCOLUMNS_TABLE_COLUMN_PROPERTIES[JOINCOLUMN1_COLUMN_INDEX])) {
+				unchanged = join.foreignKey.equals( referrerColumnValues[ index.intValue() ] );
+				if (! unchanged) {
+					
+					//update the wizard datamodel
+					TreeMap<String, String> joins = null;
+					if( joinColumnsTable == joinColumnsTable1 ){
+						joins = (TreeMap<String, String>)getWizardDataModel().get(NewAssociationWizard.ASSOCIATION_JOIN_COLUMNS1 );
+					}else{
+						joins = (TreeMap<String, String>)getWizardDataModel().get(NewAssociationWizard.ASSOCIATION_JOIN_COLUMNS2 );
+					}
+					joins.remove(join.foreignKey);
+					joins.put(referrerColumnValues[ index.intValue() ], join.primaryKey);
+
+					//Update the TableViewer model
+					join.foreignKey = referrerColumnValues[ index.intValue()];
+					joinColumnsTable.refresh();
+				}
+				return;
+			}
+			
+			if (property.equals(JOINCOLUMNS_TABLE_COLUMN_PROPERTIES[JOINCOLUMN2_COLUMN_INDEX])) {
+				unchanged = join.primaryKey.equals( referencedColumnValues[ index.intValue()] ) ;
+				if (! unchanged) {
+					//Update the TableViewer model
+					join.primaryKey = referencedColumnValues[ index.intValue()] ;
+					
+					//Update wizard data model
+					TreeMap<String, String> joins = null;
+					if( joinColumnsTable == joinColumnsTable1 ){
+						joins = (TreeMap<String, String>)getWizardDataModel().get(NewAssociationWizard.ASSOCIATION_JOIN_COLUMNS1 );
+					}else{
+						joins = (TreeMap<String, String>)getWizardDataModel().get(NewAssociationWizard.ASSOCIATION_JOIN_COLUMNS2 );
+					}
+					joins.put(join.foreignKey, join.primaryKey);
+
+					joinColumnsTable.refresh();
+				}
+			}
+			
+			
+		}
+
+	}
+
+	/**
+	 * A table label provider to return the join column names for display
+	 *
+	 */
+	private final class JoinColumnsTableLabelProvider extends LabelProvider implements ITableLabelProvider {
+		public Image getColumnImage(Object element, int columnIndex) {
+			return null;
+		}
+		public String getColumnText(Object element, int columnIndex) {
+			if( !(element instanceof SimpleJoin) )
+				return null;
+			switch (columnIndex) {
+	            case 0:
+	            	return ((SimpleJoin)element).foreignKey;
+	            case 1:
+	            	return ((SimpleJoin)element).primaryKey;
+	            default:
+	            	Assert.isTrue(false);
+	            	return null;
+            }
+		}
+		@Override
+		public String getText(Object element) {
+		    return getColumnText(element, 0); // needed to make the sorter work
+		}
+	}
+	
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/gen/JptUiEntityGenMessages.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/gen/JptUiEntityGenMessages.java
new file mode 100644
index 0000000..f3103f7
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/gen/JptUiEntityGenMessages.java
@@ -0,0 +1,123 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 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.ui.internal.wizards.gen;
+
+import org.eclipse.osgi.util.NLS;
+
+/**
+ * Localized messages used by Dali UI.
+ *
+ * @version 2.0
+ * @since 2.0
+ */
+public class JptUiEntityGenMessages {
+	private static final String BUNDLE_NAME = "jpt_ui_entity_gen"; //$NON-NLS-1$
+	private static final Class<?> BUNDLE_CLASS = JptUiEntityGenMessages.class;
+	
+	public static String GenerateEntitiesWizard_tableSelectPage_Restore_Defaults;
+	public static String GenerateEntitiesWizard_generateEntities;
+	public static String GenerateEntitiesWizard_doNotShowWarning;
+	public static String GenerateEntitiesWizard_selectJPAProject;
+	public static String GenerateEntitiesWizard_selectJPAProject_msg;
+	public static String GenerateEntitiesWizard_tableSelectPage_selectTable;
+	public static String GenerateEntitiesWizard_tableSelectPage_chooseEntityTable;
+	public static String GenerateEntitiesWizard_tableSelectPage_updatePersistenceXml;
+	public static String GenerateEntitiesWizard_tableSelectPage_tables;
+	public static String GenerateEntitiesWizard_tableSelectPage_tableColumn;
+	//Database connection group
+	public static String connection;
+	public static String addConnectionLink;
+	public static String connectLink;
+	public static String schemaInfo;
+	public static String schema;
+	public static String connectingToDatabase;
+	
+	//Default table gen properties
+	public static String GenerateEntitiesWizard_defaultTablePage_title;
+	public static String GenerateEntitiesWizard_defaultTablePage_desc;
+	public static String GenerateEntitiesWizard_defaultTablePage_domainJavaClass;
+	public static String GenerateEntitiesWizard_defaultTablePage_tableMapping;
+	public static String GenerateEntitiesWizard_tablePanel_className;
+	public static String GenerateEntitiesWizard_defaultTablePage_fetch;
+	public static String GenerateEntitiesWizard_defaultTablePage_collType;
+	public static String GenerateEntitiesWizard_defaultTablePage_sequence;
+	public static String GenerateEntitiesWizard_defaultTablePage_sequenceNote;
+	public static String GenerateEntitiesWizard_defaultTablePage_access;
+	public static String GenerateEntitiesWizard_defaultTablePage_keyGen;
+	public static String GenerateEntitiesWizard_defaultTablePage_genOptionalAnnotations;
+	public static String GenerateEntitiesWizard_defaultTablePage_genOptionalAnnotations_desc;
+	
+	//Asso figure
+	public static String manyToOneDesc;
+	public static String oneToOneDesc;
+	public static String manyToManyDesc;
+	//table association wizard page
+	public static String GenerateEntitiesWizard_assocPage_title;
+	public static String GenerateEntitiesWizard_assocPage_desc;
+	public static String GenerateEntitiesWizard_assocPage_label;
+	public static String GenerateEntitiesWizard_assocPage_newAssoc;
+	public static String GenerateEntitiesWizard_assocPage_delAssoc;
+	public static String GenerateEntitiesWizard_assocEditor_genAssoc;
+	public static String GenerateEntitiesWizard_assocEditor_entityRef;
+	public static String property;
+	public static String cascade;
+	public static String GenerateEntitiesWizard_assocEditor_setRef;
+	public static String GenerateEntitiesWizard_assocEditor_joinedWhen;
+	public static String GenerateEntitiesWizard_assocEditor_tableJoin;
+	public static String cardinality;
+	public static String selectCascadeDlgTitle;
+	//new association wizard
+	public static String GenerateEntitiesWizard_newAssoc_title;
+	public static String GenerateEntitiesWizard_newAssoc_tablesPage_title;
+	public static String GenerateEntitiesWizard_newAssoc_tablesPage_desc;
+	public static String GenerateEntitiesWizard_newAssoc_tablesPage_assocKind;
+	public static String GenerateEntitiesWizard_newAssoc_tablesPage_simpleAssoc;
+	public static String GenerateEntitiesWizard_newAssoc_tablesPage_m2mAssoc;
+	public static String GenerateEntitiesWizard_newAssoc_tablesPage_assocTables;
+	public static String GenerateEntitiesWizard_newAssoc_tablesPage_table1;
+	public static String GenerateEntitiesWizard_newAssoc_tablesPage_table2;
+	public static String GenerateEntitiesWizard_newAssoc_tablesPage_intermediateTable;
+	public static String GenerateEntitiesWizard_newAssoc_colsPage_title;
+	public static String GenerateEntitiesWizard_newAssoc_colsPage_desc;
+	public static String GenerateEntitiesWizard_newAssoc_colsPage_label;
+	public static String add;
+	public static String remove;
+	public static String GenerateEntitiesWizard_newAssoc_cardinalityPage_title;
+	public static String GenerateEntitiesWizard_newAssoc_cardinalityPage_desc;
+	public static String manyToOne;
+	public static String oneToMany;
+	public static String oneToOne;
+	public static String manyToMany;
+	//select table dialog
+	public static String selectTableDlgTitle;
+	public static String selectTableDlgDesc;
+	//individual table and column gen properties
+	public static String GenerateEntitiesWizard_tablesAndColumnsPage_title;
+	public static String GenerateEntitiesWizard_tablesAndColumnsPage_desc;
+	public static String GenerateEntitiesWizard_tablesAndColumnsPage_labelTableAndColumns;
+	public static String GenerateEntitiesWizard_colPanel_genProp;
+	public static String GenerateEntitiesWizard_colPanel_colMapping;
+	public static String GenerateEntitiesWizard_colPanel_propName;
+	public static String GenerateEntitiesWizard_colPanel_propType;
+	public static String GenerateEntitiesWizard_colPanel_mapKind;
+	public static String GenerateEntitiesWizard_colPanel_colUpdateable;
+	public static String GenerateEntitiesWizard_colPanel_colInsertable;
+	public static String GenerateEntitiesWizard_colPanel_beanProp;
+	public static String GenerateEntitiesWizard_colPanel_getterScope;
+	public static String GenerateEntitiesWizard_colPanel_setterScope;
+	static {
+		NLS.initializeMessages(BUNDLE_NAME, BUNDLE_CLASS);
+	}
+
+	private JptUiEntityGenMessages() {
+		throw new UnsupportedOperationException();
+	}
+
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/gen/NewAssociationWizard.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/gen/NewAssociationWizard.java
new file mode 100644
index 0000000..891433a
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/gen/NewAssociationWizard.java
@@ -0,0 +1,199 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 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.ui.internal.wizards.gen;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.TreeMap;
+
+import org.eclipse.jface.resource.ResourceManager;
+import org.eclipse.jface.wizard.IWizardPage;
+import org.eclipse.jface.wizard.Wizard;
+import org.eclipse.jpt.core.JpaProject;
+import org.eclipse.jpt.gen.internal.Association;
+import org.eclipse.jpt.gen.internal.ORMGenCustomizer;
+
+
+public class NewAssociationWizard extends Wizard {	
+
+	public static String ASSOCIATION_SCHEMA = "ASSOCIATION_SCHEMA"; //$NON-NLS-1$
+	public static String ASSOCIATION_REFERRER_TABLE = "ASSOCIATION_REFERRER_TABLE"; //$NON-NLS-1$
+	public static String ASSOCIATION_REFERENCED_TABLE = "ASSOCIATION_REFERENCED_TABLE"; //$NON-NLS-1$
+	public static String ASSOCIATION_JOIN_COLUMNS1 = "ASSOCIATION_REFERRER_COLUMNS1"; //$NON-NLS-1$
+	public static String ASSOCIATION_JOIN_COLUMNS2 = "ASSOCIATION_REFERRER_COLUMNS2"; //used in MTM associations only //$NON-NLS-1$
+	public static String ASSOCIATION_JOIN_TABLE = "ASSOCIATION_JOIN_TABLE"; // TreeMap<String, String> //$NON-NLS-1$
+	public static String ASSOCIATION_CADINALITY = "ASSOCIATION_CADINALITY"; //$NON-NLS-1$
+	
+	private JpaProject jpaProject;
+	private HashMap<String, Object> associationDataModel = new HashMap<String, Object>();
+
+	private ORMGenCustomizer customizer = null;	
+	
+	private AssociationTablesPage associationTablesPage;
+	private JoinColumnsPage joinColumnsPage;
+	private CardinalityPage cardinalityPage;
+	
+	protected final ResourceManager resourceManager;
+
+	public NewAssociationWizard( JpaProject jpaProject, ORMGenCustomizer customizer, ResourceManager resourceManager) {
+		super();
+		this.jpaProject = jpaProject;
+		this.customizer = customizer;
+		this.resourceManager = resourceManager;
+		this.setWindowTitle( JptUiEntityGenMessages.GenerateEntitiesWizard_newAssoc_title);
+		
+		this.associationDataModel.put( NewAssociationWizard.ASSOCIATION_SCHEMA, this.customizer.getSchema());
+		this.associationDataModel.put( NewAssociationWizard.ASSOCIATION_JOIN_COLUMNS1, new TreeMap<String, String>());
+		this.associationDataModel.put( NewAssociationWizard.ASSOCIATION_JOIN_COLUMNS2, new TreeMap<String, String>());
+	}
+
+	@Override
+	public void addPages() {
+		super.addPages();
+		this.associationTablesPage = new AssociationTablesPage( customizer, this.resourceManager);
+		addPage(this.associationTablesPage);
+		
+		this.joinColumnsPage = new JoinColumnsPage(customizer);
+		addPage(this.joinColumnsPage);
+		
+		this.cardinalityPage = new CardinalityPage(customizer);
+		addPage(this.cardinalityPage);
+	}
+
+	@Override
+	public boolean performFinish() {
+		return true;
+	}
+	
+	public ORMGenCustomizer getCustomizer (){
+		return customizer;
+	} 
+	
+	public JpaProject getJpaProject(){
+		return this.jpaProject;
+	}
+
+//	public Schema getDefaultSchema() {
+//		return getJpaProject().getDefaultDbSchema();
+//	}
+//
+//	private boolean projectDefaultSchemaExists() {
+//		return ( this.getDefaultSchema() != null);
+//	}
+
+	public HashMap<String, Object> getDataModel(){
+		return this.associationDataModel;
+	}
+	
+	public void updateTableNames(){
+		IWizardPage[] pages = this.getPages();
+		for( IWizardPage page : pages){
+			((NewAssociationWizardPage)page).updateWithNewTables();
+		}
+	}
+	
+	@SuppressWarnings("unchecked")
+	public Association getNewAssociation(){
+		String referrerTableName =getReferrerTableName(); 
+		String referencedTableName = getReferencedTableName();
+		List<String> referrerColNames = new ArrayList<String>();
+		List<String> referencedColNames = new ArrayList<String>();
+		
+		String cardinality = (String)associationDataModel.get( NewAssociationWizard.ASSOCIATION_CADINALITY );
+		if( cardinality.equals(Association.MANY_TO_MANY) ){
+			return createManyToManyAssociation();
+		}
+		
+		Object value = associationDataModel.get( NewAssociationWizard.ASSOCIATION_JOIN_COLUMNS1);
+		if(value!=null){
+			TreeMap<String, String> joinColumns = (TreeMap<String, String>)value;		
+			for( String pk : joinColumns.keySet()){
+				referrerColNames.add(pk);
+				referencedColNames.add( joinColumns.get(pk));
+			}
+		}
+
+		/*if one-to-many then convert it to many-to-one to be consistent 
+		 * with the associations computed from the db foreign keys.
+		 * Don't see at this point how one-to-many would 
+		 * affect the generation.*/
+		if( cardinality.equals(Association.ONE_TO_MANY) ){
+			cardinality = Association.MANY_TO_ONE;
+			
+			String temp1 = referrerTableName;
+			referrerTableName = referencedTableName;
+			referencedTableName = temp1;
+			
+			List<String> temp2 = referrerColNames;
+			referrerColNames = referencedColNames;
+			referencedColNames = temp2;
+		}
+		
+		Association association = null;
+		association = new Association(this.customizer, referrerTableName, referrerColNames	, referencedTableName, referencedColNames);
+		association.setCardinality( cardinality );
+		association.setCustom(true);
+		return association;
+	}
+	
+	@SuppressWarnings("unchecked")
+	private Association createManyToManyAssociation() {
+		String referrerTableName =getReferrerTableName(); 
+		String joinTable = getJoinTableName();
+		String referencedTableName = getReferencedTableName();
+
+		List<String> referrerColNames = new ArrayList<String>();
+		List<String> referrerJoinColNames = new ArrayList<String>();
+		Object value = associationDataModel.get( NewAssociationWizard.ASSOCIATION_JOIN_COLUMNS1);
+		if(value!=null){
+			TreeMap<String, String> joinColumns = (TreeMap<String, String>)value;		
+			for( String pk : joinColumns.keySet()){
+				referrerColNames.add(pk);
+				referrerJoinColNames.add( joinColumns.get(pk));
+			}
+		}
+		
+		value = associationDataModel.get( NewAssociationWizard.ASSOCIATION_JOIN_COLUMNS2);
+		List<String> referencedColNames = new ArrayList<String>();
+		List<String> referencedJoinColNames = new ArrayList<String>();
+		if(value!=null){
+			TreeMap<String, String> joinColumns = (TreeMap<String, String>)value;		
+			for( String pk : joinColumns.keySet()){
+				referencedJoinColNames.add(pk);
+				referencedColNames.add( joinColumns.get(pk));
+			}
+		}
+
+		
+		Association association = null;
+		association = new Association(this.customizer, referrerTableName, referrerColNames, 
+				referencedTableName, referencedColNames, joinTable, referrerJoinColNames, referencedJoinColNames);
+		return association;
+	}
+
+	String getReferrerTableName(){
+		return (String)associationDataModel.get(NewAssociationWizard.ASSOCIATION_REFERRER_TABLE);
+	}
+
+	String getReferencedTableName(){
+		return (String)associationDataModel.get(NewAssociationWizard.ASSOCIATION_REFERENCED_TABLE);
+	}
+	
+	String getJoinTableName(){
+		return (String)associationDataModel.get(NewAssociationWizard.ASSOCIATION_JOIN_TABLE );
+	}
+	
+	String getCardinality(){
+		return (String)associationDataModel.get(NewAssociationWizard.ASSOCIATION_CADINALITY );
+	}
+	
+}
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/gen/NewAssociationWizardPage.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/gen/NewAssociationWizardPage.java
new file mode 100644
index 0000000..68c328a
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/gen/NewAssociationWizardPage.java
@@ -0,0 +1,60 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2009 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.ui.internal.wizards.gen;
+
+import java.util.HashMap;
+
+import org.eclipse.jface.wizard.WizardPage;
+import org.eclipse.jpt.gen.internal.ORMGenCustomizer;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.help.IWorkbenchHelpSystem;
+
+
+public abstract class NewAssociationWizardPage extends WizardPage {
+
+	protected ORMGenCustomizer customizer;
+	
+	public NewAssociationWizardPage(ORMGenCustomizer customizer, String name) {
+		super(name);
+		this.customizer = customizer ;
+	}
+	
+	protected HashMap<String, Object> getWizardDataModel(){
+		return ((NewAssociationWizard)this.getWizard()).getDataModel();
+	}
+	
+	protected String getReferrerTableName(){
+		return ((NewAssociationWizard)getWizard()).getReferrerTableName();
+	}
+
+	protected String getReferencedTableName(){
+		return ((NewAssociationWizard)getWizard()).getReferencedTableName();
+	}
+
+	protected String getJoinTableName(){
+		return ((NewAssociationWizard)getWizard()).getJoinTableName();
+	}
+
+	protected String getCardinality(){
+		return ((NewAssociationWizard)getWizard()).getCardinality() ;
+	}
+	
+	public void updateWithNewTables() {
+	}
+
+	/**
+	 * Returns the helps system.
+	 * @return The platform's help system
+	 */
+	protected final IWorkbenchHelpSystem getHelpSystem() {
+		return PlatformUI.getWorkbench().getHelpSystem();
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/gen/PromptJPAProjectWizardPage.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/gen/PromptJPAProjectWizardPage.java
new file mode 100644
index 0000000..c09c53d
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/gen/PromptJPAProjectWizardPage.java
@@ -0,0 +1,154 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2009 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.ui.internal.wizards.gen;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.jface.viewers.IStructuredContentProvider;
+import org.eclipse.jface.viewers.ITableLabelProvider;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.jface.viewers.TableViewer;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.wizard.WizardPage;
+import org.eclipse.jpt.core.JpaProject;
+import org.eclipse.jpt.core.JptCorePlugin;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.TableItem;
+import org.eclipse.ui.PlatformUI;
+
+public class PromptJPAProjectWizardPage extends WizardPage {
+
+	private static String SELECT_PROJECT_PAGE_NAME = "SelectJPAProject"; //$NON-NLS-1$
+	private Table projTable;
+	private TableViewer projTableViewer;
+	private static int PROJECT_NAME_COLUMN_INDEX = 0;
+	private final String helpContextId;
+	
+	protected PromptJPAProjectWizardPage( final String helpContextId ) {
+		super(SELECT_PROJECT_PAGE_NAME);
+		setTitle( JptUiEntityGenMessages.GenerateEntitiesWizard_selectJPAProject );
+		setMessage( JptUiEntityGenMessages.GenerateEntitiesWizard_selectJPAProject_msg );
+		this.helpContextId = helpContextId;
+	}
+
+	public void createControl(Composite parent) {
+		Composite composite = new Composite(parent, SWT.NULL);
+		int nColumns= 1;
+		GridLayout layout = new GridLayout();
+		layout.numColumns = nColumns;
+		composite.setLayout(layout);			
+		Label label = new Label( composite, SWT.NONE );
+		label.setText( JptUiEntityGenMessages.GenerateEntitiesWizard_selectJPAProject );
+		
+		projTableViewer = new TableViewer(composite, SWT.SINGLE | SWT.BORDER | SWT.V_SCROLL | SWT.VIRTUAL);		
+		projTable = projTableViewer.getTable();
+		GridData gd = new GridData( SWT.FILL, SWT.FILL, true, true );
+		projTable.setLayoutData(gd);
+				
+		projTable.addSelectionListener(new SelectionAdapter() {
+			public void widgetSelected(SelectionEvent e) {
+				handleJpaProjectSelection();
+			}
+
+			public void widgetDefaultSelected(SelectionEvent e) {
+				widgetSelected(e);
+			}
+			
+		});
+		
+		projTableViewer = new TableViewer(projTable);
+		projTableViewer.setLabelProvider(new ProjectTableLabelProvider());
+		projTableViewer.setContentProvider(new ProjectTableContentProvider());
+		fillJpaProjectList();
+		setControl( composite );
+		validate();
+	}
+	
+	private void handleJpaProjectSelection() {
+		if (projTable.getSelectionIndex() != -1) {
+			TableItem item =  projTable.getItem(projTable.getSelectionIndex());
+			String projName = item.getText(0);
+			IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(projName);
+			JpaProject jpaProj = JptCorePlugin.getJpaProject( project );
+			((GenerateEntitiesFromSchemaWizard)getWizard()).setJpaProject(jpaProj);
+			validate();
+		}
+	}
+	
+	private void fillJpaProjectList() {
+		IProject[] projects = ResourcesPlugin.getWorkspace().getRoot().getProjects();
+		List<String> projNames = new ArrayList<String>();
+		for ( IProject project : projects )
+		{
+			JpaProject jpaProj = JptCorePlugin.getJpaProject( project );
+			if ( jpaProj != null ) {
+				projNames.add(project.getName());
+			}
+		}
+		projTableViewer.setInput(projNames);
+	}
+	
+	private void validate() {
+		if (projTable.getSelectionIndex() != -1)
+			setPageComplete(true);
+		else
+			setPageComplete(false);
+	}
+	
+	@Override
+	public final void performHelp() 
+	{
+	    PlatformUI.getWorkbench().getHelpSystem().displayHelp( this.helpContextId );
+	}
+
+	// inner classes
+	private final class ProjectTableLabelProvider extends LabelProvider implements ITableLabelProvider {
+		public Image getColumnImage(Object element, int columnIndex)
+		{
+			if (columnIndex == PROJECT_NAME_COLUMN_INDEX)
+				return PlatformUI.getWorkbench().getSharedImages().getImage(org.eclipse.ui.ide.IDE.SharedImages.IMG_OBJ_PROJECT);
+			return null;
+		}
+
+		public String getColumnText(Object element, int columnIndex)
+		{
+			assert element instanceof String;
+			String projectName = (String)element;
+			if (columnIndex == PROJECT_NAME_COLUMN_INDEX)
+				return projectName;
+			return null;
+		}		
+	}
+	
+	private final class ProjectTableContentProvider implements IStructuredContentProvider
+	{
+		public Object[] getElements(Object inputElement){
+			return ((Collection<?>) inputElement).toArray();
+		}
+
+		public void dispose(){}
+
+		public void inputChanged(Viewer viewer, Object oldInput, Object newInput){}
+		
+	}
+}	
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/gen/SWTUtil.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/gen/SWTUtil.java
new file mode 100644
index 0000000..7e170d1
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/gen/SWTUtil.java
@@ -0,0 +1,133 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2009 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.ui.internal.wizards.gen;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Text;
+
+/**
+ * Collection of utility methods to create SWT UI
+ *
+ */
+public class SWTUtil {
+	/**
+	 * Set the layoutData of the input control to occupy specified number of columns
+	 * @param c
+	 * @param columns
+	 */
+	public static void fillColumns(Control c, int columns){
+		GridData layoutData = new GridData();
+		layoutData.horizontalSpan = columns;
+		layoutData.verticalAlignment = SWT.FILL;
+		layoutData.horizontalAlignment = SWT.FILL;
+		layoutData.grabExcessHorizontalSpace = true;
+		layoutData.grabExcessVerticalSpace = false;
+		c.setLayoutData(layoutData);
+		return ;
+	}
+
+	public static void fillColumnsWithIndent(Control c, int columns, int indent){
+		GridData layoutData = new GridData();
+		layoutData.horizontalSpan = columns;
+		layoutData.verticalAlignment = SWT.FILL;
+		layoutData.horizontalAlignment = SWT.FILL;
+		layoutData.grabExcessHorizontalSpace = true;
+		layoutData.grabExcessVerticalSpace = false;
+		layoutData.horizontalIndent = indent ;
+		c.setLayoutData(layoutData);
+		return ;
+	}
+	
+	public static Label createLabel(Composite container, int span, String text) {
+		Label label = new Label(container, SWT.NONE);
+		label.setText(text);
+		GridData gd = new GridData();
+		gd.horizontalSpan = span;
+		label.setLayoutData(gd);
+		return label;
+	}
+
+	/**
+	 * Create a new label which occupies one grid column
+	 * @param parent
+	 * @param text
+	 */
+	public static Label newLabel(Composite parent, String text) {
+		Label label = new Label( parent, SWT.NONE);
+		label.setText( text );
+		label.setLayoutData(new GridData());
+		return label;
+	}
+
+	/**
+	 * Create a new label which occupies one grid column
+	 * @param parent
+	 * @param text
+	 */
+	public static Label newLabelWithIndent(Composite parent, String text, int indent) {
+		Label label = new Label( parent, SWT.NONE);
+		label.setText( text );
+		GridData layoutData = new GridData();
+		layoutData.horizontalAlignment = SWT.BEGINNING;
+		layoutData.verticalAlignment = SWT.TOP ;
+		layoutData.horizontalIndent = indent ;
+		label.setLayoutData(layoutData);
+		return label;
+	}
+	
+	/**
+	 * Creates a separator line. Expects a <code>GridLayout</code> with at least 1 column.
+	 * 
+	 * @param composite the parent composite
+	 * @param nColumns number of columns to span
+	 */
+	@SuppressWarnings("restriction")
+	public static void createSeparator(Composite composite, int nColumns) {
+		(new org.eclipse.jdt.internal.ui.wizards.dialogfields.Separator(
+				SWT.SEPARATOR | SWT.HORIZONTAL)).doFillIntoGrid(composite, nColumns, 5);		
+	}
+
+	
+	public static Button createButton(Composite container, int span, String text, int style) {
+		Button btn = new Button(container, style);
+		btn.setText(text);
+		GridData gd = new GridData();
+		gd.horizontalSpan = span;
+		btn.setLayoutData(gd);
+		return btn;
+	}
+	
+	public static Combo createCombo(Composite container, int span ) {
+		Combo combo = new Combo(container, SWT.SINGLE | SWT.READ_ONLY);
+		GridData gd = new GridData();
+		gd.horizontalSpan = span;
+		gd.grabExcessHorizontalSpace=true;
+		gd.horizontalAlignment = SWT.FILL;
+		combo.setLayoutData(gd);
+		return combo;
+	}
+
+	public static Text createText(Composite container, int span ) {
+		Text text = new Text(container, SWT.BORDER);
+		GridData gd = new GridData();
+		gd.horizontalSpan = span;
+		gd.grabExcessHorizontalSpace=true;
+		gd.horizontalAlignment = SWT.FILL;
+		text.setLayoutData(gd);
+		return text;
+	}
+	
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/gen/SelectTableDialog.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/gen/SelectTableDialog.java
new file mode 100644
index 0000000..d06d641
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/gen/SelectTableDialog.java
@@ -0,0 +1,75 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 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.ui.internal.wizards.gen;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.jface.resource.ResourceManager;
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.jface.viewers.ILabelProviderListener;
+import org.eclipse.jpt.db.Schema;
+import org.eclipse.jpt.db.Table;
+import org.eclipse.jpt.ui.internal.ImageRepository;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.dialogs.ElementListSelectionDialog;
+
+/**
+ * A database table selection dialog which allows user to filter tables by name
+ */
+public class SelectTableDialog extends ElementListSelectionDialog {
+	
+	public SelectTableDialog(Shell shell, final ResourceManager resourceManager){
+		super(shell, new ILabelProvider(){
+			public Image getImage(Object element) {
+				return ImageRepository.getTableImage(resourceManager);
+			}
+
+			public String getText(Object element) {
+				return element.toString();
+			}
+			public void addListener(ILabelProviderListener listener) {}
+			public void dispose() {}
+
+			public boolean isLabelProperty(Object element, String property) {
+				return false;
+			}
+
+			public void removeListener(ILabelProviderListener listener) {}
+
+		});
+		this.setTitle( JptUiEntityGenMessages.selectTableDlgTitle );//
+		this.setMessage( JptUiEntityGenMessages.selectTableDlgDesc);//
+	}
+	
+	public SelectTableDialog(Shell shell, ResourceManager resourceManager, Schema schema){
+		this(shell, resourceManager);
+		
+		ArrayList<String> list = new ArrayList<String>();
+		for (Table table : schema.getTables()) {
+			list.add(table.getName());
+		}
+		this.setElements( list.toArray() );
+		
+	}
+	
+	public SelectTableDialog(Shell shell, ResourceManager resourceManager, List<String> tableNames){
+		this(shell, resourceManager);
+		this.setElements( tableNames.toArray() );
+	}
+	
+	public String getSelectedTable() {
+		String tableName = (String)this.getFirstResult();
+		return tableName ;
+	}
+	
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/gen/TableAssociationsWizardPage.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/gen/TableAssociationsWizardPage.java
new file mode 100644
index 0000000..ec0a4c0
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/gen/TableAssociationsWizardPage.java
@@ -0,0 +1,775 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 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.ui.internal.wizards.gen;
+
+
+import static org.eclipse.jpt.ui.internal.wizards.gen.SWTUtil.fillColumns;
+import static org.eclipse.jpt.ui.internal.wizards.gen.SWTUtil.newLabel;
+import static org.eclipse.jpt.ui.internal.wizards.gen.SWTUtil.newLabelWithIndent;
+
+import java.util.List;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jdt.core.JavaConventions;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jdt.internal.ui.dialogs.StatusUtil;
+import org.eclipse.jdt.internal.ui.wizards.dialogfields.DialogField;
+import org.eclipse.jdt.internal.ui.wizards.dialogfields.IStringButtonAdapter;
+import org.eclipse.jdt.internal.ui.wizards.dialogfields.LayoutUtil;
+import org.eclipse.jdt.internal.ui.wizards.dialogfields.StringButtonDialogField;
+import org.eclipse.jface.resource.ResourceManager;
+import org.eclipse.jface.window.Window;
+import org.eclipse.jface.wizard.WizardDialog;
+import org.eclipse.jface.wizard.WizardPage;
+import org.eclipse.jpt.core.JpaProject;
+import org.eclipse.jpt.gen.internal.Association;
+import org.eclipse.jpt.gen.internal.AssociationRole;
+import org.eclipse.jpt.gen.internal.ORMGenColumn;
+import org.eclipse.jpt.gen.internal.ORMGenCustomizer;
+import org.eclipse.jpt.ui.internal.ImageRepository;
+import org.eclipse.jpt.ui.internal.JpaHelpContextIds;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.StackLayout;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.layout.FillLayout;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.help.IWorkbenchHelpSystem;
+
+public class TableAssociationsWizardPage extends WizardPage {
+
+	private JpaProject jpaProject;
+	private ORMGenCustomizer customizer ;
+	
+	private AssociationsListComposite associationList; 
+	private Association selectedAssociation;
+	private Button deleteAssociationLink ;
+	private Button createAssociationLink ;
+	
+	//Controls in Association Edit Panel
+	private Composite associationsEditPanel ;
+	private Button generateAssociationCheckBox; 
+	private Label cardinalityLabel ;
+	private Combo cardinalityCombo ;
+	/*whether to generate the referrer-->referenced role.*/
+	private Button referrerRoleCheckBox; 
+	/*the name of the property in the referrer-->referenced role.*/
+	private Label referrerRolePropertyLabel;
+	private Text referrerRolePropertyField ;
+	/*the cascade in the referrer-->referenced role.*/
+	@SuppressWarnings("restriction")
+	private StringButtonDialogField referrerRoleCascadeField;
+	/*whether to generate the referenced->referrer role.*/
+	private Button referencedRoleCheckBox;
+	/*the name of the property in the referenced->referrer role.*/
+	private Label referencedRolePropertyLabel;
+	private Text referencedRolePropertyField ;
+	/*the cascade in the referenced->referrer role.*/
+	@SuppressWarnings("restriction")
+	private StringButtonDialogField referencedRoleCascadeField;
+	private Label joinConditionLabel;
+	private Text joinConditionText; 
+	
+	private Composite detailPanel;
+	private StackLayout detailPanelStatckLayout;
+	private Composite emptyPanel;
+	
+	protected final ResourceManager resourceManager;
+
+	protected TableAssociationsWizardPage(JpaProject jpaProject, ResourceManager resourceManager) {
+		super("Table Associations"); //$NON-NLS-1$
+		this.jpaProject = jpaProject;
+		this.resourceManager = resourceManager;
+		setTitle(JptUiEntityGenMessages.GenerateEntitiesWizard_assocPage_title);
+		setMessage(JptUiEntityGenMessages.GenerateEntitiesWizard_assocPage_desc);
+		
+	}
+
+	public void createControl(Composite parent) {
+		initializeDialogUnits(parent);
+		
+		Composite composite = new Composite(parent, SWT.NULL);
+		int nColumns= 2 ;
+		GridLayout layout = new GridLayout();
+		layout.numColumns = nColumns;
+		composite.setLayout(layout);
+		this.getHelpSystem().setHelp(composite, JpaHelpContextIds.GENERATE_ENTITIES_WIZARD_TABLE_ASSOCIATIONS);
+
+		Label label = new Label(composite, SWT.NONE);
+		label.setText( JptUiEntityGenMessages.GenerateEntitiesWizard_assocPage_label );
+		GridData gd = new GridData();
+		gd.horizontalSpan = 2;
+		label.setLayoutData( gd );
+		
+		createAssociationsListPanel(composite);
+		createAddDeleteButtons(composite, nColumns);
+		SWTUtil.createSeparator(composite, nColumns);
+		
+		createDetailPanel(composite);
+		setControl(composite);
+		
+		composite.layout(true);
+		this.setPageComplete( true);
+		
+	}
+
+	private void createAddDeleteButtons(Composite composite, int columns) {
+		
+		Composite c = new Composite( composite, SWT.NONE);
+		fillColumns(c, 1);
+		c.setLayout( new GridLayout(1,true) );
+		
+		createAssociationLink = new Button(c, SWT.NONE);
+		createAssociationLink.setToolTipText( JptUiEntityGenMessages.GenerateEntitiesWizard_assocPage_newAssoc );
+		createAssociationLink.setImage( ImageRepository.getAddButtonImage(this.resourceManager) );
+		createAssociationLink.addSelectionListener(new SelectionListener(){
+			public void widgetDefaultSelected(SelectionEvent e) {}	
+			public void widgetSelected(SelectionEvent e) {
+				launchNewAssociationsWizard();
+			}	
+			
+		});
+		
+		deleteAssociationLink = new Button(c, SWT.NONE);
+		Color foreground = new Color(Display.getDefault(), 0,0,255);
+		deleteAssociationLink.setForeground(foreground);
+		foreground.dispose();
+		deleteAssociationLink.setImage( ImageRepository.getDeleteButtonImage(this.resourceManager));
+		deleteAssociationLink.setToolTipText( JptUiEntityGenMessages.GenerateEntitiesWizard_assocPage_delAssoc );
+		deleteAssociationLink.addSelectionListener(new SelectionListener(){
+			public void widgetDefaultSelected(SelectionEvent e) {}	
+			public void widgetSelected(SelectionEvent e) {
+				Association association = associationList.getSelectedAssociation();
+				if( association != null ){
+					ORMGenCustomizer customizer = getCustomizer();
+					customizer.deleteAssociation(association);
+					List<Association> associations = customizer.getAssociations();
+					associationList.updateAssociations(associations);
+					if( associations.size()==0 ){
+						hideAssociationDetail();
+					}
+				}
+			}	
+		});
+		deleteAssociationLink.setEnabled(false);
+		
+	}
+
+	private void createGenerateAssociationCheckbox(Composite composite,  int columns) {
+		generateAssociationCheckBox = new Button(composite, SWT.CHECK);
+		generateAssociationCheckBox.setText( JptUiEntityGenMessages.GenerateEntitiesWizard_assocEditor_genAssoc);
+		generateAssociationCheckBox.addSelectionListener(new SelectionListener() {
+			public void widgetDefaultSelected(SelectionEvent e) {}
+		
+			public void widgetSelected(SelectionEvent e) {
+				Association association = associationList.getSelectedAssociation();
+				if( association == null )
+					return;
+				association.setGenerated(generateAssociationCheckBox.getSelection());
+				
+				updateAssociationEditPanel(association);
+				associationList.updateSelectedAssociation();
+			}
+
+		});
+
+		fillColumns(generateAssociationCheckBox, columns-1);
+		newLabel(composite, "");
+	}
+
+	@SuppressWarnings("restriction")
+	private void createGenerateReferrerRoleControls(Composite parent,  int columns) {
+		referrerRoleCheckBox = new Button(parent, SWT.CHECK);
+		referrerRoleCheckBox.setText( JptUiEntityGenMessages.GenerateEntitiesWizard_assocEditor_entityRef );
+		referrerRoleCheckBox.addSelectionListener(new SelectionListener() {
+			public void widgetDefaultSelected(SelectionEvent e) {}
+		
+			public void widgetSelected(SelectionEvent e) {
+				boolean generate = referrerRoleCheckBox.getSelection();
+				//referrerRolePropertyField.setEditable( generate );
+				referrerRolePropertyLabel.setEnabled( generate );
+				referrerRolePropertyField.setEnabled( generate );
+				referrerRoleCascadeField.setEnabled(generate);
+				
+				//If both referencedRoleCheckBox and referencedRoleCheckBox unchecked, 
+				//the association itself shouldn't be generated 
+				if( !generate && !referencedRoleCheckBox.getSelection()){
+					generateAssociationCheckBox.setSelection(false);
+					cardinalityLabel.setEnabled( false );
+					cardinalityCombo.setEnabled(false);
+					referrerRoleCheckBox.setEnabled(false);
+					referencedRoleCheckBox.setEnabled(false);
+				}
+				
+				directionalityCheckBoxChanged( );			
+				
+				if( generate ){
+					AssociationRole role = selectedAssociation.getReferrerRole();
+					referrerRolePropertyField.setText( role.getPropertyName() );
+				}
+			}
+
+		});
+
+		SWTUtil.fillColumnsWithIndent(referrerRoleCheckBox , columns-1, 20 );
+		newLabel(parent, "");//$NON-NLS-1$
+		
+		referrerRolePropertyLabel = newLabelWithIndent( parent,  JptUiEntityGenMessages.property, 40 );
+		referrerRolePropertyField = new Text( parent, SWT.BORDER);
+		fillColumns(referrerRolePropertyField, 2);
+		referrerRolePropertyField.addModifyListener(new ModifyListener(){
+			@SuppressWarnings("deprecation")
+			public void modifyText(ModifyEvent e) {
+				if( selectedAssociation.getReferrerRole() == null )
+					return;
+				String fieldName = referrerRolePropertyField.getText();
+				IStatus status = JavaConventions.validateFieldName( fieldName );
+				if( !status.matches(IStatus.ERROR) ){
+					selectedAssociation.getReferrerRole().setPropertyName(fieldName);
+				}
+				updateStatus(status);
+			}			
+		});
+
+		Label label = new Label( parent, SWT.NONE);
+		label.setText( "" );//$NON-NLS-1$
+		label.setLayoutData(new GridData(GridData.GRAB_HORIZONTAL));
+		
+		referrerRoleCascadeField = new StringButtonDialogField( new IStringButtonAdapter(){
+			public void changeControlPressed(DialogField field) {
+				if( editCascade( selectedAssociation.getReferrerRole() )){
+					referrerRoleCascadeField.setText(selectedAssociation.getReferrerRole().getCascade());
+				}
+			}	
+		}) ;
+		referrerRoleCascadeField.setLabelText( JptUiEntityGenMessages.cascade );
+		referrerRoleCascadeField.setButtonLabel(""); //$NON-NLS-1$
+		referrerRoleCascadeField.doFillIntoGrid(parent, 3);
+		referrerRoleCascadeField.getTextControl(parent).setEditable(false);
+		int maxFieldWidth = convertWidthInCharsToPixels(40);
+		LayoutUtil.setWidthHint(referrerRoleCascadeField.getTextControl(null), maxFieldWidth );
+		Button btn = referrerRoleCascadeField.getChangeControl(null);
+		GridData data = (GridData)btn.getLayoutData();
+		btn.setImage( ImageRepository.getBrowseButtonImage(this.resourceManager) );
+		data.horizontalAlignment = SWT.BEGINNING;
+		data.widthHint = 30;
+		btn.setLayoutData(data);
+		
+		Label labelCtrl  = referrerRoleCascadeField.getLabelControl(parent);
+		data = (GridData)labelCtrl.getLayoutData();
+		data.horizontalIndent = 40 ;
+		labelCtrl.setLayoutData(data);
+		
+		
+		label = new Label( parent, SWT.NONE);
+		label.setText( "" );//$NON-NLS-1$
+		label.setLayoutData(new GridData(GridData.GRAB_HORIZONTAL));
+		
+	}	
+	
+	
+	@Override
+	public void setVisible(boolean visible) {
+		super.setVisible(visible);
+		if( visible ){
+			hideAssociationDetail();
+			updateAssociationsListPanel();
+		}
+	}
+
+	private void hideAssociationDetail( ){
+		this.detailPanelStatckLayout.topControl = emptyPanel;
+		this.detailPanel.layout();
+		this.detailPanel.getParent().layout();
+	}
+	
+	/**
+	 * Updates the status line and the OK button according to the given status
+	 * 
+	 * @param status status to apply
+	 */
+	@SuppressWarnings("restriction")
+	protected void updateStatus(IStatus status) {
+		setPageComplete(!status.matches(IStatus.ERROR));
+		
+		StatusUtil.applyToStatusLine(this, status);
+		if( status.getCode() == Status.OK ){
+			setMessage(JptUiEntityGenMessages.GenerateEntitiesWizard_assocPage_desc);
+		}
+	}
+	
+	@SuppressWarnings("restriction")
+	private void createGenerateReferencedRoleControls(Composite parent,  int columns) {
+		referencedRoleCheckBox = new Button(parent, SWT.CHECK);
+		referencedRoleCheckBox.setText( JptUiEntityGenMessages.GenerateEntitiesWizard_assocEditor_setRef );
+		referencedRoleCheckBox.addSelectionListener(new SelectionListener() {
+			public void widgetDefaultSelected(SelectionEvent e) {}
+		
+			public void widgetSelected(SelectionEvent e) {
+				boolean generate = referencedRoleCheckBox.getSelection();
+				referencedRolePropertyLabel.setEnabled( generate);
+				referencedRolePropertyField.setEnabled( generate);
+				referencedRoleCascadeField.setEnabled(generate);
+				
+				if( !generate && !referrerRoleCheckBox.getSelection()){
+					generateAssociationCheckBox.setSelection(false);
+					cardinalityCombo.setEnabled(false);
+					referrerRoleCheckBox.setEnabled(false);
+					referencedRoleCheckBox.setEnabled(false);
+				}
+				directionalityCheckBoxChanged();
+				if( generate ){
+					AssociationRole role = selectedAssociation.getReferencedRole();
+					referencedRolePropertyField.setText( role.getPropertyName() );
+				}
+			}
+
+		});
+
+		SWTUtil.fillColumnsWithIndent( referencedRoleCheckBox , columns-1, 20 );
+		newLabel(parent, "");//$NON-NLS-1$
+		
+		referencedRolePropertyLabel = SWTUtil.newLabelWithIndent(parent,  JptUiEntityGenMessages.property, 40 );
+		
+		referencedRolePropertyField = new Text( parent, SWT.BORDER);
+		fillColumns(referencedRolePropertyField, 2);
+		referencedRolePropertyField.addModifyListener(new ModifyListener(){
+			public void modifyText(ModifyEvent e) {
+				if( selectedAssociation.getReferencedRole() == null )
+					return ;
+				
+				String fieldName = referencedRolePropertyField.getText();
+				IStatus status = JavaConventions.validateIdentifier(fieldName,
+						JavaCore.VERSION_1_3, JavaCore.VERSION_1_3);
+				if( !status.matches(IStatus.ERROR) ){
+					if( !fieldName.equals(selectedAssociation.getReferencedRole().getPropertyName()) )
+						selectedAssociation.getReferencedRole().setPropertyName(fieldName);
+				}
+				updateStatus(status);
+			}			
+		});
+		
+
+		Label label = new Label( parent, SWT.NONE);
+		label.setText( "" );//$NON-NLS-1$
+		label.setLayoutData(new GridData(GridData.GRAB_HORIZONTAL));
+		
+		
+		referencedRoleCascadeField = new StringButtonDialogField( new IStringButtonAdapter(){
+			public void changeControlPressed(DialogField field) {
+				if( editCascade( selectedAssociation.getReferencedRole() ) ){
+					referencedRoleCascadeField.setText( selectedAssociation.getReferencedRole().getCascade() );
+				}
+			}	
+		}) ;
+		referencedRoleCascadeField.setLabelText( JptUiEntityGenMessages.cascade );
+		referencedRoleCascadeField.setButtonLabel(""); //$NON-NLS-1$
+		referencedRoleCascadeField.doFillIntoGrid(parent, 3);
+		referencedRoleCascadeField.getTextControl(parent).setEditable( false);
+		int maxFieldWidth = convertWidthInCharsToPixels(40);
+		LayoutUtil.setWidthHint(referencedRoleCascadeField.getTextControl(null), maxFieldWidth );
+		Button btn = referencedRoleCascadeField.getChangeControl(null);
+		btn.setImage( ImageRepository.getBrowseButtonImage(this.resourceManager) );
+		GridData data = (GridData)btn.getLayoutData();
+		data.horizontalAlignment = SWT.BEGINNING;
+		data.widthHint = 30;
+		btn.setLayoutData(data);
+		
+		Label labelCtrl  = referencedRoleCascadeField.getLabelControl(parent);
+		data = (GridData)labelCtrl.getLayoutData();
+		data.horizontalIndent = 40 ;
+		labelCtrl.setLayoutData(data);
+		
+		label = new Label( parent, SWT.NONE);
+		label.setText( "" );//$NON-NLS-1$
+		label.setLayoutData(new GridData(GridData.GRAB_HORIZONTAL));
+		
+	}	
+	
+	private void createDetailPanel(Composite composite ) {
+		
+		this.detailPanel = new Composite( composite, SWT.NONE);
+		GridData gd = new GridData(GridData.FILL_HORIZONTAL);
+		gd.grabExcessVerticalSpace = false;
+		this.detailPanel.setLayoutData(gd);
+		this.detailPanelStatckLayout = new StackLayout();
+		this.detailPanel.setLayout( this.detailPanelStatckLayout );
+		
+		emptyPanel = new Composite( detailPanel, SWT.NONE);
+		emptyPanel.setLayoutData(new GridData()); 
+		detailPanelStatckLayout.topControl = emptyPanel;
+		detailPanel.layout();
+		
+		composite.layout();
+	}
+	
+	
+	private Composite createAssociationsEditPanel(Composite composite, int columns) {
+		Composite parent = new Composite( composite, SWT.NONE);
+		fillColumns(parent, 4);
+
+		createGenerateAssociationCheckbox(parent,columns);
+		int nColumns= 4 ;
+		GridLayout layout = new GridLayout();
+		layout.numColumns = nColumns;
+		parent.setLayout(layout);
+
+		//Cardinality
+		cardinalityLabel = new Label(parent, SWT.NONE);
+		cardinalityLabel.setText( JptUiEntityGenMessages.cardinality);
+		GridData gd = new GridData();
+		gd.horizontalIndent = 20;
+		cardinalityLabel.setLayoutData( gd );
+		
+		cardinalityCombo = new Combo(parent, SWT.SINGLE | SWT.READ_ONLY );
+		
+		fillColumns(cardinalityCombo, 1);
+		
+		cardinalityCombo.addSelectionListener(new SelectionListener(){
+			public void widgetDefaultSelected(SelectionEvent e) {}
+			public void widgetSelected(SelectionEvent e) {
+				selectedAssociation.setCardinality( cardinalityCombo.getText());
+				associationList.updateSelectedAssociation();
+			}
+		});
+		
+		//Adding a filler column
+		Label label = new Label( parent, SWT.NONE);
+		label.setText( "");//$NON-NLS-1$
+		GridData layoutData = new GridData();
+		layoutData.horizontalSpan = 2;
+		layoutData.horizontalAlignment = SWT.FILL;
+		layoutData.grabExcessHorizontalSpace = true;
+		label.setLayoutData(layoutData);
+		
+		//Table join condition
+		joinConditionLabel = newLabelWithIndent(parent, JptUiEntityGenMessages.GenerateEntitiesWizard_assocEditor_tableJoin, 20 );
+		
+		joinConditionText = new Text( parent, SWT.MULTI | SWT.BORDER );
+		joinConditionText.setEditable(false);
+		joinConditionText.setText(JptUiEntityGenMessages.GenerateEntitiesWizard_assocEditor_joinedWhen);
+		layoutData = new GridData();
+		layoutData.horizontalSpan = 2;
+		layoutData.verticalAlignment = SWT.TOP;
+		layoutData.horizontalAlignment = SWT.FILL;
+		layoutData.grabExcessHorizontalSpace = true;
+		layoutData.grabExcessVerticalSpace = false;
+		layoutData.heightHint = 50;
+		joinConditionText.setLayoutData(layoutData);
+		newLabel(parent, "");//$NON-NLS-1$
+
+		//Generate UI controls for ReferrerRole
+		createGenerateReferrerRoleControls(parent, columns);
+
+		//Generate UI controls for ReferencedRole
+		createGenerateReferencedRoleControls(parent, columns);
+		
+		
+		return parent;
+	}
+
+	public boolean editCascade(AssociationRole role) {
+		CascadeDialog dlg = CascadeDialog.create(role);
+		if (dlg.open() == Window.CANCEL ) {
+			return false;
+		}
+		
+		return true;
+	}	
+
+	private void createAssociationsListPanel(Composite parent) {
+		Composite composite = new Composite( parent, SWT.NULL );
+		composite.setLayout( new FillLayout());
+		Color backgroundColor = new Color(Display.getDefault(),255, 0,0);
+		composite.setBackground(backgroundColor);
+		backgroundColor.dispose();
+		GridData layoutData = new GridData();
+		layoutData.horizontalSpan = 1;
+		layoutData.verticalAlignment = SWT.FILL;
+		layoutData.horizontalAlignment = SWT.FILL;
+		layoutData.grabExcessHorizontalSpace = false;
+		layoutData.grabExcessVerticalSpace = true;
+		layoutData.widthHint = 400;
+		layoutData.heightHint = 400;
+		composite.setLayoutData(layoutData);
+		
+		associationList = new AssociationsListComposite(composite, this, this.resourceManager);
+	}
+	
+	private void launchNewAssociationsWizard() {
+		ORMGenCustomizer customizer = getCustomizer();
+		NewAssociationWizard wizard = new NewAssociationWizard(this.jpaProject, customizer, this.resourceManager);
+		
+		WizardDialog dialog = new WizardDialog( this.getShell(), wizard);
+		dialog.create();
+		int returnCode = dialog.open();
+		if (returnCode == Window.OK) {
+			Association association = wizard.getNewAssociation();
+			if( association !=null ){
+				customizer.addAssociation(association);
+				updateForeignKeyColumnGenProperty(association);
+				updateAssociationsListPanel();
+			}
+		}		
+	}
+	/**
+	 * For user created association:
+	 * If association is to be generated, no need to generate the getter/setter for the column itself
+	 */
+	private void updateForeignKeyColumnGenProperty(Association association) {
+		//Need to process MANY_TO_ONE only since the the associations list are optimized to have MANY_TO_ONE
+		if( association.isCustom() && association.getCardinality().equals( Association.MANY_TO_ONE ) ){
+			boolean generateColumn =  !association.isGenerated();
+			//The "MANY" side DB table
+			//ORMGenTable table1 = association.getReferrerTable();
+			//The "ONE" side DB table
+			//ORMGenTable table2 = association.getReferencedTable();
+			//The list of foreign key columns in the MANY side, should not be generated
+			//The list of primary keys in the ONE side, will be generated
+			//List<ORMGenColumn> list2 = association.getReferencedColumns();	
+			List<ORMGenColumn> list1 = association.getReferrerColumns();	
+			for(ORMGenColumn c : list1 ){
+				if( c.isGenerated() != generateColumn){
+					if( !generateColumn && c.getDbColumn().isPartOfPrimaryKey() ){
+						continue;
+					}
+					c.setGenerated(generateColumn);
+					c.setInsertable(generateColumn);
+					c.setUpdateable(generateColumn);
+				}
+			}
+		}
+	}
+
+	private void updateAssociationsListPanel() {
+			ORMGenCustomizer customizer = getCustomizer();
+			//If user changed the connection or schema
+			if( this.customizer != customizer ){
+				this.customizer = customizer; 
+			}
+			List<Association> associations = customizer.getAssociations();
+			this.associationList.updateAssociations( associations );
+	}
+
+	@SuppressWarnings("restriction")
+	public void updateAssociationEditPanel(Association association) {
+		this.selectedAssociation = association;
+
+		boolean enabled = association.isCustom();
+		this.deleteAssociationLink.setEnabled(enabled);
+		
+		//Create and display the associationsEditPanel if it was hidden before
+		if( associationsEditPanel == null ){
+			associationsEditPanel = this.createAssociationsEditPanel(this.detailPanel, 4);
+		}
+		this.detailPanelStatckLayout.topControl = associationsEditPanel;
+		this.detailPanel.layout();
+		this.detailPanel.getParent().layout();
+
+		//Update the UI controls from the model
+		String table1Name = association.getReferrerTableName();
+		String table2Name = association.getReferencedTableName();
+		String joinTableName = association.getJoinTableName();
+		
+		boolean isGenerated = association.isGenerated();
+		this.generateAssociationCheckBox.setSelection(isGenerated);
+		this.referrerRolePropertyLabel.setEnabled( isGenerated );
+		this.referrerRolePropertyField.setEnabled( isGenerated );
+		this.referrerRoleCheckBox.setEnabled( isGenerated );
+		this.referencedRolePropertyLabel.setEnabled( isGenerated );
+		this.referencedRolePropertyField.setEnabled( isGenerated );
+		this.referencedRoleCheckBox.setEnabled( isGenerated );
+		this.cardinalityLabel.setEnabled(isGenerated);
+		this.cardinalityCombo.setEnabled(isGenerated);
+		this.joinConditionLabel.setEnabled( isGenerated );
+		this.joinConditionText.setEnabled( isGenerated );
+		
+		String cardinality = association.getCardinality();
+		if( Association.MANY_TO_MANY.equals( cardinality ) ){
+			cardinalityCombo.removeAll();
+			cardinalityCombo.add( Association.MANY_TO_MANY);
+		}else{
+			cardinalityCombo.removeAll();
+			cardinalityCombo.add( Association.MANY_TO_ONE);
+			cardinalityCombo.add( Association.ONE_TO_ONE);
+		}
+		
+		cardinalityCombo.setText(cardinality);
+		cardinalityCombo.setEnabled(enabled);
+		
+		String text = null;
+		//if MTM
+		if( Association.MANY_TO_MANY.equals( cardinality ) ){
+			text = String.format( JptUiEntityGenMessages.GenerateEntitiesWizard_assocEditor_setRef, table2Name, table1Name);
+		}else{
+			text = String.format( JptUiEntityGenMessages.GenerateEntitiesWizard_assocEditor_entityRef, table2Name, table1Name);
+		}
+		this.referrerRoleCheckBox.setText(text);
+
+		//if OTO
+		if( Association.ONE_TO_ONE.equals( cardinality ) ){
+			text = String.format( JptUiEntityGenMessages.GenerateEntitiesWizard_assocEditor_entityRef, table1Name, table2Name);
+		}else{
+			text = String.format( JptUiEntityGenMessages.GenerateEntitiesWizard_assocEditor_setRef, table1Name, table2Name);
+		}
+		this.referencedRoleCheckBox.setText(text);
+
+		//AssociationRole properties
+		AssociationRole referrerRole = association.getReferrerRole();
+		if( referrerRole != null){
+			this.referrerRoleCheckBox.setSelection( true );
+			this.referrerRolePropertyField.setEditable(true);
+			this.referrerRolePropertyField.setText(referrerRole.getPropertyName());
+			this.referrerRoleCascadeField.setEnabled(true);
+			String cascade = referrerRole.getCascade();
+			if( cascade!=null ) 
+				this.referrerRoleCascadeField.setText( cascade );
+			
+			//if MTO: 
+			if( Association.MANY_TO_ONE.equals( cardinality ) ){
+				this.referrerRoleCheckBox.setEnabled( false );
+			}
+		}else{
+			this.referrerRoleCheckBox.setSelection( false );
+			this.referrerRolePropertyLabel.setEnabled(false);
+			this.referrerRolePropertyField.setEditable(false);
+			this.referrerRolePropertyField.setText("");
+			this.referrerRoleCascadeField.setEnabled(false);
+		}
+		
+		AssociationRole referencedRole = association.getReferencedRole();
+		if( referencedRole != null){
+			this.referencedRoleCheckBox.setSelection( true );
+			this.referencedRolePropertyLabel.setEnabled(true);
+			this.referencedRolePropertyField.setEditable(true);
+			this.referencedRolePropertyField.setText(referencedRole.getPropertyName());
+			this.referencedRoleCascadeField.setEnabled(true);
+			String cascade = referencedRole.getCascade();
+			if( cascade!=null ) 
+				this.referencedRoleCascadeField.setText(cascade);
+		}else{
+			this.referencedRoleCheckBox.setSelection( false );
+			this.referencedRolePropertyLabel.setEnabled(false);
+			this.referencedRolePropertyField.setEditable(false);
+			this.referencedRolePropertyField.setText("");
+			this.referencedRoleCascadeField.setEnabled(false);
+		}
+		
+		//Join conditions
+		updateJoinConditions(association, table1Name, table2Name, joinTableName);
+	}
+
+	private void updateJoinConditions(Association association,
+			String table1Name, String table2Name, String joinTableName) {
+		String text = "%s";
+		if( joinTableName == null ){
+			StringBuilder strText = new StringBuilder();
+			//text = JptUiEntityGenMessages.GenerateEntitiesWizard_assocEditor_joinedWhen;
+			List<String> columnList1 = association.getReferrerColumnNames() ;
+			List<String> columnList2 = association.getReferencedColumnNames();
+			for( int i=0; i < columnList1.size(); i++){
+				strText.append( table1Name + "." + columnList1.get(i) );//$NON-NLS-1$
+				strText.append( "=" );//$NON-NLS-1$
+				strText.append( table2Name + "." + columnList2.get(i) );//$NON-NLS-1$
+				if( i < columnList1.size()-1 )
+					strText.append( "\n AND " );//$NON-NLS-1$
+			}
+			joinConditionText.setText( String.format( text , strText.toString()) ); 
+		}else{
+			StringBuilder strText = new StringBuilder();
+			//text = JptUiEntityGenMessages.GenerateEntitiesWizard_assocEditor_joinedWhen;
+			List<String> columnList1 = association.getReferrerColumnNames() ;
+			List<String> joinColumnList1 = association.getReferrerJoinColumnNames()  ;
+			for( int i=0; i < columnList1.size(); i++){
+				strText.append( table1Name + "." + columnList1.get(i) );//$NON-NLS-1$
+				strText.append( "=" );//$NON-NLS-1$
+				strText.append( joinTableName + "." + joinColumnList1.get(i) );
+				strText.append( "\n AND " );//$NON-NLS-1$
+			}
+			
+			List<String> joinTableColumnList2 = association.getReferencedJoinColumnNames();
+			List<String> columnList2 = association.getReferencedColumnNames();
+			for( int i=0; i < joinTableColumnList2.size(); i++){
+				strText.append( joinTableName + "." + joinTableColumnList2.get(i) );
+				strText.append( "=" );//$NON-NLS-1$
+				strText.append( table2Name + "." + columnList2.get(i) );//$NON-NLS-1$
+				if( i < joinTableColumnList2.size()-1 )
+					strText.append( "\n AND " );//$NON-NLS-1$
+			}
+			
+			joinConditionText.setText( String.format( text , strText.toString()) ); 
+			
+		}
+	}
+
+	/**
+	 * Called when one of referrerRoleCheckBox or referencedRoleCheckBox 
+	 * changes value. 
+	 *
+	 */
+	private void directionalityCheckBoxChanged() {
+		String dir;
+		if (referrerRoleCheckBox.getSelection()) {
+			dir = referencedRoleCheckBox.getSelection() ? Association.BI_DI : Association.NORMAL_DI;
+		} else {
+			if (referencedRoleCheckBox.getSelection()) {
+				dir = Association.OPPOSITE_DI;
+			} else {
+				dir = null;
+			}
+		}
+		if (dir != null) {
+			selectedAssociation.setDirectionality(dir);
+		} else {
+			selectedAssociation.setGenerated(false);
+		}
+		
+		this.associationList.updateSelectedAssociation();
+	}	
+	
+	private ORMGenCustomizer getCustomizer(){
+		GenerateEntitiesFromSchemaWizard wizard = (GenerateEntitiesFromSchemaWizard) this.getWizard();
+		return wizard.getCustomizer();
+	}
+	
+	
+    @Override
+    public final void performHelp() 
+    {
+        this.getHelpSystem().displayHelp( GenerateEntitiesFromSchemaWizard.HELP_CONTEXT_ID );
+    }
+    
+	protected final IWorkbenchHelpSystem getHelpSystem() {
+		return PlatformUI.getWorkbench().getHelpSystem();
+	}
+	
+	@Override
+	public void dispose() {
+		//when the JPA project wizard page is shown first, the other wizard pages are lazily built, thus
+		//associationList can be null - bug 307894
+		if (this.associationList != null) {
+			this.associationList.dispose();
+		}
+		super.dispose();
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/gen/TableFigure.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/gen/TableFigure.java
new file mode 100644
index 0000000..d219f01
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/gen/TableFigure.java
@@ -0,0 +1,86 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 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.ui.internal.wizards.gen;
+
+import org.eclipse.draw2d.ColorConstants;
+import org.eclipse.draw2d.Figure;
+import org.eclipse.draw2d.Graphics;
+import org.eclipse.draw2d.GridLayout;
+import org.eclipse.draw2d.Label;
+import org.eclipse.draw2d.LineBorder;
+import org.eclipse.draw2d.PositionConstants;
+import org.eclipse.draw2d.geometry.Insets;
+import org.eclipse.draw2d.geometry.Rectangle;
+import org.eclipse.jface.resource.ResourceManager;
+import org.eclipse.jpt.ui.internal.ImageRepository;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Font;
+
+/**
+ * A draw2D figure representing a database table
+ * 
+ */
+public class TableFigure extends Figure
+{
+	private Color tableColor = new Color(null, 220, 232, 241);
+
+	private Font tableFont = new Font(null, "Arial", 8, SWT.NONE); //$NON-NLS-1$
+
+	private Color borderColor = new Color(null, 14, 66, 115);
+
+	public static final int OUTLINE_CORNER_RADIUS = 6;
+
+	protected final ResourceManager resourceManager;
+
+	public TableFigure(String name, ResourceManager resourceManager) {
+		this.resourceManager = resourceManager;
+		GridLayout gl = new GridLayout();
+		gl.marginHeight = 2;
+		gl.marginWidth = 10;
+		setLayoutManager(gl);
+		setBorder(new LineBorder(this.tableColor, 0));
+		setBackgroundColor(this.tableColor);
+		setOpaque(true);
+		setSize(150, 20);
+		Label nameLabel = new Label("", ImageRepository.getTableObjImage(this.resourceManager));
+		nameLabel.setFont(this.tableFont);
+		nameLabel.setText(name);
+		nameLabel.setForegroundColor(this.borderColor);
+		nameLabel.setLabelAlignment(PositionConstants.CENTER);
+		add(nameLabel);
+	}
+
+	@Override
+	protected void paintClientArea(Graphics graphics) {
+		super.paintClientArea(graphics);
+		graphics.pushState();
+		Rectangle r = getBounds().getCopy();
+		graphics.drawRoundRectangle(r.expand(new Insets(-1, -1, -2, -2)), OUTLINE_CORNER_RADIUS, OUTLINE_CORNER_RADIUS);
+		graphics.popState();
+	}
+
+	@Override
+	public void setEnabled(boolean enabled) {
+		super.setEnabled(enabled);
+		if (enabled) {
+			setBackgroundColor(this.tableColor);
+		}
+		else {
+			setBackgroundColor(ColorConstants.white);
+		}
+	}
+
+	public void dispose() {
+		this.borderColor.dispose();
+		this.tableFont.dispose();
+		this.tableColor.dispose();
+	}
+}
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/gen/TableGenPanel.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/gen/TableGenPanel.java
new file mode 100644
index 0000000..f533675
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/gen/TableGenPanel.java
@@ -0,0 +1,400 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 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.ui.internal.wizards.gen;
+
+import java.util.List;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.jdt.core.JavaConventions;
+import org.eclipse.jface.wizard.WizardPage;
+import org.eclipse.jpt.gen.internal.ORMGenTable;
+import org.eclipse.jpt.ui.JptUiPlugin;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.layout.RowLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Group;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Text;
+
+/**
+ * The UI panel for setting the default and specific 
+ * table entity generation properties.
+ * 
+ */
+class TableGenPanel
+{
+	WizardPage wizardPage ; 
+	
+	private Text classNameField; // used in setting individual table/entity generation only
+	
+	private Combo idGeneratorCombo;
+	private Text sequenceNameField;
+	
+	private Button entityAccessField;
+	private Button entityAccessProperty;
+	private Button associationFetchDefault;
+	private Button associationFetchEager;
+	private Button associationFetchLazy;
+	
+	private Button collectionTypeSet;
+	private Button collectionTypeList;
+	
+	private Button generateOptionalAnnotations;
+	
+	private Label sequenceNameNoteLabel; 
+	
+	private boolean isUpdatingControls;
+	
+	private ORMGenTable mTable;
+	
+	private boolean isDefaultTable = false;
+	
+	public TableGenPanel(Composite parent, int columns , boolean isDefaultTable, WizardPage wizardPage   ){
+		super();
+		this.wizardPage = wizardPage;
+		this.isDefaultTable = isDefaultTable;
+		createTableMappingPropertiesGroup(parent, columns);
+		SWTUtil.createLabel(parent, 4, ""); //$NON-NLS-1$
+	}
+	
+	protected void createTableMappingPropertiesGroup(Composite composite, int columns) {
+		Group parent = new Group(composite, SWT.NONE );
+		parent.setText( JptUiEntityGenMessages.GenerateEntitiesWizard_defaultTablePage_tableMapping);
+		parent.setLayout(new GridLayout(columns, false));
+		GridData layoutData = new GridData();
+		layoutData.horizontalSpan = columns;
+		layoutData.verticalAlignment = SWT.FILL;
+		layoutData.horizontalAlignment = SWT.FILL;
+		layoutData.grabExcessHorizontalSpace = true;
+		layoutData.grabExcessVerticalSpace = false;
+		parent.setLayoutData(layoutData);
+		
+		createClassNameControl(parent, columns);
+		
+		createIdGeneratorControls(parent, columns);
+		createEntityAccessControls(parent, columns);
+		
+		//AssociationFetch and CollectionType only available for default table generation
+		if ( isDefaultTable ) {
+			createAssociationFetchControls(parent, columns);
+			createCollectionTypeControls(parent, columns);
+			createGenerateOptionalAnnotationControls(parent, columns);
+		}
+	}
+	
+	private void createGenerateOptionalAnnotationControls(Group parent, int columns) {
+		generateOptionalAnnotations = new Button(parent, SWT.CHECK );
+		generateOptionalAnnotations.setText( JptUiEntityGenMessages.GenerateEntitiesWizard_defaultTablePage_genOptionalAnnotations);
+		generateOptionalAnnotations.setToolTipText(JptUiEntityGenMessages.GenerateEntitiesWizard_defaultTablePage_genOptionalAnnotations_desc);
+
+		GridData gd = new GridData();
+		gd.horizontalSpan = columns;
+		generateOptionalAnnotations.setLayoutData(gd);
+		generateOptionalAnnotations.addSelectionListener(new SelectionListener(){
+			public void widgetDefaultSelected(SelectionEvent e) {}
+			public void widgetSelected(SelectionEvent e) {
+				boolean selected = generateOptionalAnnotations.getSelection();
+				mTable.setGenerateDDLAnnotations(selected);
+			}
+		});
+	}
+
+	private void createClassNameControl(Composite parent, int columns) {
+		//Customize class name for specific table only
+		if ( !isDefaultTable ) {
+			SWTUtil.createLabel( parent, 1 , JptUiEntityGenMessages.GenerateEntitiesWizard_tablePanel_className );
+			
+			classNameField = new Text(parent, SWT.SINGLE | SWT.BORDER );
+			//mPackageNameField.setEditable(false);
+			SWTUtil.fillColumns(classNameField,3);
+			classNameField.addModifyListener(new ModifyListener(){
+				@SuppressWarnings({  "deprecation" })
+				public void modifyText(ModifyEvent e) {
+					if (e.getSource() == null || !isUpdatingControls) {
+						String className = classNameField.getText();
+						IStatus status = JavaConventions.validateJavaTypeName( className );
+						if( !status.matches(IStatus.ERROR) ){
+							mTable.setClassName(  className );
+							wizardPage.setErrorMessage(null);
+						}else{
+							wizardPage.setErrorMessage(status.getMessage());
+						}
+					}
+				}			
+			});
+		}
+	}
+	
+	class AssociationFetchListener implements SelectionListener{
+		public void widgetDefaultSelected(SelectionEvent e) {}
+		public void widgetSelected(SelectionEvent e) {
+			if (!isUpdatingControls) {
+				Button radioBtn = (Button)e.getSource();
+				mTable.setDefaultFetch( radioBtn.getData().toString());
+			}
+		}
+	}
+
+	private void createAssociationFetchControls(Composite composite, int columns) {
+		SWTUtil.createLabel(composite, 1, JptUiEntityGenMessages.GenerateEntitiesWizard_defaultTablePage_fetch );
+		
+		Composite parent = new Composite( composite, SWT.NONE);
+		parent.setLayout(new RowLayout());
+		SWTUtil.fillColumns( parent , 3);
+		associationFetchDefault	= new Button( parent, SWT.RADIO );
+		associationFetchDefault.setText( "Default");
+		associationFetchDefault.setData( ORMGenTable.DEFAULT_FETCH );	
+		
+		associationFetchEager = new Button( parent, SWT.RADIO );
+		associationFetchEager.setText( "&Eager");
+		associationFetchEager.setData( ORMGenTable.EAGER_FETCH );
+
+		associationFetchLazy = new Button( parent, SWT.RADIO );
+		associationFetchLazy.setText( "La&zy");
+		associationFetchLazy.setData( ORMGenTable.LAZY_FETCH );
+		
+		AssociationFetchListener associationFetchListener = new AssociationFetchListener();
+		associationFetchDefault.addSelectionListener( associationFetchListener );
+		associationFetchLazy.addSelectionListener( associationFetchListener );
+		associationFetchEager.addSelectionListener( associationFetchListener );
+	}
+
+	class CollectionTypeListener implements SelectionListener {
+		public void widgetDefaultSelected(SelectionEvent e) {}
+		public void widgetSelected(SelectionEvent e) {
+			if (!isUpdatingControls) {
+				Button radioBtn = (Button)e.getSource();
+				mTable.setDefaultCollectionType( radioBtn.getData().toString());
+			}
+		}
+	}	
+	
+	private void createCollectionTypeControls(Composite composite, int columns) {
+		SWTUtil.createLabel(composite, 1, JptUiEntityGenMessages.GenerateEntitiesWizard_defaultTablePage_collType );
+		
+		Composite parent = new Composite( composite, SWT.NONE);
+		parent.setLayout(new RowLayout());
+		SWTUtil.fillColumns( parent , 3);
+		
+		this.collectionTypeSet = new Button( parent, SWT.RADIO);
+		this.collectionTypeSet.setText( "java.util.Se&t");
+		this.collectionTypeSet.setData( ORMGenTable.SET_COLLECTION_TYPE );
+		this.collectionTypeList = new Button( parent, SWT.RADIO);
+		this.collectionTypeList.setText("java.util.&List");
+		this.collectionTypeList.setData(ORMGenTable.LIST_COLLECTION_TYPE); 
+		
+		CollectionTypeListener collectionTypeListener = new CollectionTypeListener();
+		collectionTypeList.addSelectionListener( collectionTypeListener );
+		collectionTypeSet.addSelectionListener( collectionTypeListener );
+	}
+
+
+	public void setORMGenTable(ORMGenTable table) {
+		mTable = table;
+		
+		isUpdatingControls = true;
+				
+		try {
+			//ClassNameField is not available for default table
+			if(classNameField!= null )
+				classNameField.setText( mTable.getClassName() );
+			
+			final List<String> schemes = this.mTable.getCustomizer().getAllIdGenerators();
+			String[] values = new String[schemes.size()];
+			schemes.toArray(values);
+			idGeneratorCombo.setItems( values );
+			String idGenerator = mTable.getIdGenerator();
+			idGeneratorCombo.setText( idGenerator);
+			
+			boolean isSequence = this.mTable.getCustomizer().getSequenceIdGenerators().contains(idGenerator);		
+			String sequenceName = mTable.isDefaultsTable() ? mTable.getSequence() : mTable.getFormattedSequence();
+			sequenceName  = ( sequenceName == null ? "" : sequenceName ); 
+			sequenceNameField.setText( sequenceName );
+			if ( isSequence ) {
+				sequenceNameField.setEnabled(true);
+				sequenceNameNoteLabel.setEnabled(true);
+			} else {
+				sequenceNameField.setEnabled(false);
+				sequenceNameNoteLabel.setEnabled(false);
+			}
+			
+			String access = mTable.getAccess() ;
+			if (  ORMGenTable.FIELD_ACCESS.equals( access ) ) {
+				this.entityAccessField.setSelection( true );
+				this.entityAccessProperty.setSelection( false );
+			} else {
+				this.entityAccessProperty.setSelection( true );
+				this.entityAccessField.setSelection( false );
+			}
+	
+			if (associationFetchLazy != null && associationFetchEager != null ) {
+				String defaultFetch = mTable.getDefaultFetch();
+				//reset all three buttons
+				associationFetchDefault.setSelection(false);
+				associationFetchEager.setSelection(false);
+				associationFetchLazy.setSelection(false);
+				if( ORMGenTable.DEFAULT_FETCH.equals( defaultFetch ) )
+					associationFetchDefault.setSelection(true);
+				else if( ORMGenTable.EAGER_FETCH.equals( defaultFetch ) )
+					associationFetchEager.setSelection(true);
+				else
+					associationFetchLazy.setSelection(true);
+			}
+			
+			//DefaultTable only
+			if (collectionTypeList != null) {
+				String cType = mTable.getDefaultCollectionType();
+				if ( ORMGenTable.LIST_COLLECTION_TYPE.equals( cType ) ) {
+					this.collectionTypeList.setSelection( true );
+					this.collectionTypeSet.setSelection( false );
+				} else {
+					this.collectionTypeSet.setSelection( true );
+					this.collectionTypeList.setSelection( false );
+				}
+				
+				this.generateOptionalAnnotations.setSelection( mTable.isGenerateDDLAnnotations());
+			}
+			
+		} catch (Exception e) {
+			JptUiPlugin.log(e);
+		}
+		
+		isUpdatingControls = false;
+	}
+
+	private void createIdGeneratorControls(Composite parent, int columns) {
+		SWTUtil.createLabel(parent, 1, JptUiEntityGenMessages.GenerateEntitiesWizard_defaultTablePage_keyGen );
+
+		idGeneratorCombo = new Combo(parent,SWT.SINGLE | SWT.READ_ONLY);
+		SWTUtil.fillColumns(idGeneratorCombo, 3);
+		
+		idGeneratorCombo.addSelectionListener( new SelectionListener() {
+			public void widgetDefaultSelected(SelectionEvent e) {}
+
+			public void widgetSelected(SelectionEvent e) {
+				if (isUpdatingControls) {
+					return;
+				}
+				
+				idGenChanged();
+			}});
+
+		SWTUtil.createLabel(parent, 1, JptUiEntityGenMessages.GenerateEntitiesWizard_defaultTablePage_sequence );
+		sequenceNameField = new Text( parent, SWT.SINGLE | SWT.BORDER );
+		
+		SWTUtil.fillColumns(sequenceNameField, 3);
+		sequenceNameField.addModifyListener(new ModifyListener(){
+			public void modifyText(ModifyEvent e) {
+				if (e.getSource() == null || !isUpdatingControls) {
+
+					if ( idGeneratorCombo.getText().equals("sequence")) { //$NON-NLS-1$
+						String sequenceName = sequenceNameField.getText();
+						if ( sequenceName.toLowerCase().indexOf("$table") >= 0 ||  //$NON-NLS-1$
+								sequenceName.toLowerCase().indexOf("$pk") >= 0 ) { //$NON-NLS-1$
+							sequenceName = convertVarToLowerCase("$table", sequenceName); //$NON-NLS-1$
+							sequenceName = convertVarToLowerCase("$pk", sequenceName); //$NON-NLS-1$
+						}
+						if ( sequenceName.trim().length() != 0 ) {
+							mTable.setSequence( sequenceName );
+						} else{
+							mTable.setSequence( "" ); //$NON-NLS-1$
+						}
+					}
+				}
+			}
+
+			private String convertVarToLowerCase(String var, String sequenceName) {
+				int n = sequenceName.toLowerCase().indexOf( var );
+				if( n==0 ) {
+					return var + sequenceName.substring( var.length());
+				} else if( n >0 ) {
+					return sequenceName.substring(0,n) + var + sequenceName.substring( n + var.length());
+				}
+				return sequenceName;
+			}			
+		});
+		
+		SWTUtil.newLabel(parent, "");//$NON-NLS-1$
+		sequenceNameNoteLabel = new Label(parent, SWT.NONE);
+		String text =String.format( JptUiEntityGenMessages.GenerateEntitiesWizard_defaultTablePage_sequenceNote, 
+				ORMGenTable.TABLE_SEQ_PATTERN, ORMGenTable.PK_SEQ_PATTERN);
+		sequenceNameNoteLabel.setText( text ) ;
+		sequenceNameNoteLabel.setEnabled(false);
+		SWTUtil.fillColumns( sequenceNameNoteLabel, 3);
+	}
+
+	private void idGenChanged() {
+		String scheme = idGeneratorCombo.getText();
+		mTable.setIdGenerator(scheme);
+		
+		boolean isSequence = this.mTable.getCustomizer().getSequenceIdGenerators().contains(scheme);		
+		if (!isSequence) {
+			sequenceNameField.setText("");
+			sequenceNameField.setEnabled(false);
+			mTable.setSequence(null);
+			sequenceNameNoteLabel.setEnabled(false);
+		} else {
+			sequenceNameField.setEnabled(true);
+			Color NOTE_LABEL_COLOR = new Color( Display.getDefault(), 102,102,102);
+			sequenceNameNoteLabel.setForeground( NOTE_LABEL_COLOR );
+			NOTE_LABEL_COLOR.dispose();
+			sequenceNameNoteLabel.setEnabled(true);
+			if ( sequenceNameField.getText().length()==0 ) {
+				String newMessage = "Please specify a sequence name";
+				this.wizardPage.setMessage(newMessage);
+				this.wizardPage.setPageComplete(true);
+			} else {
+				this.wizardPage.setErrorMessage(null);
+				this.wizardPage.setPageComplete(true);
+			}
+		}
+	}
+	
+	class EntityAccessFetchListener implements SelectionListener{
+		public void widgetDefaultSelected(SelectionEvent e) {}
+		public void widgetSelected(SelectionEvent e) {
+			if (!isUpdatingControls) {
+				Button radioBtn = (Button)e.getSource();
+				mTable.setAccess( radioBtn.getData().toString() );
+			}
+		}
+	}
+	
+	private void createEntityAccessControls(Composite composite, int columns) {
+		SWTUtil.createLabel(composite, 1, JptUiEntityGenMessages.GenerateEntitiesWizard_defaultTablePage_access );
+		
+		Composite parent = new Composite( composite, SWT.NONE);
+		SWTUtil.fillColumns( parent , 3);
+		parent.setLayout(new RowLayout());
+
+		entityAccessField = new Button( parent, SWT.RADIO );
+		entityAccessField.setText( "&Field" ); //$NON-NLS1$
+		entityAccessField.setData( ORMGenTable.FIELD_ACCESS);
+
+		entityAccessProperty = new Button( parent, SWT.RADIO );
+		entityAccessProperty.setText(  "&Property" );//$NON-NLS1$
+		entityAccessProperty.setData( ORMGenTable.PROPERTY_ACCESS );
+		
+		EntityAccessFetchListener entityAccessFetchListener = new EntityAccessFetchListener();
+		entityAccessField.addSelectionListener( entityAccessFetchListener );
+		entityAccessProperty.addSelectionListener( entityAccessFetchListener );
+	}
+	
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/gen/TablesAndColumnsCustomizationWizardPage.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/gen/TablesAndColumnsCustomizationWizardPage.java
new file mode 100644
index 0000000..f91f283
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/gen/TablesAndColumnsCustomizationWizardPage.java
@@ -0,0 +1,377 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 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.ui.internal.wizards.gen;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.internal.ui.wizards.dialogfields.LayoutUtil;
+import org.eclipse.jdt.ui.wizards.NewTypeWizardPage;
+import org.eclipse.jface.dialogs.IMessageProvider;
+import org.eclipse.jface.resource.ResourceManager;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.ITreeContentProvider;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jface.viewers.TreeSelection;
+import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jpt.core.JpaProject;
+import org.eclipse.jpt.gen.internal.ORMGenColumn;
+import org.eclipse.jpt.gen.internal.ORMGenCustomizer;
+import org.eclipse.jpt.gen.internal.ORMGenTable;
+import org.eclipse.jpt.ui.internal.ImageRepository;
+import org.eclipse.jpt.ui.internal.JpaHelpContextIds;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.StackLayout;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Group;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.help.IWorkbenchHelpSystem;
+
+public class TablesAndColumnsCustomizationWizardPage extends NewTypeWizardPage {
+
+	private JpaProject jpaProject;
+
+	private TreeViewer tableColumnTreeViewer;
+	
+	private Composite detailPanel ;
+	private StackLayout detailPanelStatckLayout;
+	private Composite tableGenDetatilGroup;
+	private ColumnGenPanel columnGenPanel;
+	private Composite columnGenDetatilGroup;
+	private TableGenPanel tableGenPanel;
+	private ORMGenTable selectedTable;
+	
+	private ORMGenCustomizer customizer;
+
+	protected final ResourceManager resourceManager;
+	
+	protected TablesAndColumnsCustomizationWizardPage(JpaProject jpaProject, ResourceManager resourceManager) {
+		super(true, "TablesAndColumnsCustomizationWizardPage"); //$NON-NLS-1$
+		this.jpaProject = jpaProject;
+		this.resourceManager = resourceManager;
+		setTitle( JptUiEntityGenMessages.GenerateEntitiesWizard_tablesAndColumnsPage_title );
+		setMessage( JptUiEntityGenMessages.GenerateEntitiesWizard_tablesAndColumnsPage_desc);
+	}
+
+	// -------- Initialization ---------
+	/**
+	 * The wizard owning this page is responsible for calling this method with the
+	 * current selection. The selection is used to initialize the fields of the wizard 
+	 * page.
+	 * 
+	 * @param selection used to initialize the fields
+	 */
+	void init(IStructuredSelection selection) {
+		if ( jpaProject != null ) {
+			IJavaElement jelem = this.jpaProject.getJavaProject();
+			initContainerPage(jelem);
+			initTypePage(jelem);
+		}
+	}
+	
+	public void createControl(Composite parent) {
+		initializeDialogUnits(parent);
+		Composite composite = new Composite(parent, SWT.NULL);
+		int nColumns= 1	;
+		GridLayout layout = new GridLayout();
+		layout.numColumns = nColumns;
+		composite.setLayout(layout);
+		this.getHelpSystem().setHelp(composite, JpaHelpContextIds.GENERATE_ENTITIES_WIZARD_CUSTOMIZE_INDIVIDUAL_ENTITIES);
+
+		createTableAndColumnsListPanel(composite, 1);
+		
+		SWTUtil.createLabel( composite, 1, ""); //$NON-NLS-1$
+
+		SWTUtil.createSeparator(composite, 1);
+		
+		createGenerateDetailGroup(composite, 1);
+
+		setControl(composite);
+		this.setPageComplete( true );
+	}
+	
+	/**
+	 * A panel with JFace TreeViewer showing tables and columns to be generated into JPA entities
+	 * 
+	 * @param parent
+	 * @param columns
+	 */
+	private void createTableAndColumnsListPanel(Composite parent, int columns) {
+		Label label = new Label(parent, columns );
+		label.setText( JptUiEntityGenMessages.GenerateEntitiesWizard_tablesAndColumnsPage_labelTableAndColumns );
+		SWTUtil.fillColumns( label , columns);
+		
+		GridData data = new GridData();
+		data.horizontalSpan = columns;
+		data.verticalAlignment = SWT.FILL;
+		data.horizontalAlignment = SWT.FILL;
+		data.grabExcessHorizontalSpace = true;
+		data.heightHint = 200;
+		data.grabExcessVerticalSpace = true;
+		
+		tableColumnTreeViewer = new TreeViewer(parent);
+		tableColumnTreeViewer.getTree().setLayoutData( data);		
+		tableColumnTreeViewer.setContentProvider(new TableColumnTreeContentProvider());
+		tableColumnTreeViewer.setLabelProvider(new TableColumnTreeLabelProvider());
+		
+		tableColumnTreeViewer.addSelectionChangedListener( new ISelectionChangedListener(){
+			public void selectionChanged(SelectionChangedEvent event) {
+				updateDetailPanel(event.getSelection());
+			}
+
+		});
+	}
+
+	@Override
+	public void setVisible(boolean visible) {
+		super.setVisible(visible);
+		if(visible){
+			ORMGenCustomizer customizer = getCustomizer();
+			//If user changed the connection or schema
+			if( this.customizer != customizer ){
+				this.customizer = customizer; 
+				tableColumnTreeViewer.setInput( customizer );
+			}else{
+				tableColumnTreeViewer.refresh();
+			}
+			List<String> tableNames = this.customizer.getTableNames();
+			
+			//Select the first table
+			ORMGenTable ormGenTable = this.customizer.getTable(tableNames.get(0));
+			updateTabelGenDetail( ormGenTable );
+		}
+	}
+
+
+	private void updateDetailPanel(ISelection selection) {
+		TreeSelection ts = (TreeSelection)selection;
+		Object selectedObject = ts.getFirstElement();
+		if( selectedObject instanceof ORMGenTable ){
+			updateTabelGenDetail( (ORMGenTable)selectedObject );
+		}else if( selectedObject instanceof ORMGenColumn ){
+			updateColumnGenDetail( (ORMGenColumn)selectedObject );
+		}
+	}			
+	
+	private void updateColumnGenDetail(ORMGenColumn column) {
+		if(columnGenDetatilGroup==null){
+			columnGenDetatilGroup = new Composite(detailPanel, SWT.NONE);
+			GridLayout gridLayout = new GridLayout();
+			gridLayout.numColumns = 4;
+			columnGenDetatilGroup.setLayout(gridLayout);
+			this.columnGenPanel = new ColumnGenPanel(columnGenDetatilGroup, 4, getCustomizer() , this );
+		}
+		columnGenPanel.setColumn(column);
+		this.detailPanelStatckLayout.topControl = columnGenDetatilGroup;
+		this.detailPanel.layout();		
+		detailPanel.getParent().layout();
+	}
+
+	private void updateTabelGenDetail(ORMGenTable table) {
+		this.selectedTable = table;
+		if(tableGenDetatilGroup==null){
+			tableGenDetatilGroup = new Composite(detailPanel, SWT.NONE);
+			GridLayout gridLayout = new GridLayout();
+			gridLayout.numColumns = 4;
+			tableGenDetatilGroup.setLayout(gridLayout);
+			
+			this.tableGenPanel = new TableGenPanel(tableGenDetatilGroup, 4 , false, this );
+			createDomainJavaClassesPropertiesGroup(tableGenDetatilGroup, 4 );
+		}
+		tableGenPanel.setORMGenTable(table);
+		
+		this.detailPanelStatckLayout.topControl = tableGenDetatilGroup;
+		this.detailPanel.layout();		
+
+		String baseClass = table.getExtends();
+		if( baseClass!= null )
+			setSuperClass(baseClass, true);
+		
+		setSuperInterfaces( table.getImplements(), true);
+		
+		detailPanel.getParent().layout();
+	}
+	
+	protected void createDomainJavaClassesPropertiesGroup(Composite composite, int columns) {
+		Group parent = new Group( composite, SWT.NONE);
+		parent.setText( JptUiEntityGenMessages.GenerateEntitiesWizard_defaultTablePage_domainJavaClass );
+		parent.setLayout(new GridLayout(columns, false));
+		SWTUtil.fillColumns( parent, columns);
+
+		createSuperClassControls(parent, columns);
+		createSuperInterfacesControls(parent, columns);
+
+		//Resize supper class text width to fill the parent group.
+		//Have to do it indirectly since fSuperClassDialogField is private in super class.
+		Control[] controls = parent.getChildren();
+		if( controls.length>1 && controls[1] instanceof Text ){
+			Text text = (Text)(parent.getChildren()[1]);
+			LayoutUtil.setWidthHint(text, getMaxFieldWidth());
+			LayoutUtil.setHorizontalGrabbing(text);
+		}		
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.ui.wizards.NewTypeWizardPage#superClassChanged()
+	 */
+	@Override
+	protected IStatus superClassChanged() {
+		IStatus status = super.superClassChanged();
+		String baseClass = getSuperClass();
+		if(baseClass!=null && this.selectedTable!=null ){
+			String oldBaseClass = this.selectedTable.getExtends();
+			if( !oldBaseClass.equals(baseClass ))
+				this.selectedTable.setExtends(baseClass);
+		}
+		return status; 
+	}	
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.ui.wizards.NewTypeWizardPage#addSuperInterface(java.lang.String)
+	 */
+	@Override
+	@SuppressWarnings("unchecked")
+	public boolean addSuperInterface(String superInterface) {
+		super.addSuperInterface(superInterface);
+		List interfaces = getSuperInterfaces();
+		if(this.selectedTable!=null)
+			this.selectedTable.setImplements(interfaces);
+		return true;
+	}
+	
+	@Override
+	protected void handleFieldChanged(String fieldName) {
+		super.handleFieldChanged(fieldName);
+		if( this.fSuperClassStatus.matches(IStatus.ERROR)){
+			updateStatus(fSuperClassStatus);
+		}else{
+			setMessage("", IMessageProvider.NONE);
+			setErrorMessage(null);
+		}
+		
+	}	
+	
+	private ORMGenCustomizer getCustomizer(){
+		GenerateEntitiesFromSchemaWizard wizard = (GenerateEntitiesFromSchemaWizard) this.getWizard();
+		return wizard.getCustomizer();
+	}
+	/**
+	 * Content provider, and label provider for the DB Table/Column TreeViewer
+	 *
+	 */
+	class TableColumnTreeContentProvider implements ITreeContentProvider {
+		public Object[] getElements(Object inputElement) {
+			if( inputElement instanceof ORMGenCustomizer ){
+				ORMGenCustomizer input = (ORMGenCustomizer )inputElement;
+				List<String> tableNameList = input.getGenTableNames();
+				List<ORMGenTable> ret = new ArrayList<ORMGenTable>();
+				for(String t : tableNameList){
+					ORMGenTable ormGenTable = getCustomizer().getTable( t );
+					ret.add( ormGenTable );
+				}
+				return ret.toArray();
+			}
+			return new Object[]{};
+		}
+		public Object[] getChildren(Object parentElement) {
+			if( parentElement instanceof ORMGenTable ){
+				ORMGenTable table = (ORMGenTable) parentElement;
+				List<ORMGenColumn> columns = table.getColumns();
+				List<ORMGenColumn> ret = new ArrayList<ORMGenColumn>();
+				for( ORMGenColumn col : columns){
+					if( col.isForeignKey() )
+						continue;
+					if( col.isPrimaryKey() ){
+						ret.add(0,col );
+					}else{
+						ret.add(col);
+					}
+				}
+				return ret.toArray();
+			}
+			return new Object[]{};
+		}
+		public Object getParent(Object element) { 
+			if( element instanceof ORMGenColumn){
+				return null;
+			}
+			return null;
+		}
+		public boolean hasChildren(Object element) {
+			return( element instanceof ORMGenTable );
+		}
+		public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {}
+		public void dispose() {}
+	}
+
+	class TableColumnTreeLabelProvider extends LabelProvider{
+
+		@Override
+		public Image getImage(Object element) {
+			if( element instanceof ORMGenTable ){
+				return ImageRepository.getTableImage(resourceManager);
+			}else 	if( element instanceof ORMGenColumn ){
+				ORMGenColumn col = ( ORMGenColumn)element;
+				return col.isPrimaryKey() ?
+						ImageRepository.getKeyColumnImage(resourceManager) :
+						ImageRepository.getColumnImage(resourceManager);
+			}
+			return null;
+		}
+		
+
+		@Override
+		public String getText(Object element) {
+			if( element instanceof ORMGenTable ){
+				return ((ORMGenTable)element).getName();
+			}else 			if( element instanceof ORMGenColumn ){
+				return ((ORMGenColumn)element).getName();
+			}
+			return super.getText(element);
+		}		
+	}
+	
+	private void createGenerateDetailGroup(Composite parent, int columns) {
+		detailPanel = new Composite(parent, SWT.NONE);
+		SWTUtil.fillColumns( detailPanel, columns);
+		  
+		detailPanelStatckLayout = new StackLayout();
+		detailPanel.setLayout(detailPanelStatckLayout);
+		  
+		Composite emptyPanel = new Composite(detailPanel, SWT.NONE);
+		emptyPanel.setLayoutData(new GridData());
+
+		detailPanelStatckLayout.topControl = emptyPanel;
+		detailPanel.layout();
+	}
+
+    @Override
+    public final void performHelp() 
+    {
+        this.getHelpSystem().displayHelp( GenerateEntitiesFromSchemaWizard.HELP_CONTEXT_ID );
+    }
+
+	protected final IWorkbenchHelpSystem getHelpSystem() {
+		return PlatformUI.getWorkbench().getHelpSystem();
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/gen/TablesSelectorWizardPage.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/gen/TablesSelectorWizardPage.java
new file mode 100644
index 0000000..9e971f4
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/gen/TablesSelectorWizardPage.java
@@ -0,0 +1,557 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 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.ui.internal.wizards.gen;
+
+import java.lang.reflect.InvocationTargetException;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.jface.operation.IRunnableWithProgress;
+import org.eclipse.jface.resource.ResourceManager;
+import org.eclipse.jface.viewers.CheckboxTableViewer;
+import org.eclipse.jface.viewers.ColumnWeightData;
+import org.eclipse.jface.viewers.IBaseLabelProvider;
+import org.eclipse.jface.viewers.IContentProvider;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.IStructuredContentProvider;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.ITableLabelProvider;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerSorter;
+import org.eclipse.jface.wizard.IWizardPage;
+import org.eclipse.jface.wizard.WizardPage;
+import org.eclipse.jpt.core.JpaProject;
+import org.eclipse.jpt.db.ConnectionProfile;
+import org.eclipse.jpt.db.JptDbPlugin;
+import org.eclipse.jpt.db.Schema;
+import org.eclipse.jpt.db.Table;
+import org.eclipse.jpt.gen.internal.ORMGenCustomizer;
+import org.eclipse.jpt.ui.JptUiPlugin;
+import org.eclipse.jpt.ui.internal.ImageRepository;
+import org.eclipse.jpt.ui.internal.JpaHelpContextIds;
+import org.eclipse.jpt.ui.internal.JptUiMessages;
+import org.eclipse.jpt.ui.internal.util.SWTUtil;
+import org.eclipse.jpt.ui.internal.util.TableLayoutComposite;
+import org.eclipse.jpt.utility.internal.CollectionTools;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.KeyAdapter;
+import org.eclipse.swt.events.KeyEvent;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.TableColumn;
+import org.eclipse.swt.widgets.TableItem;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.help.IWorkbenchHelpSystem;
+
+class TablesSelectorWizardPage extends WizardPage{
+
+	private static final int TABLE_COLUMN_INDEX = 0;
+	private JpaProject jpaProject;
+	private Schema schema = null;
+	private ORMGenCustomizer customizer = null;
+	private boolean updatePersistenceXml = true;
+
+	private DatabaseGroup databaseGroup;
+	private CheckboxTableViewer tableTable;
+	private Button updatePersistenceXmlCheckBox;
+
+	protected final ResourceManager resourceManager;
+	
+	TablesSelectorWizardPage(JpaProject jpaProject, ResourceManager resourceManager) {
+		super("TablesSelectorWizardPage"); //$NON-NLS-1$
+		this.jpaProject = jpaProject;
+		this.resourceManager = resourceManager;
+		this.schema = jpaProject.getDefaultDbSchema();
+		setTitle(JptUiEntityGenMessages.GenerateEntitiesWizard_tableSelectPage_selectTable );
+		setMessage(JptUiEntityGenMessages.GenerateEntitiesWizard_tableSelectPage_chooseEntityTable );
+	}
+
+	@Override
+	public void setVisible(boolean visible) {
+		super.setVisible(visible);
+		doStatusUpdate();
+	}
+
+	// -------- Provide access to wrapped DTP connection related classes ---------
+	ConnectionProfile getProjectConnectionProfile() {
+		String profileName = this.jpaProject.getDataSource().getConnectionProfileName();
+		return this.connectionProfileNamed(profileName);
+	}
+
+	ConnectionProfile connectionProfileNamed(String profileName) {
+		return JptDbPlugin.instance().getConnectionProfileFactory().buildConnectionProfile(profileName);
+	}
+
+	Schema getSchema(){
+		return this.schema;
+	}
+
+	void setSchema(Schema s){
+		this.schema = s;
+	}
+
+	private Collection<Table> possibleTables() {
+		Schema schema = this.getSchema();
+		if (schema != null && schema.getName() != null) {
+			return CollectionTools.collection(schema.getTables());
+		}
+		return Collections.<Table> emptyList();
+	}
+
+	public void createControl(Composite parent) {
+		initializeDialogUnits(parent);
+
+		Composite composite = new Composite(parent, SWT.NULL);
+		int nColumns= 3;
+		GridLayout layout = new GridLayout();
+		layout.numColumns = nColumns;
+		composite.setLayout(layout);
+		this.getHelpSystem().setHelp(composite, JpaHelpContextIds.GENERATE_ENTITIES_WIZARD_SELECT_TABLES);
+
+		this.databaseGroup = createDatabaseGroup(composite, 400);
+
+		createTablesSelectionControl(composite, nColumns);
+
+		
+		this.updatePersistenceXmlCheckBox = new Button(composite, SWT.CHECK);
+		this.updatePersistenceXmlCheckBox.setText(JptUiEntityGenMessages.GenerateEntitiesWizard_tableSelectPage_updatePersistenceXml );
+		this.updatePersistenceXmlCheckBox.setSelection(shouldUpdatePersistenceXml());
+		this.updatePersistenceXmlCheckBox.addSelectionListener(new SelectionListener() {
+			public void widgetDefaultSelected(SelectionEvent e) {}
+
+			public void widgetSelected(SelectionEvent e) {
+				setShouldUpdatePersistenceXml(updatePersistenceXmlCheckBox.getSelection());
+			}
+
+		});
+		fillColumns( this.updatePersistenceXmlCheckBox, 3);
+
+
+		//Filler column
+		new Label( composite, SWT.NONE);
+		//Restore default button
+		final Button restoreBtn = new Button(composite, SWT.PUSH );
+		restoreBtn.setText( JptUiEntityGenMessages.GenerateEntitiesWizard_tableSelectPage_Restore_Defaults );
+		restoreBtn.addSelectionListener(new SelectionListener() {
+			public void widgetDefaultSelected(SelectionEvent e) {}
+			public void widgetSelected(SelectionEvent e) {
+				if( customizer!=null && customizer.getFile()!=null ){
+					if( customizer.getFile().exists() ){
+						customizer.getFile().delete();
+					}
+					deselectAllTables();
+					restoreUpdatePersistenceXmlDefault();
+				}
+			}
+
+		});
+		GridData gridData = new GridData();
+		gridData.horizontalAlignment = SWT.END;
+		restoreBtn.setLayoutData(gridData);
+		
+		this.updateSelectionState(databaseGroup.getSelectedSchema());
+		this.getHelpSystem().setHelp(this.tableTable.getControl(), JpaHelpContextIds.DIALOG_GENERATE_ENTITIES_TABLES);
+		this.setControl(composite);
+
+		this.setPageComplete(true);
+	}
+	
+	private void restoreUpdatePersistenceXmlDefault(){
+		updatePersistenceXmlCheckBox.setSelection(true);
+		setShouldUpdatePersistenceXml(true);
+	}
+
+	@Override
+	public void dispose() {
+		if (this.databaseGroup != null)
+			this.databaseGroup.dispose();
+		super.dispose();
+	}
+
+	@Override
+	public IWizardPage getPreviousPage() {
+		IWizardPage prevPage = super.getPreviousPage();
+		if (prevPage instanceof PromptJPAProjectWizardPage)
+			//Prevent going back to the PromptJPAProjectWizardPage
+			//if JPA project already selected
+			return prevPage.getPreviousPage();
+		else
+			return prevPage;
+	}
+
+	private DatabaseGroup createDatabaseGroup(Composite parent, int widthHint) {
+		DatabaseGroup dbGroup = new DatabaseGroup(this.getContainer(), jpaProject, parent, resourceManager, widthHint);
+		/**
+		 * listen for when the Database Connection changes its selected schema
+		 * so we can keep the page in synch
+		 */
+		class DatabasePageListener implements DatabaseGroup.Listener {
+			public void selectedConnectionProfileChanged(ConnectionProfile connectionProfile) {
+				jpaProject.getDataSource().setConnectionProfileName(connectionProfile.getName());
+			}
+			@SuppressWarnings("unchecked")
+			public void selectedSchemaChanged(Schema schema) {
+				if (schema==null) {
+					updateTablesListViewer(Collections.EMPTY_LIST );
+				} else {
+					// store the *identifier* in the JPA project, since it gets put in Java annotations
+					jpaProject.setUserOverrideDefaultSchema(schema.getIdentifier());
+					setSchema( schema );
+					updateSelectionState(schema);
+				}
+				doStatusUpdate();
+			}
+		}
+		dbGroup.addListener(new DatabasePageListener());
+		dbGroup.init();
+		return dbGroup;
+	}
+
+	private boolean shouldUpdatePersistenceXml() {
+		return this.updatePersistenceXml;
+	}
+
+	private void setShouldUpdatePersistenceXml(boolean updatePersistenceXml){
+		this.updatePersistenceXml = updatePersistenceXml;
+		doStatusUpdate();
+	}
+
+	private void selectAllTables(){
+		this.tableTable.setAllChecked(true);
+		doStatusUpdate();
+	}
+
+	private void deselectAllTables(){
+		this.tableTable.setAllChecked(false);
+		doStatusUpdate();
+	}
+
+	private void initTablesSelectionControl(Collection<Table> possibleTables) {
+		this.tableTable.setInput(possibleTables);
+	}
+
+	private void createTablesSelectionControl(Composite parent, int columns) {
+		Label tableLabel = new Label(parent, SWT.NONE);
+		GridData gd= new GridData();
+		gd.horizontalAlignment = GridData.FILL;
+		gd.verticalAlignment = GridData.BEGINNING;
+		tableLabel.setLayoutData( gd );
+		tableLabel.setText( JptUiEntityGenMessages.GenerateEntitiesWizard_tableSelectPage_tables );
+		
+		TableLayoutComposite layout= new TableLayoutComposite(parent, SWT.NONE);
+		addColumnLayoutData(layout);
+
+		final org.eclipse.swt.widgets.Table table = new org.eclipse.swt.widgets.Table(layout, SWT.H_SCROLL | SWT.V_SCROLL | SWT.SINGLE | SWT.FULL_SELECTION | SWT.BORDER | SWT.CHECK);
+
+		TableColumn tableNameColumn = new TableColumn(table, SWT.NONE, TABLE_COLUMN_INDEX);
+		tableNameColumn.setText(JptUiEntityGenMessages.GenerateEntitiesWizard_tableSelectPage_tableColumn );
+		tableNameColumn.setResizable(true);
+
+		gd= new GridData(GridData.FILL_BOTH);
+		gd.heightHint= SWTUtil.getTableHeightHint(table, 20);
+		gd.widthHint = 250;
+		gd.grabExcessHorizontalSpace = true;
+		gd.grabExcessVerticalSpace = true ;
+		layout.setLayoutData(gd);
+		Color backgroundColor = new Color( Display.getDefault(), 255, 0,0);
+		layout.setBackground(backgroundColor);
+		backgroundColor.dispose();
+
+		this.tableTable = new CheckboxTableViewer(table);
+		this.tableTable.setUseHashlookup(true);
+		this.tableTable.setLabelProvider(this.buildTableTableLabelProvider());
+		this.tableTable.setContentProvider(this.buildTableTableContentProvider());
+		this.tableTable.setSorter(new ViewerSorter() {
+			@Override
+			public int compare(Viewer viewer, Object e1, Object e2) {
+				return ((Table) e1).getName().compareTo(((Table) e2).getName());
+			}
+		});
+
+		this.tableTable.addPostSelectionChangedListener(new ISelectionChangedListener() {
+			public void selectionChanged(SelectionChangedEvent event) {
+				handleTablesListSelectionChanged(event);
+			}
+		});
+
+		table.addKeyListener(new KeyAdapter() {
+			@Override
+			public void keyPressed(KeyEvent e) {
+				if (e.keyCode == SWT.F2 && e.stateMask == SWT.NONE) {
+					editEntityNameIfPossible();
+					e.doit= false;
+				}
+			}
+		});
+
+		createButtonComposite(parent);
+		initTablesSelectionControl(possibleTables());		
+	}
+
+	private void createButtonComposite(Composite parent){
+
+		Composite buttonComposite = new Composite(parent, SWT.NULL);
+		GridLayout buttonLayout = new GridLayout(1, false);
+		buttonLayout.marginHeight = 0;
+		buttonLayout.marginWidth = 0;
+		
+		buttonComposite.setLayout(buttonLayout);
+		GridData data =  new GridData();
+		data.horizontalAlignment = GridData.FILL;
+		data.verticalAlignment = GridData.BEGINNING;
+		buttonComposite.setLayoutData(data);
+
+		Button selectAllButton = new Button(buttonComposite, SWT.PUSH);
+		selectAllButton.setToolTipText(JptUiMessages.General_selectAll);
+		selectAllButton.setImage( ImageRepository.getSelectAllButtonImage(this.resourceManager)  );
+		GridData gridData =  new GridData();
+		gridData.horizontalAlignment = GridData.FILL;
+		selectAllButton.setLayoutData(gridData);
+		selectAllButton.addSelectionListener(new SelectionListener() {
+			public void widgetDefaultSelected(SelectionEvent e) {}
+
+			public void widgetSelected(SelectionEvent e) {
+				selectAllTables();
+			}
+		});
+
+		Button deselectAllButton = new Button(buttonComposite, SWT.PUSH);
+		deselectAllButton.setToolTipText(JptUiMessages.General_deselectAll);
+		deselectAllButton.setImage( ImageRepository.getDeselectAllButtonImage(this.resourceManager) );
+		gridData =  new GridData();
+		gridData.horizontalAlignment = GridData.FILL;
+		deselectAllButton.setLayoutData(gridData);
+		deselectAllButton.addSelectionListener(new SelectionListener() {
+			public void widgetDefaultSelected(SelectionEvent e) {}
+
+			public void widgetSelected(SelectionEvent e) {
+				deselectAllTables();
+			}
+		});
+	}
+
+
+	private void addColumnLayoutData(TableLayoutComposite layout) {
+		layout.addColumnData(new ColumnWeightData(50, true));
+	}
+
+	void editEntityNameIfPossible(){
+		Object[] selected = ((IStructuredSelection) this.tableTable.getSelection()).toArray();
+		if (selected.length != 1) {
+			return;
+		}
+	}
+
+	void handleTablesListSelectionChanged(SelectionChangedEvent event) {
+		doStatusUpdate();
+	}
+
+	private IBaseLabelProvider buildTableTableLabelProvider() {
+		return new TableTableLabelProvider();
+	}
+
+	private IContentProvider buildTableTableContentProvider() {
+		return new TableTableContentProvider();
+	}
+	
+	public Schema getDefaultSchema() {
+		return this.jpaProject.getDefaultDbSchema() ;
+	}
+	
+	Collection<Table> getSelectedTables() {
+		ArrayList<Table> selectedTables = new ArrayList<Table>();
+		for (Object selectedTable : this.tableTable.getCheckedElements())
+			selectedTables.add((Table) selectedTable);
+		return selectedTables;
+	}
+
+	private boolean hasTablesSelected() {
+		return (this.tableTable != null) ? (this.getSelectedTables().size() > 0) : false;
+	}
+
+	void updateTablesListViewer(Collection<Table> possibleTables) {
+		if (this.tableTable != null) {
+			this.initTablesSelectionControl(possibleTables);
+		}
+	}
+
+	/**
+	 * Update the status line and the OK button according to the given status
+	 */
+	protected void doStatusUpdate() {
+		if ( ! this.hasTablesSelected()) {
+			this.setPageComplete(false);
+		}else{
+			setPageComplete(true);
+			try{
+				getContainer().run(false, false, new IRunnableWithProgress(){
+					public void run( final IProgressMonitor monitor ) 
+				    	throws InvocationTargetException, InterruptedException
+				    {
+						monitor.beginTask("Updating", 10);
+				
+						Collection<Table> ret = getSelectedTables();
+						ArrayList<String> tableNames = new ArrayList<String>();
+						for( Table t : ret ){
+							tableNames.add(t.getName());
+						}
+						Schema schema = getSchema();
+						if( schema == null ){
+							return ;
+						}
+						customizer.setSchema(schema);
+						customizer.setTableNames(tableNames);
+						customizer.setShouldUpdatePersistenceXml(updatePersistenceXml);
+						monitor.done();
+				    }
+				});
+			} catch (Exception e) {
+				JptUiPlugin.log(e);
+			}
+				
+		}
+	}
+
+	// ********** inner classes **********
+	private class TableTableLabelProvider extends LabelProvider implements ITableLabelProvider {
+
+		TableTableLabelProvider() {
+			super();
+		}
+
+		@Override
+		public String getText(Object element) {
+			return ((Table) element).getName();
+		}
+
+		public Image getColumnImage(Object element, int columnIndex) {
+			return null;
+		}
+
+		public String getColumnText(Object element, int columnIndex) {
+			if (element == null) {
+				return null;
+			}
+			switch (columnIndex) {
+				case TABLE_COLUMN_INDEX:
+					return ((Table) element).getName();
+
+			}
+			throw new IllegalArgumentException("invalid column index: " + columnIndex);// $NON-NLS-1$
+		}
+
+	}
+
+
+	private class TableTableContentProvider implements IStructuredContentProvider {
+
+		TableTableContentProvider() {
+			super();
+		}
+
+		public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {	}
+
+		public void dispose() {}
+
+		public Object[] getElements(Object inputElement) {
+			return ((Collection<?>) inputElement).toArray();
+		}
+
+	}
+
+	private void updateSelectionState(final Schema schema) {
+		if(schema ==null)
+			return;
+		this.jpaProject.setUserOverrideDefaultSchema( schema.getIdentifier());
+		
+		updateTablesListViewer(CollectionTools.collection(schema.getTables()));
+
+		//Create the ORMGenCustomizer
+		GenerateEntitiesFromSchemaWizard wizard = (GenerateEntitiesFromSchemaWizard) getWizard();
+		customizer = wizard.createORMGenCustomizer( schema );
+
+		if( this.tableTable!=null && this.updatePersistenceXmlCheckBox!=null && customizer != null  ){
+			restoreWizardState();
+		}
+        doStatusUpdate();
+
+	}
+
+	private boolean restoreWizardState(){
+		boolean pageComplete = false;
+		this.updatePersistenceXmlCheckBox.setSelection(this.customizer.shouldUpdatePersistenceXml());
+		List<String> preSelectedTableNames = this.customizer.getTableNames();
+		if(preSelectedTableNames!=null && preSelectedTableNames.size()>0) {
+			Set<String> set = new HashSet<String>();
+			for(String s : preSelectedTableNames ){
+				set.add(s);
+			}
+	        TableItem[] items = this.tableTable.getTable().getItems();
+	        for (int i = 0; i < items.length; ++i) {
+	            TableItem item = items[i];
+	            org.eclipse.jpt.db.Table element = (org.eclipse.jpt.db.Table)item.getData();
+	            if (element != null) {
+	                boolean check = set.contains(element.getName());
+	                // only set if different, to avoid flicker
+	                if (item.getChecked() != check) {
+	                    item.setChecked(check);
+	                    pageComplete = true;
+	                }
+	            }
+	        }
+		}
+		return pageComplete;
+	}
+
+
+	/**
+	 * Set the layoutData of the input control to occupy specified number of columns
+	 * @param c
+	 * @param columns
+	 */
+	private void fillColumns(Control c, int columns){
+		GridData layoutData = new GridData();
+		layoutData.horizontalSpan = columns;
+		layoutData.verticalAlignment = SWT.FILL;
+		layoutData.horizontalAlignment = SWT.FILL;
+		layoutData.grabExcessHorizontalSpace = true;
+		layoutData.grabExcessVerticalSpace = false;
+		c.setLayoutData(layoutData);
+		return ;
+	}
+
+    @Override
+    public final void performHelp() 
+    {
+    	this.getHelpSystem().displayHelp( GenerateEntitiesFromSchemaWizard.HELP_CONTEXT_ID );
+    }
+    
+	protected final IWorkbenchHelpSystem getHelpSystem() {
+		return PlatformUI.getWorkbench().getHelpSystem();
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/orm/MappingFileWizard.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/orm/MappingFileWizard.java
new file mode 100644
index 0000000..2dc0c3a
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/orm/MappingFileWizard.java
@@ -0,0 +1,277 @@
+/*******************************************************************************
+ *  Copyright (c) 2008, 2010  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.ui.internal.wizards.orm;
+
+import java.lang.reflect.InvocationTargetException;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.IPackageFragment;
+import org.eclipse.jdt.core.IPackageFragmentRoot;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jem.util.emf.workbench.ProjectUtilities;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jpt.core.JptCorePlugin;
+import org.eclipse.jpt.core.context.JpaContextNode;
+import org.eclipse.jpt.core.context.persistence.PersistenceUnit;
+import org.eclipse.jpt.core.internal.operations.OrmFileCreationDataModelProperties;
+import org.eclipse.jpt.core.internal.operations.OrmFileCreationDataModelProvider;
+import org.eclipse.jpt.core.internal.utility.jdt.JDTTools;
+import org.eclipse.jpt.ui.JptUiPlugin;
+import org.eclipse.jpt.ui.internal.JptUiIcons;
+import org.eclipse.jpt.ui.internal.JptUiMessages;
+import org.eclipse.ui.INewWizard;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.ide.IDE;
+import org.eclipse.wst.common.frameworks.datamodel.DataModelPropertyDescriptor;
+import org.eclipse.wst.common.frameworks.datamodel.IDataModel;
+import org.eclipse.wst.common.frameworks.datamodel.IDataModelProvider;
+import org.eclipse.wst.common.frameworks.internal.datamodel.ui.DataModelWizard;
+
+public class MappingFileWizard extends DataModelWizard 
+	implements INewWizard 
+{
+	private MappingFileWizardPage page;
+	
+	
+	public MappingFileWizard() {
+		this(null);
+	}
+	
+	public MappingFileWizard(IDataModel dataModel) {
+		super(dataModel);
+		setWindowTitle(JptUiMessages.MappingFileWizard_title);
+		setDefaultPageImageDescriptor(JptUiPlugin.getImageDescriptor(JptUiIcons.JPA_FILE_WIZ_BANNER));
+	}
+	
+	
+	@Override
+	protected void doAddPages() {
+		super.doAddPages();
+		page = buildMappingFileWizardPage();
+		addPage(page);
+	}
+	
+	protected MappingFileWizardPage buildMappingFileWizardPage() {
+		return new MappingFileWizardPage(getDataModel(), "Page_1");
+	}
+	
+	@Override
+	protected IDataModelProvider getDefaultProvider() {
+		return new OrmFileCreationDataModelProvider();
+	}
+	
+	public void init(IWorkbench workbench, IStructuredSelection selection) {
+		// check for project, source folder, persistence unit?
+		if (selection == null || selection.isEmpty()) {
+			return;
+		}
+		
+		Object firstSelection = selection.getFirstElement();
+		
+		PersistenceUnit pUnit = extractPersistenceUnit(firstSelection);
+		IFolder sourceFolder = extractSourceFolder(pUnit, firstSelection);
+		IProject project = extractProject(pUnit, sourceFolder, firstSelection);
+		
+		if (project != null) {
+			getDataModel().setStringProperty(OrmFileCreationDataModelProperties.PROJECT_NAME, project.getName());
+		}
+		if (sourceFolder != null) {
+			getDataModel().setStringProperty(OrmFileCreationDataModelProperties.SOURCE_FOLDER, sourceFolder.getFullPath().toPortableString());
+		}
+		if (pUnit != null) {
+			getDataModel().setBooleanProperty(OrmFileCreationDataModelProperties.ADD_TO_PERSISTENCE_UNIT, true);
+			getDataModel().setStringProperty(OrmFileCreationDataModelProperties.PERSISTENCE_UNIT, pUnit.getName());
+		}
+	}
+	
+	private PersistenceUnit extractPersistenceUnit(Object selection) {
+		if (selection instanceof PersistenceUnit) {
+			return (PersistenceUnit) selection;
+		}
+		PersistenceUnit pUnit = null;
+		if (selection instanceof JpaContextNode) {
+			try {
+				pUnit = ((JpaContextNode) selection).getPersistenceUnit();
+			}
+			catch (Exception e) { /* do nothing, just continue */ }
+		}
+		if (pUnit == null && selection instanceof IAdaptable) {
+			pUnit = (PersistenceUnit) ((IAdaptable) selection).getAdapter(PersistenceUnit.class);
+			
+		}
+		return pUnit;
+	}
+	
+	private IFolder extractSourceFolder(PersistenceUnit pUnit, Object selection) {
+		IJavaProject javaProject = null;
+		IFolder srcFolder = null;
+		if (pUnit != null) {
+			javaProject = pUnit.getJpaProject().getJavaProject();
+			srcFolder = findSourceFolder(javaProject, pUnit.getResource());
+			if (srcFolder != null) {
+				return srcFolder;
+			}
+			
+		}
+		if (selection instanceof IResource) {
+			javaProject = JavaCore.create(((IResource) selection).getProject());
+			if (javaProject.exists()) {
+				srcFolder = findSourceFolder(javaProject, (IResource) selection);
+				if (srcFolder != null) {
+					return srcFolder;
+				}
+			}
+		}
+		
+		if (selection instanceof IAdaptable) {
+			IResource resource = (IResource) ((IAdaptable) selection).getAdapter(IResource.class);
+			if (resource != null) {
+				javaProject = JavaCore.create((resource).getProject());
+				if (javaProject.exists()) {
+					srcFolder = findSourceFolder(javaProject, resource);	
+					if (srcFolder != null) {
+						return srcFolder;
+					}
+				}
+			}
+		}
+		return null;
+	}
+	
+	private IFolder findSourceFolder(IJavaProject javaProject, IResource resource) {
+		if (JptCorePlugin.getJpaProject(javaProject.getProject()) == null) {
+			// not even a jpa project
+			return null;
+		}
+		while (resource != null && ! (resource instanceof IFolder)) {
+			resource = resource.getParent();
+		}
+		if (resource == null) {
+			return null;
+		}
+		IFolder folder = (IFolder) resource;
+		try {
+			IPackageFragmentRoot packageFragmentRoot = null;
+			while (packageFragmentRoot == null && folder != null) {
+				packageFragmentRoot = javaProject.findPackageFragmentRoot(folder.getFullPath());
+				if (packageFragmentRoot == null) {
+					IPackageFragment packageFragment = javaProject.findPackageFragment(folder.getFullPath());
+					if (packageFragment != null) {
+						packageFragmentRoot = (IPackageFragmentRoot) packageFragment.getAncestor(IJavaElement.PACKAGE_FRAGMENT_ROOT);
+					}
+				}
+				if (packageFragmentRoot == null) {
+					try {
+						folder = (IFolder) folder.getParent();
+					}
+					catch (ClassCastException cce) {
+						folder = null;
+					}
+				}
+			}
+			if (packageFragmentRoot == null) {
+				return null;
+			}
+			if (JDTTools.packageFragmentRootIsSourceFolder(packageFragmentRoot)) {
+				return (IFolder) packageFragmentRoot.getResource();
+			}
+		}
+		catch (JavaModelException jme) { /* do nothing, return null */ }
+		return null;
+	}
+	
+	private IProject extractProject(PersistenceUnit pUnit, IFolder sourceFolder, Object selection) {
+		if (pUnit != null) {
+			return pUnit.getJpaProject().getProject();
+		}
+		if (sourceFolder != null) {
+			return sourceFolder.getProject();
+		}
+		
+		IProject project = null;
+		if (selection instanceof IResource) {
+			project = ((IResource) selection).getProject();
+		}
+		if (project == null && selection instanceof IJavaElement) {
+			project = ((IJavaElement) selection).getJavaProject().getProject();
+		}
+		if (project == null && selection instanceof JpaContextNode) {
+			project = ((JpaContextNode) selection).getJpaProject().getProject();
+		}
+		if (project == null && selection instanceof IAdaptable) {
+			project = (IProject) ((IAdaptable) selection).getAdapter(IProject.class);
+			if (project == null) {
+				IResource resource = (IResource) ((IAdaptable) selection).getAdapter(IResource.class);
+				if (resource != null) {
+					project = resource.getProject();
+				}
+			}
+			if (project == null) {
+				IJavaElement javaElement = (IJavaElement) ((IAdaptable) selection).getAdapter(IJavaElement.class);
+				if (javaElement != null) {
+					project = javaElement.getJavaProject().getProject();
+				}
+			}
+		}
+		
+		if (project != null) {
+			for (DataModelPropertyDescriptor descriptor :
+					getDataModel().getValidPropertyDescriptors(OrmFileCreationDataModelProperties.PROJECT_NAME)) {
+				if (descriptor.getPropertyDescription().equals(project.getName())) {
+					return project;
+				}
+			}
+		}
+		return null;
+	}
+	
+	@Override
+	protected void postPerformFinish() throws InvocationTargetException {      
+        try {
+        	String projectName = (String) getDataModel().getProperty(OrmFileCreationDataModelProperties.PROJECT_NAME);
+        	IProject project = ProjectUtilities.getProject(projectName);
+        	String sourceFolder = getDataModel().getStringProperty(OrmFileCreationDataModelProperties.SOURCE_FOLDER);
+        	String filePath = getDataModel().getStringProperty(OrmFileCreationDataModelProperties.FILE_PATH);
+        	
+        	IFile file = project.getWorkspace().getRoot().getFile(new Path(sourceFolder).append(filePath));
+            openEditor(file);
+        } 
+        catch (Exception cantOpen) {
+        	throw new InvocationTargetException(cantOpen);
+        } 
+    }
+	
+	private void openEditor(final IFile file) {
+        if (file != null) {
+            getShell().getDisplay().asyncExec(new Runnable() {
+                public void run() {
+                    try {
+                        IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
+                        IDE.openEditor(page, file, true);
+                    }
+                    catch (PartInitException e) {
+                    	JptUiPlugin.log(e);
+                    }
+                }
+            });
+        }
+    }
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/orm/MappingFileWizardPage.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/orm/MappingFileWizardPage.java
new file mode 100644
index 0000000..ff8abe4
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/orm/MappingFileWizardPage.java
@@ -0,0 +1,295 @@
+/*******************************************************************************
+ *  Copyright (c) 2008, 2010 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.ui.internal.wizards.orm;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jem.util.emf.workbench.ProjectUtilities;
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.ITreeContentProvider;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerFilter;
+import org.eclipse.jface.window.Window;
+import org.eclipse.jpt.core.internal.AbstractJpaProject;
+import org.eclipse.jpt.core.internal.operations.OrmFileCreationDataModelProperties;
+import org.eclipse.jpt.core.internal.utility.jdt.JDTTools;
+import org.eclipse.jpt.ui.JptUiPlugin;
+import org.eclipse.jpt.ui.internal.JptUiMessages;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.dialogs.ElementTreeSelectionDialog;
+import org.eclipse.ui.dialogs.ISelectionStatusValidator;
+import org.eclipse.ui.model.WorkbenchContentProvider;
+import org.eclipse.ui.model.WorkbenchLabelProvider;
+import org.eclipse.wst.common.frameworks.datamodel.IDataModel;
+import org.eclipse.wst.common.frameworks.internal.datamodel.ui.DataModelWizardPage;
+
+public class MappingFileWizardPage extends DataModelWizardPage
+	implements OrmFileCreationDataModelProperties
+{
+	private Label projectNameLabel;
+		
+	private Combo projectNameCombo;	
+	
+	private Label sourceFolderLabel;
+	
+	private Text sourceFolderText;
+	
+	private Label filePathLabel;
+	
+	private Text filePathText;
+	
+	private Label accessLabel;
+	
+	private Combo accessCombo;
+	
+	private Button addToPersistenceUnitButton;
+	
+	private Label persistenceUnitLabel;
+	
+	private Combo persistenceUnitCombo;
+	
+	
+	public MappingFileWizardPage(IDataModel dataModel, String pageName) {
+		super(dataModel, pageName);
+		setTitle(JptUiMessages.MappingFileWizardPage_title);
+		setDescription(JptUiMessages.MappingFileWizardPage_desc);
+		setPageComplete(false);
+	}
+	
+	
+	@Override
+	protected String[] getValidationPropertyNames() {
+		return new String[] {
+			PROJECT_NAME,
+			SOURCE_FOLDER,
+			FILE_PATH,
+			DEFAULT_ACCESS,
+			ADD_TO_PERSISTENCE_UNIT,
+			PERSISTENCE_UNIT
+		};
+	}
+	
+	@Override
+	protected Composite createTopLevelComposite(Composite parent) {
+		Composite composite = new Composite(parent, SWT.NULL);
+		GridLayout layout = new GridLayout();
+		layout.numColumns = 3;
+		composite.setLayout(layout);
+		GridData data = new GridData();
+		data.verticalAlignment = GridData.FILL;
+		data.horizontalAlignment = GridData.FILL;
+		composite.setLayoutData(data);
+		
+		this.projectNameLabel = new Label(composite, SWT.NONE);
+		this.projectNameLabel.setText(JptUiMessages.MappingFileWizardPage_projectLabel);
+		data = new GridData();
+		this.projectNameLabel.setLayoutData(data);
+		
+		this.projectNameCombo = new Combo(composite, SWT.BORDER | SWT.READ_ONLY);
+		data = new GridData(GridData.FILL_HORIZONTAL);
+		data.horizontalSpan = 1;
+		data.grabExcessHorizontalSpace = true;
+		this.projectNameCombo.setLayoutData(data);
+		this.synchHelper.synchCombo(this.projectNameCombo, PROJECT_NAME, null);
+		new Label(composite, SWT.NONE);
+		
+		this.sourceFolderLabel = new Label(composite, SWT.NONE);
+		this.sourceFolderLabel.setText(JptUiMessages.MappingFileWizardPage_sourceFolderLabel);
+		data = new GridData();
+		this.sourceFolderLabel.setLayoutData(data);
+		
+		this.sourceFolderText = new Text(composite, SWT.BORDER);
+		data = new GridData(GridData.FILL_HORIZONTAL);
+		data.horizontalSpan = 1;
+		data.grabExcessHorizontalSpace = true;
+		this.sourceFolderText.setLayoutData(data);
+		this.synchHelper.synchText(this.sourceFolderText, SOURCE_FOLDER, null);
+		
+		Button sourceFolderButton = new Button(composite, SWT.PUSH);
+		sourceFolderButton.setText(JptUiMessages.General_browse);
+		data = new GridData();
+		data.horizontalSpan = 1;
+		sourceFolderButton.addSelectionListener(
+			new SelectionListener() {
+				public void widgetDefaultSelected(SelectionEvent e) {
+					widgetSelected(e);
+				}
+				
+				public void widgetSelected(SelectionEvent e) {
+					handleSourceFolderButtonPressed();
+				}
+			});
+		
+		Label separator = new Label(composite, SWT.SEPARATOR | SWT.HORIZONTAL);
+		data = new GridData(SWT.FILL, SWT.BEGINNING, true, false, 3, 1);
+		data.verticalIndent = 5;
+		separator.setLayoutData(data);
+		
+		this.filePathLabel = new Label(composite, SWT.NONE);
+		this.filePathLabel.setText(JptUiMessages.MappingFileWizardPage_filePathLabel);
+		data = new GridData();
+		data.verticalIndent = 5;
+		this.filePathLabel.setLayoutData(data);
+		
+		this.filePathText = new Text(composite, SWT.BORDER);
+		data = new GridData(GridData.FILL_HORIZONTAL);
+		data.horizontalSpan = 1;
+		data.verticalIndent = 5;
+		data.grabExcessHorizontalSpace = true;
+		this.filePathText.setLayoutData(data);
+		this.synchHelper.synchText(this.filePathText, FILE_PATH, null);
+		new Label(composite, SWT.NONE);
+		
+		this.accessLabel = new Label(composite, SWT.NONE);
+		this.accessLabel.setText(JptUiMessages.MappingFileWizardPage_accessLabel);
+		data = new GridData();
+		this.accessLabel.setLayoutData(data);
+		
+		this.accessCombo = new Combo(composite, SWT.BORDER | SWT.READ_ONLY);
+		data = new GridData(GridData.FILL_HORIZONTAL);
+		data.horizontalSpan = 1;
+		data.grabExcessHorizontalSpace = true;
+		this.accessCombo.setLayoutData(data);
+		this.synchHelper.synchCombo(this.accessCombo, DEFAULT_ACCESS, null);
+		new Label(composite, SWT.NONE);
+		
+		this.addToPersistenceUnitButton = new Button(composite, SWT.CHECK | SWT.BEGINNING);
+		this.addToPersistenceUnitButton.setText(JptUiMessages.MappingFileWizardPage_addToPersistenceUnitButton);
+		data = new GridData(GridData.FILL_HORIZONTAL);
+		data.horizontalSpan = 3;
+		data.verticalIndent = 10;
+		this.addToPersistenceUnitButton.setLayoutData(data);
+		this.synchHelper.synchCheckbox(this.addToPersistenceUnitButton, ADD_TO_PERSISTENCE_UNIT, null);
+		
+		this.persistenceUnitLabel = new Label(composite, SWT.NONE);
+		this.persistenceUnitLabel.setText(JptUiMessages.MappingFileWizardPage_persistenceUnitLabel);
+		data = new GridData();
+		data.horizontalIndent = 10;
+		this.persistenceUnitLabel.setLayoutData(data);
+		this.persistenceUnitLabel.setEnabled(false);
+		this.addToPersistenceUnitButton.addSelectionListener(new SelectionListener() {
+			public void widgetSelected(SelectionEvent e) {
+				persistenceUnitLabel.setEnabled(addToPersistenceUnitButton.getSelection());
+			}
+			public void widgetDefaultSelected(SelectionEvent e) {/*not called*/}
+		});
+		
+		this.persistenceUnitCombo = new Combo(composite, SWT.BORDER | SWT.READ_ONLY);
+		data = new GridData(GridData.FILL_HORIZONTAL);
+		data.horizontalSpan = 1;
+		data.grabExcessHorizontalSpace = true;
+		this.persistenceUnitCombo.setLayoutData(data);
+		this.synchHelper.synchCombo(this.persistenceUnitCombo, PERSISTENCE_UNIT, null);
+		
+		new Label(composite, SWT.NONE);
+		
+//		classText.setFocus();
+		PlatformUI.getWorkbench().getHelpSystem().setHelp(composite, getInfopopID());
+	    Dialog.applyDialogFont(parent);
+		return composite;
+	}
+	
+	private void handleSourceFolderButtonPressed() {
+		ISelectionStatusValidator validator = getSourceFolderDialogSelectionValidator();
+		ViewerFilter filter = getSourceFolderDialogViewerFilter();
+		ITreeContentProvider contentProvider = new WorkbenchContentProvider();
+		ILabelProvider labelProvider = new WorkbenchLabelProvider();
+		ElementTreeSelectionDialog dialog = new ElementTreeSelectionDialog(getShell(), labelProvider, contentProvider);
+		dialog.setValidator(validator);
+		dialog.setTitle(JptUiMessages.MappingFileWizardPage_accessLabel_sourceFolderDialogTitle);
+		dialog.setMessage(JptUiMessages.MappingFileWizardPage_accessLabel_sourceFolderDialogDesc);
+		dialog.addFilter(filter);
+		String projectName = model.getStringProperty(PROJECT_NAME);
+		if (projectName==null || projectName.length()==0) {
+			return;
+		}
+		IProject project = ProjectUtilities.getProject(projectName);
+		dialog.setInput(ResourcesPlugin.getWorkspace().getRoot());
+
+		if (project != null) {
+			dialog.setInitialSelection(project);
+		}
+		if (dialog.open() == Window.OK) {
+			Object element = dialog.getFirstResult();
+			if (element instanceof IContainer) {
+				IContainer container = (IContainer) element;
+				model.setProperty(SOURCE_FOLDER, container.getFullPath().toPortableString());
+			}
+		}
+	}
+	
+	private ISelectionStatusValidator getSourceFolderDialogSelectionValidator() {
+		return new ISelectionStatusValidator() {
+			public IStatus validate(Object[] selection) {
+				if (selection != null && selection[0] != null) {
+					if (selection[0] instanceof IProject) {
+						IProject project = (IProject) selection[0];
+						if (project.equals(AbstractJpaProject.getBundleRoot(project))) {
+							return Status.OK_STATUS;
+						}
+					}
+					else {
+						return Status.OK_STATUS;
+					}
+				}
+				return new Status(IStatus.ERROR, JptUiPlugin.PLUGIN_ID, JptUiMessages.MappingFileWizardPage_incorrectSourceFolderError);
+			}
+		};
+	}
+	
+	private ViewerFilter getSourceFolderDialogViewerFilter() {
+		return new ViewerFilter() {
+			@Override
+			public boolean select(Viewer viewer, Object parent, Object element) {
+				if (element instanceof IProject) {
+					IProject project = (IProject) element;
+					return project.getName().equals(model.getProperty(PROJECT_NAME));
+				} 
+				else if (element instanceof IContainer) {
+					IContainer container = (IContainer) element;
+					// only show source folders
+					IProject project = ProjectUtilities.getProject(model.getStringProperty(PROJECT_NAME));
+					IJavaProject javaProject = JavaCore.create(project);
+					if (JDTTools.packageFragmentRootIsSourceFolder(javaProject.getPackageFragmentRoot(container))) {
+						return true;
+					}
+					// add bundle root, if it exists
+					if (element.equals(AbstractJpaProject.getBundleRoot(project))) {
+						return true;
+					}
+				}
+				return false;
+			}
+		};
+	}
+	
+	void init(IWorkbench workbench, IStructuredSelection selection) {
+		
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/jface/DelegatingContentAndLabelProvider.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/jface/DelegatingContentAndLabelProvider.java
new file mode 100644
index 0000000..49c1949
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/jface/DelegatingContentAndLabelProvider.java
@@ -0,0 +1,207 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2009 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.ui.jface;
+
+import java.util.HashMap;
+import java.util.Map;
+import org.eclipse.jface.viewers.BaseLabelProvider;
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.jface.viewers.IStructuredContentProvider;
+import org.eclipse.jface.viewers.LabelProviderChangedEvent;
+import org.eclipse.jface.viewers.StructuredViewer;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.ui.navigator.IDescriptionProvider;
+
+/**
+ * Implementation of {@link IStructuredContentProvider} and {@link ILabelProvider} that 
+ * maintains a collection (Map, actually) of {@link ItemContentProvider} 
+ * delegates that perform the function of providing content and label information
+ * for each represented item
+ * 
+ * NB: This class, if used as a label provider *MUST* be used as a content provider
+ * for the same viewer.  It may be used as a content provider with a different
+ * label provider, however.
+ * 
+ * Provisional API: This class 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.
+ */
+public abstract class DelegatingContentAndLabelProvider 
+	extends BaseLabelProvider
+	implements IStructuredContentProvider, ILabelProvider, IDescriptionProvider
+{
+	private final ItemContentProviderFactory itemContentProviderFactory;
+	
+	private final ItemLabelProviderFactory itemLabelProviderFactory;
+	
+	private final Map<Object, ItemContentProvider> itemContentProviders;
+	
+	private final Map<Object, ItemLabelProvider> itemLabelProviders;
+	
+	StructuredViewer viewer;
+	
+	
+	protected DelegatingContentAndLabelProvider(
+			ItemContentProviderFactory itemContentProviderFactory) {
+		this(itemContentProviderFactory, null);
+	}
+	
+	protected DelegatingContentAndLabelProvider(
+			ItemContentProviderFactory itemContentProviderFactory,
+			ItemLabelProviderFactory itemLabelProviderFactory) {
+		super();
+		this.itemContentProviderFactory = itemContentProviderFactory;
+		this.itemLabelProviderFactory = itemLabelProviderFactory;
+		this.itemContentProviders = new HashMap<Object, ItemContentProvider>();
+		this.itemLabelProviders = new HashMap<Object, ItemLabelProvider>();
+	}
+	
+	
+	protected ItemContentProvider itemContentProvider(Object item) {
+		ItemContentProvider itemContentProvider = itemContentProviders.get(item);
+		if (itemContentProvider != null) {
+			return itemContentProvider;
+		}
+		itemContentProvider = itemContentProviderFactory.buildItemContentProvider(item, this);
+		if (itemContentProvider == null) {
+			return null;
+		}
+		itemContentProviders.put(item, itemContentProvider);
+		return itemContentProvider;
+	}
+	
+	protected ItemLabelProvider itemLabelProvider(Object item) {
+		if (viewer == null) {
+			throw new IllegalStateException(
+					"This provider must be used as a content" +
+					"provider *as well as* a label provider.");
+		}
+		ItemLabelProvider itemLabelProvider = itemLabelProviders.get(item);
+		if (itemLabelProvider != null) {
+			return itemLabelProvider;
+		}
+		itemLabelProvider = itemLabelProviderFactory.buildItemLabelProvider(item, this);
+		if (itemLabelProvider == null) {
+			return null;
+		}
+		itemLabelProviders.put(item, itemLabelProvider);
+		return itemLabelProvider;
+	}
+	
+	
+	public Object[] getElements(Object inputElement) {
+		return itemContentProvider(inputElement).getElements();
+	}
+	
+	public Image getImage(Object element) {
+		ItemLabelProvider provider = itemLabelProvider(element);
+		return (provider == null) ? null :provider.getImage();
+	}
+	
+	public String getText(Object element) {
+		ItemLabelProvider provider = itemLabelProvider(element);
+		return (provider == null) ? null : provider.getText();
+	}
+	
+	public String getDescription(Object element) {
+		ItemLabelProvider provider = itemLabelProvider(element);
+		return (provider == null) ? null : provider.getDescription();
+	}
+	
+	/**
+	 * Disposes all items
+	 */
+	@Override
+	public void dispose() {
+		disposeProviders();
+		super.dispose();
+	}
+
+	protected void disposeProviders() {
+		// coded this way to allow some item providers to dispose of their child 
+		// elements without disrupting the entire process
+		while (! itemContentProviders.isEmpty()) {
+			dispose(itemContentProviders.keySet().iterator().next());
+		}
+		// this catches any items that weren't disposed from the content providers,
+		// though there most likely won't be any items represented here that 
+		// haven't already been disposed
+		while (! itemLabelProviders.isEmpty()) {
+			dispose(itemLabelProviders.keySet().iterator().next());
+		}
+	}
+	
+	/**
+	 * Disposes item
+	 */
+	public void dispose(Object item) {
+		if (itemContentProviders.containsKey(item)) {
+			itemContentProviders.get(item).dispose();
+			itemContentProviders.remove(item);
+		}
+		if (itemLabelProviders.containsKey(item)) {
+			itemLabelProviders.get(item).dispose();
+			itemLabelProviders.remove(item);
+		}
+	}
+	
+	public void inputChanged(Viewer structuredViewer, Object oldInput, Object newInput) {
+		if (oldInput != newInput) {
+			disposeProviders();
+		}
+		this.viewer = (StructuredViewer) structuredViewer;
+	}
+	
+	/**
+	 * Update the content for the given item
+	 */
+	public void updateContent(final Object item) {
+		Runnable runnable = new Runnable() {
+			public void run() {
+				if (viewer != null && viewer.getControl() != null && !viewer.getControl().isDisposed()) {
+					viewer.refresh(item);
+				}
+			}
+		};
+		if (!viewerIsDisposed()) {
+			this.viewer.getControl().getDisplay().asyncExec(runnable);
+		}
+	}
+	
+	// open up visibility a bit for inner classes
+	@Override
+	protected void fireLabelProviderChanged(LabelProviderChangedEvent event) {
+		super.fireLabelProviderChanged(event);
+	}
+	
+	/**
+	 * Update the label for the given item
+	 */
+	public void updateLabel(final Object item) {
+		Runnable runnable = new Runnable() {
+			public void run() {
+				if (viewer != null && viewer.getControl() != null && !viewer.getControl().isDisposed()) {
+					fireLabelProviderChanged(new LabelProviderChangedEvent(DelegatingContentAndLabelProvider.this, item));
+				}
+			}
+		};
+		if (!viewerIsDisposed()) {
+			this.viewer.getControl().getDisplay().asyncExec(runnable);
+		}
+	}
+	
+	protected boolean viewerIsDisposed() {
+		return this.viewer.getControl().isDisposed();
+	}
+
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/jface/ItemContentProvider.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/jface/ItemContentProvider.java
new file mode 100644
index 0000000..102f712
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/jface/ItemContentProvider.java
@@ -0,0 +1,36 @@
+/*******************************************************************************
+ * Copyright (c) 2008 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.ui.jface;
+
+/**
+ * Marker interface used in conjunction with DelegatingContentProvider to return 
+ * content information for a particular item.
+ * @see DelegatingContentProvider
+ * @see ItemContentProviderFactory
+ * 
+ * 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.
+ */
+public interface ItemContentProvider
+{
+	/**
+	 * Return the elements of the represented item.
+	 * Note that when this is called, the represented item is an input element.
+	 */
+	Object[] getElements();
+	
+	/**
+	 * Dispose of this content provider, cleaning up all references, listeners, etc.
+	 */
+	void dispose();
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/jface/ItemContentProviderFactory.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/jface/ItemContentProviderFactory.java
new file mode 100644
index 0000000..ef2dd09
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/jface/ItemContentProviderFactory.java
@@ -0,0 +1,26 @@
+/*******************************************************************************
+ * Copyright (c) 2008 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.ui.jface;
+
+/**
+ * Factory interface used to describe how to build {@link ItemContentProvider}s
+ * for a {@link DelegatingContentAndLabelProvider}
+ * 
+ * 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.
+ */
+public interface ItemContentProviderFactory
+{
+	ItemContentProvider buildItemContentProvider(Object item, 
+			DelegatingContentAndLabelProvider contentAndLabelProvider);
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/jface/ItemLabelProvider.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/jface/ItemLabelProvider.java
new file mode 100644
index 0000000..91aca01
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/jface/ItemLabelProvider.java
@@ -0,0 +1,47 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2009 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.ui.jface;
+
+import org.eclipse.swt.graphics.Image;
+
+/**
+ * Interface used in conjunction with DelegatingLabelProvider to return 
+ * label information for a particular item.
+ * @see DelegatingLabelProvider
+ * @see ItemLabelProviderFactory
+ * 
+ * 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.
+ */
+public interface ItemLabelProvider
+{
+	/**
+	 * Return the image for the item
+	 */
+	Image getImage();
+	
+	/**
+	 * Return the text for the item
+	 */
+	public String getText();
+	
+	/**
+	 * Return the description for the item
+	 */
+	public String getDescription();
+	
+	/**
+	 * Dispose of this label provider, cleaning up all references, listeners, etc.
+	 */
+	void dispose();
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/jface/ItemLabelProviderFactory.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/jface/ItemLabelProviderFactory.java
new file mode 100644
index 0000000..7842a23
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/jface/ItemLabelProviderFactory.java
@@ -0,0 +1,26 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2009 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.ui.jface;
+
+/**
+ * Factory interface used to describe how to build IItemLabelProviders
+ * for a DelegatingContentAndLabelProvider
+ * 
+ * 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.
+ */
+public interface ItemLabelProviderFactory
+{
+	ItemLabelProvider buildItemLabelProvider(Object item, 
+			DelegatingContentAndLabelProvider contentAndLabelProvider);
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/jface/TreeItemContentProvider.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/jface/TreeItemContentProvider.java
new file mode 100644
index 0000000..a118505
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/jface/TreeItemContentProvider.java
@@ -0,0 +1,40 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2008 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.ui.jface;
+
+/**
+ * Interface used in conjunction with DelegatingTreeContentProvider to return 
+ * tree information for a particular item.
+ * @see DelegatingTreeContentProvider
+ * @see TreeItemContentProviderFactory
+ * 
+ * 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.
+ */
+public interface TreeItemContentProvider extends ItemContentProvider
+{
+	/**
+	 * Return the parent of the represented item
+	 */
+	Object getParent();
+	
+	/**
+	 * Return whether the represented item has children
+	 */
+	boolean hasChildren();
+	
+	/**
+	 * Return the children of the represented item
+	 */
+	Object[] getChildren();
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/jface/TreeItemContentProviderFactory.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/jface/TreeItemContentProviderFactory.java
new file mode 100644
index 0000000..dcc5eb4
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/jface/TreeItemContentProviderFactory.java
@@ -0,0 +1,26 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2008 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.ui.jface;
+
+/**
+ * Extension of {@link ItemContentProviderFactory} that extends functionality
+ * for tree content
+ * 
+ * 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.
+ */
+public interface TreeItemContentProviderFactory extends ItemContentProviderFactory
+{
+	public TreeItemContentProvider buildItemContentProvider(Object item, 
+			DelegatingContentAndLabelProvider contentAndLabelProvider);
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/jpa2/details/java/JavaUiFactory2_0.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/jpa2/details/java/JavaUiFactory2_0.java
new file mode 100644
index 0000000..ea72108
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/jpa2/details/java/JavaUiFactory2_0.java
@@ -0,0 +1,41 @@
+/*******************************************************************************
+ * Copyright (c) 2009 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.ui.jpa2.details.java;
+
+import org.eclipse.jpt.core.jpa2.context.java.JavaElementCollectionMapping2_0;
+import org.eclipse.jpt.ui.WidgetFactory;
+import org.eclipse.jpt.ui.details.JpaComposite;
+import org.eclipse.jpt.ui.details.java.JavaUiFactory;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * Use {@link JavaUiFactory2_0} to create any java JPA composites
+ * <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.
+ *
+ *
+ * @version 3.0
+ * @since 3.0
+ */
+public interface JavaUiFactory2_0
+	extends JavaUiFactory
+{	
+
+	JpaComposite createJavaElementCollectionMapping2_0Composite(
+		PropertyValueModel<JavaElementCollectionMapping2_0> subjectHolder,
+		Composite parent,
+		WidgetFactory widgetFactory);
+
+}
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/jpa2/details/orm/OrmXmlUiFactory2_0.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/jpa2/details/orm/OrmXmlUiFactory2_0.java
new file mode 100644
index 0000000..eee922f
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/jpa2/details/orm/OrmXmlUiFactory2_0.java
@@ -0,0 +1,41 @@
+/*******************************************************************************
+ * Copyright (c) 2009 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.ui.jpa2.details.orm;
+
+import org.eclipse.jpt.core.jpa2.context.orm.OrmElementCollectionMapping2_0;
+import org.eclipse.jpt.ui.WidgetFactory;
+import org.eclipse.jpt.ui.details.JpaComposite;
+import org.eclipse.jpt.ui.details.orm.OrmXmlUiFactory;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * Use {@link OrmXmlUiFactory2_0} to create any ORM JPA composites
+ * <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.
+ *
+ * @see org.eclipse.jpt.ui.internal.BaseJpaUiFactory
+ *
+ * @version 3.0
+ * @since 3.0
+ */
+public interface OrmXmlUiFactory2_0 extends OrmXmlUiFactory
+{
+	
+	JpaComposite createOrmElementCollectionMapping2_0Composite(
+		PropertyValueModel<OrmElementCollectionMapping2_0> subjectHolder,
+		Composite parent,
+		WidgetFactory widgetFactory);
+
+}
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/navigator/JpaNavigatorProvider.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/navigator/JpaNavigatorProvider.java
new file mode 100644
index 0000000..c193e97
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/navigator/JpaNavigatorProvider.java
@@ -0,0 +1,43 @@
+/*******************************************************************************
+ * Copyright (c) 2008 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.ui.navigator;
+
+import org.eclipse.jpt.ui.jface.ItemLabelProvider;
+import org.eclipse.jpt.ui.jface.ItemLabelProviderFactory;
+import org.eclipse.jpt.ui.jface.TreeItemContentProvider;
+import org.eclipse.jpt.ui.jface.TreeItemContentProviderFactory;
+
+/**
+ * This provider is responsible to create the Project Navigator view contents and 
+ * labels for a given JPA project.
+ *
+ * @version 2.0
+ * @since 2.0
+ * 
+ * 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.
+ */
+public interface JpaNavigatorProvider
+{
+	/**
+	 * Build an factory to create {@link TreeItemContentProvider}s
+	 */
+	TreeItemContentProviderFactory getTreeItemContentProviderFactory();
+	
+	/**
+	 * Build a factory to create {@link ItemLabelProvider}s
+	 */
+	ItemLabelProviderFactory getItemLabelProviderFactory();
+	
+	void dispose();
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/structure/JpaStructureProvider.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/structure/JpaStructureProvider.java
new file mode 100644
index 0000000..9a4b256
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/structure/JpaStructureProvider.java
@@ -0,0 +1,41 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2009 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.ui.structure;
+
+import org.eclipse.jpt.ui.jface.ItemLabelProvider;
+import org.eclipse.jpt.ui.jface.ItemLabelProviderFactory;
+import org.eclipse.jpt.ui.jface.TreeItemContentProvider;
+import org.eclipse.jpt.ui.jface.TreeItemContentProviderFactory;
+
+/**
+ * This provider is responsible to create the JPA Structure view contents and 
+ * labels for a given JPA resource.
+ *
+ * @version 3.0
+ * @since 2.0
+ *
+ * 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.
+ */
+public interface JpaStructureProvider 
+{
+	/**
+	 * Build an factory to create {@link TreeItemContentProvider}s
+	 */
+	TreeItemContentProviderFactory getTreeItemContentProviderFactory();
+	
+	/**
+	 * Build a factory to create {@link ItemLabelProvider}s
+	 */
+	ItemLabelProviderFactory getItemLabelProviderFactory();
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/templates/annotated_entity.javajet b/jpa/plugins/org.eclipse.jpt.ui/templates/annotated_entity.javajet
new file mode 100644
index 0000000..a2c7d1d
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/templates/annotated_entity.javajet
@@ -0,0 +1,64 @@
+<%@ jet package="org.eclipse.jpt.ui.internal.wizards.entity" 
+	imports="org.eclipse.jpt.ui.internal.wizards.entity.data.model.* java.util.* " 
+	class="AnnotatedEntityTemplate" 
+%>
+<% CreateEntityTemplateModel model = (CreateEntityTemplateModel) argument; 
+if (model.getJavaPackageName()!=null && model.getJavaPackageName()!="") { %>package <%=model.getJavaPackageName()%>;<%}%>
+
+<% Collection<String> imports = model.getImports(false);
+for (String anImport : imports) { %>
+import <%=anImport%>;
+<% } %>
+
+/**
+ * Entity implementation class for Entity: <%=model.getEntityName()%>
+ *
+ */
+<%=model.getArtifactType()%><%String ENTITY_NAME = model.getEntityName();
+if (model.isEntityNameSet()) {%>(name="<%=ENTITY_NAME%>")<%}%>
+<%if (model.isTableNameSet()) {%>
+@Table(name="<%=model.getTableName()%>")<%}%>
+<%=model.getInheritanceStrategy()%>
+<%if (model.isCompositePK()) {%>
+@IdClass(<%=model.getIdClassName()%>.class)<%}%>
+public class <%=model.getClassName()%><%String superClass = model.getSuperclassName();
+	if (! "".equals(superClass)) {%> extends <%=superClass%><%}%><%
+	List<String> interfaces = model.getInterfaces(); 
+	if (interfaces.size()>0) {%> implements <% }
+	for (int i=0; i<interfaces.size(); i++) {
+ 		String INTERFACE = (String) interfaces.get(i);
+		if (i>0) { %>, <%}%><%=INTERFACE%><%}%> {
+
+	<% List<EntityRow> fields = model.getEntityFields();
+	List<String> pkFields = model.getPKFields(); 
+ 	for (EntityRow entity : fields) {
+		String NAME = entity.getName();
+		if (pkFields.contains(NAME) && model.isFieldAccess()) {
+    %>   
+	@Id<%}%>
+	private <%=entity.getType()%> <%=entity.getName()%>;<%}%>
+	private static final long serialVersionUID = 1L;
+
+	public <%=model.getClassName()%>() {
+		super();
+	}
+   <%
+	fields = model.getEntityFields();
+	if (fields != null) for (int i=0; i<fields.size(); i++) {
+		EntityRow field = (EntityRow) fields.get(i);
+		String TYPE = field.getType();
+		String NAME = field.getName();
+		String METHOD = NAME.substring(0,1).toUpperCase() + NAME.substring(1);
+	if (pkFields.contains(NAME) && !model.isFieldAccess()) {
+    %>   
+	@Id <%}%>   
+	public <%=TYPE%> get<%=METHOD%>() {
+		return this.<%=NAME%>;
+	}
+
+	public void set<%=METHOD%>(<%=TYPE%> <%=NAME%>) {
+		this.<%=NAME%> = <%=NAME%>;
+	}
+   <%}%>
+   
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/templates/entity.javajet b/jpa/plugins/org.eclipse.jpt.ui/templates/entity.javajet
new file mode 100644
index 0000000..f58231c
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/templates/entity.javajet
@@ -0,0 +1,50 @@
+<%@ jet package="org.eclipse.jpt.ui.internal.wizards.entity" 
+	imports="org.eclipse.jpt.ui.internal.wizards.entity.data.model.* java.util.* " 
+	class="EntityTemplate" 
+%>
+<% CreateEntityTemplateModel model = (CreateEntityTemplateModel) argument; 
+if (model.getJavaPackageName()!=null && model.getJavaPackageName()!="") { %>package <%=model.getJavaPackageName()%>;<%}%>
+
+<% Collection<String> imports = model.getImports(false);
+for (String anImport : imports) { %>
+import <%=anImport%>;
+<% } %>
+
+/**
+ * Entity implementation class for Entity: <%=model.getEntityName()%>
+ *
+ */
+public class <%=model.getClassName()%><%String superClass = model.getSuperclassName();
+	if (! "".equals(superClass)) {%> extends <%=superClass%><%}%><%
+	List<String> interfaces = model.getInterfaces(); 
+	if (interfaces.size()>0) {%> implements <% }
+	for (int i=0; i<interfaces.size(); i++) {
+		String INTERFACE = (String) interfaces.get(i);
+		if (i>0) { %>, <%}%><%=INTERFACE%><%}%> {
+
+	<% List<EntityRow> fields = model.getEntityFields(); 
+	for (EntityRow entity : fields) {     
+	%> 
+	private <%=entity.getType()%> <%=entity.getName()%>;<%}%>
+	private static final long serialVersionUID = 1L;	
+	public <%=model.getClassName()%>() {
+		super();
+	} 
+	<%
+	fields = model.getEntityFields();
+	if (fields != null) for (int i=0; i<fields.size(); i++) {
+		EntityRow field = (EntityRow) fields.get(i);
+		String TYPE = field.getType();
+		String NAME = field.getName();
+		String METHOD = NAME.substring(0,1).toUpperCase() + NAME.substring(1);
+	%>   
+	public <%=TYPE%> get<%=METHOD%>() {
+ 		return this.<%=NAME%>;
+	}
+
+	public void set<%=METHOD%>(<%=TYPE%> <%=NAME%>) {
+		this.<%=NAME%> = <%=NAME%>;
+	}
+	<%}%>
+   
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/templates/idClass.javajet b/jpa/plugins/org.eclipse.jpt.ui/templates/idClass.javajet
new file mode 100644
index 0000000..7997344
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/templates/idClass.javajet
@@ -0,0 +1,124 @@
+<%@ jet	package="org.eclipse.jpt.ui.internal.wizards.entity" 
+	imports="org.eclipse.jpt.ui.internal.wizards.entity.data.model.* java.util.* " 
+	class="IdClassTemplate" 
+%>
+<% CreateEntityTemplateModel model = (CreateEntityTemplateModel) argument; 
+if (model.getJavaPackageName()!=null && model.getJavaPackageName()!="") { %>package <%=model.getJavaPackageName()%>;<%}%>
+
+<% Collection<String> imports = model.getImports(true);
+for (String anImport : imports) { %>
+import <%=anImport%>;
+<% } %>
+
+/**
+ * ID class for entity: <%=model.getClassName()%>
+ *
+ */ 
+public class <%=model.getIdClassName()%> 
+<% List<String> interfaces = model.getInterfaces(); 
+	if (interfaces.size()>0) {%> implements <% }
+	for (int i=0; i<interfaces.size(); i++) {
+		String INTERFACE = (String) interfaces.get(i);
+		if (i>0) { %>, <%}%><%=INTERFACE%><%}%> {   
+   
+	<% List<EntityRow> fields = model.getEntityFields();
+	List<String> pkFields = model.getPKFields(); 
+	for (int i=0; i<fields.size(); i++) {
+		EntityRow entity = (EntityRow) fields.get(i);
+		if (!pkFields.contains(entity.getName())) {
+			continue;
+		}
+	%>         
+	private <%=entity.getType()%> <%=entity.getName()%>;<%}%>
+	private static final long serialVersionUID = 1L;
+
+	public <%=model.getIdClassName()%>() {}
+
+	<%
+	fields = model.getEntityFields();
+	if (fields != null) for (int i=0; i<fields.size(); i++) {
+		EntityRow field = (EntityRow) fields.get(i);
+		String TYPE = field.getType();
+		String NAME = field.getName();
+		if (!pkFields.contains(NAME)) {
+			continue;
+		} 		
+		String METHOD = NAME.substring(0,1).toUpperCase() + NAME.substring(1);        
+	%>
+
+	public <%=TYPE%> get<%=METHOD%>() {
+		return this.<%=NAME%>;
+	}
+
+	public void set<%=METHOD%>(<%=TYPE%> <%=NAME%>) {
+		this.<%=NAME%> = <%=NAME%>;
+	}
+	<%}%>
+   
+	/*
+	 * @see java.lang.Object#equals(Object)
+	 */	
+	public boolean equals(Object o) {
+		if (o == this) {
+			return true;
+		}
+		if (!(o instanceof <%=model.getIdClassName()%>)) {
+			return false;
+		}
+		<%=model.getIdClassName()%> other = (<%=model.getIdClassName()%>) o;
+		return true
+<% if (fields != null) for (int i=0; i<fields.size(); i++) {
+	EntityRow field = (EntityRow) fields.get(i); 
+	String NAME = field.getName();
+	if (!pkFields.contains(NAME)) {
+       	continue;
+    }%>
+<% 	String TYPE = field.getType(); 
+	String GET_METHOD = "get" + NAME.substring(0,1).toUpperCase() + NAME.substring(1); %>
+<%	if (TYPE.equals("boolean") || TYPE.equals("byte") || TYPE.equals("char") || TYPE.equals("short") || TYPE.equals("int") || TYPE.equals("long")) { %>
+			&& <%=GET_METHOD%>() == other.<%=GET_METHOD%>()
+<% 	} else if (TYPE.equals("double")) { %>
+			&& (Double.doubleToLongBits(<%=GET_METHOD%>()) == Double.doubleToLongBits(other.<%=GET_METHOD%>()))
+<% 	} else if (TYPE.equals("float")) { %>
+			&& (Float.floatToIntBits(<%=GET_METHOD%>()) == Float.floatToIntBits(other.<%=GET_METHOD%>()))
+<% 	} else { %>
+			&& (<%=GET_METHOD%>() == null ? other.<%=GET_METHOD%>() == null : <%=GET_METHOD%>().equals(other.<%=GET_METHOD%>()))
+<% 	} %>
+<% } %>;
+	}
+	
+	/*	 
+	 * @see java.lang.Object#hashCode()
+	 */	
+	public int hashCode() {
+		final int prime = 31;
+		int result = 1;
+<% if (fields != null) for (int i=0; i<fields.size(); i++) { 
+	EntityRow field = (EntityRow) fields.get(i);
+	String NAME = field.getName();
+	if (!pkFields.contains(NAME)) {
+       	continue;
+    }%>
+<% 	String TYPE = field.getType(); 
+	String GET_METHOD = "get" + NAME.substring(0,1).toUpperCase() + NAME.substring(1); %>
+<%	if (TYPE.equals("boolean")) { %>
+		result = prime * result + (<%=GET_METHOD%>() ? 1 : 0);
+<% 	} else if (TYPE.equals("int")) { %>
+		result = prime * result + <%=GET_METHOD%>();
+<% 	} else if (TYPE.equals("byte") || TYPE.equals("char") || TYPE.equals("short")) { %>
+		result = prime * result + ((int) <%=GET_METHOD%>());
+<% 	} else if (TYPE.equals("long")) { %>
+		result = prime * result + ((int) (<%=GET_METHOD%>() ^ (<%=GET_METHOD%>() >>> 32)));
+<% 	} else if (TYPE.equals("double")) { %>
+		result = prime * result + ((int) (Double.doubleToLongBits(<%=GET_METHOD%>() ) ^ (Double.doubleToLongBits(<%=GET_METHOD%>()) >>> 32)));
+<% 	} else if (TYPE.equals("float")) { %>
+		result = prime * result + Float.floatToIntBits(<%=GET_METHOD%>());
+<% 	} else { %>
+		result = prime * result + (<%=GET_METHOD%>() == null ? 0 : <%=GET_METHOD%>().hashCode());
+<% 	} %>
+<% } %>
+		return result;
+	}
+   
+   
+}