*** empty log message ***
diff --git a/bundles/org.eclipse.ui.forms/src/org/eclipse/ui/forms/IMessage.java b/bundles/org.eclipse.ui.forms/src/org/eclipse/ui/forms/IMessage.java
new file mode 100644
index 0000000..0d165d6
--- /dev/null
+++ b/bundles/org.eclipse.ui.forms/src/org/eclipse/ui/forms/IMessage.java
@@ -0,0 +1,54 @@
+/*******************************************************************************
+ * Copyright (c) 2007 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.ui.forms;
+
+import org.eclipse.jface.dialogs.IMessageProvider;
+import org.eclipse.swt.widgets.Control;
+
+/**
+ * This interface encapsulates a single message that can be shown in a form.
+ * Messages can be associated with controls, or be of a general nature.
+ * 
+ * @see IMessageManager
+ * @since 3.3
+ */
+public interface IMessage extends IMessageProvider {
+	/**
+	 * Returns the unique message key
+	 * 
+	 * @return the unique message key
+	 */
+	Object getKey();
+
+	/**
+	 * Returns data for application use
+	 * 
+	 * @return data object
+	 */
+	Object getData();
+
+	/**
+	 * Returns the control this message is associated with.
+	 * 
+	 * @return the control or <code>null</code> if this is a general message.
+	 */
+	Control getControl();
+
+	/**
+	 * Messages that are associated with controls can be shown with a prefix
+	 * that indicates the origin of the message (e.g. the label preceeding the
+	 * control).
+	 * 
+	 * @return the message prefix or <code>null</code> if this is a general
+	 *         message
+	 */
+	String getPrefix();
+}
\ No newline at end of file
diff --git a/bundles/org.eclipse.ui.forms/src/org/eclipse/ui/forms/IMessageContainer.java b/bundles/org.eclipse.ui.forms/src/org/eclipse/ui/forms/IMessageContainer.java
deleted file mode 100644
index d932f37..0000000
--- a/bundles/org.eclipse.ui.forms/src/org/eclipse/ui/forms/IMessageContainer.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2007 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.ui.forms;
-
-import org.eclipse.jface.dialogs.IMessageProvider;
-
-/**
- * Classes that implement this interface can be managed by the message manager.
- * 
- * @since 3.3
- */
-public interface IMessageContainer extends IMessageProvider {
-
-	/**
-	 * Sets the message with optional detailed text.
-	 * 
-	 * @param message
-	 *            the message or the summary or <code>null</code> to clear the
-	 *            container.
-	 * @param details
-	 *            optional details or <code>null</code> if not available.
-	 * @param type
-	 *            the message type as defined in {@link IMessageProvider}
-	 */
-	void setMessage(String message, String details, int type);
-}
\ No newline at end of file
diff --git a/bundles/org.eclipse.ui.forms/src/org/eclipse/ui/forms/IMessageManager.java b/bundles/org.eclipse.ui.forms/src/org/eclipse/ui/forms/IMessageManager.java
index 8fcd375..efad3b8 100644
--- a/bundles/org.eclipse.ui.forms/src/org/eclipse/ui/forms/IMessageManager.java
+++ b/bundles/org.eclipse.ui.forms/src/org/eclipse/ui/forms/IMessageManager.java
@@ -13,24 +13,41 @@
 
 import org.eclipse.jface.dialogs.IMessageProvider;
 import org.eclipse.swt.widgets.Control;
+import org.eclipse.ui.forms.widgets.Form;
 
 /**
  * This interface provides for managing messages in a form. It is responsible
  * for:
  * <ul>
- * <li>Bridging the concept of messages and field decorations</li>
+ * <li>Bridging the concept of typed messages and field decorations</li>
  * <li>Adding multiple messages per field in a form</li>
  * <li>Rolling up local messages to the form header</li>
  * <li>Adding multiple general messages to the form header</li>
  * </ul>
+ * <p>
+ * To use it in a form, do the following:
+ * <ol>
+ * <li>For each interactive control, add a listener to it to monitor user input</li>
+ * <li>Every time the input changes, validate it. If there is a problem, add a
+ * message with a unique ID to the manager. If there is already a message with
+ * the same ID in the manager, its type and message text will be updated (no
+ * duplicates). Note that you can messages with different ids to the same
+ * control to track multiple problem with the user input.</li>
+ * <li>If the problem has been cleared, remove the message using the id.</li>
+ * <li>If something happens in the form that is not related to any control, us
+ * the other <code>addMessage</code> method.</li>
+ * </ol>
+ * <p>
+ * This interface should only be referenced. It must not be implemented or
+ * extended.
+ * </p>
  * 
  * @since 3.3
  * @see IMessageProvider
- * @see IMessageContainer
+ * @see IManagedForm
  */
 
 public interface IMessageManager {
-
 	/**
 	 * Adds a general message that is not associated with any decorated field.
 	 * 
@@ -40,10 +57,12 @@
 	 * 
 	 * @param messageText
 	 *            the message to add
+	 * @param data
+	 *            an object for application use (can be <code>null</code>)
 	 * @param type
 	 *            the message type as defined in <code>IMessageProvider</code>.
 	 */
-	public void addMessage(Object key, String messageText, int type);
+	void addMessage(Object key, String messageText, Object data, int type);
 
 	/**
 	 * Adds a message that should be associated with the provided control.
@@ -52,12 +71,14 @@
 	 *            the unique message key
 	 * @param messageText
 	 *            the message to add
+	 * @param data
+	 *            an object for application use (can be <code>null</code>)
 	 * @param type
 	 *            the message type
 	 * @param control
 	 *            the control to associate the message with
 	 */
-	public void addMessage(Object key, String messageText, int type,
+	void addMessage(Object key, String messageText, Object data, int type,
 			Control control);
 
 	/**
@@ -66,7 +87,7 @@
 	 * @param key
 	 *            the key of the message to remove
 	 */
-	public void removeMessage(Object key);
+	void removeMessage(Object key);
 
 	/**
 	 * Removes all the general messages. If there are local messages associated
@@ -74,7 +95,7 @@
 	 * attention to these local messages. Otherwise, the container will clear
 	 * the message area.
 	 */
-	public void removeMessages();
+	void removeMessages();
 
 	/**
 	 * Removes the message associated with the provided control.
@@ -84,7 +105,7 @@
 	 * @param control
 	 *            the control the message is associated with
 	 */
-	public void removeMessage(Object key, Control control);
+	void removeMessage(Object key, Control control);
 
 	/**
 	 * Removes all the messages associated with the provided control.
@@ -92,13 +113,13 @@
 	 * @param control
 	 *            the control the messages are associated with
 	 */
-	public void removeMessages(Control control);
+	void removeMessages(Control control);
 
 	/**
 	 * Removes all the local field messages and all the general container
 	 * messages.
 	 */
-	public void removeAllMessages();
+	void removeAllMessages();
 
 	/**
 	 * Updates the message container with the messages currently in the manager.
@@ -107,5 +128,20 @@
 	 * attempt to update a container that is in the process of being disposed
 	 * itself.
 	 */
-	public void update();
+	void update();
+
+	/**
+	 * When message manager is used in context of a form, and there
+	 * are hyperlink listeners for messages in the header, the hyperlink
+	 * event will carry an object of type <code>IMessage[]</code> as an
+	 * href. You can use this method to create a summary text from this
+	 * array consistent with the tool tip used by the form header.
+	 * 
+	 * @param messages
+	 *            an array of messages
+	 * @return a textual representation of the messages with one message per
+	 *         line.
+	 * @see Form#addMessageHyperlinkListener(org.eclipse.ui.forms.events.IHyperlinkListener)
+	 */
+	String createSummary(IMessage[] messages);
 }
\ No newline at end of file
diff --git a/bundles/org.eclipse.ui.forms/src/org/eclipse/ui/forms/ManagedForm.java b/bundles/org.eclipse.ui.forms/src/org/eclipse/ui/forms/ManagedForm.java
index 44e24c7..a177078 100644
--- a/bundles/org.eclipse.ui.forms/src/org/eclipse/ui/forms/ManagedForm.java
+++ b/bundles/org.eclipse.ui.forms/src/org/eclipse/ui/forms/ManagedForm.java
@@ -324,6 +324,9 @@
 		this.container = container;
 	}
 
