// NewModifierPage.java
package org.eclipse.stem.ui.wizards;

/*******************************************************************************
 * Copyright (c) 2008 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/

import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.List;

import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.EcorePackage;
import org.eclipse.emf.edit.provider.ComposedAdapterFactory;
import org.eclipse.emf.edit.provider.IItemPropertyDescriptor;
import org.eclipse.emf.edit.provider.IItemPropertySource;
import org.eclipse.stem.core.common.CommonPackage;
import org.eclipse.stem.core.common.Identifiable;
import org.eclipse.stem.core.graph.GraphPackage;
import org.eclipse.stem.core.graph.LabelValue;
import org.eclipse.stem.core.modifier.FeatureModifier;
import org.eclipse.stem.core.modifier.NOPModifier;
import org.eclipse.stem.core.modifier.RangeModifier;
import org.eclipse.stem.core.modifier.SequenceModifier;
import org.eclipse.stem.core.modifier.SingleValueModifier;
import org.eclipse.stem.ui.adapters.featuremodifier.EStructuralFeatureFeatureModifierAdapterFactory;
import org.eclipse.stem.ui.adapters.featuremodifiereditcomposite.FeatureModifierEditCompositeAdapter;
import org.eclipse.stem.ui.adapters.featuremodifiereditcomposite.FeatureModifierFeatureModifierEditCompositeAdapterFactory;
import org.eclipse.stem.ui.adapters.propertystrings.PropertyStringProvider;
import org.eclipse.stem.ui.adapters.propertystrings.PropertyStringProviderAdapter;
import org.eclipse.stem.ui.adapters.propertystrings.PropertyStringProviderAdapterFactory;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.ScrolledComposite;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.FormAttachment;
import org.eclipse.swt.layout.FormData;
import org.eclipse.swt.layout.FormLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.layout.RowLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.ui.PlatformUI;

/**
 * This class is a {@link NewIdentifiablePage} that is customized to contain a
 * list of the {@link EStructuralFeature}s of an {@link Identifiable} that can
 * be modified by a {@link FeatureModifier}. It is extended for each type of
 * {@link Identifiable} which can be modified. Instances of subclasses of this
 * class are created by an composable adapter factory. This approach allows new
 * types of {@link Identifiable}s to be added to the system and have the
 * {@link NewModifierWizard} be able to handle them, complete with NLS
 * translations, etc.
 */
abstract public class NewModifierPage extends NewIdentifiablePage {

	/**
	 * This is the {@link Identifiable} for which the page is creating a
	 * {@link org.eclipse.stem.core.modifier.Modifier}.
	 */
	protected EObject target;

	private final List<FeatureModifierComposite> featureModifierComposites = new ArrayList<FeatureModifierComposite>();

	/**
	 * Constructor
	 * 
	 * @param identifiable
	 *            the {@link Identifiable} for which the page is creating a
	 *            {@link org.eclipse.stem.core.modifier.Modifier}.
	 */
	protected NewModifierPage(final EObject target) {
		super(Messages.getString("NModifierWiz.page_title"));
		setTitle(Messages.getString("NModifierWiz.page_title")); //$NON-NLS-1$
		setDescription(Messages.getString("NModifierWiz.page_description")); //$NON-NLS-1$
		this.target = target;
	} // NewModifierPage

