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

import java.util.ArrayList;
import java.util.Collection;
import org.eclipse.core.runtime.Assert;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.fieldassist.FieldDecorationRegistry;
import org.eclipse.jface.viewers.ComboViewer;
import org.eclipse.jface.viewers.IBaseLabelProvider;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.jpt.common.ui.WidgetFactory;
import org.eclipse.jpt.common.ui.internal.Tracing;
import org.eclipse.jpt.common.ui.internal.listeners.SWTPropertyChangeListenerWrapper;
import org.eclipse.jpt.common.ui.internal.swt.ComboModelAdapter;
import org.eclipse.jpt.common.ui.internal.swt.DateTimeModelAdapter;
import org.eclipse.jpt.common.ui.internal.swt.SpinnerModelAdapter;
import org.eclipse.jpt.common.ui.internal.swt.TriStateCheckBoxModelAdapter;
import org.eclipse.jpt.common.ui.internal.util.ControlAligner;
import org.eclipse.jpt.common.ui.internal.util.LabeledButton;
import org.eclipse.jpt.common.ui.internal.util.LabeledControlUpdater;
import org.eclipse.jpt.common.ui.internal.util.SWTUtil;
import org.eclipse.jpt.common.ui.internal.utility.swt.SWTTools;
import org.eclipse.jpt.common.utility.internal.NonNullBooleanTransformer;
import org.eclipse.jpt.common.utility.internal.StringConverter;
import org.eclipse.jpt.common.utility.internal.model.value.CompositeBooleanPropertyValueModel;
import org.eclipse.jpt.common.utility.internal.model.value.SimplePropertyValueModel;
import org.eclipse.jpt.common.utility.internal.model.value.TransformationPropertyValueModel;
import org.eclipse.jpt.common.utility.model.Model;
import org.eclipse.jpt.common.utility.model.event.PropertyChangeEvent;
import org.eclipse.jpt.common.utility.model.listener.PropertyChangeListener;
import org.eclipse.jpt.common.utility.model.value.ListValueModel;
import org.eclipse.jpt.common.utility.model.value.PropertyValueModel;
import org.eclipse.jpt.common.utility.model.value.WritablePropertyValueModel;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.DateTime;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Layout;
import org.eclipse.swt.widgets.List;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Spinner;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.forms.widgets.ExpandableComposite;
import org.eclipse.ui.forms.widgets.FormText;
import org.eclipse.ui.forms.widgets.Hyperlink;
import org.eclipse.ui.forms.widgets.Section;
import org.eclipse.ui.help.IWorkbenchHelpSystem;
import org.eclipse.ui.part.PageBook;

/**
 * The abstract definition of a pane which holds onto a <code>PropertyValueModel</code>
 * that contains the subject of this pane.
 * <p>
 * It also contains convenience methods for building buttons, labels, check
 * boxes, and radio buttons, etc.
 * <p>
 * It is possible to easily listen to any property changes coming from the
 * subject, {@link #addPropertyNames(Collection)} is specify which properties
 * are of interest and {@link #propertyChanged(String)} is used to notify the
 * pane when the property has changed.
 *
 * @see FormPane
 * @see DialogPane
 *
 * @version 2.0
 * @since 2.0
 */
@SuppressWarnings("nls")
public abstract class Pane<T extends Model>
{
	/**
	 * The listener registered with the subject in order to be notified when a
	 * property has changed, the property names are determined by
	 * {@link #propertyNames()}.
	 */
	private PropertyChangeListener aspectChangeListener;

	/**
	 * The container of this composite.
	 */
	private final Composite container;

	/**
	 * The aligner responsible to align the left controls.
	 */
	private ControlAligner leftControlAligner;

	/**
	 * Flag used to stop the circular population of widgets.
	 */
	private boolean populating;

	/**
	 * The aligner responsible to align the left controls.
	 */
	private ControlAligner rightControlAligner;

	/**
	 * This listener is registered with the subject holder in order to
	 * automatically repopulate this pane with the new subject.
	 */
	private PropertyChangeListener subjectChangeListener;

	/**
	 * The subject of this pane.
	 */
	private PropertyValueModel<T> subjectHolder;

	/**
	 * The collection of registered sub-panes will be automatically notified
	 * when listeners need to be engaged or disengaged or when to populate its
	 * widgets.
	 */
	private Collection<Pane<?>> subPanes;

	/**
	 * The factory used to create various common widgets.
	 */
	private WidgetFactory widgetFactory;

	/**
	 * The collection of <code>Control</code>s that are displayed in this pane,
	 * which will have their enablement state updated when
	 * {@link #enableWidgets(boolean)} is called.
	 */
	private ArrayList<Control> managedWidgets;

	/**
	 * The collection of <code>Pane</code>s that are displayed in this pane,
	 * which will have their enablement state updated when
	 * {@link #enableWidgets(boolean)} is called.
	 */
	private ArrayList<Pane<?>> managedSubPanes;

	/**
	 * This enabled model is used to store the pane's base enablement state.
	 * If API is called to set the pane enabled, this model gets updated.  If the pane is thereby
	 * fully enabled (controller enabled model is also in agreement) the pane's widgets are set
	 * enabled.
	 * @see #getCombinedEnabledModel()
	 */
	private final WritablePropertyValueModel<Boolean> baseEnabledModel
			= new SimplePropertyValueModel<Boolean>(Boolean.TRUE);

	/**
	 * This enabled model is used to define the pane's enablement as controlled by other widgets,
	 * tests, etc. (for example a radio button)
	 * If this model is changed, and the pane is thereby fully enabled (base enabled model is also
	 * in agreement) the pane's widgets are set enabled.
	 * @see #getCombinedEnabledModel()
	 */
	private PropertyValueModel<Boolean> controllerEnabledModel;

	/**
	 * The "and" combination of {@link #baseEnabledModel} and {@link #controllerEnabledModel}
	 */
	private PropertyValueModel<Boolean> combinedEnabledModel;

	private PropertyChangeListener combinedEnabledModelListener;

	/**
	 * Creates a new <code>Pane</code>.
	 *
	 * @param parentPane The parent pane of this one
	 * @param parent The parent container
	 *
	 * @category Constructor
	 */
	protected Pane(
			Pane<? extends T> parentPane,
	        Composite parent) {

		this(parentPane, parent, true);
	}

	/**
	 * Creates a new <code>Pane</code>.
	 *
	 * @param parentPane The parent container of this one
	 * @param parent The parent container
	 * @param widgetFactory The factory used to create various widgets
	 * @param automaticallyAlignWidgets <code>true</code> to make the widgets
	 * this pane aligned with the widgets of the given parent pane;
	 * <code>false</code> to not align them
	 *
	 * @category Constructor
	 */
	protected Pane(
			Pane<? extends T> parentPane,
	        Composite parent,
	        boolean automaticallyAlignWidgets) {

		this(
			parentPane,
			parentPane.getSubjectHolder(),
			parent,
			automaticallyAlignWidgets);
	}

	/**
	 * Creates a new <code>Pane</code>.
	 *
	 * @param parentPane The parent container of this one
	 * @param parent The parent container
	 * @param widgetFactory The factory used to create various widgets
	 * @param automaticallyAlignWidgets <code>true</code> to make the widgets
	 * this pane aligned with the widgets of the given parent pane;
	 * <code>false</code> to not align them
	 *
	 * @category Constructor
	 */
	protected Pane(
			Pane<? extends T> parentPane,
	        Composite parent,
	        boolean automaticallyAlignWidgets,
	        boolean parentManagePane) {

		this(
			parentPane,
			parentPane.getSubjectHolder(),
			parent,
			automaticallyAlignWidgets,
			parentManagePane);
	}

	/**
	 * Creates a new <code>Pane</code>.
	 *
	 * @param parentPane The parent container of this one
	 * @param subjectHolder The holder of this pane's subject
	 * @param parent The parent container
	 *
	 * @category Constructor
	 */
	protected Pane(
			Pane<?> parentPane,
	        PropertyValueModel<? extends T> subjectHolder,
	        Composite parent) {

		this(parentPane, subjectHolder, parent, true);
	}

	protected Pane(
			Pane<?> parentPane,
	        PropertyValueModel<? extends T> subjectHolder,
	        Composite parent,
	        PropertyValueModel<Boolean> enabledModel) {

		this(parentPane, subjectHolder, parent, true, enabledModel);
	}

	/**
	 * Creates a new <code>Pane</code>.
	 *
	 * @param parentPane The parent container of this one
	 * @param subjectHolder The holder of this pane's subject
	 * @param parent The parent container
	 * @param widgetFactory The factory used to create various widgets
	 * @param automaticallyAlignWidgets <code>true</code> to make the widgets
	 * this pane aligned with the widgets of the given parent pane;
	 * <code>false</code> to not align them
	 *
	 * @category Constructor
	 */
	protected Pane(
			Pane<?> parentPane,
			PropertyValueModel<? extends T> subjectHolder,
			Composite parent,
			boolean automaticallyAlignWidgets) {

		this(parentPane, subjectHolder, parent, automaticallyAlignWidgets, true);
	}

	protected Pane(
			Pane<?> parentPane,
			PropertyValueModel<? extends T> subjectHolder,
			Composite parent,
			boolean automaticallyAlignWidgets,
			PropertyValueModel<Boolean> enabledModel) {

		this(parentPane, subjectHolder, parent, automaticallyAlignWidgets, true, enabledModel);
	}

	/**
	 * Creates a new <code>Pane</code>.
	 *
	 * @param parentPane The parent container of this one
	 * @param subjectHolder The holder of this pane's subject
	 * @param parent The parent container
	 * @param widgetFactory The factory used to create various widgets
	 * @param automaticallyAlignWidgets <code>true</code> to make the widgets
	 * this pane aligned with the widgets of the given parent pane;
	 * <code>false</code> to not align them
	 * @param parentManagePane <code>true</code> to have the parent pane manage
	 * the enabled state of this pane
	 *
	 * @category Constructor
	 */
	protected Pane(
			Pane<?> parentPane,
			PropertyValueModel<? extends T> subjectHolder,
			Composite parent,
			boolean automaticallyAlignWidgets,
			boolean parentManagePane) {

		this(subjectHolder, parent, parentPane.getWidgetFactory());
		this.initialize(parentPane, automaticallyAlignWidgets, parentManagePane);
	}

	protected Pane(
			Pane<?> parentPane,
			PropertyValueModel<? extends T> subjectHolder,
			Composite parent,
			boolean automaticallyAlignWidgets,
			boolean parentManagePane,
			PropertyValueModel<Boolean> enabledModel) {

		this(subjectHolder, parent, parentPane.getWidgetFactory());
		this.initialize(parentPane, automaticallyAlignWidgets, parentManagePane);
		this.initializeEnabledModel(enabledModel);
	}

	/**
	 * Creates a new <code>Pane</code>.
	 *
	 * @param subjectHolder The holder of this pane's subject
	 * @param parent The parent container
	 * @param widgetFactory The factory used to create various common widgets
	 *
	 * @category Constructor
	 */
	protected Pane(
			PropertyValueModel<? extends T> subjectHolder,
			Composite parent,
			WidgetFactory widgetFactory) {

		super();
		this.initialize(subjectHolder, widgetFactory);
		this.container = this.addContainer(parent);
		this.initializeLayout(this.container);
		this.engageSubjectHolder();
		this.engageListeners(getSubject());
		this.populate();
	}


	// ********** initialization **********

	@SuppressWarnings("unchecked")
	private void initialize(
			PropertyValueModel<? extends T> subjectHolder,
	        WidgetFactory widgetFactory) {

		Assert.isNotNull(subjectHolder, "The subject holder cannot be null");

		this.subjectHolder         = (PropertyValueModel<T>) subjectHolder;
		this.widgetFactory         = widgetFactory;
		this.subPanes              = new ArrayList<Pane<?>>();
		this.managedWidgets        = new ArrayList<Control>();
		this.managedSubPanes       = new ArrayList<Pane<?>>();
		this.leftControlAligner    = new ControlAligner();
		this.rightControlAligner   = new ControlAligner();
		this.subjectChangeListener = this.buildSubjectChangeListener();
		this.aspectChangeListener  = this.buildAspectChangeListener();

		this.initialize();
	}

	protected void initialize() {
		// do nothing by default
	}

	/**
	 * Registers this pane with the parent pane.
	 *
	 * @param parentPane The parent pane
	 * @param automaticallyAlignWidgets <code>true</code> to make the widgets
	 * this pane aligned with the widgets of the given parent pane;
	 * <code>false</code> to not align them
	 * @param parentManagePane <code>true</code> to have the parent pane manage
	 * the enabled state of this pane
	 *
	 * @category Initialization
	 */
	private void initialize(
			Pane<?> parentPane,
			boolean automaticallyAlignWidgets,
	        boolean parentManagePane) {

		// Register this pane with the parent pane, it will call the methods
		// automatically (engageListeners(), disengageListeners(), populate(),
		// dispose(), etc)
		parentPane.registerSubPane(this);

		if (parentManagePane) {
			parentPane.manageSubPane(this);
		}

		// Align the left and right controls with the controls from the parent
		// pane
		if (automaticallyAlignWidgets) {
			parentPane.addAlignLeft(this);
			parentPane.addAlignRight(this);
		}
	}