+	/* (non-Javadoc)
+	 * @see org.eclipse.ui.forms.IManagedForm#getMessageManager()
+	 */
 	public IMessageManager getMessageManager() {
 		if (messageManager == null)
 			messageManager = new MessageManager(form);
diff --git a/bundles/org.eclipse.ui.forms/src/org/eclipse/ui/forms/widgets/Form.java b/bundles/org.eclipse.ui.forms/src/org/eclipse/ui/forms/widgets/Form.java
index 64274ab..db0da2d 100644
--- a/bundles/org.eclipse.ui.forms/src/org/eclipse/ui/forms/widgets/Form.java
+++ b/bundles/org.eclipse.ui.forms/src/org/eclipse/ui/forms/widgets/Form.java
@@ -26,7 +26,7 @@
 import org.eclipse.swt.widgets.Layout;
 import org.eclipse.swt.widgets.Menu;
 import org.eclipse.ui.forms.IFormColors;
-import org.eclipse.ui.forms.IMessageContainer;
+import org.eclipse.ui.forms.IMessage;
 import org.eclipse.ui.forms.events.IHyperlinkListener;
 import org.eclipse.ui.internal.forms.widgets.FormHeading;
 import org.eclipse.ui.internal.forms.widgets.FormUtil;
@@ -82,7 +82,7 @@
  * 
  * @since 3.0
  */
-public class Form extends Composite implements IMessageContainer {
+public class Form extends Composite {
 	private FormHeading head;
 
 	private Composite body;
@@ -336,6 +336,31 @@
 	}
 
 	/**
+	 * Sets the tool bar vertical alignment relative to the header. Can be
+	 * useful when there is more free space at the second row (with the head
+	 * client).
+	 * 
+	 * @param alignment
+	 *            SWT.TOP or SWT.BOTTOM
+	 * @since 3.3
+	 */
+
+	public void setToolBarVerticalAlignment(int alignment) {
+		head.setToolBarAlignment(alignment);
+	}
+
+	/**
+	 * Returns the current tool bar alignment (if used).
+	 * 
+	 * @return SWT.TOP or SWT.BOTTOM
+	 * @since 3.3
+	 */
+
+	public int getToolBarVerticalAlignment() {
+		return head.getToolBarAlignment();
+	}
+
+	/**
 	 * Returns the menu manager that is used to manage title area drop-down menu
 	 * items.
 	 * 
@@ -521,7 +546,8 @@
 	 *            the color to render the head separator or <code>null</code>
 	 *            to use the default color.
 	 * @since 3.2
-	 * @deprecated use <code>setHeadColor(IFormColors.H_BOTTOM_KEYLINE2, separatorColor)</code>
+	 * @deprecated use
+	 *             <code>setHeadColor(IFormColors.H_BOTTOM_KEYLINE2, separatorColor)</code>
 	 */
 	public void setSeparatorColor(Color separatorColor) {
 		head.putColor(IFormColors.H_BOTTOM_KEYLINE2, separatorColor);
@@ -562,11 +588,31 @@
 	 * @param message
 	 *            the message, or <code>null</code> to clear the message
 	 * @see #setMessage(String, int)
-	 * @deprecated use {@link #setMessage(String, int)}
 	 * @since 3.2
 	 */
 	public void setMessage(String message) {
-		this.setMessage(message, 0);
+		this.setMessage(message, 0, null);
+	}
+
+	/**
+	 * Sets the message for this form with an indication of what type of message
+	 * it is.
+	 * <p>
+	 * The valid message types are one of <code>NONE</code>,
+	 * <code>INFORMATION</code>,<code>WARNING</code>, or
+	 * <code>ERROR</code> defined in IMessageProvider interface.
+	 * </p>
+	 * 
+	 * @param newMessage
+	 *            the message, or <code>null</code> to clear the message
+	 * @param newType
+	 *            the message type
+	 * @see org.eclipse.jface.dialogs.IMessageProvider
+	 * @since 3.2
+	 */
+
+	public void setMessage(String newMessage, int newType) {
+		this.setMessage(newMessage, newType, null);
 	}
 
 	/**
@@ -578,17 +624,24 @@
 	 * <code>ERROR</code> defined in IMessageProvider interface.
 	 * </p>
 	 * <p>
+	 * In addition to the summary message, this method also sets an array of
+	 * individual messages.
+	 * 
 	 * 
 	 * @param newMessage
 	 *            the message, or <code>null</code> to clear the message
 	 * @param newType
 	 *            the message type
+	 * @param children
+	 *            the individual messages that contributed to the overall
+	 *            message
 	 * @see org.eclipse.jface.dialogs.IMessageProvider
-	 * @since 3.2
+	 * @since 3.3
 	 */
 
-	public void setMessage(String newMessage, int newType) {
-		setMessage(newMessage, null, newType);
+	public void setMessage(String newMessage, int newType, IMessage[] children) {
+		head.showMessage(newMessage, newType, children);
+		layout();
 	}
 
 	/**
@@ -681,11 +734,6 @@
 		head.addDropSupport(operations, transferTypes, listener);
 	}
 
-	public void setMessage(String message, String details, int type) {
-		head.setMessage(message, details, type);
-		layout();
-	}
-
 	/*
 	 * (non-Javadoc)
 	 * 
diff --git a/bundles/org.eclipse.ui.forms/src/org/eclipse/ui/forms/widgets/ScrolledForm.java b/bundles/org.eclipse.ui.forms/src/org/eclipse/ui/forms/widgets/ScrolledForm.java
index 7fc004d..b7576ec 100644
--- a/bundles/org.eclipse.ui.forms/src/org/eclipse/ui/forms/widgets/ScrolledForm.java
+++ b/bundles/org.eclipse.ui.forms/src/org/eclipse/ui/forms/widgets/ScrolledForm.java
@@ -17,7 +17,7 @@
 import org.eclipse.swt.widgets.Composite;
 import org.eclipse.swt.widgets.Control;
 import org.eclipse.swt.widgets.Menu;
-import org.eclipse.ui.forms.IMessageContainer;
+import org.eclipse.ui.forms.IMessage;
 
 /**
  * ScrolledForm is a control that is capable of scrolling an instance of the
@@ -44,8 +44,7 @@
  * 
  * @since 3.0
  */
-public class ScrolledForm extends SharedScrolledComposite implements
-		IMessageContainer {
+public class ScrolledForm extends SharedScrolledComposite {
 	private Form content;
 
 	public ScrolledForm(Composite parent) {
@@ -243,17 +242,17 @@
 	 * 
 	 * @param newMessage
 	 *            the message text or <code>null</code> to reset.
-	 * @param detailedMessage
-	 *            the optional detailed message or <code>null</code>.
 	 * @param newType
 	 *            as defined in
 	 *            {@link org.eclipse.jface.dialogs.IMessageProvider}.
+	 * @param messages
+	 * 			 an optional array of children that itemize individual
+	 * 			messages or <code>null</code> for a simple message.
 	 * @since 3.3
 	 * @see Form#setMessage(String, int)
 	 */
-	public void setMessage(String newMessage, String detailedMessage,
-			int newType) {
-		content.setMessage(newMessage, detailedMessage, newType);
+	public void setMessage(String newMessage, int newType, IMessage[] messages) {
+		content.setMessage(newMessage, newType, messages);
 		reflow(true);
 	}
 
@@ -264,7 +263,7 @@
 	 *      int)
 	 */
 	public void setMessage(String newMessage, int newType) {
-		this.setMessage(newMessage, null, newType);
+		this.setMessage(newMessage, newType, null);
 	}
 
 	/*
diff --git a/bundles/org.eclipse.ui.forms/src/org/eclipse/ui/internal/forms/MessageManager.java b/bundles/org.eclipse.ui.forms/src/org/eclipse/ui/internal/forms/MessageManager.java
index 74246ab..729f820 100644
--- a/bundles/org.eclipse.ui.forms/src/org/eclipse/ui/internal/forms/MessageManager.java
+++ b/bundles/org.eclipse.ui.forms/src/org/eclipse/ui/internal/forms/MessageManager.java
@@ -26,8 +26,9 @@
 import org.eclipse.swt.widgets.Composite;
 import org.eclipse.swt.widgets.Control;
 import org.eclipse.swt.widgets.Label;
-import org.eclipse.ui.forms.IMessageContainer;
+import org.eclipse.ui.forms.IMessage;
 import org.eclipse.ui.forms.IMessageManager;
+import org.eclipse.ui.forms.widgets.ScrolledForm;
 
 /**
  * @see IMessageManager
@@ -36,7 +37,7 @@
 public class MessageManager implements IMessageManager {
 	private ArrayList messages = new ArrayList();
 	private Hashtable decorators = new Hashtable();
-	private IMessageContainer messageContainer;
+	private ScrolledForm scrolledForm;
 	private static FieldDecoration standardError = FieldDecorationRegistry
 			.getDefault().getFieldDecoration(FieldDecorationRegistry.DEC_ERROR);
 	private static FieldDecoration standardWarning = FieldDecorationRegistry
@@ -55,16 +56,19 @@
 			Messages.MessageManager_pWarningSummary,
 			Messages.MessageManager_pErrorSummary };
 
-	class Message {
+	static class Message implements IMessage {
+		Control control;
+		Object data;
 		Object key;
 		String message;
 		int type;
 		String prefix;
 
-		Message(Object key, String message, int type) {
+		Message(Object key, String message, int type, Object data) {
 			this.key = key;
 			this.message = message;
 			this.type = type;
+			this.data = data;
 		}
 
 		/*
@@ -94,19 +98,37 @@
 			return type;
 		}
 
-		String getFullMessage() {
-			if (prefix == null)
-				return message;
-			return prefix + message;
+		/*
+		 * (non-Javadoc)
+		 * 
+		 * @see org.eclipse.ui.forms.messages.IMessage#getControl()
+		 */
+		public Control getControl() {
+			return control;
 		}
 
+		/*
+		 * (non-Javadoc)
+		 * 
+		 * @see org.eclipse.ui.forms.messages.IMessage#getData()
+		 */
+		public Object getData() {
+			return data;
+		}
+
+		/*
+		 * (non-Javadoc)
+		 * 
+		 * @see org.eclipse.ui.forms.messages.IMessage#getPrefix()
+		 */
+		public String getPrefix() {
+			return prefix;
+		}
 	}
 
-	class ControlDecorator implements IMessageContainer {
+	class ControlDecorator {
 		private ControlDecoration decoration;
 		private ArrayList controlMessages = new ArrayList();
-		private String message;
-		private int type;
 		private String prefix;
 
 		ControlDecorator(Control control) {
@@ -114,10 +136,6 @@
 					| SWT.BOTTOM);
 		}
 
-		public void dispose() {
-			decoration.dispose();
-		}
-
 		public boolean isDisposed() {
 			return decoration.getControl() == null;
 		}
@@ -154,71 +172,41 @@
 			target.addAll(controlMessages);
 		}
 
-		void addMessage(Object key, String text, int type) {
-			MessageManager.this.addMessage(getPrefix(), key, text, type,
-					controlMessages);
-			updateMessageContainer(this, controlMessages, true);
-		}
-
-		void removeMessage(Object key) {
-			Message message = findMessage(key, controlMessages);
-			if (message != null) {
-				controlMessages.remove(message);
-				updateMessageContainer(this, controlMessages, true);
-			}
-		}
-
-		void removeMessages() {
-			controlMessages.clear();
-			updateMessageContainer(this, controlMessages, true);
-		}
-
-		boolean isEmpty() {
-			return controlMessages.isEmpty();
-		}
-
-		/*
-		 * (non-Javadoc)
-		 * 
-		 * @see org.eclipse.jface.dialogs.IMessageContainer#setMessage(java.lang.String,
-		 *      int)
-		 */
-		public void setMessage(String newMessage, String details, int newType) {
-			if (this.message != null && newMessage != null
-					&& newMessage.equals(this.message) && newType == this.type)
-				return;
-			this.message = newMessage;
-			this.type = newType;
+		void addMessage(Object key, String text, Object data, int type) {
+			Message message = MessageManager.this.addMessage(getPrefix(), key,
+					text, data, type, controlMessages);
+			message.control = decoration.getControl();
 			update();
 		}
 
-		/*
-		 * (non-Javadoc)
-		 * 
-		 * @see org.eclipse.jface.dialogs.IMessageProvider#getMessage()
-		 */
-		public String getMessage() {
-			return message;
+		boolean removeMessage(Object key) {
+			Message message = findMessage(key, controlMessages);
+			if (message != null) {
+				controlMessages.remove(message);
+				update();
+			}
+			return message != null;
 		}
 
-		/*
-		 * (non-Javadoc)
-		 * 
-		 * @see org.eclipse.jface.dialogs.IMessageProvider#getMessageType()
-		 */
-		public int getMessageType() {
-			return type;
+		boolean removeMessages() {
+			if (controlMessages.isEmpty())
+				return false;
+			controlMessages.clear();
+			update();
+			return true;
 		}
 
 		private void update() {
-			if (message == null)
+			if (controlMessages.isEmpty())
 				decoration.hide();
 			else {
+				int type = ((IMessage) controlMessages.get(0)).getMessageType();
+				String description = createDetails(controlMessages, true);
 				if (type == IMessageProvider.ERROR)
 					decoration.setImage(standardError.getImage());
 				else if (type == IMessageProvider.WARNING)
 					decoration.setImage(standardWarning.getImage());
-				decoration.setDescriptionText(message);
+				decoration.setDescriptionText(description);
 				decoration.show();
 			}
 		}
@@ -226,13 +214,13 @@
 
 	/**
 	 * Creates a new instance of the message manager that will work with the
-	 * provided message container.
+	 * provided form.
 	 * 
-	 * @param messageContainer
-	 *            the container to control
+	 * @param scrolledForm
+	 *            the form to control
 	 */
-	public MessageManager(IMessageContainer messageContainer) {
-		this.messageContainer = messageContainer;
+	public MessageManager(ScrolledForm scrolledForm) {
+		this.scrolledForm = scrolledForm;
 	}
 
 	/*
@@ -241,8 +229,8 @@
 	 * @see org.eclipse.ui.forms.IMessageManager#addMessage(java.lang.Object,
 	 *      java.lang.String, int)
 	 */
-	public void addMessage(Object key, String messageText, int type) {
-		addMessage(null, key, messageText, type, messages);
+	public void addMessage(Object key, String messageText, Object data, int type) {
+		addMessage(null, key, messageText, data, type, messages);
 		update();
 	}
 
@@ -252,15 +240,15 @@
 	 * @see org.eclipse.ui.forms.IMessageManager#addMessage(java.lang.Object,
 	 *      java.lang.String, int, org.eclipse.swt.widgets.Control)
 	 */
-	public void addMessage(Object key, String messageText, int type,
-			Control control) {
+	public void addMessage(Object key, String messageText, Object data,
+			int type, Control control) {
 		ControlDecorator dec = (ControlDecorator) decorators.get(control);
 
 		if (dec == null) {
 			dec = new ControlDecorator(control);
 			decorators.put(control, dec);
 		}
-		dec.addMessage(key, messageText, type);
+		dec.addMessage(key, messageText, data, type);
 		update();
 	}
 
@@ -283,8 +271,10 @@
 	 * @see org.eclipse.ui.forms.IMessageManager#removeMessages()
 	 */
 	public void removeMessages() {
-		messages.clear();
-		update();
+		if (!messages.isEmpty()) {
+			messages.clear();
+			update();
+		}
 	}
 
 	/*
@@ -297,8 +287,8 @@
 		ControlDecorator dec = (ControlDecorator) decorators.get(control);
 		if (dec == null)
 			return;
-		dec.removeMessage(key);
-		update();
+		if (dec.removeMessage(key))
+			update();
 	}
 
 	/*
@@ -308,8 +298,11 @@
 	 */
 	public void removeMessages(Control control) {
 		ControlDecorator dec = (ControlDecorator) decorators.get(control);
-		dec.removeMessages();
-		update();
+		if (dec != null) {
+			if (dec.removeMessages()) {
+				update();
+			}
+		}
 	}
 
 	/*
@@ -318,29 +311,37 @@
 	 * @see org.eclipse.ui.forms.IMessageManager#removeAllMessages()
 	 */
 	public void removeAllMessages() {
+		boolean needsUpdate = false;
 		for (Enumeration enm = decorators.elements(); enm.hasMoreElements();) {
 			ControlDecorator control = (ControlDecorator) enm.nextElement();
-			control.removeMessages();
+			if (control.removeMessages())
+				needsUpdate = true;
 		}
-		messages.clear();
-		update();
+		if (!messages.isEmpty()) {
+			messages.clear();
+			needsUpdate = true;
+		}
+		if (needsUpdate)
+			update();
 	}
 
 	/*
 	 * Adds the message if it does not already exist in the provided list.
 	 */
 
-	private void addMessage(String prefix, Object key, String messageText,
-			int type, ArrayList list) {
+	private Message addMessage(String prefix, Object key, String messageText,
+			Object data, int type, ArrayList list) {
 		Message message = findMessage(key, list);
 		if (message == null) {
-			message = new Message(key, messageText, type);
+			message = new Message(key, messageText, type, data);
 			message.prefix = prefix;
 			list.add(message);
 		} else {
 			message.message = messageText;
 			message.type = type;
+			message.data = data;
 		}
+		return message;
 	}
 
 	/*
@@ -368,26 +369,47 @@
 			ControlDecorator dec = (ControlDecorator) enm.nextElement();
 			dec.addAll(mergedList);
 		}
-		updateMessageContainer(messageContainer, mergedList, false);
+		update(mergedList);
 	}
 
-	/*
-	 * This method works with a generic message container when a list of
-	 * messages of various types need to be shown. The messages with the highest
-	 * type are picked first. If there are more than one with this type, a
-	 * multiple message is constructed; otherwise, the message is used as-is.
-	 */
-
-	private void updateMessageContainer(IMessageContainer container,
-			ArrayList messages, boolean showAll) {
+	private void update(ArrayList mergedList) {
 		pruneControlDecorators();
-		if (messages.isEmpty() || messages == null) {
-			container.setMessage(null, null, IMessageProvider.NONE);
+		if (mergedList.isEmpty() || mergedList == null) {
+			scrolledForm.setMessage(null, IMessageProvider.NONE);
 			return;
 		}
-		int maxType = 0;
-		// create a subset of messages with the highest type
+		ArrayList peers = createPeers(mergedList);
+		int maxType = ((IMessage) peers.get(0)).getMessageType();
+		String messageText;
+		IMessage[] array = (IMessage[]) peers.toArray(new IMessage[peers
+		                                       					.size()]);
+		if (peers.size() == 1 && ((Message) peers.get(0)).prefix == null) {
+			// a single message
+			IMessage message = (IMessage)peers.get(0);
+			messageText = message.getMessage();
+			scrolledForm.setMessage(messageText, maxType, array); 
+		} else {
+			// show a summary message for the message
+			// and list of errors for the details
+			if (peers.size() > 1)
+				messageText = Messages.bind(
+						MULTIPLE_MESSAGE_SUMMARY_KEYS[maxType],
+						new String[] { peers.size() + "" }); //$NON-NLS-1$
+			else
+				messageText = SINGLE_MESSAGE_SUMMARY_KEYS[maxType];
+			scrolledForm.setMessage(messageText, maxType, array);
+		}
+	}
+
+	private static String getFullMessage(IMessage message) {
+		if (message.getPrefix() == null)
+			return message.getMessage();
+		return message.getPrefix() + message.getMessage();
+	}
+
+	private ArrayList createPeers(ArrayList messages) {
 		ArrayList peers = new ArrayList();
+		int maxType = 0;
 		for (int i = 0; i < messages.size(); i++) {
 			Message message = (Message) messages.get(i);
 			if (message.type > maxType) {
@@ -397,39 +419,42 @@
 			if (message.type == maxType)
 				peers.add(message);
 		}
-		String messageText;
-		String details = null;
-		if (peers.size() == 1 && ((Message) peers.get(0)).prefix == null) {
-			// a single message
-			messageText = ((Message) peers.get(0)).message;
-		} else {
-			StringWriter sw = new StringWriter();
-			PrintWriter out = new PrintWriter(sw);
-			// StringBuffer sw = new StringBuffer();
-			for (int i = 0; i < peers.size(); i++) {
-				if (i > 0)
-					out.println();
-				Message m = (Message) peers.get(i);
-				out.print(showAll ? m.message : m.getFullMessage());
-			}
-			out.flush();
-			if (showAll)
-				messageText = sw.toString();
-			else {
-				// show a summary message for the message
-				// and list of errors for the details
-				if (peers.size() > 1)
-					messageText = Messages.bind(
-							MULTIPLE_MESSAGE_SUMMARY_KEYS[maxType],
-							new String[] { peers.size() + "" }); //$NON-NLS-1$
-				else
-					messageText = SINGLE_MESSAGE_SUMMARY_KEYS[maxType];
-				details = sw.toString();
-			}
-		}
-		container.setMessage(messageText, details, maxType);
+		return peers;
 	}
 
+	private String createDetails(ArrayList messages, boolean excludePrefix) {
+		StringWriter sw = new StringWriter();
+		PrintWriter out = new PrintWriter(sw);
+
+		for (int i = 0; i < messages.size(); i++) {
+			if (i > 0)
+				out.println();
+			IMessage m = (IMessage) messages.get(i);
+			out.print(excludePrefix ? m.getMessage() : getFullMessage(m));
+		}
+		out.flush();
+		return sw.toString();
+	}
+
+	public static String createDetails(IMessage[] messages) {
+		if (messages == null || messages.length == 0)
+			return null;
+		StringWriter sw = new StringWriter();
+		PrintWriter out = new PrintWriter(sw);
+
+		for (int i = 0; i < messages.length; i++) {
+			if (i > 0)
+				out.println();
+			out.print(getFullMessage(messages[i]));
+		}
+		out.flush();
+		return sw.toString();
+	}
+	
+	public String createSummary(IMessage[] messages) {
+		return createDetails(messages);
+	}
+	
 	private void pruneControlDecorators() {
 		for (Iterator iter = decorators.values().iterator(); iter.hasNext();) {
 			ControlDecorator dec = (ControlDecorator) iter.next();
diff --git a/bundles/org.eclipse.ui.forms/src/org/eclipse/ui/internal/forms/widgets/FormHeading.java b/bundles/org.eclipse.ui.forms/src/org/eclipse/ui/internal/forms/widgets/FormHeading.java
index 458abef..b413847 100644
--- a/bundles/org.eclipse.ui.forms/src/org/eclipse/ui/internal/forms/widgets/FormHeading.java
+++ b/bundles/org.eclipse.ui.forms/src/org/eclipse/ui/internal/forms/widgets/FormHeading.java
@@ -44,10 +44,12 @@
 import org.eclipse.swt.widgets.Listener;
 import org.eclipse.swt.widgets.ToolBar;
 import org.eclipse.ui.forms.IFormColors;
+import org.eclipse.ui.forms.IMessage;
 import org.eclipse.ui.forms.events.IHyperlinkListener;
 import org.eclipse.ui.forms.widgets.Hyperlink;
 import org.eclipse.ui.forms.widgets.ILayoutExtension;
 import org.eclipse.ui.forms.widgets.SizeCache;
+import org.eclipse.ui.internal.forms.MessageManager;
 
 /**
  * Form header moved out of the form class.
@@ -61,6 +63,7 @@
 	private static final int CLIENT_MARGIN = 1;
 
 	private static final int SEPARATOR = 1 << 1;
+	private static final int BOTTOM_TOOLBAR = 1 << 2;
 	private static final int SEPARATOR_HEIGHT = 2;
 	private static final int MESSAGE_AREA_LIMIT = 50;
 
@@ -136,8 +139,11 @@
 			if (headClient != null) {
 				clientCache.setControl(headClient);
 				int cwhint = width;
-				if (cwhint != SWT.DEFAULT)
+				if (cwhint != SWT.DEFAULT) {
 					cwhint -= HMARGIN * 2;
+					if (tbsize != null && getToolBarAlignment() == SWT.BOTTOM)
+						cwhint -= tbsize.x + SPACING;
+				}
 				clsize = clientCache.computeSize(cwhint, SWT.DEFAULT);
 			}
 			int totalFlexWidth = width;
@@ -145,58 +151,55 @@
 			if (totalFlexWidth != SWT.DEFAULT) {
 				totalFlexWidth -= TITLE_HMARGIN * 2;
 				// complete right margin
-				if (hasToolBar() || hasMessageRegion())
+				if (hasToolBar() && getToolBarAlignment() == SWT.TOP
+						|| hasMessageRegion())
 					totalFlexWidth -= SPACING;
 				// subtract tool bar
-				if (hasToolBar())
+				if (hasToolBar() && getToolBarAlignment() == SWT.TOP)
 					totalFlexWidth -= tbsize.x + SPACING;
 				flexWidth = totalFlexWidth;
 				if (hasMessageRegion()) {
 					// remove message region spacing and divide by 2
 					flexWidth -= SPACING;
-					//flexWidth /= 2;
+					// flexWidth /= 2;
 				}
 			}
-/*
-			// compute text and message sizes
-			tsize = titleRegion.computeSize(flexWidth, SWT.DEFAULT);
-			if (flexWidth != SWT.DEFAULT && tsize.x < flexWidth)
-				flexWidth += flexWidth - tsize.x;
-
-			if (hasMessageRegion()) {
-				messageCache.setControl(messageRegion.getMessageControl());
-				msize = messageCache.computeSize(flexWidth, SWT.DEFAULT);
-				int maxWidth = messageCache.computeSize(SWT.DEFAULT,
-						SWT.DEFAULT).x;
-				if (maxWidth < msize.x) {
-					msize.x = maxWidth;
-					// recompute title with the reclaimed width
-					int tflexWidth = totalFlexWidth - SPACING - msize.x;
-					tsize = titleRegion.computeSize(tflexWidth, SWT.DEFAULT);
-				}
-			}
-*/	
+			/*
+			 * // compute text and message sizes tsize =
+			 * titleRegion.computeSize(flexWidth, SWT.DEFAULT); if (flexWidth !=
+			 * SWT.DEFAULT && tsize.x < flexWidth) flexWidth += flexWidth -
+			 * tsize.x;
+			 * 
+			 * if (hasMessageRegion()) {
+			 * messageCache.setControl(messageRegion.getMessageControl()); msize =
+			 * messageCache.computeSize(flexWidth, SWT.DEFAULT); int maxWidth =
+			 * messageCache.computeSize(SWT.DEFAULT, SWT.DEFAULT).x; if
+			 * (maxWidth < msize.x) { msize.x = maxWidth; // recompute title
+			 * with the reclaimed width int tflexWidth = totalFlexWidth -
+			 * SPACING - msize.x; tsize = titleRegion.computeSize(tflexWidth,
+			 * SWT.DEFAULT); } }
+			 */
 			if (!hasMessageRegion()) {
 				tsize = titleRegion.computeSize(flexWidth, SWT.DEFAULT);
-			}
-			else {
+			} else {
 				// Total flexible area in the first row is flexWidth.
-				// Try natural widths of title and 
-				Point tsizeNatural = titleRegion.computeSize(SWT.DEFAULT, SWT.DEFAULT);
+				// Try natural widths of title and
+				Point tsizeNatural = titleRegion.computeSize(SWT.DEFAULT,
+						SWT.DEFAULT);
 				messageCache.setControl(messageRegion.getMessageControl());
-				Point msizeNatural = messageCache.computeSize(SWT.DEFAULT, SWT.DEFAULT);
+				Point msizeNatural = messageCache.computeSize(SWT.DEFAULT,
+						SWT.DEFAULT);
 				// try to fit all
 				tsize = tsizeNatural;
 				msize = msizeNatural;
-				if (flexWidth!=SWT.DEFAULT) {
+				if (flexWidth != SWT.DEFAULT) {
 					int needed = tsizeNatural.x + msizeNatural.x;
-					if (needed>flexWidth) {
-						//too big - try to limit the message
-						int mwidth = flexWidth-tsizeNatural.x;
-						if (mwidth>=MESSAGE_AREA_LIMIT) {
+					if (needed > flexWidth) {
+						// too big - try to limit the message
+						int mwidth = flexWidth - tsizeNatural.x;
+						if (mwidth >= MESSAGE_AREA_LIMIT) {
 							msize.x = mwidth;
-						}
-						else {
+						} else {
 							// message is squeezed to the limit
 							int flex = flexWidth - MESSAGE_AREA_LIMIT;
 							tsize = titleRegion.computeSize(flex, SWT.DEFAULT);
@@ -205,7 +208,7 @@
 					}
 				}
 			}
-		
+
 			Point size = new Point(width, height);
 			if (!move) {
 				// compute sizes
@@ -213,26 +216,34 @@
 				width1 += tsize.x;
 				if (msize != null)
 					width1 += SPACING + msize.x;
-				if (tbsize != null)
+				if (tbsize != null && getToolBarAlignment() == SWT.TOP)
 					width1 += SPACING + tbsize.x;
-				if (msize != null || tbsize != null)
+				if (msize != null
+						|| (tbsize != null && getToolBarAlignment() == SWT.TOP))
 					width1 += SPACING;
 				size.x = width1;
 				if (clsize != null) {
-					int width2 = clsize.x + 2 * HMARGIN;
+					int width2 = clsize.x;
+					if (tbsize != null && getToolBarAlignment() == SWT.BOTTOM)
+						width2 += SPACING + tbsize.x;
+					width2 += 2 * HMARGIN;
 					size.x = Math.max(width1, width2);
 				}
 				// height, first row
 				size.y = tsize.y;
 				if (msize != null)
 					size.y = Math.max(msize.y, size.y);
-				if (tbsize != null)
+				if (tbsize != null && getToolBarAlignment() == SWT.TOP)
 					size.y = Math.max(tbsize.y, size.y);
 				if (size.y > 0)
 					size.y += VMARGIN * 2;
 				// add second row
+				int height2 = 0;
+				if (tbsize != null && getToolBarAlignment() == SWT.BOTTOM)
+					height2 = tbsize.y;
 				if (clsize != null)
-					size.y += VSPACING + clsize.y + CLIENT_MARGIN;
+					height2 = Math.max(height2, clsize.y);
+				size.y += VSPACING + height2 + CLIENT_MARGIN;
 				// add separator
 				if (isSeparatorVisible())
 					size.y += SEPARATOR_HEIGHT;
@@ -243,7 +254,7 @@
 				int row1Height = tsize.y;
 				if (hasMessageRegion())
 					row1Height = Math.max(row1Height, msize.y);
-				if (hasToolBar())
+				if (hasToolBar() && getToolBarAlignment() == SWT.TOP)
 					row1Height = Math.max(row1Height, tbsize.y);
 				titleRegion.setBounds(xloc,
 				// yloc + row1Height / 2 - tsize.y / 2,
@@ -267,22 +278,29 @@
 									msize.x, msize.y);
 					xloc += msize.x;
 				}
-				if (toolBarManager != null) {
+				if (toolBarManager != null)
+					toolBarManager.getControl().setVisible(
+							!toolBarManager.isEmpty());
+				if (tbsize != null && getToolBarAlignment() == SWT.TOP) {
 					ToolBar tbar = toolBarManager.getControl();
-					tbar.setVisible(!toolBarManager.isEmpty());
-					if (tbar.isVisible())
-						tbar.setBounds(x + width - 1 - tbsize.x - HMARGIN,
-						// yloc + row1Height / 2 - tbsize.y / 2,
-						yloc + row1Height -1 - tbsize.y, tbsize.x, tbsize.y);
+					tbar.setBounds(x + width - 1 - tbsize.x - HMARGIN, yloc
+							+ row1Height - 1 - tbsize.y, tbsize.x, tbsize.y);
 				}
 				// second row
 				xloc = HMARGIN;
 				yloc += row1Height + VSPACING;
-				if (headClient != null) {
-					headClient.setBounds(xloc, yloc, width - HMARGIN * 2,
-							clsize.y);
-				}
+				int tw = 0;
 
+				if (tbsize != null && getToolBarAlignment() == SWT.BOTTOM) {
+					ToolBar tbar = toolBarManager.getControl();
+					tbar.setBounds(x + width - 1 - tbsize.x - HMARGIN, yloc,
+							tbsize.x, tbsize.y);
+					tw = tbsize.x + SPACING;
+				}
+				if (headClient != null) {
+					int carea = width - HMARGIN * 2 - tw;
+					headClient.setBounds(xloc, yloc, carea, clsize.y);
+				}
 			}
 			return size;
 		}
@@ -329,10 +347,10 @@
 				fontHeight = gc.getFontMetrics().getHeight();
 				gc.dispose();
 			}
-			return needHyperlink()?fontHeight:fontHeight+2;
+			return needHyperlink() ? fontHeight : fontHeight + 2;
 		}
 
-		public void showMessage(String newMessage, String details, int newType) {
+		public String showMessage(String newMessage, int newType, IMessage[] messages) {
 			Control oldControl = getMessageControl();
 			int oldType = messageType;
 			this.messageType = newType;
@@ -340,20 +358,21 @@
 				// clearing of the message
 				if (oldControl != null && oldControl.isVisible())
 					oldControl.setVisible(false);
-				return;
+				return null;
 			}
 			ensureControlExists();
+			String details = MessageManager.createDetails(messages);
 			if (needHyperlink()) {
 				messageHyperlink.setText(newMessage);
-				// set the severity color
 				messageHyperlink.setToolTipText(details);
-				messageHyperlink.setHref(details);
+				messageHyperlink.setHref(messages);
 			} else {
 				messageLabel.setText(newMessage);
 				messageLabel.setToolTipText(details);
 			}
 			if (oldType != newType)
 				updateForeground();
+			return details;
 		}
 
 		public String getMessage() {
@@ -400,6 +419,8 @@
 			ensureControlExists();
 			if (messageHyperlink != null)
 				messageHyperlink.addHyperlinkListener(listener);
+			if (listeners.size()==1)
+				updateForeground();
 		}
 
 		private void removeMessageHyperlinkListener(IHyperlinkListener listener) {
@@ -408,6 +429,8 @@
 				messageHyperlink.removeHyperlinkListener(listener);
 			if (listeners.isEmpty())
 				listeners = null;
+			if (listeners==null)
+				updateForeground();
 		}
 
 		private void ensureControlExists() {
@@ -802,21 +825,15 @@
 			flags &= ~SEPARATOR;
 	}
 
-	/**
-	 * Sets the message for this form.
-	 * 
-	 * @param message
-	 *            the message, or <code>null</code> to clear the message
-	 * @since 3.2
-	 */
-	public void setMessage(String message) {
-		this.setMessage(message, null, IMessageProvider.NONE);
+	public void setToolBarAlignment(int alignment) {
+		if (alignment == SWT.BOTTOM)
+			flags |= BOTTOM_TOOLBAR;
+		else
+			flags &= ~BOTTOM_TOOLBAR;
 	}
 
-	public void setMessage(String newMessage, String details, int newType) {
-		if (isDisposed())
-			return;
-		showMessage(newMessage, details, newType);
+	public int getToolBarAlignment() {
+		return (flags & BOTTOM_TOOLBAR) != 0 ? SWT.BOTTOM : SWT.TOP;
 	}
 
 	public void addMessageHyperlinkListener(IHyperlinkListener listener) {
@@ -843,7 +860,7 @@
 			messageRegion = new MessageRegion();
 	}
 
-	private void showMessage(String newMessage, String details, int newType) {
+	public void showMessage(String newMessage, int type, IMessage[] messages) {
 		if (messageRegion == null) {
 			// check the trivial case
 			if (newMessage == null)
@@ -851,7 +868,7 @@
 		} else if (messageRegion.isDisposed())
 			return;
 		ensureMessageRegionExists();
-		messageRegion.showMessage(newMessage, details, newType);
+		String details = messageRegion.showMessage(newMessage, type, messages);
 		titleRegion.updateImage(messageRegion.getMessageImage(),
 				details != null ? details : newMessage, false);
 		layout();
@@ -910,7 +927,7 @@
 			DragSourceListener listener) {
 		titleRegion.addDragSupport(operations, transferTypes, listener);
 	}
-	
+
 	public void addDropSupport(int operations, Transfer[] transferTypes,
 			DropTargetListener listener) {
 		titleRegion.addDropSupport(operations, transferTypes, listener);
diff --git a/examples/org.eclipse.ui.forms.examples/src/org/eclipse/ui/forms/examples/internal/rcp/ErrorMessagesPage.java b/examples/org.eclipse.ui.forms.examples/src/org/eclipse/ui/forms/examples/internal/rcp/ErrorMessagesPage.java
index 566e645..be3f544 100644
--- a/examples/org.eclipse.ui.forms.examples/src/org/eclipse/ui/forms/examples/internal/rcp/ErrorMessagesPage.java
+++ b/examples/org.eclipse.ui.forms.examples/src/org/eclipse/ui/forms/examples/internal/rcp/ErrorMessagesPage.java
@@ -12,8 +12,6 @@
 
 import org.eclipse.jface.dialogs.IMessageProvider;
 import org.eclipse.jface.dialogs.MessageDialog;
-import org.eclipse.jface.wizard.Wizard;
-import org.eclipse.jface.wizard.WizardDialog;
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.events.ModifyEvent;
 import org.eclipse.swt.events.ModifyListener;
@@ -26,6 +24,7 @@
 import org.eclipse.swt.widgets.Text;
 import org.eclipse.ui.forms.HyperlinkSettings;
 import org.eclipse.ui.forms.IManagedForm;
+import org.eclipse.ui.forms.IMessage;
 import org.eclipse.ui.forms.IMessageManager;
 import org.eclipse.ui.forms.editor.FormEditor;
 import org.eclipse.ui.forms.editor.FormPage;
@@ -37,10 +36,9 @@
 import org.eclipse.ui.forms.widgets.TableWrapLayout;
 
 /**
- * @author dejan
- * 
- * To change the template for this generated type comment go to Window -
- * Preferences - Java - Code Generation - Code and Comments
+ * This page shows how to use the message manager to handle
+ * errors in a form page. 
+ * @since 3.3
  */
 public class ErrorMessagesPage extends FormPage {
 	/**
@@ -51,7 +49,7 @@
 		super(editor, "messageManager", "Message Manager");
 	}
 
-	protected void createFormContent(IManagedForm managedForm) {
+	protected void createFormContent(final IManagedForm managedForm) {
 		final ScrolledForm form = managedForm.getForm();
 		FormToolkit toolkit = managedForm.getToolkit();
 		toolkit.getHyperlinkGroup().setHyperlinkUnderlineMode(
@@ -61,8 +59,13 @@
 		form.getForm().addMessageHyperlinkListener(new HyperlinkAdapter() {
 			public void linkActivated(HyperlinkEvent e) {
 				String title = e.getLabel();
-				String details = (String) e.getHref();
-				switch (form.getForm().getMessageType()) {
+				String details = title;
+				Object href = e.getHref();
+				if (href instanceof IMessage[]) {
+					details = managedForm.getMessageManager().createSummary((IMessage[])href);
+				}
+				int type = form.getForm().getMessageType();
+				switch (type) {
 				case IMessageProvider.NONE:
 				case IMessageProvider.INFORMATION:
 					MessageDialog.openInformation(form.getShell(), title,
@@ -101,7 +104,7 @@
 			public void widgetSelected(SelectionEvent e) {
 				if (button1.getSelection()) {
 					mmng.addMessage("saveError", "Save Error",
-							IMessageProvider.ERROR);
+							null, IMessageProvider.ERROR);
 				} else {
 					mmng.removeMessage("saveError");
 				}
@@ -113,33 +116,12 @@
 			public void widgetSelected(SelectionEvent e) {
 				if (button2.getSelection()) {
 					mmng.addMessage("info", "Secondary info",
-							IMessageProvider.NONE);
+							null, IMessageProvider.NONE);
 				} else {
 					mmng.removeMessage("info");
 				}
 			}
 		});
-		final Button button3 = toolkit.createButton(form.getBody(),
-				"Open Wizard", SWT.PUSH);
-		button3.addSelectionListener(new SelectionAdapter() {
-			public void widgetSelected(SelectionEvent e) {
-				Wizard w = new Wizard() {
-					public boolean performFinish() {
-						return true;
-					}
-
-					public void addPages() {
-						addPage(new ErrorMessagesWizardPage("id"));
-					}
-				};
-				WizardDialog dialog = new WizardDialog(form.getShell(), w);
-				dialog.create();
-				dialog.getShell().setSize(300, 400);
-				dialog.getShell().setText("Field Error Messages");
-				dialog.open();
-			}
-		});
-
 	}
 
 	private void createDecoratedTextField(String label, FormToolkit toolkit,
@@ -156,11 +138,11 @@
 				if (s.length() > 5 && s.length() <= 10) {
 					mmng.addMessage("textLength",
 							"Text is longer than 5 characters",
-							IMessageProvider.WARNING, text);
+							null, IMessageProvider.WARNING, text);
 				} else if (s.length() > 10) {
 					mmng.addMessage("textLength",
 							"Text is longer than 10 characters",
-							IMessageProvider.ERROR, text);
+							null, IMessageProvider.ERROR, text);
 				} else {
 					mmng.removeMessage("textLength", text);
 				}
@@ -175,7 +157,7 @@
 				if (badType) {
 					mmng.addMessage("textType",
 							"Text must only contain letters",
-							IMessageProvider.ERROR, text);
+							null, IMessageProvider.ERROR, text);
 				} else {
 					mmng.removeMessage("textType", text);
 				}
diff --git a/examples/org.eclipse.ui.forms.examples/src/org/eclipse/ui/forms/examples/internal/rcp/ErrorMessagesWizardPage.java b/examples/org.eclipse.ui.forms.examples/src/org/eclipse/ui/forms/examples/internal/rcp/ErrorMessagesWizardPage.java
deleted file mode 100644
index fae1cc9..0000000
--- a/examples/org.eclipse.ui.forms.examples/src/org/eclipse/ui/forms/examples/internal/rcp/ErrorMessagesWizardPage.java
+++ /dev/null
@@ -1,123 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
- * Contributors:
- *     IBM Corporation - initial API and implementation
- *******************************************************************************/
-package org.eclipse.ui.forms.examples.internal.rcp;
-
-import org.eclipse.jface.wizard.WizardPage;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.widgets.Composite;
-
-/**
- * @author dejan
- * 
- * To change the template for this generated type comment go to Window -
- * Preferences - Java - Code Generation - Code and Comments
- */
-public class ErrorMessagesWizardPage extends WizardPage {
-	//private MessageManager mmng;
-
-	/**
-	 * @param id
-	 * @param title
-	 */
-	public ErrorMessagesWizardPage(String id) {
-		super(id);
-		setTitle("Example with message handling");
-		setDescription("This page shows how MessageManager can be used in wizards");
-	}
-
-	public void createControl(Composite parent) {
-		Composite container = new Composite(parent, SWT.NULL);
-		setControl(container);
-		/*
-		mmng = new MessageManager(this);
-
-		GridLayout glayout = new GridLayout();
-		glayout.horizontalSpacing = 10;
-		glayout.numColumns = 2;
-		container.setLayout(glayout);
-		createDecoratedTextField("Field1", container);
-		createDecoratedTextField("Field2", container);
-		createDecoratedTextField("Field3", container);
-		GridData gd;
-		final Button button1 = new Button(container, SWT.CHECK);
-		button1.setText("Add general error");
-		gd = new GridData();
-		gd.horizontalSpan = 2;
-		button1.setLayoutData(gd);
-		button1.addSelectionListener(new SelectionAdapter() {
-			public void widgetSelected(SelectionEvent e) {
-				if (button1.getSelection()) {
-					mmng.addMessage("saveError", "Save Error",
-							IMessageProvider.ERROR, null);
-				} else {
-					mmng.removeMessage("saveError");
-				}
-			}
-		});
-		final Button button2 = new Button(container, SWT.CHECK);
-		button2.setText("Add static message");
-		gd = new GridData();
-		gd.horizontalSpan = 2;
-		button2.setLayoutData(gd);
-		button2.addSelectionListener(new SelectionAdapter() {
-			public void widgetSelected(SelectionEvent e) {
-				if (button2.getSelection()) {
-					mmng.addMessage("info", "Secondary info",
-							IMessageProvider.NONE, null);
-				} else {
-					mmng.removeMessage("info");
-				}
-			}
-		});
-	}
-
-	private void createDecoratedTextField(String label, Composite parent) {
-		Label l = new Label(parent, SWT.NULL);
-		l.setText(label);
-		final Text text = new Text(parent, SWT.BORDER);
-		GridData gd = new GridData(GridData.FILL_HORIZONTAL);
-		gd.widthHint = 150;
-		text.setLayoutData(gd);
-		text.addModifyListener(new ModifyListener() {
-			public void modifyText(ModifyEvent e) {
-				String s = text.getText();
-				// flag length
-				if (s.length() > 5 && s.length() <= 10) {
-					mmng.addMessage("textLength",
-							"Text is longer than 5 characters",
-							IMessageProvider.WARNING, null, text);
-				} else if (s.length() > 10) {
-					mmng.addMessage("textLength",
-							"Text is longer than 10 characters",
-							IMessageProvider.ERROR, null, text);
-				} else {
-					mmng.removeMessage("textLength", text);
-				}
-				// flag type
-				boolean badType = false;
-				for (int i = 0; i < s.length(); i++) {
-					if (!Character.isLetter(s.charAt(i))) {
-						badType = true;
-						break;
-					}
-				}
-				if (badType) {
-					mmng.addMessage("textType",
-							"Text must only contain letters",
-							IMessageProvider.ERROR, text);
-				} else {
-					mmng.removeMessage("textType", text);
-				}
-			}
-		});
-		*/
-	}
-}
\ No newline at end of file
diff --git a/examples/org.eclipse.ui.forms.examples/src/org/eclipse/ui/forms/examples/internal/rcp/NewStylePage.java b/examples/org.eclipse.ui.forms.examples/src/org/eclipse/ui/forms/examples/internal/rcp/NewStylePage.java
index d53ee9e..0fc7926 100644
--- a/examples/org.eclipse.ui.forms.examples/src/org/eclipse/ui/forms/examples/internal/rcp/NewStylePage.java
+++ b/examples/org.eclipse.ui.forms.examples/src/org/eclipse/ui/forms/examples/internal/rcp/NewStylePage.java
@@ -58,7 +58,7 @@
  */
 public class NewStylePage extends FormPage {
 	private static final String SHORT_TITLE = "Short Title";
-	private static final String LONG_TITLE = "This title is longer and will compete with other header regions";
+	private static final String LONG_TITLE = "This title is somewhat longer";
 	private static final String SHORT_MESSAGE = "A short {0} message";
 	private static final String LONG_MESSAGE = "This {0} message is longer and will also compete with other header regions";
 	private static final String[] MESSAGE_NAMES = { "text", "info", "warning",
@@ -142,9 +142,23 @@
 
 		final Button tbbutton = toolkit.createButton(client, "Add tool bar",
 				SWT.CHECK);
+		
+		final Button albutton = toolkit.createButton(client, "Set tool bar allignment to SWT.BOTTOM",
+				SWT.CHECK);
+		albutton.addSelectionListener(new SelectionAdapter() {
+			public void widgetSelected(SelectionEvent e) {
+				form.getForm().setToolBarVerticalAlignment(albutton.getSelection()?SWT.BOTTOM:SWT.TOP);
+				form.reflow(true);
+			}
+		});
+		gd = new GridData();
+		gd.horizontalIndent = 10;
+		albutton.setLayoutData(gd);
+		albutton.setEnabled(false);
 		tbbutton.addSelectionListener(new SelectionAdapter() {
 			public void widgetSelected(SelectionEvent e) {
 				addToolBar(toolkit, form, tbbutton.getSelection());
+				albutton.setEnabled(tbbutton.getSelection());
 			}
 		});