	/**
	 * @see org.eclipse.stem.ui.wizards.NewIdentifiableWizard.NewIdentifiablePage#createSpecificComposite(org.eclipse.swt.widgets.Composite)
	 */
	@Override
	protected Composite createSpecificComposite(final Composite parent) {
		
		  //Display display = parent.getDisplay();
	      //Color blue = display.getSystemColor(SWT.COLOR_BLUE);
	      
	      final Composite outerComposite = new Composite(parent,SWT.BORDER);
	      outerComposite.setLayout(new FillLayout());
	      
	      // set the minimum width and height of the scrolled content - method 2
	      final ScrolledComposite scrolledComposite = new ScrolledComposite(outerComposite, SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER);
	      scrolledComposite.setExpandHorizontal(true);
	      scrolledComposite.setExpandVertical(true);
	      final Composite innerComposite = new Composite(scrolledComposite, SWT.NONE);
	      scrolledComposite.setContent(innerComposite);
	      //innerComposite.setBackground(blue);
	      GridLayout layout = new GridLayout();
	      layout.numColumns = 2;
	      innerComposite.setLayout(layout);
	      
	      scrolledComposite.setMinSize(innerComposite.computeSize(SWT.DEFAULT, SWT.DEFAULT));
	      innerComposite.setSize(innerComposite.computeSize(SWT.DEFAULT, SWT.DEFAULT));
          innerComposite.layout();
          Point innerSize = innerComposite.computeSize(SWT.DEFAULT, SWT.DEFAULT);
          scrolledComposite.setSize(innerSize);
    	  outerComposite.setSize(innerSize);
    	  innerComposite.layout();
          outerComposite.layout();
          parent.layout();
 /* Not needed with Chris fix to the wizards
          Label testLabel = new Label(innerComposite, SWT.BORDER);
          testLabel.setText("press to scroll");
	      Button add = new Button (innerComposite, SWT.PUSH);
	      add.setText("force scroll");
	      final int[] index = new int[]{0};
	      add.addListener(SWT.Selection, new Listener() {
	          public void handleEvent(@SuppressWarnings("unused") Event e) {
	              index[0]++;
	              Label emptyLabel = new Label(innerComposite, SWT.NONE);
	              emptyLabel.setText("bottom");
	              // reset size of content so children can be seen - method 1
	              innerComposite.setSize(innerComposite.computeSize(SWT.DEFAULT, SWT.DEFAULT));
	              innerComposite.layout();
	              
	              // reset the minimum width and height so children can be seen - method 2
	              Point innerSize = innerComposite.computeSize(SWT.DEFAULT, SWT.DEFAULT);
	              innerSize.y*=3;
	              innerSize.y/=2;
	              scrolledComposite.setMinSize(innerSize);
	              	
	          }
	      });
*/
          
		// Get the adapter that will provide NLS'd names for the
		// properties of the Identifiable
		final PropertyStringProviderAdapter pspa = (PropertyStringProviderAdapter) PropertyStringProviderAdapterFactory.INSTANCE
				.adapt(target, PropertyStringProvider.class);

		final ComposedAdapterFactory itemProviderFactory = new ComposedAdapterFactory(
				ComposedAdapterFactory.Descriptor.Registry.INSTANCE);

		final IItemPropertySource propertySource = (IItemPropertySource) itemProviderFactory
				.adapt(target, IItemPropertySource.class);
		final List<IItemPropertyDescriptor> properties = propertySource
				.getPropertyDescriptors(target);

		for (final IItemPropertyDescriptor descriptor : properties) {
			final EStructuralFeature feature = (EStructuralFeature) descriptor
					.getFeature(null);
			// Is this a property that the user specifies?
			if (isUserSpecifiedProperty(feature)) {
				// Yes
				// Label for the name of the property
				final Label label = new Label(innerComposite, SWT.NONE);
				label.setText(pspa.getPropertyName(descriptor));
				// label.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_CYAN));
				GridData gridData1 = new GridData(GridData.BEGINNING);
				gridData1.horizontalAlignment = SWT.BEGINNING;
				gridData1.horizontalIndent = 0;
				label.setLayoutData(gridData1);

				// Composite for the editor
				final FeatureModifierComposite featureModifierComposite = new FeatureModifierComposite(
						innerComposite, target, feature, pspa, descriptor,
						isModifiableProperty(feature), this);
				GridData gridData2 = new GridData(GridData.BEGINNING);
				gridData2.grabExcessHorizontalSpace = true;
				gridData2.horizontalAlignment = SWT.FILL;
				gridData2.horizontalIndent = 0;
				featureModifierComposite.setLayoutData(gridData2);

				featureModifierComposites.add(featureModifierComposite);

			} // if user specified
		} // for each property

		// Any text for the bottom?
		final String bottomText = getBottomText();
		if (bottomText != null) {
			// Yes
			final Label bottomTextLabel = new Label(innerComposite, SWT.NONE);
			bottomTextLabel.setText(bottomText);
			final GridData bottomTextGD = new GridData(GridData.END);
			bottomTextGD.grabExcessHorizontalSpace = true;
			bottomTextGD.horizontalSpan = 2;
			bottomTextLabel.setLayoutData(bottomTextGD);
		} // if
	
		
		// reset the minimum width and height so children can be seen - method 2
		// TODO why does the following not make the scrollbar show up at the start ??
        innerSize = innerComposite.computeSize(SWT.DEFAULT, SWT.DEFAULT);
        innerComposite.setSize(innerSize);
        innerComposite.layout();
       // scrolledComposite.setSize(innerSize);
       // innerSize.y*=3;
       // innerSize.y/=2;
        scrolledComposite.setMinSize(innerSize);
        	            
       
		PlatformUI.getWorkbench().getHelpSystem().setHelp(parent, "org.eclipse.stem.doc.newmodifier_contextid");

		return outerComposite;
	} // createSpecificComposite

