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

import java.util.ArrayList;
import java.util.Collection;
import org.eclipse.core.runtime.Assert;
import org.eclipse.jface.viewers.ComboViewer;
import org.eclipse.jface.viewers.IBaseLabelProvider;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.jpt.ui.internal.Tracing;
import org.eclipse.jpt.ui.internal.listeners.SWTPropertyChangeListenerWrapper;
import org.eclipse.jpt.ui.internal.swt.BooleanButtonModelAdapter;
import org.eclipse.jpt.ui.internal.swt.TriStateCheckBoxModelAdapter;
import org.eclipse.jpt.ui.internal.util.ControlAligner;
import org.eclipse.jpt.ui.internal.util.LabeledButton;
import org.eclipse.jpt.ui.internal.util.LabeledControlUpdater;
import org.eclipse.jpt.ui.internal.util.SWTUtil;
import org.eclipse.jpt.utility.internal.ClassTools;
import org.eclipse.jpt.utility.internal.model.Model;
import org.eclipse.jpt.utility.internal.model.event.PropertyChangeEvent;
import org.eclipse.jpt.utility.internal.model.listener.PropertyChangeListener;
import org.eclipse.jpt.utility.internal.model.value.PropertyValueModel;
import org.eclipse.jpt.utility.internal.model.value.SimplePropertyValueModel;
import org.eclipse.jpt.utility.internal.model.value.WritablePropertyValueModel;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.CCombo;
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.Display;
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.Text;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.forms.widgets.ExpandableComposite;
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 AbstractFormPane
 * @see AbstractDialogPane
 *
 * @version 2.0
 * @since 2.0
 */
@SuppressWarnings("nls")
public abstract class AbstractPane<T extends Model>
{
	/**
	 * The listener registered with the subject in order to be notified when a
	 * property has changed, the property names are determined by
	 * {@link #propertyNames()}.
	 */
	private PropertyChangeListener aspectChangeListener;

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

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

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

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

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

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

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

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

	/**
	 * Creates a new <code>AbstractSubjectPane</code>.
	 *
	 * @category Constructor
	 */
	@SuppressWarnings("unused")
	private AbstractPane() {
		super();
	}

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

