Library provider integration
diff --git a/jpa/plugins/org.eclipse.jpt.core/META-INF/MANIFEST.MF b/jpa/plugins/org.eclipse.jpt.core/META-INF/MANIFEST.MF
index f373fe6..40373c4 100644
--- a/jpa/plugins/org.eclipse.jpt.core/META-INF/MANIFEST.MF
+++ b/jpa/plugins/org.eclipse.jpt.core/META-INF/MANIFEST.MF
@@ -21,6 +21,7 @@
  org.eclipse.jem.workbench;bundle-version="[2.0.100,3.0.0)",
  org.eclipse.jpt.db;bundle-version="[1.2.0,2.0.0)",
  org.eclipse.jpt.utility;bundle-version="[1.2.0,2.0.0)",
+ org.eclipse.jst.common.project.facet.core;bundle-version="1.3.100",
  org.eclipse.jst.j2ee;bundle-version="[1.1.200,1.2.0)",
  org.eclipse.jst.j2ee.core;bundle-version="[1.1.200,1.2.0)",
  org.eclipse.jst.jee.ejb;bundle-version="[1.0.100,1.1.0)",
diff --git a/jpa/plugins/org.eclipse.jpt.core/plugin.properties b/jpa/plugins/org.eclipse.jpt.core/plugin.properties
index a605757..49bce3d 100644
--- a/jpa/plugins/org.eclipse.jpt.core/plugin.properties
+++ b/jpa/plugins/org.eclipse.jpt.core/plugin.properties
@@ -28,14 +28,17 @@
 JPA_PROBLEM_MARKER=JPA Problem Marker
 JPA_FILE_CONTENT=JPA File Content
 
+BASE_JPA_CONTENT = Base JPA Content
+ORM_XML_CONTENT = ORM XML Content
+PERSISTENCE_XML_CONTENT = Persistence XML Content
+
 GENERIC_PLATFORM_LABEL=Generic
 
+NO_OP_LIBRARY_PROVIDER_WARNING = Library configuration is disabled. The user may need to configure further classpath changes later.
+NO_OP_LIBRARY_PROVIDER_MESSAGE = The JPA facet requires a JPA implementation library to be present on the project classpath. By disabling library configuration, the user takes on the responsibility of ensuring that the classpath is configured appropriately via alternate means.
+
 JPA_FACET_LABEL=Java Persistence
 JPA_FACET_DESCRIPTION=Adds support for writing persistent meta-data using Java Persistence Architecture.
 JPA_PRESET_LABEL=Utility JPA project with Java 5.0
 JPA_TEMPLATE_LABEL=JPA Project
 JPA_VALIDATOR=JPA Validator
-
-BASE_JPA_CONTENT = Base JPA Content
-ORM_XML_CONTENT = ORM XML Content
-PERSISTENCE_XML_CONTENT = Persistence XML Content
diff --git a/jpa/plugins/org.eclipse.jpt.core/plugin.xml b/jpa/plugins/org.eclipse.jpt.core/plugin.xml
index 4a55ba0..280bdf3 100644
--- a/jpa/plugins/org.eclipse.jpt.core/plugin.xml
+++ b/jpa/plugins/org.eclipse.jpt.core/plugin.xml
@@ -47,6 +47,14 @@
 			class="org.eclipse.jpt.core.internal.JpaPlatformTester">
 		</propertyTester>
 		
+		<propertyTester
+			id="org.eclipse.jpt.core.propertyTester.enablementExpressionContext"
+			type="org.eclipse.jst.common.project.facet.core.libprov.EnablementExpressionContext"
+			namespace="org.eclipse.jpt.core"
+			properties="jpaPlatform"
+			class="org.eclipse.jpt.core.internal.JpaPlatformTester">
+		</propertyTester>
+			
 	</extension>
 	
 	
@@ -149,7 +157,44 @@
 			factoryClass="org.eclipse.jpt.core.internal.resource.orm.OrmXmlResourceProviderFactory"/>
 		
 	</extension>
+	
+	
+	<!--
+	******************************************
+	* Library Provider Framework Integration *
+	******************************************
+	-->
+	
+	<extension 
+		point="org.eclipse.jst.common.project.facet.core.libraryProviders">
 		
+		<provider id="jpa-no-op-library-provider" extends="no-op-library-provider">
+			<param name="message" value="%NO_OP_LIBRARY_PROVIDER_WARNING"/>
+			<param name="warning" value="%NO_OP_LIBRARY_PROVIDER_MESSAGE"/>
+			<enablement>
+				<with variable="requestingProjectFacet">
+					<test property="org.eclipse.wst.common.project.facet.core.projectFacet" value="jpt.jpa" forcePluginActivation="true"/>
+				</with>
+			</enablement>
+		</provider>
+		
+		<provider id="jpa-generic-user-library-provider" extends="wtp-user-library-provider">
+			<param name="validator" value="org.eclipse.jst.common.project.facet.core.libprov.user.KeyClassesValidator"/>
+			<param name="validator.param.0" value="javax.persistence.Entity"/>
+			<enablement>
+				<and>
+					<with variable="requestingProjectFacet">
+						<test property="org.eclipse.wst.common.project.facet.core.projectFacet" value="jpt.jpa" forcePluginActivation="true"/>
+					</with>
+					<with variable="context">
+						<test property="org.eclipse.jpt.core.jpaPlatform" value="generic"/>
+					</with>
+				</and>
+			</enablement>
+		</provider>
+		
+	</extension>
+	
 	
 	<!-- ***** WTP extensions ***** -->
 
@@ -289,8 +334,5 @@
 		</catalogContribution>
 		
 	</extension>
- <extension
-       point="org.eclipse.jpt.core.resourceModelProviders">
- </extension>
-
+	
 </plugin>
diff --git a/jpa/plugins/org.eclipse.jpt.core/property_files/jpa_core.properties b/jpa/plugins/org.eclipse.jpt.core/property_files/jpa_core.properties
index 7a20df2..be5f9e1 100644
--- a/jpa/plugins/org.eclipse.jpt.core/property_files/jpa_core.properties
+++ b/jpa/plugins/org.eclipse.jpt.core/property_files/jpa_core.properties
@@ -25,6 +25,7 @@
 VALIDATE_CONNECTION_INVALID=Connection profile ''{0}'' does not exist
 VALIDATE_CONNECTION_NOT_CONNECTED=Connection must be active to get data source specific help and validation.
 VALIDATE_DEFAULT_SCHEMA_NOT_SPECIFIED=Default schema is not specified
+VALIDATE_CONNECTION_DOESNT_CONTAIN_SCHEMA=Schema ''{0}'' does not exist on the connection specified
 VALIDATE_RUNTIME_NOT_SPECIFIED=There is no server runtime associated with this project to provide a JPA implementation
 VALIDATE_RUNTIME_DOES_NOT_SUPPORT_EJB_30=The server runtime selected does not support EJB 3.0, so it likely does not provide a JPA implementation
 VALIDATE_LIBRARY_NOT_SPECIFIED=No JPA implementation library specified
diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/GenericJpaProject.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/GenericJpaProject.java
index 0f86e13..2257993 100644
--- a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/GenericJpaProject.java
+++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/GenericJpaProject.java
@@ -13,7 +13,6 @@
 import java.util.Iterator;
 import java.util.List;
 import java.util.Vector;
-
 import org.eclipse.core.resources.IFile;
 import org.eclipse.core.resources.IProject;
 import org.eclipse.core.resources.IResource;
@@ -30,16 +29,11 @@
 import org.eclipse.jdt.core.ElementChangedEvent;
 import org.eclipse.jdt.core.IAnnotatable;
 import org.eclipse.jdt.core.IAnnotation;
-import org.eclipse.jdt.core.IClassFile;
 import org.eclipse.jdt.core.ICompilationUnit;
-import org.eclipse.jdt.core.IField;
 import org.eclipse.jdt.core.IJavaElement;
 import org.eclipse.jdt.core.IJavaElementDelta;
 import org.eclipse.jdt.core.IJavaProject;
-import org.eclipse.jdt.core.IMethod;
-import org.eclipse.jdt.core.IPackageFragment;
 import org.eclipse.jdt.core.IPackageFragmentRoot;
-import org.eclipse.jdt.core.IType;
 import org.eclipse.jdt.core.JavaCore;
 import org.eclipse.jdt.core.JavaModelException;
 import org.eclipse.jpt.core.JpaDataSource;
@@ -49,7 +43,6 @@
 import org.eclipse.jpt.core.JpaResourceModelListener;
 import org.eclipse.jpt.core.JptCorePlugin;
 import org.eclipse.jpt.core.context.JpaRootContextNode;
-import org.eclipse.jpt.core.internal.utility.PlatformTools;
 import org.eclipse.jpt.core.internal.validation.DefaultJpaValidationMessages;
 import org.eclipse.jpt.core.internal.validation.JpaValidationMessages;
 import org.eclipse.jpt.core.resource.java.JavaResourceCompilationUnit;
diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/JpaPlatformTester.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/JpaPlatformTester.java
index 17236d7..1ce8267 100644
--- a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/JpaPlatformTester.java
+++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/JpaPlatformTester.java
@@ -13,6 +13,14 @@
 import org.eclipse.core.resources.IResource;
 import org.eclipse.jdt.core.IJavaElement;
 import org.eclipse.jpt.core.JptCorePlugin;
+import org.eclipse.jpt.core.internal.facet.JpaFacetDataModelProperties;
+import org.eclipse.jst.common.project.facet.core.libprov.EnablementExpressionContext;
+import org.eclipse.wst.common.frameworks.datamodel.IDataModel;
+import org.eclipse.wst.common.project.facet.core.IFacetedProjectBase;
+import org.eclipse.wst.common.project.facet.core.IProjectFacet;
+import org.eclipse.wst.common.project.facet.core.ProjectFacetsManager;
+import org.eclipse.wst.common.project.facet.core.IFacetedProject.Action;
+import org.eclipse.wst.common.project.facet.core.internal.FacetedProjectWorkingCopy;
 
 public class JpaPlatformTester extends PropertyTester {
 	
@@ -20,20 +28,38 @@
 		if (! property.equals("jpaPlatform")) { //$NON-NLS-1$
 			return false;
 		}
-		IProject project = null;
-		if (receiver instanceof IResource) {
-			project = ((IResource) receiver).getProject();
-		}
-		else if (receiver instanceof IJavaElement) {
-	        project = ((IJavaElement) receiver).getResource().getProject();
-		}
 		
-		if (project == null) {
-			return false;
+		String platformId = null;
+		
+		if (receiver instanceof IResource) {
+			platformId = platformId(((IResource) receiver).getProject());
+		} 
+		else if (receiver instanceof IJavaElement) {
+			platformId = platformId(((IJavaElement) receiver).getResource().getProject());
+		} 
+		else if (receiver instanceof EnablementExpressionContext) {
+			EnablementExpressionContext context = (EnablementExpressionContext) receiver;
+			IFacetedProjectBase fp = context.getFacetedProject();
+			if (fp instanceof FacetedProjectWorkingCopy){
+				FacetedProjectWorkingCopy fpwc = (FacetedProjectWorkingCopy) fp;
+				IProjectFacet jpaFacet = ProjectFacetsManager.getProjectFacet(JptCorePlugin.FACET_ID);
+				Action action =  fpwc.getProjectFacetAction(jpaFacet);
+				if (action != null ) {
+					// in project creation wizard
+					IDataModel model = (IDataModel) action.getConfig();
+	            	platformId = (String) model.getProperty(JpaFacetDataModelProperties.PLATFORM_ID);
+				}
+			} 
+			else {
+				// in facet property page
+				platformId = platformId(fp.getProject());
+			}
 		}
-
-		String platformId = JptCorePlugin.getJpaPlatformId(project);
 		
 		return platformId == null ? false : platformId.equals(expectedValue);
-	}		
+	}
+	
+	private String platformId(IProject project) {
+		return (project == null) ? null : JptCorePlugin.getJpaPlatformId(project);
+	}
 }
diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/JptCoreMessages.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/JptCoreMessages.java
index 149c6a2..4d3c5a5 100644
--- a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/JptCoreMessages.java
+++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/JptCoreMessages.java
@@ -33,6 +33,7 @@
 	public static String VALIDATE_CONNECTION_INVALID;
 	public static String VALIDATE_CONNECTION_NOT_CONNECTED;
 	public static String VALIDATE_DEFAULT_SCHEMA_NOT_SPECIFIED;
+	public static String VALIDATE_CONNECTION_DOESNT_CONTAIN_SCHEMA;
 	public static String VALIDATE_RUNTIME_NOT_SPECIFIED;
 	public static String VALIDATE_RUNTIME_DOES_NOT_SUPPORT_EJB_30;
 	public static String VALIDATE_LIBRARY_NOT_SPECIFIED;
diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/facet/JpaFacetDataModelProperties.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/facet/JpaFacetDataModelProperties.java
index dd70b93..1a4ad9b 100644
--- a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/facet/JpaFacetDataModelProperties.java
+++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/facet/JpaFacetDataModelProperties.java
@@ -14,11 +14,23 @@
 public interface JpaFacetDataModelProperties extends IDataModelProperties
 {
 	/**
+	 * Internal, type IRuntime, identifies runtime associated with project
+	 * Used only in conjunction with validation of other properties, because this information
+	 * is otherwise inaccessible to this data model
+	 */
+	public static final String RUNTIME = "JpaFacetDataModelProperties.RUNTIME";
+	
+	/**
 	 * Required, type String, identifies Jpa Platform
 	 */
 	public static final String PLATFORM_ID = "JpaFacetDataModelProperties.PLATFORM_ID";
 	
 	/**
+	 * Required, type LibraryInstallDelegate, the library install delegate used to configure JPA provider library
+	 */
+    public static final String LIBRARY_PROVIDER_DELEGATE = "JpaFacetDataModelProperties.LIBRARY_PROVIDER_DELEGATE"; //$NON-NLS-1$    
+	
+    /**
 	 * Not required, type String, identifies database connection
 	 */
 	public static final String CONNECTION = "JpaFacetDataModelProperties.CONNECTION";
@@ -29,6 +41,22 @@
 	public static final String CONNECTION_ACTIVE = "JpaFacetDataModelProperties.CONNECTION_ACTIVE";
 	
 	/**
+	 * Required, type Boolean, identifies if the user wishes to add the database driver jars to the classpath
+	 */
+	public static final String USER_WANTS_TO_ADD_DB_DRIVER_JARS_TO_CLASSPATH = 
+		"JpaFacetDataModelProperties.USER_WANTS_TO_ADD_DB_DRIVER_JARS_TO_CLASSPATH";
+
+	/**
+	 * Not required, type String, identifies the database driver library added to the classpath
+	 */
+	public static final String DB_DRIVER_NAME = "JpaFacetDataModelProperties.DB_DRIVER_NAME";
+
+	/**
+	 * Not required, type String, identifies the database driver jars added to the classpath
+	 */
+	public static final String DB_DRIVER_JARS = "JpaFacetDataModelProperties.DB_DRIVER_JARS";
+	
+	/**
 	 * Required, type Boolean, identifies if the user wishes to override default schema name
 	 */
 	public static final String USER_WANTS_TO_OVERRIDE_DEFAULT_SCHEMA = 
@@ -39,54 +67,6 @@
 	 */
 	public static final String USER_OVERRIDE_DEFAULT_SCHEMA = 
 		"JpaFacetDataModelProperties.USER_OVERRIDE_DEFAULT_SCHEMA";
-
-	/**
-	 * Required, type Boolean, identifies if the user wishes to add the database driver jars to the classpath
-	 */
-	public static final String USER_WANTS_TO_ADD_DB_DRIVER_JARS_TO_CLASSPATH = 
-		"JpaFacetDataModelProperties.USER_WANTS_TO_ADD_DB_DRIVER_JARS_TO_CLASSPATH";
-
-	/**
-	 * Not required, type String, identifies the database driver library added to the classpath
-	 */
-	public static final String DB_DRIVER_NAME = 
-			"JpaFacetDataModelProperties.DB_DRIVER_NAME";
-
-	/**
-	 * Not required, type String, identifies the database driver jars added to the classpath
-	 */
-	public static final String DB_DRIVER_JARS = 
-			"JpaFacetDataModelProperties.DB_DRIVER_JARS";
-	
-	/**
-	 * Internal, type IRuntime, identifies runtime associated with project
-	 * Used only in conjunction with validation of other properties, because this information
-	 * is otherwise inaccessible to this data model
-	 */
-	public static final String RUNTIME = "JpaFacetDataModelProperties.RUNTIME";
-	
-	/**
-	 * Required, type boolean, opposite of USE_USER_JPA_LIBRARY, identifies whether 
-	 * server runtime provides JPA implementation
-	 * If this is true, then the property JPA_LIBRARY is not used
-	 */
-	public static final String USE_SERVER_JPA_IMPLEMENTATION = "JpaFacetDataModelProperties.USE_SERVER_JPA_IMPLEMENTATION";
-	
-	/**
-	 * Required, type boolean, opposite of USE_SERVER_JPA_IMPLEMENTATION, identifies
-	 * whether the user is providing his own JPA library 
-	 * (This additional setting is necessary in order to use synchHelper within
-	 * the wizard - there must be a unique property for each radio button. Stupid
-	 * but true)
-	 * If this is true, then the property JPA_LIBRARY is used
-	 */
-	public static final String USE_USER_JPA_LIBRARY = "JpaFacetDataModelProperties.USE_USER_JPA_LIBRARY";
-	
-	/**
-	 * Not required, type String, identifies JPA implementation library.
-	 * Only used if the property USE_SERVER_JPA_IMPLEMENTATION is false.
-	 */
-	public static final String JPA_LIBRARY = "JpaFacetDataModelProperties.JPA_LIBRARY";
 	
 	/**
 	 * Required, type boolean, opposite of LIST_ANNOTATED_CLASSES, identifies 
diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/facet/JpaFacetDataModelProvider.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/facet/JpaFacetDataModelProvider.java
index 339ec62..5e522dc 100644
--- a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/facet/JpaFacetDataModelProvider.java
+++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/facet/JpaFacetDataModelProvider.java
@@ -15,7 +15,6 @@
 import java.util.Set;
 import org.eclipse.core.runtime.IStatus;
 import org.eclipse.core.runtime.Status;
-import org.eclipse.jdt.core.JavaCore;
 import org.eclipse.jpt.core.JptCorePlugin;
 import org.eclipse.jpt.core.internal.JptCoreMessages;
 import org.eclipse.jpt.core.internal.platform.JpaPlatformRegistry;
@@ -30,6 +29,8 @@
 import org.eclipse.jpt.utility.internal.iterators.CompositeIterator;
 import org.eclipse.jpt.utility.internal.iterators.EmptyIterator;
 import org.eclipse.jpt.utility.internal.iterators.TransformationIterator;
+import org.eclipse.jst.common.project.facet.core.libprov.IPropertyChangeListener;
+import org.eclipse.jst.common.project.facet.core.libprov.LibraryInstallDelegate;
 import org.eclipse.osgi.util.NLS;
 import org.eclipse.wst.common.componentcore.datamodel.FacetInstallDataModelProvider;
 import org.eclipse.wst.common.componentcore.internal.util.IModuleConstants;
@@ -37,6 +38,7 @@
 import org.eclipse.wst.common.frameworks.datamodel.IDataModel;
 import org.eclipse.wst.common.frameworks.internal.plugin.WTPCommonMessages;
 import org.eclipse.wst.common.frameworks.internal.plugin.WTPCommonPlugin;
+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.core.runtime.IRuntime;
@@ -64,22 +66,24 @@
 	private static final IStatus RUNTIME_DOES_NOT_SUPPORT_EJB_30_STATUS = 
 			buildWarningStatus(JptCoreMessages.VALIDATE_RUNTIME_DOES_NOT_SUPPORT_EJB_30);
 	
-	private static final IStatus LIBRARY_NOT_SPECIFIED_STATUS = 
-			buildWarningStatus(JptCoreMessages.VALIDATE_LIBRARY_NOT_SPECIFIED);
-
+	
+	private LibraryInstallDelegate defaultLibraryProvider;
+	
+	
 	/**
 	 * required default constructor
 	 */
 	public JpaFacetDataModelProvider() {
 		super();
 	}
-
-
-
+	
+	
 	@Override
 	public Set<String> getPropertyNames() {
 		@SuppressWarnings("unchecked") Set<String> propertyNames = super.getPropertyNames();
+		propertyNames.add(RUNTIME);
 		propertyNames.add(PLATFORM_ID);
+		propertyNames.add(LIBRARY_PROVIDER_DELEGATE);
 		propertyNames.add(CONNECTION);
 		propertyNames.add(CONNECTION_ACTIVE);
 		propertyNames.add(USER_WANTS_TO_ADD_DB_DRIVER_JARS_TO_CLASSPATH);
@@ -87,10 +91,6 @@
 		propertyNames.add(DB_DRIVER_JARS);
 		propertyNames.add(USER_WANTS_TO_OVERRIDE_DEFAULT_SCHEMA);
 		propertyNames.add(USER_OVERRIDE_DEFAULT_SCHEMA);
-		propertyNames.add(RUNTIME);
-		propertyNames.add(USE_SERVER_JPA_IMPLEMENTATION);
-		propertyNames.add(USE_USER_JPA_LIBRARY);
-		propertyNames.add(JPA_LIBRARY);
 		propertyNames.add(DISCOVER_ANNOTATED_CLASSES);
 		propertyNames.add(LIST_ANNOTATED_CLASSES);
 		propertyNames.add(CREATE_ORM_XML);
@@ -108,20 +108,23 @@
 		if (propertyName.equals(DB_DRIVER_NAME)) {
 			return getBooleanProperty(USER_WANTS_TO_ADD_DB_DRIVER_JARS_TO_CLASSPATH);
 		}
-		if (propertyName.equals(JPA_LIBRARY)) {
-			return getBooleanProperty(USE_USER_JPA_LIBRARY);
-		}
 		return super.isPropertyEnabled(propertyName);
 	}
 	
 	@Override
 	public Object getDefaultProperty(String propertyName) {
+		if (propertyName.equals(RUNTIME)) {
+			return null;
+		}
 		if (propertyName.equals(FACET_ID)) {
 			return JptCorePlugin.FACET_ID;
 		}
 		if (propertyName.equals(PLATFORM_ID)) {
 			return JptCorePlugin.getDefaultJpaPlatformId();
 		}
+		if (propertyName.equals(LIBRARY_PROVIDER_DELEGATE)) {
+			return getDefaultLibraryProvider();
+		}
 		if (propertyName.equals(CONNECTION)) {
 			return null;
 		}
@@ -143,18 +146,6 @@
 		if (propertyName.equals(USER_OVERRIDE_DEFAULT_SCHEMA)) {
 			return getDefaultSchemaName();
 		}
-		if (propertyName.equals(RUNTIME)) {
-			return null;
-		}
-		if (propertyName.equals(USE_SERVER_JPA_IMPLEMENTATION)) {
-			return Boolean.valueOf(this.runtimeSupportsEjb30(this.runtime()));
-		}
-		if (propertyName.equals(USE_USER_JPA_LIBRARY)) {
-			return Boolean.valueOf( ! getBooleanProperty(USE_SERVER_JPA_IMPLEMENTATION));
-		}
-		if (propertyName.equals(JPA_LIBRARY)) {
-			return JptCorePlugin.getDefaultJpaLibrary();
-		}
 		if (propertyName.equals(DISCOVER_ANNOTATED_CLASSES)) {
 			return Boolean.valueOf(this.runtimeSupportsEjb30(this.runtime()));
 		}
@@ -164,20 +155,73 @@
 		if (propertyName.equals(CREATE_ORM_XML)) {
 			return Boolean.TRUE;
 		}
+		
 		return super.getDefaultProperty(propertyName);
 	}
 	
+	private String getDefaultDriverName() {
+		ConnectionProfile cp = this.getConnectionProfile();
+		if (cp == null) {
+			return null;
+		}
+		return cp.getDriverName();
+	}
+
+	private String getDefaultDriverJars() {
+		ConnectionProfile cp = this.getConnectionProfile();
+		if (cp == null) {
+			return null;
+		}
+		return cp.getDriverJarList();
+	}
 	
+	private String getDefaultSchemaName() {
+		ConnectionProfile cp = this.getConnectionProfile();
+		if (cp == null) {
+			return null;
+		}
+		Database db = cp.getDatabase();
+		if (db == null) {
+			return null;
+		}
+		Schema schema = db.getDefaultSchema();
+		return (schema == null) ? null : schema.getIdentifier();
+	}
+	
+	private LibraryInstallDelegate getDefaultLibraryProvider() {
+		// delegate itself changes, not the instance of delegate
+		if (defaultLibraryProvider == null) {
+			IFacetedProjectWorkingCopy fpjwc = (IFacetedProjectWorkingCopy) getProperty(FACETED_PROJECT_WORKING_COPY);
+			IProjectFacetVersion fv = (IProjectFacetVersion) getProperty(FACET_VERSION);
+			if (fpjwc != null && fv != null ) {
+				defaultLibraryProvider = new LibraryInstallDelegate(fpjwc, fv);
+				defaultLibraryProvider.addListener( 
+					new IPropertyChangeListener() {
+						public void propertyChanged(final String property, final Object oldValue, final Object newValue ) {
+							JpaFacetDataModelProvider.this.model.notifyPropertyChange(LIBRARY_PROVIDER_DELEGATE, IDataModel.VALUE_CHG);
+						}
+					});
+			}
+		}
+		return defaultLibraryProvider;
+	}
 	
 	@Override
 	public boolean propertySet(String propertyName, Object propertyValue) {
 		boolean ok = super.propertySet(propertyName, propertyValue);
+		
+		if (propertyName.equals(FACETED_PROJECT_WORKING_COPY)) {
+			//no-op
+		}
+		if( propertyName.equals(FACET_VERSION)){
+			this.model.notifyPropertyChange(LIBRARY_PROVIDER_DELEGATE, IDataModel.DEFAULT_CHG);
+		}
 		if (propertyName.equals(RUNTIME)) {
-			this.model.notifyPropertyChange(USE_SERVER_JPA_IMPLEMENTATION, IDataModel.DEFAULT_CHG);
-			this.model.notifyPropertyChange(USE_USER_JPA_LIBRARY, IDataModel.DEFAULT_CHG);
-			// need to fire that the default change for using user library may have
-			// actually changed enablement for library
-			this.model.notifyPropertyChange(JPA_LIBRARY, IDataModel.ENABLE_CHG);
+			LibraryInstallDelegate libProvDelegate = (LibraryInstallDelegate) this.getProperty(LIBRARY_PROVIDER_DELEGATE);
+			if (libProvDelegate != null) {
+				// may be null while model is being built up
+				libProvDelegate.refresh();
+			}
 			this.model.notifyPropertyChange(DISCOVER_ANNOTATED_CLASSES, IDataModel.DEFAULT_CHG);
 			this.model.notifyPropertyChange(LIST_ANNOTATED_CLASSES, IDataModel.DEFAULT_CHG);
 		}
@@ -212,13 +256,13 @@
 				this.model.setProperty(USER_OVERRIDE_DEFAULT_SCHEMA, null);
 			}
 		}