	/**
	 * @see org.eclipse.stem.ui.wizards.NewIdentifiableWizard.NewIdentifiablePage#getDCDescription()
	 */
	@Override
	protected String getDCDescription() {
		return MessageFormat.format(Messages
				.getString("NModifierWiz.DC_DESCRIPTION"),
				new Object[] { serializationFileNameField.getText() });
	} // getDCDescription

	/**
	 * @param feature
	 *            a {@link EStructuralFeature} of an {@link Identifiable}.
	 * @return <code>true</code> if the {@link EStructuralFeature} represents
	 *         a property that is specified by a user, <code>false</code>
	 *         otherwise.
	 */
	protected boolean isUserSpecifiedProperty(final EStructuralFeature feature) {
		boolean retValue = !feature.getEContainingClass().equals(
				CommonPackage.Literals.DUBLIN_CORE);
		retValue = retValue && !(feature instanceof EReference);
		return retValue;
	} // isUserSpecifiedProperty

	/**
	 * @return a line of text to appear below the properties, or
	 *         <code>null</code> if no text is to appear.
	 */
	protected String getBottomText() {
		return null;
	}

	/**
	 * @param feature
	 *            the {@link EStructuralFeature} to test for modifiability
	 * @return <code>true</code> (Default) if the feature represents a property
	 *         that the user should be able to modify for an
	 *         {@link org.eclipse.stem.core.experiment.Experiment} or a
	 *         {@link org.eclipse.stem.core.trigger.Trigger}.
	 */
	protected boolean isModifiableProperty(final EStructuralFeature feature) {
		boolean retValue = false;
		retValue |= (feature.getEType().equals(EcorePackage.Literals.EINT));
		retValue |= (feature.getEType().equals(EcorePackage.Literals.ELONG));
		retValue |= (feature.getEType().equals(EcorePackage.Literals.EDOUBLE));
		return retValue;
	} // isModifiableProperty

	/**
	 * @return the {@link FeatureModifier}s on the page that the user has
	 *         specified.
	 */
	public final List<FeatureModifier> getFeatureModifiers() {
		final List<FeatureModifier> retValue = new ArrayList<FeatureModifier>();
		for (final FeatureModifierComposite featureModifierComposite : featureModifierComposites) {
			final FeatureModifier featureModifier = featureModifierComposite
					.getFeatureModifier();
			// Is this FeatureModifier something other than a NOP?
			if (!(featureModifier instanceof NOPModifier)) {
				// Yes
				featureModifier.setTarget(target);
				retValue.add(featureModifier);
			} // if
		} // for each FeatureModifierComposite
		return retValue;
	} // getFeatureModifiers

	/**
	 * see org.eclipse.stem.ui.wizards.NewIdentifiablePage#validatePage()
	 */
	@Override
	public boolean validatePage() {
		return super.validatePage();
	} // validatePage

	/**
	 * This class is a {@link Composite} that displays the details of a
	 * {@link FeatureModifier}.
	 */
	protected static class FeatureModifierComposite extends Composite {

		/**
		 * This is a place holder for the current
		 * {@link FeatureModifierEditComposite} to which a reference is
		 * maintained by {@link #editComposite}. When the user selects one of
		 * the radio buttons ({@link #noneButton}, {@link #rangeButton}, or
		 * {@link #sequenceButton}) the child of this {@link Composite} is
		 * changed by {@link #setEditComposite(Composite)}.
		 */
		final Composite editCompositeHolder;