		this(parentPane, parent, true);
	}

	/**
	 * Creates a new <code>AbstractSubjectPane</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 AbstractPane(AbstractPane<? extends T> parentPane,
	                       Composite parent,
	                       boolean automaticallyAlignWidgets) {

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

	/**
	 * Creates a new <code>AbstractSubjectPane</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 AbstractPane(AbstractPane<?> parentPane,
	                       PropertyValueModel<? extends T> subjectHolder,
	                       Composite parent) {

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

	/**
	 * Creates a new <code>AbstractSubjectPane</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 AbstractPane(AbstractPane<?> parentPane,
	                       PropertyValueModel<? extends T> subjectHolder,
	                       Composite parent,
	                       boolean automaticallyAlignWidgets) {

		this(subjectHolder,
		     parent,
		     parentPane.getWidgetFactory());

		initialize(parentPane, automaticallyAlignWidgets);
	}

	/**
	 * Creates a new <code>AbstractSubjectPane</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 AbstractPane(PropertyValueModel<? extends T> subjectHolder,
	                       Composite parent,
	                       WidgetFactory widgetFactory) {

		super();

		this.initialize(subjectHolder, widgetFactory);

		try {
			this.populating = true;

			this.container = this.buildContainer(parent);
			this.initializeLayout(this.container);
		}
		finally {
			this.populating = false;
		}
	}

	/**
	 * 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(AbstractPane<?> 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(AbstractPane<?> 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(AbstractPane<?> 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) {
				updatePane(e.propertyName());
			}
		};
	}

	/**
	 * 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 buildButton(Composite container,
	                                   String text,
	                                   final Runnable buttonAction) {

		return this.buildButton(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 buildButton(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) {
			helpSystem().setHelp(button, helpId);
		}

		return button;
	}

	/**
	 * Creates a new non-editable <code>CCombo</code>.
	 *
	 * @param container The parent container
	 * @return The newly created <code>Combo</code>
	 *
	 * @category Layout
	 */
	protected final CCombo buildCCombo(Composite container) {

		CCombo combo = this.widgetFactory.createCCombo(container);

		GridData gridData = new GridData();
		gridData.horizontalAlignment = GridData.FILL;
		gridData.grabExcessHorizontalSpace = true;
		combo.setLayoutData(gridData);

		return combo;
	}

	/**
	 * Creates a new <code>ComboViewer</code> using a <code>CCombo</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 buildCComboViewer(Composite container,
	                                              IBaseLabelProvider labelProvider) {

		CCombo combo = this.buildCCombo(container);
		ComboViewer viewer = new ComboViewer(combo);
		viewer.setLabelProvider(labelProvider);
		return viewer;
	}

	/**
	 * 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
	 * @return The newly created <code>Button</code>
	 *
	 * @category Layout
	 */
	protected final Button buildCheckBox(Composite parent,
	                                     String buttonText,
	                                     WritablePropertyValueModel<Boolean> booleanHolder) {

		return this.buildCheckBox(parent, buttonText, booleanHolder, null);
	}

	/**
	 * 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 buildCheckBox(Composite parent,
	                                     String buttonText,
	                                     WritablePropertyValueModel<Boolean> booleanHolder,
	                                     String helpId) {

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

	/**
	 * 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 buildCombo(Composite container) {

		Combo combo = this.widgetFactory.createCombo(container);

		GridData gridData = new GridData();
		gridData.horizontalAlignment = GridData.FILL;
		gridData.grabExcessHorizontalSpace = true;
		combo.setLayoutData(gridData);

		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 buildComboViewer(Composite container,
	                                             IBaseLabelProvider labelProvider) {

		Combo combo = this.buildCombo(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)}
	 */
	protected Composite buildContainer(Composite parent) {
		return this.buildSubPane(parent);
	}

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

		CCombo combo = this.widgetFactory.createEditableCCombo(container);

		GridData gridData = new GridData();
		gridData.horizontalAlignment = GridData.FILL;
		gridData.grabExcessHorizontalSpace = true;
		combo.setLayoutData(gridData);

		return combo;
	}

	/**
	 * Creates a new editable <code>ComboViewer</code> using a <code>CCombo</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 buildEditableCComboViewer(Composite container,
	                                                      IBaseLabelProvider labelProvider) {

		CCombo combo = this.buildEditableCCombo(container);
		ComboViewer viewer = new ComboViewer(combo);
		viewer.setLabelProvider(labelProvider);
		return viewer;
	}

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

		Combo combo = this.widgetFactory.createEditableCombo(container);

		GridData gridData = new GridData();
		gridData.horizontalAlignment = GridData.FILL;
		gridData.grabExcessHorizontalSpace = true;
		combo.setLayoutData(gridData);

		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 buildEditableComboViewer(Composite container,
	                                                     IBaseLabelProvider labelProvider) {

		Combo combo = this.buildEditableCombo(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.newValue();
				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>
	 */
	protected final Hyperlink buildHyperLink(Composite parent,
	                                         String text,
	                                         final Runnable hyperLinkAction) {

		Hyperlink link = this.widgetFactory.createHyperlink(parent, text);
		link.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseUp(MouseEvent e) {
				SWTUtil.asyncExec(hyperLinkAction);
			}
		});
		return link;
	}

	/**
	 * Creates a new lable using the given information.
	 *
	 * @param parent The parent container
	 * @param labelText The label's text
	 *
	 * @category Layout
	 */
	protected final Label buildLabel(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 comboListener The listener that will be notified when the selection
	 * changes
	 * @param rightControl The control shown to the right of the main widget
	 * @param helpId The topic help ID to be registered for the given center
	 * compositer
	 * @return The newly created <code>CCombo</code>
	 *
	 * @category Layout
	 */
	protected final CCombo buildLabeledCCombo(Composite container,
	                                          String labelText,
	                                          ModifyListener comboListener,
	                                          Control rightControl,
	                                          String helpId) {

		CCombo combo = this.buildCCombo(container);
		combo.addModifyListener(comboListener);

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

		return combo;
	}

	/**
	 * 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 helpId The topic help ID to be registered for the given center
	 * compositer
	 * @return The newly created <code>CCombo</code>
	 *
	 * @category Layout
	 */
	protected final CCombo buildLabeledCCombo(Composite container,
	                                          String labelText,
	                                          ModifyListener comboListener,
	                                          String helpId) {

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

	/**
	 * 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 comboListener The listener that will be notified when the selection
	 * changes
	 * @param rightControl The control shown to the right of the main widget
	 * @param helpId The topic help ID to be registered for the given center
	 * compositer
	 * @return The container of the label and the given center control
	 *
	 * @category Layout
	 */
	protected final Combo buildLabeledCombo(Composite container,
	                                        String labelText,
	                                        ModifyListener comboListener,
	                                        Control rightControl,
	                                        String helpId) {

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

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

		return combo;
	}

	/**
	 * 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 helpId The topic help ID to be registered for the given center
	 * compositer
	 * @return The container of the label and the given center control
	 *
	 * @category Layout
	 */
	protected final Combo buildLabeledCombo(Composite container,
	                                        String labelText,
	                                        ModifyListener comboListener,
	                                        String helpId) {

		return this.buildLabeledCombo(
			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 rightControl The control shown to the right of the main widget
	 * @param helpId The topic help ID to be registered for the given center
	 * compositer
	 * @return The container of the label and the given center control
	 *
	 * @category Layout
	 */
	protected final Composite buildLabeledComposite(Composite container,
	                                                Control leftControl,
	                                                Control centerControl,
	                                                Control rightControl,
	                                                String helpId) {

		// Container for the label and main composite
		container = this.buildSubPane(container, 3, 5, 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.leftControlAligner.add(leftControl);

		// Center control
		gridData = new GridData();
		gridData.horizontalAlignment       = GridData.FILL;
		gridData.grabExcessHorizontalSpace = true;
		centerControl.setLayoutData(gridData);

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

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

		// Right control
		if (rightControl == null) {
			Composite spacer = this.buildPane(container);
			spacer.setLayout(buildSpacerLayout());
			this.rightControlAligner.add(spacer);
		}
		else {
			gridData = new GridData();
			gridData.horizontalAlignment       = GridData.FILL_HORIZONTAL;
			gridData.grabExcessHorizontalSpace = false;

			rightControl.setLayoutData(gridData);
			rightControl.setParent(container);

			this.rightControlAligner.add(rightControl);

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

		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 buildLabeledComposite(Composite container,
	                                                Control label,
	                                                Control centerControl,
	                                                String helpId) {

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

	/**
	 * 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
	 * @return The container of the label and the given center control
	 *
	 * @category Layout
	 */
	protected final Composite buildLabeledComposite(Composite container,
	                                                Label label,
	                                                Control centerControl) {

		return this.buildLabeledComposite(
			container,
			label,
			centerControl,
			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 centerPane The main widget
	 * @param rightControl The control shown to the right of the main widget
	 * @param helpId The topic help ID to be registered for the given center
	 * compositer
	 * @return The container of the label and the given center control
	 *
	 * @category Layout
	 */
	protected final Composite buildLabeledComposite(Composite container,
	                                                String labelText,
	                                                AbstractPane<?> centerPane,
	                                                Control rightCentrol,
	                                                String helpId) {

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

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

		return this.buildLabeledComposite(
			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 buildLabeledComposite(Composite container,
	                                                String labelText,
	                                                Control centerControl) {


		return this.buildLabeledComposite(
			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
	 * @return The container of the label and the given center control
	 *
	 * @category Layout
	 */
	protected final Composite buildLabeledComposite(Composite container,
	                                                String labelText,
	                                                Control centerControl,
	                                                Control rightControl) {


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

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

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

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

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

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

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

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

		CCombo combo = this.buildEditableCCombo(container);
		combo.addModifyListener(comboListener);

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

		return combo;
	}

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

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

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

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

		CCombo combo = comboViewer.getCCombo();
		combo.addModifyListener(comboListener);

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

		return combo;
	}

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

		return this.buildLabeledEditableCComboViewer(
			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 rightControl The control shown to the right of the main widget
	 * @param helpId The topic help ID to be registered for the given center
	 * compositer
	 * @return The container of the label and the given center control
	 *
	 * @category Layout
	 */
	protected final Combo buildLabeledEditableCombo(Composite container,
	                                                String labelText,
	                                                ModifyListener comboListener,
	                                                Control rightControl,
	                                                String helpId) {

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

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

		return combo;
	}

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

		return this.buildLabeledEditableCombo(
			container,
			labelText,
			comboListener,
			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 textListener The listener that is notified when the text field's
	 * input changes
	 * @return The newly created <code>Text</code>
	 *
	 * @category Layout
	 */
	protected final Text buildLabeledText(Composite container,
	                                      String labelText,
	                                      ModifyListener textListener) {

		Text text = this.buildText(container);
		text.addModifyListener(textListener);

		this.buildLabeledComposite(
			container,
			labelText,
			text
		);

		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 textListener The listener that is notified when the text field's
	 * input changes
	 * @param rightControl The control shown to the right of the main widget
	 * @return The newly created <code>Text</code>
	 *
	 * @category Layout
	 */
	protected final Text buildLabeledText(Composite container,
	                                      String labelText,
	                                      ModifyListener textListener,
	                                      Control rightControl) {

		Text text = this.buildText(container);
		text.addModifyListener(textListener);

		this.buildLabeledComposite(
			container,
			labelText,
			text,
			rightControl
		);

		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 textListener The listener that is notified when the text field's
	 * input changes
	 * @param rightControl The control shown to the right of the main widget
	 * @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 buildLabeledText(Composite container,
	                                      String labelText,
	                                      ModifyListener textListener,
	                                      Control rightControl,
	                                      String helpId) {

		Text text = this.buildText(container);
		text.addModifyListener(textListener);

		this.buildLabeledComposite(
			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 textListener The listener that is notified when the text field's
	 * input changes
	 * @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 buildLabeledText(Composite container,
	                                      String labelText,
	                                      ModifyListener textListener,
	                                      String helpId) {

		Text text = this.buildText(container);
		text.addModifyListener(textListener);

		this.buildLabeledComposite(
			container,
			labelText,
			text,
			helpId
		);

		return text;
	}

	/**
	 * 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
	 * @return The newly created <code>List</code>
	 *
	 * @category Layout
	 */
	protected final List buildList(Composite container) {

		return this.buildList(container, (String) null);
	}

	/**
	 * 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 buildList(Composite container, String helpId) {

		return this.buildList(
			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
	 * @return The newly created <code>List</code>
	 *
	 * @category Layout
	 */
	protected final List buildList(Composite container,
	                               WritablePropertyValueModel<String> selectionHolder) {

		return this.buildList(container, selectionHolder, null);
	}

	/**
	 * 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 buildList(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));

		GridData gridData = new GridData();
		gridData.horizontalAlignment       = GridData.FILL;
		gridData.verticalAlignment         = GridData.FILL;
		gridData.grabExcessHorizontalSpace = true;
		gridData.grabExcessVerticalSpace   = true;
		list.setLayoutData(gridData);

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

		return list;
	}

	/**
	 * 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>
	 */
	protected final PageBook buildPageBook(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 buildPane(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 buildPane(Composite container, Layout layout) {

		container = this.widgetFactory.createComposite(container);
		container.setLayout(layout);

		GridData gridData = new GridData();
		gridData.grabExcessHorizontalSpace = true;
		gridData.horizontalAlignment       = SWT.FILL;
		container.setLayoutData(gridData);

		return container;
	}

	/**
	 * 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 buildPushButton(Composite parent,
	                                       String buttonText,
	                                       final Runnable buttonAction) {

		return this.buildPushButton(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 buildPushButton(Composite parent,
	                                       String buttonText,
	                                       String helpId,
	                                       final Runnable buttonAction) {

		Button button = this.widgetFactory.createPushButton(parent, buttonText);

		button.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				SWTUtil.asyncExec(buttonAction);
			}
		});

		button.setLayoutData(new GridData());

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

		return button;
	}

	/**
	 * Creates a new radio button using the given information.
	 *
	 * @param parent The parent container
	 * @param buttonText The button's text
	 * @param booleanHolder The holder of the selection state
	 * @return The newly created <code>Button</code>
	 *
	 * @category Layout
	 */
	protected final Button buildRadioButton(Composite parent,
	                                        String buttonText,
	                                        WritablePropertyValueModel<Boolean> booleanHolder) {

		return this.buildRadioButton(parent, buttonText, booleanHolder, null);
	}

	/**
	 * 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 buildRadioButton(Composite parent,
	                                        String buttonText,
	                                        WritablePropertyValueModel<Boolean> booleanHolder,
	                                        String helpId) {

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

	/**
	 * Creates a new <code>Section</code> with flat style. 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 buildSection(Composite container,
	                                       String sectionText) {

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

	/**
	 * Creates a new <code>Section</code> with flat style. 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
	 * @return The <code>Section</code>'s sub-pane
	 *
	 * @category Layout
	 */
	private Composite buildSection(Composite container,
	                               String sectionText,
	                               int type) {

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

	/**
	 * Creates a new <code>Section</code> with flat style.  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 buildSection(Composite container,
	                               String sectionText,
	                               int type,
	                               PropertyValueModel<Boolean> expandedStateHolder) {

		Section section = this.widgetFactory.createSection(
			container,
			ExpandableComposite.TWISTIE | type
		);

		section.setText(sectionText);
		section.marginWidth  = 0;
		section.marginHeight = 0;

		GridData gridData = new GridData();
		gridData.horizontalAlignment       = GridData.FILL;
		gridData.grabExcessHorizontalSpace = true;
		section.setLayoutData(gridData);

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

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

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

		return subPane;
	}

	/**
	 * Creates a new <code>Section</code> with flat style. 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 buildSection(Composite container,
	                                       String sectionText,
	                                       PropertyValueModel<Boolean> expandedStateHolder) {

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

	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]);
				}
			}
		};
	}

	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) {
				AbstractPane.this.subjectChanged((T) e.oldValue(), (T) e.newValue());
			}
		};
	}

	/**
	 * 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 buildSubPane(Composite container) {
		return this.buildSubPane(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 buildSubPane(Composite container, int topMargin) {
		return this.buildSubPane(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 buildSubPane(Composite container,
	                                       int topMargin,
	                                       int leftMargin) {

		return this.buildSubPane(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 buildSubPane(Composite container,
	                                       int topMargin,
	                                       int leftMargin,
	                                       int bottomMargin,
	                                       int rightMargin) {

		return this.buildSubPane(
			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 buildSubPane(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.buildPane(container, layout);

		return container;
	}

	/**
	 * Creates a new <code>Section</code> with flat style. 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 buildSubSection(Composite container,
	                                          String sectionText) {

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

	/**
	 * Creates a new <code>Section</code> with flat style. 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 buildSubSection(Composite container,
	                                          String sectionText,
	                                          PropertyValueModel<Boolean> expandedStateHolder) {

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

	/**
	 * Creates a new <code>Text</code> widget, the widget is created with the
	 * flat-style look.
	 *
	 * @param container The parent container
	 * @return The newly created <code>Text</code> widget
	 *
	 * @category Layout
	 */
	protected final Text buildText(Composite container) {
		return this.widgetFactory.createText(container);
	}

	/**
	 * Creates a new <code>Text</code> widget, the widget is created with the
	 * flat-style look.
	 *
	 * @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 buildText(Composite container, String helpId) {
		Text text = this.widgetFactory.createText(container);

		GridData gridData = new GridData();
		gridData.horizontalAlignment       = GridData.FILL;
		gridData.grabExcessHorizontalSpace = true;
		text.setLayoutData(gridData);

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

		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 buildTitledPane(Composite container, String title) {
		return this.buildTitledPane(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 buildTitledPane(Composite container,
	                                      String title,
	                                      String helpId) {

		Group group = this.widgetFactory.createGroup(container, title);

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

		GridData gridData = new GridData();
		gridData.horizontalAlignment       = GridData.FILL;
		gridData.grabExcessHorizontalSpace = true;
		gridData.verticalIndent            = 0;
		group.setLayoutData(gridData);

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

		return group;
	}

	/**
	 * 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 buildToggleButton(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());
		BooleanButtonModelAdapter.adapt(booleanHolder, button);

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

		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
	 * @return The newly created <code>TriStateCheckBox</code>
	 */
	protected final TriStateCheckBox buildTriStateCheckBox(Composite parent,
	                                                       String text,
	                                                       WritablePropertyValueModel<Boolean> booleanHolder) {

		return this.buildTriStateCheckBox(parent, text, booleanHolder, null);
	}

	/**
	 * 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>
	 */
	protected final TriStateCheckBox buildTriStateCheckBox(Composite parent,
	                                                       String text,
	                                                       WritablePropertyValueModel<Boolean> booleanHolder,
	                                                       String helpId) {

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

		TriStateCheckBoxModelAdapter.adapt(
			booleanHolder,
			checkBox
		);

		if (helpId != null) {
			helpSystem().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
	 * @return The newly created <code>TriStateCheckBox</code>
	 */
	protected final TriStateCheckBox buildTriStateCheckBoxWithDefault(Composite parent,
	                                                                  String text,
	                                                                  WritablePropertyValueModel<Boolean> booleanHolder,
	                                                                  PropertyValueModel<String> stringHolder) {

		return this.buildTriStateCheckBoxWithDefault(
			parent,
			text,
			booleanHolder,
			stringHolder,
			null
		);
	}

	/**
	 * 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>
	 */
	protected final TriStateCheckBox buildTriStateCheckBoxWithDefault(Composite parent,
	                                                                  String text,
	                                                                  WritablePropertyValueModel<Boolean> booleanHolder,
	                                                                  PropertyValueModel<String> stringHolder,
	                                                                  String helpId) {

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

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

		return checkBox;
	}

	/**
	 * Uninstalls any listeners from the subject in order to stop being notified
	 * for changes made outside of this panes.
	 *
	 * @category Populate
	 */
	protected void disengageListeners() {

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

		this.subjectHolder.removePropertyChangeListener(
			PropertyValueModel.VALUE,
			this.subjectChangeListener
		);

		this.disengageListeners(this.subject());

		for (AbstractPane<?> subPane : this.subPanes) {
			subPane.disengageListeners();
		}
	}

	/**
	 * Removes any property change listeners from the given subject.
	 *
	 * @param subject The old subject
	 *
	 * @category Populate
	 */
	protected void disengageListeners(T subject) {
		if (subject != null) {
//			this.log("   ->disengageListeners() from " + subject);

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

	/**
	 * Notifies this pane is should dispose itself.
	 *
	 * @category Populate
	 */
	public final void dispose() {
		if (!this.container.isDisposed()) {
			this.log(Tracing.UI_LAYOUT, "dispose()");
			this.performDispose();
			this.disengageListeners();
		}
	}

	/**
	 * Requests this pane to dispose itself.
	 *
	 * @category Populate
	 */
	protected void doDispose() {
		this.log(Tracing.UI_LAYOUT, "   ->doDispose()");
	}

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

	/**
	 * 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) {

		if (!container.isDisposed()) {

			container.setEnabled(enabled);

			for (AbstractPane<?> subPane : this.subPanes) {
				subPane.enableWidgets(enabled);
			}
		}
	}

	/**
	 * Installs the listeners on the subject in order to be notified from changes
	 * made outside of this panes and notifies the sub-panes to do the same.
	 *
	 * @category Populate
	 */
	protected void engageListeners() {

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

		this.engageSubjectHolder();
		this.engageListeners(this.subject());

		for (AbstractPane<?> subPane : this.subPanes) {
			subPane.engageListeners();
		}
	}

	/**
	 * TODO
	 *
	 * @param subject
	 *
	 * @category Populate
	 */
	protected void engageListeners(T subject) {
		if (subject != null) {

//			this.log("   ->engageListeners() on " + subject);

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

	private void engageSubjectHolder() {
		this.subjectHolder.addPropertyChangeListener(
			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
	 *
	 * @return
	 *
	 * @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 groupBoxMargin() {
		Group group = this.widgetFactory.createGroup(Display.getCurrent().getActiveShell(), "");
		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 helpSystem() {
		return PlatformUI.getWorkbench().getHelpSystem();
	}

	/**
	 * Initializes this <code>AbstractSubjectPane</code>.
	 *
	 * @category Initialization
	 */
	protected void initialize() {
	}

	/**
	 * 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
	 *
	 * @category Initialization
	 */
	private void initialize(AbstractPane<?> parentPane,
	                        boolean automaticallyAlignWidgets) {

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

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

	/**
	 * Initializes this <code>AbstractSubjectPane</code>.
	 *
	 * @param subjectHolder The holder of this pane's subject
	 * @param widgetFactory The factory used to create various widgets
	 *
	 * @category 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<AbstractPane<?>>();
		this.leftControlAligner    = new ControlAligner();
		this.rightControlAligner   = new ControlAligner();
		this.subjectChangeListener = this.buildSubjectChangeListener();
		this.aspectChangeListener  = this.buildAspectChangeListener();

		this.initialize();
	}

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

	/**
	 * 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 (Tracing.UI_LAYOUT.equals(flag) &&
		    Tracing.booleanDebugOption(Tracing.UI_LAYOUT)) {

			Class<?> thisClass = getClass();
			String className = ClassTools.shortNameFor(thisClass);

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

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

	/**
	 * Notifies this pane is should dispose itself.
	 *
	 * @category Populate
	 */
	protected void performDispose() {
		this.log(Tracing.UI_LAYOUT, "   ->performDispose()");

		// Dispose this pane
		doDispose();

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

	/**
	 * Notifies this pane to populate itself using the subject's information.
	 *
	 * @category Populate
	 */
	public final void populate() {
		if (!this.container.isDisposed()) {
			this.log(Tracing.UI_LAYOUT, "populate()");
			this.engageListeners();
			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> propertyNames() {
		ArrayList<String> propertyNames = new ArrayList<String>();
		addPropertyNames(propertyNames);
		return propertyNames;
	}

	/**
	 * Registers another <code>AbstractSubjectPane</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(AbstractPane<?> subPane) {
		this.subPanes.add(subPane);
	}

	/**
	 * 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(AbstractPane<?> 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(AbstractPane<?> 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(AbstractPane<?> 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 (AbstractPane<?> subPane : this.subPanes) {
			subPane.repopulate();
		}
	}

	/**
	 * Determines whether this pane should be repopulate even if the subject if
	 * <code>null</code>.
	 *
	 * @return <code>true</code> is returned by default
	 */
	protected boolean repopulateWithNullSubject() {
		return true;
	}

	/**
	 * Sets (TODO)
	 *
	 * @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
	 */
	protected final Shell shell() {
		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
	 */
	protected T subject() {
		return this.subjectHolder.value();
	}

	/**
	 * 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);

			// Only repopulate if it is allowed when the subject is null
			if (newSubject != null ||
			   (newSubject == null && repopulateWithNullSubject()))
			{
				this.repopulate();
			}

			this.engageListeners(newSubject);
		}
	}

	/**
	 * Unregisters the given <code>AbstractSubjectPane</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(AbstractPane<?> subPane) {
		this.subPanes.remove(subPane);
	}

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

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