-		if (propertyName.equals(USE_SERVER_JPA_IMPLEMENTATION)) {
-			this.model.setBooleanProperty(USE_USER_JPA_LIBRARY, ! ((Boolean) propertyValue).booleanValue());
-		}
-		if (propertyName.equals(USE_USER_JPA_LIBRARY)) {
-			this.model.setBooleanProperty(USE_SERVER_JPA_IMPLEMENTATION, ! ((Boolean) propertyValue).booleanValue());
-			this.model.notifyPropertyChange(JPA_LIBRARY, IDataModel.ENABLE_CHG);
-		}
+//		if (propertyName.equals(USE_SERVER_JPA_IMPLEMENTATION)) {
+//			this.model.setBooleanProperty(USE_USER_JPA_LIBRARY, ! ((Boolean) propertyValue).booleanValue());
+//		}
+//		if (propertyName.equals(USE_USER_JPA_LIBRARY)) {
+//			this.model.setBooleanProperty(USE_SERVER_JPA_IMPLEMENTATION, ! ((Boolean) propertyValue).booleanValue());
+//			this.model.notifyPropertyChange(JPA_LIBRARY, IDataModel.ENABLE_CHG);
+//		}
 		if (propertyName.equals(DISCOVER_ANNOTATED_CLASSES)) {
 			this.model.setBooleanProperty(LIST_ANNOTATED_CLASSES, ! ((Boolean) propertyValue).booleanValue());
 		}
@@ -274,17 +318,6 @@
 				},
 				EMPTY_DMPD_ARRAY);
 		}
-		if (propertyName.equals(JPA_LIBRARY)) {
-			String[] libraries = CollectionTools.sort(JavaCore.getUserLibraryNames());
-			DataModelPropertyDescriptor[] descriptors = new DataModelPropertyDescriptor[libraries.length + 1];
-			descriptors[0] = new DataModelPropertyDescriptor("", RUNTIME_NONE); //$NON-NLS-1$
-
-			int i = 1;
-			for (String library : libraries) {
-				descriptors[i++] = new DataModelPropertyDescriptor(library, library);
-			}
-			return descriptors;
-		}
 
 		return super.getValidPropertyDescriptors(propertyName);
 	}
@@ -317,6 +350,10 @@
 		if (name.equals(PLATFORM_ID)) {
 			return this.validatePlatformId(this.getStringProperty(name));
 		}
+		if (name.equals(LIBRARY_PROVIDER_DELEGATE)) {
+			LibraryInstallDelegate delegate = (LibraryInstallDelegate) getProperty(LIBRARY_PROVIDER_DELEGATE);
+		    return delegate.validate();
+		}
 		if (name.equals(CONNECTION)) {
 			return this.validateConnectionName(this.getStringProperty(name));
 		}
@@ -328,12 +365,10 @@
 				|| name.equals(USER_OVERRIDE_DEFAULT_SCHEMA)) {
 			return this.validateUserOverrideDefaultSchema();
 		}
-		if (name.equals(USE_SERVER_JPA_IMPLEMENTATION)) {
-			return this.validateJpaLibrary(this.getBooleanProperty(name));
-		}
 		if (name.equals(DISCOVER_ANNOTATED_CLASSES)) {
 			return this.validatePersistentClassManagement(this.getBooleanProperty(name));
 		}
+		
 		return super.validate(name);
 	}
 
@@ -371,23 +406,7 @@
 		ConnectionProfile cp = this.buildConnectionProfile(connectionName);
 		return (cp != null) && cp.isActive();
 	}
-
-	private String getDefaultDriverName() {
-		ConnectionProfile cp = this.getConnectionProfile();
-		if (cp == null) {
-			return null;
-		}
-		return cp.getDriverName();
-	}
-
-	private String getDefaultDriverJars() {
-		ConnectionProfile cp = this.getConnectionProfile();
-		if (cp == null) {
-			return null;
-		}
-		return cp.getDriverJarList();
-	}
-
+	
 	private Iterator<String> connectionNames() {
 		String setValue = getStringProperty(CONNECTION);
 		
@@ -400,19 +419,6 @@
 		return connectionNames.iterator();
 	}
 	