		/**
		 * This is the current {@link FeatureModifierEditComposite} being
		 * displayed to the user and is the child of
		 * {@link #editCompositeHolder}.
		 */
		private FeatureModifierEditComposite editComposite;

		/**
		 * This is the {@link FeatureModifier}, if it exists, created by the
		 * user for the {@link EStructuralFeature} referenced by
		 * {@link #feature}.
		 */
		FeatureModifier featureModifier = null;

		/**
		 * These buttons are grouped together as "radio buttons" and allow the
		 * user to specify which type of {@link FeatureModifier} to create.
		 * Initially, {@link #noneButton} is selected and the
		 * {@link FeatureModifierEditComposite} returned by
		 * {@link #createDefaultEditComposite(Composite, NewModifierPage, Identifiable, EStructuralFeature)}
		 * is displayed, which simply shows the current value of the feature.
		 */
		Button noneButton = null;
		Button singleButton = null;
		Button rangeButton = null;
		Button sequenceButton = null;

		/**
		 * @param parent
		 *            the parent {@link Composite}
		 * @param target
		 *            the {@link EObject} that contains the
		 *            {@link EStructuralFeature}
		 * @param feature
		 *            the feature to be modified
		 * @param psp
		 *            the provider of NLS'd strings to label the properties of
		 *            the {@link Identifiable}
		 * @param descriptor
		 * @param modifiable
		 *            if <code>true</code> then the {@link EStructuralFeature}
		 *            can be modified.
		 * @param parentNewModifierPage
		 *            the {@link NewModifierPage} that contains the parent
		 *            {@link Composite}.
		 */
		public FeatureModifierComposite(final Composite parent,
				final EObject target,
				final EStructuralFeature feature,
				final PropertyStringProvider psp,
				final IItemPropertyDescriptor descriptor,
				final boolean modifiable,
				final NewModifierPage parentNewModifierPage) {
			super(parent, SWT.NONE);
			final FormLayout layout = new FormLayout();
			layout.spacing = 2;
			setLayout(layout);

			// Edit Composite Holder
			editCompositeHolder = new Composite(this, SWT.NONE);
			final FillLayout fillLayout = new FillLayout();
			fillLayout.marginHeight = 0;
			fillLayout.marginWidth = 0;
			editCompositeHolder.setLayout(fillLayout);
			editCompositeHolder.setToolTipText(psp
					.getPropertyToolTip(descriptor));

			// Units Label
			final Label unitLabel = new Label(this, SWT.NONE);
			unitLabel.setText(psp.getPropertyUnits(descriptor));
			
			// Radio button group
			final Group group = new Group(this, SWT.SHADOW_ETCHED_IN);
			group.setText("Select Modifier Type");
			group.setLayout(new RowLayout(SWT.HORIZONTAL));
			group.setEnabled(modifiable);
			noneButton = new Button(group, SWT.RADIO);
			noneButton.setText("None");
			noneButton.setEnabled(modifiable);


			// range button
			singleButton = new Button(group, SWT.RADIO);
			singleButton.setText(Messages.getString("Single.type"));
			singleButton.setEnabled(modifiable);
			
			// range button
			rangeButton = new Button(group, SWT.RADIO);
			rangeButton.setText(Messages.getString("Range.type"));
			rangeButton.setEnabled(modifiable);
			
			// sequence button
			sequenceButton = new Button(group, SWT.RADIO);
			sequenceButton.setText(Messages.getString("Sequence.type"));
			sequenceButton.setEnabled(modifiable);

			final int offset = 10;

			// The left of the editCompositeHolder is attached to the left of
			// the parent composite
			FormData formData = new FormData();
			formData.left = new FormAttachment(0, 0);
			formData.top = new FormAttachment(0, offset);
			editCompositeHolder.setLayoutData(formData);

			// left->holder.right
			// right->group
			formData = new FormData();
			formData.left = new FormAttachment(editCompositeHolder, 0,
					SWT.RIGHT);
			formData.right = new FormAttachment(group, 0, SWT.LEFT);
			formData.bottom = new FormAttachment(editCompositeHolder, -3,
					SWT.BOTTOM);
			unitLabel.setLayoutData(formData);

			// The right of the radio button composite is attached to the right
			// of the parent composite.
			formData = new FormData();
			formData.right = new FormAttachment(100, 0);
			group.setLayoutData(formData);

			// This call takes the feature and adapts it to a modifier that does
			// nothing. When we call setFeatureModifier that modifier is adapted
			// to a FeatureModifierEditComposite (and assigned to
			// editComposite). That composite doesn't allow editing, but,
			// instead, displays a "default" representation of the feature's
			// value. For a String, it would just display the value of the
			// String, for a number it just displays a string representing the
			// value of the number
			setFeatureModifier(EStructuralFeatureFeatureModifierAdapterFactory.INSTANCE
					.adapt(feature, NOPModifier.class));
			switchToFeatureModifier(target, parentNewModifierPage);

			noneButton.addSelectionListener(new SelectionAdapter() {
				@Override
				public void widgetSelected(
						@SuppressWarnings("unused") final SelectionEvent e) {
					// Put up the default?
					if (noneButton.getSelection()
							&& !(featureModifier instanceof NOPModifier)) {
						// Yes
						final FeatureModifier fm = EStructuralFeatureFeatureModifierAdapterFactory.INSTANCE
						.adapt(feature, NOPModifier.class);
						fm.setTarget(feature);
						setFeatureModifier(fm);
						switchToFeatureModifier(target,
								parentNewModifierPage);
					} // if
				}
			});
			
			singleButton.addSelectionListener(new SelectionAdapter() {
				@Override
				public void widgetSelected(
						@SuppressWarnings("unused") final SelectionEvent e) {
					// Put up the single value modifier?
					if (singleButton.getSelection()
							&& !(featureModifier instanceof SingleValueModifier)) {
						// Yes
						setFeatureModifier(EStructuralFeatureFeatureModifierAdapterFactory.INSTANCE
								.adapt(feature, SingleValueModifier.class));
						switchToFeatureModifier(target,
								parentNewModifierPage);
						// selectRangeButton();
					} // if
				}
			});
			
			rangeButton.addSelectionListener(new SelectionAdapter() {
				@Override
				public void widgetSelected(
						@SuppressWarnings("unused") final SelectionEvent e) {
					// Put up the range modifier?
					if (rangeButton.getSelection()
							&& !(featureModifier instanceof RangeModifier)) {
						// Yes
						setFeatureModifier(EStructuralFeatureFeatureModifierAdapterFactory.INSTANCE
								.adapt(feature, RangeModifier.class));
						switchToFeatureModifier(target,
								parentNewModifierPage);
						// selectRangeButton();
					} // if
				}
			});
			sequenceButton.addSelectionListener(new SelectionAdapter() {
				@Override
				public void widgetSelected(
						@SuppressWarnings("unused") final SelectionEvent e) {
					// Put up the sequence modifier?
					if (sequenceButton.getSelection()
							&& !(featureModifier instanceof SequenceModifier)) {
						// Yes
						setFeatureModifier(EStructuralFeatureFeatureModifierAdapterFactory.INSTANCE
								.adapt(feature, SequenceModifier.class));
						switchToFeatureModifier(target,
								parentNewModifierPage);
						// selectSequenceButton();
					} // if
				}
			});
			
			// The Feature Modifier Composite must have 
			// fixed size to put these in a scroll pane
			setSize(500,150);

		} // FeatureModifierComposite

