/*******************************************************************************
 * Copyright (c) 2007, 2009 Oracle. All rights reserved.
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v1.0, which accompanies this distribution
 * and is available at http://www.eclipse.org/legal/epl-v10.html.
 *
 * Contributors:
 *     Oracle - initial API and implementation
 ******************************************************************************/
package org.eclipse.jpt.ui.internal.properties;

import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Comparator;
import java.util.EventListener;
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.JptCoreMessages;
import org.eclipse.jpt.core.internal.facet.JpaLibraryProviderConstants;
import org.eclipse.jpt.core.internal.platform.JpaPlatformRegistry;
import org.eclipse.jpt.db.Catalog;
import org.eclipse.jpt.db.ConnectionAdapter;
import org.eclipse.jpt.db.ConnectionListener;
import org.eclipse.jpt.db.ConnectionProfile;
import org.eclipse.jpt.db.ConnectionProfileListener;
import org.eclipse.jpt.db.Database;
import org.eclipse.jpt.db.JptDbPlugin;
import org.eclipse.jpt.db.Schema;
import org.eclipse.jpt.db.SchemaContainer;
import org.eclipse.jpt.db.ui.internal.DTPUiTools;
import org.eclipse.jpt.ui.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.ExtendedListValueModelWrapper;
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.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.core.libprov.LibraryInstallDelegate;
import org.eclipse.jst.common.project.facet.ui.libprov.LibraryFacetPropertyPage;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Link;
import org.eclipse.ui.PlatformUI;
import org.eclipse.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;