	private void initializeEnabledModel(PropertyValueModel<Boolean> enabledModel) {
		this.controllerEnabledModel = enabledModel;
		this.combinedEnabledModel =
				CompositeBooleanPropertyValueModel.and(this.baseEnabledModel, this.controllerEnabledModel);
		this.combinedEnabledModelListener = buildCombinedEnabledModelListener();
		this.combinedEnabledModel.addPropertyChangeListener(
				PropertyValueModel.VALUE, this.combinedEnabledModelListener);
		enableWidgets_(getCombinedEnablement());
	}

	private PropertyChangeListener buildCombinedEnabledModelListener() {
		return new SWTPropertyChangeListenerWrapper(buildControllerEnabledModelListener_());
	}

	private PropertyChangeListener buildControllerEnabledModelListener_() {
		return new PropertyChangeListener() {
			@SuppressWarnings("unchecked")
			public void propertyChanged(PropertyChangeEvent e) {
				Pane.this.controllerEnablementChanged();
			}
		};
	}

	/**
	 * Initializes the layout of this pane.
	 *
	 * @param container The parent container
	 *
	 * @category Layout
	 */
	protected abstract void initializeLayout(Composite container);

	private void manageWidget(Control control) {
		if (this.managedWidgets.contains(control)) {
			throw new IllegalStateException();
		}
		this.managedWidgets.add(control);
	}

	private void manageSubPane(Pane<?> subPane) {
		if (this.managedSubPanes.contains(subPane)) {
			throw new IllegalStateException();
		}
		this.managedSubPanes.add(subPane);
	}

	/**
	 * Adds the given pane's widgets (those that were registered with its
	 * left <code>ControlAligner</code>) to this pane's left
	 * <code>ControlAligner</code> so that their width can be adjusted to have
	 * the width of the widest widget.
	 *
	 * @param pane The pane containing the widgets to add
	 *
	 * @category Layout
	 */
	protected final void addAlignLeft(Pane<?> container) {
		this.leftControlAligner.add(container.leftControlAligner);
	}

	/**
	 * Adds the given control to the collection of widgets that have their width
	 * adjust with the width of the widest widget. The left alignment is usually
	 * used for labels.
	 *
	 * @param pane The pane to add
	 *
	 * @category Layout
	 */
	protected final void addAlignLeft(Control control) {
		this.leftControlAligner.add(control);
	}

	/**
	 * Adds the given pane's widgets (those that were registered with its
	 * right <code>ControlAligner</code>) to this pane's right
	 * <code>ControlAligner</code> so that their width can be adjusted to have
	 * the width of the widest widget.
	 *
	 * @param pane The pane containing the widgets to add
	 *
	 * @category Layout
	 */
	protected final void addAlignRight(Pane<?> container) {
		this.rightControlAligner.add(container.rightControlAligner);
	}

	/**
	 * Adds the given control to the collection of widgets that have their width
	 * adjust with the width of the widest widget. The left alignment is usually
	 * used for buttons.
	 *
	 * @param pane The pane to add
	 *
	 * @category Layout
	 */
	protected final void addAlignRight(Control control) {
		this.rightControlAligner.add(control);
	}

	/**
	 * Adds the given pane's controls (those that were registered for
	 * alignment) from this pane.
	 *
	 * @param pane The pane containing the widgets to add for
	 * alignment
	 *
	 * @category Layout
	 */
	protected final void addPaneForAlignment(Pane<?> container) {
		addAlignLeft(container);
		addAlignRight(container);
	}

	/**
	 * Adds any property names to the given collection in order to be notified
	 * when the actual property changes in the subject.
	 *
	 * @param propertyNames The collection of property names to register with the
	 * subject
	 */
	protected void addPropertyNames(Collection<String> propertyNames) {
	}

	private PropertyChangeListener buildAspectChangeListener() {
		return new SWTPropertyChangeListenerWrapper(buildAspectChangeListener_());
	}

	private PropertyChangeListener buildAspectChangeListener_() {
		return new PropertyChangeListener() {
			public void propertyChanged(PropertyChangeEvent e) {
				//subject() could have changed or is null because of the possibility of
				//"jumping" on the UI thread here and a selection change occuring
				if (e.getSource() == getSubject()) {
					updatePane(e.getPropertyName());
				}
			}
		};
	}

	/**
	 * Creates a new button using the given information.
	 *
	 * @param parent The parent container
	 * @param buttonText The button's text
	 * @param buttonAction The action to be invoked when the button is pressed
	 * @return The newly created <code>Button</code>
	 *
	 * @category Layout
	 */
	protected final Button addButton(Composite container,
	                                   String text,
	                                   final Runnable buttonAction) {

		return this.addButton(container, text, null, buttonAction);
	}

	/**
	 * Creates a new unmanaged <code>Button</code> widget.  Unmanaged means
	 * that this Pane will not handle the enabling/disabling of this widget.
	 * The owning object will handle it with its own PaneEnabler or ControlEnabler.
	 *
	 * @param parent The parent container
	 * @param buttonText The button's text
	 * @param buttonAction The action to be invoked when the button is pressed
	 * @return The newly created <code>Button</code>
	 *
	 * @category Layout
	 */
	protected final Button addUnmanagedButton(Composite container,
	                                   String text,
	                                   final Runnable buttonAction) {

		return this.addUnmanagedButton(container, text, null, buttonAction);
	}

	/**
	 * Creates a new button using the given information.
	 *
	 * @param parent The parent container
	 * @param buttonText The button's text
	 * @param helpId The topic help ID to be registered for the new check box
	 * @param buttonAction The action to be invoked when the button is pressed
	 * @return The newly created <code>Button</code>
	 *
	 * @category Layout
	 */
	protected final Button addButton(Composite container,
	                                   String text,
	                                   String helpId,
	                                   final Runnable buttonAction) {

		Button button = addUnmanagedButton(container, text, helpId, buttonAction);
		this.manageWidget(button);

		return button;
	}