		void selectNoneButton() {
			noneButton.setSelection(true);
			singleButton.setSelection(false);
			rangeButton.setSelection(false);
			sequenceButton.setSelection(false);
		} // selectNoneButton

		FeatureModifierEditComposite createDefaultEditComposite(
				final Composite parent,
				final NewModifierPage parentNewModifierPage,
				final Identifiable identifiable,
				final EStructuralFeature feature) {
			final FeatureModifierEditComposite retValue = new FeatureModifierEditComposite(
					parent, parentNewModifierPage, null) {
				@Override
				protected boolean validate() {
					return true;
				}
			};
			retValue.setLayout(new GridLayout());
			final Label label = new Label(retValue, SWT.BORDER | SWT.TRAIL);
			label.setText(identifiable.eGet(feature).toString());
			final GridData gridData = new GridData();
			gridData.horizontalAlignment = SWT.END;
			label.setLayoutData(gridData);
			return retValue;
		} // createDefaultEditComposite

		void switchToFeatureModifier(final EObject target,
				final NewModifierPage parentNewModifierPage) {
			// The target of the featureModifier needs to be adjusted here. It
			// would typically be identifiable, but if identifiable is an
			// instance of a Label then the
			// features of the value of the current value feature of the
			// identifiable have been included as features. The problem is that
			// when that happens the target of the FeatureModifier needs to be
			// the label value and not the identifiable.
			// A label
			if (target instanceof org.eclipse.stem.core.graph.Label
					&& (target.eClass() != featureModifier
							.getEStructuralFeature().getEContainingClass())) {
				// Yes
				final org.eclipse.stem.core.graph.Label label = (org.eclipse.stem.core.graph.Label) target;
				final LabelValue lv = (LabelValue) label
						.eGet(GraphPackage.Literals.LABEL__CURRENT_VALUE);
				featureModifier.setTarget(lv);
			} // if static label
			else {
				featureModifier.setTarget(target);
			}

			final FeatureModifierEditCompositeAdapter fmecAdapter = (FeatureModifierEditCompositeAdapter) FeatureModifierFeatureModifierEditCompositeAdapterFactory.INSTANCE
					.adapt(featureModifier,
							FeatureModifierEditCompositeAdapter.class);
			fmecAdapter.setTarget(featureModifier);
			setEditComposite(fmecAdapter.createEditComposite(
					editCompositeHolder, target, parentNewModifierPage));
			fmecAdapter.setSelectedButton(noneButton, singleButton, rangeButton,
					sequenceButton);
		} // switchToFeatureModifier

