gt:     	GridLayout layout = new GridLayout();
context: /*******************************************************************************
   * Copyright (c) 2005, 2013 IBM Corporation and others.
   * All rights reserved. This program and the accompanying materials
   * are made available under the terms of the Eclipse Public License v1.0
   * which accompanies this distribution, and is available at
   * http://www.eclipse.org/legal/epl-v10.html
   *
   * Contributors:
   *     IBM Corporation - initial API and implementation
   *******************************************************************************/
  package org.eclipse.jface.dialogs;
  
  import org.eclipse.jface.resource.JFaceResources;
  import org.eclipse.jface.window.IShellProvider;
  import org.eclipse.swt.SWT;
  import org.eclipse.swt.events.ControlAdapter;
  import org.eclipse.swt.events.ControlEvent;
  import org.eclipse.swt.events.DisposeEvent;
  import org.eclipse.swt.events.DisposeListener;
  import org.eclipse.swt.events.SelectionAdapter;
  import org.eclipse.swt.events.SelectionEvent;
  import org.eclipse.swt.graphics.Cursor;
  import org.eclipse.swt.graphics.Image;
  import org.eclipse.swt.graphics.Rectangle;
  import org.eclipse.swt.layout.GridData;
  import org.eclipse.swt.layout.GridLayout;
  import org.eclipse.swt.widgets.Composite;
  import org.eclipse.swt.widgets.Control;
  import org.eclipse.swt.widgets.Event;
  import org.eclipse.swt.widgets.Label;
  import org.eclipse.swt.widgets.Layout;
  import org.eclipse.swt.widgets.Link;
  import org.eclipse.swt.widgets.Listener;
  import org.eclipse.swt.widgets.Sash;
  import org.eclipse.swt.widgets.Shell;
  import org.eclipse.swt.widgets.ToolBar;
  import org.eclipse.swt.widgets.ToolItem;
  
  /**
   * A <code>TrayDialog</code> is a specialized <code>Dialog</code> that can contain
   * a tray on its side. The tray's content is provided as a <code>DialogTray</code>.
   * <p>
   * It is recommended to subclass this class instead of <code>Dialog</code> in all
   * cases except where the dialog should never show a tray. For example, dialogs
   * which are very short, simple, and quick to dismiss (e.g. a message dialog with
   * an OK button) should subclass <code>Dialog</code>.
   * </p>
   * <p>
   * Note: Trays are not supported on dialogs that use a custom layout on the <code>
   * Shell</code> by overriding <code>Window#getLayout()</code>.
   * </p>
   *
   * @see org.eclipse.jface.dialogs.DialogTray
   * @see org.eclipse.jface.window.Window#getLayout()
   * @since 3.2
   */
  public abstract class TrayDialog extends Dialog {
  
  	private final class ResizeListener extends ControlAdapter {
  
  		private final GridData data;
  		private final Shell shell;
  		private final int TRAY_RATIO = 100; // Percentage of extra width devoted to tray when resizing
  		private int remainder = 0; // Used to prevent rounding errors from accumulating
  
  		private ResizeListener(GridData data, Shell shell) {
  			this.data = data;
  			this.shell = shell;
  		}
  
  		@Override
  		public void controlResized (ControlEvent event) {
  				int newWidth = shell.getSize().x;
  				if (newWidth != shellWidth) {
  					int shellWidthIncrease = newWidth - shellWidth;
  					int trayWidthIncreaseTimes100 = (shellWidthIncrease * TRAY_RATIO) + remainder;
  					int trayWidthIncrease = trayWidthIncreaseTimes100/100;
  					remainder = trayWidthIncreaseTimes100 - (100 * trayWidthIncrease);
  					data.widthHint = data.widthHint + trayWidthIncrease;
  					shellWidth = newWidth;
  					if (!shell.isDisposed()) {
  						shell.layout();
  					}
  				}
  		  }
  	}
  
  	private static boolean dialogHelpAvailable;
  
  	/**
  	 * The dialog's tray (null if none).
  	 */
  	private DialogTray tray;
  
  	/**
  	 * The tray's control (null if none).
  	 */
  	private Control trayControl;
  
  	/**
  	 * The control that had focus before the tray was opened (null if none).
  	 */
  	private Control nonTrayFocusControl;
  
  	/*
  	 * The separator to the left of the sash.
  	 */
  	private Label leftSeparator;
  
  	/*
  	 * The separator to the right of the sash.
  	 */
  	private Label rightSeparator;
  
  	/*
  	 * The sash that allows the user to resize the tray.
  	 */
  	private Sash sash;
  
  	/*
  	 * Whether or not help is available for this dialog.
  	 */
  	private boolean helpAvailable = isDialogHelpAvailable();
  
  	private int shellWidth;
  
  	private ControlAdapter resizeListener;
  
  	/**
  	 * The help button (null if none).
  	 */
  	private ToolItem fHelpButton;
  
  	/**
  	 * Creates a tray dialog instance. Note that the window will have no visual
  	 * representation (no widgets) until it is told to open.
  	 *
  	 * @param shell the parent shell, or <code>null</code> to create a top-level shell
  	 */
  	protected TrayDialog(Shell shell) {
  		super(shell);
  	}
  
  	/**
  	 * Creates a tray dialog with the given parent.
  	 *
  	 * @param parentShell the object that returns the current parent shell
  	 */
  	protected TrayDialog(IShellProvider parentShell) {
  		super(parentShell);
  	}
  
  	/**
  	 * Closes this dialog's tray, disposing its widgets.
  	 *
  	 * @throws IllegalStateException if the tray was not open
  	 */
  	public void closeTray() throws IllegalStateException {
  		if (getTray() == null) {
  			throw new IllegalStateException("Tray was not open"); //$NON-NLS-1$
  		}
  		Shell shell = getShell();
  		Control focusControl = shell.getDisplay().getFocusControl();
  		if (focusControl!= null && isContained(trayControl, focusControl)) {
  			if (nonTrayFocusControl!= null && !nonTrayFocusControl.isDisposed()) {
  				nonTrayFocusControl.setFocus();
  			} else {
  				shell.setFocus();
  			}
  		}
  		nonTrayFocusControl= null;
  		shell.removeControlListener (resizeListener);
  		resizeListener = null;
  		int trayWidth = trayControl.getSize().x + leftSeparator.getSize().x + sash.getSize().x + rightSeparator.getSize().x;
  		trayControl.dispose();
  		trayControl = null;
  		tray = null;
  		leftSeparator.dispose();
  		leftSeparator = null;
  		rightSeparator.dispose();
  		rightSeparator = null;
  		sash.dispose();
  		sash = null;
  		Rectangle bounds = shell.getBounds();
  		shell.setBounds(bounds.x + ((getDefaultOrientation() == SWT.RIGHT_TO_LEFT) ? trayWidth : 0), bounds.y, bounds.width - trayWidth, bounds.height);
  		if (fHelpButton != null) {
  			fHelpButton.setSelection(false);
  		}
  	}
  
  	/**
  	 * Returns true if the given Control is a direct or indirect child of
  	 * container.
  	 *
  	 * @param container
  	 *            the potential parent
  	 * @param control
  	 * @return boolean <code>true</code> if control is a child of container
  	 */
  	private boolean isContained(Control container, Control control) {
  		Composite parent;
  		while ((parent = control.getParent()) != null) {
  			if (parent == container) {
  				return true;
  			}
  			control = parent;
  		}
  		return false;
  	}
  
  	@Override
  	protected void handleShellCloseEvent() {
  		/*
  		 * Close the tray to ensure that those dialogs that remember their
  		 * size do not store the tray size.
  		 */
  		if (getTray() != null) {
  			closeTray();
  		}
  
  		super.handleShellCloseEvent();
  	}
  
  	@Override
  	protected Control createButtonBar(Composite parent) {
      	Composite composite = new Composite(parent, SWT.NONE);
  