	/**
	 * Creates a new unmanaged <code>Button</code> widget.  Unmanaged means
	 * that this Pane will not handle the enabling/disabling of this widget.
	 * The owning object will handle it with its own PaneEnabler or ControlEnabler.
	 *
	 * @param parent The parent container
	 * @param buttonText The button's text
	 * @param helpId The topic help ID to be registered for the new check box
	 * @param buttonAction The action to be invoked when the button is pressed
	 * @return The newly created <code>Button</code>
	 *
	 * @category Layout
	 */
	private Button addUnmanagedButton(Composite container,
	                                   String text,
	                                   String helpId,
	                                   final Runnable buttonAction) {

		Button button = this.widgetFactory.createButton(container, text);
		button.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				SWTUtil.asyncExec(buttonAction);
			}
		});

		if (helpId != null) {
			getHelpSystem().setHelp(button, helpId);
		}

		GridData gridData = new GridData();
		gridData.grabExcessHorizontalSpace = false;
		gridData.horizontalAlignment       = GridData.FILL;
		button.setLayoutData(gridData);

		return button;
	}

	/**
	 * This layout will leave space for decorations on widgets.
	 * Whether decorated or not, all of the widgets need the same indent
 	 * so that they align properly.
	 */
	protected GridData getFieldGridData() {
		int margin = FieldDecorationRegistry.getDefault()
				.getMaximumDecorationWidth();
		GridData data = new GridData();
		data.horizontalAlignment = SWT.FILL;
		data.widthHint = IDialogConstants.ENTRY_FIELD_WIDTH + margin;
		data.horizontalIndent = margin;
		data.grabExcessHorizontalSpace = true;
		return data;
	}

	/**
	 * Creates a new check box using the given information.
	 *
	 * @param parent The parent container
	 * @param buttonText The button's text
	 * @param booleanHolder The holder of the selection state
	 * @param helpId The topic help ID to be registered for the new check box
	 * @return The newly created <code>Button</code>
	 *
	 * @category Layout
	 */
	protected final Button addCheckBox(
			Composite parent,
	        String buttonText,
	        WritablePropertyValueModel<Boolean> booleanHolder,
	        String helpId) {

		return this.addToggleButton(
			parent,
			buttonText,
			booleanHolder,
			helpId,
			SWT.CHECK);
	}

	protected final Button addCheckBox(
			Composite parent,
			String buttonText,
			WritablePropertyValueModel<Boolean> booleanHolder,
			String helpId,
			PropertyValueModel<Boolean> enabledModel) {

		Button button = this.addUnmanagedToggleButton(parent, buttonText, booleanHolder, helpId, SWT.CHECK);
		this.controlEnabledState(enabledModel, button);
		return button;
	}

	/**
	 * Creates a new <code>Section</code> that can be collapsed. A sub-pane is
	 * automatically added as its client and is the returned <code>Composite</code>.
	 *
	 * @param container The container of the new widget
	 * @param sectionText The text of the new section
	 * @return The <code>Section</code>'s sub-pane
	 *
	 * @category Layout
	 */
	protected final Composite addCollapsibleSection(
			Composite container,
	        String sectionText) {

		return this.addCollapsibleSection(
				container,
				sectionText,
				new SimplePropertyValueModel<Boolean>(Boolean.FALSE));
	}

	/**
	 * Creates a new <code>Section</code> that can be collapsed. A sub-pane is
	 * automatically added as its client and is the returned <code>Composite</code>.
	 *
	 * @param container The container of the new widget
	 * @param sectionText The text of the new section
	 * @param description The section's description or <code>null</code> if none
	 * @return The <code>Section</code>'s sub-pane
	 *
	 * @category Layout
	 */
	protected final Composite addCollapsibleSection(Composite container,
	                                                  String sectionText,
	                                                  String description) {

		return this.addCollapsibleSection(
			container,
			sectionText,
			description,
			new SimplePropertyValueModel<Boolean>(Boolean.FALSE)
		);
	}

	/**
	 * Creates a new <code>Section</code>. A sub-pane is automatically added as
	 * its client and is the returned <code>Composite</code>.
	 *
	 * @param container The container of the new widget
	 * @param sectionText The text of the new section
	 * @param type The type of section to create
	 * @param expandedStateHolder The holder of the boolean that will dictate
	 * when to expand or collapse the section
	 * @return The <code>Section</code>'s sub-pane
	 *
	 * @category Layout
	 */
	private Composite addCollapsibleSection(Composite container,
	                                          String sectionText,
	                                          int type,
	                                          PropertyValueModel<Boolean> expandedStateHolder) {

		return addCollapsibleSection(container, sectionText, null, type, expandedStateHolder);
	}

	/**
	 * Creates a new <code>Section</code>. A sub-pane is automatically added as
	 * its client and is the returned <code>Composite</code>.
	 *
	 * @param container The container of the new widget
	 * @param sectionText The text of the new section
	 * @param description The section's description or <code>null</code> if none
	 * was provided
	 * @param type The type of section to create
	 * @param expandedStateHolder The holder of the boolean that will dictate
	 * when to expand or collapse the section
	 * @return The <code>Section</code>'s sub-pane
	 *
	 * @category Layout
	 */
	private Composite addCollapsibleSection(Composite container,
	                                          String sectionText,
	                                          String description,
	                                          int type,
	                                          PropertyValueModel<Boolean> expandedStateHolder) {

		Composite subPane = this.addSection(
			container,
			sectionText,
			description,
			ExpandableComposite.TWISTIE | type
		);

		Section section = (Section) subPane.getParent();

		expandedStateHolder.addPropertyChangeListener(
			PropertyValueModel.VALUE,
			buildExpandedStateChangeListener(section)
		);

		section.setExpanded(
			expandedStateHolder.getValue() != null ? expandedStateHolder.getValue() : true
		);

		return subPane;
	}

	/**
	 * Creates a new <code>Section</code>. A sub-pane is automatically added as
	 * its client and is the returned <code>Composite</code>.
	 *
	 * @param container The container of the new widget
	 * @param sectionText The text of the new section
	 * @param expandedStateHolder The holder of the boolean that will dictate
	 * when to expand or collapse the section
	 * @return The <code>Section</code>'s sub-pane
	 *
	 * @category Layout
	 */
	protected final Composite addCollapsibleSection(Composite container,
	                                                  String sectionText,
	                                                  PropertyValueModel<Boolean> expandedStateHolder) {

		return this.addCollapsibleSection(
			container,
			sectionText,
			ExpandableComposite.TITLE_BAR | ExpandableComposite.TWISTIE,
			expandedStateHolder
		);
	}

	/**
	 * Creates a new <code>Section</code>. A sub-pane is automatically added as
	 * its client and is the returned <code>Composite</code>.
	 *
	 * @param container The container of the new widget
	 * @param sectionText The text of the new section
	 * @param description The section's description or <code>null</code> if none
	 * @param expandedStateHolder The holder of the boolean that will dictate
	 * when to expand or collapse the section
	 * @return The <code>Section</code>'s sub-pane
	 *
	 * @category Layout
	 */
	protected final Composite addCollapsibleSection(Composite container,
	                                                  String sectionText,
	                                                  String description,
	                                                  PropertyValueModel<Boolean> expandedStateHolder) {

		return this.addCollapsibleSection(
			container,
			sectionText,
			description,
			ExpandableComposite.TITLE_BAR | ExpandableComposite.TWISTIE,
			expandedStateHolder
		);
	}

	/**
	 * Creates a new <code>Section</code>. A sub-pane is automatically added as
	 * its client which can be typed cast directly as a <code>Composite</code>.
	 *
	 * @param container The container of the new widget
	 * @param sectionText The text of the new section
	 * @param expandedStateHolder The holder of the boolean that will dictate
	 * when to expand or collapse the section
	 * @return The <code>Section</code>'s sub-pane
	 *
	 * @category Layout
	 */
	protected final Composite addCollapsibleSubSection(Composite container,
	                                          String sectionText,
	                                          PropertyValueModel<Boolean> expandedStateHolder) {

		return this.addCollapsibleSection(
			container,
			sectionText,
			SWT.NULL,
			expandedStateHolder
		);
	}

	/**
	 * Creates a new non-editable <code>Combo</code>.
	 *
	 * @param container The parent container
	 * @return The newly created <code>Combo</code>
	 *
	 * @category Layout
	 */
	protected final Combo addCombo(Composite container) {
		Combo combo = this.addUnmanagedCombo(container);
		this.manageWidget(combo);
		return combo;
	}

	/**
	 * Creates a new non-editable <code>Combo</code>.
	 *
	 * @param container The parent container
	 * @return The newly created <code>Combo</code>
	 *
	 * @category Layout
	 */
	private Combo addUnmanagedCombo(Composite container) {
		Combo combo = this.widgetFactory.createCombo(container);
		combo.setLayoutData(getFieldGridData());
		return combo;
	}

	/**
	 * Creates a new non-editable <code>Combo</code>.
	 *
	 * @param container The parent container
	 * @param listHolder The <code>ListValueHolder</code>
	 * @param selectedItemHolder The holder of the selected item
	 * @param stringConverter The converter responsible to transform each item
	 * into a string representation
	 * @return The newly created <code>Combo</code>
	 *
	 * @category Layout
	 */
	protected final <V> Combo addCombo(Composite container,
	                                     ListValueModel<V> listHolder,
	                                     WritablePropertyValueModel<V> selectedItemHolder,
	                                     StringConverter<V> stringConverter) {

		Combo combo = this.addCombo(container);

		ComboModelAdapter.adapt(
			listHolder,
			selectedItemHolder,
			combo,
			stringConverter
		);

		return combo;
	}

	/**
	 * Creates a new non-editable <code>Combo</code>.
	 *
	 * @param container The parent container
	 * @param listHolder The <code>ListValueHolder</code>
	 * @param selectedItemHolder The holder of the selected item
	 * @param stringConverter The converter responsible to transform each item
	 * into a string representation
	 * @return The newly created <code>Combo</code>
	 *
	 * @category Layout
	 */
	private <V> Combo addUnmanagedCombo(Composite container,
	                                     ListValueModel<V> listHolder,
	                                     WritablePropertyValueModel<V> selectedItemHolder,
	                                     StringConverter<V> stringConverter) {

		Combo combo = this.addUnmanagedCombo(container);

		ComboModelAdapter.adapt(
			listHolder,
			selectedItemHolder,
			combo,
			stringConverter
		);

		return combo;
	}

	protected final <V> Combo addCombo(
			Composite container,
			ListValueModel<V> listHolder,
			WritablePropertyValueModel<V> selectedItemHolder,
			StringConverter<V> stringConverter,
			PropertyValueModel<Boolean> enabledModel) {

		Combo combo = this.addUnmanagedCombo(container, listHolder, selectedItemHolder, stringConverter);
		this.controlEnabledState(enabledModel, combo);
		return combo;
	}

	/**
	 * Creates a new <code>ComboViewer</code> using a <code>Combo</code>.
	 *
	 * @param container The parent container
	 * @param labelProvider The provider responsible to convert the combo's items
	 * into human readable strings
	 * @return The newly created <code>ComboViewer</code>
	 *
	 * @category Layout
	 */
	protected final ComboViewer addComboViewer(Composite container,
	                                             IBaseLabelProvider labelProvider) {

		Combo combo = this.addCombo(container);
		ComboViewer viewer = new ComboViewer(combo);
		viewer.setLabelProvider(labelProvider);
		return viewer;
	}

	/**
	 * Creates the main container of this pane. The layout and layout data are
	 * automatically set.
	 *
	 * @param parent The parent container
	 * @return The newly created <code>Composite</code> that will holds all the
	 * widgets created by this pane through {@link #initializeLayout(Composite)}
	 *
	 * @category Layout
	 */
	protected Composite addContainer(Composite parent) {
		return this.addSubPane(parent);
	}

	protected final <V> Combo addEditableCombo(
			Composite container,
			ListValueModel<V> listHolder,
			WritablePropertyValueModel<V> selectedItemHolder,
			StringConverter<V> stringConverter,
			PropertyValueModel<Boolean> enabledModel) {

		Combo combo = this.addUnmanagedEditableCombo(container, listHolder, selectedItemHolder, stringConverter);
		this.controlEnabledState(enabledModel, combo);
		return combo;
	}

	protected final Combo addEditableCombo(
			Composite container) {

		Combo combo = this.widgetFactory.createEditableCombo(container);
		combo.setLayoutData(getFieldGridData());
		this.manageWidget(combo);
		return combo;
	}

	/**
	 * Creates a new editable <code>Combo</code>.
	 *
	 * @param container The parent container
	 * @param listHolder The <code>ListValueHolder</code>
	 * @param selectedItemHolder The holder of the selected item
	 * @param stringConverter The converter responsible to transform each item
	 * into a string representation
	 * @return The newly created <code>Combo</code>
	 *
	 * @category Layout
	 */
	protected final <V> Combo addEditableCombo(Composite container,
	                                             ListValueModel<V> listHolder,
	                                             WritablePropertyValueModel<V> selectedItemHolder,
	                                             StringConverter<V> stringConverter) {

		Combo combo = this.addEditableCombo(container);

		ComboModelAdapter.adapt(
			listHolder,
			selectedItemHolder,
			combo,
			stringConverter
		);

		return combo;
	}

	/**
	 * Creates a new editable <code>ComboViewer</code> using a <code>Combo</code>.
	 *
	 * @param container The parent container
	 * @param labelProvider The provider responsible to convert the combo's items
	 * into human readable strings
	 * @return The newly created <code>ComboViewer</code>
	 *
	 * @category Layout
	 */
	protected final ComboViewer addEditableComboViewer(Composite container,
	                                                     IBaseLabelProvider labelProvider) {

		Combo combo = this.addEditableCombo(container);
		ComboViewer viewer = new ComboViewer(combo);
		viewer.setLabelProvider(labelProvider);
		return viewer;
	}

	private PropertyChangeListener buildExpandedStateChangeListener(final Section section) {
		return new SWTPropertyChangeListenerWrapper(buildExpandedStateChangeListener_(section));
	}

	private PropertyChangeListener buildExpandedStateChangeListener_(final Section section) {
		return new PropertyChangeListener() {
			public void propertyChanged(final PropertyChangeEvent e) {
				Boolean value = (Boolean) e.getNewValue();
				if (value == null) {
					value = Boolean.TRUE;
				}
				section.setExpanded(value);
			}
		};
	}

	/**
	 * Creates a new <code>Hyperlink</code> that will invoked the given
	 * <code>Runnable</code> when selected. The given action is always invoked
	 * from the UI thread.
	 *
	 * @param parent The parent container
	 * @param text The hyperlink's text
	 * @param hyperLinkAction The action to be invoked when the link was selected
	 * return The newly created <code>Hyperlink</code>
	 *
	 * @category Layout
	 */
	protected final Hyperlink addHyperlink(Composite parent,
	                                         String text,
	                                         final Runnable hyperLinkAction) {

		Hyperlink link = this.widgetFactory.createHyperlink(parent, text);
		this.manageWidget(link);

		link.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseUp(MouseEvent e) {

				Hyperlink hyperLink = (Hyperlink) e.widget;

				if (hyperLink.isEnabled()) {
					SWTUtil.asyncExec(hyperLinkAction);
				}
			}
		});

		return link;
	}

	/**
	 * Creates a new label using the given information.
	 *
	 * @param parent The parent container
	 * @param labelText The label's text
	 *
	 * @category Layout
	 */
	protected final Label addLabel(Composite container,
	                                 String labelText) {

		Label label = addUnmanagedLabel(container, labelText);
		manageWidget(label);
		return label;
	}

	protected final Label addLabel(
			Composite container,
			String labelText,
			PropertyValueModel<Boolean> enabledModel
	) {
		Label label = this.addUnmanagedLabel(container, labelText);
		this.controlEnabledState(enabledModel, label);
		return label;
	}

	/**
	 * Creates a new unmanaged <code>Label</code> widget.  Unmanaged means
	 * that this Pane will not handle the enabling/disabling of this widget.
	 * The owning object will handle it with its own PaneEnabler or ControlEnabler.
	 *
	 * @param parent The parent container
	 * @param labelText The label's text
	 *
	 * @category Layout
	 */
	private Label addUnmanagedLabel(Composite container,
	                                 String labelText) {

		return this.widgetFactory.createLabel(container, labelText);
	}

	/**
	 * Creates a new container that will have a non-editable combo labeled with
	 * the given text.
	 *
	 * @param container The parent container
	 * @param labelText The text of the label
	 * @param listHolder The <code>ListValueHolder</code>
	 * @param selectedItemHolder The holder of the selected item
	 * @param rightControl The control shown to the right of the main widget
	 * @param helpId The topic help ID to be registered for the given center
	 * composite
	 * @return The container of the label and the given center control
	 *
	 * @category Layout
	 */
	protected final <V> Combo addLabeledCombo(Composite container,
	                                            String labelText,
	                                            ListValueModel<V> listHolder,
	                                            WritablePropertyValueModel<V> selectedItemHolder,
	                                            StringConverter<V> stringConverter,
	                                            Control rightControl,
	                                            String helpId) {

		Combo combo = this.addCombo(
			container,
			listHolder,
			selectedItemHolder,
			stringConverter
		);

		this.addLabeledComposite(
			container,
			labelText,
			(combo.getParent() != container) ? combo.getParent() : combo,
			rightControl,
			helpId
		);

		return combo;
	}

	/**
	 * Creates a new container that will have a non-editable combo labeled with
	 * the given text.
	 *
	 * @param container The parent container
	 * @param labelText The text of the label
	 * @param listHolder The <code>ListValueHolder</code>
	 * @param selectedItemHolder The holder of the selected item
	 * @param helpId The topic help ID to be registered for the given center
	 * composite
	 * @return The container of the label and the given center control
	 *
	 * @category Layout
	 */
	protected final <V> Combo addLabeledCombo(Composite container,
	                                            String labelText,
	                                            ListValueModel<V> listHolder,
	                                            WritablePropertyValueModel<V> selectedItemHolder,
	                                            StringConverter<V> stringConverter,
	                                            String helpId) {

		return this.addLabeledCombo(
			container,
			labelText,
			listHolder,
			selectedItemHolder,
			stringConverter,
			null,
			helpId
		);
	}

	/**
	 * Creates a new container that will have the given center control labeled
	 * with the given label.
	 *
	 * @param container The parent container
	 * @param leftControl The widget shown to the left of the main widget
	 * @param centerControl The main widget
	 * @param rightControl The control shown to the right of the main widget
	 * @param helpId The topic help ID to be registered for the given center
	 * composite
	 * @return The container of the label and the given center control
	 *
	 * @category Layout
	 */
	protected final Composite addLabeledComposite(Composite container,
													Control leftControl,
	                                                Control centerControl,
	                                                Control rightControl,
	                                                String helpId) {

		// Container for the label and main composite
		container = this.addSubPane(container, 3, 0, 0, 0, 0);

		// Left control
		GridData gridData = new GridData();
		gridData.horizontalAlignment       = GridData.BEGINNING;
		gridData.grabExcessHorizontalSpace = false;
		leftControl.setLayoutData(gridData);

		// Re-parent the left control to the new sub pane
		leftControl.setParent(container);
		this.addAlignLeft(leftControl);


		// Re-parent the center control to the new sub pane
		centerControl.setParent(container);

		// Register the help id for the center control
		if (helpId != null) {
			getHelpSystem().setHelp(centerControl, helpId);
		}

		// Right control
		if (rightControl == null) {
			Composite spacer = this.addPane(container);
			spacer.setLayout(this.buildSpacerLayout());
			rightControl = spacer;
		}
		else {
			rightControl.setParent(container);

			// Register the help id for the right control
			if (helpId != null) {
				getHelpSystem().setHelp(rightControl, helpId);
			}
		}

		gridData = new GridData();
		gridData.horizontalAlignment       = GridData.FILL_HORIZONTAL;
		gridData.grabExcessHorizontalSpace = false;

		rightControl.setLayoutData(gridData);
		this.addAlignRight(rightControl);

		return container;
	}

	/**
	 * Creates a new container that will have the given center control labeled
	 * with the given label.
	 *
	 * @param container The parent container
	 * @param label The label used to describe the center control
	 * @param centerControl The main widget
	 * @param helpId The topic help ID to be registered for the given center
	 * control
	 * @return The container of the label and the given center control
	 *
	 * @category Layout
	 */
	protected final Composite addLabeledComposite(Composite container,
													Control label,
	                                                Control centerControl,
	                                                String helpId) {

		return this.addLabeledComposite(
			container,
			label,
			centerControl,
			null,
			helpId
		);
	}

	/**
	 * Creates a new container that will have the given center composite labeled
	 * with the given label text.
	 *
	 * @param container The parent container
	 * @param labelText The text to label the main composite
	 * @param centerPane The main widget
	 * @param helpId The topic help ID to be registered for the given center
	 * composite
	 * @return The container of the label and the given center control
	 *
	 * @category Layout
	 */
	protected final Composite addLabeledComposite(Composite container,
	                                                String labelText,
	                                                Pane<?> centerPane,
	                                                String helpId) {

		return this.addLabeledComposite(
			container,
			labelText,
			centerPane.getControl(),
			helpId
		);
	}

	/**
	 * Creates a new container that will have the given center composite labeled
	 * with the given label text.
	 *
	 * @param container The parent container
	 * @param labelText The text to label the main composite
	 * @param centerControl The main widget
	 * @return The container of the label and the given center control
	 *
	 * @category Layout
	 */
	protected final Composite addLabeledComposite(Composite container,
	                                                String labelText,
	                                                Control centerControl) {


		return this.addLabeledComposite(
			container,
			labelText,
			centerControl,
			null,
			null
		);
	}

	/**
	 * Creates a new container that will have the given center composite labeled
	 * with the given label text.
	 *
	 * @param container The parent container
	 * @param labelText The text to label the main composite
	 * @param centerControl The main widget
	 * @param rightControl The control shown to the right of the main widget
	 * @param helpId The topic help ID to be registered for the given center
	 * composite
	 * @return The container of the label and the given center control
	 *
	 * @category Layout
	 */
	protected final Composite addLabeledComposite(Composite container,
	                                                String labelText,
	                                                Control centerControl,
	                                                Control rightControl,
	                                                String helpId) {

		return this.addLabeledComposite(
			container,
			this.addLabel(container, labelText),
			centerControl,
			rightControl,
			helpId
		);
	}

	/**
	 * Creates a new container that will have the given center composite labeled
	 * with the given label text.
	 *
	 * @param container The parent container
	 * @param labelText The text to label the main composite
	 * @param centerControl The main widget
	 * @param helpId The topic help ID to be registered for the given center
	 * composite
	 * @return The container of the label and the given center control
	 *
	 * @category Layout
	 */
	protected final Composite addLabeledComposite(Composite container,
	                                                String labelText,
	                                                Control centerControl,
	                                                String helpId) {

		Label label = this.addLabel(container, labelText);

		return this.addLabeledComposite(
			container,
			label,
			centerControl,
			helpId
		);
	}

	/**
	 * Creates a new container that will have the given center control labeled
	 * with the given label.
	 *
	 * @param container The parent container
	 * @param leftControl The widget shown to the left of the main widget
	 * @param centerControl The main widget
	 * @param rightControl The control shown to the right of the main widget
	 * @param helpId The topic help ID to be registered for the given center
	 * composite
	 * @return The newly created <code>CCombo</code>
	 *
	 * @category Layout
	 */
	protected final Combo addLabeledEditableCombo(Composite container,
	                                                  String labelText,
	                                                  ModifyListener comboListener,
	                                                  Control rightControl,
	                                                  String helpId) {

		Combo combo = this.addEditableCombo(container);
		combo.addModifyListener(comboListener);

		this.addLabeledComposite(
			container,
			labelText,
			(combo.getParent() != container) ? combo.getParent() : combo,
			rightControl,
			helpId
		);

		return combo;
	}

	/**
	 * Creates a new container that will have an editable combo labeled with the
	 * given text.
	 *
	 * @param container The parent container
	 * @param labelText The text of the label
	 * @param comboListener The listener that will be notified when the selection
	 * changes
	 * @param helpId The topic help ID to be registered for the given center
	 * composite
	 * @return The newly created <code>CCombo</code>
	 *
	 * @category Layout
	 */
	protected final Combo addLabeledEditableCombo(Composite container,
	                                                  String labelText,
	                                                  ModifyListener comboListener,
	                                                  String helpId) {

		return this.addLabeledEditableCombo(
			container,
			labelText,
			comboListener,
			null,
			helpId
		);
	}

	/**
	 * Creates a new container that will have the given center control labeled
	 * with the given label.
	 *
	 * @param container The parent container
	 * @param leftControl The widget shown to the left of the main widget
	 * @param centerControl The main widget
	 * @param labelProvider The provider responsible to convert the combo's items
	 * into human readable strings
	 * @param rightControl The control shown to the right of the main widget
	 * @param helpId The topic help ID to be registered for the given center
	 * composite
	 * @return The newly created <code>CCombo</code>
	 *
	 * @category Layout
	 */
	protected final Combo addLabeledEditableComboViewer(Composite container,
	                                                        String labelText,
	                                                        ModifyListener comboListener,
	                                                        ILabelProvider labelProvider,
	                                                        Control rightControl,
	                                                        String helpId) {

		ComboViewer comboViewer = this.addEditableComboViewer(
			container,
			labelProvider
		);

		Combo combo = comboViewer.getCombo();
		combo.addModifyListener(comboListener);

		this.addLabeledComposite(
			container,
			labelText,
			(combo.getParent() != container) ? combo.getParent() : combo,
			rightControl,
			helpId
		);

		return combo;
	}

	/**
	 * Creates a new container that will have an editable combo labeled with the
	 * given text.
	 *
	 * @param container The parent container
	 * @param labelText The text of the label
	 * @param comboListener The listener that will be notified when the selection
	 * changes
	 * @param labelProvider The provider responsible to convert the combo's items
	 * into human readable strings
	 * @param helpId The topic help ID to be registered for the given center
	 * composite
	 * @return The newly created <code>CCombo</code>
	 *
	 * @category Layout
	 */
	protected final Combo addLabeledEditableComboViewer(Composite container,
	                                                        String labelText,
	                                                        ModifyListener comboListener,
	                                                        ILabelProvider labelProvider,
	                                                        String helpId) {

		return this.addLabeledEditableComboViewer(
			container,
			labelText,
			comboListener,
			labelProvider,
			null,
			helpId
		);
	}

	/**
	 * Creates a new container that will have an editable combo labeled with the
	 * given text.
	 *
	 * @param container The parent container
	 * @param labelText The text of the label
	 * @param listHolder The <code>ListValueHolder</code>
	 * @param selectedItemHolder The holder of the selected item
	 * @param helpId The topic help ID to be registered for the given center
	 * composite
	 * @return The newly created <code>CCombo</code>
	 *
	 * @category Layout
	 */
	protected final <V> Combo addLabeledEditableCombo(Composite container,
	                                                      String labelText,
	                                                      ListValueModel<V> listHolder,
	                                                      WritablePropertyValueModel<V> selectedItemHolder,
	                                                      String helpId) {

		return this.addLabeledEditableCombo(
			container,
			labelText,
			listHolder,
			selectedItemHolder,
			StringConverter.Default.<V>instance(),
			null,
			helpId
		);
	}

	/**
	 * Creates a new container that will have the given center control labeled
	 * with the given label.
	 *
	 * @param container The parent container
	 * @param labelText The text of the label
	 * @param listHolder The <code>ListValueHolder</code>
	 * @param selectedItemHolder The holder of the selected item
	 * @param stringConverter The converter responsible to transform each item
	 * into a string representation
	 * @param rightControl The control shown to the right of the main widget
	 * @param helpId The topic help ID to be registered for the given center
	 * composite
	 * @return The newly created <code>Combo</code>
	 *
	 * @category Layout
	 */
	protected final <V> Combo addLabeledEditableCombo(Composite container,
	                                                    String labelText,
	                                                    ListValueModel<V> listHolder,
	                                                    WritablePropertyValueModel<V> selectedItemHolder,
	                                                    StringConverter<V> stringConverter,
	                                                    Control rightControl,
	                                                    String helpId) {

		Combo combo = this.addEditableCombo(
			container,
			listHolder,
			selectedItemHolder,
			stringConverter
		);

		this.addLabeledComposite(
			container,
			labelText,
			(combo.getParent() != container) ? combo.getParent() : combo,
			rightControl,
			helpId
		);

		return combo;
	}

	/**
	 * Creates a new container that will have an editable combo labeled with the
	 * given text.
	 *
	 * @param container The parent container
	 * @param labelText The text of the label
	 * @param listHolder The <code>ListValueHolder</code>
	 * @param selectedItemHolder The holder of the selected item
	 * @param stringConverter The converter responsible to transform each item
	 * into a string representation
	 * @param helpId The topic help ID to be registered for the given center
	 * composite
	 * @return The newly created <code>Combo</code>
	 *
	 * @category Layout
	 */
	protected final <V> Combo addLabeledEditableCombo(Composite container,
	                                                    String labelText,
	                                                    ListValueModel<V> listHolder,
	                                                    WritablePropertyValueModel<V> selectedItemHolder,
	                                                    StringConverter<V> stringConverter,
	                                                    String helpId) {

		return this.addLabeledEditableCombo(
			container,
			labelText,
			listHolder,
			selectedItemHolder,
			stringConverter,
			null,
			helpId
		);
	}

	/**
	 * Creates a new container that will have a text field as the center control
	 * labeled with the given label.
	 *
	 * @param container The parent container
	 * @param labelText The text area's label
	 * @param textHolder The holder of the text field's input
	 * @param lineCount The number of lines the text area should display
	 * @param helpId The topic help ID to be registered for the text field
	 * @return The newly created <code>Text</code>
	 *
	 * @category Layout
	 */
	protected final Text addLabeledMultiLineText(Composite container,
	                                               String labelText,
	                                               WritablePropertyValueModel<String> textHolder,
	                                               int lineCount,
	                                               String helpId) {

		Text text = this.addMultiLineText(container, textHolder, lineCount);

		container = this.addLabeledComposite(
			container,
			labelText,
			text,
			helpId
		);

		int textHeight = text.computeSize(SWT.DEFAULT, SWT.DEFAULT).y;

		// Specify the number of lines the text area should display
		GridData gridData = (GridData) text.getLayoutData();
		gridData.heightHint = text.getLineHeight() * lineCount;

		// Move the label to the top of its cell
		Control label = container.getChildren()[0];
		int labelHeight = label.computeSize(SWT.DEFAULT, SWT.DEFAULT).y;

		gridData = (GridData) label.getLayoutData();
		gridData.verticalAlignment = SWT.TOP;
		gridData.verticalIndent   += (Math.abs(textHeight - labelHeight) / 2);

		return text;
	}

	/**
	 * Creates a new container that will have a text field as the center control
	 * labeled with the given label.
	 *
	 * @param container The parent container
	 * @param textHolder The holder of the text field's input
	 * @return The newly created <code>Text</code>
	 *
	 * @category Layout
	 */
	protected final Text addLabeledPasswordText(Composite container,
	                                              String labelText,
	                                              WritablePropertyValueModel<String> textHolder) {

		return this.addLabeledPasswordText(
			container,
			labelText,
			textHolder,
			null
		);
	}

	/**
	 * Creates a new container that will have a text field as the center control
	 * labeled with the given label.
	 *
	 * @param container The parent container
	 * @param labelText The text field's label
	 * @param rightComponent The component to be placed to the right of the text
	 * field
	 * @param textHolder The holder of the text field's input
	 * @param helpId The topic help ID to be registered for the text field
	 * @return The newly created <code>Text</code>
	 *
	 * @category Layout
	 */
	protected final Text addLabeledPasswordText(Composite container,
	                                              String labelText,
	                                              WritablePropertyValueModel<String> textHolder,
	                                              Control rightControl,
	                                              String helpId) {

		Text text = this.addPasswordText(container, textHolder);

		this.addLabeledComposite(
			container,
			labelText,
			text,
			rightControl,
			helpId
		);

		return text;
	}

	/**
	 * Creates a new container that will have a text field as the center control
	 * labeled with the given label.
	 *
	 * @param container The parent container
	 * @param textHolder The holder of the text field's input
	 * @param helpId The topic help ID to be registered for the text field
	 * @return The newly created <code>Text</code>
	 *
	 * @category Layout
	 */
	protected final Text addLabeledPasswordText(Composite container,
	                                              String labelText,
	                                              WritablePropertyValueModel<String> textHolder,
	                                              String helpId) {

		return this.addLabeledPasswordText(
			container,
			labelText,
			textHolder,
			null,
			helpId
		);
	}

	/**
	 * Creates a new spinner.
	 *
	 * @param parent The parent container
	 * @param labelText The label's text
	 * @param numberHolder The holder of the integer value
	 * @param defaultValue The value shown when the holder has <code>null</code>
	 * @param minimumValue The minimum value that the spinner will allow
	 * @param maximumValue The maximum value that the spinner will allow
	 * @param rightControl The widget to be placed to the right of spinner
	 * @param helpId The topic help ID to be registered for the spinner
	 * @return The newly created <code>Spinner</code>
	 *
	 * @category Layout
	 */
	protected final Spinner addLabeledSpinner(Composite parent,
	                                            String labelText,
	                                            WritablePropertyValueModel<Integer> numberHolder,
	                                            int defaultValue,
	                                            int minimumValue,
	                                            int maximumValue,
	                                            Control rightControl,
	                                            String helpId) {

		Spinner spinner = this.addSpinner(
			parent,
			numberHolder,
			defaultValue,
			minimumValue,
			maximumValue,
			helpId
		);
		Label label = addLabel(parent, labelText);
		addLabeledComposite(
			parent,
			label,
			(spinner.getParent() != parent) ? spinner.getParent() : spinner,
			rightControl,
			helpId
		);

		GridData gridData = (GridData) spinner.getLayoutData();
		gridData.horizontalAlignment = GridData.BEGINNING;

		return spinner;
	}

	/**
	 * Creates a new managed spinner. Managed means that this Pane will
	 * handle enabling/disabling of this widget if a PaneEnabler is used.
	 *
	 * @param parent The parent container
	 * @param numberHolder The holder of the integer value
	 * @param defaultValue The value shown when the holder has <code>null</code>
	 * @param minimumValue The minimum value that the spinner will allow
	 * @param maximumValue The maximum value that the spinner will allow
	 * @param helpId The topic help ID to be registered for the new button
	 * @return The newly created <code>Spinner</code>
	 *
	 * @category Layout
	 */
	protected final Spinner addSpinner(Composite parent,
	                                     WritablePropertyValueModel<Integer> numberHolder,
	                                     int defaultValue,
	                                     int minimumValue,
	                                     int maximumValue,
	                                     String helpId) {

		Spinner spinner = addUnmanagedSpinner(parent, numberHolder, defaultValue, minimumValue, maximumValue, helpId);
		this.manageWidget(spinner);
		return spinner;
	}

	/**
	 * Creates a new unmanaged spinner.  Unmanaged means that this Pane will
	 * not handle the enabling/disabling of this widget.  The owning object will handle
	 * it with its own PaneEnabler or ControlEnabler.
	 *
	 * @param parent The parent container
	 * @param numberHolder The holder of the integer value
	 * @param defaultValue The value shown when the holder has <code>null</code>
	 * @param minimumValue The minimum value that the spinner will allow
	 * @param maximumValue The maximum value that the spinner will allow
	 * @param helpId The topic help ID to be registered for the new button
	 * @return The newly created <code>Spinner</code>
	 *
	 * @category Layout
	 */
	private Spinner addUnmanagedSpinner(Composite parent,
	                                     WritablePropertyValueModel<Integer> numberHolder,
	                                     int defaultValue,
	                                     int minimumValue,
	                                     int maximumValue,
	                                     String helpId) {

		Spinner spinner = this.widgetFactory.createSpinner(parent);
		spinner.setMinimum(minimumValue);
		spinner.setMaximum(maximumValue);
		GridData gridData = getFieldGridData();
		gridData.grabExcessHorizontalSpace = false;
		spinner.setLayoutData(gridData);

		SpinnerModelAdapter.adapt(numberHolder, spinner, defaultValue);

		if (helpId != null) {
			getHelpSystem().setHelp(spinner, helpId);
		}

		return spinner;
	}

	/**
	 * Creates a new managed DateTime of type SWT.TIME.  Managed means that this Pane will
	 * handle enabling/disabling of this widget if a PaneEnabler is used.
	 *
	 * @param parent The parent container
	 * @param hoursHolder The holder of the hours integer value
	 * @param minutesHolder The holder of the minutes integer value
	 * @param secondsHolder The holder of the seconds integer value
	 * @param helpId The topic help ID to be registered for the new dateTime
	 * @return The newly created <code>DateTime</code>
	 *
	 * @category Layout
	 */
	protected final DateTime addDateTime(Composite parent,
											WritablePropertyValueModel<Integer> hoursHolder,
											WritablePropertyValueModel<Integer> minutesHolder,
											WritablePropertyValueModel<Integer> secondsHolder,
											String helpId) {

		DateTime dateTime = this.addUnmanagedDateTime(parent, hoursHolder, minutesHolder, secondsHolder, helpId);
		this.manageWidget(dateTime);

		return dateTime;
	}

	protected final DateTime addDateTime(
			Composite parent,
			WritablePropertyValueModel<Integer> hoursHolder,
			WritablePropertyValueModel<Integer> minutesHolder,
			WritablePropertyValueModel<Integer> secondsHolder,
			String helpId,
			PropertyValueModel<Boolean> enabledModel
	) {
		DateTime dateTime = this.addUnmanagedDateTime(parent, hoursHolder, minutesHolder, secondsHolder, helpId);
		this.controlEnabledState(enabledModel, dateTime);
		return dateTime;
	}

	/**
	 * Creates a new unmanaged DateTime of type SWT.TIME.  Unmanaged means that this Pane will
	 * not handle the enabling/disabling of this widget.  The owning object will handle
	 * it with its own PaneEnabler or ControlEnabler.
	 *
	 * @param parent The parent container
	 * @param hoursHolder The holder of the hours integer value
	 * @param minutesHolder The holder of the minutes integer value
	 * @param secondsHolder The holder of the seconds integer value
	 * @param helpId The topic help ID to be registered for the new dateTime
	 * @return The newly created <code>DateTime</code>
	 *
	 * @category Layout
	 */
	private DateTime addUnmanagedDateTime(Composite parent,
											WritablePropertyValueModel<Integer> hoursHolder,
											WritablePropertyValueModel<Integer> minutesHolder,
											WritablePropertyValueModel<Integer> secondsHolder,
											String helpId) {

		DateTime dateTime = this.widgetFactory.createDateTime(parent, SWT.TIME);

		DateTimeModelAdapter.adapt(hoursHolder, minutesHolder, secondsHolder, dateTime);

		if (helpId != null) {
			getHelpSystem().setHelp(dateTime, helpId);
		}

		return dateTime;
	}
	/**
	 * Creates a new editable <code>Combo</code>.
	 *
	 * @param container The parent container
	 * @param listHolder The <code>ListValueHolder</code>
	 * @param selectedItemHolder The holder of the selected item
	 * @param stringConverter The converter responsible to transform each item
	 * into a string representation
	 * @return The newly created <code>CCombo</code>
	 *
	 * @category Layout
	 */
	private <V> Combo addUnmanagedEditableCombo(Composite container,
	                                               ListValueModel<V> listHolder,
	                                               WritablePropertyValueModel<V> selectedItemHolder,
	                                               StringConverter<V> stringConverter) {

		Combo combo = addUnmanagedEditableCombo(container);

		ComboModelAdapter.adapt(
			listHolder,
			selectedItemHolder,
			combo,
			stringConverter
		);

		return combo;
	}


	/**
	 * Creates a new editable <code>Combo</code>.
	 *
	 * @param container The parent container
	 * @return The newly created <code>CCombo</code>
	 *
	 * @category Layout
	 */
	private Combo addUnmanagedEditableCombo(Composite container) {

		Combo combo = this.widgetFactory.createEditableCombo(container);
		combo.setLayoutData(getFieldGridData());
		return combo;
	}

	/**
	 * Creates a new container that will have a text field as the center control
	 * labeled with the given label.
	 *
	 * @param container The parent container
	 * @param textHolder The holder of the text field's input
	 * @return The newly created <code>Text</code>
	 *
	 * @category Layout
	 */
	protected final Text addLabeledText(Composite container,
	                                      String labelText,
	                                      WritablePropertyValueModel<String> textHolder) {

		return this.addLabeledText(container, labelText, textHolder, null);
	}

	/**
	 * Creates a new container that will have a text field as the center control
	 * labeled with the given label.
	 *
	 * @param container The parent container
	 * @param labelText The text field's label
	 * @param rightComponent The component to be placed to the right of the text
	 * field
	 * @param textHolder The holder of the text field's input
	 * @param helpId The topic help ID to be registered for the text field
	 * @return The newly created <code>Text</code>
	 *
	 * @category Layout
	 */
	protected final Text addLabeledText(Composite container,
	                                      String labelText,
	                                      WritablePropertyValueModel<String> textHolder,
	                                      Control rightComponent,
	                                      String helpId) {

		Text text = this.addText(container, textHolder);

		this.addLabeledComposite(
			container,
			labelText,
			text,
			rightComponent,
			helpId
		);

		return text;
	}
	/**
	 *
	 * Creates a new container that will have a text field as the center control
	 * labeled with the given label.
	 *
	 * @param container The parent container
	 * @param labelText The text field's label
	 * @param rightComponent The component to be placed to the right of the text
	 * field
	 * @param textHolder The holder of the text field's input
	 * @param helpId The topic help ID to be registered for the text field
	 * @return The newly created <code>Text</code>
	 *
	 * @category Layout
	 */
	protected final Text addLabeledText(Composite container,
	                                      Label label,
	                                      WritablePropertyValueModel<String> textHolder,
	                                      Control rightComponent,
	                                      String helpId) {

		Text text = this.addText(container, textHolder);

		this.addLabeledComposite(
			container,
			label,
			text,
			rightComponent,
			helpId
		);

		return text;
	}

	/**
	 * Creates a new container that will have a text field as the center control
	 * labeled with the given label.
	 *
	 * @param container The parent container
	 * @param textHolder The holder of the text field's input
	 * @param helpId The topic help ID to be registered for the text field
	 * @return The newly created <code>Text</code>
	 *
	 * @category Layout
	 */
	protected final Text addLabeledText(Composite container,
	                                      String labelText,
	                                      WritablePropertyValueModel<String> textHolder,
	                                      String helpId) {

		return this.addLabeledText(
			container,
			labelText,
			textHolder,
			null,
			helpId
		);
	}

	/**
	 * Creates a new container that will have a text field as the center control
	 * labeled with the given label.
	 *
	 * @param container The parent container
	 * @param textHolder The holder of the text field's input
	 * @param helpId The topic help ID to be registered for the text field
	 * @return The newly created <code>Text</code>
	 *
	 * @category Layout
	 */
	protected final Text addLabeledText(Composite container,
	                                      Label label,
	                                      WritablePropertyValueModel<String> textHolder,
	                                      String helpId) {

		return this.addLabeledText(
			container,
			label,
			textHolder,
			null,
			helpId
		);
	}

	/**
	 * Creates a new list and notify the given selection holder when the
	 * selection changes. If the selection count is different than one than the
	 * holder will receive <code>null</code>.
	 *
	 * @param container The parent container
	 * @param helpId The topic help ID to be registered for the new radio button
	 * @return The newly created <code>List</code>
	 *
	 * @category Layout
	 */
	protected final List addList(Composite container, String helpId) {

		return this.addList(
			container,
			new SimplePropertyValueModel<String>(),
			helpId
		);
	}

	/**
	 * Creates a new list and notify the given selection holder when the
	 * selection changes. If the selection count is different than one than the
	 * holder will receive <code>null</code>.
	 *
	 * @param container The parent container
	 * @param selectionHolder The holder of the unique selected item
	 * @param helpId The topic help ID to be registered for the new radio button
	 * @return The newly created <code>List</code>
	 *
	 * @category Layout
	 */
	protected final List addList(Composite container,
	                               WritablePropertyValueModel<String> selectionHolder,
	                               String helpId) {

		List list = this.addUnmanagedList(container, selectionHolder, helpId);
		this.manageWidget(list);

		return list;
	}

	/**
	 * Creates a new unmanaged list and notify the given selection holder when the
	 * selection changes. If the selection count is different than one than the
	 * holder will receive <code>null</code>.
	 * Unmanaged means that this Pane will not handle the enabling/disabling of this widget.
	 * The owning object will handle it with its own PaneEnabler or ControlEnabler.
	 *
	 * @param container The parent container
	 * @param selectionHolder The holder of the unique selected item
	 * @param helpId The topic help ID to be registered for the new radio button
	 * @return The newly created <code>List</code>
	 *
	 * @category Layout
	 */
	private List addUnmanagedList(Composite container,
	                               WritablePropertyValueModel<String> selectionHolder,
	                               String helpId) {

		List list = this.widgetFactory.createList(
			container,
			SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL | SWT.MULTI
		);

		list.addSelectionListener(buildSelectionListener(selectionHolder));
		list.setLayoutData(new GridData(GridData.FILL_BOTH));

		if (helpId != null) {
			getHelpSystem().setHelp(list, helpId);
		}

		return list;
	}

	/**
	 * Creates a new lable expanding on multiple lines.
	 *
	 * @param parent The parent container
	 * @param labelText The label's text
	 *
	 * @category Layout
	 */
	protected final FormText addMultiLineLabel(Composite container,
	                                         String labelText) {

		FormText label = this.widgetFactory.createMultiLineLabel(container, labelText);
		manageWidget(label);
		return label;
	}

	/**
	 * Creates a new <code>Text</code> widget that has multiple lines.
	 *
	 * @param container The parent container
	 * @return The newly created <code>Text</code> widget
	 *
	 */
	protected final Text addMultiLineText(Composite container) {

		Text text = this.widgetFactory.createMultiLineText(container);
		text.setLayoutData(getFieldGridData());
		this.manageWidget(text);

		return text;
	}

	/**
	 * Creates a new <code>Text</code> widget that has multiple lines.
	 *
	 * @param container The parent container
	 * @param lineCount The number of lines the text area should display
	 * @param helpId The topic help ID to be registered for the new text
	 * @return The newly created <code>Text</code> widget
	 *
	 * @category Layout
	 */
	protected final Text addMultiLineText(Composite container,
	                                      int lineCount,
	                                      String helpId) {

		Text text = this.addMultiLineText(container);
		adjustMultiLineTextLayout(container, lineCount, text, text.getLineHeight());

		if (helpId != null) {
			getHelpSystem().setHelp(text, helpId);
		}

		return text;
	}

	/**
	 * Creates a new <code>Text</code> widget that has multiple lines.
	 *
	 * @param container The parent container
	 * @param textHolder The holder of the text field's input
	 * @param lineCount The number of lines the text area should display
	 * @return The newly created <code>Text</code> widget
	 *
	 * @category Layout
	 */
	protected final Text addMultiLineText(Composite container,
	                                        WritablePropertyValueModel<String> textHolder,
	                                        int lineCount) {

		return this.addMultiLineText(container, textHolder, lineCount, null);
	}

	/**
	 * Creates a new <code>Text</code> widget that has multiple lines.
	 *
	 * @param container The parent container
	 * @param textHolder The holder of the text field's input
	 * @param helpId The topic help ID to be registered for the new text
	 * @return The newly created <code>Text</code> widget
	 *
	 * @category Layout
	 */
	protected final Text addMultiLineText(Composite container,
	                                        WritablePropertyValueModel<String> textHolder,
	                                        int lineCount,
	                                        String helpId) {

		Text text = this.addMultiLineText(container, lineCount, helpId);
		SWTTools.bind(textHolder, text);
		return text;
	}

	/**
	 * Adjusts the layout of the given container so that the text control has the correct amount of
	 * lines by default.
	 */
	protected final void adjustMultiLineTextLayout(Composite container,
	                                               int lineCount,
	                                               Control text,
	                                               int lineHeight) {

		int textHeight = text.computeSize(SWT.DEFAULT, SWT.DEFAULT).y;

		// Specify the number of lines the text area should display
		GridData gridData = (GridData) text.getLayoutData();
		if (gridData == null) {
			gridData = this.getFieldGridData();
			text.setLayoutData(gridData);
		}
		gridData.heightHint = lineHeight * lineCount;

		// Move the label to the top of its cell
		Control label = container.getChildren()[0];
		int labelHeight = label.computeSize(SWT.DEFAULT, SWT.DEFAULT).y;

		gridData = (GridData) label.getLayoutData();
		gridData.verticalAlignment = SWT.TOP;
		gridData.verticalIndent   += (Math.abs(textHeight - labelHeight) / 2);
	}
	/**
	 * Creates a new <code>PageBook</code> and set the proper layout and layout
	 * data.
	 *
	 * @param container The parent container
	 * @return The newly created <code>PageBook</code>
	 *
	 * @category Layout
	 */
	protected final PageBook addPageBook(Composite container) {

		PageBook pageBook = new PageBook(container, SWT.NULL);
		pageBook.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
		return pageBook;
	}

	/**
	 * Creates a new container without specifying any layout manager.
	 *
	 * @param container The parent of the new container
	 * @return The newly created <code>Composite</code>
	 *
	 * @category Layout
	 */
	protected final Composite addPane(Composite parent) {
		return this.widgetFactory.createComposite(parent);
	}

	/**
	 * Creates a new container using the given layout manager.
	 *
	 * @param parent The parent of the new container
	 * @param layout The layout manager of the new container
	 * @return The newly created container
	 *
	 * @category Layout
	 */
	protected final Composite addPane(Composite container, Layout layout) {

		container = this.addPane(container);
		container.setLayout(layout);
		container.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
		return container;
	}

	/**
	 * Creates a new <code>Text</code> widget.
	 *
	 * @param container The parent container
	 * @param textHolder The holder of the text field's input
	 * @return The newly created <code>Text</code> widget
	 *
	 * @category Layout
	 */
	protected final Text addPasswordText(Composite container,
	                                       WritablePropertyValueModel<String> textHolder) {

		Text text = this.addPasswordText(container);
		SWTTools.bind(textHolder, text);

		return text;
	}

	/**
	 * Creates a new <code>Text</code> widget.
	 *
	 * @param container The parent container
	 * @param textHolder The holder of the text field's input
	 * @return The newly created <code>Text</code> widget
	 *
	 * @category Layout
	 */
	protected final Text addPasswordText(Composite container) {

		Text text = this.widgetFactory.createPasswordText(container);
		text.setLayoutData(getFieldGridData());

		this.manageWidget(text);
		return text;
	}

	/**
	 * Creates a new push button using the given information.
	 *
	 * @param parent The parent container
	 * @param buttonText The button's text
	 * @param buttonAction The action to be invoked when the button is pressed
	 * @return The newly created <code>Button</code>
	 *
	 * @category Layout
	 */
	protected final Button addPushButton(Composite parent,
	                                       String buttonText,
	                                       final Runnable buttonAction) {

		return this.addPushButton(parent, buttonText, null, buttonAction);
	}

	/**
	 * Creates a new push button using the given information.
	 *
	 * @param parent The parent container
	 * @param buttonText The button's text
	 * @param buttonAction The action to be invoked when the button is pressed
	 * @param helpId The topic help ID to be registered for the new radio button
	 * @return The newly created <code>Button</code>
	 *
	 * @category Layout
	 */
	protected final Button addPushButton(Composite parent,
	                                       String buttonText,
	                                       String helpId,
	                                       final Runnable buttonAction) {

		Button button = this.widgetFactory.createPushButton(parent, buttonText);
		manageWidget(button);
		button.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				SWTUtil.asyncExec(buttonAction);
			}
		});

		button.setLayoutData(new GridData());

		if (helpId != null) {
			getHelpSystem().setHelp(button, helpId);
		}

		return button;
	}

	/**
	 * Creates a new check box using the given information.
	 *
	 * @param parent The parent container
	 * @param buttonText The button's text
	 * @param booleanHolder The holder of the selection state
	 * @param helpId The topic help ID to be registered for the new radio button
	 * @return The newly created <code>Button</code>
	 *
	 * @category Layout
	 */
	protected final Button addRadioButton(Composite parent,
	                                        String buttonText,
	                                        WritablePropertyValueModel<Boolean> booleanHolder,
	                                        String helpId) {

		return this.addToggleButton(
			parent,
			buttonText,
			booleanHolder,
			helpId,
			SWT.RADIO
		);
	}

	/**
	 * Creates a new <code>Section</code>. A sub-pane is automatically added as
	 * its client and is the returned <code>Composite</code>.
	 *
	 * @param container The container of the new widget
	 * @param sectionText The text of the new section
	 * @return The <code>Section</code>'s sub-pane
	 *
	 * @category Layout
	 */
	protected final Composite addSection(Composite container,
	                                       String sectionText) {

		return this.addSection(
			container,
			sectionText,
			ExpandableComposite.TITLE_BAR
		);
	}

	/**
	 * Creates a new <code>Section</code>. A sub-pane is automatically added as
	 * its client and is the returned <code>Composite</code>.
	 *
	 * @param container The container of the new widget
	 * @param sectionText The text of the new section
	 * @param type The type of section to create
	 * @param expandedStateHolder The holder of the boolean that will dictate
	 * when to expand or collapse the section
	 * @return The <code>Section</code>'s sub-pane
	 *
	 * @category Layout
	 */
	private Composite addSection(Composite container,
	                               String sectionText,
	                               int type) {

		return this.addSection(container, sectionText, null, type);
	}

	/**
	 * Creates a new <code>Section</code>. A sub-pane is automatically added as
	 * its client and is the returned <code>Composite</code>.
	 *
	 * @param container The container of the new widget
	 * @param sectionText The text of the new section
	 * @param description The section's description
	 * @return The <code>Section</code>'s sub-pane
	 *
	 * @category Layout
	 */
	protected final Composite addSection(Composite container,
	                                       String sectionText,
	                                       String description) {

		return this.addSection(
			container,
			sectionText,
			description,
			ExpandableComposite.TITLE_BAR
		);
	}

	/**
	 * Creates a new <code>Section</code>. A sub-pane is automatically added as
	 * its client and is the returned <code>Composite</code>.
	 *
	 * @param container The container of the new widget
	 * @param sectionText The text of the new section
	 * @param description The section's description or <code>null</code> if none
	 * was provider
	 * @param type The type of section to create
	 * @param expandedStateHolder The holder of the boolean that will dictate
	 * when to expand or collapse the section
	 * @return The <code>Section</code>'s sub-pane
	 *
	 * @category Layout
	 */
	private Composite addSection(Composite container,
	                               String sectionText,
	                               String description,
	                               int type) {

		Section section = this.widgetFactory.createSection(container, type | ((description != null) ? Section.DESCRIPTION : SWT.NULL));
		section.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
		section.setText(sectionText);
		section.marginWidth  = 0;
		section.marginHeight = 0;

		if (description != null) {
			section.setDescription(description);
		}

		Composite subPane = this.addSubPane(section);
		section.setClient(subPane);

		return subPane;
	}

	private SelectionListener buildSelectionListener(final WritablePropertyValueModel<String> selectionHolder) {
		return new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				List list = (List) e.widget;
				String[] selectedItems = list.getSelection();
				if ((selectedItems == null) || (selectedItems.length != 1)) {
					selectionHolder.setValue(null);
				}
				else {
					selectionHolder.setValue(selectedItems[0]);
				}
			}
		};
	}

	/**
	 * Creates the layout responsible to compute the size of the spacer created
	 * for the right control when none was given. The spacer helps to align all
	 * the right controls.
	 *
	 * @category Layout
	 */
	private Layout buildSpacerLayout() {
		return new Layout() {
			@Override
			protected Point computeSize(Composite composite,
			                            int widthHint,
			                            int heightHint,
			                            boolean flushCache) {

				return new Point(widthHint, heightHint);
			}

			@Override
			protected void layout(Composite composite, boolean flushCache) {
				GridData data = (GridData) composite.getLayoutData();
				composite.setBounds(0, 0, data.widthHint, data.heightHint);
			}
		};
	}

	private PropertyChangeListener buildSubjectChangeListener() {
		return new SWTPropertyChangeListenerWrapper(this.buildSubjectChangeListener_());
	}

	private PropertyChangeListener buildSubjectChangeListener_() {
		return new PropertyChangeListener() {
			@SuppressWarnings("unchecked")
			public void propertyChanged(PropertyChangeEvent e) {
				Pane.this.subjectChanged((T) e.getOldValue(), (T) e.getNewValue());
			}
		};
	}

	/**
	 * Creates a new <code>Composite</code> used as a sub-pane.
	 *
	 * @param container The parent container
	 * @return The newly created <code>Composite</code> used as a sub-pane
	 *
	 * @category Layout
	 */
	protected final Composite addSubPane(Composite container) {
		return this.addSubPane(container, 0);
	}

	/**
	 * Creates a new <code>Composite</code> used as a sub-pane.
	 *
	 * @param container The parent container
	 * @param topMargin The extra spacing to add at the top of the pane
	 * @return The newly created <code>Composite</code> used as a sub-pane
	 *
	 * @category Layout
	 */
	protected final Composite addSubPane(Composite container, int topMargin) {
		return this.addSubPane(container, topMargin, 0);
	}

	/**
	 * Creates a new <code>Composite</code> used as a sub-pane.
	 *
	 * @param container The parent container
	 * @param topMargin The extra spacing to add at the top of the pane
	 * @param leftMargin The extra spacing to add to the left of the pane
	 * @return The newly created <code>Composite</code> used as a sub-pane
	 *
	 * @category Layout
	 */
	protected final Composite addSubPane(Composite container,
	                                       int topMargin,
	                                       int leftMargin) {

		return this.addSubPane(container, topMargin, leftMargin, 0, 0);
	}

	/**
	 * Creates a new <code>Composite</code> used as a sub-pane, the new widget
	 * will have its layout and layout data already initialized, the layout will
	 * be a <code>GridLayout</code> with 1 column.
	 *
	 * @param container The parent container
	 * @param topMargin The extra spacing to add at the top of the pane
	 * @param leftMargin The extra spacing to add to the left of the pane
	 * @param bottomMargin The extra spacing to add at the bottom of the pane
	 * @param rightMargin The extra spacing to add to the right of the pane
	 * @return The newly created <code>Composite</code> used as a sub-pane
	 *
	 * @category Layout
	 */
	protected final Composite addSubPane(Composite container,
	                                       int topMargin,
	                                       int leftMargin,
	                                       int bottomMargin,
	                                       int rightMargin) {

		return this.addSubPane(
			container,
			1,
			topMargin,
			leftMargin,
			bottomMargin,
			rightMargin);
	}

	/**
	 * Creates a new <code>Composite</code> used as a sub-pane, the new widget
	 * will have its layout and layout data already initialized, the layout will
	 * be a <code>GridLayout</code> with 1 column.
	 *
	 * @param container The parent container
	 * @param topMargin The extra spacing to add at the top of the pane
	 * @param leftMargin The extra spacing to add to the left of the pane
	 * @param bottomMargin The extra spacing to add at the bottom of the pane
	 * @param rightMargin The extra spacing to add to the right of the pane
	 * @return The newly created <code>Composite</code> used as a sub-pane
	 *
	 * @category Layout
	 */
	protected final Composite addSubPane(Composite container,
	                                       int columnCount,
	                                       int topMargin,
	                                       int leftMargin,
	                                       int bottomMargin,
	                                       int rightMargin) {

		GridLayout layout = new GridLayout(columnCount, false);
		layout.marginHeight = 0;
		layout.marginWidth  = 0;
		layout.marginTop    = topMargin;
		layout.marginLeft   = leftMargin;
		layout.marginBottom = bottomMargin;
		layout.marginRight  = rightMargin;

		container = this.addPane(container, layout);

		return container;
	}

	/**
	 * Creates a new <code>Section</code>. A sub-pane is automatically added as
	 * its client which can be typed cast directly as a <code>Composite</code>.
	 *
	 * @param container The container of the new widget
	 * @param sectionText The text of the new section
	 * @return The <code>Section</code>'s sub-pane
	 *
	 * @category Layout
	 */
	protected final Composite addSubSection(Composite container,
	                                          String sectionText) {

		return this.addCollapsibleSubSection(
			container,
			sectionText,
			new SimplePropertyValueModel<Boolean>(Boolean.TRUE)
		);
	}

	/**
	 * Creates a new table.
	 *
	 * @param container The parent container
	 * @param style The style to apply to the table
	 * @param helpId The topic help ID to be registered for the new table or
	 * <code>null</code> if no help ID is required
	 * @return The newly created <code>Table</code>
	 *
	 * @category Layout
	 */
	protected final Table addTable(Composite container,
	                                 int style,
	                                 String helpId) {

		Table table = addUnmanagedTable(container, style, helpId);
		this.manageWidget(table);

		return table;
	}
	/**
	 * Creates a new unmanaged table.  Unmanaged means that this Pane will
	 * not handle the enabling/disabling of this widget.  The owning object will handle
	 * it with its own PaneEnabler or ControlEnabler.
	 *
	 * @param container The parent container
	 * @param style The style to apply to the table
	 * @param helpId The topic help ID to be registered for the new table or
	 * <code>null</code> if no help ID is required
	 * @return The newly created <code>Table</code>
	 *
	 * @category Layout
	 */
	protected final Table addUnmanagedTable(Composite container,
	                                 int style,
	                                 String helpId) {

		Table table = this.widgetFactory.createTable(container, style);
		table.setHeaderVisible(true);
		table.setLinesVisible(true);

		GridData gridData   = new GridData(GridData.FILL_BOTH);
		gridData.heightHint = table.getItemHeight() * 4;
		table.setLayoutData(gridData);

		if (helpId != null) {
			getHelpSystem().setHelp(table, helpId);
		}

		return table;
	}

	/**
	 * Creates a new table.
	 *
	 * @param container The parent container
	 * @param helpId The topic help ID to be registered for the new table or
	 * <code>null</code> if no help ID is required
	 * @return The newly created <code>Table</code>
	 *
	 * @category Layout
	 */
	protected final Table addTable(Composite container, String helpId) {

		return this.addTable(
			container,
			SWT.V_SCROLL | SWT.H_SCROLL | SWT.FULL_SELECTION | SWT.MULTI,
			helpId
		);
	}

	/**
	 * Creates a new unmanaged table.  Unmanaged means that this Pane will
	 * not handle the enabling/disabling of this widget.  The owning object will handle
	 * it with its own PaneEnabler or ControlEnabler.
	 *
	 * @param container The parent container
	 * @param helpId The topic help ID to be registered for the new table or
	 * <code>null</code> if no help ID is required
	 * @return The newly created <code>Table</code>
	 *
	 * @category Layout
	 */
	protected final Table addUnmanagedTable(Composite container, String helpId) {

		return this.addUnmanagedTable(
			container,
			SWT.V_SCROLL | SWT.H_SCROLL | SWT.FULL_SELECTION | SWT.MULTI,
			helpId
		);
	}

	/**
	 * Creates a new managed <code>Text</code> widget.
	 *
	 * @param container The parent container
	 * @return The newly created <code>Text</code> widget
	 *
	 * @category Layout
	 */
	protected final Text addText(Composite container) {
		Text text = this.addUnmanagedText(container);
		this.manageWidget(text);
		return text;
	}

	/**
	 * Creates a new unmanaged <code>Text</code> widget.  Unmanaged means
	 * that this Pane will not handle the enabling/disabling of this widget.
	 * The owning object will handle it with its own PaneEnabler or ControlEnabler.
	 *
	 * @param container The parent container
	 * @return The newly created <code>Text</code> widget
	 *
	 * @category Layout
	 */
	private Text addUnmanagedText(Composite container) {
		Text text = this.widgetFactory.createText(container);
		text.setLayoutData(getFieldGridData());
		return text;
	}

	/**
	 * Creates a new <code>Text</code> widget.
	 *
	 * @param container The parent container
	 * @param helpId The topic help ID to be registered for the new text
	 * @return The newly created <code>Text</code> widget
	 *
	 * @category Layout
	 */
	protected final Text addText(Composite container, String helpId) {

		Text text = this.addText(container);

		if (helpId != null) {
			getHelpSystem().setHelp(text, helpId);
		}

		return text;
	}

	/**
	 * Creates a new unmanaged <code>Text</code> widget.  Unmanaged means
	 * that this Pane will not handle the enabling/disabling of this widget.
	 * The owning object will handle it with its own PaneEnabler or ControlEnabler.
	 *
	 * @param container The parent container
	 * @param helpId The topic help ID to be registered for the new text
	 * @return The newly created <code>Text</code> widget
	 *
	 * @category Layout
	 */
	private Text addUnmanagedText(Composite container, String helpId) {

		Text text = this.addUnmanagedText(container);

		if (helpId != null) {
			getHelpSystem().setHelp(text, helpId);
		}

		return text;
	}

	/**
	 * Creates a new <code>Text</code> widget.
	 *
	 * @param container The parent container
	 * @param textHolder The holder of the text field's input
	 * @return The newly created <code>Text</code> widget
	 *
	 * @category Layout
	 */
	protected final Text addText(Composite container,
	                               WritablePropertyValueModel<String> textHolder) {

		return this.addText(container, textHolder, null);
	}

	/**
	 * Creates a new <code>Text</code> widget.
	 *
	 * @param container The parent container
	 * @param textHolder The holder of the text field's input
	 * @param helpId The topic help ID to be registered for the new text
	 * @return The newly created <code>Text</code> widget
	 *
	 * @category Layout
	 */
	protected final Text addText(Composite container,
	                               WritablePropertyValueModel<String> textHolder,
	                               String helpId) {

		Text text = this.addText(container, helpId);
		SWTTools.bind(textHolder, text);

		return text;
	}

	protected final Text addText(
			Composite container,
			WritablePropertyValueModel<String> textHolder,
			String helpId,
			PropertyValueModel<Boolean> enabledModel
	) {
		Text text = this.addUnmanagedText(container, textHolder, helpId);
		this.controlEnabledState(enabledModel, text);
		return text;
	}

	/**
	 * Creates a new unmanaged <code>Text</code> widget.  Unmanaged means
	 * that this Pane will not handle the enabling/disabling of this widget.
	 * The owning object will handle it with its own PaneEnabler or ControlEnabler.
	 *
	 * @param container The parent container
	 * @param textHolder The holder of the text field's input
	 * @param helpId The topic help ID to be registered for the new text
	 * @return The newly created <code>Text</code> widget
	 *
	 * @category Layout
	 */
	private Text addUnmanagedText(Composite container,
	                               WritablePropertyValueModel<String> textHolder,
	                               String helpId) {

		Text text = this.addUnmanagedText(container, helpId);
		SWTTools.bind(textHolder, text);

		return text;
	}

	/**
	 * Creates a new container with a titled border.
	 *
	 * @param title The text of the titled border
	 * @param container The parent container
	 * @return The newly created <code>Composite</code> with a titled border
	 *
	 * @category Layout
	 */
	protected final Group addTitledGroup(Composite container, String title) {
		return this.addTitledGroup(container, title, null);
	}

	/**
	 * Creates a new container with a titled border.
	 *
	 * @param title The text of the titled border
	 * @param container The parent container
	 * @param helpId The topic help ID to be registered for the new group
	 * @return The newly created <code>Composite</code> with a titled border
	 *
	 * @category Layout
	 */
	protected final Group addTitledGroup(Composite container,
	                                      String title,
	                                      String helpId) {

		return addTitledGroup(container, title, 1, helpId);
	}

	/**
	 * Creates a new container with a titled border.
	 *
	 * @param title The text of the titled border
	 * @param container The parent container
	 * @param helpId The topic help ID to be registered for the new group
	 * @return The newly created <code>Composite</code> with a titled border
	 *
	 * @category Layout
	 */
	protected final Group addTitledGroup(Composite container,
	                                      String title,
	                                      int columnCount,
	                                      String helpId) {

		Group group = this.widgetFactory.createGroup(container, title);
		//manageWidget(group); TODO unsure if I want to manage groups,
		//also should probably rename this addUnmanagedTitledPane
		group.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));

		GridLayout layout = new GridLayout(columnCount, false);
		layout.marginHeight = 0;
		layout.marginWidth  = 0;
		layout.marginTop    = 5;
		layout.marginLeft   = 5;
		layout.marginBottom = 5;
		layout.marginRight  = 5;
		group.setLayout(layout);

		if (helpId != null) {
			getHelpSystem().setHelp(group, helpId);
		}

		return group;
	}

	/**
	 * Creates a new unmanaged new toggle button (radio button or check box).
	 * Unmanaged means  that this Pane will not handle the enabling/disabling
	 * of this widget. The owning object will handle it with its own PaneEnabler
	 * or ControlEnabler.
	 *
	 * @param parent The parent container
	 * @param buttonText The button's text
	 * @param booleanHolder The holder of the selection state
	 * @param helpId The topic help ID to be registered for the new button
	 * @return The newly created <code>Button</code>
	 *
	 * @category Layout
	 */
	private Button addUnmanagedToggleButton(
			Composite parent,
	        String buttonText,
	        WritablePropertyValueModel<Boolean> booleanHolder,
	        String helpId,
	        int toggleButtonType) {

		Button button;

		if (toggleButtonType == SWT.PUSH) {
			button = this.widgetFactory.createPushButton(parent, buttonText);
		}
		else if (toggleButtonType == SWT.RADIO) {
			button = this.widgetFactory.createRadioButton(parent, buttonText);
		}
		else if (toggleButtonType == SWT.CHECK) {
			button = this.widgetFactory.createCheckBox(parent, buttonText);
		}
		else {
			button = this.widgetFactory.createButton(parent, buttonText);
		}

		button.setLayoutData(new GridData());
		SWTTools.bind(booleanHolder, button);

		if (helpId != null) {
			getHelpSystem().setHelp(button, helpId);
		}

		return button;
	}

	/**
	 * Creates a new toggle button (radio button or check box) using the given
	 * information.
	 *
	 * @param parent The parent container
	 * @param buttonText The button's text
	 * @param booleanHolder The holder of the selection state
	 * @param helpId The topic help ID to be registered for the new button
	 * @return The newly created <code>Button</code>
	 *
	 * @category Layout
	 */
	private Button addToggleButton(
			Composite parent,
	        String buttonText,
	        WritablePropertyValueModel<Boolean> booleanHolder,
	        String helpId,
	        int toggleButtonType) {

		Button button = addUnmanagedToggleButton(
				parent,
				buttonText,
				booleanHolder,
				helpId,
				toggleButtonType);
		this.manageWidget(button);
		return button;
	}

	/**
	 * Creates a new check box that can have 3 selection states (selected,
	 * unselected and partially selected.
	 *
	 * @param parent The parent container
	 * @param text The button's text
	 * @param booleanHolder The holder of the boolean value where <code>null</code>
	 * means partially selected
	 * @param helpId The topic help ID to be registered for the new check box
	 * @return The newly created <code>TriStateCheckBox</code>
	 *
	 * @category Layout
	 */
	protected final TriStateCheckBox addTriStateCheckBox(Composite parent,
	                                                       String text,
	                                                       WritablePropertyValueModel<Boolean> booleanHolder,
	                                                       String helpId) {

		TriStateCheckBox checkBox = new TriStateCheckBox(
			parent,
			text,
			this.getWidgetFactory()
		);

		this.manageWidget(checkBox.getCheckBox());

		TriStateCheckBoxModelAdapter.adapt(
			booleanHolder,
			checkBox
		);

		if (helpId != null) {
			getHelpSystem().setHelp(checkBox.getCheckBox(), helpId);
		}

		return checkBox;
	}

	/**
	 * Creates a new check box that can have 3 selection states (selected,
	 * unselected and partially selected.
	 *
	 * @param parent The parent container
	 * @param text The button's text
	 * @param booleanHolder The holder of the boolean value where <code>null</code>
	 * means partially selected
	 * @param stringHolder The holder of the string to put in parenthesis after
	 * the check box's text when it is partially selected
	 * @param helpId The topic help ID to be registered for the new check box
	 * @return The newly created <code>TriStateCheckBox</code>
	 *
	 * @category Layout
	 */
	protected final TriStateCheckBox addTriStateCheckBoxWithDefault(Composite parent,
	                                                                  String text,
	                                                                  WritablePropertyValueModel<Boolean> booleanHolder,
	                                                                  PropertyValueModel<String> stringHolder,
	                                                                  String helpId) {

		TriStateCheckBox checkBox = this.addTriStateCheckBox(
			parent,
			text,
			booleanHolder,
			helpId
		);

		new LabeledControlUpdater(
			new LabeledButton(checkBox.getCheckBox()),
			stringHolder
		);

		return checkBox;
	}

	/**
	 * Requests this pane to populate its widgets with the subject's values.
	 *
	 * @category Populate
	 */
	protected void doPopulate() {
		this.log(Tracing.UI_LAYOUT, "   ->doPopulate()");
	}

	private void controlEnabledState(PropertyValueModel<Boolean> booleanModel, Control... controls) {
		this.controlEnabledState_(this.wrapEnabledModel(booleanModel), controls);
	}

	/**
	 * Assume the "enabled" models can return null (which is typical with aspect
	 * adapters etc.).
	 */
	private PropertyValueModel<Boolean> wrapEnabledModel(PropertyValueModel<Boolean> booleanModel) {
		return new TransformationPropertyValueModel<Boolean, Boolean>(booleanModel, NonNullBooleanTransformer.FALSE);
	}

	private void controlEnabledState_(PropertyValueModel<Boolean> booleanModel, Control... controls) {
		SWTTools.controlEnabledState(this.andEnabledModel(booleanModel), controls);
	}

	private PropertyValueModel<Boolean> getCombinedEnabledModel() {
		return (this.combinedEnabledModel != null) ? this.combinedEnabledModel : this.baseEnabledModel;
	}

	private boolean getCombinedEnablement() {
		Boolean enabled = getCombinedEnabledModel().getValue();
		return (enabled == null) ? true : enabled.booleanValue();
	}

	private PropertyValueModel<Boolean> andEnabledModel(PropertyValueModel<Boolean> booleanModel) {
		return CompositeBooleanPropertyValueModel.and(getCombinedEnabledModel(), booleanModel);
	}

	protected void controllerEnablementChanged() {
		enableWidgets_(getCombinedEnablement());
	}

	/**
	 * Changes the enablement state of the widgets of this pane.
	 *
	 * @param enabled <code>true</code> to enable the widgets or <code>false</code>
	 * to disable them
	 *
	 * @category Layout
	 */
	public void enableWidgets(boolean enabled) {
		this.baseEnabledModel.setValue(Boolean.valueOf(enabled));
		enableWidgets_(getCombinedEnablement());
	}

	private void enableWidgets_(boolean enabled) {
		if (! this.container.isDisposed()) {
			for (Control control : this.managedWidgets) {
				control.setEnabled(enabled);
			}

			for (Pane<?> subPane : this.managedSubPanes) {
				subPane.enableWidgets(enabled);
			}
		}
	}

	private void engageSubjectHolder() {
		this.subjectHolder.addPropertyChangeListener(PropertyValueModel.VALUE, this.subjectChangeListener);
	}

	/**
	 * engage the specified subject
	 */
	protected void engageListeners(T subject) {
		if (subject != null) {
			this.engageListeners_(subject);
		}
	}

	/**
	 * specified subject is not null
	 */
	protected void engageListeners_(T subject) {
		this.log(Tracing.UI_LAYOUT, "   ->engageListeners_(" + subject + ')');

		for (String propertyName : this.getPropertyNames()) {
			subject.addPropertyChangeListener(propertyName, this.aspectChangeListener);
		}
	}

	/**
	 * disengage the specified subject
	 */
	protected void disengageListeners(T subject) {
		if (subject != null) {
			this.disengageListeners_(subject);
		}
	}

	/**
	 * specified subject is not null
	 */
	protected void disengageListeners_(T subject) {
		this.log(Tracing.UI_LAYOUT, "   ->disengageListeners_(" + subject + ')');

		for (String propertyName : this.getPropertyNames()) {
			subject.removePropertyChangeListener(propertyName, this.aspectChangeListener);
		}
	}

	private void disengageSubjectHolder() {
		this.subjectHolder.removePropertyChangeListener(PropertyValueModel.VALUE, this.subjectChangeListener);
	}

	/**
	 * Returns the main <code>Control</code> of this pane.
	 *
	 * @return The main container
	 *
	 * @category Layout
	 */
	public Composite getControl() {
		return this.container;
	}

	/**
	 * Returns the subject holder used by this pane.
	 *
	 * @return The holder of the subject
	 *
	 * @category Populate
	 */
	protected final PropertyValueModel<T> getSubjectHolder() {
		return this.subjectHolder;
	}

	/**
	 * Returns the factory responsible for creating the widgets.
	 *
	 * @return The factory used by this pane to create the widgets
	 *
	 * @category Layout
	 */
	protected final WidgetFactory getWidgetFactory() {
		return this.widgetFactory;
	}

	/**
	 * Returns the margin taken by a group box, which is the number of pixel the
	 * group box border and its margin takes before displaying its widgets plus
	 * 5 pixels since the widgets inside of the group box and the border should
	 * have that extra 5 pixels.
	 *
	 * @return The width taken by the group box border with its margin
	 *
	 * @category Layout
	 */
	protected final int getGroupBoxMargin() {
		Group group = this.widgetFactory.createGroup(SWTUtil.getShell(), "");
		Rectangle clientArea = group.getClientArea();
		group.dispose();
		return clientArea.x + 5;
	}

	/**
	 * Returns the helps system.
	 *
	 * @return The platform's help system
	 *
	 * @category Helper
	 */
	protected final IWorkbenchHelpSystem getHelpSystem() {
		return PlatformUI.getWorkbench().getHelpSystem();
	}


	/**
	 * Determines whether
	 *
	 * @return
	 *
	 * @category Populate
	 */
	protected final boolean isPopulating() {
		return this.populating;
	}

	/**
	 * Logs the given message if the <code>Tracing.DEBUG_LAYOUT</code> is enabled.
	 *
	 * @param flag
	 * @param message The logging message
	 */
	protected void log(String flag, String message) {
		if (flag.equals(Tracing.UI_LAYOUT) && Tracing.booleanDebugOption(Tracing.UI_LAYOUT)) {
			this.log(message);
		}
	}

	protected void log(String message) {
		Class<?> thisClass = this.getClass();
		String className = thisClass.getSimpleName();

		if (thisClass.isAnonymousClass()) {
			className = className.substring(0, className.indexOf('$'));
			className += "->" + thisClass.getSuperclass().getSimpleName();
		}

		Tracing.log(className + ": " + message);
	}

	/**
	 * Notifies this pane to populate itself using the subject's information.
	 *
	 * @category Populate
	 */
	private void populate() {
		if (!this.container.isDisposed()) {
			this.log(Tracing.UI_LAYOUT, "populate()");
			this.repopulate();
		}
	}

	/**
	 * Notifies the subject's property associated with the given property name
	 * has changed.
	 *
	 * @param propertyName The property name associated with the property change
	 *
	 * @category Populate
	 */
	protected void propertyChanged(String propertyName) {
	}

	/**
	 * Returns the list of names to listen for properties changing from the
	 * subject.
	 *
	 * @return A non-<code>null</code> list of property names
	 *
	 * @category Populate
	 */
	protected Collection<String> getPropertyNames() {
		ArrayList<String> propertyNames = new ArrayList<String>();
		addPropertyNames(propertyNames);
		return propertyNames;
	}

	/**
	 * Removes the given pane's widgets (those that were registered with
	 * its left <code>ControlAligner</code>) from this pane's left
	 * <code>ControlAligner</code> so that their width will no longer be adjusted
	 * with the width of the widest widget.
	 *
	 * @param pane The pane containing the widgets to remove
	 *
	 * @category Layout
	 */
	protected final void removeAlignLeft(Pane<?> pane) {
		this.leftControlAligner.remove(pane.leftControlAligner);
	}

	/**
	 * Removes the given control from the collection of widgets that are aligned
	 * to have the same width when they are shown to the left side of the 3
	 * widget colums.
	 *
	 * @param pane The pane to remove, its width will no longer be
	 * ajusted to be the width of the longest widget
	 *
	 * @category Layout
	 */
	protected final void removeAlignLeft(Control control) {
		this.leftControlAligner.remove(control);
	}

	/**
	 * Removes the given pane's widgets (those that were registered with
	 * its right <code>ControlAligner</code>) from this pane's right
	 * <code>ControlAligner</code> so that their width will no longer be adjusted
	 * with the width of the widest widget.
	 *
	 * @param pane The pane containing the widgets to remove
	 *
	 * @category Layout
	 */
	protected final void removeAlignRight(Pane<?> pane) {
		this.rightControlAligner.remove(pane.rightControlAligner);
	}

	/**
	 * Removes the given control from the collection of widgets that are aligned
	 * to have the same width when they are shown to the right side of the 3
	 * widget colums.
	 *
	 * @param pane The pane to remove, its width will no longer be
	 * ajusted to be the width of the longest widget
	 *
	 * @category Layout
	 */
	protected final void removeAlignRight(Control control) {
		this.rightControlAligner.remove(control);
	}

	/**
	 * Removes the given pane's controls (those that were registered for
	 * alignment) from this pane.
	 *
	 * @param pane The pane containing the widgets that no longer
	 * requires their width adjusted with the width of the longest widget
	 *
	 * @category Layout
	 */
	protected final void removePaneForAlignment(Pane<?> pane) {
		removeAlignLeft(pane);
		removeAlignRight(pane);
	}

	/**
	 * This method is called (perhaps internally) when this needs to repopulate
	 * but the object of interest has not changed.
	 *
	 * @category Populate
	 */
	protected final void repopulate() {

		this.log(Tracing.UI_LAYOUT, "   ->repopulate()");

		// Populate this pane
		try {
			setPopulating(true);
			doPopulate();
		}
		finally {
			setPopulating(false);
		}

		// Ask the sub-panes to repopulate themselves
		for (Pane<?> subPane : this.subPanes) {
			subPane.repopulate();
		}
	}

	/**
	 * Sets the internal flag that is used to determine whether the pane is being
	 * populated or not. During population, it is required to not update the
	 * widgets when the model is updated nor to update the model when the widgets
	 * are being synchronized with the model's values.
	 *
	 * @param populating
	 *
	 * @category Populate
	 */
	protected final void setPopulating(boolean populating) {
		this.populating = populating;
	}

	/**
	 * Either show or hides this pane.
	 *
	 * @param visible The new visibility state
	 */
	public void setVisible(boolean visible) {
		if (!this.container.isDisposed()) {
			this.container.setVisible(visible);
		}
	}

	/**
	 * Returns the nearest <code>Shell</code> displaying the main widget of this
	 * pane.
	 *
	 * @return The nearest window displaying this pane
	 */
	public final Shell getShell() {
		return this.container.getShell();
	}

	/**
	 * Returns the subject of this pane.
	 *
	 * @return The subject if this pane was not disposed; <code>null</code>
	 * if it was
	 *
	 * @category Populate
	 */
	public T getSubject() {
		return this.subjectHolder.getValue();
	}

	/**
	 * The subject has changed, disconnects any listeners from the old subject
	 * and connects those listeners onto the new subject.
	 *
	 * @param oldsubject The old subject or <code>null</code> if none was set
	 * @param newSubject The new subject or <code>null</code> if none needs to be
	 * set
	 *
	 * @category Populate
	 */
	protected final void subjectChanged(T oldSubject, T newSubject) {
		if (!this.container.isDisposed()) {

			this.log(Tracing.UI_LAYOUT, "subjectChanged()");
			this.disengageListeners(oldSubject);

			this.repopulate();

			this.engageListeners(newSubject);
		}
	}


	/**
	 * Registers another <code>Pane</code> with this one so it can
	 * be automatically notified about certain events such as engaging or
	 * disengaging the listeners, etc.
	 *
	 * @param subPane The sub-pane to register
	 *
	 * @category Controller
	 */
	protected final void registerSubPane(Pane<?> subPane) {
		this.subPanes.add(subPane);
	}

	/**
	 * Unregisters the given <code>Pane</code> from this one so it
	 * can no longer be automatically notified about certain events such as
	 * engaging or disengaging the listeners, etc.
	 *
	 * @param subPane The sub-pane to unregister
	 *
	 * @category Controller
	 */
	protected final void unregisterSubPane(Pane<?> subPane) {
		this.subPanes.remove(subPane);
	}

	private void updatePane(String propertyName) {
		if (!isPopulating() && !this.container.isDisposed()) {
			this.populating = true;

			try {
				propertyChanged(propertyName);
			}
			finally {
				this.populating = false;
			}
		}
	}

	public void dispose() {
		this.log(Tracing.UI_LAYOUT, "dispose()");

		// Dispose this pane
		this.disengageListeners(getSubject());
		this.disengageSubjectHolder();

		if (this.combinedEnabledModel != null && this.combinedEnabledModelListener != null) {
			this.combinedEnabledModel.removePropertyChangeListener(PropertyValueModel.VALUE, this.combinedEnabledModelListener);
		}

		this.leftControlAligner.dispose();
		this.rightControlAligner.dispose();

		// Ask the sub-panes to dispose themselves
		for (Pane<?> subPane : this.subPanes) {
			subPane.dispose();
		}
	}

}