		void setEditComposite(final FeatureModifierEditComposite editComposite) {
			// Get rid of the old one?
			if (this.editComposite != null) {
				// Yes
				this.editComposite.dispose();
			} // if
			this.editComposite = editComposite;
			getShell().pack();
			// getShell().layout();
			getShell().layout(true, true);
		} // setEditComposite

		/**
		 * @return the {@link FeatureModifier}, possibly <code>null</code>
		 */
		public final FeatureModifier getFeatureModifier() {
			return featureModifier;
		}

		/**
		 * @param featureModifier
		 *            the {@link FeatureModifier} to set
		 */
		protected final void setFeatureModifier(
				final FeatureModifier featureModifier) {
			this.featureModifier = featureModifier;
		}
	} // FeatureModifierComposite

	/**
	 * This class is a {@link Composite} that allows a user to specify the
	 * details of a {@link FeatureModifier}.
	 */
	abstract public static class FeatureModifierEditComposite extends Composite {

		/**
		 * This is the {@link FeatureModifier} that this {@link Composite} is
		 * editing.
		 */
		protected FeatureModifier featureModifier = null;

		/**
		 * This is the {@link NewModifierPage} that is the ultimate parent of
		 * the parent {@link Composite}
		 */
		protected NewModifierPage parentNewModifierPage;

		protected ModifyListener modifyListener = new ModifyListener() {
			public void modifyText(
					@SuppressWarnings("unused") final ModifyEvent e) {
				parentNewModifierPage.setPageComplete(validate());
			}
		};

		/**
		 * @param parent
		 *            the parent {@link Composite}
		 * @param parentNewModifierPage
		 *            the ultimate parent {@link NewModifierPage} of the parent
		 *            {@link Composite}
		 * @param featureModifier
		 *            the {@link FeatureModifier} being edited.
		 */
		public FeatureModifierEditComposite(final Composite parent,
				final NewModifierPage parentNewModifierPage,
				final FeatureModifier featureModifier) {
			super(parent, SWT.NONE);
			this.parentNewModifierPage = parentNewModifierPage;
			this.featureModifier = featureModifier;
		} // FeatureModifierEditComposite

		/**
		 * @return the {@link FeatureModifier}
		 */
		public final FeatureModifier getFeatureModifier() {
			return featureModifier;
		}

		/**
		 * @return the modifyListener
		 */
		public final ModifyListener getModifyListener() {
			return modifyListener;
		}

		/**
		 * As a side-effect this method sets the error message of the
		 * {@link #parentNewModifierPage} if it returns <code>false</code>.
		 * 
		 * @return <code>true</code> if the
		 *         {@link FeatureModifierEditComposite} is valid.
		 */
		abstract protected boolean validate();

	} // FeatureModifierEditComposite
} // NewModifierPage