public class JpaProjectPropertiesPage
	extends LibraryFacetPropertyPage 
{
	public static final String PROP_ID = "org.eclipse.jpt.ui.jpaProjectPropertiesPage"; //$NON-NLS-1$

	private WritablePropertyValueModel<IProject> projectHolder;
	
	private PropertyValueModel<JpaProject> jpaProjectHolder;
	
	private Trigger trigger;
	
	private PropertyChangeListener validationListener;
	
	private PropertyChangeListener overrideDefaultCatalogListener;
	
	private PropertyChangeListener overrideDefaultSchemaListener;

	private PropertyChangeListener platformChangelistener;
	
	private BufferedWritablePropertyValueModel<String> platformIdModel;
	
	private BufferedWritablePropertyValueModel<String> connectionModel;
	
	private ListValueModel<String> connectionChoicesModel;
	
	private PropertyValueModel<ConnectionProfile> connectionProfileModel;
	
	private BufferedWritablePropertyValueModel<Boolean> overrideDefaultCatalogModel;
	
	private BufferedWritablePropertyValueModel<String> defaultCatalogModel;
	
	private WritablePropertyValueModel<String> combinedDefaultCatalogModel;
	
	private ListValueModel<String> catalogChoicesModel;

	private BufferedWritablePropertyValueModel<Boolean> overrideDefaultSchemaModel;
	
	private BufferedWritablePropertyValueModel<String> defaultSchemaModel;
	
	private WritablePropertyValueModel<String> combinedDefaultSchemaModel;
	
	private ListValueModel<String> schemaChoicesModel;
	
	private BufferedWritablePropertyValueModel<Boolean> discoverAnnotatedClassesModel;
	
	private WritablePropertyValueModel<Boolean> listAnnotatedClassesModel;


	// ************ construction/initialization ************

	public JpaProjectPropertiesPage() {
		super();
		initialize();
	}

	protected void initialize() {
		this.projectHolder = new SimplePropertyValueModel<IProject>();
		this.jpaProjectHolder = initializeJpaProjectHolder();
		this.trigger = new Trigger();
		this.validationListener = this.initializeValidationListener();
		this.overrideDefaultCatalogListener = this.initializeOverrideDefaultCatalogChangeListener();
		this.overrideDefaultSchemaListener = this.initializeOverrideDefaultSchemaChangeListener();
		
		this.platformChangelistener = this.initializePlatformChangeListener();
		this.platformIdModel = this.initializePlatformIdModel();
		
		this.connectionModel = this.initializeConnectionModel();
		this.connectionChoicesModel = this.initializeConnectionChoicesModel();
		this.connectionProfileModel = this.initializeConnectionProfileModel();
		
		this.overrideDefaultCatalogModel = this.initializeOverrideDefaultCatalogModel();
		this.defaultCatalogModel = this.initializeDefaultCatalogModel();
		this.combinedDefaultCatalogModel = this.initializeCombinedDefaultCatalogModel();
		this.catalogChoicesModel = this.initializeCatalogChoicesModel();
		
		this.overrideDefaultSchemaModel = this.initializeOverrideDefaultSchemaModel();
		this.defaultSchemaModel = this.initializeDefaultSchemaModel();
		this.combinedDefaultSchemaModel = this.initializeCombinedDefaultSchemaModel();
		this.schemaChoicesModel = this.initializeSchemaChoicesModel();
		
		this.discoverAnnotatedClassesModel = this.initializeDiscoverAnnotatedClassesModel();
		this.listAnnotatedClassesModel = this.initializeListAnnotatedClassesModel();
	}
	
	protected PropertyValueModel<JpaProject> initializeJpaProjectHolder() {
		return new JpaProjectHolder(this.projectHolder);
	}
	
	protected PropertyChangeListener initializeValidationListener() {
		return new PropertyChangeListener() {
			public void propertyChanged(PropertyChangeEvent event) {
				if (! JpaProjectPropertiesPage.this.getControl().isDisposed()) {
					updateValidation();
				}
			}
		};
	}
	
	protected PropertyChangeListener initializeOverrideDefaultCatalogChangeListener() {
		return new PropertyChangeListener() {
			public void propertyChanged(PropertyChangeEvent event) {
				Boolean enabled = (Boolean) event.getNewValue();
				if( ! enabled) {
					defaultCatalogModel.setValue(null);
				}
			}
		};
	}
	
	protected PropertyChangeListener initializeOverrideDefaultSchemaChangeListener() {
		return new PropertyChangeListener() {
			public void propertyChanged(PropertyChangeEvent event) {
				Boolean enabled = (Boolean) event.getNewValue();
				if( ! enabled) {
					defaultSchemaModel.setValue(null);
				}
			}
		};
	}
	
	protected PropertyChangeListener initializePlatformChangeListener(){
		return new PropertyChangeListener() {
			public void propertyChanged(PropertyChangeEvent event) {
				if (! JpaProjectPropertiesPage.this.getControl().isDisposed()) {
					JpaProjectPropertiesPage.this.getLibraryInstallDelegate().
						setEnablementContextVariable(
							JpaLibraryProviderConstants.EXPR_VAR_JPA_PLATFORM,
							event.getNewValue());
				}
			}
		};
	}
	
	protected BufferedWritablePropertyValueModel<String> initializePlatformIdModel() {
		BufferedWritablePropertyValueModel<String> model =
			new BufferedWritablePropertyValueModel(
				new PlatformIdModel(this.jpaProjectHolder), this.trigger);
		model.addPropertyChangeListener(PropertyValueModel.VALUE, this.validationListener);
		model.addPropertyChangeListener(PropertyValueModel.VALUE, this.platformChangelistener);
		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 ExtendedListValueModelWrapper(
				(String) null,
				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> initializeOverrideDefaultCatalogModel() {
		OverrideDefaultCatalogModel model = new OverrideDefaultCatalogModel(this.jpaProjectHolder);
		model.addPropertyChangeListener(PropertyValueModel.VALUE, this.overrideDefaultCatalogListener);

		BufferedWritablePropertyValueModel<Boolean> bufferedModel = new BufferedWritablePropertyValueModel<Boolean>(model, this.trigger);
		bufferedModel.addPropertyChangeListener(PropertyValueModel.VALUE, this.validationListener);

		return bufferedModel;
	}
	
	protected BufferedWritablePropertyValueModel<String> initializeDefaultCatalogModel() {
		return new BufferedWritablePropertyValueModel(
			new DefaultCatalogModel(this.jpaProjectHolder),
			this.trigger);
	}
	
	protected WritablePropertyValueModel<String> initializeCombinedDefaultCatalogModel() {
		WritablePropertyValueModel<String> model = 
			new CombinedDefaultCatalogModel(
				this.defaultCatalogModel,
				this.overrideDefaultCatalogModel,
				new DefaultDefaultCatalogModel(this.connectionProfileModel));
		model.addPropertyChangeListener(PropertyValueModel.VALUE, this.validationListener);
		return model;
	}
	
	protected ListValueModel<String> initializeCatalogChoicesModel() {
		Collection<CollectionValueModel<String>> cvms = new ArrayList<CollectionValueModel<String>>();
		cvms.add(new PropertyCollectionValueModelAdapter<String>(this.defaultCatalogModel));
		cvms.add(new CatalogChoicesModel(this.connectionProfileModel));
		return new CollectionListValueModelAdapter<String>(
			new CompositeCollectionValueModel<CollectionValueModel<String>, String>(cvms) {
				@Override
				public Iterator<String> iterator() {
					ArrayList<String> uniqueValues = new ArrayList<String>();
					for (String each : CollectionTools.iterable(super.iterator())) {
						if ((each != null) && ! uniqueValues.contains(each)) {
							uniqueValues.add(each);
						}
					}
					return uniqueValues.iterator();
				}
			});
	}

	protected BufferedWritablePropertyValueModel<Boolean> initializeOverrideDefaultSchemaModel() {
		OverrideDefaultSchemaModel model = new OverrideDefaultSchemaModel(this.jpaProjectHolder);
		BufferedWritablePropertyValueModel<Boolean> modelBuffer = 
			new BufferedWritablePropertyValueModel(model, this.trigger);
		model.addPropertyChangeListener(PropertyValueModel.VALUE, this.overrideDefaultSchemaListener);
		modelBuffer.addPropertyChangeListener(PropertyValueModel.VALUE, this.validationListener);
		return modelBuffer;
	
	}
	
	protected BufferedWritablePropertyValueModel<String> initializeDefaultSchemaModel() {
		return new BufferedWritablePropertyValueModel(
			new DefaultSchemaModel(this.jpaProjectHolder),
			this.trigger);
	}
	
	protected WritablePropertyValueModel<String> initializeCombinedDefaultSchemaModel() {
		WritablePropertyValueModel<String> model = 
			new CombinedDefaultSchemaModel(
				this.defaultSchemaModel,
				this.overrideDefaultSchemaModel,
				new DefaultDefaultSchemaModel(this.defaultCatalogModel, this.connectionProfileModel));
		model.addPropertyChangeListener(PropertyValueModel.VALUE, this.validationListener);
		return model;
	}
	
	protected ListValueModel<String> initializeSchemaChoicesModel() {
		Collection<CollectionValueModel<String>> cvms = new ArrayList<CollectionValueModel<String>>();
		cvms.add(new PropertyCollectionValueModelAdapter<String>(this.defaultSchemaModel));
		cvms.add(new SchemaChoicesModel(this.defaultCatalogModel, this.connectionProfileModel));
		return new CollectionListValueModelAdapter<String>(
			new CompositeCollectionValueModel<CollectionValueModel<String>, String>(cvms) {
				@Override
				public Iterator<String> iterator() {
					ArrayList<String> uniqueValues = new ArrayList<String>();
					for (String each : CollectionTools.iterable(super.iterator())) {
						if ((each != null) && ! uniqueValues.contains(each)) {
							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;
			}
		};
	}

	// ************ queries ************
	
	protected JpaProject getJpaProject() {
		return this.jpaProjectHolder.getValue();
	}
	
	protected String getJpaPlatformId() {
		return this.platformIdModel.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 getOverrideDefaultCatalog() {
		return this.overrideDefaultCatalogModel.getValue();
	}
	
	protected List<String> getDefaultCatalogChoices() {
		return CollectionTools.list(this.catalogChoicesModel.iterator());
	}
	
	protected String getDefaultCatalog() {
		return this.defaultCatalogModel.getValue();
	}
	
	
	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 LibraryInstallDelegate createLibraryInstallDelegate(
			IFacetedProject project, IProjectFacetVersion fv) {
		Map<String, Object> enablementVariables = new HashMap<String, Object>();
		enablementVariables.put(
			JpaLibraryProviderConstants.EXPR_VAR_JPA_PLATFORM, "");	
		return new LibraryInstallDelegate(project, fv, enablementVariables);
	}
	
	@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;
		if (fillHorizontal) {
			gd = new GridData(GridData.FILL_HORIZONTAL);
		}
		else {
			gd = new GridData();
		}
		gd.horizontalSpan = span;
		combo.setLayoutData(gd);
		return combo;
	}
	
	@Override
	public boolean performOk() {
		super.performOk();
		
		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 {
					IWorkspace ws = ResourcesPlugin.getWorkspace();
					ws.run(wr, ws.getRoot(), IWorkspace.AVOID_UPDATE, monitor);
				}
				catch(CoreException e) {
					throw new InvocationTargetException(e);
				}
			}
		};
		
		try {
			new ProgressMonitorDialog(getShell()).run(true, false, op);
		}
		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.overrideDefaultCatalogModel.isBuffering()
				|| this.defaultCatalogModel.isBuffering()
				|| this.overrideDefaultSchemaModel.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)));
			}
			else if (! connectionProfile.isActive()) {
				statuses.get(IStatus.INFO).add( 
					buildInfoStatus(
						JptCoreMessages.VALIDATE_CONNECTION_NOT_CONNECTED));
			}
		}
		
		/* default catalog */
		if (getOverrideDefaultCatalog()) {
			String defaultCatalog = getDefaultCatalog();
			if (StringTools.stringIsEmpty(defaultCatalog)) {
				statuses.get(IStatus.ERROR).add( 
					buildErrorStatus(
						JptCoreMessages.VALIDATE_DEFAULT_CATALOG_NOT_SPECIFIED));
			}
			else if (connectionProfile != null
				&& connectionProfile.isConnected()
				&& ! getDefaultCatalogChoices().contains(defaultCatalog)) {
				statuses.get(IStatus.WARNING).add(
					buildWarningStatus(
						NLS.bind(
							JptCoreMessages.VALIDATE_CONNECTION_DOESNT_CONTAIN_CATALOG,
							defaultCatalog)));
			}
		}
		
		/* 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);
	}
	
	@Override
	public void dispose() {
		super.dispose();
		this.platformIdModel.removePropertyChangeListener(PropertyValueModel.VALUE, platformChangelistener);
	}
	
	
	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 EventListener> getListenerClass() {
			return PropertyChangeListener.class;
		}
		
		@Override
		protected String getListenerAspectName() {
			return VALUE;
		}
		
		@Override
		protected boolean hasListeners() {
			return hasAnyPropertyChangeListeners(VALUE);
		}
		
		@Override
		protected void fireAspectChanged(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.fireAspectChanged(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 EventListener> getListenerClass() {
			return CollectionChangeListener.class;
		}
	
		@Override
		protected String getListenerAspectName() {
			return VALUES;
		}
	
		@Override
		protected boolean hasListeners() {
			return this.hasAnyCollectionChangeListeners(VALUES);
		}
		
		@Override
		protected void fireAspectChanged(Object oldValue, Object newValue) {
			@SuppressWarnings("unchecked") Iterator<E> newIterator = (Iterator<E>) newValue;
			this.fireCollectionChanged(VALUES, CollectionTools.collection(newIterator));
		}
		
		
		// ************ internal ***********************************************
		
		protected Iterator<E> iterator_() {
			throw new UnsupportedOperationException();
		}
		
		protected int size_() {
			return CollectionTools.size(this.iterator());
		}
		
		protected void collectionChanged() {
			this.fireCollectionChanged(VALUES, CollectionTools.collection(this.iterator()));
		}
	}
	
	
	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
	{
		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));
			
			Combo platformCombo = createCombo(group, 1, true);
			
			ComboModelAdapter.adapt(
				buildPlatformChoicesListValueModel(),
				JpaProjectPropertiesPage.this.platformIdModel,
				platformCombo,
				buildPlatformLabelConverter());
		}
		
		
		private ListValueModel<String> buildPlatformChoicesListValueModel() {
			return new SortedListValueModelAdapter<String>(
				new SimpleListValueModel<String>(
					CollectionTools.list(JpaPlatformRegistry.instance().jpaPlatformIds())),
				new Comparator<String>() {
					public int compare(String o1, String o2) {
						return JpaPlatformRegistry.instance().getJpaPlatformLabel(o1).
							compareTo(JpaPlatformRegistry.instance().getJpaPlatformLabel(o2));
					}
				});
		}
		
		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) {
			this.subject.getDataSource().setConnectionProfileName(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 this.subject.getDataSource().getConnectionProfileName();
		}
	}
	
	
	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 abstract static class OverrideDefaultModel
		extends BasePropertyAspectAdapter<JpaProject, Boolean>
	{
		// the superclass "value" is the *cached* value
		private Boolean actualValue;


		OverrideDefaultModel(PropertyValueModel<JpaProject> jpaProjectHolder) {
			super(jpaProjectHolder);
		}
		
		
		// ************ WritablePropertyValueModel impl ************************
		
		@Override
		public Boolean getValue() {
			Boolean v = super.getValue();
			return (v == null) ? Boolean.FALSE : v;
		}
		
		@Override
		public void setValue_(Boolean newValue) {
			this.actualValue = newValue;
			this.valueChanged();
		}
		
		
		// ************ AspectAdapter impl *************************************
		
		@Override
		protected void engageSubject_() {
			// we need to build 'actualValue' *before* calling 'super'
			// because 'super' calls back here to #buildValue_()
			this.actualValue = this.buildActualValue_();
			super.engageSubject_();
		}
		
		@Override
		protected void disengageSubject_() {
			super.disengageSubject_();
			this.actualValue = null;
		}
		
		
		// ************ internal ***********************************************
		
		@Override
		protected Boolean buildValue_() {
			return this.actualValue;
		}
		
		protected Boolean buildActualValue_() {
			return Boolean.valueOf(this.subjectHasUserOverrideDefault());
		}

		protected boolean subjectHasUserOverrideDefault() {
			return ! StringTools.stringIsEmpty(this.getSubjectUserOverrideDefault());
		}
		
		protected abstract String getSubjectUserOverrideDefault();
	}

	
	// ************ Catalog ************
	private static class OverrideDefaultCatalogModel
		extends OverrideDefaultModel
	{
		OverrideDefaultCatalogModel(PropertyValueModel<JpaProject> jpaProjectHolder) {
			super(jpaProjectHolder);
		}

		@Override
		protected String getSubjectUserOverrideDefault() {
			return this.subject.getUserOverrideDefaultCatalog();
		}
	}

	
	private static class DefaultCatalogModel
		extends PropertyAspectAdapter<JpaProject, String>
	{
		DefaultCatalogModel(PropertyValueModel<JpaProject> jpaProjectModel) { 
			super(jpaProjectModel, JpaProject.USER_OVERRIDE_DEFAULT_CATALOG_PROPERTY);
		}
		
		
		// ************ WritablePropertyValueModel impl ************************
		
		@Override
		public void setValue_(String newCatalog) {
			this.subject.setUserOverrideDefaultCatalog(newCatalog);
		}
		
		
		// ************ internal ***********************************************
		
		@Override
		protected String buildValue_() {
			return this.subject.getUserOverrideDefaultCatalog();
		}
	}

	private abstract static class ConnectionProfilePropertyAspectAdapter<V>
		extends BasePropertyAspectAdapter<ConnectionProfile, V>
	{
		private ConnectionListener connectionListener;

		ConnectionProfilePropertyAspectAdapter(PropertyValueModel<ConnectionProfile> connectionProfileModel) {
			super(connectionProfileModel);
			this.connectionListener = this.buildConnectionListener();
		}

		// the connection opening is probably the only thing that will happen...
		private ConnectionListener buildConnectionListener() {
			return new ConnectionAdapter() {
				@Override
				public void opened(ConnectionProfile profile) {
					ConnectionProfilePropertyAspectAdapter.this.profileOpened(profile);
				}
			};
		}

		void profileOpened(ConnectionProfile profile) {
			if (profile.equals(this.subject)) {
				this.valueChanged();
			}
		}

		@Override
		protected void engageSubject_() {
			super.engageSubject_();
			this.subject.addConnectionListener(this.connectionListener);
		}

		@Override
		protected void disengageSubject_() {
			this.subject.removeConnectionListener(this.connectionListener);
			super.disengageSubject_();
		}

	}

	private static class DefaultDefaultCatalogModel
		extends ConnectionProfilePropertyAspectAdapter<String>
	{
		DefaultDefaultCatalogModel(PropertyValueModel<ConnectionProfile> connectionProfileModel) {
			super(connectionProfileModel);
		}

		@Override
		protected String buildValue_() {
			Database db = this.subject.getDatabase();
			if (db == null) {
				return null;
			}
			Catalog catalog = db.getDefaultCatalog();
			return (catalog == null) ? null : catalog.getIdentifier();
		}
	}

	private static class CombinedDefaultCatalogModel
		extends ListPropertyValueModelAdapter<String>
		implements WritablePropertyValueModel<String>
	{
		private WritablePropertyValueModel<String> defaultCatalogModel;
		
		private PropertyValueModel<Boolean> overrideDefaultCatalogModel;
		
		private PropertyValueModel<String> defaultDefaultCatalogModel;
		
		
		CombinedDefaultCatalogModel(
				WritablePropertyValueModel<String> defaultCatalogModel,
				PropertyValueModel<Boolean> overrideDefaultCatalogModel,
				PropertyValueModel<String> defaultDefaultCatalogModel) {
			super(
				new CompositeListValueModel<ListValueModel<?>,Object>(
					CollectionTools.<ListValueModel<?>>list(
						new PropertyListValueModelAdapter<String>(defaultCatalogModel),
						new PropertyListValueModelAdapter<Boolean>(overrideDefaultCatalogModel),
						new PropertyListValueModelAdapter<String>(defaultDefaultCatalogModel)
					)));
			this.defaultCatalogModel = defaultCatalogModel;
			this.overrideDefaultCatalogModel = overrideDefaultCatalogModel;
			this.defaultDefaultCatalogModel = defaultDefaultCatalogModel;
		}
		
		
		// ************ ListPropertyValueModelAdapter impl *********************
		
		@Override
		protected String buildValue() {
			if (this.overrideDefaultCatalogModel.getValue()) {
				return this.defaultCatalogModel.getValue();
			}
			return this.defaultDefaultCatalogModel.getValue();
		}
		
		
		// ************ WritablePropertyValueModel impl ************************
		
		public void setValue(String value) {
			if (this.overrideDefaultCatalogModel.getValue()) {
				this.defaultCatalogModel.setValue(value);
			}
			propertyChanged();
		}
	}

	
	private static class ConnectionProfileCollectionAspectAdapter<E>
		extends BaseCollectionAspectAdapter<ConnectionProfile, E>
	{
		private ConnectionListener connectionListener;

		ConnectionProfileCollectionAspectAdapter(PropertyValueModel<ConnectionProfile> subjectHolder) {
			super(subjectHolder);
			this.connectionListener = this.buildConnectionListener();
		}

		// the connection opening is probably the only thing that will happen...
		private ConnectionListener buildConnectionListener() {
			return new ConnectionAdapter() {
				@Override
				public void opened(ConnectionProfile profile) {
					ConnectionProfileCollectionAspectAdapter.this.profileOpened(profile);
				}
			};
		}

		void profileOpened(ConnectionProfile profile) {
			if (profile.equals(this.subject)) {
				this.collectionChanged();
			}
		}

		@Override
		protected void engageSubject_() {
			this.subject.addConnectionListener(this.connectionListener);
		}

		@Override
		protected void disengageSubject_() {
			this.subject.removeConnectionListener(this.connectionListener);
		}

	}

	private static class CatalogChoicesModel
		extends ConnectionProfileCollectionAspectAdapter<String>
	{
		CatalogChoicesModel(PropertyValueModel<ConnectionProfile> subjectHolder) {
			super(subjectHolder);
		}

		@Override
		protected Iterator<String> iterator_() {
			Database db = this.subject.getDatabase();
			// use catalog *identifiers* since the string ends up being the "default" for various text entries
			return (db != null) ? db.sortedCatalogIdentifiers() : EmptyIterator.<String>instance();
		}
	}

	
	// ************ Schema ************
	private static class OverrideDefaultSchemaModel
		extends OverrideDefaultModel
	{
		OverrideDefaultSchemaModel(PropertyValueModel<JpaProject> jpaProjectHolder) {
			super(jpaProjectHolder);
		}

		@Override
		public String getSubjectUserOverrideDefault() {
			return this.subject.getUserOverrideDefaultSchema();
		}
	}
	
	
	private static class DefaultSchemaModel
		extends PropertyAspectAdapter<JpaProject, String>
	{
		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 ConnectionProfilePropertyAspectAdapter<String>
	{
		private final PropertyValueModel<String> defaultCatalogModel;
		private final PropertyChangeListener catalogListener;

		DefaultDefaultSchemaModel(PropertyValueModel<String> defaultCatalogModel,
				PropertyValueModel<ConnectionProfile> connectionProfileModel) {
			super(connectionProfileModel);
			this.defaultCatalogModel = defaultCatalogModel;
			this.catalogListener = this.buildCatalogListener();
		}

		private PropertyChangeListener buildCatalogListener() {
			return new PropertyChangeListener() {
				public void propertyChanged(PropertyChangeEvent event) {
					DefaultDefaultSchemaModel.this.valueChanged();
				}
			};
		}

		@Override
		protected void engageSubject_() {
			// call 'super' last?
			this.defaultCatalogModel.addPropertyChangeListener(PropertyValueModel.VALUE, this.catalogListener);
			super.engageSubject_();
		}
		
		@Override
		protected void disengageSubject_() {
			super.disengageSubject_();
			this.defaultCatalogModel.removePropertyChangeListener(PropertyValueModel.VALUE, this.catalogListener);
		}

		@Override
		protected String buildValue_() {
			Schema schema = this.getDefaultSchema();
			return (schema == null) ? null : schema.getIdentifier();
		}

		private Schema getDefaultSchema() {
			SchemaContainer sc = this.getSchemaContainer();
			return (sc == null) ? null : sc.getDefaultSchema();
		}

		private SchemaContainer getSchemaContainer() {
			return this.databaseSupportsCatalogs() ? this.getCatalog() : this.getDatabase();
		}

		private boolean databaseSupportsCatalogs() {
			Database db = this.getDatabase();
			return (db != null) && db.supportsCatalogs();
		}

		private Catalog getCatalog() {
			String name = this.defaultCatalogModel.getValue();
			return (name == null) ? null : this.getCatalog(name);
		}

		/**
		 * pre-condition: 'name' is not null
		 */
		private Catalog getCatalog(String name) {
			Database db = this.getDatabase();
			return (db == null) ? null : db.getCatalogForIdentifier(name);
		}

		private Database getDatabase() {
			return this.subject.getDatabase();
		}

	}
	
	
	private static class CombinedDefaultSchemaModel
		extends ListPropertyValueModelAdapter<String>
		implements WritablePropertyValueModel<String>
	{
		private WritablePropertyValueModel<String> defaultSchemaModel;
		
		private PropertyValueModel<Boolean> overrideDefaultSchemaModel;
		
		private PropertyValueModel<String> defaultDefaultSchemaModel;
		
		
		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();
			}
			return this.defaultDefaultSchemaModel.getValue();
		}
		
		
		// ************ WritablePropertyValueModel impl ************************
		
		public void setValue(String value) {
			if (this.overrideDefaultSchemaModel.getValue()) {
				this.defaultSchemaModel.setValue(value);
			}
			propertyChanged();
		}
	}


	private static class SchemaChoicesModel
		extends ConnectionProfileCollectionAspectAdapter<String>
	{
		private final PropertyValueModel<String> defaultCatalogModel;
		private final PropertyChangeListener catalogListener;

		SchemaChoicesModel(PropertyValueModel<String> defaultCatalogModel,
				PropertyValueModel<ConnectionProfile> subjectHolder) {
			super(subjectHolder);
			this.defaultCatalogModel = defaultCatalogModel;
			this.catalogListener = this.buildCatalogListener();
		}

		private PropertyChangeListener buildCatalogListener() {
			return new PropertyChangeListener() {
				public void propertyChanged(PropertyChangeEvent event) {
					collectionChanged();
				}
			};
		}

		@Override
		protected void engageSubject_() {
			// call 'super' last?
			this.defaultCatalogModel.addPropertyChangeListener(PropertyValueModel.VALUE, this.catalogListener);
			super.engageSubject_();
		}

		@Override
		protected void disengageSubject_() {
			super.disengageSubject_();
			this.defaultCatalogModel.removePropertyChangeListener(PropertyValueModel.VALUE, this.catalogListener);
		}

		@Override
		protected Iterator<String> iterator_() {
			SchemaContainer sc = this.getSchemaContainer();
			// use schema *identifiers* since the string ends up being the "default" for various text entries
			return (sc != null) ? sc.sortedSchemaIdentifiers() : EmptyIterator.<String>instance();
		}

		private SchemaContainer getSchemaContainer() {
			return this.databaseSupportsCatalogs() ? this.getCatalog() : this.getDatabase();
		}

		private boolean databaseSupportsCatalogs() {
			Database db = this.getDatabase();
			return (db != null) && db.supportsCatalogs();
		}

		private Catalog getCatalog() {
			String name = this.defaultCatalogModel.getValue();
			return (name == null) ? null : this.getCatalog(name);
		}

		/**
		 * pre-condition: 'name' is not null
		 */
		private Catalog getCatalog(String name) {
			Database db = this.getDatabase();
			return (db == null) ? null : db.getCatalogForIdentifier(name);
		}

		private Database getDatabase() {
			return this.subject.getDatabase();
		}

	}
	
	
	private final class ConnectionGroup
	{
		private Link connectLink;
		
		
		public ConnectionGroup(Composite composite) {
			Group group = new Group(composite, SWT.NONE);
			group.setText(JptUiMessages.JpaFacetWizardPage_connectionLabel);
			group.setLayout(new GridLayout(3, false));
			group.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));

			PlatformUI.getWorkbench().getHelpSystem().setHelp(group, JpaHelpContextIds.PROPERTIES_JAVA_PERSISTENCE_CONNECTION);
			
			Combo connectionCombo = createCombo(group, 3, true);
			
			ComboModelAdapter.adapt(
				JpaProjectPropertiesPage.this.connectionChoicesModel,
				JpaProjectPropertiesPage.this.connectionModel,
				connectionCombo,
				new StringConverter<String>() {
					public String convertToString(String o) {
						return (o == null) ? 
							JptUiMessages.JpaFacetWizardPage_none :
							o;
					}
				});
			
			Link connectionLink = new Link(group, SWT.NONE);
			GridData data = new GridData(GridData.END, GridData.CENTER, false, false);
			data.horizontalSpan = 2;
			connectionLink.setLayoutData(data);
			connectionLink.setText(JptUiMessages.JpaFacetWizardPage_connectionLink);
			connectionLink.addSelectionListener(
				new SelectionAdapter() {
					@Override
					public void widgetSelected(SelectionEvent e) {
						openNewConnectionWizard();
					}
				}
			);
			
			connectLink = new Link(group, SWT.NONE);
			data = new GridData(GridData.END, GridData.CENTER, false, false);
			data.horizontalSpan = 2;
			connectLink.setLayoutData(data);
			connectLink.setText(JptUiMessages.JpaFacetWizardPage_connectLink);
			updateConnectLink();
			connectLink.addSelectionListener(
				new SelectionAdapter() {
					@Override
					public void widgetSelected(SelectionEvent e) {
						openConnectionProfile();
					}
				});
			
			PropertyChangeListener linkUpdateListener = new PropertyChangeListener() {
					public void propertyChanged(PropertyChangeEvent event) {
						updateConnectLink();
					}
				};
			JpaProjectPropertiesPage.this.connectionModel.addPropertyChangeListener(
					PropertyValueModel.VALUE,
					linkUpdateListener);

			// overrideDefaultCatalog
			Button overrideDefaultCatalogButton = createButton(
					group, 3, 
					JptUiMessages.JpaFacetWizardPage_overrideDefaultCatalogLabel, 
					SWT.CHECK);
			
			BooleanButtonModelAdapter.adapt(
				JpaProjectPropertiesPage.this.overrideDefaultCatalogModel,
				overrideDefaultCatalogButton);
			
			Label defaultCatalogLabel = new Label(group, SWT.LEFT);
			defaultCatalogLabel.setText(JptUiMessages.JpaFacetWizardPage_defaultCatalogLabel);
			GridData gd = new GridData();
			gd.horizontalSpan = 1;
			defaultCatalogLabel.setLayoutData(gd);
			
			Combo defaultCatalogCombo = createCombo(group, 1, true);
			
			ComboModelAdapter.adapt(
				JpaProjectPropertiesPage.this.catalogChoicesModel,
				JpaProjectPropertiesPage.this.combinedDefaultCatalogModel,
				defaultCatalogCombo);
			
			new ControlEnabler(
				JpaProjectPropertiesPage.this.overrideDefaultCatalogModel,
				defaultCatalogLabel, defaultCatalogCombo);
			
			// overrideDefaultSchema
			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);
			gd = new GridData();
			gd.horizontalSpan = 1;
			defaultSchemaLabel.setLayoutData(gd);
			
			Combo defaultSchemaCombo = createCombo(group, 1, true);
			
			ComboModelAdapter.adapt(
				JpaProjectPropertiesPage.this.schemaChoicesModel,
				JpaProjectPropertiesPage.this.combinedDefaultSchemaModel,
				defaultSchemaCombo);
			
			new ControlEnabler(
				JpaProjectPropertiesPage.this.overrideDefaultSchemaModel,
				defaultSchemaLabel, defaultSchemaCombo);
		}
		
		private void openNewConnectionWizard() {
			String connectionName = DTPUiTools.createNewConnectionProfile();
			if (connectionName != null) {
				JpaProjectPropertiesPage.this.connectionModel.setValue(connectionName);
			}
		}
		
		private void openConnectionProfile() {
			ConnectionProfile cp = JpaProjectPropertiesPage.this.getConnectionProfile();
			if (cp != null) {
				cp.connect();
			}
			updateConnectLink();
		}
		
		private void updateConnectLink() {
			if (! getControl().isDisposed()) {
				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
	{
		public PersistentClassManagementGroup(Composite composite) {
			Group group = new Group(composite, SWT.NONE);
			group.setText(JptUiMessages.JpaFacetWizardPage_persistentClassManagementLabel);
			group.setLayout(new GridLayout());
			group.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
			PlatformUI.getWorkbench().getHelpSystem().setHelp(group, JpaHelpContextIds.NEW_JPA_PROJECT_CONTENT_PAGE_CLASSPATH);

			Button discoverClassesButton = createButton(group, 1, JptUiMessages.JpaFacetWizardPage_discoverClassesButton, SWT.RADIO);
			
			BooleanButtonModelAdapter.adapt(
				JpaProjectPropertiesPage.this.discoverAnnotatedClassesModel, 
				discoverClassesButton);
			
			Button listClassesButton = createButton(group, 1, JptUiMessages.JpaFacetWizardPage_listClassesButton, SWT.RADIO);
			
			BooleanButtonModelAdapter.adapt(
				JpaProjectPropertiesPage.this.listAnnotatedClassesModel,
				listClassesButton);
		}
	}
}