-	private String getDefaultSchemaName() {
-		ConnectionProfile cp = this.getConnectionProfile();
-		if (cp == null) {
-			return null;
-		}
-		Database db = cp.getDatabase();
-		if (db == null) {
-			return null;
-		}
-		Schema schema = db.getDefaultSchema();
-		return (schema == null) ? null : schema.getIdentifier();
-	}
-
 	private List<String> buildSortedSchemaNames() {
 		ConnectionProfile cp = this.getConnectionProfile();
 		if (cp == null) {
@@ -476,23 +482,6 @@
 		return OK_STATUS;
 	}
 
-	private IStatus validateJpaLibrary(boolean useServerJpaImplementation) {
-		if (useServerJpaImplementation) {
-			IRuntime runtime = this.runtime();
-			if (runtime == null) {
-				return RUNTIME_NOT_SPECIFIED_STATUS;
-			}
-			if ( ! this.runtimeSupportsEjb30(runtime)) {
-				return RUNTIME_DOES_NOT_SUPPORT_EJB_30_STATUS;
-			}
-		} else {
-			if (StringTools.stringIsEmpty(this.getStringProperty(JPA_LIBRARY))) {
-				return LIBRARY_NOT_SPECIFIED_STATUS;
-			}
-		}
-		return OK_STATUS;
-	}
-
 	private IStatus validatePersistentClassManagement(boolean discoverAnnotatedClasses) {
 		// TODO warning if "discovery" is used, but no runtime specified ??
 		return OK_STATUS;
diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/facet/JpaFacetInstallDelegate.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/facet/JpaFacetInstallDelegate.java
index cb8512d..a42cf45 100644
--- a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/facet/JpaFacetInstallDelegate.java
+++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/facet/JpaFacetInstallDelegate.java
@@ -14,16 +14,13 @@
 import org.eclipse.core.runtime.IProgressMonitor;
 import org.eclipse.core.runtime.NullProgressMonitor;
 import org.eclipse.core.runtime.Path;
-import org.eclipse.jdt.core.IClasspathAttribute;
 import org.eclipse.jdt.core.IClasspathEntry;
 import org.eclipse.jdt.core.IJavaProject;
 import org.eclipse.jdt.core.JavaCore;
 import org.eclipse.jpt.core.JptCorePlugin;
 import org.eclipse.jpt.utility.internal.CollectionTools;
 import org.eclipse.jpt.utility.internal.StringTools;
-import org.eclipse.jst.j2ee.classpathdep.ClasspathDependencyUtil;
-import org.eclipse.jst.j2ee.classpathdep.IClasspathDependencyConstants;
-import org.eclipse.jst.j2ee.project.EarUtilities;
+import org.eclipse.jst.common.project.facet.core.libprov.LibraryInstallDelegate;
 import org.eclipse.wst.common.frameworks.datamodel.IDataModel;
 import org.eclipse.wst.common.project.facet.core.IDelegate;
 import org.eclipse.wst.common.project.facet.core.IProjectFacetVersion;
@@ -58,7 +55,6 @@
 
 		IJavaProject javaProject = JavaCore.create(project);
 		IDataModel dataModel = (IDataModel) config;
-		this.configureClasspath(javaProject, dataModel, monitor);
 		
 		// project settings
 		JptCorePlugin.setJpaPlatformId(project, dataModel.getStringProperty(PLATFORM_ID));
@@ -74,31 +70,12 @@
 		// defaults settings
 		JptCorePlugin.setDefaultJpaPlatformId(dataModel.getStringProperty(PLATFORM_ID));
 		
+		//Delegate to LibraryInstallDelegate to configure the project classpath
+		((LibraryInstallDelegate) dataModel.getProperty(JpaFacetDataModelProperties.LIBRARY_PROVIDER_DELEGATE)).execute(new NullProgressMonitor());
+		
 		monitor.worked(1);
 	}
 
-	private void configureClasspath(IJavaProject javaProject, IDataModel dataModel, IProgressMonitor monitor) throws CoreException {
-		boolean useServerLibrary = dataModel.getBooleanProperty(USE_SERVER_JPA_IMPLEMENTATION);
-		if (useServerLibrary) {
-			return;
-		}
-
-		String jpaLibrary = dataModel.getStringProperty(JPA_LIBRARY);
-		if (StringTools.stringIsEmpty(jpaLibrary)) {
-			return;
-		}
-
-		// build the JPA library to be added to the classpath
-		IClasspathAttribute[] attributes = this.buildClasspathAttributes(javaProject.getProject());
-		IClasspathEntry jpaLibraryEntry = 
-			JavaCore.newContainerEntry(
-				new Path(JavaCore.USER_LIBRARY_CONTAINER_ID + "/" + jpaLibrary), //$NON-NLS-1$
-				null, attributes, true
-			);
-
-		this.addClasspathEntryToProject(jpaLibraryEntry, javaProject, monitor);
-	}
-
 	private void addDbDriverLibraryToClasspath(IJavaProject javaProject, IDataModel dataModel, IProgressMonitor monitor) throws CoreException {
 		if( ! dataModel.getBooleanProperty(USER_WANTS_TO_ADD_DB_DRIVER_JARS_TO_CLASSPATH)) {
 			return;
@@ -134,25 +111,6 @@
 		javaProject.setRawClasspath(newClasspath, monitor);
 	}
 
-	private static final IClasspathAttribute[] EMPTY_CLASSPATH_ATTRIBUTES = new IClasspathAttribute[0];
-
-	private IClasspathAttribute[] buildClasspathAttributes(IProject project) {
-		boolean webApp = JptCorePlugin.projectHasWebFacet(project);
-		if ( ! webApp && this.projectIsStandalone(project)) {
-			return EMPTY_CLASSPATH_ATTRIBUTES;
-		}
-		return new IClasspathAttribute[] {
-				JavaCore.newClasspathAttribute(
-					IClasspathDependencyConstants.CLASSPATH_COMPONENT_DEPENDENCY,
-					ClasspathDependencyUtil.getDefaultRuntimePath(webApp).toString()
-				)
-		};
-	}
-
-	private boolean projectIsStandalone(IProject project) {
-		return EarUtilities.isStandaloneProject(project);
-	}
-
 	private IProgressMonitor nonNullMonitor(IProgressMonitor monitor) {
 		return (monitor != null) ? monitor : new NullProgressMonitor();
 	}
diff --git a/jpa/plugins/org.eclipse.jpt.eclipselink.core/META-INF/MANIFEST.MF b/jpa/plugins/org.eclipse.jpt.eclipselink.core/META-INF/MANIFEST.MF
index c929229..ea62a1e 100644
--- a/jpa/plugins/org.eclipse.jpt.eclipselink.core/META-INF/MANIFEST.MF
+++ b/jpa/plugins/org.eclipse.jpt.eclipselink.core/META-INF/MANIFEST.MF
@@ -20,6 +20,7 @@
  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.utility;bundle-version="[1.2.0,2.0.0)",
+ org.eclipse.jst.common.project.facet.core;bundle-version="1.4.0",
  org.eclipse.wst.common.emf;bundle-version="[1.1.200,2.0.0)",
  org.eclipse.wst.common.emfworkbench.integration;bundle-version="[1.1.200,2.0.0)",
  org.eclipse.wst.common.frameworks;bundle-version="[1.1.200,2.0.0)",
diff --git a/jpa/plugins/org.eclipse.jpt.eclipselink.core/plugin.xml b/jpa/plugins/org.eclipse.jpt.eclipselink.core/plugin.xml
index 9157a58..7cd7b4a 100644
--- a/jpa/plugins/org.eclipse.jpt.eclipselink.core/plugin.xml
+++ b/jpa/plugins/org.eclipse.jpt.eclipselink.core/plugin.xml
@@ -47,6 +47,34 @@
 	</extension>
 	
 	
+	<!--
+	******************************************
+	* Library Provider Framework Integration *
+	******************************************
+	-->
+	
+	<extension 
+		point="org.eclipse.jst.common.project.facet.core.libraryProviders">
+		
+		<provider id="jpa-eclipselink-user-library-provider" extends="wtp-user-library-provider">
+			<param name="validator" value="org.eclipse.jst.common.project.facet.core.libprov.user.KeyClassesValidator"/>
+			<param name="validator.param.0" value="javax.persistence.Entity"/>
+			<param name="validator.param.1" value="org.eclipse.persistence.annotations.Cache"/>
+			<enablement>
+				<and>
+					<with variable="requestingProjectFacet">
+						<test property="org.eclipse.wst.common.project.facet.core.projectFacet" value="jpt.jpa" forcePluginActivation="true"/>
+					</with>
+					<with variable="context">
+						<test property="org.eclipse.jpt.core.jpaPlatform" value="org.eclipse.eclipselink.platform"/>
+					</with>
+				</and>
+			</enablement>
+		</provider>
+	
+	</extension>
+	
+	
 	<!-- ***** WTP extensions ***** -->
 
 	<extension
diff --git a/jpa/plugins/org.eclipse.jpt.ui/META-INF/MANIFEST.MF b/jpa/plugins/org.eclipse.jpt.ui/META-INF/MANIFEST.MF
index 83204f5..c317f00 100644
--- a/jpa/plugins/org.eclipse.jpt.ui/META-INF/MANIFEST.MF
+++ b/jpa/plugins/org.eclipse.jpt.ui/META-INF/MANIFEST.MF
@@ -24,16 +24,18 @@
  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.editors;bundle-version="[3.4.0,4.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",
+ 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.emfworkbench.integration;bundle-version="[1.1.202, 1.2.0)",
+ org.eclipse.wst.common.emfworkbench.integration;bundle-version="[1.1.202,1.2.0)",
  org.eclipse.wst.common.frameworks;bundle-version="[1.1.200,1.2.0)",
  org.eclipse.wst.common.frameworks.ui;bundle-version="[1.1.200,1.2.0)",
  org.eclipse.wst.common.modulecore;bundle-version="[1.1.200,2.0.0)",
diff --git a/jpa/plugins/org.eclipse.jpt.ui/plugin.properties b/jpa/plugins/org.eclipse.jpt.ui/plugin.properties
index 4e2c51a..9d03dc9 100644
--- a/jpa/plugins/org.eclipse.jpt.ui/plugin.properties
+++ b/jpa/plugins/org.eclipse.jpt.ui/plugin.properties
@@ -52,9 +52,9 @@
 
 persistenceEditor=Persistence XML Editor
 
-jpaPreferencePage = JPA
+jpaPreferencePage = Java Persistence
 
-jpaProjectPropertiesPage = JPA
+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.
diff --git a/jpa/plugins/org.eclipse.jpt.ui/plugin.xml b/jpa/plugins/org.eclipse.jpt.ui/plugin.xml
index 0c09c5b..869fa4b 100644
--- a/jpa/plugins/org.eclipse.jpt.ui/plugin.xml
+++ b/jpa/plugins/org.eclipse.jpt.ui/plugin.xml
@@ -52,12 +52,14 @@
 	<extension
 		point="org.eclipse.jdt.ui.javaCompletionProposalComputer"
 		id="JpaCompletionProposalComputer">
+		
 		<javaCompletionProposalComputer 
 			class="org.eclipse.jpt.ui.internal.JpaJavaCompletionProposalComputer"
 			categoryId="org.eclipse.jpt.ui.jpaProposalCategory">
 			<partition type="__dftl_partition_content_type"/>
 			<partition type="__java_string"/>
 		</javaCompletionProposalComputer>
+		
 	</extension>
 	
 	
@@ -79,23 +81,27 @@
 			factoryClass="org.eclipse.jpt.ui.internal.platform.generic.GenericJpaPlatformUiFactory"/>
 		
 	</extension>
- <extension
-       point="org.eclipse.ui.actionSets">
-    <actionSet
-          description="%JptCreationActionSet.description"
-          id="org.eclipse.jpt.ui.JptCreationActionSet"
-          label="%JptCreationActionSet.label">
-       <action
-             class="org.eclipse.jpt.ui.internal.wizards.NewEntityDropDownAction"
-             disabledIcon="icons/full/etool16/new_entity_wiz.gif"
-             icon="icons/full/etool16/new_entity_wiz.gif"
-             id="org.eclipse.jpt.ui.NewEntityAction"
-             label="%NewEntityAction.label"
-             pulldown="true"
-             toolbarPath="Normal/JptWizards">
-       </action>
-    </actionSet>
- </extension>
+	
+	
+	<extension
+		point="org.eclipse.ui.actionSets">
+		
+		<actionSet
+			description="%JptCreationActionSet.description"
+			id="org.eclipse.jpt.ui.JptCreationActionSet"
+			label="%JptCreationActionSet.label">
+			<action
+				class="org.eclipse.jpt.ui.internal.wizards.NewEntityDropDownAction"
+				disabledIcon="icons/full/etool16/new_entity_wiz.gif"
+				icon="icons/full/etool16/new_entity_wiz.gif"
+				id="org.eclipse.jpt.ui.NewEntityAction"
+				label="%NewEntityAction.label"
+				pulldown="true"
+				toolbarPath="Normal/JptWizards">
+			</action>
+		</actionSet>
+		
+	</extension>
 	
 	
 	<extension
@@ -760,16 +766,17 @@
 			name="%jpaProjectPropertiesPage"
 			class="org.eclipse.jpt.ui.internal.properties.JpaProjectPropertiesPage">
 			<enabledWhen>
-				<adapt 
-					type="org.eclipse.core.resources.IProject">
-					<test 
-						property="org.eclipse.wst.common.project.facet.core.projectFacet"
-						value="jpt.jpa"/>
-				</adapt>
+				<adapt type="org.eclipse.core.resources.IProject">
+			        <test 
+			            forcePluginActivation="true"
+			            property="org.eclipse.wst.common.project.facet.core.projectFacet"
+			            value="jpt.jpa"/>
+		        </adapt>
 			</enabledWhen>
 		</page>
 	</extension>
-		
+	
+	  		
 	<extension
 		point="org.eclipse.ui.views">
 		
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
index a8f74f6..29e448e 100644
--- a/jpa/plugins/org.eclipse.jpt.ui/property_files/jpt_ui.properties
+++ b/jpa/plugins/org.eclipse.jpt.ui/property_files/jpt_ui.properties
@@ -50,6 +50,7 @@
 Error_openingEditor=Error Opening Editor
 
 General_browse=Browse...
+General_revert=Revert
 General_deselectAll=Deselect All
 General_selectAll=Select All
 
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
index 47c9f95..b53bbab 100644
--- 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
@@ -52,6 +52,7 @@
 	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;
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
index daace81..4e97bd3 100644
--- 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
@@ -10,25 +10,77 @@
 package org.eclipse.jpt.ui.internal.properties;
 
 import java.lang.reflect.InvocationTargetException;
-
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
 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.jface.dialogs.Dialog;
+import org.eclipse.jface.dialogs.ProgressMonitorDialog;
 import org.eclipse.jface.operation.IRunnableWithProgress;
+import org.eclipse.jpt.core.JpaDataSource;
 import org.eclipse.jpt.core.JpaProject;
 import org.eclipse.jpt.core.JptCorePlugin;
 import org.eclipse.jpt.core.internal.JpaModelManager;
-import org.eclipse.jpt.core.internal.facet.JpaFacetDataModelProperties;
-import org.eclipse.jpt.core.internal.facet.JpaFacetDataModelProvider;
+import org.eclipse.jpt.core.internal.JptCoreMessages;
+import org.eclipse.jpt.core.internal.platform.JpaPlatformRegistry;
+import org.eclipse.jpt.db.ConnectionAdapter;
+import org.eclipse.jpt.db.ConnectionListener;
 import org.eclipse.jpt.db.ConnectionProfile;
+import org.eclipse.jpt.db.ConnectionProfileListener;
+import org.eclipse.jpt.db.Database;
 import org.eclipse.jpt.db.JptDbPlugin;
+import org.eclipse.jpt.db.Schema;
 import org.eclipse.jpt.db.ui.internal.DTPUiTools;
-import org.eclipse.jpt.ui.JptUiPlugin;
 import org.eclipse.jpt.ui.internal.JpaHelpContextIds;
 import org.eclipse.jpt.ui.internal.JptUiMessages;
+import org.eclipse.jpt.ui.internal.swt.BooleanButtonModelAdapter;
+import org.eclipse.jpt.ui.internal.swt.ComboModelAdapter;
+import org.eclipse.jpt.ui.internal.util.ControlEnabler;
+import org.eclipse.jpt.utility.internal.CollectionTools;
+import org.eclipse.jpt.utility.internal.StringConverter;
 import org.eclipse.jpt.utility.internal.StringTools;
+import org.eclipse.jpt.utility.internal.iterators.EmptyIterator;
+import org.eclipse.jpt.utility.internal.model.value.AspectAdapter;
+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.CollectionListValueModelAdapter;
+import org.eclipse.jpt.utility.internal.model.value.CompositeCollectionValueModel;
+import org.eclipse.jpt.utility.internal.model.value.CompositeListValueModel;
+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.PropertyCollectionValueModelAdapter;
+import org.eclipse.jpt.utility.internal.model.value.PropertyListValueModelAdapter;
+import org.eclipse.jpt.utility.internal.model.value.SimpleListValueModel;
+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.TransformationWritablePropertyValueModel;
+import org.eclipse.jpt.utility.internal.model.value.BufferedWritablePropertyValueModel.Trigger;
+import org.eclipse.jpt.utility.model.event.PropertyChangeEvent;
+import org.eclipse.jpt.utility.model.listener.ChangeListener;
+import org.eclipse.jpt.utility.model.listener.CollectionChangeListener;
+import org.eclipse.jpt.utility.model.listener.PropertyChangeListener;
+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.ui.libprov.FacetLibraryPropertyPage;
+import org.eclipse.osgi.util.NLS;
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.events.SelectionAdapter;
 import org.eclipse.swt.events.SelectionEvent;
@@ -42,81 +94,246 @@
 import org.eclipse.swt.widgets.Label;
 import org.eclipse.swt.widgets.Link;
 import org.eclipse.ui.PlatformUI;
-import org.eclipse.wst.common.frameworks.datamodel.DataModelFactory;
 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 org.eclipse.wst.common.project.facet.core.runtime.IRuntime;
 
 public class JpaProjectPropertiesPage
-	extends DataModelPropertyPage
-	implements JpaFacetDataModelProperties
+	extends FacetLibraryPropertyPage 
 {
 	public static final String PROP_ID= "org.eclipse.jpt.ui.jpaProjectPropertiesPage"; //$NON-NLS-1$
 
-	private PlatformGroup platformGroup;
-
-	private ConnectionGroup connectionGroup;
-
-	private PersistentClassManagementGroup persistentClassManagementGroup;
-
-
-	/**
-	 * Constructor for SamplePropertyPage.
-	 */
+	
+	private WritablePropertyValueModel<IProject> projectHolder;
+	
+	private PropertyValueModel<JpaProject> jpaProjectHolder;
+	
+	private Trigger trigger;
+	
+	private PropertyChangeListener validationListener;
+	
+	private BufferedWritablePropertyValueModel<String> platformIdModel;
+	
+	private BufferedWritablePropertyValueModel<String> connectionModel;
+	
+	private ListValueModel<String> connectionChoicesModel;
+	
+	private PropertyValueModel<ConnectionProfile> connectionProfileModel;
+	
+	private BufferedWritablePropertyValueModel<Boolean> overrideDefaultSchemaModel;
+	
+	private BufferedWritablePropertyValueModel<String> defaultSchemaModel;
+	
+	private WritablePropertyValueModel<String> combinedDefaultSchemaModel;
+	
+	private ListValueModel<String> schemaChoicesModel;
+	
+	private BufferedWritablePropertyValueModel<Boolean> discoverAnnotatedClassesModel;
+	
+	private WritablePropertyValueModel<Boolean> listAnnotatedClassesModel;
+	
+	
 	public JpaProjectPropertiesPage() {
-		super(DataModelFactory.createDataModel(new JpaFacetDataModelProvider()));
+		super();
+		this.projectHolder = new SimplePropertyValueModel<IProject>();
+		this.jpaProjectHolder = initializeJpaProjectHolder();
+		this.trigger = new Trigger();
+		this.validationListener = initializeValidationListener();
+		this.platformIdModel = initializePlatformIdModel();
+		this.connectionModel = initializeConnectionModel();
+		this.connectionChoicesModel = initializeConnectionChoicesModel();
+		this.connectionProfileModel = initializeConnectionProfileModel();
+		this.overrideDefaultSchemaModel = initializeOverrideDefaultSchemaModel();
+		this.defaultSchemaModel = initializeDefaultSchemaModel();
+		this.combinedDefaultSchemaModel = initializeCombinedDefaultSchemaModel();
+		this.schemaChoicesModel = initializeSchemaChoicesModel();
+		this.discoverAnnotatedClassesModel = initializeDiscoverAnnotatedClassesModel();
+		this.listAnnotatedClassesModel = initializeListAnnotatedClassesModel();
 	}
-
-
-	@Override
-	protected Composite createTopLevelComposite(Composite parent) {
-		Composite composite = new Composite(parent, SWT.NULL);
-		GridLayout layout = new GridLayout();
-		composite.setLayout(layout);
-
-		platformGroup = new PlatformGroup(composite);
-		connectionGroup = new ConnectionGroup(composite);
-		persistentClassManagementGroup = new PersistentClassManagementGroup(composite);
-
-		setRuntime();
-
-		Dialog.applyDialogFont(parent);
-		PlatformUI.getWorkbench().getHelpSystem().setHelp(composite, JpaHelpContextIds.PROPERTIES_JAVA_PERSISTENCE);
-
-		return composite;
+	
+	
+	protected PropertyValueModel<JpaProject> initializeJpaProjectHolder() {
+		return new JpaProjectHolder(this.projectHolder);
 	}
-
-	private void setRuntime() {
-		if (getJpaProject() == null) {
-			return;
-		}
-		IFacetedProject facetedProject = null;
-		try {
-			facetedProject = ProjectFacetsManager.create(getJpaProject().getProject());
-		}
-		catch (CoreException ce) {
-			JptUiPlugin.log(ce);
-			return;
-		}
-		IRuntime runtime = facetedProject.getPrimaryRuntime();
-		model.setProperty(JpaFacetDataModelProperties.RUNTIME, runtime);
-	}
-
-	@Override
-	protected String[] getValidationPropertyNames() {
-		return new String[] {
-			JpaFacetDataModelProperties.PLATFORM_ID,
-			JpaFacetDataModelProperties.CONNECTION,
-			JpaFacetDataModelProperties.USER_WANTS_TO_OVERRIDE_DEFAULT_SCHEMA,
-			JpaFacetDataModelProperties.USER_OVERRIDE_DEFAULT_SCHEMA,
-			JpaFacetDataModelProperties.DISCOVER_ANNOTATED_CLASSES
+	
+	protected PropertyChangeListener initializeValidationListener() {
+		return new PropertyChangeListener() {
+			public void propertyChanged(PropertyChangeEvent event) {
+				if (! JpaProjectPropertiesPage.this.getControl().isDisposed()) {
+					updateValidation();
+				}
+			}
 		};
 	}
-
-	protected JpaProject getJpaProject() {
-		return (JpaProject) this.getElement().getAdapter(JpaProject.class);
+	
+	protected BufferedWritablePropertyValueModel<String> initializePlatformIdModel() {
+		BufferedWritablePropertyValueModel<String> model =
+			new BufferedWritablePropertyValueModel(
+				new PlatformIdModel(this.jpaProjectHolder), this.trigger);
+		model.addPropertyChangeListener(PropertyValueModel.VALUE, this.validationListener);
+		return model;
 	}
+	
+	protected BufferedWritablePropertyValueModel<String> initializeConnectionModel() {
+		BufferedWritablePropertyValueModel<String> model = 
+			new BufferedWritablePropertyValueModel(
+				new ConnectionModel(this.jpaProjectHolder), this.trigger);
+		model.addPropertyChangeListener(PropertyValueModel.VALUE, this.validationListener);
+		return model;
+	}
+	
+	protected ListValueModel<String> initializeConnectionChoicesModel() {
+		return new SortedListValueModelAdapter(
+			new CollectionListValueModelAdapter(
+				new ConnectionChoicesModel(this.projectHolder)));
+	}
+	
+	protected PropertyValueModel<ConnectionProfile> initializeConnectionProfileModel() {
+		return new CachingTransformationPropertyValueModel<String, ConnectionProfile>(this.connectionModel) {
+			@Override
+			protected ConnectionProfile transform_(String value) {
+				return JptDbPlugin.instance().getConnectionProfileFactory().buildConnectionProfile(value);
+			}
+		};
+	}
+	
+	protected BufferedWritablePropertyValueModel<Boolean> initializeOverrideDefaultSchemaModel() {
+		BufferedWritablePropertyValueModel<Boolean> model = 
+			new BufferedWritablePropertyValueModel( 
+				new OverrideDefaultSchemaModel(this.jpaProjectHolder), 
+				this.trigger);
+		model.addPropertyChangeListener(PropertyValueModel.VALUE, this.validationListener);
+		return model;
+	
+	}
+	
+	protected BufferedWritablePropertyValueModel<String> initializeDefaultSchemaModel() {
+		return new BufferedWritablePropertyValueModel(
+			new DefaultSchemaModel(this.jpaProjectHolder),
+			new DefaultSchemaTrigger(this.trigger, this.overrideDefaultSchemaModel));
+	}
+	
+	protected WritablePropertyValueModel<String> initializeCombinedDefaultSchemaModel() {
+		WritablePropertyValueModel<String> model = 
+			new CombinedDefaultSchemaModel(
+				this.defaultSchemaModel,
+				this.overrideDefaultSchemaModel,
+				new DefaultDefaultSchemaModel(this.connectionProfileModel));
+		model.addPropertyChangeListener(PropertyValueModel.VALUE, this.validationListener);
+		return model;
+	}
+	
+	protected ListValueModel<String> initializeSchemaChoicesModel() {
+		Collection<CollectionValueModel> cvms = new ArrayList<CollectionValueModel>();
+		cvms.add(new PropertyCollectionValueModelAdapter(this.defaultSchemaModel));
+		cvms.add(new SchemaChoicesModel(this.connectionProfileModel));
+		return new SortedListValueModelAdapter(
+			new CompositeCollectionValueModel<CollectionValueModel, String>(cvms) {
+				@Override
+				public Iterator<String> iterator() {
+					Set<String> uniqueValues = new HashSet<String>();
+					for (String each : CollectionTools.iterable(super.iterator())) {
+						if (each != null) {
+							uniqueValues.add(each);
+						}
+					}
+					return uniqueValues.iterator();
+				}
+			});
+	}
+	
+	protected BufferedWritablePropertyValueModel<Boolean> initializeDiscoverAnnotatedClassesModel() {
+		BufferedWritablePropertyValueModel<Boolean> model = 
+			new BufferedWritablePropertyValueModel(
+				new DiscoverAnnotatedClassesModel(this.jpaProjectHolder), this.trigger);
+		model.addPropertyChangeListener(PropertyValueModel.VALUE, this.validationListener);
+		return model;
+	}
+	
+	protected WritablePropertyValueModel<Boolean> initializeListAnnotatedClassesModel() {
+		return new TransformationWritablePropertyValueModel<Boolean, Boolean>(
+				this.discoverAnnotatedClassesModel) {
+			@Override
+			protected Boolean transform_(Boolean value) {
+				return ! value;
+			}
+			
+			@Override
+			protected Boolean reverseTransform_(Boolean value) {
+				return ! value;
+			}
+		};
+	}
+	
+	protected JpaProject getJpaProject() {
+		return this.jpaProjectHolder.getValue();
+	}
+	
+	protected String getConnectionName() {
+		return this.connectionModel.getValue();
+	}
+	
+	protected ConnectionProfile getConnectionProfile() {
+		// we just use the connection profile to log in, so go to the db plug-in
+		return JptDbPlugin.instance().getConnectionProfileFactory().
+			buildConnectionProfile(getConnectionName());
+	}
+	
+	protected Boolean getOverrideDefaultSchema() {
+		return this.overrideDefaultSchemaModel.getValue();
+	}
+	
+	protected List<String> getDefaultSchemaChoices() {
+		return CollectionTools.list(this.schemaChoicesModel.iterator());
+	}
+	
+	protected String getDefaultSchema() {
+		return this.defaultSchemaModel.getValue();
+	}
+	
+	@Override
+	public IProjectFacetVersion getProjectFacetVersion() {
+		final IProjectFacet jsfFacet = ProjectFacetsManager.getProjectFacet( "jpt.jpa" );
+		final IFacetedProject fproj = getFacetedProject();
+		return fproj.getInstalledVersion( jsfFacet );
+	}
+	
+	@Override
+	protected Control createPageContents(Composite parent) {
+		this.projectHolder.setValue(getProject());
+		
+		Composite composite = new Composite(parent, SWT.NULL);
+		GridLayout layout = new GridLayout();
+		layout.marginWidth = 0;
+		layout.marginHeight = 0;
+		composite.setLayout(layout);
+		
+		new PlatformGroup(composite);
+		
+		Control libraryProviderComposite = super.createPageContents(composite);
+		libraryProviderComposite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+		
+		new ConnectionGroup(composite);
+		new PersistentClassManagementGroup(composite);
 
+		Dialog.applyDialogFont(composite);
+		PlatformUI.getWorkbench().getHelpSystem().setHelp(composite, JpaHelpContextIds.PROPERTIES_JAVA_PERSISTENCE);
+		
+		updateValidation();
+		
+		return composite;
+	}
+	
+	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;
+	}
+	
 	Combo createCombo(Composite container, int span, boolean fillHorizontal) {
 		Combo combo = new Combo(container, SWT.BORDER | SWT.SINGLE | SWT.READ_ONLY);
 		GridData gd;
@@ -130,145 +347,838 @@
 		combo.setLayoutData(gd);
 		return combo;
 	}
-
-	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;
-	}
-
-	@Override
-	protected void performDefaults() {
-		platformGroup.performDefaults();
-		connectionGroup.performDefaults();
-		persistentClassManagementGroup.performDefaults();
-	}
-
+	
 	@Override
 	public boolean performOk() {
-		JpaProject jpaProject = this.getJpaProject();
-		if (jpaProject == null) {
-			return true;  // the facet has been uninstalled during our trip to the properties
-		}
-
-		boolean change = false;
-		boolean platformChange = false;
-
-		IProject project = jpaProject.getProject();
-
-		String platform = this.model.getStringProperty(JpaFacetDataModelProperties.PLATFORM_ID);
-		if ( ! platform.equals(jpaProject.getJpaPlatform().getId())) {
-			change = true;
-			platformChange = true;
-			JptCorePlugin.setJpaPlatformId(project, platform);
-		}
-
-		String connection = this.model.getStringProperty(JpaFacetDataModelProperties.CONNECTION);
-		if ( ! connection.equals(jpaProject.getDataSource().getConnectionProfileName())) {
-			change = true;
-			jpaProject.getDataSource().setConnectionProfileName(connection);
-			JptCorePlugin.setConnectionProfileName(project, connection);
-		}
+		super.performOk();
 		
-		String userOverrideDefaultSchema = null;
-		if (this.model.getBooleanProperty(JpaFacetDataModelProperties.USER_WANTS_TO_OVERRIDE_DEFAULT_SCHEMA)) {
-			userOverrideDefaultSchema = this.model.getStringProperty(JpaFacetDataModelProperties.USER_OVERRIDE_DEFAULT_SCHEMA);
-		}
-		String projectUserOverrideDefaultSchema = jpaProject.getUserOverrideDefaultSchema();
-		if (! StringTools.stringsAreEqualIgnoreCase(userOverrideDefaultSchema, projectUserOverrideDefaultSchema)) {
-			change = true;
-			jpaProject.setUserOverrideDefaultSchema(userOverrideDefaultSchema);
-			JptCorePlugin.setUserOverrideDefaultSchemaName(project, userOverrideDefaultSchema);
-		}
-
-		boolean discover = this.model.getBooleanProperty(JpaFacetDataModelProperties.DISCOVER_ANNOTATED_CLASSES);
-		if (discover != jpaProject.discoversAnnotatedClasses()) {
-			change = true;
-			jpaProject.setDiscoversAnnotatedClasses(discover);
-			JptCorePlugin.setDiscoverAnnotatedClasses(project, discover);
-		}
-
-		if (platformChange) {
-			JpaModelManager.instance().rebuildJpaProject(project);
-		}
-		if (change) {
-			buildProject(project);
-		}
-		return true;
-	}
-
-	private static void buildProject(final IProject project) {
-		IRunnableWithProgress r= new IRunnableWithProgress() {
-			public void run(IProgressMonitor pm) throws InvocationTargetException {
+		final IWorkspaceRunnable wr = new IWorkspaceRunnable() {
+			public void run(IProgressMonitor monitor)
+					throws CoreException {
+				performOkInternal(monitor);
+			}
+		};
+		
+		IRunnableWithProgress op = new IRunnableWithProgress() {
+			public void run(IProgressMonitor monitor) 
+					throws InvocationTargetException, InterruptedException {
 				try {
-					project.build(IncrementalProjectBuilder.FULL_BUILD, pm);
+					IWorkspace ws = ResourcesPlugin.getWorkspace();
+					ws.run(wr, ws.getRoot(), IWorkspace.AVOID_UPDATE, monitor);
 				}
-				catch (CoreException ce) {
-					JptUiPlugin.log(ce);
+				catch(CoreException e) {
+					throw new InvocationTargetException(e);
 				}
 			}
 		};
+		
 		try {
-			PlatformUI.getWorkbench().getProgressService().run(true, false, r);
+			new ProgressMonitorDialog(getShell()).run(true, false, op);
 		}
-		catch (InterruptedException ie) { /* nothing to do */ }
-		catch (InvocationTargetException ie) { /* nothing to do */ }
+		catch (InterruptedException e) {
+			return false;
+		} 
+		catch (InvocationTargetException e) {
+			final Throwable te = e.getTargetException();
+			throw new RuntimeException(te);
+		}
+		
+		return true;
 	}
-
-
+	
+	private void performOkInternal(IProgressMonitor monitor) 
+			throws CoreException {
+		if (this.platformIdModel.isBuffering()) {
+			this.trigger.accept();
+			JpaModelManager.instance().rebuildJpaProject(getProject());
+			getProject().build(IncrementalProjectBuilder.FULL_BUILD, monitor);
+		}
+		else if (this.connectionModel.isBuffering()
+				|| this.defaultSchemaModel.isBuffering()
+				|| this.discoverAnnotatedClassesModel.isBuffering()) {
+			this.trigger.accept();
+			getProject().build(IncrementalProjectBuilder.FULL_BUILD, monitor);
+		}
+	}
+	
+	@Override
+	protected void performDefaults() {
+		super.performDefaults();
+		this.trigger.reset();
+	}
+	
+	@Override
+	protected IStatus performValidation() {
+		Map<Integer, List<IStatus>> statuses = new HashMap<Integer, List<IStatus>>();
+		statuses.put(IStatus.ERROR, new ArrayList<IStatus>());
+		statuses.put(IStatus.WARNING, new ArrayList<IStatus>());
+		statuses.put(IStatus.INFO, new ArrayList<IStatus>());
+		statuses.put(IStatus.OK, CollectionTools.list(Status.OK_STATUS));
+		
+		/* validate platform */
+		// user is unable to unset the platform, so no validation necessary
+		
+		/* library provider */
+		IStatus lpStatus = super.performValidation();
+		statuses.get(lpStatus.getSeverity()).add(lpStatus);
+		
+		/* validate connection */
+		String connectionName = getConnectionName();
+		ConnectionProfile connectionProfile = getConnectionProfile();
+		if (! StringTools.stringIsEmpty(connectionName)) {
+			if (connectionProfile == null) {
+				statuses.get(IStatus.ERROR).add( 
+					buildErrorStatus(
+						NLS.bind(
+							JptCoreMessages.VALIDATE_CONNECTION_INVALID, 
+							connectionName)));
+			}
+			if (! connectionProfile.isActive()) {
+				statuses.get(IStatus.INFO).add( 
+					buildInfoStatus(
+						JptCoreMessages.VALIDATE_CONNECTION_NOT_CONNECTED));
+			}
+		}
+		
+		/* default schema */
+		if (getOverrideDefaultSchema()) {
+			String defaultSchema = getDefaultSchema();
+			if (StringTools.stringIsEmpty(defaultSchema)) {
+				statuses.get(IStatus.ERROR).add( 
+					buildErrorStatus(
+						JptCoreMessages.VALIDATE_DEFAULT_SCHEMA_NOT_SPECIFIED));
+			}
+			else if (connectionProfile != null
+					&& connectionProfile.isConnected()
+					&& ! getDefaultSchemaChoices().contains(defaultSchema)) {
+				statuses.get(IStatus.WARNING).add(
+					buildWarningStatus(
+						NLS.bind(
+							JptCoreMessages.VALIDATE_CONNECTION_DOESNT_CONTAIN_SCHEMA,
+							defaultSchema)));
+			}
+		}
+		
+		if (! statuses.get(IStatus.ERROR).isEmpty()) {
+			return statuses.get(IStatus.ERROR).get(0);
+		}
+		else if (! statuses.get(IStatus.WARNING).isEmpty()) {
+			return statuses.get(IStatus.WARNING).get(0);
+		}
+		else if (! statuses.get(IStatus.INFO).isEmpty()) {
+			return statuses.get(IStatus.INFO).get(0);
+		}
+		else {
+			return statuses.get(IStatus.OK).get(0);
+		}
+	}
+	
+	private IStatus buildInfoStatus(String message) {
+		return buildStatus(IStatus.INFO, message);
+	}
+	
+	private IStatus buildWarningStatus(String message) {
+		return buildStatus(IStatus.WARNING, message);
+	}
+	
+	private IStatus buildErrorStatus(String message) {
+		return buildStatus(IStatus.ERROR, message);
+	}
+	
+	private IStatus buildStatus(int severity, String message) {
+		return new Status(severity, JptCorePlugin.PLUGIN_ID, message);
+	}
+	
+	
+	private static abstract class BasePropertyAspectAdapter<S, V>
+		extends AspectAdapter<S>
+		implements WritablePropertyValueModel<V>
+	{
+		/**
+		 * Cache the current value so we can pass an old value when we fire a 
+		 * property change event
+		 */
+		protected V value;
+		
+		
+		protected BasePropertyAspectAdapter(PropertyValueModel<S> subjectHolder) {
+			super(subjectHolder);
+			this.value = null;
+		}
+		
+		
+		// ************ WritablePropertyValueModel impl ************************
+		
+		@Override
+		public V getValue() {
+			return this.value;
+		}
+		
+		public final void setValue(V value) {
+			if (this.subject != null) {
+				setValue_(value);
+			}
+		}
+		
+		protected void setValue_(V value) {
+			throw new UnsupportedOperationException("setValue");
+		}
+		
+		
+		// ************ AspectAdapter impl *************************************
+		
+		@Override
+		protected Class<? extends ChangeListener> getListenerClass() {
+			return PropertyChangeListener.class;
+		}
+		
+		@Override
+		protected String getListenerAspectName() {
+			return VALUE;
+		}
+		
+		@Override
+		protected boolean hasListeners() {
+			return hasAnyPropertyChangeListeners(VALUE);
+		}
+		
+		@Override
+		protected void fireAspectChange(Object oldValue, Object newValue) {
+			firePropertyChanged(VALUE, oldValue, newValue);
+		}
+		
+		@Override
+		protected void engageSubject_() {
+			this.value = buildValue();
+		}
+		
+		@Override
+		protected void disengageSubject_() {
+			this.value = null;
+		}
+		
+		@Override
+		public void toString(StringBuilder sb) {
+			sb.append(this.getValue());
+		}
+		
+		
+		// ************ internal ***********************************************
+		
+		protected V buildValue() {
+			if (this.subject != null) {
+				return buildValue_();
+			}
+			return null;
+		}
+		
+		protected abstract V buildValue_();
+		
+		protected void valueChanged() {
+			V oldValue = this.getValue();
+			this.value = buildValue();
+			this.fireAspectChange(oldValue, this.getValue());
+		}
+	}
+	
+	
+	private abstract static class BaseCollectionAspectAdapter<S, E>
+		extends AspectAdapter<S>
+		implements CollectionValueModel<E>
+	{
+		protected BaseCollectionAspectAdapter(PropertyValueModel<? extends S> subjectHolder) {
+			super(subjectHolder);
+		}
+		
+			
+		// ************ ListValueModel impl ************************************
+		
+		public Iterator<E> iterator() {
+			return this.subject == null ? EmptyIterator.<E>instance() : this.iterator_();
+		}
+		
+		public int size() {
+			return this.subject == null ? 0 : this.size_();
+		}
+		
+		
+		// ************ AspectAdapter impl *************************************
+		
+		@Override
+		protected Object getValue() {
+			return this.iterator();
+		}
+	
+		@Override
+		protected Class<? extends ChangeListener> getListenerClass() {
+			return CollectionChangeListener.class;
+		}
+	
+		@Override
+		protected String getListenerAspectName() {
+			return VALUES;
+		}
+	
+		@Override
+		protected boolean hasListeners() {
+			return this.hasAnyCollectionChangeListeners(VALUES);
+		}
+		
+		@Override
+		protected void fireAspectChange(Object oldValue, Object newValue) {
+			this.fireCollectionChanged(VALUES);
+		}
+		
+		
+		// ************ internal ***********************************************
+		
+		protected Iterator<E> iterator_() {
+			throw new UnsupportedOperationException();
+		}
+		
+		protected int size_() {
+			return CollectionTools.size(this.iterator());
+		}
+		
+		protected void collectionChanged() {
+			this.fireCollectionChanged(VALUES);
+		}
+	}
+	
+	
+	private static class JpaProjectHolder
+		extends BasePropertyAspectAdapter<IProject, JpaProject>
+	{
+		/**
+		 * Listens to the preferences to determine if the project's platform
+		 * has changed, and is therefore a new JPA project
+		 */
+		private IPreferenceChangeListener platformChangeListener;
+		
+		
+		private JpaProjectHolder(PropertyValueModel<IProject> projectHolder) {
+			super(projectHolder);
+			this.platformChangeListener = buildPlatformChangeListener();
+		}
+		
+		
+		// ************ initialization *****************************************
+		
+		private IPreferenceChangeListener buildPlatformChangeListener() {
+			return new IPreferenceChangeListener() {
+				public void preferenceChange(PreferenceChangeEvent event) {
+					if (JptCorePlugin.JPA_PLATFORM.equals(event.getKey())) {
+						JpaProjectHolder.this.valueChanged();
+					}
+				}
+			};
+		}
+		
+		
+		// ************ AspectAdapter impl *************************************
+		
+		@Override
+		protected void engageSubject_() {
+			IEclipsePreferences preferences = JptCorePlugin.getProjectPreferences(this.subject);
+			preferences.addPreferenceChangeListener(this.platformChangeListener);
+			super.engageSubject_();
+		}
+		
+		@Override
+		protected void disengageSubject_() {
+			IEclipsePreferences preferences = JptCorePlugin.getProjectPreferences(this.subject);
+			preferences.removePreferenceChangeListener(this.platformChangeListener);
+			super.disengageSubject_();
+		}
+		
+		
+		// ************ internal ***********************************************
+		
+		@Override
+		protected JpaProject buildValue_() {
+			return JptCorePlugin.getJpaProject(this.subject);
+		}
+	}
+	
+	
+	private static class PlatformIdModel
+		extends BasePropertyAspectAdapter<JpaProject, String>
+	{
+		private PlatformIdModel(PropertyValueModel<JpaProject> jpaProjectHolder) {
+			super(jpaProjectHolder);
+		}
+		
+		
+		// ************ WritablePropertyValueModel impl ************************
+		
+		@Override
+		public void setValue_(String newPlatformId) {
+			JptCorePlugin.setJpaPlatformId(this.subject.getProject(), newPlatformId);
+		}
+		
+		
+		// ************ internal ***********************************************
+		
+		@Override
+		protected String buildValue_() {
+			return JptCorePlugin.getJpaPlatformId(this.subject.getProject());
+		}
+	}
+	
+	
 	private final class PlatformGroup
 	{
-		final Combo platformCombo;
-		
-		
-		public PlatformGroup(Composite composite) {
+		private 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));
-			// TODO
-			// PlatformUI.getWorkbench().getHelpSystem().setHelp(group, IDaliHelpContextIds.NEW_JPA_PROJECT_CONTENT_PAGE_DATABASE);
 			
-			platformCombo = createCombo(group, 1, true);
-			synchHelper.synchCombo(platformCombo, PLATFORM_ID, null);
-			platformCombo.addSelectionListener(
-				new SelectionAdapter() {
-					@Override
-					public void widgetSelected(SelectionEvent e) {
-						JpaProjectPropertiesPage.this.connectionGroup.updateConnectLink();
-					}
-				});
+			Combo platformCombo = createCombo(group, 1, true);
 			
-			performDefaults();
+			ComboModelAdapter.adapt(
+				buildPlatformChoicesListValueModel(),
+				JpaProjectPropertiesPage.this.platformIdModel,
+				platformCombo,
+				buildPlatformLabelConverter());
 		}
 		
-		void performDefaults() {
-			if (getJpaProject() == null) {
-				return;
+		
+		private ListValueModel<String> buildPlatformChoicesListValueModel() {
+			return new SimpleListValueModel(
+				CollectionTools.list(JpaPlatformRegistry.instance().jpaPlatformIds()));
+		}
+		
+		private StringConverter<String> buildPlatformLabelConverter() {
+			return new StringConverter<String>() {
+				public String convertToString(String platformId) {
+					return JpaPlatformRegistry.instance().getJpaPlatformLabel(platformId);
+				}
+			};
+		}
+	}
+	
+	
+	private static class ConnectionModel
+		extends BasePropertyAspectAdapter<JpaProject, String>
+	{
+		private PropertyChangeListener connectionChangeListener;
+		
+		
+		private ConnectionModel(PropertyValueModel<JpaProject> jpaProjectHolder) {
+			super(jpaProjectHolder);
+			this.connectionChangeListener = buildConnectionChangeListener();
+		}
+		
+		
+		// ************ initialization *****************************************
+		
+		private PropertyChangeListener buildConnectionChangeListener() {
+			return new PropertyChangeListener() {
+				public void propertyChanged(PropertyChangeEvent event) {
+					ConnectionModel.this.valueChanged();
+				}
+			};
+		}
+		
+		
+		// ************ WritablePropertyValueModel impl ************************
+		
+		@Override
+		public void setValue_(String newConnection) {
+			JptCorePlugin.setConnectionProfileName(this.subject.getProject(), newConnection);
+		}
+		
+		
+		// ************ AspectAdapter impl *************************************
+		
+		@Override
+		protected void engageSubject_() {
+			JpaDataSource dataSource = this.subject.getDataSource();
+			dataSource.addPropertyChangeListener(JpaDataSource.CONNECTION_PROFILE_NAME_PROPERTY, this.connectionChangeListener);
+			super.engageSubject_();
+		}
+		
+		@Override
+		protected void disengageSubject_() {
+			JpaDataSource dataSource = this.subject.getDataSource();
+			dataSource.removePropertyChangeListener(JpaDataSource.CONNECTION_PROFILE_NAME_PROPERTY, this.connectionChangeListener);
+			super.disengageSubject_();
+		}
+		
+		
+		// ************ internal ***********************************************
+		
+		@Override
+		protected String buildValue_() {
+			return JptCorePlugin.getConnectionProfileName(this.subject.getProject());
+		}
+	}
+	
+	
+	private static class ConnectionChoicesModel
+		extends BaseCollectionAspectAdapter<IProject, String>
+	{
+		private ConnectionProfileListener connectionProfileListener;
+		
+		
+		private ConnectionChoicesModel(PropertyValueModel<IProject> subjectHolder) {
+			super(subjectHolder);
+			this.connectionProfileListener = buildConnectionProfileListener();
+		}
+		
+		
+		// ************ initialization *****************************************
+		
+		private ConnectionProfileListener buildConnectionProfileListener() {
+			return new ConnectionProfileListener() {
+				public void connectionProfileAdded(String name) {
+					collectionChanged();
+				}
+				
+				public void connectionProfileRemoved(String name) {
+					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.
+					// collectionChanged();
+				}
+			};
+		}
+		
+		
+		// ************ AspectAdapter impl *************************************
+		
+		@Override
+		protected void engageSubject_() {
+			JptDbPlugin.instance().getConnectionProfileFactory().
+				addConnectionProfileListener(this.connectionProfileListener);
+		}
+		
+		@Override
+		protected void disengageSubject_() {
+			JptDbPlugin.instance().getConnectionProfileFactory().
+				removeConnectionProfileListener(this.connectionProfileListener);
+		}
+		
+		
+		// ************ internal ***********************************************
+		
+		@Override
+		protected Iterator<String> iterator_() {
+			return JptDbPlugin.instance().getConnectionProfileFactory().connectionProfileNames();
+		}
+	}
+	
+	
+	private static class OverrideDefaultSchemaModel
+		extends BasePropertyAspectAdapter<JpaProject, Boolean>
+	{
+		// the superclass "value" is the *cached* value
+		private Boolean actualValue;
+		
+		
+		private OverrideDefaultSchemaModel(PropertyValueModel<JpaProject> jpaProjectHolder) {
+			super(jpaProjectHolder);
+		}
+		
+		
+		// ************ WritablePropertyValueModel impl ************************
+		
+		@Override
+		public Boolean getValue() {
+			Boolean value = super.getValue();
+			return (value == null) ? Boolean.FALSE : value;
+		}
+		
+		@Override
+		public void setValue_(Boolean newValue) {
+			this.actualValue = newValue;
+			valueChanged();
+		}
+		
+		
+		// ************ AspectAdapter impl *************************************
+		
+		@Override
+		protected void engageSubject_() {
+			this.actualValue = this.buildActualValue_();
+			super.engageSubject_();
+		}
+		
+		@Override
+		protected void disengageSubject_() {
+			this.actualValue = null;
+			super.disengageSubject_();
+		}
+		
+		
+		// ************ internal ***********************************************
+		
+		@Override
+		protected Boolean buildValue_() {
+			return this.actualValue;
+		}
+		
+		protected Boolean buildActualValue_() {
+			return ! StringTools.stringIsEmpty(this.subject.getUserOverrideDefaultSchema());
+		}
+	}
+	
+	
+	private static class DefaultSchemaModel
+		extends PropertyAspectAdapter<JpaProject, String>
+	{
+		private DefaultSchemaModel(PropertyValueModel<JpaProject> jpaProjectModel) { 
+			super(jpaProjectModel, JpaProject.USER_OVERRIDE_DEFAULT_SCHEMA_PROPERTY);
+		}
+		
+		
+		// ************ WritablePropertyValueModel impl ************************
+		
+		@Override
+		public void setValue_(String newSchema) {
+			this.subject.setUserOverrideDefaultSchema(newSchema);
+		}
+		
+		
+		// ************ internal ***********************************************
+		
+		@Override
+		protected String buildValue_() {
+			return this.subject.getUserOverrideDefaultSchema();
+		}
+	}
+	
+	
+	private static class DefaultDefaultSchemaModel
+		extends BasePropertyAspectAdapter<ConnectionProfile, String>
+	{
+		private ConnectionListener connectionListener;
+		
+		
+		private DefaultDefaultSchemaModel(
+				PropertyValueModel<ConnectionProfile> connectionProfileModel) {
+			super(connectionProfileModel);
+			this.connectionListener = buildConnectionListener();
+		}
+		
+		
+		// ************ initialization *****************************************
+		
+		private ConnectionListener buildConnectionListener() {
+			return new ConnectionAdapter() {
+				@Override
+				public void opened(ConnectionProfile profile) {
+					if (profile.equals(DefaultDefaultSchemaModel.this.subject)) {
+						valueChanged();
+					}
+				}
+				@Override
+				public void schemaChanged(ConnectionProfile profile, Schema schema) {
+					if (profile.equals(DefaultDefaultSchemaModel.this.subject)) {
+						valueChanged();
+					}
+				}
+			};
+		}
+		
+		
+		// ************ AspectAdapter impl *************************************
+		
+		@Override
+		protected void engageSubject_() {
+			this.subject.addConnectionListener(this.connectionListener);
+			super.engageSubject_();
+		}
+		
+		@Override
+		protected void disengageSubject_() {
+			this.subject.removeConnectionListener(this.connectionListener);
+			super.disengageSubject_();
+		}
+		
+		
+		// ************ internal ***********************************************
+		
+		@Override
+		protected String buildValue_() {
+			Database db = this.subject.getDatabase();
+			if (db == null) {
+				return null;
 			}
-			String platformId = getJpaProject().getJpaPlatform().getId();
-			model.setProperty(PLATFORM_ID, platformId);
+			Schema schema = db.getDefaultSchema();
+			return (schema == null) ? null : schema.getIdentifier();
+		}
+	}
+	
+	
+	private static class CombinedDefaultSchemaModel
+		extends ListPropertyValueModelAdapter<String>
+		implements WritablePropertyValueModel<String>
+	{
+		private WritablePropertyValueModel<String> defaultSchemaModel;
+		
+		private PropertyValueModel<Boolean> overrideDefaultSchemaModel;
+		
+		private PropertyValueModel<String> defaultDefaultSchemaModel;
+		
+		
+		private CombinedDefaultSchemaModel(
+				WritablePropertyValueModel<String> defaultSchemaModel,
+				PropertyValueModel<Boolean> overrideDefaultSchemaModel,
+				PropertyValueModel<String> defaultDefaultSchemaModel) {
+			super(
+				new CompositeListValueModel(
+					CollectionTools.list(
+						new PropertyListValueModelAdapter<String>(defaultSchemaModel),
+						new PropertyListValueModelAdapter<Boolean>(overrideDefaultSchemaModel),
+						new PropertyListValueModelAdapter<String>(defaultDefaultSchemaModel)
+					)));
+			this.defaultSchemaModel = defaultSchemaModel;
+			this.overrideDefaultSchemaModel = overrideDefaultSchemaModel;
+			this.defaultDefaultSchemaModel = defaultDefaultSchemaModel;
+		}
+		
+		
+		// ************ ListPropertyValueModelAdapter impl *********************
+		
+		@Override
+		protected String buildValue() {
+			if (this.overrideDefaultSchemaModel.getValue()) {
+				return this.defaultSchemaModel.getValue();
+			}
+			else {
+				return this.defaultDefaultSchemaModel.getValue();
+			}
+		}
+		
+		
+		// ************ WritablePropertyValueModel impl ************************
+		
+		public void setValue(String value) {
+			if (this.overrideDefaultSchemaModel.getValue()) {
+				this.defaultSchemaModel.setValue(value);
+			}
+			propertyChanged();
+		}
+	}
+	
+	
+	private static class DefaultSchemaTrigger
+		extends Trigger
+	{
+		private Trigger parentTrigger;
+		
+		private PropertyValueModel<Boolean> overrideDefaultSchemaModel;
+		
+		
+		private DefaultSchemaTrigger(
+				Trigger parentTrigger, 
+				PropertyValueModel<Boolean> overrideDefaultSchemaModel) {
+			super();
+			this.parentTrigger = parentTrigger;
+			this.parentTrigger.addPropertyChangeListener(
+				VALUE,
+				new PropertyChangeListener() {
+					public void propertyChanged(PropertyChangeEvent event) {
+						respondToParent();
+					}
+				});
+			this.overrideDefaultSchemaModel = overrideDefaultSchemaModel;
+			this.overrideDefaultSchemaModel.addPropertyChangeListener(
+				VALUE,
+				new PropertyChangeListener() {
+					public void propertyChanged(PropertyChangeEvent event) {
+						respondToOverride();
+					}
+				});
+		}
+		
+		
+		protected void respondToParent() {
+			if (this.parentTrigger.isAccepted()) {
+				if (this.overrideDefaultSchemaModel.getValue()) {
+					accept();
+				}
+			}
+			else if (this.parentTrigger.isReset()) {
+				reset();
+			}
+		}
+		
+		protected void respondToOverride() {
+			if (! this.overrideDefaultSchemaModel.getValue()) {
+				reset();
+			}
+		}
+	}
+	
+	
+	private static class SchemaChoicesModel
+		extends BaseCollectionAspectAdapter<ConnectionProfile, String>
+	{
+		private ConnectionListener connectionListener;
+		
+		
+		private SchemaChoicesModel(PropertyValueModel<ConnectionProfile> subjectHolder) {
+			super(subjectHolder);
+			this.connectionListener = buildConnectionListener();
+		}
+		
+		
+		// ************ initialization *****************************************
+		
+		private ConnectionListener buildConnectionListener() {
+			return new ConnectionAdapter() {
+				@Override
+				public void opened(ConnectionProfile profile) {
+					if (profile.equals(SchemaChoicesModel.this.subject)) {
+						collectionChanged();
+					}
+				}
+				@Override
+				public void schemaChanged(ConnectionProfile profile, Schema schema) {
+					if (profile.equals(SchemaChoicesModel.this.subject)) {
+						collectionChanged();
+					}
+				}
+			};
+		}
+		
+		
+		// ************ AspectAdapter impl *************************************
+		
+		@Override
+		protected void engageSubject_() {
+			this.subject.addConnectionListener(this.connectionListener);
+		}
+		
+		@Override
+		protected void disengageSubject_() {
+			this.subject.removeConnectionListener(this.connectionListener);
+		}
+		
+		
+		// ************ internal ***********************************************
+		
+		@Override
+		protected Iterator<String> iterator_() {
+			return (this.subject.getDatabase() == null) ? 
+				EmptyIterator.<String>instance() : 
+				this.subject.getDatabase().sortedSchemaIdentifiers();
 		}
 	}
 	
 	
 	private final class ConnectionGroup
 	{
-		final Combo connectionCombo;
-
-		private Link connectionLink;
-		
 		private Link connectLink;
 		
-		private final Button overrideDefaultSchemaButton;
-		
-		private final Label defaultSchemaLabel;
-		
-		private final Combo defaultSchemaCombo;
-		
 		
 		public ConnectionGroup(Composite composite) {
 			Group group = new Group(composite, SWT.NONE);
@@ -276,18 +1186,16 @@
 			group.setLayout(new GridLayout(3, false));
 			group.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
 
-			connectionCombo = createCombo(group, 3, true);
 			PlatformUI.getWorkbench().getHelpSystem().setHelp(group, JpaHelpContextIds.PROPERTIES_JAVA_PERSISTENCE_CONNECTION);
-			synchHelper.synchCombo(connectionCombo, CONNECTION, null);
-			connectionCombo.addSelectionListener(
-				new SelectionAdapter() {
-					@Override
-					public void widgetSelected(SelectionEvent e) {
-						updateConnectLink();
-					}
-				});
 			
-			connectionLink = new Link(group, SWT.NONE);
+			Combo connectionCombo = createCombo(group, 3, true);
+			
+			ComboModelAdapter.adapt(
+				JpaProjectPropertiesPage.this.connectionChoicesModel,
+				JpaProjectPropertiesPage.this.connectionModel,
+				connectionCombo);
+			
+			Link connectionLink = new Link(group, SWT.NONE);
 			GridData data = new GridData(GridData.END, GridData.CENTER, false, false);
 			data.horizontalSpan = 2;
 			connectionLink.setLayoutData(data);
@@ -306,7 +1214,7 @@
 			data.horizontalSpan = 2;
 			connectLink.setLayoutData(data);
 			connectLink.setText(JptUiMessages.JpaFacetWizardPage_connectLink);
-			connectLink.setEnabled(false);
+			updateConnectLink();
 			connectLink.addSelectionListener(
 				new SelectionAdapter() {
 					@Override
@@ -315,73 +1223,92 @@
 					}
 				});
 			
-			overrideDefaultSchemaButton = createButton(group, 3, JptUiMessages.JpaFacetWizardPage_overrideDefaultSchemaLabel, SWT.CHECK);
-			synchHelper.synchCheckbox(overrideDefaultSchemaButton, USER_WANTS_TO_OVERRIDE_DEFAULT_SCHEMA, new Control[0]);
+			PropertyChangeListener linkUpdateListener = new PropertyChangeListener() {
+					public void propertyChanged(PropertyChangeEvent event) {
+						updateConnectLink();
+					}
+				};
+			JpaProjectPropertiesPage.this.connectionModel.addPropertyChangeListener(
+					PropertyValueModel.VALUE,
+					linkUpdateListener);
 			
-			defaultSchemaLabel = new Label(group, SWT.LEFT);
+			
+			Button overrideDefaultSchemaButton = createButton(
+					group, 3, 
+					JptUiMessages.JpaFacetWizardPage_overrideDefaultSchemaLabel, 
+					SWT.CHECK);
+			
+			BooleanButtonModelAdapter.adapt(
+				JpaProjectPropertiesPage.this.overrideDefaultSchemaModel,
+				overrideDefaultSchemaButton);
+			
+			Label defaultSchemaLabel = new Label(group, SWT.LEFT);
 			defaultSchemaLabel.setText(JptUiMessages.JpaFacetWizardPage_defaultSchemaLabel);
 			GridData gd = new GridData();
 			gd.horizontalSpan = 1;
 			defaultSchemaLabel.setLayoutData(gd);
 			
-			defaultSchemaCombo = createCombo(group, 1, true);
-			synchHelper.synchCombo(
-				defaultSchemaCombo, USER_OVERRIDE_DEFAULT_SCHEMA, 
-				new Control[] {defaultSchemaLabel});
+			Combo defaultSchemaCombo = createCombo(group, 1, true);
 			
-			performDefaults();
+			ComboModelAdapter.adapt(
+				JpaProjectPropertiesPage.this.schemaChoicesModel,
+				JpaProjectPropertiesPage.this.combinedDefaultSchemaModel,
+				defaultSchemaCombo);
+			
+			new ControlEnabler(
+				JpaProjectPropertiesPage.this.overrideDefaultSchemaModel,
+				defaultSchemaLabel, defaultSchemaCombo);
 		}
 		
-		void openNewConnectionWizard() {
+		private void openNewConnectionWizard() {
 			String connectionName = DTPUiTools.createNewConnectionProfile();
 			if (connectionName != null) {
-				model.setProperty(CONNECTION, connectionName);
+				JpaProjectPropertiesPage.this.connectionModel.setValue(connectionName);
 			}
 		}
 		
-		void openConnectionProfile() {
-			ConnectionProfile cp = this.getConnectionProfile();
+		private void openConnectionProfile() {
+			ConnectionProfile cp = JpaProjectPropertiesPage.this.getConnectionProfile();
 			if (cp != null) {
 				cp.connect();
 			}
-			model.setBooleanProperty(CONNECTION_ACTIVE, (cp != null) && cp.isActive());
-			this.updateConnectLink(cp);
-			return;
+			updateConnectLink();
 		}
 		
-		void updateConnectLink(ConnectionProfile cp) {
-			connectLink.setEnabled((cp != null) && cp.isDisconnected());
-		}
-		
-		void updateConnectLink() {
-			this.updateConnectLink(this.getConnectionProfile());
-		}
-		
-		ConnectionProfile getConnectionProfile() {
-			// we just use the connection profile to log in, so go to the db plug-in
-			return JptDbPlugin.instance().getConnectionProfileFactory().buildConnectionProfile(model.getStringProperty(CONNECTION));
-		}
-
-		void performDefaults() {
-			if (getJpaProject() == null) {
-				return;
-			}
-			model.setProperty(CONNECTION, getJpaProject().getDataSource().getConnectionProfileName());
-			
-			String defaultSchema = getJpaProject().getUserOverrideDefaultSchema();
-			model.setProperty(USER_WANTS_TO_OVERRIDE_DEFAULT_SCHEMA, Boolean.valueOf(defaultSchema != null));
-			model.setProperty(USER_OVERRIDE_DEFAULT_SCHEMA, defaultSchema);
+		private void updateConnectLink() {
+			ConnectionProfile cp = getConnectionProfile();
+			this.connectLink.setEnabled((cp != null) && cp.isDisconnected());
 		}
 	}
-
-
+	
+	
+	private class DiscoverAnnotatedClassesModel
+		extends PropertyAspectAdapter<JpaProject, Boolean>
+	{
+		private DiscoverAnnotatedClassesModel(PropertyValueModel<JpaProject> jpaProjectModel) { 
+			super(jpaProjectModel, JpaProject.DISCOVERS_ANNOTATED_CLASSES_PROPERTY);
+		}
+		
+		
+		// ************ WritablePropertyValueModel impl ************************
+		
+		@Override
+		protected void setValue_(Boolean newValue) {
+			this.subject.setDiscoversAnnotatedClasses(newValue);
+		}
+		
+		
+		// ************ internal ***********************************************
+		
+		@Override
+		protected Boolean buildValue_() {
+			return this.subject.discoversAnnotatedClasses();
+		}
+	}
+	
+	
 	private final class PersistentClassManagementGroup
 	{
-		final Button discoverClassesButton;
-
-		final Button listClassesButton;
-
-
 		public PersistentClassManagementGroup(Composite composite) {
 			Group group = new Group(composite, SWT.NONE);
 			group.setText(JptUiMessages.JpaFacetWizardPage_persistentClassManagementLabel);
@@ -389,21 +1316,17 @@
 			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);
+			Button discoverClassesButton = createButton(group, 1, JptUiMessages.JpaFacetWizardPage_discoverClassesButton, SWT.RADIO);
 			
-			listClassesButton = createButton(group, 1, JptUiMessages.JpaFacetWizardPage_listClassesButton, SWT.RADIO);
-			synchHelper.synchRadio(listClassesButton, LIST_ANNOTATED_CLASSES, null);
+			BooleanButtonModelAdapter.adapt(
+				JpaProjectPropertiesPage.this.discoverAnnotatedClassesModel, 
+				discoverClassesButton);
 			
-			performDefaults();
-		}
-		
-		void performDefaults() {
-			if (getJpaProject() == null) {
-				return;
-			}
-			boolean discoverClasses = getJpaProject().discoversAnnotatedClasses();
-			model.setProperty(DISCOVER_ANNOTATED_CLASSES, Boolean.valueOf(discoverClasses));
+			Button listClassesButton = createButton(group, 1, JptUiMessages.JpaFacetWizardPage_listClassesButton, SWT.RADIO);
+			
+			BooleanButtonModelAdapter.adapt(
+				JpaProjectPropertiesPage.this.listAnnotatedClassesModel,
+				listClassesButton);
 		}
 	}
-}
\ No newline at end of file
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/JpaFacetWizardPage.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/JpaFacetWizardPage.java
index 7f1d0d3..dec0687 100644
--- a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/JpaFacetWizardPage.java
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/JpaFacetWizardPage.java
@@ -10,9 +10,7 @@
 package org.eclipse.jpt.ui.internal.wizards;
 
 import org.eclipse.core.runtime.IStatus;
-import org.eclipse.jdt.ui.JavaUI;
 import org.eclipse.jface.dialogs.Dialog;
-import org.eclipse.jface.preference.PreferenceDialog;
 import org.eclipse.jpt.core.internal.facet.JpaFacetDataModelProperties;
 import org.eclipse.jpt.db.ConnectionProfile;
 import org.eclipse.jpt.db.JptDbPlugin;
@@ -21,7 +19,8 @@
 import org.eclipse.jpt.ui.internal.JpaHelpContextIds;
 import org.eclipse.jpt.ui.internal.JptUiIcons;
 import org.eclipse.jpt.ui.internal.JptUiMessages;
-import org.eclipse.jpt.ui.internal.prefs.JpaPreferencePage;
+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.events.SelectionAdapter;
 import org.eclipse.swt.events.SelectionEvent;
@@ -35,8 +34,8 @@
 import org.eclipse.swt.widgets.Label;
 import org.eclipse.swt.widgets.Link;
 import org.eclipse.ui.PlatformUI;
-import org.eclipse.ui.dialogs.PreferencesUtil;
-import org.eclipse.wst.common.frameworks.datamodel.IDataModel;
+import org.eclipse.wst.common.frameworks.datamodel.DataModelEvent;
+import org.eclipse.wst.common.frameworks.datamodel.IDataModelListener;
 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;
@@ -46,6 +45,7 @@
 public class JpaFacetWizardPage extends DataModelFacetInstallPage
 	implements JpaFacetDataModelProperties
 {
+	
 	public JpaFacetWizardPage() {
 		super("jpt.jpa.facet.install.page"); //$NON-NLS-1$
 		setTitle(JptUiMessages.JpaFacetWizardPage_title);
@@ -53,7 +53,6 @@
 		setImageDescriptor(JptUiPlugin.getImageDescriptor(JptUiIcons.JPA_WIZ_BANNER));
 	}
 
-
 	@Override
 	protected Composite createTopLevelComposite(Composite parent) {
 		Composite composite = new Composite(parent, SWT.NULL);
@@ -61,8 +60,8 @@
 		composite.setLayout(layout);
 
 		new PlatformGroup(composite);
-		new ConnectionGroup(composite);
 		new ClasspathConfigGroup(composite);
+		new ConnectionGroup(composite);
 		new PersistentClassManagementGroup(composite);
 		new OrmXmlGroup(composite);
 
@@ -121,9 +120,8 @@
 			DB_DRIVER_JARS,
 			USER_WANTS_TO_OVERRIDE_DEFAULT_SCHEMA,
 			USER_OVERRIDE_DEFAULT_SCHEMA,
-			USE_SERVER_JPA_IMPLEMENTATION,
-			JPA_LIBRARY,
-			DISCOVER_ANNOTATED_CLASSES
+			DISCOVER_ANNOTATED_CLASSES,
+			LIBRARY_PROVIDER_DELEGATE
 		};
 	}
 
@@ -133,7 +131,13 @@
 			return false;
 		}
 		else {
-			return (model.validate().getSeverity() != IStatus.ERROR);
+			IStatus status =model.validate(); 
+			if( status.getSeverity() == IStatus.ERROR){
+				setErrorMessage( status.getMessage() );
+				return false;
+			};
+			setErrorMessage(null);
+			return true;
 		}
 	}
 
@@ -162,8 +166,34 @@
 			synchHelper.synchCombo(platformCombo, PLATFORM_ID, null);
 		}
 	}
-
-
+	
+	
+	private final class ClasspathConfigGroup
+	{
+		public ClasspathConfigGroup(Composite composite) {
+			
+			final LibraryInstallDelegate librariesInstallDelegate
+				= (LibraryInstallDelegate) getDataModel().getProperty(LIBRARY_PROVIDER_DELEGATE);
+			
+			getDataModel().addListener(
+				new IDataModelListener() {
+					public void propertyChanged(DataModelEvent event) {
+						if (event.getPropertyName().equals(JpaFacetDataModelProperties.PLATFORM_ID)) {
+							librariesInstallDelegate.refresh();
+						}
+					}
+				});			
+			
+			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);			
+		}
+	}
+	
+	
 	private final class ConnectionGroup
 	{
 		private final Combo connectionCombo;
@@ -288,91 +318,8 @@
 			return JptDbPlugin.instance().getConnectionProfileFactory().buildConnectionProfile(model.getStringProperty(CONNECTION));
 		}
 	}
-
-
-	private final class ClasspathConfigGroup
-	{
-		private final Button useServerLibButton;
-
-		private final Button specifyLibButton;
-
-		private final Combo jpaLibCombo;
-
-		private final Link jpaPrefsLink;
-
-		private final Link userLibsLink;
-		
-		
-		public ClasspathConfigGroup(Composite composite) {
-			Group group = new Group(composite, SWT.NONE);
-			group.setText(JptUiMessages.JpaFacetWizardPage_jpaImplementationLabel);
-			group.setLayout(new GridLayout(2, false));
-			group.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-			PlatformUI.getWorkbench().getHelpSystem().setHelp(group, JpaHelpContextIds.NEW_JPA_PROJECT_CONTENT_PAGE_CLASSPATH);
-			
-			useServerLibButton = createButton(group, 2, JptUiMessages.JpaFacetWizardPage_userServerLibLabel, SWT.RADIO);
-			synchHelper.synchRadio(useServerLibButton, USE_SERVER_JPA_IMPLEMENTATION, null);
-			
-			specifyLibButton = createButton(group, 1, JptUiMessages.JpaFacetWizardPage_specifyLibLabel, SWT.RADIO);
-			synchHelper.synchRadio(specifyLibButton, USE_USER_JPA_LIBRARY, null);
-			
-			jpaLibCombo = createCombo(group, 1, true);
-			synchHelper.synchCombo(jpaLibCombo, JPA_LIBRARY, null);
-			
-			jpaPrefsLink = new Link(group, SWT.NONE);
-			GridData data = new GridData(GridData.END, GridData.CENTER, false, false);
-			data.horizontalSpan = 2;
-			jpaPrefsLink.setLayoutData(data);
-			jpaPrefsLink.setText(JptUiMessages.JpaFacetWizardPage_jpaPrefsLink);
-			jpaPrefsLink.addSelectionListener(
-				new SelectionAdapter() {
-					@Override
-					public void widgetSelected(SelectionEvent e) {
-						promptToConfigJpaPrefs();
-					}
-				}
-			);
-			
-			userLibsLink = new Link(group, SWT.NONE);
-			data = new GridData(GridData.END, GridData.CENTER, false, false);
-			data.horizontalSpan = 2;
-			userLibsLink.setLayoutData(data);
-			userLibsLink.setText(JptUiMessages.JpaFacetWizardPage_userLibsLink);
-			userLibsLink.addSelectionListener(
-				new SelectionAdapter() {
-					@Override
-					public void widgetSelected(SelectionEvent e) {
-						promptToConfigUserLibraries();
-					}
-				}
-			);
-		}
-		
-		private void promptToConfigJpaPrefs() {
-			PreferenceDialog dlg =
-				PreferencesUtil.createPreferenceDialogOn(
-					getShell(),
-					JpaPreferencePage.ID,
-					new String[] {JpaPreferencePage.ID},
-					null);
-			dlg.open();
-			model.notifyPropertyChange(JPA_LIBRARY, IDataModel.VALID_VALUES_CHG);
-			model.notifyPropertyChange(JPA_LIBRARY, IDataModel.DEFAULT_CHG);
-		}
-		
-		private void promptToConfigUserLibraries() {
-			PreferenceDialog dlg =
-				PreferencesUtil.createPreferenceDialogOn(
-					getShell(),
-					JavaUI.ID_USER_LIBRARY_PREFERENCE_PAGE,
-					new String[] {JavaUI.ID_USER_LIBRARY_PREFERENCE_PAGE},
-					null);
-			dlg.open();
-			model.notifyPropertyChange(JPA_LIBRARY, IDataModel.VALID_VALUES_CHG);
-		}
-	}
-
-
+	
+	
 	private final class PersistentClassManagementGroup
 	{
 		private final Button discoverClassesButton;