merge_new_look_20040203
diff --git a/bundles/org.eclipse.jface/src/org/eclipse/jface/action/ContributionManager.java b/bundles/org.eclipse.jface/src/org/eclipse/jface/action/ContributionManager.java
index 0dd6b8d..7026e5d 100644
--- a/bundles/org.eclipse.jface/src/org/eclipse/jface/action/ContributionManager.java
+++ b/bundles/org.eclipse.jface/src/org/eclipse/jface/action/ContributionManager.java
@@ -363,6 +363,36 @@
 	dynamicItems = 0;
 	markDirty();
 }
+
+/**
+ * Replaces the item of the given identifier with another contribution item.
+ * This can be used, for example, to replace large contribution items with
+ * placeholders to avoid memory leaks.  If the identifier cannot be found in the
+ * current list of items, then this does nothing.
+ * @param identifier The identifier to look for in the list of contributions;
+ * should not be <code>null</code>.
+ * @param replacementItem The contribution item to replace the old item; must
+ * not be <code>null</code>.  Use {@link org.eclipse.jface.action.ContributionManager#remove(java.lang.String) remove} if that is what you want to do.
+ * @return <code>true</code> if the given identifier can be; <code>
+ * @since 3.0
+ */
+public boolean replaceItem(final String identifier, final IContributionItem replacementItem) {    
+    final int index = indexOf(identifier);
+    if (index < 0) {
+        return false; // couldn't find the item.
+    }
+    
+    // Remove the old item.
+	final IContributionItem oldItem = (IContributionItem) contributions.get(index);
+	itemRemoved(oldItem);
+	
+	// Add the new item.
+	contributions.set(index, replacementItem);
+	itemAdded(replacementItem); // throws NPE if (replacementItem == null)
+	
+	return true; // success
+}
+
 /**
  * Sets whether this manager is dirty. When dirty, the list of contributions 
  * is not accurately reflected in the corresponding widgets.
diff --git a/bundles/org.eclipse.jface/src/org/eclipse/jface/action/CoolBarManager.java b/bundles/org.eclipse.jface/src/org/eclipse/jface/action/CoolBarManager.java
index 9f5fb0e..68e2e1f 100644
--- a/bundles/org.eclipse.jface/src/org/eclipse/jface/action/CoolBarManager.java
+++ b/bundles/org.eclipse.jface/src/org/eclipse/jface/action/CoolBarManager.java
@@ -13,6 +13,7 @@
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.Iterator;
+import java.util.List;
 import java.util.ListIterator;
 
 import org.eclipse.swt.SWT;
@@ -27,8 +28,8 @@
 import org.eclipse.jface.util.Assert;
 
 /**
- * A cool bar manager is a contribution manager which realizes itself and its items
- * in a cool bar control.
+ * A cool bar manager is a contribution manager which realizes itself and its
+ * items in a cool bar control.
  * <p>
  * This class may be instantiated; it may also be subclassed.
  * </p>
@@ -36,793 +37,925 @@
  * @see #ICoolBarManager
  * @since 3.0
  */
-public class CoolBarManager extends ContributionManager implements ICoolBarManager {
+public class CoolBarManager extends ContributionManager implements
+        ICoolBarManager {
 
-	/** 
-	 * The cool bar items style; <code>SWT.NONE</code> by default.
-	 */
-	private int itemStyle = SWT.NONE;
-	
-	/**
-	 * A separator created by the end user.
-	 */
-	public final static String USER_SEPARATOR = "UserSeparator"; //$NON-NLS-1$
-	
-	/** 
-	 * The cool bar control; <code>null</code> before creation
-	 * and after disposal.
-	 */
-	private CoolBar coolBar = null;	
-	
-	/** 
-	 * MenuManager for cool bar pop-up menu, or null if none.
-	 */
-	private MenuManager contextMenuManager = null;
-	
-	/**
-	 * The original creation order of the contribution items.
-	 */
-	private ArrayList cbItemsCreationOrder = new ArrayList();
-	
-	/**
-	 * Creates a new cool bar manager with the default style.
-	 * Equivalent to <code>CoolBarManager(SWT.NONE)</code>.
-	 */
-	public CoolBarManager() {
-		// do nothing
-	}
-	
-	/**
-	 * Creates a cool bar manager with the given SWT style.
-	 * Calling <code>createControl</code> will create the cool bar control.
-	 *
-	 * @param style the cool bar item style; see 
-	 * {@link org.eclipse.swt.widgets.CoolBar CoolBar} for for valid style bits
-	 */
-	public CoolBarManager(int style) {
-		itemStyle= style;
-	}
-	
-	/**
-	 * Creates a cool bar manager for an existing cool bar control.
-	 * This manager becomes responsible for the control, and will
-	 * dispose of it when the manager is disposed.
-	 *
-	 * @param coolBar the cool bar control
-	 */
-	public CoolBarManager(CoolBar coolBar) {
-		this();
-		Assert.isNotNull(coolBar);
-		this.coolBar = coolBar;
-		itemStyle = coolBar.getStyle();
-	}
-	
-	/* (non-Javadoc)
-	 * @see org.eclipse.jface.action.ICoolBarManager#add(org.eclipse.jface.action.IToolBarManager)
-	 */
-	public void add(IToolBarManager toolBarManager) {
-		Assert.isNotNull(toolBarManager);
-		super.add(new ToolBarContributionItem(toolBarManager));
-	}
-	
-	/**
-	 * Creates and returns this manager's cool bar control. 
-	 * Does not create a new control if one already exists.
-	 *
-	 * @param parent the parent control
-	 * @return the cool bar control
-	 */
-	public CoolBar createControl(Composite parent) {
-		Assert.isNotNull(parent);
-		if (!coolBarExist()) {
-			coolBar = new CoolBar(parent, itemStyle);
-			coolBar.setMenu(getContextMenuControl());
-			coolBar.setLocked(false);
-			coolBar.addListener(SWT.Resize, new Listener() {
-				public void handleEvent(Event event) {
-					coolBar.getParent().layout();
-				}
-			});
-			update(false);
-		}
-		return coolBar;
-	}
-	
-	/**
-	 * Subclasses may extend this <code>ContributionManager</code> method, but
-	 * must call <code>super.itemAdded</code>.
-	 * 
-	 * @see org.eclipse.jface.action.ContributionManager#itemAdded(org.eclipse.jface.action.IContributionItem)
-	 */
-	protected void itemAdded(IContributionItem item) {
-		Assert.isNotNull(item);
-		super.itemAdded(item);
-		int insertedAt = indexOf(item);
-		cbItemsCreationOrder.add(Math.min(Math.max(insertedAt, 0), cbItemsCreationOrder.size()),item);
-	}
-	
-	/**
-	 * Restores the canonical order of this cool bar manager. The canonical order
-	 * is the order in which the contribution items where added.
-	 */
-	public void resetLayout() {
-		for (ListIterator iterator=cbItemsCreationOrder.listIterator();iterator.hasNext();) {
-			IContributionItem item = (IContributionItem)iterator.next();
-			// if its a user separator then do not include in original order.
-			if ( (item.getId() != null) && (item.getId().equals(USER_SEPARATOR)) ) {
-				iterator.remove();
-			}
-		}
-		setLayout(cbItemsCreationOrder);
-	}
-	
-	/**
-	 * Disposes of this cool bar manager and frees all allocated SWT resources.
-	 * Notifies all contribution items of the dispose. Note that this method does
-	 * not clean up references between this cool bar manager and its associated
-	 * contribution items. Use <code>removeAll</code> for that purpose.
-	 */
-	public void dispose() {
-		if (coolBarExist()) {
-			IContributionItem[] items = getItems();
-			for (int i=0; i<items.length; i++) {
-				// Disposes of the contribution item.
-				// If Contribution Item is a toolbar then it will dispose of all the nested
-				// contribution items.
-				items[i].dispose();
-			}
-			coolBar.dispose();
-			coolBar = null;
-		}
-		// If a context menu existed then dispose of it.
-		if (contextMenuManager != null) {
-			contextMenuManager.dispose();
-			contextMenuManager = null;
-		}
-		
-	}
-	
-	/**
-	 * Returns whether the cool bar control has been created
-	 * and not yet disposed.
-	 * 
-	 * @return <code>true</code> if the control has been created
-	 *	and not yet disposed, <code>false</code> otherwise
-	 */
-	private boolean coolBarExist() {
-		return coolBar != null && !coolBar.isDisposed(); 
-	}
-	
-	/**
-	 * Returns the cool bar control for this manager.
-	 *
-	 * @return the cool bar control, or <code>null</code> if none
-	 */
-	public CoolBar getControl() {
-		return coolBar;
-	}
-	
-	/**
-	 * Finds the cool item associated with the given contribution item.
-	 * 
-	 * @param item the contribution item
-	 * @return the associated cool item, or <code>null</code> if not found
-	 */
-	private CoolItem findCoolItem(IContributionItem item) {
-		if (coolBar == null) return null;
-		CoolItem[] items = coolBar.getItems();
-		for (int i = 0; i < items.length; i++) {
-			CoolItem coolItem = items[i];
-			IContributionItem data = (IContributionItem)coolItem.getData();
-			if (data != null && data.equals(item)) return coolItem;
-		}
-		return null;
-	}
-	
-	
-	/**
-	 * Disposes the given cool item.
-	 * 
-	 * @param item the cool item to dispose
-	 */
-	private void dispose(CoolItem item) {
-		if ((item != null) && !item.isDisposed()) {
-			
-			item.setData(null);
-			Control control = item.getControl();
-			// if the control is already disposed, setting the coolitem
-			// control to null will cause an SWT exception, workaround
-			// for 19630
-			if ((control != null) && !control.isDisposed()) {
-				item.setControl(null);
-			}
-			item.dispose();
-		}
-	}
+    /**
+     * The number of widgets above which the cool bar should have its redraw
+     * disabled. This is to reduce flicker.
+     */
+    private static final int REDRAW_LIMIT = 3;
 
-	/**
-	 * Subclasses may extend this <code>ContributionManager</code> method, but
-	 * must call <code>super.itemRemoved</code>.
-	 * 
-	 * @see org.eclipse.jface.action.ContributionManager#itemRemoved(org.eclipse.jface.action.IContributionItem)
-	 */
-	protected void itemRemoved(IContributionItem item) {
-		Assert.isNotNull(item);
-		super.itemRemoved(item);
-		CoolItem coolItem = findCoolItem(item);
-		if (coolItem != null) {
-			coolItem.setData(null);
-		}
-	}
-	
-	/**
-	 * Sets the tab order of the coolbar to the visual order of its items.
-	 */
-	/* package */ void updateTabOrder() {
-		if (coolBar != null) {
-			CoolItem[] items = coolBar.getItems();
-			if (items != null) {
-				ArrayList children = new ArrayList(items.length);
-				for(int i=0; i < items.length; i++) {
-					if ((items[i].getControl() != null) && (!items[i].getControl().isDisposed())) {
-						children.add(items[i].getControl());
-					}						
-				}
-				// Convert array
-				Control[] childrenArray = new Control[0];
-				childrenArray = (Control [])children.toArray(childrenArray);
-				
-				if (childrenArray != null) {
-					coolBar.setTabList(childrenArray);
-				}
-				
-			}
-		}
-	}
-	
-	/* (non-Javadoc)
-	 * @see org.eclipse.jface.action.ICoolBarManager#getStyle()
-	 */
-	public int getStyle() {
-		return itemStyle;
-	}
-	
-	/**
-	 * Return a consistent set of wrap indices.  The return value
-	 * will always include at least one entry and the first entry will 
-	 * always be zero.  CoolBar.getWrapIndices() is inconsistent 
-	 * in whether or not it returns an index for the first row.
-	 * 
-	 * @param wraps the wrap indicies from the cool bar widget
-	 * @return the adjusted wrap indicies.
-	 */
-	private int[] getAdjustedWrapIndices(int[] wraps) {
-		int[] adjustedWrapIndices;
-		if (wraps.length == 0) {
-			adjustedWrapIndices = new int[] { 0 };
-		} else {
-			if (wraps[0] != 0) {
-				adjustedWrapIndices = new int[wraps.length + 1];
-				adjustedWrapIndices[0] = 0;
-				for (int i = 0; i < wraps.length; i++) {
-					adjustedWrapIndices[i + 1] = wraps[i];
-				}
-			} else {
-				adjustedWrapIndices = wraps;
-			}
-		}
-		return adjustedWrapIndices;
-	}
-	
-	/**
-	 * Returns an array list of all the contribution items in the manager. 
-	 * @return an array list of contribution items.
-	 */
-	private ArrayList getItemList() {
-		IContributionItem[] cbItems = getItems();
-		ArrayList list = new ArrayList(cbItems.length);
-		for(int i=0; i < cbItems.length; i++) {
-			list.add(cbItems[i]);
-		}
-		return list;
-	}
-	
-	/**
-	 * Positions the list iterator to the starting of the next row. By calling
-	 * next on the returned iterator, it will return the first element of the
-	 * next row.
-	 * @param iterator the list iterator of contribution items
-	 */
-	private void nextRow(ListIterator iterator, boolean ignoreCurrentItem) {
-		
-		IContributionItem currentElement = null;
-		if (!ignoreCurrentItem && iterator.hasPrevious()) {
-			currentElement = (IContributionItem)iterator.previous();
-			iterator.next();
-		}
-		
-		if ((currentElement != null) && (currentElement.isSeparator() )) {
-			collapseSeparators(iterator);
-			return;
-		}
-		else {
-			//Find next separator
-			while (iterator.hasNext()) {
-				IContributionItem item = (IContributionItem)iterator.next();
-				if (item.isSeparator()) {
-					// we we find a separator, collapse any consecutive separators
-					// and return
-					collapseSeparators(iterator);
-					return;
-				}
-			}
-		}
-	}
-	
-	/**
-	 * Relocates the given contribution item to the specified index.
-	 * 
-	 * @param cbItem the conribution item to relocate
-	 * @param index the index to locate this item
-	 * @param contributionList the current list of conrtributions
-	 * @param itemLocation
-	 */
-	private void relocate(IContributionItem cbItem, int index, ArrayList contributionList, HashMap itemLocation) {
-		
-		if (!(itemLocation.get(cbItem) instanceof Integer)) return;
-		int targetRow = ((Integer)itemLocation.get(cbItem)).intValue();
-		
-		int cbInternalIndex = contributionList.indexOf(cbItem);	
+    /**
+     * A separator created by the end user.
+     */
+    public final static String USER_SEPARATOR = "UserSeparator"; //$NON-NLS-1$
 
-		//	by default add to end of list
-		int insertAt = 	contributionList.size();	
-		// Find the row to place this item in.
-		ListIterator iterator = contributionList.listIterator();
-		// bypass any separators at the begining
-		collapseSeparators(iterator);
-		int currentRow=-1;
-		while (iterator.hasNext()) {				
-			
-			currentRow++;
-			if (currentRow == targetRow) {
-				// We found the row to insert the item
-				int virtualIndex = 0;
-				insertAt = iterator.nextIndex();
-				// first check the position of the current element (item)
-				// then get the next element
-				while(iterator.hasNext()) {
-					IContributionItem item = (IContributionItem)iterator.next();
-					Integer itemRow = (Integer)itemLocation.get(item);
-					if (item.isSeparator()) break;
-					// if the item has an associate widget
-					if ( (itemRow != null) && (itemRow.intValue() == targetRow) ) {
-						// if the next element is the index we are looking for
-						// then break
-						if (virtualIndex >= index) break;
-						virtualIndex++;
-						
-					}
-					insertAt++;
-				}
-				// If we don't need to move it then we return
-				if (cbInternalIndex == insertAt) return;
-				break;
-			}
-			nextRow(iterator, true);	
-		}
-		contributionList.remove(cbItem);
-		
-		// Adjust insertAt index
-		if (cbInternalIndex < insertAt) {
-			insertAt--;
-		}
-		
-		// if we didn't find the row then add a new row
-		if (currentRow != targetRow) {
-			contributionList.add(new Separator(USER_SEPARATOR));
-			insertAt = contributionList.size();
-		}
-		insertAt = Math.min(insertAt, contributionList.size());
-		contributionList.add(insertAt,cbItem);
-			
-	}
-	
-	/**
-	 * Positions the list iterator to the end of all the separators. Calling
-	 * <code>next()</code> the iterator should return the immediate object following the last
-	 * separator.
-	 * @param iterator the list iterator.
-	 */
-	private void collapseSeparators(ListIterator iterator) {
-		
-		while (iterator.hasNext()) {
-			IContributionItem item = (IContributionItem)iterator.next();
-			if (!item.isSeparator()) {
-				iterator.previous();
-				return;
-			}
-		}
-	}
-	
-	/**
-	 * Colapses consecutive separators and removes a separator from the beginning and end of
-	 * the list.
-	 * @param contributionList the list of contributions
-	 */
-	private ArrayList adjustContributionList(ArrayList contributionList) {
-		IContributionItem item;
-		// Fist remove a separator if it is the first element of the list
-		if (contributionList.size() != 0) {
-			item = (IContributionItem)contributionList.get(0);
-			if (item.isSeparator()) {
-				contributionList.remove(0);
-			}
-		
-			ListIterator iterator = contributionList.listIterator();
-			// collapse consecutive separators
-			while (iterator.hasNext()) {
-				item = (IContributionItem)iterator.next();
-				if (item.isSeparator()) {
-					while (iterator.hasNext()) {
-						item = (IContributionItem)iterator.next();
-						if (item.isSeparator()) {
-							iterator.remove();
-						}else {
-							break;
-						}
-					}
-		
-				}
-			}
-			// Now check last element to see if there is a separator
-			item = (IContributionItem)contributionList.get(contributionList.size()-1);
-			if (item.isSeparator()) {
-				contributionList.remove(contributionList.size() - 1);
-			}
-		}
-		return contributionList;
-		
-	}
-	
-	/**
-	 * Synchronizes the visual order of the cool items in the control with 
-	 * this manager's internal data structures. This method should be called before 
-	 * requesting the order of the contribution items to ensure that the order is
-	 * accurate.
-	 * <p>
-	 * Note that <code>update()</code> and <code>refresh()</code> are converses:
-	 * <code>update()</code> changes the visual order to match the internal
-	 * structures, and <code>refresh</code> changes the internal structures to
-	 * match the visual order.
-	 * </p>
-	 */
-	public void refresh() {
-		
-		// Retreives the list of contribution items as an array list
-		ArrayList contributionList = getItemList();
-		
-		// Check the size of the list
-		if (contributionList.size() == 0) return;
-		
-		// The list of all the cool items in their visual order
-		CoolItem[] coolItems = coolBar.getItems();
-		// The wrap indicies of the coolbar
-		int[] wrapIndicies = getAdjustedWrapIndices(coolBar.getWrapIndices());
-		
-		int row = 0;
-		int lastRow = (wrapIndicies.length - 1);
-		int nextRow = row+1;
-		int coolItemIndex=0;
-		
-		// Traverse through all cool items in the coolbar add them to a new data structure
-		// in the correct order
-		ArrayList displayedItems = new ArrayList(coolBar.getItemCount());
-		for (int i=0; i < coolItems.length; i++) {
-			CoolItem coolItem = coolItems[i];
-			if (coolItem.getData() instanceof IContributionItem) {
-				IContributionItem cbItem = (IContributionItem)coolItem.getData();
-				displayedItems.add(Math.min(i,displayedItems.size()),cbItem);
-			}
-		}
-		
-		// Add separators to the displayed Items data structure
-		int offset = 0;
-		for(int i=1; i < wrapIndicies.length; i++) {
-			int insertAt = wrapIndicies[i] + offset;
-			displayedItems.add(insertAt,new Separator(USER_SEPARATOR));
-			offset++;
-		}
-		
-		// Determine which rows are invisible
-		ArrayList existingVisibleRows = new ArrayList(4);
-		ListIterator rowIterator=contributionList.listIterator();
-		collapseSeparators(rowIterator);
-		int numRow = 0;
-		while(rowIterator.hasNext()) {
-			// Scan row
-			while (rowIterator.hasNext()) {
-				IContributionItem cbItem = (IContributionItem)rowIterator.next();
-				if (displayedItems.contains(cbItem)) {
-					existingVisibleRows.add(new Integer(numRow));
-					break;
-				}
-				if (cbItem.isSeparator()) {
-					break;
-				}
-			}
-			nextRow(rowIterator, false);
-			numRow++;
-		}
-		
-		Iterator existingRows = existingVisibleRows.iterator();
-		// Adjust row number to the first visible
-		if (existingRows.hasNext()) {
-			row = ((Integer)existingRows.next()).intValue();
-		}
-		
-		HashMap itemLocation = new HashMap();
-		for(ListIterator locationIterator=displayedItems.listIterator();locationIterator.hasNext();) {
-			IContributionItem item = (IContributionItem)locationIterator.next();
-			if (item.isSeparator()) {
-				if (existingRows.hasNext()) {
-					Integer value = (Integer)existingRows.next();
-					row = value.intValue();
-				}else {
-					row++;
-				}
-			}else {
-				itemLocation.put(item,new Integer(row));
-			}
-			
-		}
-		
-		// Insert the contribution items in their correct location
-		for(ListIterator iterator=displayedItems.listIterator();iterator.hasNext();) {
-			IContributionItem cbItem = (IContributionItem)iterator.next();
-			if (cbItem.isSeparator()) {
-				coolItemIndex=0;
-			}else {
-				relocate(cbItem, coolItemIndex, contributionList, itemLocation);
-				cbItem.saveWidgetState();
-				coolItemIndex++;
-			}
-		}
-	
-		if (contributionList.size() != 0) {
-			contributionList = adjustContributionList(contributionList);
-			IContributionItem[] array = new IContributionItem[contributionList.size()-1];
-			array = (IContributionItem[])contributionList.toArray(array);
-			internalSetItems(array);
-		}
-		
-	}
+    /**
+     * The original creation order of the contribution items.
+     */
+    private ArrayList cbItemsCreationOrder = new ArrayList();
 
-	/*
-	 * Used for debuging. Prints all the items in the internal structures.
-	 */
-	private void printContributions(ArrayList contributionList) {
-		int index = 0;
-		System.out.println("----------------------------------\n"); //$NON-NLS-1$
-		for (Iterator i = contributionList.iterator();i.hasNext();index++) {
-			IContributionItem item = (IContributionItem)i.next();
-			if (item.isSeparator()) {
-				System.out.println("Separator"); //$NON-NLS-1$
-			}else  {
-				System.out.println(index + ". Item id: " + item.getId() + " - is Visible: " + item.isVisible());  //$NON-NLS-1$//$NON-NLS-2$
-			}
-		}
-	}
-	
+    /**
+     * MenuManager for cool bar pop-up menu, or null if none.
+     */
+    private MenuManager contextMenuManager = null;
 
-	/**
-	 * Subclasses may extend this <code>IContributionManager</code> method, but
-	 * must call <code>super.update</code>.
-	 * 
-	 * @see org.eclipse.jface.action.IContributionManager#update(boolean)
-	 */
-	public void update(boolean force) {
-		if (isDirty() || force) {
-			if (coolBarExist()) {
-				boolean useRedraw = false;
-				boolean relock = false;
-				boolean changed = false;
-				try {
-					
-					coolBar.setRedraw(false);
-					
-					//1. Refresh the widget data with the internal data structure
-					refresh();
+    /**
+     * The cool bar control; <code>null</code> before creation and after
+     * disposal.
+     */
+    private CoolBar coolBar = null;
 
-					// 2: Fill in all the contribution items that do not have widgets
-					int fillIndex = 0;
-					boolean incrementCount = true;
-					CoolItem[] coolItems = coolBar.getItems();	
-					IContributionItem[] contributionItems = this.getItems();
-					for (int i=0; i < contributionItems.length; i++) {
-						contributionItems[i].update(ICoolBarManager.VISIBILITY);
-						// only valid contribution items a.k.a. no place markers, no group markers or separators and only visible contribution items
-						if ((contributionItems[i].isVisible()) && (!contributionItems[i].isGroupMarker()) 
-							&& (!contributionItems[i].isSeparator())) {
-							incrementCount = true;
-							// Find the widget that is associated with this contribution item
-							CoolItem item = findCoolItem(contributionItems[i]);
-							if (item == null) {
-								int prevItemCount = coolBar.getItemCount();
-								if (changed == false) {
-									if (coolBar.getLocked()) {
-										// workaround for 14330
-										coolBar.setLocked(false);
-										relock = true;
-									}
-									changed = true;
-								}
-								// guarantee fillIndex < coolBar.getItemCount()
-								fillIndex = Math.min(fillIndex,coolBar.getItemCount());
-								contributionItems[i].fill(coolBar,fillIndex);
-								
-								if (prevItemCount >= coolBar.getItemCount()) {
-									incrementCount = false;
-								}
-							}
-							// This index is needed so that we don't count invisible items and items
-							// that don't fill anything.
-							if (incrementCount) {
-								fillIndex++;
-							}
-						}
-					}
-					
-					// 3: Remove widgets without contribution items
-					for (int coolItemIndex=0; coolItemIndex < coolItems.length; coolItemIndex++) {
-						CoolItem coolItem = coolItems[coolItemIndex];
-						IContributionItem foundItem = (IContributionItem)coolItems[coolItemIndex].getData();
-						
-						// Dispose of widget if not needed
-						if ((foundItem == null) || (!foundItem.isVisible())) {	
-							// dispose the widget
-							foundItem.dispose();
-							changed = true;
-						}
-						
-					}
-					
-					// 4. Handle wrap indicies
-					int numRows = getNumRows(contributionItems)-1;
-					int[] wrapIndicies = new int[numRows];
-					int j = 0;
-					boolean foundSeparator = false;
-					for (int i=0; i < contributionItems.length; i++) {
-						IContributionItem item = contributionItems[i];
-						CoolItem coolItem = findCoolItem(item);
-						if (item.isSeparator()) {
-							foundSeparator = true;
-						}
-						if ((!item.isSeparator()) && (!item.isGroupMarker()) && (item.isVisible()) && (coolItem != null) && (foundSeparator)) {
-							wrapIndicies[j] = coolBar.indexOf(coolItem);
-							j++;
-							foundSeparator=false;
-						}
-					}
-					// Set the new wrap indicies
-					coolBar.setWrapIndices(wrapIndicies);
-					
-					
-					// 5. update the sizes
-					for (int i=0; i < contributionItems.length; i++) {
-						IContributionItem item = contributionItems[i];
-						item.update(SIZE);
-					}
-					
-					// if the coolBar was previously locked then lock it
-					if (relock) coolBar.setLocked(true);
-					
-					if (changed) {
-						updateTabOrder();
-					}
-					setDirty(false);
-				} finally {
-					coolBar.setRedraw(true);
-				}
-				
-			} // if (coolBarExist())
-		}// if (isDirty() || force) 
-	}
-	
-	/**
-	 * Returns the number of rows that should be displayed visually.
-	 * 
-	 * @param items the array of contributin items
-	 * @return the number of rows
-	 */
-	private int getNumRows(IContributionItem[] items) {
-		int numRows = 1;
-		boolean separatorFound = false;
-		for (int i=0; i < items.length; i++) {
-			if (items[i].isSeparator()) {
-				separatorFound = true;
-			}
-			if ((separatorFound) && (items[i].isVisible()) && (!items[i].isGroupMarker()) && (!items[i].isSeparator()) ) {
-				numRows++;
-				separatorFound = false;
-			}
-		}
-		return numRows;
-	}
-	
-	/**
-	 * Returns the control of the Menu Manager. If the menu manager does not have a control
-	 * then one is created.
-	 * 
-	 * @return menu control associated with manager, or null if none
-	 */
-	private Menu getContextMenuControl() {
-		if ((contextMenuManager != null) && (coolBar != null) ) {			
-			Menu menuWidget = contextMenuManager.getMenu();
-			if ((menuWidget == null) || (menuWidget.isDisposed())) {
-				menuWidget = contextMenuManager.createContextMenu(coolBar);
-			}
-			return menuWidget;
-		}
-		return null;
-	}
-	
-	/* (non-Javadoc)
-	 * @see org.eclipse.jface.action.ICoolBarManager#isLayoutLocked()
-	 */
-	public IMenuManager getContextMenuManager() {
-		return contextMenuManager;
-	}
+    /**
+     * The cool bar items style; <code>SWT.NONE</code> by default.
+     */
+    private int itemStyle = SWT.NONE;
 
-	/* (non-Javadoc)
-	 * @see org.eclipse.jface.action.ICoolBarManager#setContextMenuManager(org.eclipse.jface.action.IMenuManager)
-	 */
-	public void setContextMenuManager(IMenuManager contextMenuManager) {
-		this.contextMenuManager = (MenuManager)contextMenuManager;
-		if (coolBar != null) {
-			coolBar.setMenu(getContextMenuControl());
-		}
-	}
-	
-	/*
-	 *  (non-Javadoc)
-	 * @see org.eclipse.jface.action.ICoolBarManager#isLayoutLocked()
-	 */
-	public boolean getLockLayout() {
-		if (!coolBarExist()) {
-			return false;
-		}
-		return coolBar.getLocked();
-	}
-	
-	/*
-	 *  (non-Javadoc)
-	 * @see org.eclipse.jface.action.ICoolBarManager#lockLayout(boolean)
-	 */
-	public void setLockLayout(boolean value) {
-		if (!coolBarExist()) {
-			return;
-		}
-		coolBar.setLocked(value);
-	}
-	
-	/**
-	 * Replaces the internal data structure with the given new order. Then force
-	 * and update.
-	 * @param newLayout a list of new order of contribution items.
-	 */
-	public void setLayout(ArrayList newLayout) {
-		IContributionItem[] newItems = new IContributionItem[0];
-		newItems = (IContributionItem[])newLayout.toArray(newItems);
-		// dispose of all the cool items on the cool bar manager
-		if (coolBar != null) {
-			CoolItem[] coolItems = coolBar.getItems();
-			for (int i=0; i < coolItems.length; i++) {
-				dispose(coolItems[i]);
-			}
-		}
-		// Set the internal structure to this order
-		internalSetItems(newItems);
-		// Force and update
-		update(true);
-	}
+    /**
+     * Creates a new cool bar manager with the default style. Equivalent to
+     * <code>CoolBarManager(SWT.NONE)</code>.
+     */
+    public CoolBarManager() {
+        // do nothing
+    }
+
+    /**
+     * Creates a cool bar manager for an existing cool bar control. This
+     * manager becomes responsible for the control, and will dispose of it when
+     * the manager is disposed.
+     * 
+     * @param coolBar
+     *            the cool bar control
+     */
+    public CoolBarManager(CoolBar coolBar) {
+        this();
+        Assert.isNotNull(coolBar);
+        this.coolBar = coolBar;
+        itemStyle = coolBar.getStyle();
+    }
+
+    /**
+     * Creates a cool bar manager with the given SWT style. Calling <code>createControl</code>
+     * will create the cool bar control.
+     * 
+     * @param style
+     *            the cool bar item style; see
+     *            {@link org.eclipse.swt.widgets.CoolBar CoolBar}for for valid
+     *            style bits
+     */
+    public CoolBarManager(int style) {
+        itemStyle = style;
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see org.eclipse.jface.action.ICoolBarManager#add(org.eclipse.jface.action.IToolBarManager)
+     */
+    public void add(IToolBarManager toolBarManager) {
+        Assert.isNotNull(toolBarManager);
+        super.add(new ToolBarContributionItem(toolBarManager));
+    }
+
+    /**
+     * Colapses consecutive separators and removes a separator from the
+     * beginning and end of the list.
+     * 
+     * @param contributionList
+     *            the list of contributions
+     */
+    private ArrayList adjustContributionList(ArrayList contributionList) {
+        IContributionItem item;
+        // Fist remove a separator if it is the first element of the list
+        if (contributionList.size() != 0) {
+            item = (IContributionItem) contributionList.get(0);
+            if (item.isSeparator()) {
+                contributionList.remove(0);
+            }
+
+            ListIterator iterator = contributionList.listIterator();
+            // collapse consecutive separators
+            while (iterator.hasNext()) {
+                item = (IContributionItem) iterator.next();
+                if (item.isSeparator()) {
+                    while (iterator.hasNext()) {
+                        item = (IContributionItem) iterator.next();
+                        if (item.isSeparator()) {
+                            iterator.remove();
+                        } else {
+                            break;
+                        }
+                    }
+
+                }
+            }
+            // Now check last element to see if there is a separator
+            item = (IContributionItem) contributionList.get(contributionList
+                    .size() - 1);
+            if (item.isSeparator()) {
+                contributionList.remove(contributionList.size() - 1);
+            }
+        }
+        return contributionList;
+
+    }
+
+    /**
+     * Positions the list iterator to the end of all the separators. Calling
+     * <code>next()</code> the iterator should return the immediate object
+     * following the last separator.
+     * 
+     * @param iterator
+     *            the list iterator.
+     */
+    private void collapseSeparators(ListIterator iterator) {
+
+        while (iterator.hasNext()) {
+            IContributionItem item = (IContributionItem) iterator.next();
+            if (!item.isSeparator()) {
+                iterator.previous();
+                return;
+            }
+        }
+    }
+
+    /**
+     * Returns whether the cool bar control has been created and not yet
+     * disposed.
+     * 
+     * @return <code>true</code> if the control has been created and not yet
+     *         disposed, <code>false</code> otherwise
+     */
+    private boolean coolBarExist() {
+        return coolBar != null && !coolBar.isDisposed();
+    }
+
+    /**
+     * Creates and returns this manager's cool bar control. Does not create a
+     * new control if one already exists.
+     * 
+     * @param parent
+     *            the parent control
+     * @return the cool bar control
+     */
+    public CoolBar createControl(Composite parent) {
+        Assert.isNotNull(parent);
+        if (!coolBarExist()) {
+            coolBar = new CoolBar(parent, itemStyle);
+            coolBar.setMenu(getContextMenuControl());
+            coolBar.setLocked(false);
+            coolBar.addListener(SWT.Resize, new Listener() {
+
+                public void handleEvent(Event event) {
+                    coolBar.getParent().layout();
+                }
+            });
+            update(false);
+        }
+        return coolBar;
+    }
+
+    /**
+     * Disposes of this cool bar manager and frees all allocated SWT resources.
+     * Notifies all contribution items of the dispose. Note that this method
+     * does not clean up references between this cool bar manager and its
+     * associated contribution items. Use <code>removeAll</code> for that
+     * purpose.
+     */
+    public void dispose() {
+        if (coolBarExist()) {
+            IContributionItem[] items = getItems();
+            for (int i = 0; i < items.length; i++) {
+                // Disposes of the contribution item.
+                // If Contribution Item is a toolbar then it will dispose of
+                // all the nested
+                // contribution items.
+                items[i].dispose();
+            }
+            coolBar.dispose();
+            coolBar = null;
+        }
+        // If a context menu existed then dispose of it.
+        if (contextMenuManager != null) {
+            contextMenuManager.dispose();
+            contextMenuManager = null;
+        }
+
+    }
+
+    /**
+     * Disposes the given cool item.
+     * 
+     * @param item
+     *            the cool item to dispose
+     */
+    private void dispose(CoolItem item) {
+        if ((item != null) && !item.isDisposed()) {
+
+            item.setData(null);
+            Control control = item.getControl();
+            // if the control is already disposed, setting the coolitem
+            // control to null will cause an SWT exception, workaround
+            // for 19630
+            if ((control != null) && !control.isDisposed()) {
+                item.setControl(null);
+            }
+            item.dispose();
+        }
+    }
+
+    /**
+     * Finds the cool item associated with the given contribution item.
+     * 
+     * @param item
+     *            the contribution item
+     * @return the associated cool item, or <code>null</code> if not found
+     */
+    private CoolItem findCoolItem(IContributionItem item) {
+        if (coolBar == null) return null;
+        CoolItem[] items = coolBar.getItems();
+        for (int i = 0; i < items.length; i++) {
+            CoolItem coolItem = items[i];
+            IContributionItem data = (IContributionItem) coolItem.getData();
+            if (data != null && data.equals(item)) return coolItem;
+        }
+        return null;
+    }
+
+    /**
+     * Return a consistent set of wrap indices. The return value will always
+     * include at least one entry and the first entry will always be zero.
+     * CoolBar.getWrapIndices() is inconsistent in whether or not it returns an
+     * index for the first row.
+     * 
+     * @param wraps
+     *            the wrap indicies from the cool bar widget
+     * @return the adjusted wrap indicies.
+     */
+    private int[] getAdjustedWrapIndices(int[] wraps) {
+        int[] adjustedWrapIndices;
+        if (wraps.length == 0) {
+            adjustedWrapIndices = new int[] { 0};
+        } else {
+            if (wraps[0] != 0) {
+                adjustedWrapIndices = new int[wraps.length + 1];
+                adjustedWrapIndices[0] = 0;
+                for (int i = 0; i < wraps.length; i++) {
+                    adjustedWrapIndices[i + 1] = wraps[i];
+                }
+            } else {
+                adjustedWrapIndices = wraps;
+            }
+        }
+        return adjustedWrapIndices;
+    }
+
+    /**
+     * Returns the control of the Menu Manager. If the menu manager does not
+     * have a control then one is created.
+     * 
+     * @return menu control associated with manager, or null if none
+     */
+    private Menu getContextMenuControl() {
+        if ((contextMenuManager != null) && (coolBar != null)) {
+            Menu menuWidget = contextMenuManager.getMenu();
+            if ((menuWidget == null) || (menuWidget.isDisposed())) {
+                menuWidget = contextMenuManager.createContextMenu(coolBar);
+            }
+            return menuWidget;
+        }
+        return null;
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see org.eclipse.jface.action.ICoolBarManager#isLayoutLocked()
+     */
+    public IMenuManager getContextMenuManager() {
+        return contextMenuManager;
+    }
+
+    /**
+     * Returns the cool bar control for this manager.
+     * 
+     * @return the cool bar control, or <code>null</code> if none
+     */
+    public CoolBar getControl() {
+        return coolBar;
+    }
+
+    /**
+     * Returns an array list of all the contribution items in the manager.
+     * 
+     * @return an array list of contribution items.
+     */
+    private ArrayList getItemList() {
+        IContributionItem[] cbItems = getItems();
+        ArrayList list = new ArrayList(cbItems.length);
+        for (int i = 0; i < cbItems.length; i++) {
+            list.add(cbItems[i]);
+        }
+        return list;
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see org.eclipse.jface.action.ICoolBarManager#isLayoutLocked()
+     */
+    public boolean getLockLayout() {
+        if (!coolBarExist()) { return false; }
+        return coolBar.getLocked();
+    }
+
+    /**
+     * Returns the number of rows that should be displayed visually.
+     * 
+     * @param items
+     *            the array of contributin items
+     * @return the number of rows
+     */
+    private int getNumRows(IContributionItem[] items) {
+        int numRows = 1;
+        boolean separatorFound = false;
+        for (int i = 0; i < items.length; i++) {
+            if (items[i].isSeparator()) {
+                separatorFound = true;
+            }
+            if ((separatorFound) && (items[i].isVisible())
+                    && (!items[i].isGroupMarker()) && (!items[i].isSeparator())) {
+                numRows++;
+                separatorFound = false;
+            }
+        }
+        return numRows;
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see org.eclipse.jface.action.ICoolBarManager#getStyle()
+     */
+    public int getStyle() {
+        return itemStyle;
+    }
+
+    /**
+     * Subclasses may extend this <code>ContributionManager</code> method,
+     * but must call <code>super.itemAdded</code>.
+     * 
+     * @see org.eclipse.jface.action.ContributionManager#itemAdded(org.eclipse.jface.action.IContributionItem)
+     */
+    protected void itemAdded(IContributionItem item) {
+        Assert.isNotNull(item);
+        super.itemAdded(item);
+        int insertedAt = indexOf(item);
+        boolean replaced = false;
+        final int size = cbItemsCreationOrder.size();
+        for (int i = 0; i < size; i++) {
+            IContributionItem created = (IContributionItem) cbItemsCreationOrder.get(i);
+            if (created.getId() != null && created.getId().equals(item.getId())) {
+                cbItemsCreationOrder.set(i, item);
+                replaced = true;
+                break;
+            }
+        }
+        
+        if (!replaced) { 
+            cbItemsCreationOrder.add(Math.min(Math.max(insertedAt, 0),
+                    cbItemsCreationOrder.size()), item);
+        }
+    }
+
+    /**
+     * Subclasses may extend this <code>ContributionManager</code> method,
+     * but must call <code>super.itemRemoved</code>.
+     * 
+     * @see org.eclipse.jface.action.ContributionManager#itemRemoved(org.eclipse.jface.action.IContributionItem)
+     */
+    protected void itemRemoved(IContributionItem item) {
+        Assert.isNotNull(item);
+        super.itemRemoved(item);
+        CoolItem coolItem = findCoolItem(item);
+        if (coolItem != null) {
+            coolItem.setData(null);
+        }
+    }
+
+    /**
+     * Positions the list iterator to the starting of the next row. By calling
+     * next on the returned iterator, it will return the first element of the
+     * next row.
+     * 
+     * @param iterator
+     *            the list iterator of contribution items
+     */
+    private void nextRow(ListIterator iterator, boolean ignoreCurrentItem) {
+
+        IContributionItem currentElement = null;
+        if (!ignoreCurrentItem && iterator.hasPrevious()) {
+            currentElement = (IContributionItem) iterator.previous();
+            iterator.next();
+        }
+
+        if ((currentElement != null) && (currentElement.isSeparator())) {
+            collapseSeparators(iterator);
+            return;
+        } else {
+            //Find next separator
+            while (iterator.hasNext()) {
+                IContributionItem item = (IContributionItem) iterator.next();
+                if (item.isSeparator()) {
+                    // we we find a separator, collapse any consecutive
+                    // separators
+                    // and return
+                    collapseSeparators(iterator);
+                    return;
+                }
+            }
+        }
+    }
+
+    /*
+     * Used for debuging. Prints all the items in the internal structures.
+     */
+    private void printContributions(ArrayList contributionList) {
+        int index = 0;
+        System.out.println("----------------------------------\n"); //$NON-NLS-1$
+        for (Iterator i = contributionList.iterator(); i.hasNext(); index++) {
+            IContributionItem item = (IContributionItem) i.next();
+            if (item.isSeparator()) {
+                System.out.println("Separator"); //$NON-NLS-1$
+            } else {
+                System.out.println(index + ". Item id: " + item.getId()
+                        + " - is Visible: " //$NON-NLS-1$//$NON-NLS-2$
+                        + item.isVisible());
+            }
+        }
+    }
+
+    /**
+     * Synchronizes the visual order of the cool items in the control with this
+     * manager's internal data structures. This method should be called before
+     * requesting the order of the contribution items to ensure that the order
+     * is accurate.
+     * <p>
+     * Note that <code>update()</code> and <code>refresh()</code> are
+     * converses: <code>update()</code> changes the visual order to match the
+     * internal structures, and <code>refresh</code> changes the internal
+     * structures to match the visual order.
+     * </p>
+     */
+    public void refresh() {
+
+        // Retreives the list of contribution items as an array list
+        ArrayList contributionList = getItemList();
+
+        // Check the size of the list
+        if (contributionList.size() == 0) return;
+
+        // The list of all the cool items in their visual order
+        CoolItem[] coolItems = coolBar.getItems();
+        // The wrap indicies of the coolbar
+        int[] wrapIndicies = getAdjustedWrapIndices(coolBar.getWrapIndices());
+
+        int row = 0;
+        int coolItemIndex = 0;
+
+        // Traverse through all cool items in the coolbar add them to a new
+        // data structure
+        // in the correct order
+        ArrayList displayedItems = new ArrayList(coolBar.getItemCount());
+        for (int i = 0; i < coolItems.length; i++) {
+            CoolItem coolItem = coolItems[i];
+            if (coolItem.getData() instanceof IContributionItem) {
+                IContributionItem cbItem = (IContributionItem) coolItem
+                        .getData();
+                displayedItems.add(Math.min(i, displayedItems.size()), cbItem);
+            }
+        }
+
+        // Add separators to the displayed Items data structure
+        int offset = 0;
+        for (int i = 1; i < wrapIndicies.length; i++) {
+            int insertAt = wrapIndicies[i] + offset;
+            displayedItems.add(insertAt, new Separator(USER_SEPARATOR));
+            offset++;
+        }
+
+        // Determine which rows are invisible
+        ArrayList existingVisibleRows = new ArrayList(4);
+        ListIterator rowIterator = contributionList.listIterator();
+        collapseSeparators(rowIterator);
+        int numRow = 0;
+        while (rowIterator.hasNext()) {
+            // Scan row
+            while (rowIterator.hasNext()) {
+                IContributionItem cbItem = (IContributionItem) rowIterator
+                        .next();
+                if (displayedItems.contains(cbItem)) {
+                    existingVisibleRows.add(new Integer(numRow));
+                    break;
+                }
+                if (cbItem.isSeparator()) {
+                    break;
+                }
+            }
+            nextRow(rowIterator, false);
+            numRow++;
+        }
+
+        Iterator existingRows = existingVisibleRows.iterator();
+        // Adjust row number to the first visible
+        if (existingRows.hasNext()) {
+            row = ((Integer) existingRows.next()).intValue();
+        }
+
+        HashMap itemLocation = new HashMap();
+        for (ListIterator locationIterator = displayedItems.listIterator(); locationIterator
+                .hasNext();) {
+            IContributionItem item = (IContributionItem) locationIterator
+                    .next();
+            if (item.isSeparator()) {
+                if (existingRows.hasNext()) {
+                    Integer value = (Integer) existingRows.next();
+                    row = value.intValue();
+                } else {
+                    row++;
+                }
+            } else {
+                itemLocation.put(item, new Integer(row));
+            }
+
+        }
+
+        // Insert the contribution items in their correct location
+        for (ListIterator iterator = displayedItems.listIterator(); iterator
+                .hasNext();) {
+            IContributionItem cbItem = (IContributionItem) iterator.next();
+            if (cbItem.isSeparator()) {
+                coolItemIndex = 0;
+            } else {
+                relocate(cbItem, coolItemIndex, contributionList, itemLocation);
+                cbItem.saveWidgetState();
+                coolItemIndex++;
+            }
+        }
+
+        if (contributionList.size() != 0) {
+            contributionList = adjustContributionList(contributionList);
+            IContributionItem[] array = new IContributionItem[contributionList
+                    .size() - 1];
+            array = (IContributionItem[]) contributionList.toArray(array);
+            internalSetItems(array);
+        }
+
+    }
+
+    /**
+     * Relocates the given contribution item to the specified index.
+     * 
+     * @param cbItem
+     *            the conribution item to relocate
+     * @param index
+     *            the index to locate this item
+     * @param contributionList
+     *            the current list of conrtributions
+     * @param itemLocation
+     */
+    private void relocate(IContributionItem cbItem, int index,
+            ArrayList contributionList, HashMap itemLocation) {
+
+        if (!(itemLocation.get(cbItem) instanceof Integer)) return;
+        int targetRow = ((Integer) itemLocation.get(cbItem)).intValue();
+
+        int cbInternalIndex = contributionList.indexOf(cbItem);
+
+        //	by default add to end of list
+        int insertAt = contributionList.size();
+        // Find the row to place this item in.
+        ListIterator iterator = contributionList.listIterator();
+        // bypass any separators at the begining
+        collapseSeparators(iterator);
+        int currentRow = -1;
+        while (iterator.hasNext()) {
+
+            currentRow++;
+            if (currentRow == targetRow) {
+                // We found the row to insert the item
+                int virtualIndex = 0;
+                insertAt = iterator.nextIndex();
+                // first check the position of the current element (item)
+                // then get the next element
+                while (iterator.hasNext()) {
+                    IContributionItem item = (IContributionItem) iterator
+                            .next();
+                    Integer itemRow = (Integer) itemLocation.get(item);
+                    if (item.isSeparator()) break;
+                    // if the item has an associate widget
+                    if ((itemRow != null) && (itemRow.intValue() == targetRow)) {
+                        // if the next element is the index we are looking for
+                        // then break
+                        if (virtualIndex >= index) break;
+                        virtualIndex++;
+
+                    }
+                    insertAt++;
+                }
+                // If we don't need to move it then we return
+                if (cbInternalIndex == insertAt) return;
+                break;
+            }
+            nextRow(iterator, true);
+        }
+        contributionList.remove(cbItem);
+
+        // Adjust insertAt index
+        if (cbInternalIndex < insertAt) {
+            insertAt--;
+        }
+
+        // if we didn't find the row then add a new row
+        if (currentRow != targetRow) {
+            contributionList.add(new Separator(USER_SEPARATOR));
+            insertAt = contributionList.size();
+        }
+        insertAt = Math.min(insertAt, contributionList.size());
+        contributionList.add(insertAt, cbItem);
+
+    }
+
+    /**
+     * Restores the canonical order of this cool bar manager. The canonical
+     * order is the order in which the contribution items where added.
+     */
+    public void resetLayout() {
+        for (ListIterator iterator = cbItemsCreationOrder.listIterator(); iterator
+                .hasNext();) {
+            IContributionItem item = (IContributionItem) iterator.next();
+            // if its a user separator then do not include in original order.
+            if ((item.getId() != null) && (item.getId().equals(USER_SEPARATOR))) {
+                iterator.remove();
+            }
+        }
+        setLayout(cbItemsCreationOrder);
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see org.eclipse.jface.action.ICoolBarManager#setContextMenuManager(org.eclipse.jface.action.IMenuManager)
+     */
+    public void setContextMenuManager(IMenuManager contextMenuManager) {
+        this.contextMenuManager = (MenuManager) contextMenuManager;
+        if (coolBar != null) {
+            coolBar.setMenu(getContextMenuControl());
+        }
+    }
+
+    /**
+     * Replaces the internal data structure with the given new order. Then
+     * force and update.
+     * 
+     * @param newLayout
+     *            a list of new order of contribution items.
+     */
+    public void setLayout(ArrayList newLayout) {
+        IContributionItem[] newItems = new IContributionItem[0];
+        newItems = (IContributionItem[]) newLayout.toArray(newItems);
+        // dispose of all the cool items on the cool bar manager
+        if (coolBar != null) {
+            CoolItem[] coolItems = coolBar.getItems();
+            for (int i = 0; i < coolItems.length; i++) {
+                dispose(coolItems[i]);
+            }
+        }
+        // Set the internal structure to this order
+        internalSetItems(newItems);
+        // Force and update
+        update(true);
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see org.eclipse.jface.action.ICoolBarManager#lockLayout(boolean)
+     */
+    public void setLockLayout(boolean value) {
+        if (!coolBarExist()) { return; }
+        coolBar.setLocked(value);
+    }
+
+    /**
+     * Subclasses may extend this <code>IContributionManager</code> method,
+     * but must call <code>super.update</code>.
+     * 
+     * @see org.eclipse.jface.action.IContributionManager#update(boolean)
+     */
+    public void update(boolean force) {
+        if ((!isDirty() && !force) || (!coolBarExist())) { return; }
+
+        boolean relock = false;
+        boolean changed = false;
+
+        try {
+            // Refresh the widget data with the internal data structure.
+            refresh();
+
+            if (coolBar.getLocked()) {
+                coolBar.setLocked(false);
+                relock = true;
+            }
+
+            /*
+             * Make a list of items including only those items that are
+             * visible. Separators should stay because they mark line breaks in
+             * a cool bar.
+             */
+            final IContributionItem[] items = getItems();
+            final List visibleItems = new ArrayList(items.length);
+            for (int i = 0; i < items.length; i++) {
+                final IContributionItem item = items[i];
+                if (item.isVisible()) {
+                    visibleItems.add(item);
+                }
+            }
+
+            /*
+             * Make a list of CoolItem widgets in the cool bar for which there
+             * is no current visible contribution item. These are the widgets
+             * to be disposed. Dynamic items are also removed.
+             */
+            CoolItem[] coolItems = coolBar.getItems();
+            final ArrayList coolItemsToRemove = new ArrayList(coolItems.length);
+            for (int i = 0; i < coolItems.length; i++) {
+                final Object data = coolItems[i].getData();
+                if ((data == null)
+                        || (!visibleItems.contains(data))
+                        || ((data instanceof IContributionItem) && ((IContributionItem) data)
+                                .isDynamic())) {
+                    coolItemsToRemove.add(coolItems[i]);
+                }
+            }
+
+            /*
+             * Redraw is turned off if the number of items to be added is above
+             * a certain threshold -- minimizing flicker. It is assumed that
+             * each contribution item will contribute at least one tool bar
+             * item.
+             */
+            final boolean useRedraw = (visibleItems.size() - (coolItems.length - coolItemsToRemove
+                    .size())) >= REDRAW_LIMIT;
+            if (useRedraw) {
+                coolBar.setRedraw(false);
+            }
+
+            // Dispose of any items in the list to be removed.
+            for (int i = coolItemsToRemove.size() - 1; i >= 0; i--) {
+                CoolItem coolItem = (CoolItem) coolItemsToRemove.get(i);
+                if (!coolItem.isDisposed()) {
+                    Control control = coolItem.getControl();
+                    if (control != null) {
+                        coolItem.setControl(null);
+                        control.dispose();
+                    }
+                    coolItem.dispose();
+                }
+            }
+
+            // Add any new items by telling them to fill.
+            coolItems = coolBar.getItems();
+            IContributionItem sourceItem;
+            IContributionItem destinationItem;
+            int sourceIndex = 0;
+            int destinationIndex = 0;
+            final Iterator visibleItemItr = visibleItems.iterator();
+            while (visibleItemItr.hasNext()) {
+                sourceItem = (IContributionItem) visibleItemItr.next();
+
+                // Retrieve the corresponding contribution item from SWT's
+                // data.
+                if (sourceIndex < coolItems.length) {
+                    destinationItem = (IContributionItem) coolItems[sourceIndex]
+                            .getData();
+                } else {
+                    destinationItem = null;
+                }
+
+                // The items match is they are equal or both separators.
+                if (destinationItem != null) {
+                    if (sourceItem.equals(destinationItem)) {
+                        sourceIndex++;
+                        destinationIndex++;
+                        continue;
+
+                    } else if ((destinationItem.isSeparator())
+                            && (sourceItem.isSeparator())) {
+                        coolItems[sourceIndex].setData(sourceItem);
+                        sourceIndex++;
+                        destinationIndex++;
+                        continue;
+
+                    }
+                }
+
+                // Otherwise, a new item has to be added.
+                final int start = coolBar.getItemCount();
+                sourceItem.fill(coolBar, destinationIndex);
+                final int newItems = coolBar.getItemCount() - start;
+                for (int i = 0; i < newItems; i++) {
+                    coolBar.getItem(destinationIndex++).setData(sourceItem);
+                }
+                changed = true;
+            }
+
+            // Remove any old widgets not accounted for.
+            for (int i = coolItems.length - 1; i >= sourceIndex; i--) {
+                final CoolItem item = coolItems[i];
+                if (!item.isDisposed()) {
+                    Control control = item.getControl();
+                    if (control != null) {
+                        item.setControl(null);
+                        control.dispose();
+                    }
+                    item.dispose();
+                    changed = true;
+                }
+            }
+
+            // Turn redraw back on if we turned it off above
+            if (useRedraw) {
+                coolBar.setRedraw(true);
+            }
+
+            // Update the wrap indices.
+            final int numRows = getNumRows(items) - 1;
+            final int[] wrapIndices = new int[numRows];
+            int j = 0;
+            boolean foundSeparator = false;
+            for (int i = 0; i < items.length; i++) {
+                IContributionItem item = items[i];
+                CoolItem coolItem = findCoolItem(item);
+                if (item.isSeparator()) {
+                    foundSeparator = true;
+                }
+                if ((!item.isSeparator()) && (!item.isGroupMarker())
+                        && (item.isVisible()) && (coolItem != null)
+                        && (foundSeparator)) {
+                    wrapIndices[j] = coolBar.indexOf(coolItem);
+                    j++;
+                    foundSeparator = false;
+                }
+            }
+            coolBar.setWrapIndices(wrapIndices);
+
+            // Update the sizes.
+            for (int i = 0; i < items.length; i++) {
+                IContributionItem item = items[i];
+                item.update(SIZE);
+            }
+
+            // if the coolBar was previously locked then lock it
+            if (relock) {
+                coolBar.setLocked(true);
+            }
+
+            if (changed) {
+                updateTabOrder();
+            }
+
+            // We are no longer dirty.
+            setDirty(false);
+        } finally {
+            coolBar.setRedraw(true);
+        }
+    }
+
+    /**
+     * Sets the tab order of the coolbar to the visual order of its items.
+     */
+    /* package */void updateTabOrder() {
+        if (coolBar != null) {
+            CoolItem[] items = coolBar.getItems();
+            if (items != null) {
+                ArrayList children = new ArrayList(items.length);
+                for (int i = 0; i < items.length; i++) {
+                    if ((items[i].getControl() != null)
+                            && (!items[i].getControl().isDisposed())) {
+                        children.add(items[i].getControl());
+                    }
+                }
+                // Convert array
+                Control[] childrenArray = new Control[0];
+                childrenArray = (Control[]) children.toArray(childrenArray);
+
+                if (childrenArray != null) {
+                    coolBar.setTabList(childrenArray);
+                }
+
+            }
+        }
+    }
 }
diff --git a/bundles/org.eclipse.jface/src/org/eclipse/jface/action/ICoolBarManager.java b/bundles/org.eclipse.jface/src/org/eclipse/jface/action/ICoolBarManager.java
index 02bad2f..68b79db 100644
--- a/bundles/org.eclipse.jface/src/org/eclipse/jface/action/ICoolBarManager.java
+++ b/bundles/org.eclipse.jface/src/org/eclipse/jface/action/ICoolBarManager.java
@@ -12,98 +12,90 @@
 
 /**
  * The <code>ICoolBarManager</code> interface provides protocol for managing
- * contributions to a cool bar. A cool bar manager delegates responsibility
- * for creating child controls to its contribution items by calling 
+ * contributions to a cool bar. A cool bar manager delegates responsibility for
+ * creating child controls to its contribution items by calling
  * {@link IContributionItem#fillCoolBar IContributionItem.fillCoolBar}}.
  * <p>
- * This interface is internal to the framework; it should not be implemented outside
- * the framework. This package provides a concrete cool bar manager implementation,
- * {@link CoolBarManager <code>CoolBarManager</code>}, which clients may
- * instantiate or subclass.
+ * This interface is internal to the framework; it should not be implemented
+ * outside the framework. This package provides a concrete cool bar manager
+ * implementation, {@link CoolBarManager <code>CoolBarManager</code>}, which
+ * clients may instantiate or subclass.
  * </p>
  * 
  * @see ToolBarContributionItem
  * @since 3.0
  */
 public interface ICoolBarManager extends IContributionManager {
-	
-	/**
-	 * Property name of a cool item's size (value <code>"size"</code>).
-	 * <p>
-	 * The cool bar manager uses this property to tell its cool items
-	 * to update their size.
-	 * </p>
-	 * 
-	 * @see IContributionItem#update(String)
-	 * @issue consider declaring this constant elsewhere
-	 */
-	public static final String SIZE = "size"; //$NON-NLS-1$
-	
-	/**
-	 * Property name of a cool item's visiblity (value <code>"visibility"</code>).
-	 * <p>
-	 * The cool bar manager uses this property to tell its cool items
-	 * to update their visibility.
-	 * </p>
-	 * 
-	 * @see IContributionItem#update(String)
-	 * @issue consider declaring this constant elsewhere
-	 */
-	public static final String VISIBILITY = "visibility"; //$NON-NLS-1$
-	
-	/**
-	 * A convenience method to add a tool bar as a contribution item to
-	 * this cool bar manager.
-	 * Equivalent to <code>add(new ToolBarContributionManager(toolBarManager))</code>.
-	 * 
-	 * @param toolBarManager the tool bar manager to be added 
-	 * @see ToolBarContributionItem
-	 */
-	public void add(IToolBarManager toolBarManager);
-	
-	/**
-	 * Returns the style of the underlying cool bar widget.
-	 * 
-	 * @return the style of the cool bar
-	 */
-	public int getStyle();
-	
-	/**
-	 * Returns whether the layout of the underlying cool bar widget is locked.
-	 * 
-	 * @return <code>true</code> if cool bar layout is locked, 
-	 * <code>false</code> otherwise
-	 */
-	public boolean getLockLayout();
-	
-	/**
-	 * Locks or unlocks the layout of the underlying cool bar widget.
-	 * Once the cool bar is locked, cool items cannot be repositioned by the user.
-	 * <p>
-	 * Note that items can be added or removed programmatically even while
-	 * the cool bar is locked.
-	 * </p>
-	 * 
-	 * @param value <code>true</code> to lock the cool bar, <code>false</code> to unlock
-	 */
-	public void setLockLayout(boolean value);
-	
-	/**
-	 * Returns the context menu manager used by this cool bar manager. This context menu
-	 * manager is used by the cool bar manager except for cool items that provide 
-	 * their own.
-	 * 
-	 * @return the context menu manager, or <code>null</code> if none
-	 * @see #setContextMenuManager
-	 */
-	public IMenuManager getContextMenuManager();
-	
-	/**
-	 * Sets the context menu of this cool bar manager to the given menu manager.
-	 * 
-	 * @param menuManager the context menu manager, or <code>null</code> if none
-	 * @see #getContextMenuManager
-	 */
-	public void setContextMenuManager(IMenuManager menuManager);
-	
+
+    /**
+     * Property name of a cool item's size (value <code>"size"</code>).
+     * <p>
+     * The cool bar manager uses this property to tell its cool items to update
+     * their size.
+     * </p>
+     * 
+     * @see IContributionItem#update(String) @issue consider declaring this
+     *      constant elsewhere
+     */
+    public static final String SIZE = "size"; //$NON-NLS-1$
+
+    /**
+     * A convenience method to add a tool bar as a contribution item to this
+     * cool bar manager. Equivalent to <code>add(new ToolBarContributionManager(toolBarManager))</code>.
+     * 
+     * @param toolBarManager
+     *            the tool bar manager to be added
+     * @see ToolBarContributionItem
+     */
+    public void add(IToolBarManager toolBarManager);
+
+    /**
+     * Returns the context menu manager used by this cool bar manager. This
+     * context menu manager is used by the cool bar manager except for cool
+     * items that provide their own.
+     * 
+     * @return the context menu manager, or <code>null</code> if none
+     * @see #setContextMenuManager
+     */
+    public IMenuManager getContextMenuManager();
+
+    /**
+     * Returns whether the layout of the underlying cool bar widget is locked.
+     * 
+     * @return <code>true</code> if cool bar layout is locked, <code>false</code>
+     *         otherwise
+     */
+    public boolean getLockLayout();
+
+    /**
+     * Returns the style of the underlying cool bar widget.
+     * 
+     * @return the style of the cool bar
+     */
+    public int getStyle();
+
+    /**
+     * Sets the context menu of this cool bar manager to the given menu
+     * manager.
+     * 
+     * @param menuManager
+     *            the context menu manager, or <code>null</code> if none
+     * @see #getContextMenuManager
+     */
+    public void setContextMenuManager(IMenuManager menuManager);
+
+    /**
+     * Locks or unlocks the layout of the underlying cool bar widget. Once the
+     * cool bar is locked, cool items cannot be repositioned by the user.
+     * <p>
+     * Note that items can be added or removed programmatically even while the
+     * cool bar is locked.
+     * </p>
+     * 
+     * @param value
+     *            <code>true</code> to lock the cool bar, <code>false</code>
+     *            to unlock
+     */
+    public void setLockLayout(boolean value);
+
 }
diff --git a/bundles/org.eclipse.jface/src/org/eclipse/jface/action/ToolBarContributionItem.java b/bundles/org.eclipse.jface/src/org/eclipse/jface/action/ToolBarContributionItem.java
index 17f34a6..3244260 100644
--- a/bundles/org.eclipse.jface/src/org/eclipse/jface/action/ToolBarContributionItem.java
+++ b/bundles/org.eclipse.jface/src/org/eclipse/jface/action/ToolBarContributionItem.java
@@ -11,7 +11,6 @@
 
 package org.eclipse.jface.action;
 
-import org.eclipse.jface.util.Assert;
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.events.DisposeEvent;
 import org.eclipse.swt.events.DisposeListener;
@@ -28,11 +27,13 @@
 import org.eclipse.swt.widgets.ToolBar;
 import org.eclipse.swt.widgets.ToolItem;
 
+import org.eclipse.jface.util.Assert;
+
 /**
- * The <code>ToolBarContributionItem</code> class provides a wrapper for tool bar
- * managers when used in cool bar managers. It extends <code>ContributionItem</code>
- * but and provides some additional methods to customize the size of the cool item
- * and to retrieve the underlying tool bar manager.
+ * The <code>ToolBarContributionItem</code> class provides a wrapper for tool
+ * bar managers when used in cool bar managers. It extends <code>ContributionItem</code>
+ * but and provides some additional methods to customize the size of the cool
+ * item and to retrieve the underlying tool bar manager.
  * <p>
  * This class may be instantiated; it is not intended to be subclassed.
  * </p>
@@ -40,510 +41,536 @@
  * @since 3.0
  */
 public class ToolBarContributionItem extends ContributionItem {
-	
-	/**
-	 * A constant used by <code>setMinimumItemsToShow</code> and <code>getMinimumItemsToShow</code>
-	 * to indicate that all tool items should be shown in the cool item.
-	 */
-	public static final int SHOW_ALL_ITEMS = -1;
-	
-	/**
-	 * The tool bar manager used to manage the tool items contained in the cool item widget.
-	 */
-	private ToolBarManager toolBarManager = null;
-	
-	/**
-	 * The pull down menu used to list all hidden tool items if the current size is less than
-	 * the preffered size.
-	 */
-	private MenuManager chevronMenuManager = null;
-	
-	/**
-	 * The context menu of the cool item. If one is not defined the the parents context menu
-	 * is used.
-	 */
-	private MenuManager contextMenuManager = null;
-	
-	/**
-	 * Mininum number of tool items to show in the cool item widget.
-	 */
-	private int minimumItemsToShow = SHOW_ALL_ITEMS;
-	
-	/**
-	 * Enable/disable chevron support.
-	 */
-	private boolean useChevron = true;
-	
-	/**
-	 * Current width of cool item. 
-	 */
-	private int currentWidth = -1;
-	
-	/**
-	 * Current height of cool item
-	 */
-	private int currentHeight = -1;
-	
-	/**
-	 * The widget created for this item; <code>null</code>
-	 * before creation and after disposal.
-	 */
-	private CoolItem coolItem = null;
-	
-	/**
-	 * Creates a tool bar contribution item.
-	 * 
-	 * @param toolBarManager the tool bar manager to wrap
-	 * @param id the contribution item id, or <code>null</code> if none
-	 */
-	public ToolBarContributionItem(IToolBarManager toolBarManager, String id) {
-		super(id);
-		Assert.isTrue(toolBarManager instanceof ToolBarManager);
-		this.toolBarManager = (ToolBarManager)toolBarManager;
-	}
-	
-	/**
-	 * Convenience method equivalent to 
-	 * <code>ToolBarContributionItem(toolBarManager, null)</code>.
-	 * 
-	 * @param toolBarManager the tool bar manager
-	 */
-	public ToolBarContributionItem(IToolBarManager toolBarManager) {
-		this(toolBarManager,null);
-	}
-	
-	/**
-	 * Convenience method equivalent to
-	 * <code>ToolBarContributionItem(new ToolBarManager(), null)</code>.
-	 */
-	public ToolBarContributionItem() {
-		this(new ToolBarManager(), null);
-	}
-	
-	/**
-	 * Returns the internal tool bar manager of the contribution item.
-	 * 
-	 * @return the tool bar manager, or <code>null</code> if one is not defined.
-	 * @see IToolBarManager
-	 */
-	public IToolBarManager getToolBarManager() {
-		return toolBarManager;
-	}
 
-	/** 
-	 * Returns a consistent set of wrap indices. The return value
-	 * will always include at least one entry and the first entry will 
-	 * always be zero.  CoolBar.getWrapIndices() is inconsistent 
-	 * in whether or not it returns an index for the first row.
-	 */
-	private int[] getAdjustedWrapIndices(int[] wraps) {
-		int[] adjustedWrapIndices;
-		if (wraps.length == 0) {
-			adjustedWrapIndices = new int[] { 0 };
-		} else {
-			if (wraps[0] != 0) {
-				adjustedWrapIndices = new int[wraps.length + 1];
-				adjustedWrapIndices[0] = 0;
-				for (int i = 0; i < wraps.length; i++) {
-					adjustedWrapIndices[i + 1] = wraps[i];
-				}
-			} else {
-				adjustedWrapIndices = wraps;
-			}
-		}
-		return adjustedWrapIndices;
-	}
-	
-	/*
-	 * (non-Javadoc)
-	 * @see org.eclipse.jface.action.IContributionItem#fill(org.eclipse.swt.widgets.CoolBar, int)
-	 */
-	public void fill(CoolBar coolBar, int index) {
-	   if (coolItem == null && coolBar != null) {
-	   	   ToolBar toolBar = toolBarManager.createControl(coolBar);
-		   //toolBarManager.update(true);
-		   // Do not create a coolItem if the toolbar is empty
-		   if (toolBar.getItemCount() < 1) return;
-		   int flags = SWT.DROP_DOWN;
-		   if (index >= 0) {
-		   		coolItem = new CoolItem(coolBar, flags, index);
-		   }else {
-		   		coolItem = new CoolItem(coolBar, flags);
-		   }
-		   // sets the back reference   
-		   coolItem.setData(this);
-		   // Add the toolbar to the CoolItem widget
-		   coolItem.setControl(toolBar);   
-		   
-		   // Handle Context Menu
-		   toolBar.addListener(SWT.MenuDetect, new Listener() {
-			   public void handleEvent(Event event) {
-			   		// if the toolbar does not have its own context menu then
-			   	 	// handle the event
-					 if (toolBarManager.getContextMenuManager() == null) {   
-					 	handleContextMenu(event);
-					 }
-			   }
-		   });
-		   
-		   // Handle for chevron clicking
-		   if (getUseChevron()) {
-			   // Chevron Support
-			   coolItem.addSelectionListener(new SelectionAdapter() {
-				   	public void widgetSelected(SelectionEvent event) {
-				   		if (event.detail == SWT.ARROW) {
-				   			handleChevron(event);
-				   		}
-				   	}
-			   });
-		   }
-		   
-		   // Handle for disposal
-		   coolItem.addDisposeListener(new DisposeListener() {
-				public void widgetDisposed(DisposeEvent event) {
-					handleWidgetDispose(event);
-				}
-		   });
-		   
-		   // Sets the size of the coolItem
-		   updateSize(true);
-	   }
-	}
-	
-	/**
-	 * Handles the event when the toobar item does not have its own context menu.
-	 * @param event the event object
-	 */
-	private void handleContextMenu(Event event) {
-		ToolBar toolBar = toolBarManager.getControl();
-		// If parent has a menu then use that one
-		Menu parentMenu = toolBar.getParent().getMenu();
-		if ((parentMenu != null) && (!parentMenu.isDisposed())) {
-			toolBar.setMenu(parentMenu);
-			// Hook listener to remove menu once it has disapeared
-			parentMenu.addListener(SWT.Hide, new Listener(){
-				public void handleEvent(Event event) {
-					ToolBar toolBar = toolBarManager.getControl();
-					if (toolBar != null) {
-						toolBar.setMenu(null);
-						Menu parentMenu = toolBar.getParent().getMenu();
-						if (parentMenu != null) {
-							parentMenu.removeListener(SWT.Hide,this);
-						}
-					}
-				}
-			});
-		}
-	}
-	
-	/**
-	 * Handles the disposal of the widget.
-	 * @param event the event object
-	 */
-	private void handleWidgetDispose(DisposeEvent event) {
-		coolItem = null;	
-	}
-	
-	
-	/* (non-Javadoc)
-	 * @see org.eclipse.jface.action.IContributionItem#saveWidgetState()
-	 */
-	public void saveWidgetState() {
-		if (coolItem == null)  return;
-		
-		//1. Save current size
-		CoolBar coolBar = coolItem.getParent();
-		boolean isLastOnRow = false;
-		int lastIndex = coolBar.getItemCount() - 1;
-		int coolItemIndex = coolBar.indexOf(coolItem);
-		int [] wrapIndicies = getAdjustedWrapIndices(coolBar.getWrapIndices());
-		// Traverse through all wrap indicies backwards
-		for (int row=wrapIndicies.length-1; row >= 0; row--) {
-			if (wrapIndicies[row] <= coolItemIndex) {
+    /**
+     * A constant used by <code>setMinimumItemsToShow</code> and <code>getMinimumItemsToShow</code>
+     * to indicate that all tool items should be shown in the cool item.
+     */
+    public static final int SHOW_ALL_ITEMS = -1;
 
-				int nextRow = row + 1;
-				int rowStartIndex = wrapIndicies[row];
-				int nextRowStartIndex;
-				if (nextRow > (wrapIndicies.length - 1) ) {
-					nextRowStartIndex = lastIndex + 1;
-				}else {
-					nextRowStartIndex = wrapIndicies[nextRow];
-				}
-				 
-				// Check to see if its the last item on the row
-				if (coolItemIndex == (nextRowStartIndex -1)) {
-					isLastOnRow = true;
-				}
-				boolean isAloneOnRow = ((rowStartIndex == coolItemIndex) && isLastOnRow);
-				break;
-			 }
-		 }
-		
-		// Save the preferred size as actual size for the last item on a row
-		int nCurrentWidth;
-		if (isLastOnRow) {
-			nCurrentWidth = coolItem.getPreferredSize().x;
-		}else {
-			nCurrentWidth = coolItem.getSize().x;
-		}
-		setCurrentWidth(nCurrentWidth);
-		setCurrentHeight(coolItem.getSize().y);
-	}
-	
-	/*
-	 * (non-Javadoc)
-	 * @see org.eclipse.jface.action.IContributionItem#dispose()
-	 */
-	public void dispose() {
-		
-		// Dispose of the ToolBar and all its contributions
-		if (toolBarManager != null) {
-			toolBarManager.dispose();
-		}
-		
-		/* 
-		 * We need to dispose the cool item or we might be left holding a cool 
-		 * item with a disposed control.
-		 */
-		if ((coolItem != null) && (!coolItem.isDisposed())) {
-			coolItem.dispose();
-		}
-		
-	}
-	
-	/**
-	 * Updates the cool items' preferred, minimum, and current size. The preferred
-	 * size is calculated based on the tool bar size and extra trim.
-	 * 
-	 * @param changeCurrentSize <code>true</code> if the current size should be changed
-	 * to the preferred size, <code>false</code> to not change the current size
-	 */
-	public void updateSize(boolean changeCurrentSize) {
-		// cannot set size if coolItem is null
-		if (coolItem == null || coolItem.isDisposed()) {
-			return;
-		}
-		boolean locked = false;
-		CoolBar coolBar = coolItem.getParent();
-		try {	
-			// Fix odd behaviour with locked tool bars
-			if (coolBar != null) {
-				if (coolBar.getLocked() == true) {
-					coolBar.setLocked(false);
-					locked = true;
-				}
-			}
-			ToolBar toolBar = (ToolBar)coolItem.getControl();
-			if ( (toolBar == null) || (toolBar.isDisposed()) || (toolBar.getItemCount() <= 0) ) {	
-				// if the toolbar does not contain any items then dispose of coolItem
-				coolItem.setData(null);
-				Control control = coolItem.getControl();
-				if ((control != null) && !control.isDisposed()) {
-					control.dispose();
-					coolItem.setControl(null);
-				}
-				if (!coolItem.isDisposed()) {
-					coolItem.dispose();
-				}
-			}else {
-				// If the toolbar item exists then adjust the size of the cool item
-				Point toolBarSize = toolBar.computeSize(SWT.DEFAULT, SWT.DEFAULT);
-				// Set the preffered size to the size of the toolbar plus trim
-				Point prefferedSize = coolItem.computeSize(toolBarSize.x, toolBarSize.y);
-				coolItem.setPreferredSize(prefferedSize);
-				// note setMinimumSize must be called before setSize, see PR 15565
-				// Set minimum size
-				if (getMinimumItemsToShow() != SHOW_ALL_ITEMS) {
-					int toolItemWidth = toolBar.getItems()[1].getWidth();
-					int minimumWidth = toolItemWidth * getMinimumItemsToShow();
-					coolItem.setMinimumSize(minimumWidth, toolBarSize.y);
-				}else {
-					coolItem.setMinimumSize(toolBarSize.x, toolBarSize.y);
-				}
-				if (changeCurrentSize) {
-					// Set current size to preffered size
-					coolItem.setSize(prefferedSize);
-				}
-			}
-		} finally {
-			// If the cool bar was locked, then set it back to locked
-			if ((locked) && (coolBar != null) ) {
-				coolBar.setLocked(true);
-			}
-		}
-	}
-	
-	/**
-	 * Create and display the chevron menu.
-	 */
-	private void handleChevron(SelectionEvent event) {
-		CoolItem item = (CoolItem) event.widget;
-		Control control = item.getControl();
-		if ((control instanceof ToolBar) == false) {
-			return;
-		}
-		CoolBar coolBar = item.getParent();
-		Point chevronPosition = coolBar.toDisplay(new Point(event.x, event.y));
-		ToolBar toolBar = (ToolBar) control;
-		ToolItem[] tools = toolBar.getItems();
-		int toolCount = tools.length;
-		int visibleItemCount = 0;
-		while (visibleItemCount < toolCount) {
-			Rectangle toolBounds = tools[visibleItemCount].getBounds();
-			Point point = toolBar.toDisplay(new Point(toolBounds.x, toolBounds.y));
-			toolBounds.x = point.x;
-			toolBounds.y = point.y;
-			// stop if the tool is at least partially hidden by the drop down chevron
-			if (chevronPosition.x >= toolBounds.x && chevronPosition.x - toolBounds.x <= toolBounds.width) {
-				break;
-			}
-			visibleItemCount++;
-		}
+    /**
+     * The pull down menu used to list all hidden tool items if the current
+     * size is less than the preffered size.
+     */
+    private MenuManager chevronMenuManager = null;
 
-		// Create a pop-up menu with items for each of the hidden buttons.
-		if (chevronMenuManager != null) {
-			chevronMenuManager.dispose();
-		}
-		chevronMenuManager = new MenuManager();
-		for (int i = visibleItemCount; i < toolCount; i++) {
-			IContributionItem data = (IContributionItem) tools[i].getData();
-			if (data instanceof ActionContributionItem) {
-				ActionContributionItem contribution = new ActionContributionItem(((ActionContributionItem) data).getAction());
-				chevronMenuManager.add(contribution);
-			} else if (data instanceof SubContributionItem) {
-				IContributionItem innerData = ((SubContributionItem)data).getInnerItem();
-				if (innerData instanceof ActionContributionItem) {
-					ActionContributionItem contribution = new ActionContributionItem(((ActionContributionItem) innerData).getAction());
-					chevronMenuManager.add(contribution);
-				}
-			} else if (data.isSeparator()) {
-				chevronMenuManager.add(new Separator());
-			}
-		}
-		Menu popup = chevronMenuManager.createContextMenu(coolBar);
-		popup.setLocation(chevronPosition.x, chevronPosition.y);
-		popup.setVisible(true);
-	}
-	
+    /**
+     * The widget created for this item; <code>null</code> before creation
+     * and after disposal.
+     */
+    private CoolItem coolItem = null;
 
-	/* (non-Javadoc)
-	 * @see org.eclipse.jface.action.IContributionItem#update(java.lang.String)
-	 */
-	public void update(String propertyName) {
-		if (coolItem != null) {	
-			boolean sizeChanged = (propertyName == null) || propertyName.equals(CoolBarManager.SIZE);
-			
-			if (sizeChanged) {
-				updateSize(true);
-			}
-			
-		}
-		// Sets its own visibility depending on whether there exist any items in 
-		// tool bar manager that are visible
-		if (propertyName.equals(CoolBarManager.VISIBILITY)) {
-			// if there is no visible items in our tool bar
-			if (toolBarManager != null) {
-				IContributionItem[] items = toolBarManager.getItems();
-				boolean visibleItem = false;
-				for (int i=0; i < items.length; i++) {
-					if ((!items[i].isGroupMarker()) && (!items[i].isSeparator()) && (items[i].isVisible())) {
-						visibleItem = true;
-						break;
-					}
-				}
-				if (!visibleItem) {
-					setVisible(false);
-				}else {
-					setVisible(true);
-					if (getParent() != null) {
-						getParent().markDirty();
-					}
-				}
-			}
-			
-		}
-	}
+    /**
+     * Current height of cool item
+     */
+    private int currentHeight = -1;
 
+    /**
+     * Current width of cool item.
+     */
+    private int currentWidth = -1;
 
-	/**
-	 * Returns the minimum number of tool items to show in the cool item.
-	 * 
-	 * @return the minimum number of tool items to show,
-	 * or <code>SHOW_ALL_ITEMS</code> if a value was not set
-	 * @see #setMinimumItemsToShow(int)
-	 */
-	public int getMinimumItemsToShow() {
-		return minimumItemsToShow;
-	}
+    /**
+     * Mininum number of tool items to show in the cool item widget.
+     */
+    private int minimumItemsToShow = SHOW_ALL_ITEMS;
 
-	/**
-	 * Sets the minimum number of tool items to show in the cool item. If this number is less
-	 * than the total tool items, a chevron will appear and the hidden tool items appear in a 
-	 * drop down menu. By default, all the tool items are shown in the cool item.
-	 * 
-	 * @param minimumItemsToShow the minimum number of tool items to show. 
-	 * @see #getMinimumItemsToShow()
-	 * @see #setUseChevron(boolean)
-	 */
-	public void setMinimumItemsToShow(int minimumItemsToShow) {
-		this.minimumItemsToShow = minimumItemsToShow;
-	}
-	
-	/**
-	 * Enables or disables chevron support for the cool item. By default, chevron support is 
-	 * enabled.
-	 * 
-	 * @param value <code>true</code> to enable chevron support, <code>false</code> otherwise.
-	 */
-	public void setUseChevron(boolean value) {
-		useChevron = value;	
-	}
-	
-	/**
-	 * Returns whether chevron support is enabled.
-	 * 
-	 * @return <code>true</code> if chevron support is enabled, <code>false</code> otherwise
-	 */
-	public boolean getUseChevron() {
-		return useChevron;
-	}
+    /**
+     * The tool bar manager used to manage the tool items contained in the cool
+     * item widget.
+     */
+    private ToolBarManager toolBarManager = null;
 
-	/**
-	 * Returns the current width of the corresponding cool item.
-	 * 
-	 * @return the current size
-	 */
-	public int getCurrentWidth() {
-		return currentWidth;
-	}
-	
-	/**
-	 * Returns the current height of the corresponding cool item.
-	 * 
-	 * @return the current height
-	 */
-	public int getCurrentHeight() {
-		return currentHeight;
-	}
-	
-	/**
-	 * Sets the current height of the cool item. 
-	 * Update(SIZE) should be called to adjust the widget.
-	 * 
-	 * @param currentHeight the current height to set
-	 */
-	public void setCurrentHeight(int currentHeight) {
-		this.currentHeight = currentHeight;
-	}
-	
-	/**
-	 * Sets the current width of the cool item. 
-	 * Update(SIZE) should be called to adjust the widget.
-	 * 
-	 * @param currentWidth the current width to set
-	 */
-	public void setCurrentWidth(int currentWidth) {
-		this.currentWidth = currentWidth;
-	}
+    /**
+     * Enable/disable chevron support.
+     */
+    private boolean useChevron = true;
+
+    /**
+     * Convenience method equivalent to <code>ToolBarContributionItem(new ToolBarManager(), null)</code>.
+     */
+    public ToolBarContributionItem() {
+        this(new ToolBarManager(), null);
+    }
+
+    /**
+     * Convenience method equivalent to <code>ToolBarContributionItem(toolBarManager, null)</code>.
+     * 
+     * @param toolBarManager
+     *            the tool bar manager
+     */
+    public ToolBarContributionItem(IToolBarManager toolBarManager) {
+        this(toolBarManager, null);
+    }
+
+    /**
+     * Creates a tool bar contribution item.
+     * 
+     * @param toolBarManager
+     *            the tool bar manager to wrap
+     * @param id
+     *            the contribution item id, or <code>null</code> if none
+     */
+    public ToolBarContributionItem(IToolBarManager toolBarManager, String id) {
+        super(id);
+        Assert.isTrue(toolBarManager instanceof ToolBarManager);
+        this.toolBarManager = (ToolBarManager) toolBarManager;
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see org.eclipse.jface.action.IContributionItem#dispose()
+     */
+    public void dispose() {
+        // Dispose of the ToolBar and all its contributions
+        if (toolBarManager != null) {
+            toolBarManager.dispose();
+            toolBarManager = null;
+        }
+
+        /*
+         * We need to dispose the cool item or we might be left holding a cool
+         * item with a disposed control.
+         */
+        if ((coolItem != null) && (!coolItem.isDisposed())) {
+            coolItem.dispose();
+            coolItem = null;
+        }
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see org.eclipse.jface.action.IContributionItem#fill(org.eclipse.swt.widgets.CoolBar,
+     *      int)
+     */
+    public void fill(CoolBar coolBar, int index) {
+        if (coolItem == null && coolBar != null) {
+            ToolBar toolBar = toolBarManager.createControl(coolBar);
+            //toolBarManager.update(true);
+            // Do not create a coolItem if the toolbar is empty
+            if (toolBar.getItemCount() < 1) return;
+            int flags = SWT.DROP_DOWN;
+            if (index >= 0) {
+                coolItem = new CoolItem(coolBar, flags, index);
+            } else {
+                coolItem = new CoolItem(coolBar, flags);
+            }
+            // sets the back reference
+            coolItem.setData(this);
+            // Add the toolbar to the CoolItem widget
+            coolItem.setControl(toolBar);
+
+            // Handle Context Menu
+            toolBar.addListener(SWT.MenuDetect, new Listener() {
+
+                public void handleEvent(Event event) {
+                    // if the toolbar does not have its own context menu then
+                    // handle the event
+                    if (toolBarManager.getContextMenuManager() == null) {
+                        handleContextMenu(event);
+                    }
+                }
+            });
+
+            // Handle for chevron clicking
+            if (getUseChevron()) {
+                // Chevron Support
+                coolItem.addSelectionListener(new SelectionAdapter() {
+
+                    public void widgetSelected(SelectionEvent event) {
+                        if (event.detail == SWT.ARROW) {
+                            handleChevron(event);
+                        }
+                    }
+                });
+            }
+
+            // Handle for disposal
+            coolItem.addDisposeListener(new DisposeListener() {
+
+                public void widgetDisposed(DisposeEvent event) {
+                    handleWidgetDispose(event);
+                }
+            });
+
+            // Sets the size of the coolItem
+            updateSize(true);
+        }
+    }
+
+    /**
+     * Returns a consistent set of wrap indices. The return value will always
+     * include at least one entry and the first entry will always be zero.
+     * CoolBar.getWrapIndices() is inconsistent in whether or not it returns an
+     * index for the first row.
+     */
+    private int[] getAdjustedWrapIndices(int[] wraps) {
+        int[] adjustedWrapIndices;
+        if (wraps.length == 0) {
+            adjustedWrapIndices = new int[] { 0};
+        } else {
+            if (wraps[0] != 0) {
+                adjustedWrapIndices = new int[wraps.length + 1];
+                adjustedWrapIndices[0] = 0;
+                for (int i = 0; i < wraps.length; i++) {
+                    adjustedWrapIndices[i + 1] = wraps[i];
+                }
+            } else {
+                adjustedWrapIndices = wraps;
+            }
+        }
+        return adjustedWrapIndices;
+    }
+
+    /**
+     * Returns the current height of the corresponding cool item.
+     * 
+     * @return the current height
+     */
+    public int getCurrentHeight() {
+        return currentHeight;
+    }
+
+    /**
+     * Returns the current width of the corresponding cool item.
+     * 
+     * @return the current size
+     */
+    public int getCurrentWidth() {
+        return currentWidth;
+    }
+
+    /**
+     * Returns the minimum number of tool items to show in the cool item.
+     * 
+     * @return the minimum number of tool items to show, or <code>SHOW_ALL_ITEMS</code>
+     *         if a value was not set
+     * @see #setMinimumItemsToShow(int)
+     */
+    public int getMinimumItemsToShow() {
+        return minimumItemsToShow;
+    }
+
+    /**
+     * Returns the internal tool bar manager of the contribution item.
+     * 
+     * @return the tool bar manager, or <code>null</code> if one is not
+     *         defined.
+     * @see IToolBarManager
+     */
+    public IToolBarManager getToolBarManager() {
+        return toolBarManager;
+    }
+
+    /**
+     * Returns whether chevron support is enabled.
+     * 
+     * @return <code>true</code> if chevron support is enabled, <code>false</code>
+     *         otherwise
+     */
+    public boolean getUseChevron() {
+        return useChevron;
+    }
+
+    /**
+     * Create and display the chevron menu.
+     */
+    private void handleChevron(SelectionEvent event) {
+        CoolItem item = (CoolItem) event.widget;
+        Control control = item.getControl();
+        if ((control instanceof ToolBar) == false) { return; }
+        CoolBar coolBar = item.getParent();
+        Point chevronPosition = coolBar.toDisplay(new Point(event.x, event.y));
+        ToolBar toolBar = (ToolBar) control;
+        ToolItem[] tools = toolBar.getItems();
+        int toolCount = tools.length;
+        int visibleItemCount = 0;
+        while (visibleItemCount < toolCount) {
+            Rectangle toolBounds = tools[visibleItemCount].getBounds();
+            Point point = toolBar.toDisplay(new Point(toolBounds.x,
+                    toolBounds.y));
+            toolBounds.x = point.x;
+            toolBounds.y = point.y;
+            // stop if the tool is at least partially hidden by the drop down
+            // chevron
+            if (chevronPosition.x >= toolBounds.x
+                    && chevronPosition.x - toolBounds.x <= toolBounds.width) {
+                break;
+            }
+            visibleItemCount++;
+        }
+
+        // Create a pop-up menu with items for each of the hidden buttons.
+        if (chevronMenuManager != null) {
+            chevronMenuManager.dispose();
+        }
+        chevronMenuManager = new MenuManager();
+        for (int i = visibleItemCount; i < toolCount; i++) {
+            IContributionItem data = (IContributionItem) tools[i].getData();
+            if (data instanceof ActionContributionItem) {
+                ActionContributionItem contribution = new ActionContributionItem(
+                        ((ActionContributionItem) data).getAction());
+                chevronMenuManager.add(contribution);
+            } else if (data instanceof SubContributionItem) {
+                IContributionItem innerData = ((SubContributionItem) data)
+                        .getInnerItem();
+                if (innerData instanceof ActionContributionItem) {
+                    ActionContributionItem contribution = new ActionContributionItem(
+                            ((ActionContributionItem) innerData).getAction());
+                    chevronMenuManager.add(contribution);
+                }
+            } else if (data.isSeparator()) {
+                chevronMenuManager.add(new Separator());
+            }
+        }
+        Menu popup = chevronMenuManager.createContextMenu(coolBar);
+        popup.setLocation(chevronPosition.x, chevronPosition.y);
+        popup.setVisible(true);
+    }
+
+    /**
+     * Handles the event when the toobar item does not have its own context
+     * menu.
+     * 
+     * @param event
+     *            the event object
+     */
+    private void handleContextMenu(Event event) {
+        ToolBar toolBar = toolBarManager.getControl();
+        // If parent has a menu then use that one
+        Menu parentMenu = toolBar.getParent().getMenu();
+        if ((parentMenu != null) && (!parentMenu.isDisposed())) {
+            toolBar.setMenu(parentMenu);
+            // Hook listener to remove menu once it has disapeared
+            parentMenu.addListener(SWT.Hide, new Listener() {
+
+                public void handleEvent(Event innerEvent) {
+                    ToolBar innerToolBar = toolBarManager.getControl();
+                    if (innerToolBar != null) {
+                        innerToolBar.setMenu(null);
+                        Menu innerParentMenu = innerToolBar.getParent()
+                                .getMenu();
+                        if (innerParentMenu != null) {
+                            innerParentMenu.removeListener(SWT.Hide, this);
+                        }
+                    }
+                }
+            });
+        }
+    }
+
+    /**
+     * Handles the disposal of the widget.
+     * 
+     * @param event
+     *            the event object
+     */
+    private void handleWidgetDispose(DisposeEvent event) {
+        coolItem = null;
+    }
+
+    /**
+     * A contribution item is visible iff its internal state is visible <em>or</em>
+     * the tool bar manager contains something other than group markers and
+     * separators.
+     * 
+     * @return <code>true</code> if the tool bar manager contains something
+     *         other than group marks and separators, and the internal state is
+     *         set to be visible.
+     */
+    public boolean isVisible() {
+        boolean visibleItem = false;
+        if (toolBarManager != null) {
+            IContributionItem[] contributionItems = toolBarManager.getItems();
+            for (int i = 0; i < contributionItems.length; i++) {
+                IContributionItem contributionItem = contributionItems[i];
+                if ((!contributionItem.isGroupMarker())
+                        && (!contributionItem.isSeparator())) {
+                    visibleItem = true;
+                    break;
+                }
+            }
+        }
+
+        return visibleItem || super.isVisible();
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see org.eclipse.jface.action.IContributionItem#saveWidgetState()
+     */
+    public void saveWidgetState() {
+        if (coolItem == null) return;
+
+        //1. Save current size
+        CoolBar coolBar = coolItem.getParent();
+        boolean isLastOnRow = false;
+        int lastIndex = coolBar.getItemCount() - 1;
+        int coolItemIndex = coolBar.indexOf(coolItem);
+        int[] wrapIndicies = getAdjustedWrapIndices(coolBar.getWrapIndices());
+        // Traverse through all wrap indicies backwards
+        for (int row = wrapIndicies.length - 1; row >= 0; row--) {
+            if (wrapIndicies[row] <= coolItemIndex) {
+
+                int nextRow = row + 1;
+                int nextRowStartIndex;
+                if (nextRow > (wrapIndicies.length - 1)) {
+                    nextRowStartIndex = lastIndex + 1;
+                } else {
+                    nextRowStartIndex = wrapIndicies[nextRow];
+                }
+
+                // Check to see if its the last item on the row
+                if (coolItemIndex == (nextRowStartIndex - 1)) {
+                    isLastOnRow = true;
+                }
+                break;
+            }
+        }
+
+        // Save the preferred size as actual size for the last item on a row
+        int nCurrentWidth;
+        if (isLastOnRow) {
+            nCurrentWidth = coolItem.getPreferredSize().x;
+        } else {
+            nCurrentWidth = coolItem.getSize().x;
+        }
+        setCurrentWidth(nCurrentWidth);
+        setCurrentHeight(coolItem.getSize().y);
+    }
+
+    /**
+     * Sets the current height of the cool item. Update(SIZE) should be called
+     * to adjust the widget.
+     * 
+     * @param currentHeight
+     *            the current height to set
+     */
+    public void setCurrentHeight(int currentHeight) {
+        this.currentHeight = currentHeight;
+    }
+
+    /**
+     * Sets the current width of the cool item. Update(SIZE) should be called
+     * to adjust the widget.
+     * 
+     * @param currentWidth
+     *            the current width to set
+     */
+    public void setCurrentWidth(int currentWidth) {
+        this.currentWidth = currentWidth;
+    }
+
+    /**
+     * Sets the minimum number of tool items to show in the cool item. If this
+     * number is less than the total tool items, a chevron will appear and the
+     * hidden tool items appear in a drop down menu. By default, all the tool
+     * items are shown in the cool item.
+     * 
+     * @param minimumItemsToShow
+     *            the minimum number of tool items to show.
+     * @see #getMinimumItemsToShow()
+     * @see #setUseChevron(boolean)
+     */
+    public void setMinimumItemsToShow(int minimumItemsToShow) {
+        this.minimumItemsToShow = minimumItemsToShow;
+    }
+
+    /**
+     * Enables or disables chevron support for the cool item. By default,
+     * chevron support is enabled.
+     * 
+     * @param value
+     *            <code>true</code> to enable chevron support, <code>false</code>
+     *            otherwise.
+     */
+    public void setUseChevron(boolean value) {
+        useChevron = value;
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see org.eclipse.jface.action.IContributionItem#update(java.lang.String)
+     */
+    public void update(String propertyName) {
+        if (coolItem != null) {
+            if ((propertyName == null)
+                    || propertyName.equals(ICoolBarManager.SIZE)) {
+                updateSize(true);
+            }
+        }
+    }
+
+    /**
+     * Updates the cool items' preferred, minimum, and current size. The
+     * preferred size is calculated based on the tool bar size and extra trim.
+     * 
+     * @param changeCurrentSize
+     *            <code>true</code> if the current size should be changed to
+     *            the preferred size, <code>false</code> to not change the
+     *            current size
+     */
+    public void updateSize(boolean changeCurrentSize) {
+        // cannot set size if coolItem is null
+        if (coolItem == null || coolItem.isDisposed()) { return; }
+        boolean locked = false;
+        CoolBar coolBar = coolItem.getParent();
+        try {
+            // Fix odd behaviour with locked tool bars
+            if (coolBar != null) {
+                if (coolBar.getLocked() == true) {
+                    coolBar.setLocked(false);
+                    locked = true;
+                }
+            }
+            ToolBar toolBar = (ToolBar) coolItem.getControl();
+            if ((toolBar == null) || (toolBar.isDisposed())
+                    || (toolBar.getItemCount() <= 0)) {
+                // if the toolbar does not contain any items then dispose of
+                // coolItem
+                coolItem.setData(null);
+                Control control = coolItem.getControl();
+                if ((control != null) && !control.isDisposed()) {
+                    control.dispose();
+                    coolItem.setControl(null);
+                }
+                if (!coolItem.isDisposed()) {
+                    coolItem.dispose();
+                }
+            } else {
+                // If the toolbar item exists then adjust the size of the cool
+                // item
+                Point toolBarSize = toolBar.computeSize(SWT.DEFAULT,
+                        SWT.DEFAULT);
+                // Set the preffered size to the size of the toolbar plus trim
+                Point prefferedSize = coolItem.computeSize(toolBarSize.x,
+                        toolBarSize.y);
+                coolItem.setPreferredSize(prefferedSize);
+                // note setMinimumSize must be called before setSize, see PR
+                // 15565
+                // Set minimum size
+                if (getMinimumItemsToShow() != SHOW_ALL_ITEMS) {
+                    int toolItemWidth = toolBar.getItems()[1].getWidth();
+                    int minimumWidth = toolItemWidth * getMinimumItemsToShow();
+                    coolItem.setMinimumSize(minimumWidth, toolBarSize.y);
+                } else {
+                    coolItem.setMinimumSize(toolBarSize.x, toolBarSize.y);
+                }
+                if (changeCurrentSize) {
+                    // Set current size to preffered size
+                    coolItem.setSize(prefferedSize);
+                }
+            }
+        } finally {
+            // If the cool bar was locked, then set it back to locked
+            if ((locked) && (coolBar != null)) {
+                coolBar.setLocked(true);
+            }
+        }
+    }
 
 }
diff --git a/bundles/org.eclipse.jface/src/org/eclipse/jface/dialogs/IconAndMessageDialog.java b/bundles/org.eclipse.jface/src/org/eclipse/jface/dialogs/IconAndMessageDialog.java
index c6cec9b..1ab3f80 100644
--- a/bundles/org.eclipse.jface/src/org/eclipse/jface/dialogs/IconAndMessageDialog.java
+++ b/bundles/org.eclipse.jface/src/org/eclipse/jface/dialogs/IconAndMessageDialog.java
@@ -68,7 +68,7 @@
 
 		// create message
 		if (message != null) {
-			messageLabel = new Label(composite, SWT.WRAP);
+			messageLabel = new Label(composite, getMessageLabelStyle());
 			messageLabel.setText(message);
 			GridData data =
 				new GridData(
@@ -91,7 +91,9 @@
 	 */
 	protected int getMessageLabelStyle() {
 		return SWT.WRAP;
-	}	/*
+	}
+
+	/*
 	 * @see Dialog.createButtonBar()
 	 */
 	protected Control createButtonBar(Composite parent) {
diff --git a/bundles/org.eclipse.jface/src/org/eclipse/jface/resource/FileImageDescriptor.java b/bundles/org.eclipse.jface/src/org/eclipse/jface/resource/FileImageDescriptor.java
index 059d5b0..bbd4237 100644
--- a/bundles/org.eclipse.jface/src/org/eclipse/jface/resource/FileImageDescriptor.java
+++ b/bundles/org.eclipse.jface/src/org/eclipse/jface/resource/FileImageDescriptor.java
@@ -73,21 +73,20 @@
  */
 public ImageData getImageData() {
 	InputStream in = getStream();
+	ImageData result = null;
 	if (in != null) {
 		try {
-			return new ImageData(in);
-		}
-		finally {
+			result= new ImageData(in);
+		}finally {
 			try {
 				in.close();
-			}
-			catch (IOException e) {
-				return null;
+			}catch (IOException e) {
+				//System.err.println(getClass().getName()+".getImageData(): "+
+				//  "Exception while closing InputStream : "+e);
 			}
 		}
-	} else {
-		return null;
 	}
+	return result;
 }
 /**
  * Returns a stream on the image contents.  Returns
diff --git a/bundles/org.eclipse.jface/src/org/eclipse/jface/resource/jfacefonts_linux_gtk.properties b/bundles/org.eclipse.jface/src/org/eclipse/jface/resource/jfacefonts_linux_gtk.properties
index a09fdab..e5b2d94 100644
--- a/bundles/org.eclipse.jface/src/org/eclipse/jface/resource/jfacefonts_linux_gtk.properties
+++ b/bundles/org.eclipse.jface/src/org/eclipse/jface/resource/jfacefonts_linux_gtk.properties
@@ -12,4 +12,4 @@
 #############################################################
 org.eclipse.jface.bannerfont.0=Sans-bold-12 
 org.eclipse.jface.headerfont.0=Sans-bold-12
-org.eclipse.jface.textfont.0=Sans-regular-11
+org.eclipse.jface.textfont.0=Monospace-regular-10
diff --git a/bundles/org.eclipse.ui.ide/.project b/bundles/org.eclipse.ui.ide/.project
index 2f35280..0ba33da 100644
--- a/bundles/org.eclipse.ui.ide/.project
+++ b/bundles/org.eclipse.ui.ide/.project
@@ -6,8 +6,11 @@
 		<project>org.eclipse.core.resources</project>
 		<project>org.eclipse.core.runtime.compatibility</project>
 		<project>org.eclipse.help</project>
+		<project>org.eclipse.jface</project>
+		<project>org.eclipse.swt</project>
 		<project>org.eclipse.ui</project>
 		<project>org.eclipse.ui.views</project>
+		<project>org.eclipse.ui.workbench</project>
 		<project>org.eclipse.update.core</project>
 	</projects>
 	<buildSpec>
diff --git a/bundles/org.eclipse.ui.ide/plugin.xml b/bundles/org.eclipse.ui.ide/plugin.xml
index 45d61da..db6d814 100644
--- a/bundles/org.eclipse.ui.ide/plugin.xml
+++ b/bundles/org.eclipse.ui.ide/plugin.xml
@@ -347,7 +347,7 @@
       <page
             name="%PreferencePages.WorkbenchWorkInProgress"
             category="org.eclipse.ui.preferencePages.Workbench"
-            class="org.eclipse.ui.internal.misc.WorkInProgressPreferencePage"
+            class="org.eclipse.ui.internal.ide.misc.WorkInProgressPreferencePage"
             id="org.eclipse.ui.preferencePages.WorkInProgress">
       </page>
    </extension>
diff --git a/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/IDEWorkbenchAdvisor.java b/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/IDEWorkbenchAdvisor.java
index 8b98cf6..1b9c7de 100644
--- a/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/IDEWorkbenchAdvisor.java
+++ b/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/IDEWorkbenchAdvisor.java
@@ -345,6 +345,10 @@
 	 */
 	public void preWindowOpen(IWorkbenchWindowConfigurer windowConfigurer) {
 		
+	    // show the shortcut bar and progress indicator, which are hidden by default
+	    windowConfigurer.setShowShortcutBar(true);
+	    windowConfigurer.setShowProgressIndicator(true);
+	    
 		// add the drag and drop support for the editor area
 		windowConfigurer.addEditorAreaTransfer(EditorInputTransfer.getInstance());
 		windowConfigurer.addEditorAreaTransfer(ResourceTransfer.getInstance());
@@ -1136,7 +1140,7 @@
 			if ((flags & FILL_MENU_BAR) != 0) {
 				actionBuilder.populateMenuBar(actionConfigurer);
 			}
-			if ((flags & FILL_TOOL_BAR) != 0) {
+			if ((flags & FILL_COOL_BAR) != 0) {
 				actionBuilder.populateCoolBar(actionConfigurer);
 			}
 		} else {
diff --git a/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/views/markers/internal/ActionDeleteCompleted.java b/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/views/markers/internal/ActionDeleteCompleted.java
index b940f15..2f209ee 100644
--- a/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/views/markers/internal/ActionDeleteCompleted.java
+++ b/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/views/markers/internal/ActionDeleteCompleted.java
@@ -38,6 +38,7 @@
 	 */
 	public ActionDeleteCompleted(TaskView part, ISelectionProvider provider) {
 		super(provider, Messages.getString("deleteCompletedAction.title")); //$NON-NLS-1$
+		this.part = part;
 		setEnabled(false);
 	}
 	
diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/IEditorSite.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/IEditorSite.java
index 81ede15..35c2249 100644
--- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/IEditorSite.java
+++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/IEditorSite.java
@@ -12,7 +12,7 @@
 
 
 /**
- * The primary interface between an editor part and the outside world.
+ * The primary interface between an editor part and the workbench.
  * <p>
  * The workbench exposes its implemention of editor part sites via this 
  * interface, which is not intended to be implemented or extended by clients.
diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/IFolderLayout.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/IFolderLayout.java
index c456d51..893d919 100644
--- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/IFolderLayout.java
+++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/IFolderLayout.java
@@ -30,4 +30,14 @@
  * @param viewId the view id
  */
 public void addView(String viewId);
+/**
+ * Adds a fixed view with the given id to this folder.
+ * Once added, a fixed view cannot be moved or closed.
+ * The id must name a view contributed to the workbench's view extension point 
+ * (named <code>"org.eclipse.ui.views"</code>).
+ *
+ * @param viewId the view id
+ * @since 3.0
+ */
+public void addFixedView(String viewId);
 }
diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/IPageLayout.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/IPageLayout.java
index fcecfb1..006f5da 100644
--- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/IPageLayout.java
+++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/IPageLayout.java
@@ -241,6 +241,28 @@
  */
 public void addShowViewShortcut(String id);
 /**
+ * Adds a fixed view with the given id to this page layout.  
+ * Once added, a fixed view cannot be moved or closed.
+ * The id must name a view contributed to the workbench's view extension point 
+ * (named <code>"org.eclipse.ui.views"</code>).
+ *
+ * @param viewId the view id
+ * @param relationship the position relative to the reference part;
+ *  one of <code>TOP</code>, <code>BOTTOM</code>, <code>LEFT</code>,
+ *  or <code>RIGHT</code>
+ * @param ratio a ratio specifying how to divide the space currently occupied by the reference part,
+ *    in the range <code>0.05f</code> to <code>0.95f</code>.
+ *    Values outside this range will be clipped to facilitate direct manipulation.
+ *    For a vertical split, the part on top gets the specified ratio of the current space
+ *    and the part on bottom gets the rest.
+ *    Likewise, for a horizontal split, the part at left gets the specified ratio of the current space
+ *    and the part at right gets the rest.
+ * @param refId the id of the reference part; either a view id, a folder id,
+ *   or the special editor area id returned by <code>getEditorArea</code>
+ * @since 3.0
+ */
+public void addFixedView(String viewId, int relationship, float ratio, String refId);
+/**
  * Adds a view with the given id to this page layout.
  * The id must name a view contributed to the workbench's view extension point 
  * (named <code>"org.eclipse.ui.views"</code>).
@@ -353,4 +375,21 @@
  * @deprecated
  */
 public void setEditorReuseThreshold(int openEditors);
+/**
+ * Sets the fixed state of the layout.
+ * In a fixed layout, layout parts cannot be moved or zoomed.
+ *
+ * @param isFixed the fixed state
+ * @since 3.0
+ */
+public void setFixed(boolean isFixed);
+/**
+ * Returns true if this layout is fixed.
+ * In a fixed layout, layout parts cannot be moved or zoomed.
+ * The default is <code>false</code>.
+ * 
+ * @return isFixed
+ * @since 3.0
+ */
+public boolean isFixed();
 }
diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/IPerspectiveDescriptor.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/IPerspectiveDescriptor.java
index 437f1f5..a3202f4 100644
--- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/IPerspectiveDescriptor.java
+++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/IPerspectiveDescriptor.java
@@ -71,4 +71,13 @@
  * @return the label
  */
 public String getLabel();
+/**
+ * Returns this perspective's theme id. For perspectives declared via an extension,
+ * this is the value of its <code>"theme"</code> attribute.
+ *
+ * @return the theme id
+ *
+ * @since 3.0
+ */
+public String getTheme();
 }
diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/IViewReference.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/IViewReference.java
index da70f59..aebad01 100644
--- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/IViewReference.java
+++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/IViewReference.java
@@ -18,13 +18,24 @@
  * </p>
  */
 public interface IViewReference extends IWorkbenchPartReference {
+	
 	/**
-	 * Returns the IViewPart referenced by this object.
-	 * Returns null if the view was not instanciated or
-	 * it failed to be restored. Tries to restore the view
+	 * Returns the secondary ID for the view.
+	 * 
+	 * @return the secondary ID, or <code>null</code> if there is no secondary id
+     * @see IWorkbenchPage#showView(String, String, String)
+     * @since 3.0
+	 */
+	public String getSecondaryId();
+	
+	/**
+	 * Returns the <code>IViewPart</code> referenced by this object.
+	 * Returns <code>null</code> if the view was not instantiated or
+	 * it failed to be restored.  Tries to restore the view
 	 * if <code>restore</code> is true.
 	 */
 	public IViewPart getView(boolean restore);
+
 	/**
 	 * Returns true if the view is a fast view otherwise returns false.
 	 */	
diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/IViewSite.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/IViewSite.java
index 95aa88d..7f40488 100644
--- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/IViewSite.java
+++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/IViewSite.java
@@ -10,9 +10,8 @@
  *******************************************************************************/
 package org.eclipse.ui;
 
-
 /**
- * The primary interface between a view part and the outside world.
+ * The primary interface between a view part and the workbench.
  * <p>
  * The workbench exposes its implemention of view part sites via this interface,
  * which is not intended to be implemented or extended by clients.
@@ -27,4 +26,13 @@
 	 * @return the action bars
 	 */
 	public IActionBars getActionBars();
+	
+	/**
+	 * Returns the secondary id for this part site's part,
+	 * or <code>null</code> if it has none.
+	 * 
+	 * @see IWorkbenchPage#showView(String, String)
+     * @since 3.0
+	 */
+	public String getSecondaryId();
 }
diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/IWorkbenchPage.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/IWorkbenchPage.java
index 7944d9e..fbb7f73 100644
--- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/IWorkbenchPage.java
+++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/IWorkbenchPage.java
@@ -140,6 +140,28 @@
 	public static final String CHANGE_WORKING_SET_REPLACE = "workingSetReplace"; //$NON-NLS-1$	 
 
 	/**
+	 * Show view mode that indicates the view should be made visible and activated.
+	 * 
+	 * @since 3.0
+	 */
+	public static final int VIEW_ACTIVATE = 1;
+
+	/**
+	 * Show view mode that indicates the view should be made visible.
+	 * 
+	 * @since 3.0
+	 */	
+	public static final int VIEW_VISIBLE = 2;
+	
+	/**
+	 * Show view mode that indicates the view should be made created but not necessarily be made 
+	 * visible.
+	 * 
+	 * @since 3.0
+	 */
+	public static final int VIEW_CREATE = 3;
+	
+	/**
 	 * Activates the given part. The part will be brought to the front and
 	 * given focus. The part must belong to this page.
 	 * 
@@ -228,6 +250,17 @@
 	 */	
 	public IViewReference findViewReference(String viewId);
 	/**
+	 * Returns the view reference with the specified id and secondary id. 
+	 * 
+	 * @param viewId
+	 *            the id of the view extension to use
+	 * @param secondaryId
+	 *            the secondary id to use, or <code>null</code> for no secondary id
+	 * @return the view reference, or <code>null</code> if none is found
+	 * @since 3.0
+	 */	
+	public IViewReference findViewReference(String viewId, String secondaryId);
+	/**
 	 * Returns the active editor open in this page.
 	 * <p>
 	 * This is the visible editor on the page, or, if there is more than one
@@ -566,25 +599,50 @@
 	 */
 	public void showActionSet(String actionSetID);
 	/**
-	 * Shows a view in this page and give it focus. If the view is already
-	 * visible, it is given focus.
-	 * <p>
-	 * The view type is determined by mapping <code>viewId</code> to a view
-	 * extension registered with the workbench. A view id is passed rather than
-	 * a view object to prevent the accidental creation of more than one view
-	 * of a particular type. It also guarantees a consistent lifecycle for
-	 * views, regardless of whether they are created by the user or restored
-	 * from saved data.
-	 * </p>
+	 * Shows the view identified by the given view id in this page and gives it 
+	 * focus.  If there is a view identified by the given view id (and with no 
+	 * secondary id) already open in this page, it is given focus.
 	 * 
 	 * @param viewId
 	 *            the id of the view extension to use
-	 * @return a view
+	 * @return the shown view
 	 * @exception PartInitException
 	 *                if the view could not be initialized
 	 */
 	public IViewPart showView(String viewId) throws PartInitException;
 	/**
+	 * Shows a view in this page with the given id and secondary id.  The behaviour of this method 
+	 * varies based on the supplied mode. If <code>VIEW_ACTIVATE</code> is supplied, the view is 
+	 * focus.  If <code>VIEW_VISIBLE</code> is supplied, then it is made visible but not given 
+	 * focus. Finally, if <code>VIEW_CREATE</code> is supplied the view is created and will only be 
+	 * made visible if it is not created in a folder that already contains visible views.
+	 * <p>
+	 * This allows multiple instances of a particular view to be created.
+	 * They are disambiguated using the secondary id.
+	 * If a secondary id is given, the view must allow multiple instances by
+	 * having specified allowMultiple="true" in its extension.
+	 * </p>
+	 *   
+ 	 * @param viewId
+	 *            the id of the view extension to use
+	 * @param secondaryId
+	 *            the secondary id to use, or <code>null</code> for no secondary id 
+	 * @param mode
+	 * 			  the activation mode.  Must be <code>VIEW_ACTIVATE</code>, 
+	 * 			  <code>VIEW_VISIBLE</code> or <code>VIEW_CREATE</code>
+	 * @return a view
+	 * @see VIEW_ACTIVATE
+	 * @see VIEW_VISIBLE
+	 * @see VIEW_CREATE
+	 * @exception PartInitException
+	 *                if the view could not be initialized
+	 * @exception IllegalArgumentException
+	 * 				  if the supplied mode is not valid
+	 * @since 3.0
+	 */
+	public IViewPart showView(String viewId, String secondaryId, int mode) throws PartInitException;	
+	
+	/**
 	 * Returns true if the editor is pinned and should not be reused.
 	 * 
 	 * @return boolean
diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/IWorkbenchPart.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/IWorkbenchPart.java
index a063c3c..4a1b01e 100644
--- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/IWorkbenchPart.java
+++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/IWorkbenchPart.java
@@ -93,7 +93,8 @@
 public interface IWorkbenchPart extends IAdaptable {
 	
 	/**
-	 * The property id for <code>getTitle</code> and <code>getTitleImage</code>.
+	 * The property id for <code>getTitle</code>, <code>getTitleImage</code>
+	 * and <code>getTitleToolTip</code>.
 	 */
 	public static final int PROP_TITLE = 0x01;
 /**
diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/IWorkbenchPartSite.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/IWorkbenchPartSite.java
index 72d6fe4..fc1a4e4 100644
--- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/IWorkbenchPartSite.java
+++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/IWorkbenchPartSite.java
@@ -14,7 +14,7 @@
 import org.eclipse.jface.viewers.ISelectionProvider;
 
 /**
- * The primary interface between a workbench part and the outside world.
+ * The primary interface between a workbench part and the workbench.
  * <p>
  * This interface is not intended to be implemented or extended by clients.
  * </p>
@@ -30,7 +30,6 @@
  *
  * @return the registry extension id
  */
-	
 public String getId();
 /**
  * Returns the unique identifier of the plug-in that defines this workbench
diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/application/IWorkbenchPreferences.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/application/IWorkbenchPreferences.java
index 7e8a903..a220d4b 100644
--- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/application/IWorkbenchPreferences.java
+++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/application/IWorkbenchPreferences.java
@@ -61,7 +61,7 @@
 	 * should have a shortcut bar by default, and <code>false</code> if they
 	 * should not have a shortcut bar by default.
 	 * <p>
-	 * The default value for this preference is: <code>true</code> (has shortcut bar)
+	 * The default value for this preference is: <code>false</code> (does not have shortcut bar)
 	 * </p>
 	 */
 	public static String SHOULD_SHOW_SHORTCUT_BAR = "wb.show.shortcut.bar"; //$NON-NLS-1$
@@ -90,6 +90,17 @@
 	public static String SHOW_MULTIPLE_EDITOR_TABS = "wb.show.multiple.editor.tabs"; //$NON-NLS-1$	
 
 	/**
+	 * Workbench preference id for whether workbench windows should have a progress 
+	 * indicator by default. Boolean-valued: <code>true</code> if workbench windows 
+	 * should have a menu bar by default, and <code>false</code> if they
+	 * should not have a menu bar by default.
+	 * <p>
+	 * The default value for this preference is: <code>false</code> (does not have progress indicator)
+	 * </p>
+	 */
+	public static String SHOULD_SHOW_PROGRESS_INDICATOR = "wb.show.progress.indicator"; //$NON-NLS-1$
+
+	/**
 	 * Workbench preference id for whether the workbench should show text 
 	 * on the perspective bar. 
 	 * 
diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/application/IWorkbenchWindowConfigurer.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/application/IWorkbenchWindowConfigurer.java
index 045356b..2a5ceea 100644
--- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/application/IWorkbenchWindowConfigurer.java
+++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/application/IWorkbenchWindowConfigurer.java
@@ -96,14 +96,14 @@
 	public void setShowTitleBar(boolean show);
 
 	/**
-	 * Returns whether the underlying workbench window has a title bar.
+	 * Returns whether the underlying workbench window has a menu bar.
 	 * <p>
 	 * The initial value is controlled by the preference
 	 * {@link IWorkbenchPreferences#SHOULD_SHOW_MENU_BAR IWorkbenchPreferences.SHOULD_SHOW_MENU_BAR}
 	 * </p>
 	 * 
-	 * @return <code>true</code> for a title bar, and <code>false</code>
-	 * for no title bar
+	 * @return <code>true</code> for a menu bar, and <code>false</code>
+	 * for no menu bar
 	 */
 	public boolean getShowMenuBar();
 
@@ -179,6 +179,44 @@
 	public void setShowStatusLine(boolean show);
 	
 	/**
+	 * Returns whether the underlying workbench window has a progress indicator.
+	 * <p>
+	 * The initial value is controlled by the preference
+	 * {@link IWorkbenchPreferences#SHOULD_SHOW_PROGRESS_INDICATOR IWorkbenchPreferences.SHOULD_SHOW_PROGRESS_INDICATOR}
+	 * </p>
+	 * 
+	 * @return <code>true</code> for a progress indicator, and <code>false</code>
+	 * for no progress indicator
+	 */
+	public boolean getShowProgressIndicator();
+	
+	/**
+	 * Sets whether the underlying workbench window has a progress indicator.
+	 * 
+	 * @param show <code>true</code> for a progress indicator, and <code>false</code>
+	 * for no progress indicator
+	 */
+	public void setShowProgressIndicator(boolean show);
+
+	/**
+	 * Returns the style bits to use for the window's shell when it is created.
+	 * The default is <code>SWT.SHELL_TRIM</code>.
+	 *
+	 * @return the shell style bits
+	 */
+	public int getShellStyle();
+
+	/**
+	 * Sets the style bits to use for the window's shell when it is created.
+	 * This method has no effect after the shell is created.
+	 * That is, it must be called within the <code>preWindowOpen</code>
+	 * callback on <code>WorkbenchAdvisor</code>.
+	 *
+	 * @param newShellStyle the new shell style bits
+	 */
+	public void setShellStyle(int shellStyle);
+
+	/**
 	 * Returns the data associated with this workbench window at the given key.
 	 * 
 	 * @param key the key
diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/application/WorkbenchAdvisor.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/application/WorkbenchAdvisor.java
index 323ea21..020acf2 100644
--- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/application/WorkbenchAdvisor.java
+++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/application/WorkbenchAdvisor.java
@@ -114,10 +114,10 @@
 	
 	/**
 	 * Bit flag for {@link #fillActionBars fillActionBars} indicating that the
-	 * operation is supposed to fill (or describe) the workbench window's tool
+	 * operation is supposed to fill (or describe) the workbench window's cool
 	 * bar.
 	 */
-	public static final int FILL_TOOL_BAR = 0x04;
+	public static final int FILL_COOL_BAR = 0x04;
 
 	/**
 	 * Bit flag for {@link #fillActionBars fillActionBars} indicating that the
@@ -490,24 +490,6 @@
 	 * 
 	 * @return the default input for a new workbench window page, or
 	 * <code>null</code> if none
-	 * @deprecated This method has been renamed getDefaultPageInput.
-	 * It has been marked final as advanced wiarning, and
-	 * will be removed entirely by M7.
-	 */
-	public final IAdaptable getDefaultWindowInput() {
-		// default: no input
-		return null;
-	}
-	
-	/**
-	 * Returns the default input for newly created workbench pages.
-	 * <p>
-	 * The default implementation returns <code>null</code>.
-	 * Subclasses may override.
-	 * </p>
-	 * 
-	 * @return the default input for a new workbench window page, or
-	 * <code>null</code> if none
 	 */
 	public IAdaptable getDefaultPageInput() {
 		// default: no input
diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/commands/IWorkbenchCommandSupport.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/commands/IWorkbenchCommandSupport.java
index 7db4187..c48448e 100644
--- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/commands/IWorkbenchCommandSupport.java
+++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/commands/IWorkbenchCommandSupport.java
@@ -1,8 +1,17 @@
+/*******************************************************************************
+ * Copyright (c) 2003 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.commands;
 
 import org.eclipse.swt.widgets.Shell;
 
-import org.eclipse.ui.internal.keys.WorkbenchKeyboard;
 
 /**
  * An instance of this interface provides support for managing commands at the
@@ -63,16 +72,6 @@
 	ICompoundCommandHandlerService getCompoundCommandHandlerService();
 
 	/**
-	 * An accessor for the keyboard interface this workbench is using. This can
-	 * be used by external class to get a reference with which they can
-	 * simulate key presses in the key binding architecture. This is used for
-	 * testing purposes currently.
-	 * 
-	 * @return A reference to the workbench keyboard interface; never <code>null</code>.
-	 */
-	public WorkbenchKeyboard getKeyboard();
-
-	/**
 	 * Tests whether the global key binding architecture is currently active.
 	 * 
 	 * @return <code>true</code> if the key bindings are active; <code>false</code>
diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/ActionSetActionBars.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/ActionSetActionBars.java
index 22856d3..2809d11 100644
--- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/ActionSetActionBars.java
+++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/ActionSetActionBars.java
@@ -10,11 +10,19 @@
  *******************************************************************************/
 package org.eclipse.ui.internal;
 
-
 import java.util.ArrayList;
 import java.util.Iterator;
 
-import org.eclipse.jface.action.*;
+import org.eclipse.jface.action.ContributionItem;
+import org.eclipse.jface.action.IContributionItem;
+import org.eclipse.jface.action.IContributionManager;
+import org.eclipse.jface.action.ICoolBarManager;
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.action.IToolBarManager;
+import org.eclipse.jface.action.SubMenuManager;
+import org.eclipse.jface.action.SubToolBarManager;
+import org.eclipse.jface.action.ToolBarContributionItem;
+import org.eclipse.jface.action.ToolBarManager;
 
 import org.eclipse.ui.IActionBars2;
 import org.eclipse.ui.IWorkbenchActionConstants;
@@ -24,254 +32,269 @@
  * This class represents the action bars for an action set.
  */
 public class ActionSetActionBars extends SubActionBars2 {
-	private String actionSetId;
-	private ToolBarContributionItem toolBarContributionItem = null;
-	private IToolBarManager coolItemToolBarMgr = null;
-	private ArrayList adjunctContributions = new ArrayList();
-	/**
-	 * Constructs a new action bars object
-	 */
-	public ActionSetActionBars(IActionBars2 parent, String actionSetId) {
-		super(parent);		
-		this.actionSetId = actionSetId;
-	}
-	/**
-	 * Adds to the list all the actions that are part of this action set but belong to
-	 * different cool bar items.
-	 * @param item the item defined in this actionset but in a different tool Bar contribution item
-	 */
-	/* package */ void addAdjunctContribution(IContributionItem item) {
-		adjunctContributions.add(item);
-	}
-	/* (non-Javadoc)
-	 * Inherited from SubActionBars.
-	 */
-	protected SubMenuManager createSubMenuManager(IMenuManager parent) {
-		return new ActionSetMenuManager(parent, actionSetId);
-	}
-	/* (non-Javadoc)
-	 * Inherited from SubActionBars.
-	 */
-	protected SubToolBarManager createSubToolBarManager(IToolBarManager parent) {
-		// return null, action sets are managed by CoolItemToolBarManagers
-		return null;
-	}
-	/**
-	 * Dispose the contributions.
-	 */
-	public void dispose() {
-		super.dispose();
-		if (coolItemToolBarMgr == null) return;
-		IContributionItem[] items = coolItemToolBarMgr.getItems();
-		// remove the action set's items from its action bar, don't use 
-		// removeAll since other items from other actions sets may be in
-		// the action bar's cool item
-		for (int i=0; i<items.length; i++) {
-			IContributionItem item = items[i];
-			if (item instanceof PluginActionCoolBarContributionItem) {
-				PluginActionCoolBarContributionItem actionSetItem = (PluginActionCoolBarContributionItem) item;
-				if (actionSetItem.getActionSetId().equals(actionSetId)) {
-					coolItemToolBarMgr.remove(item);
-				}
-			} else {
-				// leave separators and group markers intact, doing
-				// so allows ordering to be maintained when action sets
-				// are removed then added back
-			}		
-		}
-			
-		// remove items from this action set that are in other action bars
-		for (int i=0; i<adjunctContributions.size(); i++) {
-			ContributionItem item = (ContributionItem)adjunctContributions.get(i);
-			ToolBarManager parent = (ToolBarManager)item.getParent();
-			if (parent != null) {
-				parent.remove(item);
-			}
-		}
-		toolBarContributionItem = null;
-		coolItemToolBarMgr = null;
-		adjunctContributions = new ArrayList();
-	}
-		
-	/**
-	 * Returns a tool bar manager for this Item.
-	 * @return the tool bar manager
-	 */
-	public IToolBarManager getToolBarManager() {
-		ICoolBarManager coolBarManager = getCastedParent().getCoolBarManager();
-		if (coolBarManager == null) {
-			return null;
-		}
-		return new ToolBarManager(coolBarManager.getStyle());
-	}
-	
-	/**
-	 * Returns the correct tool bar for the given action id. If this action is an adjunct type
-	 * the it returns the toolbar manager from the cool bar manager.
-	 * @param id the id of the action
-	 * @return the tool bar manager
-	 */
-	public IToolBarManager getToolBarManager(String actionId) {
-		// Check if a tool bar manager for an adjunct type is being requested
-		String toolBarId = actionSetId;
-		boolean isAdjunctType = false;
-		if (!actionId.equals(actionSetId)) {
-			// Adjunct type
-			toolBarId = actionId;
-			isAdjunctType = true;
-		}
-		
-		// Rereive the cool bar manager
-		ICoolBarManager coolBarManager = getCastedParent().getCoolBarManager();
-		if (coolBarManager == null) {
-			return null;
-		}
-		
-		// Check to see that there isn't already a tool bar created
-		// and the tool bar being requested is not for an adjunct action
-		if ((coolItemToolBarMgr != null) && (!isAdjunctType) ) {
-			return coolItemToolBarMgr;
-		}
-		
-		// Search for toolBarId in the cool Bar manager
-		IContributionItem cbItem = coolBarManager.find(toolBarId);
-		// If there hasn't been a tool bar contribution item created for this tool bar
-		// id then create one. Otherwise retrieve the tool bar contribution item
-		if (cbItem instanceof ToolBarContributionItem) {
-			
-			ToolBarContributionItem tbcbItem = (ToolBarContributionItem)cbItem;
-			coolItemToolBarMgr = tbcbItem.getToolBarManager();
-			// If this not an adjuct type then we can cashe the tool bar contribution type
-			if (!isAdjunctType) {
-				toolBarContributionItem = tbcbItem;
-			}
-		} else {
-			
-			coolItemToolBarMgr = new ToolBarManager(coolBarManager.getStyle());
-			// If this is not an adjunct type then create a tool bar contribution item
-			// we don't create one for an adjunct type because another action set action bars contains one
-			
-			toolBarContributionItem = new ToolBarContributionItem(coolItemToolBarMgr,toolBarId);
-			toolBarContributionItem.setParent(coolItemToolBarMgr);
-			toolBarContributionItem.setVisible(getActive());
-			coolItemToolBarMgr.markDirty();
-			
-			// Now add the  tool bar contribution Item to the cool bar manager
-			IContributionItem refItem = findAlphabeticalOrder(IWorkbenchActionConstants.MB_ADDITIONS,toolBarId,coolBarManager);
-			if (refItem != null) {
-				coolBarManager.insertAfter(refItem.getId(),toolBarContributionItem);
-			}else {
-				coolBarManager.add(toolBarContributionItem);
-			}
-		}	
-		return coolItemToolBarMgr;
-	}
-	
-	
-	/* package */ String getActionSetId() {
-		return actionSetId;
-	}
-	
-	/**
-	 * Activate / Deactivate the contributions.
-	 */
-	protected void setActive(boolean set) {
-		super.setActive(set);
 
-		ICoolBarManager coolBarManager = getCastedParent().getCoolBarManager();
-		if (coolBarManager == null) return;
-	
-		// 1. Need to set visibility for all non-adjunct actions 
-		if (coolItemToolBarMgr != null) {
-			IContributionItem[] items = coolItemToolBarMgr.getItems();
-			for (int i=0; i < items.length; i++) {
-				IContributionItem item = items[i];
-				if (item instanceof PluginActionCoolBarContributionItem) {
-					PluginActionCoolBarContributionItem actionSetItem = (PluginActionCoolBarContributionItem) item;
-					// Only if the action set id for this contribution item is the same
-					// as this object
-					if (actionSetItem.getActionSetId().equals(actionSetId)) {
-						item.setVisible(set);
-						coolItemToolBarMgr.markDirty();
-						if (!coolBarManager.isDirty()) {
-							coolBarManager.markDirty();
-						}
-					}
-				}
-			}
-			// Update the manager
-			coolItemToolBarMgr.update(false);
-			if (toolBarContributionItem != null) {
-				toolBarContributionItem.update(ICoolBarManager.SIZE);
-			}
-		}
+    private String actionSetId;
+    private ArrayList adjunctContributions = new ArrayList();
+    private IToolBarManager coolItemToolBarMgr = null;
+    private ToolBarContributionItem toolBarContributionItem = null;
 
-		// 2. Need to set visibility for all adjunct actions 
-		if (adjunctContributions.size() > 0) {
-			for(Iterator i=adjunctContributions.iterator(); i.hasNext();) {
-				IContributionItem item = (IContributionItem)i.next();
-				if (item instanceof ContributionItem) {
-					item.setVisible(set);
-					IContributionManager manager = ((ContributionItem)item).getParent();
-					manager.markDirty();
-					manager.update(false);
-					if (!coolBarManager.isDirty()) {
-						coolBarManager.markDirty();
-					}
-					item.update(ICoolBarManager.SIZE);
-				}
-				
-			}
-			
-		}
-		coolBarManager.update(false);
-	}
-	
-	/**
-	 * Returns the contribution item that the given contribution item should be inserted after.
-	 * 
-	 * @param startId the location to start looking alphabetically.
-	 * @param itemId the target item id.
-	 * @param mgr the contribution manager.
-	 * @return the contribution item that the given items should be returned after.
-	 * 
-	 * @since 3.0
-	 */
-	private IContributionItem findAlphabeticalOrder(String startId, String itemId, IContributionManager mgr) {
-		IContributionItem[] items = mgr.getItems();
-		int insertIndex = 0;
-		
-		// look for starting point
-		while (insertIndex < items.length) {
-			IContributionItem item = items[insertIndex];
-			if (item.getId().equals(startId))
-				break;
-			++insertIndex;
-		}
-		
-		// Find the index that this item should be inserted in
-		for (int i= insertIndex+1; i < items.length; i++) {
-			IContributionItem item = (IContributionItem) items[i];
-			String testId = item.getId();
-			
-			if (item.isGroupMarker()) break;
-			
-			if (itemId != null) {
-				if (itemId.compareTo(testId) < 1)
-					break;
-			}
-			insertIndex = i;
-		}
-		// Should be inserted at the end
-		if (insertIndex >= items.length) {
-			return null;
-		}
-		return items[insertIndex];
-	}
-	
-	//for dynamic UI
-	/* package */ void removeAdjunctContribution(ContributionItem item) {
-		adjunctContributions.remove(item);
-	}
-	
+    /**
+     * Constructs a new action bars object
+     */
+    public ActionSetActionBars(IActionBars2 parent, String actionSetId) {
+        super(parent);
+        this.actionSetId = actionSetId;
+    }
+
+    /**
+     * Adds to the list all the actions that are part of this action set but
+     * belong to different cool bar items.
+     * 
+     * @param item
+     *            the item defined in this actionset but in a different tool
+     *            Bar contribution item
+     */
+    /* package */void addAdjunctContribution(IContributionItem item) {
+        adjunctContributions.add(item);
+    }
+
+    /*
+     * (non-Javadoc) Inherited from SubActionBars.
+     */
+    protected SubMenuManager createSubMenuManager(IMenuManager parent) {
+        return new ActionSetMenuManager(parent, actionSetId);
+    }
+
+    /*
+     * (non-Javadoc) Inherited from SubActionBars.
+     */
+    protected SubToolBarManager createSubToolBarManager(IToolBarManager parent) {
+        // return null, action sets are managed by CoolItemToolBarManagers
+        return null;
+    }
+
+    /**
+     * Dispose the contributions.
+     */
+    public void dispose() {
+        super.dispose();
+        if (coolItemToolBarMgr == null) return;
+        IContributionItem[] items = coolItemToolBarMgr.getItems();
+        // remove the action set's items from its action bar, don't use
+        // removeAll since other items from other actions sets may be in
+        // the action bar's cool item
+        for (int i = 0; i < items.length; i++) {
+            IContributionItem item = items[i];
+            if (item instanceof PluginActionCoolBarContributionItem) {
+                PluginActionCoolBarContributionItem actionSetItem = (PluginActionCoolBarContributionItem) item;
+                if (actionSetItem.getActionSetId().equals(actionSetId)) {
+                    coolItemToolBarMgr.remove(item);
+                }
+            } else {
+                // leave separators and group markers intact, doing
+                // so allows ordering to be maintained when action sets
+                // are removed then added back
+            }
+        }
+
+        // remove items from this action set that are in other action bars
+        for (int i = 0; i < adjunctContributions.size(); i++) {
+            ContributionItem item = (ContributionItem) adjunctContributions.get(i);
+            ToolBarManager parent = (ToolBarManager) item.getParent();
+            if (parent != null) {
+                parent.remove(item);
+            }
+        }
+        toolBarContributionItem = null;
+        coolItemToolBarMgr = null;
+        adjunctContributions = new ArrayList();
+    }
+
+    /**
+     * Returns the contribution item that the given contribution item should be
+     * inserted after.
+     * 
+     * @param startId
+     *            the location to start looking alphabetically.
+     * @param itemId
+     *            the target item id.
+     * @param mgr
+     *            the contribution manager.
+     * @return the contribution item that the given items should be returned
+     *         after.
+     * 
+     * @since 3.0
+     */
+    private IContributionItem findAlphabeticalOrder(String startId, String itemId,
+            IContributionManager mgr) {
+        IContributionItem[] items = mgr.getItems();
+        int insertIndex = 0;
+
+        // look for starting point
+        while (insertIndex < items.length) {
+            IContributionItem item = items[insertIndex];
+            if (item.getId().equals(startId)) break;
+            ++insertIndex;
+        }
+
+        // Find the index that this item should be inserted in
+        for (int i = insertIndex + 1; i < items.length; i++) {
+            IContributionItem item = (IContributionItem) items[i];
+            String testId = item.getId();
+
+            if (item.isGroupMarker()) break;
+
+            if (itemId != null) {
+                if (itemId.compareTo(testId) < 1) break;
+            }
+            insertIndex = i;
+        }
+        // Should be inserted at the end
+        if (insertIndex >= items.length) { return null; }
+        return items[insertIndex];
+    }
+
+    /* package */String getActionSetId() {
+        return actionSetId;
+    }
+
+    /**
+     * Returns a tool bar manager for this Item.
+     * 
+     * @return the tool bar manager
+     */
+    public IToolBarManager getToolBarManager() {
+        ICoolBarManager coolBarManager = getCastedParent().getCoolBarManager();
+        if (coolBarManager == null) { return null; }
+        return new ToolBarManager(coolBarManager.getStyle());
+    }
+
+    /**
+     * Returns the correct tool bar for the given action id. If this action is
+     * an adjunct type the it returns the toolbar manager from the cool bar
+     * manager.
+     * 
+     * @param id
+     *            the id of the action
+     * @return the tool bar manager
+     */
+    public IToolBarManager getToolBarManager(String actionId) {
+        // Check if a tool bar manager for an adjunct type is being requested
+        String toolBarId = actionSetId;
+        boolean isAdjunctType = false;
+        if (!actionId.equals(actionSetId)) {
+            // Adjunct type
+            toolBarId = actionId;
+            isAdjunctType = true;
+        }
+
+        // Rereive the cool bar manager
+        ICoolBarManager coolBarManager = getCastedParent().getCoolBarManager();
+        if (coolBarManager == null) { return null; }
+
+        // Check to see that there isn't already a tool bar created
+        // and the tool bar being requested is not for an adjunct action
+        if ((coolItemToolBarMgr != null) && (!isAdjunctType)) { return coolItemToolBarMgr; }
+
+        // Search for toolBarId in the cool Bar manager
+        IContributionItem cbItem = coolBarManager.find(toolBarId);
+        // If there hasn't been a tool bar contribution item created for this
+        // tool bar
+        // id then create one. Otherwise retrieve the tool bar contribution
+        // item
+        if (cbItem instanceof ToolBarContributionItem) {
+
+            ToolBarContributionItem tbcbItem = (ToolBarContributionItem) cbItem;
+            coolItemToolBarMgr = tbcbItem.getToolBarManager();
+            // If this not an adjuct type then we can cashe the tool bar
+            // contribution type
+            if (!isAdjunctType) {
+                toolBarContributionItem = tbcbItem;
+            }
+        } else {
+
+            coolItemToolBarMgr = new ToolBarManager(coolBarManager.getStyle());
+            // If this is not an adjunct type then create a tool bar
+            // contribution item
+            // we don't create one for an adjunct type because another action
+            // set action bars contains one
+
+            toolBarContributionItem = new ToolBarContributionItem(coolItemToolBarMgr, toolBarId);
+            toolBarContributionItem.setParent(coolItemToolBarMgr);
+            toolBarContributionItem.setVisible(getActive());
+            coolItemToolBarMgr.markDirty();
+
+            // Now add the tool bar contribution Item to the cool bar manager
+            IContributionItem refItem = findAlphabeticalOrder(
+                    IWorkbenchActionConstants.MB_ADDITIONS, toolBarId, coolBarManager);
+            if (refItem != null) {
+                coolBarManager.insertAfter(refItem.getId(), toolBarContributionItem);
+            } else {
+                coolBarManager.add(toolBarContributionItem);
+            }
+        }
+        return coolItemToolBarMgr;
+    }
+
+    //for dynamic UI
+    /* package */void removeAdjunctContribution(ContributionItem item) {
+        adjunctContributions.remove(item);
+    }
+
+    /**
+     * Activate / Deactivate the contributions.
+     */
+    protected void setActive(boolean set) {
+        super.setActive(set);
+
+        ICoolBarManager coolBarManager = getCastedParent().getCoolBarManager();
+        if (coolBarManager == null) return;
+
+        // 1. Need to set visibility for all non-adjunct actions
+        if (coolItemToolBarMgr != null) {
+            IContributionItem[] items = coolItemToolBarMgr.getItems();
+            for (int i = 0; i < items.length; i++) {
+                IContributionItem item = items[i];
+                if (item instanceof PluginActionCoolBarContributionItem) {
+                    PluginActionCoolBarContributionItem actionSetItem = (PluginActionCoolBarContributionItem) item;
+                    // Only if the action set id for this contribution item is
+                    // the same
+                    // as this object
+                    if (actionSetItem.getActionSetId().equals(actionSetId)) {
+                        item.setVisible(set);
+                        coolItemToolBarMgr.markDirty();
+                        if (!coolBarManager.isDirty()) {
+                            coolBarManager.markDirty();
+                        }
+                    }
+                }
+            }
+            // Update the manager
+            coolItemToolBarMgr.update(false);
+            if (toolBarContributionItem != null) {
+                toolBarContributionItem.update(ICoolBarManager.SIZE);
+            }
+        }
+
+        // 2. Need to set visibility for all adjunct actions
+        if (adjunctContributions.size() > 0) {
+            for (Iterator i = adjunctContributions.iterator(); i.hasNext();) {
+                IContributionItem item = (IContributionItem) i.next();
+                if (item instanceof ContributionItem) {
+                    item.setVisible(set);
+                    IContributionManager manager = ((ContributionItem) item).getParent();
+                    manager.markDirty();
+                    manager.update(false);
+                    if (!coolBarManager.isDirty()) {
+                        coolBarManager.markDirty();
+                    }
+                    item.update(ICoolBarManager.SIZE);
+                }
+
+            }
+
+        }
+        coolBarManager.update(false);
+    }
+
 }
diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/DetachedWindow.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/DetachedWindow.java
index c6180f9..c074086 100644
--- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/DetachedWindow.java
+++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/DetachedWindow.java
@@ -48,7 +48,7 @@
 		setShellStyle( //SWT.CLOSE | SWT.MIN | SWT.MAX | 
 			SWT.RESIZE );
 		this.page = workbenchPage;
-		folder = new PartTabFolder();
+		folder = new PartTabFolder(page);
 	}
 	/**
 	 * Adds a visual part to this window.
diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/EditorActionBars.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/EditorActionBars.java
index d03725d..b66e943 100644
--- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/EditorActionBars.java
+++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/EditorActionBars.java
@@ -11,16 +11,20 @@
 package org.eclipse.ui.internal;
 
 import org.eclipse.jface.action.ActionContributionItem;
+import org.eclipse.jface.action.ContributionManager;
 import org.eclipse.jface.action.IContributionItem;
+import org.eclipse.jface.action.IContributionManager;
 import org.eclipse.jface.action.IContributionManagerOverrides;
 import org.eclipse.jface.action.ICoolBarManager;
 import org.eclipse.jface.action.IMenuManager;
 import org.eclipse.jface.action.IToolBarManager;
+import org.eclipse.jface.action.SubContributionManager;
 import org.eclipse.jface.action.SubMenuManager;
 import org.eclipse.jface.action.SubStatusLineManager;
 import org.eclipse.jface.action.SubToolBarManager;
 import org.eclipse.jface.action.ToolBarContributionItem;
 import org.eclipse.jface.action.ToolBarManager;
+
 import org.eclipse.ui.IActionBars2;
 import org.eclipse.ui.IEditorActionBarContributor;
 import org.eclipse.ui.IEditorPart;
@@ -33,311 +37,367 @@
  * The action bars for an editor.
  */
 public class EditorActionBars extends SubActionBars2 {
-	private String type;
-	private int refCount;
-	private IEditorActionBarContributor editorContributor;
-	private IEditorActionBarContributor extensionContributor;
-	private ToolBarContributionItem toolBarContributionItem = null;
-	private IToolBarManager coolItemToolBarMgr = null;
-	private boolean enabledAllowed = true;
 
-	private class Overrides implements IContributionManagerOverrides {
-		public Boolean getEnabled(IContributionItem item) {
-			if (((item instanceof ActionContributionItem)
-				&& (((ActionContributionItem) item).getAction()
-					instanceof RetargetAction))
-				|| enabledAllowed)
-				return null;
-			else
-				return Boolean.FALSE;
-		}
-		public Integer getAccelerator(IContributionItem item) {
-			return null;
-		}
-		public String getAcceleratorText(IContributionItem item) {
-			return null;
-		}
-		public String getText(IContributionItem item) {
-			return null;
-		}
-	}
+    private class Overrides implements IContributionManagerOverrides {
 
-	/**
-	 * Constructs the EditorActionBars for an editor.
-	 */
-	public EditorActionBars(IActionBars2 parent, String type) {
-		super(parent);
-		this.type = type;
-	}
-	/**
-	 * Activate the contributions.
-	 */
-	public void activate(boolean forceVisibility) {
-		setActive(true, forceVisibility);
-	}
-	/**
-	 * Add one ref to the bars.
-	 */
-	public void addRef() {
-		++refCount;
-	}
-	/*
-	 * (non-Javadoc) Method declared on SubActionBars.
-	 */
-	protected SubMenuManager createSubMenuManager(IMenuManager parent) {
-		return new EditorMenuManager(parent);
-	}
-	/*
-	 * (non-Javadoc) Method declared on SubActionBars.
-	 */
-	protected SubToolBarManager createSubToolBarManager(IToolBarManager parent) {
-		// return null, editor actions are managed by CoolItemToolBarManagers
-		return null;
-	}
-	/**
-	 * Deactivate the contributions.
-	 */
-	public void deactivate(boolean forceVisibility) {
-		setActive(false, forceVisibility);
-	}
-	/**
-	 * Dispose the contributions.
-	 */
-	public void dispose() {
-		super.dispose();
-		if (editorContributor != null)
-			editorContributor.dispose();
-		if (extensionContributor != null)
-			extensionContributor.dispose();
-		
-		// Dispose of the Cool Item that is created for this editor.
-		// For action sets we just make the cool item invisible. Here we
-		// will actually delete all the contribuitons items in the tool bar
-		// manager that is in the tool bar conribution item.
-		if (toolBarContributionItem != null) {
-			toolBarContributionItem.dispose();
-		}
-		toolBarContributionItem = null;
-		// Remove actions
-		if (coolItemToolBarMgr != null) {
-			coolItemToolBarMgr.removeAll();
-		}
-		coolItemToolBarMgr = null;
-	}
-	/**
-	 * Gets the editor contributor
-	 */
-	public IEditorActionBarContributor getEditorContributor() {
-		return editorContributor;
-	}
-	/**
-	 * Gets the extension contributor
-	 */
-	public IEditorActionBarContributor getExtensionContributor() {
-		return extensionContributor;
-	}
-	/**
-	 * Returns the editor type.
-	 */
-	public String getEditorType() {
-		return type;
-	}
-	/**
-	 * Returns the tool bar manager. If items are added or removed from the
-	 * manager be sure to call <code>updateActionBars</code>. Overridden to
-	 * support CoolBars.
-	 * 
-	 * @return the tool bar manager
-	 */
-	public IToolBarManager getToolBarManager() {
+        public Integer getAccelerator(IContributionItem item) {
+            return null;
+        }
 
-		// by pass the sub coolBar and use the real cool bar.
-		ICoolBarManager coolBarManager = getCastedParent().getCoolBarManager();
-		if (coolBarManager == null) {
-			return null;
-		}
-		
-		if (toolBarContributionItem == null) {
-			IContributionItem foundItem = coolBarManager.find(type);
-			if (foundItem instanceof ToolBarContributionItem) {
-				toolBarContributionItem = (ToolBarContributionItem)foundItem;
-				coolItemToolBarMgr = toolBarContributionItem.getToolBarManager();
-			}else {
-				coolItemToolBarMgr = new ToolBarManager(coolBarManager.getStyle());
-				toolBarContributionItem = new ToolBarContributionItem(coolItemToolBarMgr, type);
-				// Add editor item to group
-				coolBarManager.prependToGroup(
-						IWorkbenchActionConstants.GROUP_EDITOR,
-						toolBarContributionItem);
-			}
-			((ToolBarManager) coolItemToolBarMgr).setOverrides(new Overrides());
-			toolBarContributionItem.setVisible(getActive());
-			coolItemToolBarMgr.markDirty();
-		}
-		
-		return coolItemToolBarMgr;
-	}
-	/**
-	 * Returns the reference count.
-	 */
-	public int getRef() {
-		return refCount;
-	}
-	/**
-	 * Returns whether the contribution list is visible. If the visibility is
-	 * <code>true</code> then each item within the manager appears within the
-	 * parent manager. Otherwise, the items are not visible.
-	 * 
-	 * @return <code>true</code> if the manager is visible
-	 */
-	private boolean isVisible() {
-		if (toolBarContributionItem != null)
-			return toolBarContributionItem.isVisible();
-		return false;
-	}
-	/**
-	 * Sets the target part for the action bars. For views this is ignored
-	 * because each view has its own action vector. For editors this is
-	 * important because the action vector is shared by editors of the same
-	 * type.
-	 */
-	public void partChanged(IWorkbenchPart part) {
-		super.partChanged(part);
-		if (part instanceof IEditorPart) {
-			IEditorPart editor = (IEditorPart) part;
-			if (editorContributor != null)
-				editorContributor.setActiveEditor(editor);
-			if (extensionContributor != null)
-				extensionContributor.setActiveEditor(editor);
-		}
-	}
-	/**
-	 * Remove one ref to the bars.
-	 */
-	public void removeRef() {
-		--refCount;
-	}
-	/**
-	 * Activate / Deactivate the contributions.
-	 * 
-	 * Workaround for flashing when editor contributes many menu/tool
-	 * contributions. In this case, the force visibility flag determines if the
-	 * contributions should be actually made visible/hidden or just change the
-	 * enablement state.
-	 */
-	private void setActive(boolean set, boolean forceVisibility) {
-		basicSetActive(set);
-		if (isSubMenuManagerCreated())
-			((EditorMenuManager) getMenuManager()).setVisible(
-				set,
-				forceVisibility);
+        public String getAcceleratorText(IContributionItem item) {
+            return null;
+        }
 
-		if (isSubStatusLineManagerCreated())
-			 ((SubStatusLineManager) getStatusLineManager()).setVisible(set);
+        public Boolean getEnabled(IContributionItem item) {
+            if (((item instanceof ActionContributionItem) && (((ActionContributionItem) item)
+                    .getAction() instanceof RetargetAction))
+                    || enabledAllowed)
+                return null;
+            else
+                return Boolean.FALSE;
+        }
 
-		setVisible(set, forceVisibility);
-	}
-	/**
-	 * Sets the editor contributor
-	 */
-	public void setEditorContributor(IEditorActionBarContributor c) {
-		editorContributor = c;
-	}
-	/**
-	 * Sets the extension contributor
-	 */
-	public void setExtensionContributor(IEditorActionBarContributor c) {
-		extensionContributor = c;
-	}
-	/**
-	 * Sets the visibility of the manager. If the visibility is <code>true</code>
-	 * then each item within the manager appears within the parent manager.
-	 * Otherwise, the items are not visible.
-	 * 
-	 * @param visible
-	 *            the new visibility
-	 */
-	private void setVisible(boolean visible) {
-		if (toolBarContributionItem != null) {
-			toolBarContributionItem.setVisible(visible);
-			if (toolBarContributionItem.getParent() != null) {
-				toolBarContributionItem.getParent().markDirty();
-			}
-		}
-	}
-	/**
-	 * Sets the visibility of the manager. If the visibility is <code>true</code>
-	 * then each item within the manager appears within the parent manager.
-	 * Otherwise, the items are not visible if force visibility is <code>true</code>,
-	 * or grayed out if force visibility is <code>false</code>
-	 * <p>
-	 * This is a workaround for the layout flashing when editors contribute
-	 * large amounts of items.
-	 * </p>
-	 * 
-	 * @param visible
-	 *            the new visibility
-	 * @param forceVisibility
-	 *            whether to change the visibility or just the enablement
-	 *            state. This parameter is ignored if visible is <code>true</code>.
-	 */
-	private void setVisible(boolean visible, boolean forceVisibility) {
-		if (visible) {
-			if (forceVisibility) {
-				// Make the items visible
-				if (!enabledAllowed)
-					setEnabledAllowed(true);
-			} else {
-				if (enabledAllowed)
-					setEnabledAllowed(false);
-			}
-			if (!isVisible())
-				setVisible(true);
-		} else {
-			if (forceVisibility)
-				// Remove the editor tool bar items
-				setVisible(false);
-			else
-				// Disabled the tool bar items.
-				setEnabledAllowed(false);
-		}
-		
-		ICoolBarManager coolBarManager = getCastedParent().getCoolBarManager();
-		if ((coolItemToolBarMgr != null) && (coolBarManager != null) ){
-			IContributionItem[] items = coolItemToolBarMgr.getItems();
-			for (int i=0; i < items.length; i++) {
-				IContributionItem item = items[i];
-				item.setVisible(visible);
-				coolItemToolBarMgr.markDirty();
-				if (!coolBarManager.isDirty()) {
-					coolBarManager.markDirty();
-				}
-			}
-			// Update the manager
-			coolItemToolBarMgr.update(false);
-			if (toolBarContributionItem != null) {
-				toolBarContributionItem.setVisible(visible);
-			}
-			coolBarManager.update(false);
-		}
-	}
-	/**
-	 * Sets the enablement ability of all the items contributed by the editor.
-	 * 
-	 * @param enabledAllowed
-	 *            <code>true</code> if the items may enable
-	 * @since 2.0
-	 */
-	private void setEnabledAllowed(boolean enabledAllowed) {
-		if (this.enabledAllowed == enabledAllowed)
-			return;
-		this.enabledAllowed = enabledAllowed;
-		if (coolItemToolBarMgr != null) {
-			IContributionItem[] items = coolItemToolBarMgr.getItems();
-			for (int i = 0; i < items.length; i++) {
-				IContributionItem item = items[i];
-				item.update(IContributionManagerOverrides.P_ENABLED);
-			}
-		}
-	}
+        public String getText(IContributionItem item) {
+            return null;
+        }
+    }
+
+    private IToolBarManager coolItemToolBarMgr = null;
+
+    private IEditorActionBarContributor editorContributor;
+
+    private boolean enabledAllowed = true;
+
+    private IEditorActionBarContributor extensionContributor;
+
+    private int refCount;
+
+    private ToolBarContributionItem toolBarContributionItem = null;
+
+    private String type;
+
+    /**
+     * Constructs the EditorActionBars for an editor.
+     */
+    public EditorActionBars(IActionBars2 parent, String type) {
+        super(parent);
+        this.type = type;
+    }
+
+    /**
+     * Activate the contributions.
+     */
+    public void activate(boolean forceVisibility) {
+        setActive(true, forceVisibility);
+    }
+
+    /**
+     * Add one ref to the bars.
+     */
+    public void addRef() {
+        ++refCount;
+    }
+
+    /*
+     * (non-Javadoc) Method declared on SubActionBars.
+     */
+    protected SubMenuManager createSubMenuManager(IMenuManager parent) {
+        return new EditorMenuManager(parent);
+    }
+
+    /*
+     * (non-Javadoc) Method declared on SubActionBars.
+     */
+    protected SubToolBarManager createSubToolBarManager(IToolBarManager parent) {
+        // return null, editor actions are managed by CoolItemToolBarManagers
+        return null;
+    }
+
+    /**
+     * Deactivate the contributions.
+     */
+    public void deactivate(boolean forceVisibility) {
+        setActive(false, forceVisibility);
+    }
+
+    /**
+     * Dispose the contributions.
+     */
+    public void dispose() {
+        super.dispose();
+        if (editorContributor != null) editorContributor.dispose();
+        if (extensionContributor != null) extensionContributor.dispose();
+
+        /*
+         * Dispose of the contribution item, but also make sure that no one
+         * else is holding on to it. In this case, go through the
+         * SubCoolBarManager to its parent (the real CoolBarManager), and
+         * replace the reference with a placeholder.
+         */
+        if (toolBarContributionItem != null) {
+            // Create a placeholder and place it in the cool bar manager.
+            ICoolBarManager coolBarManager = getCoolBarManager();
+            if (coolBarManager instanceof SubContributionManager) {
+                SubContributionManager subManager = (SubContributionManager) coolBarManager;
+                IContributionManager manager = subManager.getParent();
+                if (manager instanceof ContributionManager) {
+                    final IContributionItem replacementItem = new PlaceholderContributionItem(
+                            toolBarContributionItem);
+                    ((ContributionManager) manager).replaceItem(replacementItem
+                            .getId(), replacementItem);
+                }
+            }
+
+            // Dispose of the replaced item.
+            toolBarContributionItem.dispose();
+        }
+        toolBarContributionItem = null;
+        // Remove actions
+        if (coolItemToolBarMgr != null) {
+            coolItemToolBarMgr.removeAll();
+        }
+        coolItemToolBarMgr = null;
+    }
+
+    /**
+     * Gets the editor contributor
+     */
+    public IEditorActionBarContributor getEditorContributor() {
+        return editorContributor;
+    }
+
+    /**
+     * Returns the editor type.
+     */
+    public String getEditorType() {
+        return type;
+    }
+
+    /**
+     * Gets the extension contributor
+     */
+    public IEditorActionBarContributor getExtensionContributor() {
+        return extensionContributor;
+    }
+
+    /**
+     * Returns the reference count.
+     */
+    public int getRef() {
+        return refCount;
+    }
+
+    /**
+     * Returns the tool bar manager. If items are added or removed from the
+     * manager be sure to call <code>updateActionBars</code>. Overridden to
+     * support CoolBars.
+     * 
+     * @return the tool bar manager
+     */
+    public IToolBarManager getToolBarManager() {
+
+        // by pass the sub coolBar and use the real cool bar.
+        ICoolBarManager coolBarManager = getCastedParent().getCoolBarManager();
+        if (coolBarManager == null) { return null; }
+
+        if (toolBarContributionItem == null) {
+            IContributionItem foundItem = coolBarManager.find(type);
+            if ((foundItem instanceof ToolBarContributionItem)) {
+                toolBarContributionItem = (ToolBarContributionItem) foundItem;
+                coolItemToolBarMgr = toolBarContributionItem
+                        .getToolBarManager();
+                if (coolItemToolBarMgr == null) {
+                    coolItemToolBarMgr = new ToolBarManager(coolBarManager
+                            .getStyle());
+                    toolBarContributionItem = new ToolBarContributionItem(
+                            coolItemToolBarMgr, type);
+                    // Add editor item to group
+                    coolBarManager.prependToGroup(
+                            IWorkbenchActionConstants.GROUP_EDITOR,
+                            toolBarContributionItem);
+                }
+            } else {
+                coolItemToolBarMgr = new ToolBarManager(coolBarManager
+                        .getStyle());
+                if ((coolBarManager instanceof ContributionManager)
+                        && (foundItem instanceof PlaceholderContributionItem)) {
+                    PlaceholderContributionItem placeholder = (PlaceholderContributionItem) foundItem;
+                    toolBarContributionItem = placeholder
+                            .createToolBarContributionItem(coolItemToolBarMgr);
+                    // Restore from a placeholder
+                    ((ContributionManager) coolBarManager).replaceItem(type,
+                            toolBarContributionItem);
+                } else {
+                    toolBarContributionItem = new ToolBarContributionItem(
+                            coolItemToolBarMgr, type);
+                    // Add editor item to group
+                    coolBarManager.prependToGroup(
+                            IWorkbenchActionConstants.GROUP_EDITOR,
+                            toolBarContributionItem);
+                }
+            }
+            ((ToolBarManager) coolItemToolBarMgr).setOverrides(new Overrides());
+            toolBarContributionItem.setVisible(getActive());
+            coolItemToolBarMgr.markDirty();
+        }
+
+        return coolItemToolBarMgr;
+    }
+
+    /**
+     * Returns whether the contribution list is visible. If the visibility is
+     * <code>true</code> then each item within the manager appears within the
+     * parent manager. Otherwise, the items are not visible.
+     * 
+     * @return <code>true</code> if the manager is visible
+     */
+    private boolean isVisible() {
+        if (toolBarContributionItem != null)
+                return toolBarContributionItem.isVisible();
+        return false;
+    }
+
+    /**
+     * Sets the target part for the action bars. For views this is ignored
+     * because each view has its own action vector. For editors this is
+     * important because the action vector is shared by editors of the same
+     * type.
+     */
+    public void partChanged(IWorkbenchPart part) {
+        super.partChanged(part);
+        if (part instanceof IEditorPart) {
+            IEditorPart editor = (IEditorPart) part;
+            if (editorContributor != null)
+                    editorContributor.setActiveEditor(editor);
+            if (extensionContributor != null)
+                    extensionContributor.setActiveEditor(editor);
+        }
+    }
+
+    /**
+     * Remove one ref to the bars.
+     */
+    public void removeRef() {
+        --refCount;
+    }
+
+    /**
+     * Activate / Deactivate the contributions.
+     * 
+     * Workaround for flashing when editor contributes many menu/tool
+     * contributions. In this case, the force visibility flag determines if the
+     * contributions should be actually made visible/hidden or just change the
+     * enablement state.
+     */
+    private void setActive(boolean set, boolean forceVisibility) {
+        basicSetActive(set);
+        if (isSubMenuManagerCreated())
+                ((EditorMenuManager) getMenuManager()).setVisible(set,
+                        forceVisibility);
+
+        if (isSubStatusLineManagerCreated())
+                ((SubStatusLineManager) getStatusLineManager()).setVisible(set);
+
+        setVisible(set, forceVisibility);
+    }
+
+    /**
+     * Sets the editor contributor
+     */
+    public void setEditorContributor(IEditorActionBarContributor c) {
+        editorContributor = c;
+    }
+
+    /**
+     * Sets the enablement ability of all the items contributed by the editor.
+     * 
+     * @param enabledAllowed
+     *            <code>true</code> if the items may enable
+     * @since 2.0
+     */
+    private void setEnabledAllowed(boolean enabledAllowed) {
+        if (this.enabledAllowed == enabledAllowed) return;
+        this.enabledAllowed = enabledAllowed;
+        if (coolItemToolBarMgr != null) {
+            IContributionItem[] items = coolItemToolBarMgr.getItems();
+            for (int i = 0; i < items.length; i++) {
+                IContributionItem item = items[i];
+                item.update(IContributionManagerOverrides.P_ENABLED);
+            }
+        }
+    }
+
+    /**
+     * Sets the extension contributor
+     */
+    public void setExtensionContributor(IEditorActionBarContributor c) {
+        extensionContributor = c;
+    }
+
+    /**
+     * Sets the visibility of the manager. If the visibility is <code>true</code>
+     * then each item within the manager appears within the parent manager.
+     * Otherwise, the items are not visible.
+     * 
+     * @param visible
+     *            the new visibility
+     */
+    private void setVisible(boolean visible) {
+        if (toolBarContributionItem != null) {
+            toolBarContributionItem.setVisible(visible);
+            if (toolBarContributionItem.getParent() != null) {
+                toolBarContributionItem.getParent().markDirty();
+            }
+        }
+    }
+
+    /**
+     * Sets the visibility of the manager. If the visibility is <code>true</code>
+     * then each item within the manager appears within the parent manager.
+     * Otherwise, the items are not visible if force visibility is <code>true</code>,
+     * or grayed out if force visibility is <code>false</code>
+     * <p>
+     * This is a workaround for the layout flashing when editors contribute
+     * large amounts of items.
+     * </p>
+     * 
+     * @param visible
+     *            the new visibility
+     * @param forceVisibility
+	 *            <code>true</code> to change the visibility or <code>false</code> 
+	 *            to change just the enablement state. This parameter is ignored 
+	 *            if visible is <code>true</code>.
+     */
+    private void setVisible(boolean visible, boolean forceVisibility) {
+        if (visible) {
+			setEnabledAllowed(true);
+            if (!isVisible()) setVisible(true);
+        } else {
+            if (forceVisibility)
+                // Remove the editor tool bar items
+                setVisible(false);
+            else
+                // Disabled the tool bar items.
+                setEnabledAllowed(false);
+        }
+
+        ICoolBarManager coolBarManager = getCastedParent().getCoolBarManager();
+        if ((coolItemToolBarMgr != null) && (coolBarManager != null)) {
+            IContributionItem[] items = coolItemToolBarMgr.getItems();
+            for (int i = 0; i < items.length; i++) {
+                IContributionItem item = items[i];
+				item.setVisible(visible || !forceVisibility);
+                coolItemToolBarMgr.markDirty();
+                if (!coolBarManager.isDirty()) {
+                    coolBarManager.markDirty();
+                }
+            }
+            // Update the manager
+            coolItemToolBarMgr.update(false);
+            if (toolBarContributionItem != null) {
+				toolBarContributionItem.setVisible(visible || !forceVisibility);
+            }
+            coolBarManager.update(false);
+        }
+    }
 }
diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/EditorArea.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/EditorArea.java
index db206c2..75e54c1 100644
--- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/EditorArea.java
+++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/EditorArea.java
@@ -350,7 +350,7 @@
 	
 	/* (non-Javadoc)
 	 * @see org.eclipse.ui.internal.IWorkbenchDropTarget#getType()
-	 */
+	 */ 
 	public int getType() {
 		return EDITOR;
 	}
diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/EditorManager.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/EditorManager.java
index cebcaca..d4a69d8 100644
--- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/EditorManager.java
+++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/EditorManager.java
@@ -515,7 +515,7 @@
 			descArray[i] = innerDesc;
 			partArray[i] = createPart(descArray[i]);
 			refArray[i] = new Editor();
-			createSite(partArray[i],descArray[i],inputArray[i]);
+			createSite(ref, partArray[i],descArray[i],inputArray[i]);
 			((Editor)refArray[i]).setPart(partArray[i]);			
 		}
 		part.setChildren(partArray);
@@ -560,8 +560,8 @@
 	/*
 	 * Create the site and initialize it with its action bars.
 	 */
-	private void createSite(final IEditorPart part, final EditorDescriptor desc, final IEditorInput input) throws PartInitException {
-		EditorSite site = new EditorSite(part, page, desc);
+	private void createSite(final IEditorReference ref, final IEditorPart part, final EditorDescriptor desc, final IEditorInput input) throws PartInitException {
+		EditorSite site = new EditorSite(ref, part, page, desc);
 		final String label = part.getTitle();
 		try {
 			UIStats.start(UIStats.INIT_PART,label);
@@ -629,7 +629,7 @@
 			UIStats.end(UIStats.CREATE_PART,label);
 		}
 		// Open the instance.
-		createSite(editor, desc, input);
+		createSite(ref, editor, desc, input);
 		((Editor)ref).setPart(editor);
 		createEditorTab(ref, desc, input, setVisible);
 	}
@@ -683,7 +683,7 @@
 		if (cEditor == null) {
 			return null;
 		} else {				
-			createSite(cEditor, desc, input);
+			createSite(ref, cEditor, desc, input);
 			((Editor)ref).setPart(cEditor);
 			createEditorTab(ref, desc, input, true);
 			return ref;
diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/EditorSite.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/EditorSite.java
index 1cd750b..2097d39 100644
--- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/EditorSite.java
+++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/EditorSite.java
@@ -30,10 +30,10 @@
  * Constructs an EditorSite for an editor.  The resource editor descriptor
  * may be omitted for an OLE editor.
  */
-public EditorSite(IEditorPart editor, WorkbenchPage page, 
+public EditorSite(IEditorReference ref, IEditorPart editor, WorkbenchPage page, 
 	EditorDescriptor desc) 
 {
-	super(editor, page);
+	super(ref, editor, page);
 	if (desc != null) {
 		this.desc = desc;
 		if (desc.getConfigurationElement() != null) {
diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/EditorsDropDownAction.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/EditorsDropDownAction.java
index 1fbb369..bd5a90f 100644
--- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/EditorsDropDownAction.java
+++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/EditorsDropDownAction.java
@@ -11,12 +11,11 @@
 package org.eclipse.ui.internal;
 
 import org.eclipse.jface.action.Action;
-
 import org.eclipse.ui.IWorkbenchWindow;
 
 /**
  * The <code>EditorsDropDownAction</code> is used to show the
- * editors drop-down. 
+ * editors drop-down.
  */
 public class EditorsDropDownAction extends Action {
 	private IWorkbenchWindow window;
@@ -37,5 +36,16 @@
 	/* (non-Javadoc)
 	 * Method declared on IAction.
 	 */
-	public void run() {}
+	public void run() {
+		/*
+		WorkbenchPage page = (WorkbenchPage) window.getActivePage();
+		if (page != null) {
+			EditorArea editorArea = (EditorArea) page.getEditorPresentation().getLayoutPart();
+			EditorWorkbook workbook = editorArea.getActiveWorkbook();
+			if (workbook instanceof DropDownEditorWorkbook2) {
+				((DropDownEditorWorkbook2) workbook).dropDown();
+			}
+		}
+		*/
+	}
 }
diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/ExtensionEventHandler.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/ExtensionEventHandler.java
index 7a1cf9c..8d4c714 100644
--- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/ExtensionEventHandler.java
+++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/ExtensionEventHandler.java
@@ -13,19 +13,22 @@
 
 import java.util.ArrayList;
 import java.util.Iterator;
+import java.util.List;
 
+import org.eclipse.core.runtime.IAdaptable;
 import org.eclipse.core.runtime.IConfigurationElement;
 import org.eclipse.core.runtime.IExtension;
-import org.eclipse.core.runtime.IExtensionPoint;
-import org.eclipse.core.runtime.IAdaptable;
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.core.runtime.MultiStatus;
 import org.eclipse.core.runtime.IExtensionDelta;
+import org.eclipse.core.runtime.IExtensionPoint;
 import org.eclipse.core.runtime.IRegistryChangeEvent;
 import org.eclipse.core.runtime.IRegistryChangeListener;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.MultiStatus;
 import org.eclipse.jface.action.IContributionItem;
 import org.eclipse.jface.action.MenuManager;
 import org.eclipse.jface.dialogs.ErrorDialog;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.preference.PreferenceManager;
 import org.eclipse.swt.widgets.Display;
 import org.eclipse.swt.widgets.Shell;
 import org.eclipse.ui.IEditorInput;
@@ -44,6 +47,8 @@
 import org.eclipse.ui.PlatformUI;
 import org.eclipse.ui.WorkbenchException;
 import org.eclipse.ui.XMLMemento;
+import org.eclipse.ui.internal.dialogs.PropertyPageContributorManager;
+import org.eclipse.ui.internal.dialogs.WorkbenchPreferenceNode;
 import org.eclipse.ui.internal.registry.ActionSetPartAssociationsReader;
 import org.eclipse.ui.internal.registry.ActionSetRegistry;
 import org.eclipse.ui.internal.registry.ActionSetRegistryReader;
@@ -54,6 +59,8 @@
 import org.eclipse.ui.internal.registry.IViewRegistry;
 import org.eclipse.ui.internal.registry.PerspectiveRegistry;
 import org.eclipse.ui.internal.registry.PerspectiveRegistryReader;
+import org.eclipse.ui.internal.registry.PreferencePageRegistryReader;
+import org.eclipse.ui.internal.registry.PropertyPagesRegistryReader;
 import org.eclipse.ui.internal.registry.ViewRegistry;
 import org.eclipse.ui.internal.registry.ViewRegistryReader;
 import org.eclipse.ui.internal.registry.WorkingSetRegistry;
@@ -65,7 +72,7 @@
 	private static final String TAG_PART="part";//$NON-NLS-1$
 	private static final String ATT_ID="id";//$NON-NLS-1$
 	private static final String TAG_PROVIDER = "imageprovider";//$NON-NLS-1$
-	private static final String TAG_ACTION_SET_PART_ASSOCIATION ="actionSetPartAssociation";
+	private static final String TAG_ACTION_SET_PART_ASSOCIATION ="actionSetPartAssociation"; //$NON-NLS-1$
 
 	IWorkbench workbench;
 	
@@ -117,13 +124,14 @@
 			ext = extDelta.getExtension();
 			asyncAppear(display, extPt, ext);
 		}
-		iter = revokeList.iterator();
-		while(iter.hasNext()) {
-			extDelta = (IExtensionDelta) iter.next();
-			extPt = extDelta.getExtensionPoint();
-			ext = extDelta.getExtension();
-			asyncRevoke(display, extPt, ext);
-		}	
+		// Suspend support for removing a plug-in until this is more stable
+//		iter = revokeList.iterator();
+//		while(iter.hasNext()) {
+//			extDelta = (IExtensionDelta) iter.next();
+//			extPt = extDelta.getExtensionPoint();
+//			ext = extDelta.getExtension();
+//			asyncRevoke(display, extPt, ext);
+//		}	
 	}
 	private void asyncAppear(Display display, final IExtensionPoint extpt, final IExtension ext) {
 		Runnable run = new Runnable() {
@@ -161,6 +169,10 @@
 			loadPerspective(ext);
 			return;
 		}
+		if (name.equalsIgnoreCase(IWorkbenchConstants.PL_PERSPECTIVE_EXTENSIONS)) {
+			loadPerspectiveExtensions(ext);
+			return;
+		}
 		if (name.equalsIgnoreCase(IWorkbenchConstants.PL_ACTION_SETS)) {
 			loadActionSets(ext);
 			return;
@@ -173,7 +185,86 @@
 			loadWorkingSets(ext);
 			return;
 		}
-				
+		if (name.equalsIgnoreCase(IWorkbenchConstants.PL_POPUP_MENU)) {
+			loadPopupMenu(ext);
+			return;
+		}
+		if (name.equalsIgnoreCase(IWorkbenchConstants.PL_PREFERENCES)) {
+			loadPreferencePages(ext);
+			return;
+		}
+		if (name.equalsIgnoreCase(IWorkbenchConstants.PL_PROPERTY_PAGES)) {
+			loadPropertyPages(ext);
+			return;
+		}		
+	}
+	
+	private void loadPropertyPages(IExtension ext) {
+		PropertyPageContributorManager manager = PropertyPageContributorManager.getManager();
+		PropertyPagesRegistryReader reader = new PropertyPagesRegistryReader(manager);
+		IConfigurationElement [] elements = ext.getConfigurationElements();
+		for (int i = 0; i < elements.length; i++) {
+			reader.readElement(elements[i]);
+		}
+	}
+
+	private void loadPreferencePages(IExtension ext) {
+		PreferenceManager manager = workbench.getPreferenceManager();
+		List nodes = manager.getElements(PreferenceManager.POST_ORDER);
+		IConfigurationElement [] elements = ext.getConfigurationElements();
+		for (int i = 0; i < elements.length; i++) {
+			WorkbenchPreferenceNode node = PreferencePageRegistryReader.createNode(workbench, elements[i]);
+			if (node == null)
+				continue;
+			String category = node.getCategory();
+			if (category == null) {
+				manager.addToRoot(node);
+			}
+			else {
+				WorkbenchPreferenceNode parent = null;
+				for (Iterator j = nodes.iterator(); j.hasNext();) {
+					WorkbenchPreferenceNode element = (WorkbenchPreferenceNode) j.next();
+					if (category.equals(element.getId())) {
+						parent = element;
+						break;
+					}
+				}
+				if (parent == null) {
+					//Could not find the parent - log
+					WorkbenchPlugin.log("Invalid preference page path: " + category); //$NON-NLS-1$
+					manager.addToRoot(node);
+				}
+				else {
+					parent.add(node);
+				}				
+			}
+		}
+	}
+
+	/**
+	 * TODO: object contributions are easy to update, but viewer contributions are not because they're 
+	 * statically cached in anonymous PopupMenuExtenders.  Currently you will be prompted to restart in 
+	 * the case of a viewer contribtion. 
+	 * 
+	 * We can implement this refresh by keeping a weak set of references to PopupMenuExtenders and 
+	 * iterating over them on a delta.  We add a method to PopupMenuExtender that will supply an extension
+	 * to the underlying staticActionBuilder for processing. 
+	 */
+	private void loadPopupMenu(IExtension ext) {
+		ObjectActionContributorManager oMan = ObjectActionContributorManager.getManager();
+		ObjectActionContributorReader oReader = new ObjectActionContributorReader();
+		oReader.setManager(oMan);
+		IConfigurationElement[] elements = ext.getConfigurationElements();
+		boolean restartNeeded = false;
+		// takes care of object contributions
+		for (int i = 0; i < elements.length; i++) {
+			oReader.readElement(elements[i]);
+			if (elements[i].getName().equals(ViewerActionBuilder.TAG_CONTRIBUTION_TYPE))
+				restartNeeded = true;	
+		}
+
+		if (restartNeeded) 
+			restartPrompt(ExtensionEventHandlerMessages.getString("ExtensionEventHandler.new_view_contributions")); //$NON-NLS-1$
 	}
 
 	private void revoke(IExtensionPoint extPt, IExtension ext) {
@@ -298,7 +389,7 @@
 //								//((WorkbenchPage)pages[j]).getStateMap().put(id, memento);
 //							}
 							((WorkbenchPage)pages[j]).hideView(viewRef);
-							((WorkbenchPage)pages[j]).getViewFactory().releaseView(id);
+							((WorkbenchPage)pages[j]).getViewFactory().releaseView(viewRef);
 						}
 						viewsRemoved.add(id);
 						((ViewRegistry)vReg).remove(id);
@@ -340,7 +431,7 @@
 		IContributionItem[] items = menuManager.getItems();
 		menuManager = null;
 		for(int i=0; i<items.length; i++)
-			if (items[i] instanceof MenuManager && ((MenuManager)items[i]).getMenuText().equals("&Window")) {
+			if (items[i] instanceof MenuManager && ((MenuManager)items[i]).getMenuText().equals("&Window")) { //$NON-NLS-1$
 				menuManager = (MenuManager)items[i];
 				break;
 			}
@@ -349,7 +440,7 @@
 		items = menuManager.getItems();
 		menuManager = null;
 		for(int i=0; i<items.length; i++)
-			if (items[i] instanceof MenuManager && ((MenuManager)items[i]).getMenuText().equals("Show &View")) {
+			if (items[i] instanceof MenuManager && ((MenuManager)items[i]).getMenuText().equals("Show &View")) { //$NON-NLS-1$
 				menuManager = (MenuManager)items[i];
 				break;
 			}
@@ -574,6 +665,39 @@
 		}
 	}
 
+	private void loadPerspectiveExtensions(IExtension ext) {
+		IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
+		if (window == null)
+			return;
+		IWorkbenchPage page = window.getActivePage();
+		if (page == null)
+			return;
+	
+		// Get the current perspective.
+		IPerspectiveDescriptor persp = page.getPerspective();
+		if (persp == null)
+			return;
+		String currentId = persp.getId();
+		IConfigurationElement[] elements = ext.getConfigurationElements();
+		for (int i = 0; i < elements.length; i++) {
+			// If any of these refer to the current perspective, output
+			// a message saying this perspective will need to be reset
+			// in order to see the changes.  For any other case, the
+			// perspective extension registry will be rebuilt anyway so
+			// just ignore it.
+			String id = elements[i].getAttribute(ATT_TARGET_ID);
+			if (id == null)
+				continue;
+			if (id.equals(currentId)) {
+				// Display message
+				MessageDialog.openInformation(window.getShell(), ExtensionEventHandlerMessages.getString("ExtensionEventHandler.newPerspectiveExtensionTitle"), //$NON-NLS-1$
+						ExtensionEventHandlerMessages.getString("ExtensionEventHandler.newPerspectiveExtension"));  //$NON-NLS-1$
+				// don't bother outputing this message more than once.
+				break;
+			}
+		}
+	}
+
 	private void restorePerspectiveState(MultiStatus result, String id){
 		IWorkbenchWindow[] windows = workbench.getWorkbenchWindows();
 		IMemento memento;
@@ -721,7 +845,7 @@
 						IViewReference viewRef = viewFactory.getView(id);
 						if (viewRef != null) {
 							((WorkbenchPage)pages[j]).hideView(viewRef);
-							((WorkbenchPage)pages[j]).getViewFactory().releaseView(id);
+							((WorkbenchPage)pages[j]).getViewFactory().releaseView(viewRef);
 						}
 					}
 				}
@@ -792,4 +916,16 @@
 			}
 		}
 	}
+	
+	private void restartPrompt(String message) {
+		Shell parentShell = null;
+		IWorkbenchWindow window =workbench.getActiveWorkbenchWindow();
+		if (window != null)
+			parentShell = window.getShell();
+
+		message +=  ExtensionEventHandlerMessages.getString("ExtensionEventHandler.need_to_restart"); //$NON-NLS-1$
+		if (MessageDialog.openQuestion(parentShell, ExtensionEventHandlerMessages.getString("ExtensionEventHandler.restart_workbench"), message)) { //$NON-NLS-1$
+			workbench.restart();
+		}
+	}
 }
diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/FolderLayout.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/FolderLayout.java
index d20399a..fd75311 100644
--- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/FolderLayout.java
+++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/FolderLayout.java
@@ -88,7 +88,9 @@
 
 				ViewPane newPart = LayoutHelper.createView(
 						pageLayout.getViewFactory(),
-						viewId);
+						viewId,
+						// @issue view should refer to current perspective for theme setting
+						pageLayout.getTheme());
 				linkPartToPageLayout(viewId, newPart);
 				folder.add(newPart);
 			}
@@ -96,6 +98,20 @@
 			// cannot safely open the dialog so log the problem
 			WorkbenchPlugin.log(e.getMessage());
 		}
+		
+		// if page layout is fixed, add to fixed view list
+		if (pageLayout.isFixed() && 
+				!pageLayout.getFixedViews().contains(viewFactory.getView(viewId)))
+			pageLayout.getFixedViews().add(viewFactory.getView(viewId));
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.ui.IFolderLayout#addFixedView(java.lang.String)
+	 */
+	public void addFixedView(String viewId) {
+		addView(viewId);
+		if (!pageLayout.getFixedViews().contains(viewFactory.getView(viewId)))
+			pageLayout.getFixedViews().add(viewFactory.getView(viewId));		
 	}
 
 	/**
diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/IPreferenceConstants.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/IPreferenceConstants.java
index 7fce6df..b9bbe98 100644
--- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/IPreferenceConstants.java
+++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/IPreferenceConstants.java
@@ -138,4 +138,7 @@
 	 * </p>
 	 */
 	public static final String MULTI_KEY_ASSIST_TIME = "MULTI_KEY_ASSIST_TIME"; //$NON-NLS-1$
+	
+	//Preferences for the floating toolbar
+	public static final String SHOW_FLOATING_PROGRESS = "SHOW_FLOATING_PROGRESS"; //$NON-NLS-1$
 }
\ No newline at end of file
diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/IWorkbenchConstants.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/IWorkbenchConstants.java
index 987f430..c1527e1 100644
--- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/IWorkbenchConstants.java
+++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/IWorkbenchConstants.java
@@ -38,6 +38,7 @@
 	public static final String PL_DROP_ACTIONS ="dropActions"; //$NON-NLS-1$
 	public static final String PL_WORKINGSETS = "workingSets"; //$NON-NLS-1$	
 	public static final String PL_STARTUP ="startup"; //$NON-NLS-1$
+	public static final String PL_THEMES ="themes"; //$NON-NLS-1$
 		
 	/**
 	 * @deprecated
@@ -139,6 +140,7 @@
 	public static final String TAG_OPEN_IN_PLACE = "open_in_place"; //$NON-NLS-1$
 	public static final String TAG_PROGRAM_NAME = "program_name"; //$NON-NLS-1$
 	public static final String TAG_FAST_VIEWS = "fastViews"; //$NON-NLS-1$
+	public static final String TAG_FIXED_VIEWS = "fixedViews"; //$NON-NLS-1$
 	public static final String TAG_VIEW_STATE = "viewState"; //$NON-NLS-1$
 	public static final String TAG_SINGLETON="singleton"; //$NON-NLS-1$
 	public static final String TAG_EDITOR_REUSE_THRESHOLD="editorReuseThreshold"; //$NON-NLS-1$
@@ -158,6 +160,7 @@
 	public static final String TAG_TYPE_SEPARATOR = "typeSeparator";	//$NON-NLS-1$
 	public static final String TAG_TYPE_GROUPMARKER = "typeGroupMarker";	//$NON-NLS-1$
 	public static final String TAG_TYPE_TOOLBARCONTRIBUTION = "typeToolBarContribution"; //$NON-NLS-1$
+	public static final String TAG_TYPE_PLACEHOLDER = "typePlaceholder"; //$NON-NLS-1$
 	public static final String TAG_COOLITEM = "coolItem";	//$NON-NLS-1$
 	public static final String TAG_INDEX = "index";	//$NON-NLS-1$
 	public static final String TAG_PINNED = "pinned";	//$NON-NLS-1$
@@ -179,4 +182,6 @@
 	
 	//Fonts
 	public static final String SMALL_FONT = "org.eclipse.ui.smallFont"; //$NON-NLS-1$
+	public static final String TAG_THEME = "theme";//$NON-NLS-1$	
+	public static final String TAG_FIXED = "fixed";//$NON-NLS-1$	
 }
diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/LayoutHelper.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/LayoutHelper.java
index 1b87cd6..fa29625 100644
--- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/LayoutHelper.java
+++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/LayoutHelper.java
@@ -164,10 +164,37 @@
 				viewId);
 		ViewPane newPart = (ViewPane) ref.getPane();
 		if (newPart == null) {
-			newPart =
-				new ViewPane(
-					(IViewReference) ref,
-					(WorkbenchPage) ref.getPage());
+			WorkbenchPage page = (WorkbenchPage) ref.getPage();
+			newPart = new ViewPane((IViewReference)ref, page);
+			ref.setPane(newPart);
+		}
+		return newPart;
+	}
+	
+	/**
+	 * Create the view with a specified theme.  
+	 * If it's already been been created in the provided 
+	 * factory, return the shared instance.
+	 * 
+	 * @param factory the <code>ViewFactory</code> to use.
+	 * @param viewID the view id to use.
+	 * @return the new <code>ViewPane</code>.
+	 * @throws PartInitException thrown if there is a problem creating the view.
+	 *
+	 * @issue view should refer to current perspective for theme setting
+	 */
+	public static final ViewPane createView(
+			ViewFactory factory,
+			String viewId, 
+			String theme)
+	throws PartInitException {
+		WorkbenchPartReference ref =
+		(WorkbenchPartReference) factory.createView(
+				viewId);
+		ViewPane newPart = (ViewPane) ref.getPane();
+		if (newPart == null) {
+			WorkbenchPage page = (WorkbenchPage) ref.getPage();
+			newPart = new ViewPane((IViewReference)ref, page, theme);
 			ref.setPane(newPart);
 		}
 		return newPart;
diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/ObjectActionContributorReader.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/ObjectActionContributorReader.java
index b10427d..ff5ec6d 100644
--- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/ObjectActionContributorReader.java
+++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/ObjectActionContributorReader.java
@@ -56,8 +56,13 @@
  * found there.
  */
 public void readPopupContributors(ObjectActionContributorManager mng) {
-	manager = mng;
+	setManager(mng);
 	IPluginRegistry registry = Platform.getPluginRegistry();
 	readRegistry(registry, PlatformUI.PLUGIN_ID, IWorkbenchConstants.PL_POPUP_MENU);
 }
+
+// for dynamic UI
+public void setManager(ObjectActionContributorManager mng) {
+	manager = mng;
+}
 }
diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/PageLayout.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/PageLayout.java
index 5fad53c..4d999c8 100644
--- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/PageLayout.java
+++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/PageLayout.java
@@ -60,7 +60,9 @@
 	private IPerspectiveDescriptor descriptor;
 	private LayoutPart editorFolder;
 	private boolean editorVisible = true;
+	private boolean fixed;
 	private ArrayList fastViews = new ArrayList(3);
+	private ArrayList fixedViews = new ArrayList(3);
 	private Map mapFastViewToWidthRatio = new HashMap(10);
 	private Map mapIDtoFolder = new HashMap(10);
 	private Map mapIDtoPart = new HashMap(10);
@@ -70,7 +72,8 @@
 	private ArrayList showInPartIds = new ArrayList(3);
 	private ArrayList showViewActionIds = new ArrayList(3);
 	private ViewFactory viewFactory;
-
+	private String theme;
+	
 	/**
 	 * Constructs a new PageLayout for other purposes.
 	 */
@@ -152,6 +155,19 @@
 			}
 		}
 	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.ui.IPageLayout#addFixedView(java.lang.String, int, float, java.lang.String)
+	 */
+	public void addFixedView(		
+			String viewId,
+			int relationship,
+			float ratio,
+			String refId) {
+		addView(viewId, relationship, ratio, refId);
+		if (!fixedViews.contains(viewFactory.getView(viewId)))
+			fixedViews.add(viewFactory.getView(viewId));
+	}
 
 	/**
 	 * Adds a creation wizard to the File New menu.
@@ -259,7 +275,6 @@
 			return;
 
 		try {
-
 			// Create the part.
 			LayoutPart newPart = createView(viewId);
 			if (newPart == null) {
@@ -270,6 +285,10 @@
 		} catch (PartInitException e) {
 			WorkbenchPlugin.log(e.getMessage());
 		}
+		
+		// add view to fixed list if we are a fixed layout
+		if (fixed && !fixedViews.contains(viewFactory.getView(viewId)))
+			fixedViews.add(viewFactory.getView(viewId));
 	}
 
 	/**
@@ -289,7 +308,7 @@
 
 		return false;
 	}
-
+	
 	/* (non-Javadoc)
 	 * @see org.eclipse.ui.IPageLayout#createFolder(java.lang.String, int, float, java.lang.String)
 	 */
@@ -305,8 +324,10 @@
 				viewFactory);
 
 		// Create the folder.
-		PartTabFolder folder = new PartTabFolder();
+		PartTabFolder folder = new PartTabFolder(rootLayoutContainer.page);
 		folder.setID(folderId);
+		// @issue should the folder capture the current theme?
+		folder.setTheme(theme);
 		addPart(folder, folderId, relationship, ratio, refId);
 
 		// Create a wrapper.
@@ -329,7 +350,7 @@
 		// Create the folder.
 		ContainerPlaceholder folder = new ContainerPlaceholder(null);
 		folder.setContainer(rootLayoutContainer);
-		folder.setRealContainer(new PartTabFolder());
+		folder.setRealContainer(new PartTabFolder(rootLayoutContainer.page));
 		folder.setID(folderId);
 		addPart(folder, folderId, relationship, ratio, refId);
 
@@ -354,7 +375,8 @@
 				viewFactory.getViewRegistry().find(partID);
 			if (WorkbenchActivityHelper.filterItem(viewDescriptor))
 				return null;
-			return LayoutHelper.createView(getViewFactory(), partID);
+			// @issue view should refer to current perspective for theme setting
+			return LayoutHelper.createView(getViewFactory(), partID, theme);
 		}
 	}
 
@@ -393,6 +415,14 @@
 	/**
 	 * @return <code>ArrayList</code>
 	 */
+	/*package*/
+	ArrayList getFixedViews() {
+		return fixedViews;
+	}
+	
+	/**
+	 * @return <code>ArrayList</code>
+	 */
 	public ArrayList getFastViews() {
 		return fastViews;
 	}
@@ -528,6 +558,20 @@
 	public void setEditorReuseThreshold(int openEditors) {
 		//no-op
 	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.ui.IPageLayout#setFixed(boolean)
+	 */
+	public void setFixed(boolean fixed) { 
+		this.fixed = fixed;
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.ui.IPageLayout#getFixed()
+	 */
+	public boolean isFixed() {
+		return fixed;
+	}
 
 	/**
 	 * Map the folder part containing the given view ID.
@@ -587,7 +631,7 @@
 		// a new folder and add the new view.
 		LayoutPart refPart = getRefPart(refId);
 		if (refPart != null) {
-			PartTabFolder newFolder = new PartTabFolder();
+			PartTabFolder newFolder = new PartTabFolder(rootLayoutContainer.page);
 			rootLayoutContainer.replace(refPart, newFolder);
 			newFolder.add(refPart);
 			newFolder.add(newPart);
@@ -614,6 +658,12 @@
 
 		// Create the placeholder.
 		PartPlaceholder newPart = new PartPlaceholder(viewId);
+		
+		LayoutPart refPart = getRefPart(refId);
+		if (refPart != null) {
+			newPart.setContainer(refPart.getContainer());
+		}		
+		
 		stackPart(newPart, viewId, refId);
 	}
 
@@ -635,9 +685,18 @@
 				stackPlaceholder(viewId, refId);
 				LayoutHelper.addViewActivator(this, viewId);
 			}
-			stackPart(newPart, viewId, refId);
+			else
+				stackPart(newPart, viewId, refId);
 		} catch (PartInitException e) {
 			WorkbenchPlugin.log(e.getMessage());
 		}
 	}
+	
+	void setTheme(String theme) {
+		this.theme = theme;
+	}
+	
+	String getTheme() {
+		return this.theme;
+	}
 }
diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/PartPane.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/PartPane.java
index 6717f86..4a44a6a 100644
--- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/PartPane.java
+++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/PartPane.java
@@ -21,6 +21,8 @@
 import org.eclipse.jface.util.PropertyChangeEvent;
 import org.eclipse.jface.util.SafeRunnable;
 import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.CTabItem2;
+import org.eclipse.swt.custom.ViewForm;
 import org.eclipse.swt.custom.ViewForm2;
 import org.eclipse.swt.events.FocusAdapter;
 import org.eclipse.swt.events.FocusEvent;
@@ -29,6 +31,7 @@
 import org.eclipse.swt.events.KeyListener;
 import org.eclipse.swt.events.SelectionAdapter;
 import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.graphics.Image;
 import org.eclipse.swt.graphics.Point;
 import org.eclipse.swt.graphics.Rectangle;
 import org.eclipse.swt.layout.FillLayout;
@@ -52,11 +55,9 @@
  * and editor panes.
  */
 public abstract class PartPane extends LayoutPart
-	implements Listener, IWorkbenchDragSource
+	implements Listener
 {
-	
 	public static final String PROP_ZOOMED = "zoomed"; //$NON-NLS-1$
-
 	private boolean isZoomed = false;
 	private MenuManager paneMenuManager;
 	protected IWorkbenchPartReference partReference;
@@ -74,62 +75,15 @@
 			return true;
 		}
 		public void fill(Menu menu, int index) {
-			MenuItem item; 
-		
-			// Get various view states.
-			final boolean isFastView = (page.getActiveFastView() == partReference);
-			final boolean isZoomed = page.isZoomed();
-			boolean canZoom = (getWindow() instanceof IWorkbenchWindow);
-		
-			// add restore item
-			item = new MenuItem(menu, SWT.NONE);
-			item.setText(WorkbenchMessages.getString("PartPane.restore")); //$NON-NLS-1$
-			item.addSelectionListener(new SelectionAdapter() {
-				public void widgetSelected(SelectionEvent e) {
-					if (isZoomed)
-						doZoom();
-				}
-			});
-			item.setEnabled(isZoomed);
-			
-			//Add move menu
-			item = new MenuItem(menu, SWT.CASCADE);
-			item.setText(WorkbenchMessages.getString("PartPane.move")); //$NON-NLS-1$
-			Menu moveMenu = new Menu(menu);
-			item.setMenu(moveMenu);
-			addMoveItems(moveMenu);
-			
-			//Add size menu
-			item = new MenuItem(menu, SWT.CASCADE);
-			item.setText(WorkbenchMessages.getString("PartPane.size")); //$NON-NLS-1$
-			Menu sizeMenu = new Menu(menu);
-			item.setMenu(sizeMenu);
-			addSizeItems(sizeMenu);
-			
+			// add view context menu items
+			final boolean isFastView = (page.getActiveFastView() == partReference);			
+			addRestoreMenuItem(menu);
+			addMoveMenuItem(menu);
+			addSizeMenuItem(menu);			
 			addFastViewMenuItem(menu,isFastView);
-		
-			// add maximize item
-			item = new MenuItem(menu, SWT.NONE);
-			item.setText(WorkbenchMessages.getString("PartPane.maximize")); //$NON-NLS-1$
-			item.addSelectionListener(new SelectionAdapter() {
-				public void widgetSelected(SelectionEvent e) {
-					doZoom();
-				}
-			});
-			item.setEnabled(!isZoomed && canZoom);
-		
-			addPinEditorItem(menu);
-			
-			new MenuItem(menu, SWT.SEPARATOR);
-			
-			// add close item
-			item = new MenuItem(menu, SWT.NONE);
-			item.setText(WorkbenchMessages.getString("PartPane.close")); //$NON-NLS-1$
-			item.addSelectionListener(new SelectionAdapter() {
-				public void widgetSelected(SelectionEvent e) {
-					doHide();
-				}
-			});			
+			addMaximizeMenuItem(menu);		
+			addPinEditorItem(menu);						
+			addCloseMenuItem(menu);	
 		}
 	}
 	
@@ -190,6 +144,64 @@
 	page.addPart(partReference);
 	page.firePartOpened(part[0]);	
 }
+
+protected void addRestoreMenuItem (Menu menu) {
+	// add restore item
+	MenuItem item = new MenuItem(menu, SWT.NONE);
+	item.setText(WorkbenchMessages.getString("PartPane.restore")); //$NON-NLS-1$
+	item.addSelectionListener(new SelectionAdapter() {
+		public void widgetSelected(SelectionEvent e) {
+			if (isZoomed())
+				doZoom();
+		}
+	});
+	item.setEnabled(isZoomed());
+}
+
+protected void addMoveMenuItem (Menu menu) {
+	//Add move menu
+	MenuItem item = new MenuItem(menu, SWT.CASCADE);
+	item.setText(WorkbenchMessages.getString("PartPane.move")); //$NON-NLS-1$
+	Menu moveMenu = new Menu(menu);
+	item.setMenu(moveMenu);
+	addMoveItems(moveMenu);
+	
+}
+
+protected void addSizeMenuItem (Menu menu) {
+	//Add size menu
+	MenuItem item = new MenuItem(menu, SWT.CASCADE);
+	item.setText(WorkbenchMessages.getString("PartPane.size")); //$NON-NLS-1$
+	Menu sizeMenu = new Menu(menu);
+	item.setMenu(sizeMenu);
+	addSizeItems(sizeMenu);
+}
+
+protected void addMaximizeMenuItem (Menu menu) {
+	// add maximize item
+	boolean canZoom = (getWindow() instanceof IWorkbenchWindow);
+	MenuItem item = new MenuItem(menu, SWT.NONE);
+	item.setText(WorkbenchMessages.getString("PartPane.maximize")); //$NON-NLS-1$
+	item.addSelectionListener(new SelectionAdapter() {
+		public void widgetSelected(SelectionEvent e) {
+			doZoom();
+		}
+	});
+	item.setEnabled(!isZoomed() && canZoom);
+}
+
+protected void addCloseMenuItem (Menu menu) {
+	// add close item
+	new MenuItem(menu, SWT.SEPARATOR);
+	MenuItem item = new MenuItem(menu, SWT.NONE);
+	item.setText(WorkbenchMessages.getString("PartPane.close")); //$NON-NLS-1$
+	item.addSelectionListener(new SelectionAdapter() {
+		public void widgetSelected(SelectionEvent e) {
+			doHide();
+		}
+	});		
+}
+
 /**
  * 
  */
@@ -292,6 +304,13 @@
 	// account for the borders
 	topHeight = control.computeTrim(0, 0, 0, topHeight).height;
 	
+	/* add +1 for highlight line. ViewForm adds this *inside* client area
+	 * even though it's arguably an inset; see ViewForm.layout for details.
+	 */
+	if (top) {
+		topHeight += 1;
+	}
+	
 	return topHeight;
 }
 
@@ -385,6 +404,9 @@
  * Set whether the pane is zoomed or not
  */
 public void setZoomed(boolean isZoomed) {
+	if (this.isZoomed == isZoomed)
+		return; // do nothing if we're already in the right state.
+	
 	this.isZoomed = isZoomed;
 	
 	final Object[] listeners = getPropertyListeners().getListeners();
@@ -396,7 +418,6 @@
 			((IPropertyChangeListener)listeners[i]).propertyChange(event);
 	}
 }
-
 /**
  * Informs the pane that it's window shell has
  * been activated.
@@ -411,7 +432,12 @@
  * Indicate focus in part.
  */
 public abstract void showFocus(boolean inFocus);
-
+/**
+ * @see IPartDropTarget::targetPartFor
+ */
+public LayoutPart targetPartFor(LayoutPart dragSource) {
+	return this;
+}
 
 /**
  * Show a title label menu for this pane.
@@ -424,13 +450,13 @@
 /**
  * Show a title label menu for this pane.
  */
-final public void showPaneMenu(Control parent, Point point) {
+final protected void showPaneMenu(Control parent, Point point) {
 	if(paneMenuManager == null) {
 		paneMenuManager = new MenuManager();
 		paneMenuManager.add(new PaneContribution());			
 	}
-	
 	Menu aMenu = paneMenuManager.createContextMenu(parent);
+	// open menu    
 	aMenu.setLocation(point.x, point.y);
 	aMenu.setVisible(true);
 }
@@ -556,7 +582,16 @@
 				folder.showBusy(PartPane.this);
 		}
 	};
+	
 }
-
-
+	
+	/**
+	 * Set the image to image. item is used for future work where 
+	 * the tab item may be updated.
+	 * @param item
+	 * @param image
+	 */
+	void setImage(CTabItem2 item, Image image){
+		//Do nothing by default
+	}
 }
diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/PartSashContainer.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/PartSashContainer.java
index 258efca..8b07027 100644
--- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/PartSashContainer.java
+++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/PartSashContainer.java
@@ -28,495 +28,475 @@
  * the container.
  */
 public abstract class PartSashContainer extends LayoutPart implements ILayoutContainer {
-
+ 
 	protected Composite parent;
 	protected ControlListener resizeListener;
 	protected LayoutTree root;
 	protected LayoutTree unzoomRoot;
 	protected Listener mouseDownListener;
+	protected WorkbenchPage page;
 	boolean active = false;
-
+	
 	/* Array of LayoutPart */
-	protected ArrayList children = new ArrayList();
-
+	protected ArrayList children = new ArrayList(); 
+	
 	protected static class RelationshipInfo {
 		protected LayoutPart part;
 		protected LayoutPart relative;
 		protected int relationship;
 		protected float ratio;
 	}
-
-	public PartSashContainer(String id, final WorkbenchPage page) {
-		super(id);
-		resizeListener = new ControlAdapter() {
-			public void controlResized(ControlEvent e) {
-				resizeSashes(parent.getClientArea());
-			}
-		};
-		// Mouse down listener to hide fast view when
-		// user clicks on empty editor area or sashes.
-		mouseDownListener = new Listener() {
-			public void handleEvent(Event event) {
-				if (event.type == SWT.MouseDown)
-					page.toggleFastView(null);
-			}
-		};
-	}
-	/**
-	 * Find the sashs around the specified part.
-	 */
-	public void findSashes(LayoutPart pane, PartPane.Sashes sashes) {
-		LayoutTree part = root.find(pane);
-		if (part == null)
-			return;
-		part.findSashes(sashes);
-	}
-	/**
-	 * Add a part.
-	 */
-	public void add(LayoutPart child) {
-		if (isZoomed())
-			zoomOut();
-
-		if (child == null)
-			return;
-		
-		RelationshipInfo info = new RelationshipInfo();
-		info.part = child;
-		if (root != null) {
-			findPosition(info);
-		}
-		addChild(info);
-	}
-	/**
-	 * Add on part relative to another
-	 */
-	public void add(LayoutPart child, int relationship, float ratio, LayoutPart relative) {
-		if (isZoomed())
-			zoomOut();
-
-		if (child == null)
-			return;
-		if (relative != null && !isChild(relative))
-			return;
-		if (relationship < IPageLayout.LEFT || relationship > IPageLayout.BOTTOM)
-			relationship = IPageLayout.LEFT;
-
-		// store info about relative positions
-		RelationshipInfo info = new RelationshipInfo();
-		info.part = child;
-		info.relationship = relationship;
-		info.ratio = ratio;
-		info.relative = relative;
-		addChild(info);
-	}
-	private void addChild(RelationshipInfo info) {
-		LayoutPart child = info.part;
-		
-		// Nasty hack: ensure that all views end up inside a tab folder.
-		// Since the view title is provided by the tab folder, this ensures
-		// that views don't get created without a title tab.
-		if (child instanceof ViewPane) {
-			PartTabFolder folder = new PartTabFolder();
-			folder.add(child);
-			child = folder;
-		}
-		
-		children.add(child);
-
-		if (root == null) {
-			root = new LayoutTree(child);
-		} else {
-			//Add the part to the tree.
-			int vertical =
-				(info.relationship == IPageLayout.LEFT || info.relationship == IPageLayout.RIGHT)
-					? SWT.VERTICAL
-					: SWT.HORIZONTAL;
-			boolean left =
-				info.relationship == IPageLayout.LEFT || info.relationship == IPageLayout.TOP;
-			LayoutPartSash sash = new LayoutPartSash(this, vertical);
-			sash.setRatio(info.ratio);
-			if ((parent != null) && !(child instanceof PartPlaceholder))
-				sash.createControl(parent);
-			root = root.insert(child, left, sash, info.relative);
-		}
-
-		childAdded(child);
-
-		if (active) {
-			child.createControl(parent);
-			child.setVisible(true);
-			child.setContainer(this);
+	
+public PartSashContainer(String id,final WorkbenchPage page) {
+	super(id);
+	this.page = page;
+	resizeListener = new ControlAdapter() {
+		public void controlResized(ControlEvent e) {
 			resizeSashes(parent.getClientArea());
 		}
-
-	}
-	/**
-	 * See ILayoutContainer#allowBorder
-	 */
-	public boolean allowsBorder() {
-		return true;
-	}
-	/**
-	 * Notification that a child layout part has been
-	 * added to the container. Subclasses may override
-	 * this method to perform any container specific
-	 * work.
-	 */
-	protected abstract void childAdded(LayoutPart child);
-	/**
-	 * Notification that a child layout part has been
-	 * removed from the container. Subclasses may override
-	 * this method to perform any container specific
-	 * work.
-	 */
-	protected abstract void childRemoved(LayoutPart child);
-	/**
-	 * Returns an array with all the relation ship between the
-	 * parts.
-	 */
-	public RelationshipInfo[] computeRelation() {
-		LayoutTree treeRoot = root;
-		if (isZoomed())
-			treeRoot = unzoomRoot;
-		ArrayList list = new ArrayList();
-		if (treeRoot == null)
-			return new RelationshipInfo[0];
-		RelationshipInfo r = new RelationshipInfo();
-		r.part = treeRoot.computeRelation(list);
-		list.add(0, r);
-		RelationshipInfo[] result = new RelationshipInfo[list.size()];
-		list.toArray(result);
-		return result;
-	}
-	/**
-	 * @see LayoutPart#getControl
-	 */
-	public void createControl(Composite parentWidget) {
-		if (active)
-			return;
-
-		parent = createParent(parentWidget);
-		parent.addControlListener(resizeListener);
-
-		ArrayList children = (ArrayList) this.children.clone();
-		for (int i = 0, length = children.size(); i < length; i++) {
-			LayoutPart child = (LayoutPart) children.get(i);
-			child.setContainer(this);
-			child.createControl(parent);
+	};
+	// Mouse down listener to hide fast view when
+	// user clicks on empty editor area or sashes.
+	mouseDownListener = new Listener() {
+		public void handleEvent(Event event) {
+			if (event.type == SWT.MouseDown)
+				page.toggleFastView(null);
 		}
-
-		root.updateSashes(parent);
-		active = true;
-		resizeSashes(parent.getClientArea());
+	};	
+}
+/**
+ * Find the sashs around the specified part.
+ */
+public void findSashes(LayoutPart pane,PartPane.Sashes sashes) {
+	LayoutTree part = root.find(pane);
+	if(part == null)
+		return;
+	part.findSashes(sashes);
+}
+/**
+ * Add a part.
+ */
+public void add(LayoutPart child) {
+	if (isZoomed())
+		zoomOut();
+		
+	if (child == null)
+		return;
+	
+	RelationshipInfo info = new RelationshipInfo();
+	info.part = child;
+	if(root != null) {
+		findPosition(info);
 	}
-	/**
-	 * Subclasses override this method to specify
-	 * the composite to use to parent all children
-	 * layout parts it contains.
-	 */
-	protected abstract Composite createParent(Composite parentWidget);
-	/**
-	 * @see LayoutPart#dispose
-	 */
-	public void dispose() {
-		if (!active)
-			return;
+	addChild(info);
+}
+/**
+ * Add on part relative to another
+ */
+public void add(LayoutPart child, int relationship, float ratio, LayoutPart relative) {
+	if (isZoomed())
+		zoomOut();
 
-		// remove all Listeners
-		if (resizeListener != null && parent != null) {
-			parent.removeControlListener(resizeListener);
-		}
+	if (child == null)
+		return;
+	if (relative != null && !isChild(relative))
+		return;
+	if (relationship < IPageLayout.LEFT || relationship > IPageLayout.BOTTOM)
+		relationship = IPageLayout.LEFT;
 
-		resizeSashes(new Rectangle(-200, -200, 0, 0));
-
-		if (children != null) {
-			for (int i = 0, length = children.size(); i < length; i++) {
-				LayoutPart child = (LayoutPart) children.get(i);
-				child.setContainer(null);
-				// In PartSashContainer dispose really means deactivate, so we
-				// only dispose PartTabFolders.
-				if (child instanceof PartTabFolder)
-					child.dispose();
-			}
-		}
-
-		disposeParent();
-		this.parent = null;
-
-		active = false;
+	// store info about relative positions
+	RelationshipInfo info = new RelationshipInfo();
+	info.part = child;
+	info.relationship = relationship;
+	info.ratio = ratio;
+	info.relative = relative;
+	addChild(info);
+}
+private void addChild(RelationshipInfo info) {
+	LayoutPart child = info.part;
+	
+	// Nasty hack: ensure that all views end up inside a tab folder.
+	// Since the view title is provided by the tab folder, this ensures
+	// that views don't get created without a title tab.
+	if (child instanceof ViewPane) {
+		PartTabFolder folder = new PartTabFolder(page);
+		folder.add(child);
+		child = folder;
 	}
-	/**
-	 * Subclasses override this method to dispose
-	 * of any swt resources created during createParent.
-	 */
-	protected abstract void disposeParent();
-	/**
-	 * Dispose all sashs used in this perspective.
-	 */
-	public void disposeSashes() {
-		root.disposeSashes();
-	}
-	/**
-	 * Return the most bottom right part or null if none.
-	 */
-	public LayoutPart findBottomRight() {
-		if (root == null)
-			return null;
-		return root.findBottomRight();
-	}
-	/**
-	 * Find a initial position for a new part.
-	 */
-	private void findPosition(RelationshipInfo info) {
-
-		info.ratio = (float) 0.5;
-		info.relationship = IPageLayout.RIGHT;
-		info.relative = root.findBottomRight();
-
-		// If no parent go with default.
-		if (parent == null)
-			return;
-
-		// If the relative part is too small, place the part on the left of everything.
-		if (((float) this.getBounds().width / (float) info.relative.getBounds().width > 2)
-			|| ((float) this.getBounds().height / (float) info.relative.getBounds().height > 4)) {
-			info.relative = null;
-			info.ratio = 0.75f;
-		}
-	}
-	/**
-	 * @see LayoutPart#getBounds
-	 */
-	public Rectangle getBounds() {
-		return this.parent.getBounds();
-	}
-
-	// getMinimumHeight() added by cagatayk@acm.org 
-	/**
-	 * @see LayoutPart#getMinimumHeight()
-	 */
-	public int getMinimumHeight() {
-		return getLayoutTree().getMinimumHeight();
-	}
-
-	// getMinimumHeight() added by cagatayk@acm.org 
-	/**
-	 * @see LayoutPart#getMinimumWidth()
-	 */
-	public int getMinimumWidth() {
-		return getLayoutTree().getMinimumWidth();
-	}
-
-	/**
-	 * @see ILayoutContainer#getChildren
-	 */
-	public LayoutPart[] getChildren() {
-		LayoutPart[] result = new LayoutPart[children.size()];
-		children.toArray(result);
-		return result;
-	}
-
-	/**
-	 * @see LayoutPart#getControl
-	 */
-	public Control getControl() {
-		return this.parent;
-	}
-
-	public LayoutTree getLayoutTree() {
-		return root;
-	}
-	/**
-	 * Return the interested listener of mouse down events.
-	 */
-	protected Listener getMouseDownListener() {
-		return mouseDownListener;
-	}
-	/**
-	 * Returns the composite used to parent all the
-	 * layout parts contained within.
-	 */
-	public Composite getParent() {
-		return parent;
-	}
-	private boolean isChild(LayoutPart part) {
-		return children.indexOf(part) >= 0;
-	}
-	private boolean isRelationshipCompatible(int relationship, boolean isVertical) {
-		if (isVertical)
-			return (relationship == IPageLayout.RIGHT || relationship == IPageLayout.LEFT);
-		else
-			return (relationship == IPageLayout.TOP || relationship == IPageLayout.BOTTOM);
-	}
-	/**
-	 * Returns whether this container is zoomed.
-	 */
-	public boolean isZoomed() {
-		return (unzoomRoot != null);
-	}
-	/**
-	 * Move a part to a new position and keep the bounds when possible, ie,
-	 * when the new relative part has the same higth or width as the part
-	 * being move.
-	 */
-	public void move(LayoutPart child, int relationship, LayoutPart relative) {
-		LayoutTree childTree = root.find(child);
-		LayoutTree relativeTree = root.find(relative);
-
-		LayoutTreeNode commonParent = relativeTree.getParent().findCommonParent(child, relative);
-		boolean isVertical = commonParent.getSash().isVertical();
-		boolean recomputeRatio = false;
-		recomputeRatio =
-			isRelationshipCompatible(relationship, isVertical)
-				&& commonParent.sameDirection(isVertical, relativeTree.getParent())
-				&& commonParent.sameDirection(isVertical, childTree.getParent());
-
-		root = root.remove(child);
-		int vertical =
-			(relationship == IPageLayout.LEFT || relationship == IPageLayout.RIGHT)
-				? SWT.VERTICAL
-				: SWT.HORIZONTAL;
-		boolean left = relationship == IPageLayout.LEFT || relationship == IPageLayout.TOP;
-		LayoutPartSash sash = new LayoutPartSash(this, vertical);
-		sash.setRatio(0.5f);
-		if ((parent != null) && !(child instanceof PartPlaceholder))
+	
+	children.add(child);
+	
+	if(root == null) {
+		root = new LayoutTree(child);
+	} else {
+		//Add the part to the tree.
+		int vertical = (info.relationship == IPageLayout.LEFT || info.relationship == IPageLayout.RIGHT)?SWT.VERTICAL:SWT.HORIZONTAL;
+		boolean left = info.relationship == IPageLayout.LEFT || info.relationship == IPageLayout.TOP; 
+		LayoutPartSash sash = new LayoutPartSash(this,vertical);
+		sash.setRatio(info.ratio);
+		if((parent != null) && !(child instanceof PartPlaceholder))
 			sash.createControl(parent);
-		root = root.insert(child, left, sash, relative);
-		root.updateSashes(parent);
-		if (recomputeRatio)
-			root.recomputeRatio();
-
+		root = root.insert(child,left,sash,info.relative);
+	}
+	
+	childAdded(child);
+	
+	if (active) {
+		child.createControl(parent);
+		child.setVisible(true);
+		child.setContainer(this);
 		resizeSashes(parent.getClientArea());
 	}
-	/**
-	 * Remove a part.
-	 */
-	public void remove(LayoutPart child) {
-		if (isZoomed())
-			zoomOut();
 
-		if (!isChild(child))
-			return;
+}
+/**
+ * See ILayoutContainer#allowBorder
+ */
+public boolean allowsBorder() {
+	return true;
+}
+/**
+ * Notification that a child layout part has been
+ * added to the container. Subclasses may override
+ * this method to perform any container specific
+ * work.
+ */
+protected abstract void childAdded(LayoutPart child);
+/**
+ * Notification that a child layout part has been
+ * removed from the container. Subclasses may override
+ * this method to perform any container specific
+ * work.
+ */
+protected abstract void childRemoved(LayoutPart child);
+/**
+ * Returns an array with all the relation ship between the
+ * parts.
+ */
+public RelationshipInfo[] computeRelation() {
+	LayoutTree treeRoot = root;
+	if(isZoomed())
+		treeRoot = unzoomRoot;
+	ArrayList list = new ArrayList();
+	if(treeRoot == null)
+		return new RelationshipInfo[0];
+	RelationshipInfo r = new RelationshipInfo();
+	r.part = treeRoot.computeRelation(list);
+	list.add(0,r);
+	RelationshipInfo[] result = new RelationshipInfo[list.size()];
+	list.toArray(result);
+	return result;
+}
+/**
+ * @see LayoutPart#getControl
+ */
+public void createControl(Composite parentWidget) {
+	if (active)
+		return;
 
-		children.remove(child);
-		root = root.remove(child);
-		if (root != null)
-			root.updateSashes(parent);
-		childRemoved(child);
+	parent = createParent(parentWidget);
+	parent.addControlListener(resizeListener);
+	
+	ArrayList children = (ArrayList)this.children.clone();
+	for (int i = 0, length = children.size(); i < length; i++) {
+		LayoutPart child = (LayoutPart)children.get(i);
+		child.setContainer(this);
+		child.createControl(parent);
+	}
 
-		if (active) {
-			child.setVisible(false);
+	root.updateSashes(parent);
+	active = true;
+	resizeSashes(parent.getClientArea());
+}
+/**
+ * Subclasses override this method to specify
+ * the composite to use to parent all children
+ * layout parts it contains.
+ */
+protected abstract Composite createParent(Composite parentWidget);
+/**
+ * @see LayoutPart#dispose
+ */
+public void dispose() {
+	if (!active)
+		return;
+	
+	// remove all Listeners
+	if (resizeListener != null && parent != null){
+		parent.removeControlListener(resizeListener);
+	}
+	
+	resizeSashes(new Rectangle(-200, -200, 0, 0));
+
+	if (children != null) {
+		for (int i = 0, length = children.size(); i < length; i++){
+			LayoutPart child = (LayoutPart)children.get(i);
 			child.setContainer(null);
-			resizeSashes(parent.getClientArea());
+			// In PartSashContainer dispose really means deactivate, so we
+			// only dispose PartTabFolders.
+			if (child instanceof PartTabFolder)
+				child.dispose();
 		}
 	}
-	/**
-	 * Replace one part with another.
-	 */
-	public void replace(LayoutPart oldChild, LayoutPart newChild) {
-		if (isZoomed())
-			zoomOut();
+	
+	disposeParent();
+	this.parent = null;
+	
+	active = false;
+}
+/**
+ * Subclasses override this method to dispose
+ * of any swt resources created during createParent.
+ */
+protected abstract void disposeParent();
+/**
+ * Dispose all sashs used in this perspective.
+ */
+public void disposeSashes() {
+	root.disposeSashes();
+}
+/**
+ * Return the most bottom right part or null if none.
+ */
+public LayoutPart findBottomRight() {
+	if(root == null)
+		return null;
+	return root.findBottomRight();
+}
+/**
+ * Find a initial position for a new part.
+ */
+private void findPosition(RelationshipInfo info) {
 
-		if (!isChild(oldChild))
-			return;
+	info.ratio = (float)0.5;
+	info.relationship = IPageLayout.RIGHT;
+	info.relative = root.findBottomRight();
 
-		// Nasty hack: ensure that all views end up inside a tab folder.
-		// Since the view title is provided by the tab folder, this ensures
-		// that views don't get created without a title tab.
-		if (newChild instanceof ViewPane) {
-			PartTabFolder folder = new PartTabFolder();
-			folder.add(newChild);
-			newChild = folder;
-		}
+	// If no parent go with default.
+	if (parent == null)
+		return;
 		
-		children.remove(oldChild);
-		children.add(newChild);
+	// If the relative part is too small, place the part on the left of everything.
+	if (((float)this.getBounds().width / (float)info.relative.getBounds().width > 2) ||
+		 ((float)this.getBounds().height / (float)info.relative.getBounds().height > 4)) {
+		info.relative = null;
+		info.ratio = 0.75f;
+	}
+}
+/**
+ * @see LayoutPart#getBounds
+ */
+public Rectangle getBounds() {
+	return this.parent.getBounds();
+}
 
-		childAdded(newChild);
-		LayoutTree leaf = root.find(oldChild);
-		leaf.setPart(newChild);
+
+// getMinimumHeight() added by cagatayk@acm.org 
+/**
+ * @see LayoutPart#getMinimumHeight()
+ */
+public int getMinimumHeight() {
+	return getLayoutTree().getMinimumHeight();
+}
+
+// getMinimumHeight() added by cagatayk@acm.org 
+/**
+ * @see LayoutPart#getMinimumWidth()
+ */
+public int getMinimumWidth() {
+	return getLayoutTree().getMinimumWidth();
+}
+
+
+/**
+ * @see ILayoutContainer#getChildren
+ */
+public LayoutPart[] getChildren() {
+	LayoutPart[] result = new LayoutPart[children.size()];
+	children.toArray(result);
+	return result;
+}
+
+/**
+ * @see LayoutPart#getControl
+ */
+public Control getControl() {
+	return this.parent;
+}
+
+public LayoutTree getLayoutTree() {
+	return root;
+}
+/**
+ * Return the interested listener of mouse down events.
+ */
+protected Listener getMouseDownListener() {
+	return mouseDownListener;
+}
+/**
+ * Returns the composite used to parent all the
+ * layout parts contained within.
+ */
+public Composite getParent() {
+	return parent;
+}
+private boolean isChild(LayoutPart part) {
+	return children.indexOf(part) >= 0;
+}
+private boolean isRelationshipCompatible(int relationship,boolean isVertical) {
+	if(isVertical)
+		return (relationship == IPageLayout.RIGHT || relationship == IPageLayout.LEFT);
+	else 
+		return (relationship == IPageLayout.TOP || relationship == IPageLayout.BOTTOM);
+}
+/**
+ * Returns whether this container is zoomed.
+ */
+public boolean isZoomed() {
+	return (unzoomRoot != null);
+}
+/**
+ * Move a part to a new position and keep the bounds when possible, ie,
+ * when the new relative part has the same higth or width as the part
+ * being move.
+ */
+public void move(LayoutPart child, int relationship, LayoutPart relative) {
+	LayoutTree childTree = root.find(child);
+	LayoutTree relativeTree = root.find(relative);
+
+	LayoutTreeNode commonParent = relativeTree.getParent().findCommonParent(child,relative);
+	boolean isVertical = commonParent.getSash().isVertical();
+	boolean recomputeRatio = false;
+	recomputeRatio =
+		isRelationshipCompatible(relationship,isVertical) &&
+			commonParent.sameDirection(isVertical,relativeTree.getParent()) && 
+				commonParent.sameDirection(isVertical,childTree.getParent());
+
+	root = root.remove(child);
+	int vertical = (relationship == IPageLayout.LEFT || relationship == IPageLayout.RIGHT)?SWT.VERTICAL:SWT.HORIZONTAL;
+	boolean left = relationship == IPageLayout.LEFT || relationship == IPageLayout.TOP; 
+	LayoutPartSash sash = new LayoutPartSash(this,vertical);
+	sash.setRatio(0.5f);
+	if((parent != null) && !(child instanceof PartPlaceholder))
+		sash.createControl(parent);
+	root = root.insert(child,left,sash,relative);
+	root.updateSashes(parent);
+	if(recomputeRatio)
+		root.recomputeRatio();
+		
+	resizeSashes(parent.getClientArea());
+}
+/**
+ * Remove a part.
+ */ 
+public void remove(LayoutPart child) {
+	if (isZoomed())
+		zoomOut();
+		
+	if (!isChild(child))
+		return;
+
+	children.remove(child); 
+	root = root.remove(child);
+	if(root != null)
 		root.updateSashes(parent);
-
-		childRemoved(oldChild);
-		if (active) {
-			oldChild.setVisible(false);
-			oldChild.setContainer(null);
-			newChild.createControl(parent);
-			newChild.setContainer(this);
-			newChild.setVisible(true);
-			resizeSashes(parent.getClientArea());
-		}
-	}
-	private void resizeSashes(Rectangle parentSize) {
-		if (!active)
-			return;
-		root.setBounds(parentSize);
-	}
-	/**
-	 * @see LayoutPart#setBounds
-	 */
-	public void setBounds(Rectangle r) {
-		this.parent.setBounds(r);
-	}
-	/**
-	 * Zoom in on a particular layout part.
-	 *
-	 * The implementation of zoom is quite simple.  When zoom occurs we create
-	 * a zoom root which only contains the zoom part.  We store the old
-	 * root in unzoomRoot and then active the zoom root.  When unzoom occurs
-	 * we restore the unzoomRoot and dispose the zoom root.
-	 *
-	 * Note: Method assumes we are active.
-	 */
-	public void zoomIn(LayoutPart part) {
-		// Sanity check.
-		if (unzoomRoot != null)
-			return;
-
-		// Hide main root.
-		Rectangle oldBounds = root.getBounds();
-		root.setBounds(new Rectangle(0, 0, 0, 0));
-		unzoomRoot = root;
-
-		// Show zoom root.
-		root = new LayoutTree(part);
-		root.setBounds(oldBounds);
-	}
-	/**
-	 * Zoom out.
-	 *
-	 * See zoomIn for implementation details.
-	 * 
-	 * Note: Method assumes we are active.
-	 */
-	public void zoomOut() {
-		// Sanity check.
-		if (unzoomRoot == null)
-			return;
-
-		// Dispose zoom root.
-		Rectangle oldBounds = root.getBounds();
-		root.setBounds(new Rectangle(0, 0, 0, 0));
-
-		// Show main root.
-		root = unzoomRoot;
-		root.setBounds(oldBounds);
-		unzoomRoot = null;
-	}
+	childRemoved(child);
 	
-	/* (non-Javadoc)
-	 * @see org.eclipse.ui.internal.IWorkbenchDropTarget#addDropTargets(java.util.Collection)
-	 */
-	public void addDropTargets(Collection result) {
-		addDropTargets(result,this);
+	if (active){
+		child.setVisible(false);
+		child.setContainer(null);
+		resizeSashes(parent.getClientArea());
+	}
+}
+/**
+ * Replace one part with another.
+ */ 
+public void replace(LayoutPart oldChild, LayoutPart newChild) {
+	if (isZoomed())
+		zoomOut();
+
+	if (!isChild(oldChild))return;
 		
+	// Nasty hack: ensure that all views end up inside a tab folder.
+	// Since the view title is provided by the tab folder, this ensures
+	// that views don't get created without a title tab.
+	if (newChild instanceof ViewPane) {
+		PartTabFolder folder = new PartTabFolder(page);
+		folder.add(newChild);
+		newChild = folder;
 	}
 	
-	/* (non-Javadoc)
-	 * @see org.eclipse.ui.internal.IWorkbenchDropTarget#targetPartFor(org.eclipse.ui.internal.IWorkbenchDragSource)
-	 */
-	public LayoutPart targetPartFor(IWorkbenchDragSource dragSource) {
-		return this;
+	children.remove(oldChild);
+	children.add(newChild);
+
+	childAdded(newChild);
+	LayoutTree leaf = root.find(oldChild);
+	leaf.setPart(newChild);
+	root.updateSashes(parent);
+
+	childRemoved(oldChild);
+	if (active){
+		oldChild.setVisible(false);
+		oldChild.setContainer(null);
+		newChild.createControl(parent);
+		newChild.setContainer(this);
+		newChild.setVisible(true);		
+		resizeSashes(parent.getClientArea());
 	}
 }
+private void resizeSashes(Rectangle parentSize) {
+	if (!active) return;
+	root.setBounds(parentSize);
+}
+/**
+ * @see LayoutPart#setBounds
+ */
+public void setBounds(Rectangle r) {
+	this.parent.setBounds(r);
+}
+/**
+ * Zoom in on a particular layout part.
+ *
+ * The implementation of zoom is quite simple.  When zoom occurs we create
+ * a zoom root which only contains the zoom part.  We store the old
+ * root in unzoomRoot and then active the zoom root.  When unzoom occurs
+ * we restore the unzoomRoot and dispose the zoom root.
+ *
+ * Note: Method assumes we are active.
+ */
+public void zoomIn(LayoutPart part) {
+	// Sanity check.
+	if (unzoomRoot != null)
+		return;
+
+	// Hide main root.
+	Rectangle oldBounds = root.getBounds();
+	root.setBounds(new Rectangle(0,0,0,0));
+	unzoomRoot = root;
+
+	// Show zoom root.
+	root = new LayoutTree(part);
+	root.setBounds(oldBounds);
+}
+/**
+ * Zoom out.
+ *
+ * See zoomIn for implementation details.
+ * 
+ * Note: Method assumes we are active.
+ */
+public void zoomOut() {
+	// Sanity check.
+	if (unzoomRoot == null)
+		return;
+
+	// Dispose zoom root.
+	Rectangle oldBounds = root.getBounds();
+	root.setBounds(new Rectangle(0,0,0,0));
+
+	// Show main root.
+	root = unzoomRoot;
+	root.setBounds(oldBounds);
+	unzoomRoot = null;
+}
+}
diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/PartSite.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/PartSite.java
index 9347340..f06325e 100644
--- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/PartSite.java
+++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/PartSite.java
@@ -18,23 +18,28 @@
 import org.eclipse.core.runtime.IPluginDescriptor;
 import org.eclipse.core.runtime.jobs.IJobChangeListener;
 import org.eclipse.core.runtime.jobs.Job;
+
+import org.eclipse.swt.widgets.Shell;
+
 import org.eclipse.jface.action.IAction;
 import org.eclipse.jface.action.MenuManager;
 import org.eclipse.jface.viewers.ISelectionProvider;
-import org.eclipse.swt.widgets.Shell;
+
 import org.eclipse.ui.IActionBars;
 import org.eclipse.ui.IKeyBindingService;
 import org.eclipse.ui.IWorkbenchPage;
 import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.IWorkbenchPartReference;
 import org.eclipse.ui.IWorkbenchPartSite;
 import org.eclipse.ui.IWorkbenchWindow;
 import org.eclipse.ui.SubActionBars;
 import org.eclipse.ui.commands.IWorkbenchPartSiteCommandSupport;
 import org.eclipse.ui.contexts.IWorkbenchPartSiteContextSupport;
+import org.eclipse.ui.progress.IWorkbenchSiteProgressService;
+
 import org.eclipse.ui.internal.commands.ws.WorkbenchPartSiteCommandSupport;
 import org.eclipse.ui.internal.contexts.ws.WorkbenchPartSiteContextSupport;
 import org.eclipse.ui.internal.progress.WorkbenchSiteProgressService;
-import org.eclipse.ui.progress.IWorkbenchSiteProgressService;
 
 /**
  * <code>PartSite</code> is the general implementation for an
@@ -58,6 +63,7 @@
  */
 public class PartSite implements IWorkbenchPartSite {
 
+    private IWorkbenchPartReference partReference;
 	private IWorkbenchPart part;
 	private IWorkbenchPage page;
 	private PartPane pane;
@@ -73,7 +79,8 @@
 	/**
 	 * EditorContainer constructor comment.
 	 */
-	public PartSite(IWorkbenchPart part, IWorkbenchPage page) {
+	public PartSite(IWorkbenchPartReference ref, IWorkbenchPart part, IWorkbenchPage page) {
+	    this.partReference = ref;
 		this.part = part;
 		this.page = page;
 		extensionID = "org.eclipse.ui.UnknownID"; //$NON-NLS-1$
@@ -138,6 +145,12 @@
 		return part;
 	}
 	/**
+	 * Returns the part reference.
+	 */
+	public IWorkbenchPartReference getPartReference() {
+		return partReference;
+	}
+	/**
 	 * Returns the part registry plugin ID.  It cannot be <code>null</code>.
 	 *
 	 * @return the registry plugin ID
@@ -327,7 +340,6 @@
 			return getSiteProgressService();
 		return null;
 	}
-	
 	/**
 	 * Get a progress service for the receiver.
 	 * @return
diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/PartTabFolder.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/PartTabFolder.java
index 17ef156..ebbad53 100644
--- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/PartTabFolder.java
+++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/PartTabFolder.java
@@ -21,24 +21,6 @@
 import org.eclipse.core.runtime.IProgressMonitor;
 import org.eclipse.core.runtime.IStatus;
 import org.eclipse.core.runtime.Status;
-
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.custom.CTabFolder2;
-import org.eclipse.swt.custom.CTabFolderCloseAdapter;
-import org.eclipse.swt.custom.CTabFolderEvent;
-import org.eclipse.swt.custom.CTabFolderMinMaxAdapter;
-import org.eclipse.swt.custom.CTabItem2;
-import org.eclipse.swt.events.MouseAdapter;
-import org.eclipse.swt.events.MouseEvent;
-import org.eclipse.swt.events.MouseListener;
-import org.eclipse.swt.graphics.Image;
-import org.eclipse.swt.graphics.Point;
-import org.eclipse.swt.graphics.Rectangle;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-import org.eclipse.swt.widgets.Event;
-import org.eclipse.swt.widgets.Listener;
-
 import org.eclipse.jface.preference.IPreferenceStore;
 import org.eclipse.jface.resource.JFaceColors;
 import org.eclipse.jface.resource.JFaceResources;
@@ -47,17 +29,41 @@
 import org.eclipse.jface.util.PropertyChangeEvent;
 import org.eclipse.jface.window.ColorSchemeService;
 import org.eclipse.jface.window.Window;
-
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.CTabFolder2;
+import org.eclipse.swt.custom.CTabFolderCloseAdapter;
+import org.eclipse.swt.custom.CTabFolderEvent;
+import org.eclipse.swt.custom.CTabFolderListener;
+import org.eclipse.swt.custom.CTabFolderMinMaxAdapter;
+import org.eclipse.swt.custom.CTabItem2;
+import org.eclipse.swt.events.MouseAdapter;
+import org.eclipse.swt.events.MouseEvent;
+import org.eclipse.swt.events.MouseListener;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Listener;
 import org.eclipse.ui.IMemento;
+import org.eclipse.ui.IPropertyListener;
+import org.eclipse.ui.IViewPart;
+import org.eclipse.ui.IWorkbenchPart;
 import org.eclipse.ui.PlatformUI;
-import org.eclipse.ui.progress.UIJob;
-
 import org.eclipse.ui.internal.dnd.AbstractDragSource;
 import org.eclipse.ui.internal.dnd.DragUtil;
+import org.eclipse.ui.internal.intro.IIntroConstants;
 import org.eclipse.ui.internal.progress.ProgressManager;
 import org.eclipse.ui.internal.registry.IViewDescriptor;
+import org.eclipse.ui.internal.themes.ITabThemeDescriptor;
+import org.eclipse.ui.internal.themes.IThemeDescriptor;
+import org.eclipse.ui.internal.themes.TabThemeDescriptor;
+import org.eclipse.ui.internal.themes.WorkbenchThemeManager;
+import org.eclipse.ui.progress.UIJob;
 
-public class PartTabFolder extends LayoutPart implements ILayoutContainer, IWorkbenchDragSource {
+public class PartTabFolder extends LayoutPart implements ILayoutContainer, IPropertyListener, IWorkbenchDragSource {
 	
 	private static final int STATE_MINIMIZED = 0;
 	private static final int STATE_RESTORED = 1;
@@ -72,6 +78,7 @@
 	private LayoutPart current;
 	private boolean assignFocusOnSelection = true;
 	private int viewState = STATE_RESTORED;
+	private WorkbenchPage page;
 
 	// inactiveCurrent is only used when restoring the persisted state of
 	// perspective on startup.
@@ -146,27 +153,53 @@
 	private class TabInfo {
 		private String tabText;
 		private LayoutPart part;
+		private Image partImage;
+		private boolean fixed;
 	}
-	TabInfo[] invisibleChildren;
+
+	private TabInfo[] invisibleChildren;
+
+	// Themes
+	private String themeid;
+	private ITabThemeDescriptor tabThemeDescriptor;
+	private int tabPosition = -1;
 
 	/**
 	 * PartTabFolder constructor comment.
 	 */
-	public PartTabFolder() {
+	public PartTabFolder(WorkbenchPage page) {
 		super("PartTabFolder"); //$NON-NLS-1$
 		setID(this.toString());
 		// Each folder has a unique ID so relative positioning is unambiguous.
+		
+		// save off a ref to the page
+		//@issue is it okay to do this??
+		//I think so since a PartTabFolder is
+		//not used on more than one page.
+		this.page = page;
+
+		// Get the location of the tabs from the preferences
+		if (tabLocation == -1)
+			tabLocation =
+				WorkbenchPlugin.getDefault().getPreferenceStore().getInt(
+					IPreferenceConstants.VIEW_TAB_POSITION);
+
 	}
 	/**
 	 * Add a part at an index.
 	 */
 	public void add(String name, int index, LayoutPart part) {		
 		if (active && !(part instanceof PartPlaceholder)) {
-			CTabItem2 tab = createPartTab(part, name, index);
+			CTabItem2 tab = createPartTab(part, name, null, index);
 			index = tabFolder.indexOf(tab);
 			setSelection(index);
 		} else {
 			TabInfo info = new TabInfo();
+			if (part instanceof PartPane) {
+				WorkbenchPartReference ref =
+					(WorkbenchPartReference) ((PartPane) part).getPartReference();
+				info.partImage = ref.getTitleImage();
+			}
 			info.tabText = name;
 			info.part = part;
 			invisibleChildren = arrayAdd(invisibleChildren, info, index);
@@ -175,17 +208,44 @@
 		}
 	}
 	/**
+	 * Add a part at an index. Also use Image
+	 */
+	public void add(String name, int index, LayoutPart part, Image partImage) {
+		if (active && !(part instanceof PartPlaceholder)) {
+			CTabItem2 tab = createPartTab(part, name, partImage, index);
+			index = tabFolder.indexOf(tab);
+			setSelection(index);
+		} else {
+			TabInfo info = new TabInfo();
+			if (partImage != null)
+				info.partImage = partImage;
+			else if (part instanceof PartPane) {
+				WorkbenchPartReference ref =
+					(WorkbenchPartReference) ((PartPane) part).getPartReference();
+				info.partImage = ref.getTitleImage();
+			}
+			info.tabText = name;
+			info.part = part;
+			invisibleChildren = arrayAdd(invisibleChildren, info, index);
+			if (active)
+				part.setContainer(this);
+		}
+	}
+
+	/**
 	 * See IVisualContainer#add
 	 */
 	public void add(LayoutPart child) {
 		int index = getItemCount();
 		String label = ""; //$NON-NLS-1$
+		Image partimage = null;
 		if (child instanceof PartPane) {
 			WorkbenchPartReference ref =
 				(WorkbenchPartReference) ((PartPane) child).getPartReference();
 			label = ref.getRegisteredName();
+			partimage = ref.getTitleImage();
 		}
-		add(label, index, child);
+		add(label, index, child, partimage);
 	}
 	/**
 	 * See ILayoutContainer::allowBorder
@@ -194,7 +254,14 @@
 	 * folder so no need for one from the parts.
 	 */
 	public boolean allowsBorder() {
-		return false;
+		// @issue need to support old look even if a theme is set (i.e. show border
+		//   even when only one item) -- separate theme attribute, or derive this
+		//   from existing attributes?
+		// @issue this says to show the border only if there are no items, but 
+		//   in this case the folder should not be visible anyway
+		if (tabThemeDescriptor != null)
+			return (mapTabToPart.size() < 1);
+		return mapTabToPart.size() <= 1;
 	}
 	private TabInfo[] arrayAdd(TabInfo[] array, TabInfo item, int index) {
 
@@ -277,10 +344,22 @@
 		preferenceStore.addPropertyChangeListener(propertyChangeListener);
 		int tabLocation = preferenceStore.getInt(IPreferenceConstants.VIEW_TAB_POSITION); 
 		
+		// probably won't work, given the code above..
+		if (tabPosition == -1) {
+			if (tabThemeDescriptor != null)
+				tabPosition = tabThemeDescriptor.getTabPosition();
+			else
+				tabPosition = tabLocation;
+		}
+		
 		tabFolder = new CTabFolder2(parent, tabLocation | SWT.BORDER | SWT.CLOSE);
 		//tabFolder.setBorderVisible(true);
 		ColorSchemeService.setTabColors(tabFolder);
 		
+		if (tabThemeDescriptor != null) {
+			useThemeInfo();
+		}
+
 		// listener to switch between visible tabItems
 		tabFolder.addListener(SWT.Selection, new Listener() {
 			public void handleEvent(Event e) {
@@ -363,9 +442,18 @@
 					newStillInactive[stillInactive.length] = invisibleChildren[i];
 					stillInactive = newStillInactive;
 				} else {
+					if (invisibleChildren[i].partImage == null) {
+						if (invisibleChildren[i].part instanceof PartPane) {
+							WorkbenchPartReference ref =
+								(WorkbenchPartReference) ((PartPane) invisibleChildren[i].part)
+									.getPartReference();
+							invisibleChildren[i].partImage = ref.getTitleImage();
+						}
+					}
 					createPartTab(
 						invisibleChildren[i].part,
 						invisibleChildren[i].tabText,
+						invisibleChildren[i].partImage,
 						tabCount);
 					++tabCount;
 				}
@@ -388,15 +476,35 @@
 		updateControlState();
 	}
 		
-	private CTabItem2 createPartTab(LayoutPart part, String tabName, int tabIndex) {
+	private CTabItem2 createPartTab(LayoutPart part, String tabName, Image tabImage, int tabIndex) {
 		CTabItem2 tabItem;
 
 		if (tabIndex < 0)
 			tabItem = new CTabItem2(this.tabFolder, SWT.NONE);
 		else
 			tabItem = new CTabItem2(this.tabFolder, SWT.NONE, tabIndex);
-		tabItem.setText(tabName);
+		
+		if (tabThemeDescriptor != null) {
+			int showInTab = tabThemeDescriptor.getShowInTab();
 
+			//		tabItem.setItemMargins(tabThemeDescriptor.getItemMargins());
+			if (tabThemeDescriptor.isShowTooltip())
+				tabItem.setToolTipText(tabName);
+
+			if ((tabImage != null) && (showInTab != TabThemeDescriptor.TABLOOKSHOWTEXTONLY))
+				tabItem.setImage(tabImage);
+			if (showInTab != TabThemeDescriptor.TABLOOKSHOWICONSONLY)
+				tabItem.setText(tabName);
+			
+			// @issue not sure of exact API on CTabItem
+			//if (part instanceof ViewPane) {
+			//	tabItem.setShowClose(!((ViewPane)part).isFixedView());
+			//}
+			
+		} else {
+			tabItem.setText(tabName);
+		}
+		
 		if (part instanceof PartPane) {
 			tabItem.setImage(((PartPane) part).getPartReference().getTitleImage());
 		}
@@ -414,9 +522,14 @@
 			((LayoutPart) parts.next()).setContainer(this);
 			((LayoutPart) parts.next()).setContainer(this);
 		}
+				
+		if (part instanceof PartPane) {
+			WorkbenchPartReference ref =
+				(WorkbenchPartReference) ((PartPane) part).getPartReference();
+			ref.addPropertyListener(this);
+		}
 
 		updateControlBounds();
-		
 		return tabItem;
 	}
 
@@ -723,13 +836,25 @@
 
 		// dispose of the old tab and remove it
 		String sourceLabel = sourceTab.getText();
+		Image partImage = sourceTab.getImage();
+
 		mapTabToPart.remove(sourceTab);
 		assignFocusOnSelection = false;
 		sourceTab.dispose();
 		assignFocusOnSelection = true;
-
+		
 		// update the new tab's title and visibility
-		newTab.setText(sourceLabel);
+		if (tabThemeDescriptor != null) {
+			int showInTab = tabThemeDescriptor.getShowInTab();
+
+			if ((partImage != null) && (showInTab != TabThemeDescriptor.TABLOOKSHOWTEXTONLY))
+				newTab.setImage(partImage);
+			if (showInTab != TabThemeDescriptor.TABLOOKSHOWICONSONLY)
+				newTab.setText(sourceLabel);
+		} else {
+			newTab.setText(sourceLabel);
+		}
+		
 		if (wasVisible) {
 			tabFolder.setSelection(newTab);
 			setSelection(pane);
@@ -823,7 +948,7 @@
 						info.tabText = ref.getRegisteredName();
 					}
 					CTabItem2 oldItem = tabFolder.getSelection();
-					CTabItem2 item = createPartTab(newChild, info.tabText, -1);
+					CTabItem2 item = createPartTab(newChild, info.tabText, info.partImage, -1);
 					if (oldItem == null) 
 						oldItem = item;
 					int index = tabFolder.indexOf(oldItem);
@@ -863,8 +988,11 @@
 				IViewDescriptor descriptor = (IViewDescriptor)WorkbenchPlugin.getDefault().
 					getViewRegistry().find(partID);
 			
-				if(descriptor != null) 
+				if (descriptor != null) {
+					if (descriptor.getId().equals(IIntroConstants.INTRO_VIEW_ID))
+						continue; // ignore the intro view
 					tabText = descriptor.getLabel();
+				}
 
 				// Create the part.
 				LayoutPart part = new PartPlaceholder(partID);
@@ -958,7 +1086,14 @@
 	private void setControlSize() {
 		if (current == null || tabFolder == null)
 			return;
-		current.setBounds(calculatePageBounds(tabFolder));
+		Rectangle bounds;
+		// @issue as above, the mere presence of a theme should not change the behaviour
+		if ((mapTabToPart.size() > 1)
+			|| ((tabThemeDescriptor != null) && (mapTabToPart.size() >= 1)))
+			bounds = calculatePageBounds(tabFolder);
+		else
+			bounds = tabFolder.getBounds();
+		current.setBounds(bounds);
 		current.moveAbove(tabFolder);
 	}
 
@@ -1062,6 +1197,176 @@
 		}
 	}
 	
+	private void useThemeInfo() {
+
+		//	if (tabThemeDescriptor.getSelectedImageDesc() != null)
+		//		tabFolder.setSelectedTabImage(tabThemeDescriptor.getSelectedImageDesc().createImage());
+		//	if (tabThemeDescriptor.getUnselectedImageDesc() != null)
+		//		tabFolder.setUnselectedTabImage(tabThemeDescriptor.getUnselectedImageDesc().createImage());
+
+		if (tabThemeDescriptor.getTabMarginSize(SWT.DEFAULT) != -1) {
+			//		tabFolder.setUseSameMarginAllSides(true);		
+			//		tabFolder.setMarginHeight(tabThemeDescriptor.getTabMarginSize(SWT.DEFAULT));
+			//		tabFolder.setBorderMarginHeightColor(tabThemeDescriptor.getTabMarginColor(SWT.DEFAULT));
+		} else if (tabThemeDescriptor.getTabMarginSize(tabPosition) != -1) {
+			//		tabFolder.setMarginHeight(tabThemeDescriptor.getTabMarginSize(tabPosition));
+			//		tabFolder.setBorderMarginHeightColor(tabThemeDescriptor.getTabMarginColor(tabPosition));
+		}
+
+		if (tabThemeDescriptor.getTabFixedHeight() > 0) {
+			tabFolder.setTabHeight(tabThemeDescriptor.getTabFixedHeight());
+		}
+		if (tabThemeDescriptor.getTabFixedWidth() > 0) {
+			//		tabFolder.setTabWidth(tabThemeDescriptor.getTabFixedWidth());
+		}
+		if (tabThemeDescriptor.getBorderStyle() == SWT.NONE) {
+			tabFolder.setBorderVisible(false);
+		}
+
+		//	setTabDragInFolder(tabThemeDescriptor.isDragInFolder());
+
+		/* get the font */
+		if (themeid != null) {
+			Font tabfont =
+				WorkbenchThemeManager.getInstance().getTabFont(
+					themeid,
+					IThemeDescriptor.TAB_TITLE_FONT);
+			tabFolder.setFont(tabfont);
+
+			//		tabFolder.setHoverForeground(WorkbenchThemeManager.getInstance().
+			//					getTabColor(themeid, IThemeDescriptor.TAB_TITLE_TEXT_COLOR_HOVER));
+			tabFolder.setSelectionForeground(
+				WorkbenchThemeManager.getInstance().getTabColor(
+					themeid,
+					IThemeDescriptor.TAB_TITLE_TEXT_COLOR_ACTIVE));
+			//		tabFolder.setInactiveForeground(WorkbenchThemeManager.getInstance().
+			//					getTabColor(themeid, IThemeDescriptor.TAB_TITLE_TEXT_COLOR_DEACTIVATED));										
+		}
+		if (tabThemeDescriptor.isShowClose()) {
+
+			//		if (tabThemeDescriptor.getCloseActiveImageDesc() != null)
+			//			tabFolder.setCloseActiveImage(tabThemeDescriptor.getCloseActiveImageDesc().createImage());
+			//		if (tabThemeDescriptor.getCloseInactiveImageDesc() != null)
+			//			tabFolder.setCloseInactiveImage(tabThemeDescriptor.getCloseInactiveImageDesc().createImage());
+
+			// listener to close the view
+			tabFolder.addCTabFolderListener(new CTabFolderListener() {
+				public void itemClosed(CTabFolderEvent e) {
+					LayoutPart item = (LayoutPart) mapTabToPart.get(e.item);
+					// Item can be null when tab is just created but not map yet.
+					if (item != null) {
+						if (item instanceof ViewPane) {
+							ViewPane pane = (ViewPane) item;
+							pane.doHide();
+						} else
+							remove(item);
+					}
+					//			e.doit = false; // otherwise tab is auto disposed on return
+				}
+			});
+
+			// listener to close the view
+			//		tabFolder.addCTabFolderThemeListener(new CTabFolderThemeListener() {
+			//			public boolean showClosebar(CTabFolderEvent e) {
+			//				LayoutPart item = (LayoutPart)mapTabToPart.get(e.item);
+			//				boolean showClosebar = true;
+			//				// Item can be null when tab is just created but not map yet.
+			//				if (item != null) {
+			//					if (item instanceof PartPane) {
+			//						WorkbenchPartReference ref = (WorkbenchPartReference)((PartPane)item).getPartReference();
+			//						if (ref instanceof IViewReference) {
+			//							IViewReference viewref = (IViewReference)ref;
+			//							if (viewref.getHideCloseButton())
+			//								showClosebar = false;
+			//						}
+			//					}
+			//	
+			//				}
+			//	//			e.doit = false; // otherwise tab is auto disposed on return
+			//				return showClosebar;
+			//			}		
+			//		});
+		}
+	}
+
+	/**
+	 * Listen for notifications from the view part
+	 * that its title has change or it's dirty, and
+	 * update the corresponding tab
+	 *
+	 * @see IPropertyListener
+	 */
+	public void propertyChanged(Object source, int property) {
+		if (property == IWorkbenchPart.PROP_TITLE) {
+			if (source instanceof IViewPart) {
+				IViewPart part = (IViewPart) source;
+				PartPane pane = ((ViewSite) part.getSite()).getPane();
+				CTabItem2 sourceTab = getTab(pane);
+				String title = part.getTitle();
+				Image newImage = part.getTitleImage();
+
+				// @issue need to handle backwards compatibility: tab text is always
+				//   registry name -- for now, only update tab if there's a theme set
+				if (tabThemeDescriptor != null) {
+					// @issue need to take theme settings into account - may not
+					//   want to show text or image
+					if ((title != null) && (title.length() != 0))
+						sourceTab.setText(title);
+
+					if (newImage != sourceTab.getImage())
+						sourceTab.setImage(newImage);
+
+					// @issue what about tooltip?
+				}
+			}
+		}
+	}
+
+	/**
+	 * Returns the theme id.
+	 *
+	 * @return the theme id.
+	 */
+	public String getTheme() {
+		return themeid;
+	}
+
+	/**
+	 * Sets the theme id.
+	 *
+	 * @param theme the theme id to set.
+	 */
+	public void setTheme(String theme) {
+		if ((theme != null) && (theme.length() > 0)) {
+			this.themeid = theme;
+			tabThemeDescriptor = WorkbenchThemeManager.getInstance().getTabThemeDescriptor(theme);
+		}
+	}
+	
+	/**
+	 * Replace the image on the tab with the supplied image.
+	 * @param part PartPane
+	 * @param image Image
+	 */
+	private void updateImage(final PartPane part, final Image image){
+		final CTabItem2 item = getTab(part);
+		if(item != null){
+			UIJob updateJob = new UIJob("Tab Update"){ //$NON-NLS-1$
+				/* (non-Javadoc)
+				 * @see org.eclipse.ui.progress.UIJob#runInUIThread(org.eclipse.core.runtime.IProgressMonitor)
+				 */
+				public IStatus runInUIThread(IProgressMonitor monitor) {
+					part.setImage(item,image);
+					return Status.OK_STATUS;
+				}
+			};
+			updateJob.setSystem(true);
+			updateJob.schedule();
+		}
+	}
+	
+	
+	
 	/**
 	 * Indicate busy state in the supplied partPane.
 	 * @param partPane PartPane.
diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/Perspective.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/Perspective.java
index edb3e73..af29af0 100644
--- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/Perspective.java
+++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/Perspective.java
@@ -22,22 +22,34 @@
 import org.eclipse.core.runtime.IStatus;
 import org.eclipse.core.runtime.MultiStatus;
 import org.eclipse.core.runtime.Status;
-
-import org.eclipse.swt.graphics.Rectangle;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-import org.eclipse.swt.widgets.Shell;
-
 import org.eclipse.jface.dialogs.ErrorDialog;
 import org.eclipse.jface.dialogs.MessageDialog;
 import org.eclipse.jface.preference.IPreferenceStore;
-
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.FocusEvent;
+import org.eclipse.swt.events.FocusListener;
+import org.eclipse.swt.events.PaintEvent;
+import org.eclipse.swt.events.PaintListener;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.GC;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.RGB;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Listener;
+import org.eclipse.swt.widgets.Sash;
+import org.eclipse.swt.widgets.Shell;
 import org.eclipse.ui.IMemento;
 import org.eclipse.ui.IPageLayout;
 import org.eclipse.ui.IPerspectiveDescriptor;
 import org.eclipse.ui.IPerspectiveFactory;
 import org.eclipse.ui.IViewPart;
 import org.eclipse.ui.IViewReference;
+import org.eclipse.ui.IViewSite;
 import org.eclipse.ui.IWorkbenchPart;
 import org.eclipse.ui.PartInitException;
 import org.eclipse.ui.PlatformUI;
@@ -47,7 +59,6 @@
 import org.eclipse.ui.commands.ICompoundCommandHandlerService;
 import org.eclipse.ui.contexts.ContextActivationServiceFactory;
 import org.eclipse.ui.contexts.ICompoundContextActivationService;
-
 import org.eclipse.ui.internal.intro.IIntroConstants;
 import org.eclipse.ui.internal.registry.ActionSetRegistry;
 import org.eclipse.ui.internal.registry.IActionSetDescriptor;
@@ -73,19 +84,87 @@
 	private ArrayList showViewActionIds;
 	private ArrayList perspectiveActionIds;
 	private ArrayList fastViews;
+	private ArrayList fixedViews;
+	private boolean fixed;
 	private ArrayList showInPartIds;
 	private HashMap showInTimes = new HashMap();
 	private IViewReference activeFastView;
+	private IViewReference previousActiveFastView;
 	private IMemento memento;
 	protected PerspectivePresentation presentation;
 	final static private String VERSION_STRING = "0.016";//$NON-NLS-1$
 	private FastViewPane fastViewPane = new FastViewPane();
 	
 	// fields used by fast view resizing via a sash
+	private static final int SASH_SIZE = 3;
 	private static final int FASTVIEW_HIDE_STEPS = 5;
-
+	private static final long FASTVIEW_HIDE_MIN_DURATION = 50;
+	private static final long FASTVIEW_HIDE_MAX_DURATION = 250;
+	private static final RGB RGB_COLOR1 = new RGB(132, 130, 132);
+	private static final RGB RGB_COLOR2 = new RGB(143, 141, 138);
+	private static final RGB RGB_COLOR3 = new RGB(171, 168, 165);
+	private Color borderColor1;
+	private Color borderColor2;
+	private Color borderColor3;
 	private Map mapFastViewToWidthRatio = new HashMap();
+	private Sash fastViewSash;
 	
+	// resize listener to update fast view height and width when
+	// window resized.
+	Listener resizeListener = new Listener() {
+		public void handleEvent(Event event) {
+			if (event.type == SWT.Resize && activeFastView != null) {
+				ViewPane pane = getPane(activeFastView);
+				if (pane.isZoomed() == false) {
+					Rectangle bounds = pane.getBounds();
+					bounds.height = Math.max(0, getClientComposite().getSize().y);
+					float ratio = getFastViewWidthRatio(pane.getID());
+					bounds.width = Math.max(0, (int)((float)(getClientComposite().getSize().x) * ratio));
+					pane.setBounds(bounds);
+					fastViewSash.setBounds(bounds.width - SASH_SIZE, bounds.y, SASH_SIZE, bounds.height - SASH_SIZE);
+					fastViewSash.moveAbove(null);
+				}
+			}
+		}
+	};
+
+	private PaintListener paintListener = new PaintListener() {
+		public void paintControl(PaintEvent event) {
+			if (borderColor1 == null) borderColor1 = WorkbenchColors.getColor(RGB_COLOR1);
+			if (borderColor2 == null) borderColor2 = WorkbenchColors.getColor(RGB_COLOR2);
+			if (borderColor3 == null) borderColor3 = WorkbenchColors.getColor(RGB_COLOR3);
+			
+			Point size = fastViewSash.getSize();
+			Rectangle d = new Rectangle(0, 0, size.x, size.y);
+			GC gc = event.gc;
+			
+			gc.setForeground(borderColor1);
+			gc.drawLine(d.x, d.y, d.x, d.y + d.height);
+		
+			gc.setForeground(borderColor2);
+			gc.drawLine(d.x + 1, d.y + 1, d.x + 1, d.y + d.height);
+		
+			gc.setForeground(borderColor3);
+			gc.drawLine(d.x + 2, d.y + 2, d.x + 2, d.y + d.height);
+		}
+	};
+	private SelectionAdapter selectionListener = new SelectionAdapter () {
+		public void widgetSelected(SelectionEvent e) {
+			if (e.detail == SWT.DRAG && activeFastView != null)
+				checkDragLimit(e);
+			if (e.detail != SWT.DRAG && activeFastView != null) {
+				ViewPane pane = getPane(activeFastView);
+				Rectangle bounds = pane.getBounds();
+				bounds.width = Math.max(0, e.x - bounds.x);
+				pane.setBounds(bounds);
+				Float newRatio = new Float((float)bounds.width/(float)getClientComposite().getSize().x);
+				mapFastViewToWidthRatio.put(pane.getID(), newRatio);
+				updateFastViewSashBounds(bounds);
+				fastViewSash.moveAbove(null);
+			}
+		}
+	};
+
 	private String oldPartID = null;
 	private boolean shouldHideEditorsOnActivate = false;
 
@@ -111,6 +190,7 @@
 	alwaysOnActionSets = new ArrayList(2);
 	alwaysOffActionSets = new ArrayList(2);
 	fastViews = new ArrayList(2);
+	fixedViews = new ArrayList(2);
 }
 
 private final ICompoundCommandHandlerService compoundCommandHandlerService = CommandHandlerServiceFactory.getCompoundCommandHandlerService();
@@ -166,13 +246,22 @@
 	return true;
 }
 
+/**
+ * Prevents the user from making a fast view too narrow or too wide.
+ */
+private void checkDragLimit(SelectionEvent event) {
+	if (event.x < ((float)getClientComposite().getSize().x * IPageLayout.RATIO_MIN))
+		event.x = (int)((float)getClientComposite().getSize().x * IPageLayout.RATIO_MIN);
+	if (event.x > ((float)getClientComposite().getSize().x * IPageLayout.RATIO_MAX))
+		event.x = (int)((float)getClientComposite().getSize().x * IPageLayout.RATIO_MAX);
+}
 
 /**
  * Returns whether a view exists within the perspective.
  */
 public boolean containsView(IViewPart view) {
-	String id = view.getSite().getId();
-	IViewReference ref = findView(id);
+    IViewSite site = view.getViewSite();
+    IViewReference ref = findView(site.getId(), site.getSecondaryId());
 	if(ref == null)
 		return false;
 	return (view == ref.getPart(false));
@@ -219,21 +308,43 @@
 	// Release each view.
 	IViewReference refs[] = getViewReferences();
 	for (int i = 0,length = refs.length; i < length; i ++) {
-		getViewFactory().releaseView(refs[i].getId());
+		getViewFactory().releaseView(refs[i]);
 	}
 
 	fastViewPane.dispose();
+	
+		// Dispose of the sash too...
+	if (fastViewSash != null) {
+		fastViewSash.dispose();
+		fastViewSash = null;
+	}
 
 	mapFastViewToWidthRatio.clear();
 }
 /**
- * See IWorkbenchPage@findView.
+ * Finds the view with the given ID that is open in this page, or <code>null</code>
+ * if not found.
+ * 
+ * @param viewId the view ID
  */
-public IViewReference findView(String id) {
+public IViewReference findView(String viewId) {
+	return findView(viewId, null);
+}
+
+/**
+ * Finds the view with the given id and secondary id that is open in this page, 
+ * or <code>null</code> if not found.
+ * 
+ * @param viewId the view ID
+ * @param secondaryId the secondary ID
+ */
+public IViewReference findView(String id, String secondaryId) {
 	IViewReference refs[] = getViewReferences();
 	for (int i = 0; i < refs.length; i ++) {
 		IViewReference ref = refs[i];
-		if (id.equals(ref.getId()))
+			if (id.equals(ref.getId())
+					&& (secondaryId == null ? ref.getSecondaryId() == null : secondaryId.equals(ref
+							.getSecondaryId())))
 			return ref;
 	}
 	return null;
@@ -350,6 +461,12 @@
 }
 
 /**
+ * Returns the last active fast view.
+ */
+/*package*/ IViewReference getPreviousActiveFastView() {
+	return previousActiveFastView;	
+}
+/**
  * Returns the view factory.
  */
 private ViewFactory getViewFactory() {
@@ -429,18 +546,57 @@
 private void hideFastView(IViewReference ref, int steps) {
 	setFastViewIconSelection(ref, false);
 
+	// Get pane.
+	ViewPane pane = getPane(ref);
+	// Hide the right side sash first
+	if (fastViewSash != null)
+		fastViewSash.setBounds(0, 0, 0, 0);
+	Control ctrl = pane.getControl();
+	
+	if(steps != 0) {
+		// Slide it off screen.
+		Rectangle bounds = pane.getBounds();
+		int increment = bounds.width / steps;
+		
+		// Record the longest we can go before cancelling the animation, 
+		// and the minimum time we will allow each step to take.
 		// Note: We always do at least one step of the animation.
+		long endTime = System.currentTimeMillis() + FASTVIEW_HIDE_MAX_DURATION;
+		long minStepTime = FASTVIEW_HIDE_MIN_DURATION / steps;
+
+		for (int i = 0; i <= bounds.width - 2; i += increment) {
+			long time = System.currentTimeMillis();
+			ctrl.setLocation(-i, bounds.y);
+			ctrl.getParent().update();
+			long afterTime = System.currentTimeMillis();
+			if (afterTime >= endTime) {
+				// Took too long. Just exit the loop.
+				break;
+			}
+			long stepDuration = afterTime - time;
+			if (stepDuration < minStepTime) {
 				// Note: This doesn't take into account the overhead of doing
-	if (ref == activeFastView) {
-		saveFastViewWidthRatio();
-		fastViewPane.hideView();
+				// the loop and these calculations, so the total delay is
+				// always slightly more than "minStepTime".
+				try {
+					Thread.sleep (minStepTime - stepDuration);
+				} catch (InterruptedException ex) {
+					// Do nothing.
 	}	
 }
+		}
+	}
+	// Hide it completely.
+	pane.setVisible(false);
+	pane.setFastViewSash(null);
+	ctrl.setEnabled(false); // Remove focus support.
+}
 /**
  * Hides the fast view sash for zooming in a fast view.
  */
 void hideFastViewSash() {
-	fastViewPane.hideFastViewSash();
+	if (fastViewSash != null)
+		fastViewSash.setBounds(0, 0, 0, 0);
 }
 public boolean hideView(IViewReference ref) {
 	// If the view is locked just return.
@@ -460,7 +616,7 @@
 	}
 	
 	// Dispose view if ref count == 0.
-	getViewFactory().releaseView(ref.getId());
+	getViewFactory().releaseView(ref);
 	return true;
 }
 /*
@@ -476,6 +632,25 @@
 	return fastViews.contains(ref);
 }
 /**
+ * Returns true if a view is fixed.
+ */
+public boolean isFixedView(IViewReference ref) {
+	return fixedViews.contains(ref);
+}
+/**
+ * Returns true if a layout or perspective is fixed.
+ */
+public boolean isFixedLayout() {
+	//@issue is there a difference between a fixed
+	//layout and a fixed perspective?? If not the API
+	//may need some polish, WorkbenchPage, PageLayout
+	//and Perspective all have isFixed methods.  
+	//PageLayout and Perspective have their own fixed
+	//attribute, we are assuming they are always in sync.
+	//WorkbenchPage delegates to the perspective.
+	return fixed;
+}
+/**
  * Creates a new presentation from a persistence file.
  * Note: This method should not modify the current state of the perspective.
  */
@@ -532,6 +707,8 @@
 	// Create layout factory.
 	RootLayoutContainer container = new RootLayoutContainer(page);
 	PageLayout layout = new PageLayout(container, getViewFactory(), editorArea, descriptor);
+	layout.setTheme(getDesc().getTheme());
+	layout.setFixed(descriptor.getFixed());
 
 	// add the placeholder for the intro view
 	layout.addPlaceholder(IIntroConstants.INTRO_VIEW_ID, IPageLayout.RIGHT, .75f, IPageLayout.ID_EDITOR_AREA);
@@ -554,6 +731,12 @@
 	// Create fast views
 	fastViews = layout.getFastViews();
 		
+	// Create fixed views
+	fixedViews = layout.getFixedViews();
+	
+	// Is the layout fixed
+	fixed = layout.isFixed();
+				
 	// Create presentation.	
 	presentation = new PerspectivePresentation(page, container);
 
@@ -598,6 +781,7 @@
 	
 	setAllPinsVisible(true);
 	presentation.activate(getClientComposite());
+	getClientComposite().addListener(SWT.Resize, resizeListener);
 	
 	if (shouldHideEditorsOnActivate) {
 		// We do this here to ensure that createPartControl is called on the top editor
@@ -610,6 +794,7 @@
  * deactivate.
  */
 protected void onDeactivate() {
+	getClientComposite().removeListener(SWT.Resize, resizeListener);
 	presentation.deactivate();
 	setActiveFastView(null);
 	setAllPinsVisible(false);
@@ -655,7 +840,10 @@
 		Control ctrl = pane.getControl();
 		if (ctrl != null)
 			ctrl.setEnabled(true); // Modify focus support.
-
+		// We are disabling the pane because it will be enabled when it
+		// is added to the presentation. When a pane is enabled a drop
+		// listener is added to it, and we do not want to have multiple
+		// listeners for a pane
 		presentation.addPart(pane);
 	}
 }
@@ -766,7 +954,9 @@
 			continue;
 		}
 		if(ref.getPane() == null) {
-			ref.setPane(new ViewPane((IViewReference)ref,page));
+			ViewPane vp = new ViewPane((IViewReference)ref,page);
+			vp.setTheme(getDesc().getTheme());
+			ref.setPane(vp);
 		}
 		page.addPart(ref);
 		if(pres.willPartBeVisible(ref.getId())) {
@@ -825,6 +1015,39 @@
 		}
 	}
 		
+	// Load the fixed views
+	IMemento fixedViewsMem = memento.getChild(IWorkbenchConstants.TAG_FIXED_VIEWS);
+	if(fixedViewsMem != null) {
+		views = fixedViewsMem.getChildren(IWorkbenchConstants.TAG_VIEW);
+		for (int x = 0; x < views.length; x ++) {
+			// Get the view details.
+			IMemento childMem = views[x];
+			String viewID = childMem.getString(IWorkbenchConstants.TAG_ID);
+			
+			WorkbenchPartReference ref = (WorkbenchPartReference) viewFactory.getView(viewID);
+			if(ref == null) {
+				WorkbenchPlugin.log("Could not create view: '" + viewID + "'."); //$NON-NLS-1$ //$NON-NLS-2$
+				result.add(new Status(
+						Status.ERROR,PlatformUI.PLUGIN_ID,0,
+						WorkbenchMessages.format("Perspective.couldNotFind", new String[]{viewID}), //$NON-NLS-1$
+						null));
+				continue;
+			}
+			// Add to fixed view list because creating a view pane
+			// will come back to check if its a fast view. We really
+			// need to clean up this code.
+			
+			//@issue see directly above, also I don't think we need
+			// to actually restore the view bleow, probably shouldn't
+			// throw the error above either
+			fixedViews.add(ref);
+//			if(ref.getPane() == null) {
+//				ref.setPane(new ViewPane((IViewReference)ref,page));
+//			}
+//			page.addPart(ref);
+		}
+	}
+		
 	// Load the action sets.
 	IMemento [] actions = memento.getChildren(IWorkbenchConstants.TAG_ACTION_SET);
 	ArrayList actionsArray = new ArrayList(actions.length);
@@ -907,6 +1130,11 @@
 	// are created. This ensures that if an editor is instantiated, createPartControl
 	// is also called. See bug 20166.
 	shouldHideEditorsOnActivate = (areaVisible != null && areaVisible.intValue() == 0);
+	
+	// restore the fixed state
+	Integer isFixed = memento.getInteger(IWorkbenchConstants.TAG_FIXED);
+	fixed = (isFixed != null && isFixed.intValue() == 1);
+	
 	return result;
 }
 
@@ -1078,6 +1306,16 @@
 			viewMemento.putFloat(IWorkbenchConstants.TAG_RATIO, ratio);
 		}
 	}
+	if(fixedViews.size() > 0) {
+		IMemento childMem = memento.createChild(IWorkbenchConstants.TAG_FIXED_VIEWS);
+		enum = fixedViews.iterator();
+		while (enum.hasNext()) {
+			IViewReference ref = (IViewReference)enum.next();
+			IMemento viewMemento = childMem.createChild(IWorkbenchConstants.TAG_VIEW);
+			String id = ref.getId();
+			viewMemento.putString(IWorkbenchConstants.TAG_ID, id);
+		}
+	}
 	if(errors > 0) {
 		String message = WorkbenchMessages.getString("Perspective.multipleErrors"); //$NON-NLS-1$
 		if(errors == 1)
@@ -1094,6 +1332,13 @@
 		memento.putInteger(IWorkbenchConstants.TAG_AREA_VISIBLE, 1);
 	else
 		memento.putInteger(IWorkbenchConstants.TAG_AREA_VISIBLE, 0);
+	
+	// Save the fixed state
+	if (fixed)
+		memento.putInteger(IWorkbenchConstants.TAG_FIXED, 1);
+	else
+		memento.putInteger(IWorkbenchConstants.TAG_FIXED, 0);
+	
 	return result;
 }
 /**
@@ -1142,6 +1387,9 @@
 	if (activeFastView == ref)
 		return;
 		
+	if (activeFastView != null)
+		previousActiveFastView = activeFastView;
+		
 	if (activeFastView != null) {
 		ViewPane pane = getPane(activeFastView);
 		if (pane.isZoomed()) {
@@ -1265,31 +1513,55 @@
 	
 	ViewPane pane = getPane(ref);	
 
-	saveFastViewWidthRatio();
+	// Create the control first
+	Control ctrl = pane.getControl();
+	if(ctrl == null) {
+		pane.createControl(getClientComposite());
+		ctrl = pane.getControl();
+	}
 	
-	int side = ((WorkbenchWindow)pane.getWorkbenchWindow()).getFastViewBarSide();
+	// Show pane fast.
+	ctrl.setEnabled(true); // Add focus support.
+	Composite parent = ctrl.getParent();
+	Rectangle bounds = getFastViewBounds(ref);
 	
-	fastViewPane.showView(getClientComposite(), pane, side, getFastViewWidthRatio(ref.getId()));	
+	pane.setVisible(true);
+	pane.setBounds(bounds);
+	pane.moveAbove(null);
+	pane.setFocus();
+	
+	// Show the Sash to enable right side resize
+	if (fastViewSash == null) {
+		fastViewSash = new Sash(parent, SWT.VERTICAL);
+		fastViewSash.addPaintListener(paintListener);
+		fastViewSash.addFocusListener(new FocusListener() {
+			public void focusGained(FocusEvent e) {
+				fastViewSash.removePaintListener(paintListener);
+			}
+			public void focusLost(FocusEvent e) {
+				fastViewSash.addPaintListener(paintListener);
+			}
+		});
+		fastViewSash.addSelectionListener(selectionListener);
+	}
+	pane.setFastViewSash(fastViewSash);
+	updateFastViewSashBounds(bounds);
+	fastViewSash.moveAbove(null);
 	
 	setFastViewIconSelection(ref, true);
 }
 
-private void saveFastViewWidthRatio() {
-	ViewPane pane = fastViewPane.getCurrentPane();
-	
-	if (pane != null) {
-		mapFastViewToWidthRatio.put(pane.getViewReference().getId(), new Float(fastViewPane.getCurrentRatio()));
+public void updateFastViewSashBounds(Rectangle partBounds) {
+	fastViewSash.setBounds(partBounds.x + partBounds.width - 1, partBounds.y + 1, SASH_SIZE, partBounds.height - 2);
 	}
-}
-
 /**
- * See IWorkbenchPage.
+ * Shows the view with the given id and secondary id.
  */
-public IViewPart showView(String viewID) 
+public IViewPart showView(String viewId, String secondaryId) 
 	throws PartInitException 
 {
 	ViewFactory factory = getViewFactory();
-	IViewReference ref = factory.createView(viewID);
+	IViewReference ref = factory.createView(viewId, secondaryId);
 	IViewPart part = (IViewPart)ref.getPart(false);
 	if(part == null) {
 		IStatus status = factory.restoreView(ref);
@@ -1307,7 +1579,7 @@
 	
 	IPreferenceStore store = WorkbenchPlugin.getDefault().getPreferenceStore();
 	int openViewMode = store.getInt(IPreferenceConstants.OPEN_VIEW_MODE);
-	if (presentation.hasPlaceholder(viewID)) {
+	if (presentation.hasPlaceholder(viewId)) {
 		presentation.addPart(pane);
 	} else if (openViewMode == IPreferenceConstants.OVM_EMBED) {
 		presentation.addPart(pane);
diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/PerspectivePresentation.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/PerspectivePresentation.java
index 65ed113..ee63e63 100644
--- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/PerspectivePresentation.java
+++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/PerspectivePresentation.java
@@ -822,7 +822,7 @@
 					LayoutPart visiblePart =
 						((PartTabFolder) part).getVisiblePart();
 					// create a new folder and add the children to it
-					PartTabFolder folder = new PartTabFolder();
+					PartTabFolder folder = new PartTabFolder(page);
 					sashContainer.add(
 						folder,
 						relativePosition,
@@ -853,7 +853,7 @@
 				derefPart(part);
 
 				// Create a new folder and add both items
-				PartTabFolder folder = new PartTabFolder();
+				PartTabFolder folder = new PartTabFolder(page);
 				sashContainer.add(
 					folder,
 					relativePosition,
@@ -1359,7 +1359,7 @@
 			folder.add(newPart);
 		} else if (newContainer instanceof RootLayoutContainer) {
 			// Create a new folder and add both items
-			PartTabFolder folder = new PartTabFolder();
+			PartTabFolder folder = new PartTabFolder(page);
 			((RootLayoutContainer) newContainer).replace(refPart, folder);
 			folder.add(refPart);
 			folder.add(newPart);
diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/PlatformUIPreferenceListener.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/PlatformUIPreferenceListener.java
index 842d4e5..d458216 100644
--- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/PlatformUIPreferenceListener.java
+++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/PlatformUIPreferenceListener.java
@@ -22,7 +22,6 @@
 import org.eclipse.swt.graphics.FontData;
 import org.eclipse.ui.IWorkbench;
 import org.eclipse.ui.IWorkbenchPreferenceConstants;
-import org.eclipse.ui.IWorkbenchWindow;
 import org.eclipse.ui.PlatformUI;
 import org.eclipse.ui.internal.fonts.FontDefinition;
 
@@ -77,22 +76,9 @@
 					PreferenceConverter.readFontData((String) newValue);
 			else
 				newSetting = (FontData[]) newValue;
-			
-			//Do not update for null setting
-			if(newSetting == null)
-				return;
 				
 			JFaceResources.getFontRegistry().put(propertyName, newSetting);
 		}
-		
-		//Update the workbench windows if we get the small font
-		if(propertyName.equals(PerspectiveBarManager.SMALL_FONT)){
-			IWorkbenchWindow[] windows =  PlatformUI.getWorkbench().getWorkbenchWindows();
-			for (int i = 0; i < windows.length; i++) {
-				WorkbenchWindow window = (WorkbenchWindow) windows[i];
-				window.getPerspectiveBar().updateFont();
-			}
-		}
 	}
 
 	/**
diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/RootLayoutContainer.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/RootLayoutContainer.java
index d14d9dd..c564c22 100644
--- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/RootLayoutContainer.java
+++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/RootLayoutContainer.java
@@ -19,160 +19,158 @@
 /**
  * Represents the top level container.
  */
-public class RootLayoutContainer
-	extends PartSashContainer {
-	public RootLayoutContainer(WorkbenchPage page) {
-		super("root layout container", page); //$NON-NLS-1$
-	}
-	/**
-	 * Notification that a child layout part has been
-	 * added to the container. Subclasses may override
-	 * this method to perform any container specific
-	 * work.
-	 */
-	protected void childAdded(LayoutPart child) {
-		// do nothing
-	}
-	/**
-	 * Gets root container for this part.
-	 */
-	public RootLayoutContainer getRootContainer() {
-		return this;
-	}
-	/**
-	 * Notification that a child layout part has been
-	 * removed from the container. Subclasses may override
-	 * this method to perform any container specific
-	 * work.
-	 */
-	protected void childRemoved(LayoutPart child) {
-		// do nothing
-	}
-	/**
-	 * Subclasses override this method to specify
-	 * the composite to use to parent all children
-	 * layout parts it contains.
-	 */
-	protected Composite createParent(Composite parentWidget) {
-		return parentWidget;
-	}
-	/**
-	 * Subclasses override this method to dispose
-	 * of any swt resources created during createParent.
-	 */
-	protected void disposeParent() {
-		// do nothing
-	}
-	/**
-	 * Get the part control.  This method may return null.
-	 */
-	public Control getControl() {
-		return this.parent;
-	}
-	/**
-	 * @see IPersistablePart
-	 */
-	public IStatus restoreState(IMemento memento) {
-		MultiStatus result = new MultiStatus(PlatformUI.PLUGIN_ID, IStatus.OK, WorkbenchMessages.getString("RootLayoutContainer.problemsRestoringPerspective"), null); //$NON-NLS-1$
-
-		// Read the info elements.
-		IMemento[] children = memento.getChildren(IWorkbenchConstants.TAG_INFO);
-
-		// Create a part ID to part hashtable.
-		Map mapIDtoPart = new HashMap(children.length);
-
-		// Loop through the info elements.
-		for (int i = 0; i < children.length; i++) {
-			// Get the info details.
-			IMemento childMem = children[i];
-			String partID = childMem.getString(IWorkbenchConstants.TAG_PART);
-			String relativeID = childMem.getString(IWorkbenchConstants.TAG_RELATIVE);
-			int relationship = 0;
-			float ratio = 0.0f;
-			if (relativeID != null) {
-				relationship = childMem.getInteger(IWorkbenchConstants.TAG_RELATIONSHIP).intValue();
-				ratio = childMem.getFloat(IWorkbenchConstants.TAG_RATIO).floatValue();
-			}
-			String strFolder = childMem.getString(IWorkbenchConstants.TAG_FOLDER);
-
-			// Create the part.
-			LayoutPart part = null;
-			if (strFolder == null)
-				part = new PartPlaceholder(partID);
-			else {
-				PartTabFolder folder = new PartTabFolder();
-				folder.setID(partID);
-				result.add(folder.restoreState(childMem.getChild(IWorkbenchConstants.TAG_FOLDER)));
-				ContainerPlaceholder placeholder = new ContainerPlaceholder(partID);
-				placeholder.setRealContainer(folder);
-				part = placeholder;
-			}
-			// 1FUN70C: ITPUI:WIN - Shouldn't set Container when not active
-			part.setContainer(this);
-
-			// Add the part to the layout
-			if (relativeID == null) {
-				add(part);
-			} else {
-				LayoutPart refPart = (LayoutPart) mapIDtoPart.get(relativeID);
-				if (refPart != null) {
-					add(part, relationship, ratio, refPart);
-				} else {
-					WorkbenchPlugin.log("Unable to find part for ID: " + relativeID); //$NON-NLS-1$
-				}
-			}
-			mapIDtoPart.put(partID, part);
-		}
-		return result;
-	}
-	/**
-	 * @see IPersistablePart
-	 */
-	public IStatus saveState(IMemento memento) {
-		RelationshipInfo[] relationships = computeRelation();
-
-		MultiStatus result = new MultiStatus(PlatformUI.PLUGIN_ID, IStatus.OK, WorkbenchMessages.getString("RootLayoutContainer.problemsSavingPerspective"), null); //$NON-NLS-1$
-
-		// Loop through the relationship array.
-		for (int i = 0; i < relationships.length; i++) {
-			// Save the relationship info ..
-			//		private LayoutPart part;
-			// 		private int relationship;
-			// 		private float ratio;
-			// 		private LayoutPart relative;
-			RelationshipInfo info = relationships[i];
-			IMemento childMem = memento.createChild(IWorkbenchConstants.TAG_INFO);
-			childMem.putString(IWorkbenchConstants.TAG_PART, info.part.getID());
-			if (info.relative != null) {
-				childMem.putString(IWorkbenchConstants.TAG_RELATIVE, info.relative.getID());
-				childMem.putInteger(IWorkbenchConstants.TAG_RELATIONSHIP, info.relationship);
-				childMem.putFloat(IWorkbenchConstants.TAG_RATIO, info.ratio);
-			}
-
-			// Is this part a folder or a placeholder for one?
-			PartTabFolder folder = null;
-			if (info.part instanceof PartTabFolder) {
-				folder = (PartTabFolder) info.part;
-			} else if (info.part instanceof ContainerPlaceholder) {
-				LayoutPart part = ((ContainerPlaceholder) info.part).getRealContainer();
-				if (part instanceof PartTabFolder)
-					folder = (PartTabFolder) part;
-			}
-
-			// If this is a folder save the contents.
-			if (folder != null) {
-				childMem.putString(IWorkbenchConstants.TAG_FOLDER, "true"); //$NON-NLS-1$
-				IMemento folderMem = childMem.createChild(IWorkbenchConstants.TAG_FOLDER);
-				result.add(folder.saveState(folderMem));
-			}
-		}
-		return result;
-	}
+public class RootLayoutContainer extends PartSashContainer {
+public RootLayoutContainer(WorkbenchPage page) {
+	super("root layout container",page);//$NON-NLS-1$
+}
+/**
+ * Notification that a child layout part has been
+ * added to the container. Subclasses may override
+ * this method to perform any container specific
+ * work.
+ */
+protected void childAdded(LayoutPart child) {
+	// do nothing
+}
+/**
+ * Gets root container for this part.
+ */
+public RootLayoutContainer getRootContainer() {
+	return this;
+}
+/**
+ * Notification that a child layout part has been
+ * removed from the container. Subclasses may override
+ * this method to perform any container specific
+ * work.
+ */
+protected void childRemoved(LayoutPart child) {
+	// do nothing
+}
+/**
+ * Subclasses override this method to specify
+ * the composite to use to parent all children
+ * layout parts it contains.
+ */
+protected Composite createParent(Composite parentWidget) {
+	return parentWidget;
+}
+/**
+ * Subclasses override this method to dispose
+ * of any swt resources created during createParent.
+ */
+protected void disposeParent() {
+	// do nothing
+}
+/**
+ * Get the part control.  This method may return null.
+ */
+public Control getControl() {
+	return this.parent;
+}
+/**
+ * @see IPersistablePart
+ */
+public IStatus restoreState(IMemento memento) 
+{
+	MultiStatus result = new MultiStatus(
+		PlatformUI.PLUGIN_ID,IStatus.OK,
+		WorkbenchMessages.getString("RootLayoutContainer.problemsRestoringPerspective"),null); //$NON-NLS-1$
 	
-	/* (non-Javadoc)
-	 * @see org.eclipse.ui.internal.IWorkbenchDropTarget#getType()
-	 */
-	public int getType() {
-		return EDITOR | VIEW;
+	// Read the info elements.
+	IMemento [] children = memento.getChildren(IWorkbenchConstants.TAG_INFO);
+
+	// Create a part ID to part hashtable.
+	Map mapIDtoPart = new HashMap(children.length);
+
+	// Loop through the info elements.
+	for (int i = 0; i < children.length; i ++) 
+	{
+		// Get the info details.
+		IMemento childMem = children[i];
+		String partID = childMem.getString(IWorkbenchConstants.TAG_PART);
+		String relativeID = childMem.getString(IWorkbenchConstants.TAG_RELATIVE);
+		int relationship = 0;
+		float ratio = 0.0f;
+		if (relativeID != null) {
+			relationship = childMem.getInteger(IWorkbenchConstants.TAG_RELATIONSHIP).intValue();
+			ratio = childMem.getFloat(IWorkbenchConstants.TAG_RATIO).floatValue();
+		}
+		String strFolder = childMem.getString(IWorkbenchConstants.TAG_FOLDER);
+
+		// Create the part.
+		LayoutPart part = null;
+		if (strFolder == null)
+			part = new PartPlaceholder(partID);
+		else {
+			PartTabFolder folder = new PartTabFolder(page);
+			folder.setID(partID);
+			result.add(folder.restoreState(childMem.getChild(IWorkbenchConstants.TAG_FOLDER)));
+			ContainerPlaceholder placeholder = new ContainerPlaceholder(partID);
+			placeholder.setRealContainer(folder);
+			part = placeholder;
+		}
+		// 1FUN70C: ITPUI:WIN - Shouldn't set Container when not active
+		part.setContainer(this);
+		
+		// Add the part to the layout
+		if (relativeID == null) {
+			add(part);
+		} else {
+			LayoutPart refPart = (LayoutPart)mapIDtoPart.get(relativeID);
+			if (refPart != null) {
+				add(part, relationship, ratio, refPart);	
+			} else {
+				WorkbenchPlugin.log("Unable to find part for ID: " + relativeID);//$NON-NLS-1$
+			}
+		}
+		mapIDtoPart.put(partID, part);
 	}
+	return result;
+}
+/**
+ * @see IPersistablePart
+ */
+public IStatus saveState(IMemento memento) {
+	RelationshipInfo[] relationships = computeRelation();
+
+	MultiStatus result = new MultiStatus(
+		PlatformUI.PLUGIN_ID,IStatus.OK,
+		WorkbenchMessages.getString("RootLayoutContainer.problemsSavingPerspective"),null); //$NON-NLS-1$
+	
+	// Loop through the relationship array.
+	for (int i = 0; i < relationships.length; i ++) {
+		// Save the relationship info ..
+		//		private LayoutPart part;
+		// 		private int relationship;
+		// 		private float ratio;
+		// 		private LayoutPart relative;
+		RelationshipInfo info = relationships[i];
+		IMemento childMem = memento.createChild(IWorkbenchConstants.TAG_INFO);
+		childMem.putString(IWorkbenchConstants.TAG_PART, info.part.getID());
+		if (info.relative != null) {
+			childMem.putString(IWorkbenchConstants.TAG_RELATIVE, info.relative.getID());
+			childMem.putInteger(IWorkbenchConstants.TAG_RELATIONSHIP, info.relationship);
+			childMem.putFloat(IWorkbenchConstants.TAG_RATIO, info.ratio);
+		}
+
+		// Is this part a folder or a placeholder for one?
+		PartTabFolder folder = null;
+		if (info.part instanceof PartTabFolder) {
+			folder = (PartTabFolder)info.part;
+		} else if (info.part instanceof ContainerPlaceholder) {
+			LayoutPart part = ((ContainerPlaceholder)info.part).getRealContainer();
+			if (part instanceof PartTabFolder)
+				folder = (PartTabFolder)part;
+		}
+
+		// If this is a folder save the contents.
+		if (folder != null) {
+			childMem.putString(IWorkbenchConstants.TAG_FOLDER, "true");//$NON-NLS-1$
+			IMemento folderMem = childMem.createChild(IWorkbenchConstants.TAG_FOLDER);
+			result.add(folder.saveState(folderMem));
+		}
+	}
+	return result;
+}
 }
diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/ViewFactory.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/ViewFactory.java
index 7d4a914..278efe1 100644
--- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/ViewFactory.java
+++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/ViewFactory.java
@@ -47,9 +47,14 @@
 
 	private class ViewReference extends WorkbenchPartReference implements IViewReference {
 
-		boolean create = true;
+		private String secondaryId;
+		private boolean create = true;
 
 		public ViewReference(String id) {
+			this(id, null);
+		}
+		
+		public ViewReference(String id, String secondaryId) {
 			ViewDescriptor desc = (ViewDescriptor) viewReg.find(id);
 			ImageDescriptor iDesc = null;
 			String title = null;
@@ -58,6 +63,7 @@
 				title = desc.getLabel();
 			}
 			init(id, title, null, iDesc);
+			this.secondaryId = secondaryId;
 		}
 		
 		/* (non-Javadoc)
@@ -99,7 +105,7 @@
 			}
 			return part;
 		}
-		
+
 		/* (non-Javadoc)
 		 * @see org.eclipse.ui.internal.WorkbenchPartReference#getRegisteredName()
 		 */
@@ -115,6 +121,13 @@
 		}
 		
 		/* (non-Javadoc)
+		 * @see org.eclipse.ui.IViewReference
+		 */
+		public String getSecondaryId() {
+			return secondaryId;
+		}
+
+		/* (non-Javadoc)
 		 * @see org.eclipse.ui.IViewReference#getView(boolean)
 		 */
 		public IViewPart getView(boolean restore) {
@@ -200,7 +213,7 @@
 				}
 
 				// Create site
-				ViewSite site = new ViewSite(view, page, desc);
+				ViewSite site = new ViewSite(ref, view, page, desc);
 				try {
 					try {
 						UIStats.start(UIStats.INIT_PART, label);
@@ -209,13 +222,13 @@
 						UIStats.end(UIStats.INIT_PART, label);
 					}
 				} catch (PartInitException e) {
-					releaseView(viewID);
+					releaseView(ref);
 					result[0] = new Status(IStatus.ERROR, PlatformUI.PLUGIN_ID, 0, WorkbenchMessages.format("Perspective.exceptionRestoringView", new String[] { viewID }), //$NON-NLS-1$
 					e);
 					return;
 				}
 				if (view.getSite() != site) {
-					releaseView(viewID);
+					releaseView(ref);
 					result[0] = new Status(IStatus.ERROR, PlatformUI.PLUGIN_ID, 0, WorkbenchMessages.format("ViewFactory.siteException", new Object[] { desc.getID()}), //$NON-NLS-1$
 					null);
 					return;
@@ -223,7 +236,7 @@
 
 				PartPane pane = ((ViewReference) ref).getPane();
 				if (pane == null) {
-					pane = new ViewPane(ref, page);
+					pane = new ViewPane(ref, page, page.getPerspective().getTheme());
 					((ViewReference) ref).setPane(pane);
 				}
 				site.setPane(pane);
@@ -246,25 +259,46 @@
 	 * to getView.
 	 */
 	public IViewReference createView(final String id) throws PartInitException {
+	    return createView(id, null);
+	}
+
+	/**
+	 * Creates an instance of a view defined by id and secondary id.
+	 * 
+	 * This factory implements reference counting.  The first call to this
+	 * method will return a new view.  Subsequent calls will return the
+	 * first view with an additional reference count.  The view is
+	 * disposed when releaseView is called an equal number of times
+	 * to createView.
+	 */
+	public IViewReference createView(String id, String secondaryId) throws PartInitException {
 		IViewDescriptor desc = viewReg.find(id);
+		// ensure that the view id is valid
 		if (desc == null)
 			throw new PartInitException(WorkbenchMessages.format("ViewFactory.couldNotCreate", new Object[] { id })); //$NON-NLS-1$
-		IViewReference ref = (IViewReference) counter.get(desc);
+		// ensure that multiple instances are allowed if a secondary id is given
+		if (secondaryId != null) {
+		    if (!desc.getAllowMultiple()) {
+				throw new PartInitException(WorkbenchMessages.format("ViewFactory.noMultiple", new Object[] { id })); //$NON-NLS-1$
+		    }
+		}
+		String key = getKey(id, secondaryId);
+		IViewReference ref = (IViewReference) counter.get(key);
 		if (ref == null) {
-			ref = new ViewReference(id);
-			counter.put(desc, ref);
+			ref = new ViewReference(id, secondaryId);
+			counter.put(key, ref);
 		} else {
-			counter.addRef(desc);
+			counter.addRef(key);
 		}
 		return ref;
 	}
-	
-	/**
+
+    /**
 	 * Remove a view rec from the manager.
 	 *
 	 * The IViewPart.dispose method must be called at a higher level.
 	 */
-	private void destroyView(IViewDescriptor desc, IViewPart view) {
+	private void destroyView(IViewPart view) {
 		// Free action bars, pane, etc.
 		PartSite site = (PartSite) view.getSite();
 		ViewActionBars actionBars = (ViewActionBars) site.getActionBars();
@@ -277,11 +311,29 @@
 	}
 	
 	/**
+     * Returns the key to use in the ReferenceCounter.
+     * 
+     * @param id the primary view id
+     * @param secondaryId the secondary view id or <code>null</code>
+     * @return the key to use in the ReferenceCounter
+     */
+    private String getKey(String id, String secondaryId) {
+        return secondaryId == null ? id : id + '/' + secondaryId;
+    }
+
+	/**
 	 * Returns the view with the given id, or <code>null</code> if not found.
 	 */
 	public IViewReference getView(String id) {
-		IViewDescriptor desc = viewReg.find(id);
-		return (IViewReference) counter.get(desc);
+	    return getView(id, null);
+	}
+
+	/**
+	 * Returns the view with the given id and secondary id, or <code>null</code> if not found.
+	 */
+	public IViewReference getView(String id, String secondaryId) {
+	    String key = getKey(id, secondaryId);
+		return (IViewReference) counter.get(key);
 	}
 
 	/**
@@ -298,9 +350,7 @@
 	public IViewReference[] getViews() {
 		List list = counter.values();
 		IViewReference[] array = new IViewReference[list.size()];
-		for (int i = 0; i < array.length; i++) {
-			array[i] = (IViewReference) list.get(i);
-		}
+		list.toArray(array);
 		return array;
 	}
 	
@@ -316,27 +366,25 @@
 	 * Returns whether a view with the given id exists.
 	 */
 	public boolean hasView(String id) {
-		IViewDescriptor desc = viewReg.find(id);
-		Object view = counter.get(desc);
-		return (view != null);
+	    return getView(id) != null;
 	}
 	
 	/**
-	 * Releases an instance of a view defined by id.
+	 * Releases an instance of a view.
 	 *
 	 * This factory does reference counting.  For more info see
 	 * getView.
 	 */
-	public void releaseView(String id) {
-		IViewDescriptor desc = viewReg.find(id);
-		IViewReference ref = (IViewReference) counter.get(desc);
+	public void releaseView(IViewReference viewRef) {
+	    String key = getKey(viewRef.getId(), viewRef.getSecondaryId());
+		IViewReference ref = (IViewReference) counter.get(key);
 		if (ref == null)
 			return;
-		int count = counter.removeRef(desc);
+		int count = counter.removeRef(key);
 		if (count <= 0) {
 			IViewPart view = (IViewPart) ref.getPart(false);
 			if (view != null)
-				destroyView(desc, view);
+				destroyView(view);
 		}
 	}
 	
diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/ViewIntroAdapterPart.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/ViewIntroAdapterPart.java
index a8f375a..1609676 100644
--- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/ViewIntroAdapterPart.java
+++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/ViewIntroAdapterPart.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2003 IBM Corporation and others.
+ * Copyright (c) 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
diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/ViewIntroAdapterSite.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/ViewIntroAdapterSite.java
index 36209a9..f8134e4 100644
--- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/ViewIntroAdapterSite.java
+++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/ViewIntroAdapterSite.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2003 IBM Corporation and others.
+ * Copyright (c) 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
diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/ViewPane.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/ViewPane.java
index b312935..d6c87fd 100644
--- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/ViewPane.java
+++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/ViewPane.java
@@ -14,28 +14,6 @@
 **********************************************************************/
 
 import org.eclipse.core.runtime.Platform;
-
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.custom.CTabFolder2;
-import org.eclipse.swt.custom.ViewForm2;
-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.graphics.Color;
-import org.eclipse.swt.graphics.Image;
-import org.eclipse.swt.graphics.Point;
-import org.eclipse.swt.graphics.Rectangle;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-import org.eclipse.swt.widgets.Menu;
-import org.eclipse.swt.widgets.MenuItem;
-import org.eclipse.swt.widgets.Sash;
-import org.eclipse.swt.widgets.Text;
-import org.eclipse.swt.widgets.ToolBar;
-import org.eclipse.swt.widgets.ToolItem;
-
 import org.eclipse.jface.action.ContributionItem;
 import org.eclipse.jface.action.IAction;
 import org.eclipse.jface.action.IContributionItem;
@@ -43,17 +21,42 @@
 import org.eclipse.jface.action.ToolBarManager;
 import org.eclipse.jface.resource.JFaceColors;
 import org.eclipse.jface.util.SafeRunnable;
-
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.CLabel;
+import org.eclipse.swt.custom.CTabFolder2;
+import org.eclipse.swt.custom.CTabItem;
+import org.eclipse.swt.custom.ViewForm2;
+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.graphics.Color;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Listener;
+import org.eclipse.swt.widgets.Menu;
+import org.eclipse.swt.widgets.MenuItem;
+import org.eclipse.swt.widgets.Sash;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.swt.widgets.ToolBar;
+import org.eclipse.swt.widgets.ToolItem;
 import org.eclipse.ui.IPropertyListener;
 import org.eclipse.ui.IViewPart;
 import org.eclipse.ui.IViewReference;
 import org.eclipse.ui.IWorkbenchPart;
 import org.eclipse.ui.IWorkbenchPartSite;
-import org.eclipse.ui.part.ViewPart;
-import org.eclipse.ui.part.WorkbenchPart;
-
 import org.eclipse.ui.internal.dnd.AbstractDragSource;
 import org.eclipse.ui.internal.dnd.DragUtil;
+import org.eclipse.ui.internal.themes.IThemeDescriptor;
+import org.eclipse.ui.internal.themes.WorkbenchThemeManager;
+import org.eclipse.ui.part.ViewPart;
+import org.eclipse.ui.part.WorkbenchPart;
 
 /**
  * Provides support for a title bar where the
@@ -67,8 +70,10 @@
  * part.
  */
 public class ViewPane extends PartPane implements IPropertyListener {
+	private CLabel titleLabel;
 
 	private boolean fast = false;
+		private boolean showFocus = false;
 	// toolbars can be locked (i.e. part of the view form and 
 	// positioned inside it, or not locked (embedded in a floating
 	// toolbar that is not part of the view form
@@ -90,6 +95,7 @@
 	 * Indicates whether a toolbar button is shown for the view local menu.
 	 */
 	private boolean showMenuButton = false;
+	private String theme;
 
 	//Created in o.e.ui.Perspective, disposed there.
 	private Sash fastViewSash;
@@ -215,6 +221,22 @@
 				});
 			}
 
+			if (isCloseable()) {
+				ToolItem closeButton = new ToolItem(toolbar, SWT.PUSH, index++);
+				// Image img = WorkbenchImages.getImage(IWorkbenchGraphicConstants.IMG_LCL_CLOSE_VIEW);
+				Image hoverImage =
+					WorkbenchImages.getImage(IWorkbenchGraphicConstants.IMG_LCL_CLOSE_VIEW_HOVER);
+				closeButton.setDisabledImage(hoverImage);
+				// PR#1GE56QT - Avoid creation of unnecessary image.
+				closeButton.setImage(hoverImage);
+				// closeButton.setHotImage(hoverImage);
+				closeButton.setToolTipText(WorkbenchMessages.getString("Close")); //$NON-NLS-1$
+				closeButton.addSelectionListener(new SelectionAdapter() {
+					public void widgetSelected(SelectionEvent e) {
+						doHide();
+		}
+				});
+	}
 		}
 	}
 
@@ -228,6 +250,17 @@
 		fast = ref.isFastView();
 	}
 	/**
+	 * Constructs a view pane for a view part with a theme id.
+	 * 
+	 * @issue the theme should be obtained from the current perspective as needed, 
+	 *   not bound to the view, since the view may be shared across multiple perspectives
+	 */
+	public ViewPane(IViewReference ref, WorkbenchPage page, String theme) {
+		this(ref, page);
+		this.theme = theme;
+	}
+
+	/**
 	 * Create control. Add the title bar.
 	 */
 	public void createControl(Composite parent) {
@@ -366,7 +399,7 @@
 		// See also similar restrictions in addMoveItems method
 		// No need to worry about fast views as they do not
 		// register for D&D operations
-		return !isZoomed();
+		return isMoveable() && !overImage(p.x) && !isZoomed();
 	}
 
 	/**
@@ -382,6 +415,18 @@
 		floatingWindow = new ToolbarFloatingWindow(getWorkbenchWindow().getShell(), this.getControl(), AssociatedWindow.TRACK_OUTER_TOP_RHS);
 		return floatingWindow;
 	}
+	
+		/*
+	 * Return true if <code>x</code> is over the label image.
+	 */
+	private boolean overImage(int x) {
+		if (titleLabel.getImage() == null) {
+			return false;
+		} else {
+			return x < titleLabel.getImage().getBounds().width;
+		}
+	}
+	
 	/**
 	 * Create a title bar for the pane.
 	 * 	- the view icon and title to the far left
@@ -390,10 +435,35 @@
 	 */
 	protected void createTitleBar() {
 		// Only do this once.
-		if (viewToolBar != null)
+		if (titleLabel != null)
 			return;
 
+		// Title.   
+		titleLabel = new CLabel(control, SWT.SHADOW_NONE);
+		if (getTitleFont() != null)
+			titleLabel.setFont(getTitleFont());
+		titleLabel.setAlignment(SWT.LEFT);
+		titleLabel.setBackground(getNormalGradient(), getNormalGradientPercents(), isGradientVertical());
+		titleLabel.setForeground(getNormalForeground());
+		titleLabel.addMouseListener(new MouseAdapter() {
+			public void mouseDown(MouseEvent e) {
+				if ((e.button == 1) && overImage(e.x))
+					showPaneMenu();
+			}
+			public void mouseDoubleClick(MouseEvent event) {
+				doZoom();
+			}
+		});
+		// Listen for popup menu mouse event
+		titleLabel.addListener(SWT.MenuDetect, new Listener() {
+			public void handleEvent(Event event) {
+				if (event.type == SWT.MenuDetect) {
+					showPaneMenu(titleLabel, new Point(event.x, event.y));
+				}
+			}
+		});
 		updateTitles();
+		control.setTopLeft(titleLabel);
 
 		// Listen to title changes.
 		getPartReference().addPropertyListener(this);
@@ -479,6 +549,8 @@
 		 * containing the titleLabel will also disappear (disposing of the 
 		 * titleLabel).  As a result, the reference to titleLabel should be dropped. 
 		 */
+		titleLabel = null;
+
 		if (isvMenuMgr != null)
 			isvMenuMgr.dispose();
 		if (isvToolBarMgr != null)
@@ -519,7 +591,7 @@
 	 * Returns the drag control.
 	 */
 	public Control getDragHandle() {
-		return viewToolBar;
+		return titleLabel;
 	}
 	/**
 	 * @see ViewActionBars
@@ -683,6 +755,11 @@
 	 * Shows the pane menu (system menu) for this pane.
 	 */
 	public void showPaneMenu() {
+		// If this is a fast view, it may have been minimized. Do nothing in this case.
+		if (isFastView() && (page.getActiveFastView() != getViewReference()))
+			return;
+		Rectangle bounds = titleLabel.getBounds();
+		showPaneMenu(titleLabel, titleLabel.toDisplay(new Point(0, bounds.height)));
 	}
 	/**
 	 * Return true if this view is a fast view.
@@ -691,6 +768,18 @@
 		return page.isFastView(getViewReference());
 	}
 	/**
+	 * Return true if this view can be closed or is fixed.
+	 */
+	boolean isCloseable() {
+		return !page.isFixedView(getViewReference());
+	}
+	/**
+	 * Return true if the view may be moved.
+	 */
+	boolean isMoveable() {
+		return !page.isFixedLayout();
+	}
+	/**
 	 * Finds and return the sashes around this part.
 	 */
 	protected Sashes findSashes() {
@@ -713,6 +802,7 @@
 	 * Add the Fast View menu item to the view title menu.
 	 */
 	protected void addFastViewMenuItem(Menu parent, boolean isFastView) {
+		if (isMoveable() && isCloseable()) {
 		// add fast view item
 		MenuItem item = new MenuItem(parent, SWT.CHECK);
 		item.setText(WorkbenchMessages.getString("ViewPane.fastView")); //$NON-NLS-1$
@@ -737,6 +827,7 @@
 			item.setEnabled(true);
 		}
 	}
+	}
 	/**
 	 * Add the View and Tab Group items to the Move menu.
 	 */
@@ -826,6 +917,234 @@
 	 * Update the title attributes.
 	 */
 	public void updateTitles() {
+		IViewReference ref = getViewReference();
+		if (titleLabel != null && !titleLabel.isDisposed()) {
+			boolean changed = false;
+
+			// only update if text or image has changed 
+			String text = ref.getTitle();
+			if (text == null)
+				text = ""; //$NON-NLS-1$
+			if (!text.equals(titleLabel.getText())) {
+				titleLabel.setText(text);
+				changed = true;
+			}
+			Image image = ref.getTitleImage();
+			if (image != titleLabel.getImage()) {
+				titleLabel.setImage(image);
+				changed = true;
+			}
+			// only relayout if text or image has changed
+			if (changed) {
+				((Composite) getControl()).layout();
+			}
+
+			String tooltip = ref.getTitleToolTip();
+			if (!(tooltip == null
+				? titleLabel.getToolTipText() == null
+				: tooltip.equals(titleLabel.getToolTipText()))) {
+				titleLabel.setToolTipText(ref.getTitleToolTip());
+				changed = true;
+			}
+
+			if (changed) {
+				// XXX: Workaround for 1GCGA89: SWT:ALL - CLabel tool tip does not always update properly
+				titleLabel.update();
+
+				// notify the page that this view's title has changed
+				// in case it needs to update its fast view button
+				page.updateTitle(ref);
+			}
+		}
+	}
+
+	private Color[] getNormalGradient() {
+		if (theme != null) {
+			return WorkbenchThemeManager.getInstance().getViewGradientColors(
+				theme,
+				IThemeDescriptor.VIEW_TITLE_GRADIENT_COLOR_NORMAL);
+		}
+		return null;
+	}
+
+	private int[] getNormalGradientPercents() {
+		if (theme != null) {
+			return WorkbenchThemeManager.getInstance().getViewGradientPercents(
+				theme,
+				IThemeDescriptor.VIEW_TITLE_GRADIENT_PERCENTS_NORMAL);
+		}
+		return null;
+	}
+
+	private Color getNormalForeground() {
+		if (theme != null) {
+			return WorkbenchThemeManager.getInstance().getViewColor(
+				theme,
+				IThemeDescriptor.VIEW_TITLE_TEXT_COLOR_NORMAL);
+		}
+		return null;
+	}
+
+	private Color[] getActiveGradient() {
+		if (theme != null) {
+			return WorkbenchThemeManager.getInstance().getViewGradientColors(
+				theme,
+				IThemeDescriptor.VIEW_TITLE_GRADIENT_COLOR_ACTIVE);
+		}
+		return WorkbenchColors.getActiveViewGradient();
+	}
+
+	private int[] getActiveGradientPercents() {
+		if (theme != null)
+			return WorkbenchThemeManager.getInstance().getViewGradientPercents(
+				theme,
+				IThemeDescriptor.VIEW_TITLE_GRADIENT_PERCENTS_ACTIVE);
+		else
+			return WorkbenchColors.getActiveViewGradientPercents();
+	}
+
+	private Color getActiveForeground() {
+		if (theme != null) {
+			return WorkbenchThemeManager.getInstance().getViewColor(
+				theme,
+				IThemeDescriptor.VIEW_TITLE_TEXT_COLOR_ACTIVE);
+		}
+		return WorkbenchColors.getSystemColor(SWT.COLOR_TITLE_FOREGROUND);
+	}
+
+	private Color[] getDeactivatedGradient() {
+		if (theme != null) {
+			return WorkbenchThemeManager.getInstance().getViewGradientColors(
+				theme,
+				IThemeDescriptor.VIEW_TITLE_GRADIENT_COLOR_DEACTIVATED);
+		}
+		return WorkbenchColors.getDeactivatedViewGradient();
+	}
+
+	private int[] getDeactivatedGradientPercents() {
+		if (theme != null) {
+			return WorkbenchThemeManager.getInstance().getViewGradientPercents(
+				theme,
+				IThemeDescriptor.VIEW_TITLE_GRADIENT_PERCENTS_DEACTIVATED);
+		}
+		return WorkbenchColors.getDeactivatedViewGradientPercents();
+	}
+
+	private Color getDeactivatedForeground() {
+		if (theme != null) {
+			return WorkbenchThemeManager.getInstance().getViewColor(
+				theme,
+				IThemeDescriptor.VIEW_TITLE_TEXT_COLOR_DEACTIVATED);
+		}
+		return WorkbenchColors.getSystemColor(SWT.COLOR_TITLE_INACTIVE_FOREGROUND);
+	}
+
+	private int getGradientDirection() {
+		if (theme != null) {
+			return WorkbenchThemeManager.getInstance().getViewGradientDirection(
+				theme,
+				IThemeDescriptor.VIEW_TITLE_GRADIENT_DIRECTION);
+		}
+		return SWT.HORIZONTAL;
+	}
+
+	private boolean isGradientVertical() {
+	    return getGradientDirection() == SWT.VERTICAL;
+	}
+	
+	private Font getTitleFont() {
+		if (theme != null) {
+			return WorkbenchThemeManager.getInstance().getViewFont(
+				theme,
+				IThemeDescriptor.VIEW_TITLE_FONT);
+		}
+		return null;
+	}
+
+	/**
+	 * Answer the SWT widget style.
+	 */
+	int getStyle() {
+		if (theme == null) {
+			return super.getStyle();
+		}
+		// @issue even if there is a style, it may still be a function of whether the
+		//   container allows a border
+		return WorkbenchThemeManager.getInstance().getViewBorderStyle(
+			theme,
+			IThemeDescriptor.VIEW_BORDER_STYLE);
+	}
+
+	/**
+	 * Sets the theme.
+	 * 
+	 * @param theme the theme id
+	 */
+	void setTheme(String theme) {
+		this.theme = theme;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ui.internal.PartPane#setImage(org.eclipse.swt.widgets.TabItem, org.eclipse.swt.graphics.Image)
+	 */
+	void setImage(CTabItem item, Image image) {
+		titleLabel.setImage(image);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ui.internal.PartPane#addCloseMenuItem(org.eclipse.swt.widgets.Menu)
+	 */
+	protected void addCloseMenuItem(Menu menu) {
+		if(isCloseable())
+			super.addCloseMenuItem(menu);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ui.internal.PartPane#addMaximizeMenuItem(org.eclipse.swt.widgets.Menu)
+	 */
+	protected void addMaximizeMenuItem(Menu menu) {
+		if(isMoveable())
+			super.addMaximizeMenuItem(menu);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ui.internal.PartPane#addMoveMenuItem(org.eclipse.swt.widgets.Menu)
+	 */
+	protected void addMoveMenuItem(Menu menu) {
+		if(isMoveable())
+			super.addMoveMenuItem(menu);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ui.internal.PartPane#addPinEditorItem(org.eclipse.swt.widgets.Menu)
+	 */
+	protected void addPinEditorItem(Menu parent) {
+		if(isMoveable() && isCloseable())
+			super.addPinEditorItem(parent);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ui.internal.PartPane#addRestoreMenuItem(org.eclipse.swt.widgets.Menu)
+	 */
+	protected void addRestoreMenuItem(Menu menu) {
+		if(isMoveable())
+			super.addRestoreMenuItem(menu);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ui.internal.PartPane#addSizeMenuItem(org.eclipse.swt.widgets.Menu)
+	 */
+	protected void addSizeMenuItem(Menu menu) {
+		if(isMoveable())
+			super.addSizeMenuItem(menu);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ui.internal.PartPane#doZoom()
+	 */
+	protected void doZoom() {
+		if (isMoveable())
+			super.doZoom();
 	}
 
 	/* (non-Javadoc)
diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/ViewSite.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/ViewSite.java
index 24556e5..3178cf2 100644
--- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/ViewSite.java
+++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/ViewSite.java
@@ -11,6 +11,7 @@
 package org.eclipse.ui.internal;
 
 import org.eclipse.ui.IViewPart;
+import org.eclipse.ui.IViewReference;
 import org.eclipse.ui.IViewSite;
 import org.eclipse.ui.internal.registry.IViewDescriptor;
 
@@ -23,11 +24,17 @@
 /**
  * Creates a new ViewSite.
  */
-public ViewSite(IViewPart view, WorkbenchPage page, IViewDescriptor desc) {
-	super(view, page);
+public ViewSite(IViewReference ref, IViewPart view, WorkbenchPage page, IViewDescriptor desc) {
+	super(ref, view, page);
 	setConfigurationElement(desc.getConfigurationElement());
 }
 /**
+ * Returns the secondary id or <code>null</code>.
+ */
+public String getSecondaryId() {
+    return ((IViewReference) getPartReference()).getSecondaryId();
+}
+/**
  * Returns the view.
  */
 public IViewPart getViewPart() {
diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/WorkbenchPage.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/WorkbenchPage.java
index 99729b9..0cb1ec0 100644
--- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/WorkbenchPage.java
+++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/WorkbenchPage.java
@@ -15,7 +15,6 @@
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Comparator;
-//for dynamic UI - add import HashMap
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Iterator;
@@ -88,7 +87,7 @@
 /**
  * A collection of views and editors in a workbench.
  */
-public class WorkbenchPage extends CompatibleWorkbenchPage  implements IWorkbenchPage {
+public class WorkbenchPage extends CompatibleWorkbenchPage implements IWorkbenchPage {
 	private WorkbenchWindow window;
 	private IAdaptable input;
 	private IWorkingSet workingSet;
@@ -494,6 +493,7 @@
 		}
 
 		// Notify listeners.
+		window.getFastViewBar().update(true);
 		window.firePerspectiveChanged(
 			this,
 			getPerspective(),
@@ -686,38 +686,46 @@
 		}
 	}
 	/**
-	 * Opens a view.
+	 * Shows a view.
 	 * 
 	 * Assumes that a busy cursor is active.
 	 */
-	private IViewPart busyShowView(String viewID, boolean activate)
+	private IViewPart busyShowView(
+			String viewID, 
+			String secondaryID, 
+			int mode)
 		throws PartInitException {
 		Perspective persp = getActivePerspective();
 		if (persp == null)
 			return null;
 
 		// If this view is already visible just return.
-		IViewReference ref = persp.findView(viewID);
+		IViewReference ref = persp.findView(viewID, secondaryID);
 		IViewPart view = null;
 		if (ref != null)
 			view = ref.getView(true);
 		if (view != null) {
-			if (activate)
+			if (mode == VIEW_ACTIVATE)			
 				activate(view);
+			else if (mode == VIEW_VISIBLE)
+				bringToTop(view);
 			return view;
 		}
 
 		// Show the view.
-		view = persp.showView(viewID);
+		view = persp.showView(viewID, secondaryID);
 		if (view != null) {
 			zoomOutIfNecessary(view);
-			if (activate)
+			if (mode == VIEW_ACTIVATE)			
 				activate(view);
+			else if (mode == VIEW_VISIBLE)
+				bringToTop(view);
 			window.firePerspectiveChanged(
 				this,
 				getPerspective(),
 				CHANGE_VIEW_SHOW);
-			
+			// Just in case view was fast.
+			window.getFastViewBar().update(true);
 		}
 		return view;
 	}
@@ -1234,14 +1242,22 @@
 	}
 	
 	/* (non-Javadoc)
-	 * @see org.eclipse.ui.IWorkbenchPage#findViewReference(java.lang.String)
+	 * @see org.eclipse.ui.IWorkbenchPage
 	 */
 	public IViewReference findViewReference(String viewId) {
+	    return findViewReference(viewId, null);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ui.IWorkbenchPage
+	 */
+	public IViewReference findViewReference(String viewId, String secondaryId) {
 		Perspective persp = getActivePerspective();
 		if (persp == null)
 			return null;
-		return persp.findView(viewId);
+		return persp.findView(viewId, secondaryId);
 	}
+
 	/**
 	 * Fire part activation out.
 	 */
@@ -1674,7 +1690,7 @@
 			hideView((IViewPart) part);
 		} else {
 			hideView(getActivePerspective(), ref);
-		}
+		}		
 	}
 	/**
 	 * See IPerspective
@@ -1730,6 +1746,9 @@
 		// Notify interested listeners
 		window.firePerspectiveChanged(this, getPerspective(), CHANGE_VIEW_HIDE);
 
+		// Just in case view was fast.
+		window.getFastViewBar().update(true);
+
 		//if it was the last part, close the perspective
 		lastPartClosePerspective();
 	}
@@ -1812,6 +1831,27 @@
 			return false;
 	}
 	/**
+	 * Returns whether the view is fixed.
+	 */
+	public boolean isFixedView(IViewReference ref) {
+		Perspective persp = getActivePerspective();
+		if (persp != null)
+			return persp.isFixedView(ref);
+		else
+			return false;
+	}
+	/**
+	 * Returns whether the layout of the active
+	 * perspective is fixed.
+	 */
+	public boolean isFixedLayout() {
+		Perspective persp = getActivePerspective();
+		if (persp != null)
+			return persp.isFixedLayout();
+		else
+			return false;
+	}
+	/**
 	 * Return the active fast view or null if there are no fast views or if
 	 * there are all minimized.
 	 */
@@ -2134,6 +2174,7 @@
 		persp.removeFastView(ref);
 
 		// Notify listeners.
+		window.getFastViewBar().update(true);
 		window.firePerspectiveChanged(
 			this,
 			getPerspective(),
@@ -2778,21 +2819,24 @@
 	/**
 	 * See IWorkbenchPage.
 	 */
-	public IViewPart showView(final String viewID) throws PartInitException {
-		return showView(viewID, true);
+	public IViewPart showView(String viewID) throws PartInitException {
+		return showView(viewID, null, VIEW_ACTIVATE);
 	}
-
-	/**
-	 * See IWorkbenchPage.
-	 */
-	private IViewPart showView(final String viewID, final boolean activate)
-		throws PartInitException {
+	
+	public IViewPart showView(
+			final String viewID, 
+			final String secondaryID, 
+			final int mode) throws PartInitException {
+		
+		if (!certifyMode(mode)) 
+			throw new IllegalArgumentException(WorkbenchMessages.getString("WorkbenchPage.IllegalViewMode")); //$NON-NLS-1$
+		
 		// Run op in busy cursor.
 		final Object[] result = new Object[1];
 		BusyIndicator.showWhile(null, new Runnable() {
 			public void run() {
 				try {
-					result[0] = busyShowView(viewID, activate);
+					result[0] = busyShowView(viewID, secondaryID, mode);
 				} catch (PartInitException e) {
 					result[0] = e;
 				}
@@ -2806,6 +2850,21 @@
 			throw new PartInitException(WorkbenchMessages.getString("WorkbenchPage.AbnormalWorkbenchCondition")); //$NON-NLS-1$
 	}
 	/**
+	 * @param mode the mode to test
+	 * @return whether the mode is recognized
+	 * @since 3.0
+	 */
+	private boolean certifyMode(int mode) {
+		switch(mode) {
+			case VIEW_ACTIVATE:
+			case VIEW_VISIBLE:
+			case VIEW_CREATE:
+				return true;
+			default:
+				return false;
+		}
+	}
+	/**
 	 * Toggles the visibility of a fast view. If the view is active it is
 	 * deactivated. Otherwise, it is activated.
 	 */
@@ -3340,6 +3399,6 @@
 	 * @see org.eclipse.ui.IWorkbenchPage#createView(java.lang.String)
 	 */
 	public IViewPart createView(String viewId) throws PartInitException {		
-		return showView(viewId, false);		
+		return showView(viewId);		
 	}	
 }
diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/WorkbenchPartReference.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/WorkbenchPartReference.java
index aa4a73a..a052fd6 100644
--- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/WorkbenchPartReference.java
+++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/WorkbenchPartReference.java
@@ -9,12 +9,14 @@
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
 package org.eclipse.ui.internal;
+import org.eclipse.swt.graphics.Image;
+
 import org.eclipse.jface.resource.ImageDescriptor;
 import org.eclipse.jface.util.ListenerList;
-import org.eclipse.swt.graphics.Image;
-import org.eclipse.ui.*;
+
 import org.eclipse.ui.IPropertyListener;
 import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.IWorkbenchPartReference;
 
 /**
  * 
@@ -28,7 +30,7 @@
 	private String title;
 	private String tooltip;
 	private Image image;
-	private ImageDescriptor imageDescritor;
+	private ImageDescriptor imageDescriptor;
 	private ListenerList propChangeListeners = new ListenerList(2);		
 	
 	public WorkbenchPartReference() {
@@ -37,23 +39,23 @@
 		this.id = id;
 		this.title = title;
 		this.tooltip = tooltip;
-		this.imageDescritor = desc;
+		this.imageDescriptor = desc;
 	}
 	public void releaseReferences() {
 		id = null;
 		tooltip = null;
 		title = null;
-		if(image != null && imageDescritor != null) {
+		if(image != null && imageDescriptor != null) {
 			//make sure part has inc. the reference count.
 			if(part != null)
 				part.getTitleImage();
 			ReferenceCounter imageCache = WorkbenchImages.getImageCache();
-			image = (Image)imageCache.get(imageDescritor);
+			image = (Image)imageCache.get(imageDescriptor);
 			if(image != null) {
-				imageCache.removeRef(imageDescritor);
+				imageCache.removeRef(imageDescriptor);
 			}
 			image = null;
-			imageDescritor = null;
+			imageDescriptor = null;
 		}
 	}
 	/**
@@ -101,16 +103,16 @@
 			return part.getTitleImage();
 		if(image != null)
 			return image;
-		if(imageDescritor == null)
+		if(imageDescriptor == null)
 			return null;
 		ReferenceCounter imageCache = WorkbenchImages.getImageCache();
-		image = (Image)imageCache.get(imageDescritor);
+		image = (Image)imageCache.get(imageDescriptor);
 		if(image != null) {
-			imageCache.addRef(imageDescritor);
+			imageCache.addRef(imageDescriptor);
 			return image;
 		}
-		image = imageDescritor.createImage();
-		imageCache.put(imageDescritor,image);
+		image = imageDescriptor.createImage();
+		imageCache.put(imageDescriptor,image);
 		return image;		
 	}	
 	public void setPart(IWorkbenchPart part) {
@@ -146,14 +148,14 @@
 		return result;
 	}	
 	public void dispose() {
-		if(image != null && imageDescritor != null) {
+		if(image != null && imageDescriptor != null) {
 			ReferenceCounter imageCache = WorkbenchImages.getImageCache();
 			if(image != null) {
-				int count = imageCache.removeRef(imageDescritor);
+				int count = imageCache.removeRef(imageDescriptor);
 				if(count <= 0)
 					image.dispose();				
 			}
-			imageDescritor = null;
+			imageDescriptor = null;
 			image = null;
 		}
 		if(part != null)
diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/WorkbenchPlugin.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/WorkbenchPlugin.java
index 2048c5a..bbefd9b 100644
--- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/WorkbenchPlugin.java
+++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/WorkbenchPlugin.java
@@ -28,6 +28,12 @@
 import org.eclipse.core.runtime.IStatus;
 import org.eclipse.core.runtime.Platform;
 import org.eclipse.core.runtime.Status;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.BusyIndicator;
+import org.eclipse.swt.graphics.FontData;
+import org.eclipse.swt.graphics.RGB;
+
 import org.eclipse.jface.preference.IPreferenceNode;
 import org.eclipse.jface.preference.IPreferenceStore;
 import org.eclipse.jface.preference.JFacePreferences;
@@ -38,10 +44,7 @@
 import org.eclipse.jface.resource.ImageRegistry;
 import org.eclipse.jface.resource.JFaceResources;
 import org.eclipse.jface.util.OpenStrategy;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.custom.BusyIndicator;
-import org.eclipse.swt.graphics.FontData;
-import org.eclipse.swt.graphics.RGB;
+
 import org.eclipse.ui.IEditorRegistry;
 import org.eclipse.ui.IElementFactory;
 import org.eclipse.ui.IPerspectiveRegistry;
@@ -50,6 +53,8 @@
 import org.eclipse.ui.IWorkingSetManager;
 import org.eclipse.ui.PlatformUI;
 import org.eclipse.ui.application.IWorkbenchPreferences;
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+
 import org.eclipse.ui.internal.decorators.DecoratorManager;
 import org.eclipse.ui.internal.intro.IIntroRegistry;
 import org.eclipse.ui.internal.intro.IntroRegistry;
@@ -63,7 +68,9 @@
 import org.eclipse.ui.internal.registry.ViewRegistry;
 import org.eclipse.ui.internal.registry.ViewRegistryReader;
 import org.eclipse.ui.internal.registry.WorkingSetRegistry;
-import org.eclipse.ui.plugin.AbstractUIPlugin;
+import org.eclipse.ui.internal.themes.IThemeRegistry;
+import org.eclipse.ui.internal.themes.ThemeRegistry;
+import org.eclipse.ui.internal.themes.ThemeRegistryReader;
 
 /**
  * This class represents the TOP of the workbench UI world
@@ -91,6 +98,8 @@
 	private EditorRegistry editorRegistry;
 	// Manager for the DecoratorManager
 	private DecoratorManager decoratorManager;
+	// Theme registry
+	private ThemeRegistry themeRegistry;
 	// Manager for working sets (IWorkingSet)
 	private WorkingSetManager workingSetManager;
 	// Working set registry, stores working set dialogs
@@ -147,29 +156,29 @@
 	 */
 	public static Object createExtension(final IConfigurationElement element, final String classAttribute) throws CoreException {
 		try {
-		// If plugin has been loaded create extension.
-		// Otherwise, show busy cursor then create extension.
-		IPluginDescriptor plugin = element.getDeclaringExtension().getDeclaringPluginDescriptor();
-		if (plugin.isPluginActivated()) {
-			return element.createExecutableExtension(classAttribute);
-		} else {
-			final Object[] ret = new Object[1];
-			final CoreException[] exc = new CoreException[1];
-			BusyIndicator.showWhile(null, new Runnable() {
-				public void run() {
-					try {
-						ret[0] = element.createExecutableExtension(classAttribute);
-					} catch (CoreException e) {
-						exc[0] = e;
+			// If plugin has been loaded create extension.
+			// Otherwise, show busy cursor then create extension.
+			IPluginDescriptor plugin = element.getDeclaringExtension().getDeclaringPluginDescriptor();
+			if (plugin.isPluginActivated()) {
+				return element.createExecutableExtension(classAttribute);
+			} else {
+				final Object[] ret = new Object[1];
+				final CoreException[] exc = new CoreException[1];
+				BusyIndicator.showWhile(null, new Runnable() {
+					public void run() {
+						try {
+							ret[0] = element.createExecutableExtension(classAttribute);
+						} catch (CoreException e) {
+							exc[0] = e;
+						}
 					}
-				}
-			});
-			if (exc[0] != null)
-				throw exc[0];
-			else
-				return ret[0];
+				});
+				if (exc[0] != null)
+					throw exc[0];
+				else
+					return ret[0];
+			}
 		}
-	}
 		catch (CoreException core) {
 			throw core;			
 		}
@@ -351,6 +360,26 @@
 			sharedImages = new SharedImages();
 		return sharedImages;
 	}
+
+	/**
+	 * Returns the theme registry for the workbench.
+	 * 
+	 * @return the theme registry
+	 */
+	public IThemeRegistry getThemeRegistry() {
+		if (themeRegistry == null) {
+			try {
+				themeRegistry = new ThemeRegistry();
+				ThemeRegistryReader reader = new ThemeRegistryReader();
+				reader.readThemes(Platform.getPluginRegistry(), themeRegistry);
+			} catch (CoreException e) {
+				// cannot safely show a dialog so log it
+				WorkbenchPlugin.log("Unable to read theme registry.", e.getStatus()); //$NON-NLS-1$
+			}
+		}
+		return themeRegistry;
+	}
+	
 	/**
 	 * Answer the view registry.
 	 */
@@ -386,15 +415,12 @@
 		// new generic workbench preferences
 		store.setDefault(IWorkbenchPreferences.SHOULD_SAVE_WORKBENCH_STATE, false);
 		store.setDefault(IWorkbenchPreferences.SHOULD_CLOSE_EDITORS_ON_EXIT, false);
-		
-		store.setDefault(IWorkbenchPreferences.SHOW_MULTIPLE_EDITOR_TABS, false);
-		store.setDefault(IWorkbenchPreferences.SHOW_TEXT_ON_PERSPECTIVE_BAR, true);
-		
 		store.setDefault(IWorkbenchPreferences.SHOULD_SHOW_TITLE_BAR, true);
 		store.setDefault(IWorkbenchPreferences.SHOULD_SHOW_MENU_BAR, true);
 		store.setDefault(IWorkbenchPreferences.SHOULD_SHOW_TOOL_BAR, true);
-		store.setDefault(IWorkbenchPreferences.SHOULD_SHOW_SHORTCUT_BAR, true);
+		store.setDefault(IWorkbenchPreferences.SHOULD_SHOW_SHORTCUT_BAR, false);
 		store.setDefault(IWorkbenchPreferences.SHOULD_SHOW_STATUS_LINE, true);
+		store.setDefault(IWorkbenchPreferences.SHOULD_SHOW_PROGRESS_INDICATOR, false);
 			
 		// @issue some of these may be IDE-specific
 		store.setDefault(IPreferenceConstants.EDITORLIST_PULLDOWN_ACTIVE, false);
@@ -407,7 +433,7 @@
 		store.setDefault(IPreferenceConstants.SELECT_ON_HOVER, false);
 		store.setDefault(IPreferenceConstants.OPEN_AFTER_DELAY, false);
 		store.setDefault(IPreferenceConstants.RECENT_FILES, 4);
-		store.setDefault(IPreferenceConstants.VIEW_TAB_POSITION, SWT.TOP);
+		store.setDefault(IPreferenceConstants.VIEW_TAB_POSITION, SWT.BOTTOM);
 		store.setDefault(IPreferenceConstants.EDITOR_TAB_POSITION, SWT.TOP);
 		store.setDefault(IPreferenceConstants.EDITOR_TAB_WIDTH, 3); // high
 		store.setDefault(IPreferenceConstants.OPEN_VIEW_MODE, IPreferenceConstants.OVM_EMBED);
@@ -421,8 +447,8 @@
 		store.setDefault(IPreferenceConstants.SHOW_TOOL_BAR, true);
 		store.setDefault(IPreferenceConstants.MULTI_KEY_ASSIST, false);
 		store.setDefault(IPreferenceConstants.MULTI_KEY_ASSIST_TIME, 1000);
+		store.setDefault(IPreferenceConstants.SHOW_FLOATING_PROGRESS,true);
 		
-		store.setDefault(JFacePreferences.USE_DEFAULT_THEME, true);
 		// @issue get rid of PreferenceConverter - just hard code the RGB string		
 		//Set the default error colour to red
 		PreferenceConverter.setDefault(store,JFacePreferences.ERROR_COLOR, new RGB(255, 0, 0));
@@ -431,21 +457,7 @@
 		//Set the default active hyperlink line colour to blue
 		PreferenceConverter.setDefault(store,JFacePreferences.ACTIVE_HYPERLINK_COLOR, new RGB(0, 0, 255));
 		
-		//Set the default inactive tab background, if this value is the default then it is queried
-		// from JFaceColors
-		PreferenceConverter.setDefault(store, JFacePreferences.SCHEME_TAB_SELECTION_BACKGROUND, PreferenceConverter.COLOR_DEFAULT_DEFAULT);
-		//Set the default inactive tab foreground, if this value is the default then it is queried
-		// from JFaceColors
-		PreferenceConverter.setDefault(store, JFacePreferences.SCHEME_TAB_SELECTION_FOREGROUND, PreferenceConverter.COLOR_DEFAULT_DEFAULT);
-		//Set the default tab background, if this value is the default then it is queried
-		//from JFaceColors
-		PreferenceConverter.setDefault(store, JFacePreferences.SCHEME_TAB_BACKGROUND, PreferenceConverter.COLOR_DEFAULT_DEFAULT);
-		//Set the default tab foreground, if this value is the default then it is queried
-		// from JFaceColors
-		PreferenceConverter.setDefault(store, JFacePreferences.SCHEME_TAB_FOREGROUND, PreferenceConverter.COLOR_DEFAULT_DEFAULT);
 		
-		
-
 		// Temporary option to enable wizard for project capability
 		store.setDefault("ENABLE_CONFIGURABLE_PROJECT_WIZARD", false); //$NON-NLS-1$
 		// Temporary option to enable single click
@@ -456,7 +468,6 @@
 		store.setDefault("ENABLE_NEW_MENUS", true); //$NON-NLS-1$	
 		//Temporary option to turn off the dialog font
 		store.setDefault("DISABLE_DIALOG_FONT", false); //$NON-NLS-1$
-		store.setDefault(IWorkbenchConstants.SHOW_PROGRESS_INDICATOR, true); //$NON-NLS-1$	
 
 		// @issue get rid of PreferenceConverter - defer setting default fonts until Display created.
 		FontRegistry registry = JFaceResources.getFontRegistry();
@@ -465,7 +476,6 @@
 		initializeFont(JFaceResources.HEADER_FONT, registry, store);
 		initializeFont(JFaceResources.TEXT_FONT, registry, store);
 		
-		
 		store.addPropertyChangeListener(new PlatformUIPreferenceListener());
 	}
 
@@ -474,9 +484,6 @@
 		FontData[] fontData = registry.getFontData(fontKey);
 		PreferenceConverter.setDefault(store, fontKey, fontData);
 	}
-
-	
-	
 	/**
 	 * Log the given status to the ISV log.
 	 *
@@ -506,7 +513,7 @@
 	 */
 
 	public static void log(String message) {
-		getDefault().getLog().log(StatusUtil.newStatus(Status.ERROR, message, null));
+		getDefault().getLog().log(StatusUtil.newStatus(IStatus.ERROR, message, null));
 		System.err.println(message);
 		//1FTTJKV: ITPCORE:ALL - log(status) does not allow plugin information to be recorded
 	}
diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/WorkbenchWindow.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/WorkbenchWindow.java
index f15a6ed..ac9289f 100644
--- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/WorkbenchWindow.java
+++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/WorkbenchWindow.java
@@ -22,7 +22,21 @@
 import org.eclipse.core.runtime.IStatus;
 import org.eclipse.core.runtime.MultiStatus;
 import org.eclipse.core.runtime.Status;
-
+import org.eclipse.jface.action.ActionContributionItem;
+import org.eclipse.jface.action.CoolBarManager;
+import org.eclipse.jface.action.GroupMarker;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.action.IContributionItem;
+import org.eclipse.jface.action.IContributionManager;
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.action.MenuManager;
+import org.eclipse.jface.action.Separator;
+import org.eclipse.jface.action.StatusLineManager;
+import org.eclipse.jface.action.ToolBarContributionItem;
+import org.eclipse.jface.action.ToolBarManager;
+import org.eclipse.jface.operation.IRunnableWithProgress;
+import org.eclipse.jface.window.ApplicationWindow;
+import org.eclipse.jface.window.ColorSchemeService;
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.custom.BusyIndicator;
 import org.eclipse.swt.custom.CBanner;
@@ -47,22 +61,6 @@
 import org.eclipse.swt.widgets.Shell;
 import org.eclipse.swt.widgets.ToolBar;
 import org.eclipse.swt.widgets.ToolItem;
-
-import org.eclipse.jface.action.CoolBarManager;
-import org.eclipse.jface.action.GroupMarker;
-import org.eclipse.jface.action.IAction;
-import org.eclipse.jface.action.IContributionItem;
-import org.eclipse.jface.action.IContributionManager;
-import org.eclipse.jface.action.IMenuManager;
-import org.eclipse.jface.action.MenuManager;
-import org.eclipse.jface.action.Separator;
-import org.eclipse.jface.action.StatusLineManager;
-import org.eclipse.jface.action.ToolBarContributionItem;
-import org.eclipse.jface.action.ToolBarManager;
-import org.eclipse.jface.operation.IRunnableWithProgress;
-import org.eclipse.jface.window.ApplicationWindow;
-import org.eclipse.jface.window.ColorSchemeService;
-
 import org.eclipse.ui.IEditorPart;
 import org.eclipse.ui.IElementFactory;
 import org.eclipse.ui.IMemento;
@@ -88,7 +86,6 @@
 import org.eclipse.ui.commands.IWorkbenchWindowCommandSupport;
 import org.eclipse.ui.contexts.IWorkbenchWindowContextSupport;
 import org.eclipse.ui.help.WorkbenchHelp;
-
 import org.eclipse.ui.internal.commands.ActionHandler;
 import org.eclipse.ui.internal.commands.ws.WorkbenchWindowCommandSupport;
 import org.eclipse.ui.internal.contexts.ws.WorkbenchWindowContextSupport;
@@ -96,6 +93,7 @@
 import org.eclipse.ui.internal.misc.Assert;
 import org.eclipse.ui.internal.misc.UIStats;
 import org.eclipse.ui.internal.progress.AnimationItem;
+import org.eclipse.ui.internal.progress.AnimationManager;
 import org.eclipse.ui.internal.registry.ActionSetRegistry;
 import org.eclipse.ui.internal.registry.IActionSet;
 import org.eclipse.ui.internal.registry.IActionSetDescriptor;
@@ -109,6 +107,7 @@
 	private PageList pageList = new PageList();
 	private PageListenerList pageListeners = new PageListenerList();
 	private PerspectiveListenerListOld perspectiveListeners = new PerspectiveListenerListOld();
+	private IPartDropListener partDropListener;
 	private WWinPerspectiveService perspectiveService = new WWinPerspectiveService(this);
 	private WWinPartService partService = new WWinPartService(this);
 	private ActionPresentation actionPresentation;
@@ -122,6 +121,8 @@
 
 	private PerspectiveBarManager perspectiveBar;
 	private Menu perspectiveBarMenu;
+	private Menu fastViewBarMenu;
+	private MenuItem restoreItem;
 	
 	//private PerspectiveBarManager newBar;
 	
@@ -151,6 +152,11 @@
 	 */
 	private WorkbenchWindowConfigurer windowConfigurer = null;
 
+	// constants for shortcut bar group ids 
+	static final String GRP_PAGES = "pages"; //$NON-NLS-1$
+	static final String GRP_PERSPECTIVES = "perspectives"; //$NON-NLS-1$
+	static final String GRP_FAST_VIEWS = "fastViews"; //$NON-NLS-1$
+
 	// static fields for inner classes.
 	static final int VGAP = 0;
 	static final int CLIENT_INSET = 3;
@@ -221,7 +227,7 @@
 	 */
 	private static final int FILL_ALL_ACTION_BARS =
 		WorkbenchAdvisor.FILL_MENU_BAR
-			| WorkbenchAdvisor.FILL_TOOL_BAR
+			| WorkbenchAdvisor.FILL_COOL_BAR
 			| WorkbenchAdvisor.FILL_STATUS_LINE;
 
 	/**
@@ -253,6 +259,10 @@
 
 		// let the application do further configuration
 		getAdvisor().preWindowOpen(getWindowConfigurer());
+		
+		// set the shell style
+		setShellStyle(getWindowConfigurer().getShellStyle());
+		
 		// Fill the action bars	
 		getAdvisor().fillActionBars(
 			this,
@@ -1063,9 +1073,12 @@
 						} else {
 							newItem = new Separator();
 						}
-					} else if ((id != null) && (type.equals(IWorkbenchConstants.TAG_TYPE_GROUPMARKER))) {
+					} else if (id != null) {
+					    if (type.equals(IWorkbenchConstants.TAG_TYPE_GROUPMARKER)) {
 						newItem = new GroupMarker(id);
-					} else if ((id != null) && (type.equals(IWorkbenchConstants.TAG_TYPE_TOOLBARCONTRIBUTION))) {
+
+					    } else if (type.equals(IWorkbenchConstants.TAG_TYPE_TOOLBARCONTRIBUTION) 
+					            || type.equals(IWorkbenchConstants.TAG_TYPE_PLACEHOLDER)) {
 
 						// Get Width and height
 						Integer width = contributionMem.getInteger(IWorkbenchConstants.TAG_ITEM_X);
@@ -1073,13 +1086,23 @@
 						// Look for the object in the current cool bar manager
 						IContributionItem oldItem = coolBarMgr.find(id);
 						// If a tool bar contribution item already exists for this id then use the old object
-						if (oldItem instanceof ToolBarContributionItem) {
-							newItem = (ToolBarContributionItem) oldItem;
+					        if (oldItem != null) {
+					            newItem = oldItem;
 						} else {
 							newItem =
 								new ToolBarContributionItem(
 										new ToolBarManager(coolBarMgr.getStyle()),
 										id);
+					            if (type.equals(IWorkbenchConstants.TAG_TYPE_PLACEHOLDER)) {
+					                ToolBarContributionItem newToolBarItem = (ToolBarContributionItem) newItem;
+					                if (height != null) {
+					                    newToolBarItem.setCurrentHeight(height.intValue());
+					                }
+					                if (width != null) {
+					                    newToolBarItem.setCurrentWidth(width.intValue());
+					                }
+					                newItem = new PlaceholderContributionItem(newToolBarItem);
+					            }
 							// make it invisible by default
 							newItem.setVisible(false);
 							// Need to add the item to the cool bar manager so that its canonical order can be preserved
@@ -1095,13 +1118,14 @@
 							}
 						}
 						// Set the current height and width
-						if (width != null) {
+					        if ((width != null) && (newItem instanceof ToolBarContributionItem)) {
 							((ToolBarContributionItem) newItem).setCurrentWidth(width.intValue());
 						}
-						if (height != null) {
+					        if ((height != null) && (newItem instanceof ToolBarContributionItem)) {
 							((ToolBarContributionItem) newItem).setCurrentHeight(height.intValue());
 						}
 					}
+					}
 					// Add new item into cool bar manager
 					if (newItem != null) {
 						layout.add(newItem);
@@ -1510,19 +1534,40 @@
 							IWorkbenchConstants.TAG_ITEM_TYPE,
 							IWorkbenchConstants.TAG_TYPE_GROUPMARKER);
 				} else {
-					// Assume that it is a ToolBarContributionItem
+				    if (item instanceof PlaceholderContributionItem) {
 					coolItemMem.putString(
 							IWorkbenchConstants.TAG_ITEM_TYPE,
+				                IWorkbenchConstants.TAG_TYPE_PLACEHOLDER);
+				    } else {
+				        // Store the identifier.
+				        coolItemMem.putString(
+				                IWorkbenchConstants.TAG_ITEM_TYPE,
 							IWorkbenchConstants.TAG_TYPE_TOOLBARCONTRIBUTION);
-					ToolBarContributionItem tbItem = (ToolBarContributionItem) item;
-					tbItem.saveWidgetState();
-					coolItemMem.putInteger(
-							IWorkbenchConstants.TAG_ITEM_X,
-							tbItem.getCurrentWidth());
-					coolItemMem.putInteger(
-							IWorkbenchConstants.TAG_ITEM_Y,
-							tbItem.getCurrentHeight());
 				}
+					
+					/* Retrieve a reasonable approximation of the height and
+					 * width, if possible.
+					 */
+					final int height;
+					final int width;
+					if (item instanceof ToolBarContributionItem) {
+					    ToolBarContributionItem toolBarItem = (ToolBarContributionItem) item;
+					    toolBarItem.saveWidgetState();
+					    height = toolBarItem.getCurrentHeight();
+					    width = toolBarItem.getCurrentWidth();
+					} else if (item instanceof PlaceholderContributionItem) {
+					    PlaceholderContributionItem placeholder = (PlaceholderContributionItem) item;
+					    height = placeholder.getHeight();
+					    width = placeholder.getWidth();
+					} else {
+					    height = -1;
+					    width = -1;
+			}
+					
+					// Store the height and width.
+					coolItemMem.putInteger(IWorkbenchConstants.TAG_ITEM_X, width);
+					coolItemMem.putInteger(IWorkbenchConstants.TAG_ITEM_Y, height); 
+		}
 			}
 		}
 		
@@ -1636,7 +1681,50 @@
 		// Get the action for the tool item.
 		Object data = toolItem.getData();
 
-		if (!(data instanceof PerspectiveBarContributionItem))
+		// If the tool item is an icon for a fast view
+		if (data instanceof ShowFastViewContribution) {
+			// The fast view bar menu is created lazily here.
+			if (fastViewBarMenu == null) {
+				Menu menu = new Menu(toolBar);
+				MenuItem closeItem = new MenuItem(menu, SWT.NONE);
+				closeItem.setText(WorkbenchMessages.getString("WorkbenchWindow.close")); //$NON-NLS-1$
+				closeItem.addSelectionListener(new SelectionAdapter() {
+					public void widgetSelected(SelectionEvent e) {
+						ToolItem toolItem = (ToolItem) fastViewBarMenu.getData();
+						if (toolItem != null && !toolItem.isDisposed()) {
+							IViewReference ref =
+								(IViewReference) toolItem.getData(
+									ShowFastViewContribution.FAST_VIEW);
+							getActiveWorkbenchPage().hideView(ref);
+						}
+					}
+				});
+				restoreItem = new MenuItem(menu, SWT.CHECK);
+				restoreItem.setText(WorkbenchMessages.getString("WorkbenchWindow.restore")); //$NON-NLS-1$
+				restoreItem.addSelectionListener(new SelectionAdapter() {
+					public void widgetSelected(SelectionEvent e) {
+						ToolItem toolItem = (ToolItem) fastViewBarMenu.getData();
+						if (toolItem != null && !toolItem.isDisposed()) {
+							IViewReference ref =
+								(IViewReference) toolItem.getData(
+									ShowFastViewContribution.FAST_VIEW);
+							getActiveWorkbenchPage().removeFastView(ref);
+						}
+					}
+				});
+				fastViewBarMenu = menu;
+			}
+			restoreItem.setSelection(true);
+			fastViewBarMenu.setData(toolItem);
+
+			// Show popup menu.
+			if (fastViewBarMenu != null) {
+				fastViewBarMenu.setLocation(pt.x, pt.y);
+				fastViewBarMenu.setVisible(true);
+			}
+		}
+
+		if (!(data instanceof ActionContributionItem))
 			return;
 		
 			// The perspective bar menu is created lazily here.
@@ -1844,12 +1932,13 @@
 		return PlatformUI.getWorkbench().getPreferenceStore().getBoolean(
 			IWorkbenchConstants.SHOW_PROGRESS_INDICATOR);
 	}
+
 	/**
 	 * Create the progress indicator for the receiver.
 	 * @param shell	the parent shell
 	 */
 	private void createProgressIndicator(Shell shell) {
-		if (showProgressIndicator()) {
+		if (getWindowConfigurer().getShowProgressIndicator()) {
 			animationItem = new AnimationItem(this);
 			animationItem.createControl(shell);
 		}
@@ -2067,12 +2156,7 @@
 	 * Toggle the floating window in the receiver.
 	 */
 	public void toggleFloatingWindow(){
-		animationItem.toggleFloatingWindow();
-	}	/**
-	 * @return Returns the animationItem.
-	 */
-	public AnimationItem getAnimationItem() {
-		return animationItem;
+		AnimationManager.getInstance().toggleFloatingWindow();
 	}
 
 	/* package */ public int getFastViewBarSide() {
diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/WorkbenchWindowConfigurer.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/WorkbenchWindowConfigurer.java
index a19abce..af78311 100644
--- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/WorkbenchWindowConfigurer.java
+++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/WorkbenchWindowConfigurer.java
@@ -14,16 +14,19 @@
 import java.util.HashMap;
 import java.util.Map;
 
-import org.eclipse.jface.action.IAction;
-import org.eclipse.jface.action.IContributionItem;
-import org.eclipse.jface.action.IMenuManager;
-import org.eclipse.jface.action.IStatusLineManager;
-import org.eclipse.jface.action.ICoolBarManager;
-import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.swt.SWT;
 import org.eclipse.swt.dnd.DropTarget;
 import org.eclipse.swt.dnd.DropTargetListener;
 import org.eclipse.swt.dnd.Transfer;
 import org.eclipse.swt.widgets.Shell;
+
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.action.IContributionItem;
+import org.eclipse.jface.action.ICoolBarManager;
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.action.IStatusLineManager;
+import org.eclipse.jface.preference.IPreferenceStore;
+
 import org.eclipse.ui.IWorkbenchPage;
 import org.eclipse.ui.IWorkbenchWindow;
 import org.eclipse.ui.application.IActionBarConfigurer;
@@ -51,6 +54,11 @@
 	private WorkbenchWindow window;
 
 	/**
+	 * The shell style bits to use when the window's shell is being created.
+	 */
+	private int shellStyle = SWT.SHELL_TRIM;
+	
+	/**
 	 * The window title to set when the window's shell has been created,
 	 * or <code>null</code> if there is none to set.
 	 */
@@ -82,6 +90,11 @@
 	private boolean showTitleBar = true;
 
 	/**
+	 * Whether the workbench window should have a progress indicator.
+	 */
+	private boolean showProgressIndicator = true;
+	
+	/**
 	 * Table to hold arbitrary key-data settings (key type: <code>String</code>,
 	 * value type: <code>Object</code>).
 	 * @see #setData
@@ -183,6 +196,7 @@
 	/* package */ void init() {
 		IPreferenceStore store = WorkbenchPlugin.getDefault().getPreferenceStore();
 		showMenuBar = store.getBoolean(IWorkbenchPreferences.SHOULD_SHOW_MENU_BAR);
+		showProgressIndicator = store.getBoolean(IWorkbenchPreferences.SHOULD_SHOW_PROGRESS_INDICATOR);
 		showShortcutBar = store.getBoolean(IWorkbenchPreferences.SHOULD_SHOW_SHORTCUT_BAR);
 		showStatusLine = store.getBoolean(IWorkbenchPreferences.SHOULD_SHOW_STATUS_LINE);
 		showTitleBar = store.getBoolean(IWorkbenchPreferences.SHOULD_SHOW_TITLE_BAR);
@@ -267,7 +281,19 @@
 	 */
 	public void setShowMenuBar(boolean show) {
 		showMenuBar = show;
-		// @issue need to be able to reconfigure after window's controls created
+		WorkbenchWindow win = (WorkbenchWindow) getWindow();
+		Shell shell = win.getShell();
+		if (shell != null) {
+			boolean showing = shell.getMenuBar() != null;
+			if (show != showing) {
+				if (show) {
+					shell.setMenuBar(win.getMenuBarManager().getMenu());
+				}
+				else {
+					shell.setMenuBar(null);
+				}
+			}
+		}
 	}
 
 	/* (non-javadoc)
@@ -315,6 +341,23 @@
 		// @issue need to be able to reconfigure after window's controls created
 	}
 	
+	
+    /* (non-Javadoc)
+     * @see org.eclipse.ui.application.IWorkbenchWindowConfigurer
+     */
+    public boolean getShowProgressIndicator() {
+        return showProgressIndicator;
+    }
+    
+    
+    /* (non-Javadoc)
+     * @see org.eclipse.ui.application.IWorkbenchWindowConfigurer
+     */
+    public void setShowProgressIndicator(boolean show) {
+        showProgressIndicator = show;
+		// @issue need to be able to reconfigure after window's controls created
+    }
+    
 	/* (non-javadoc)
 	 * @see org.eclipse.ui.application.IWorkbenchWindowConfigurer#getData
 	 */
@@ -414,4 +457,20 @@
 		getActionBarConfigurer();
 		return actionBarConfigurer.containsCoolItem(id);
 	}
+	
+	
+    /* (non-Javadoc)
+     * @see org.eclipse.ui.application.IWorkbenchWindowConfigurer
+     */
+    public int getShellStyle() {
+        return shellStyle;
+    }
+    
+    
+    /* (non-Javadoc)
+     * @see org.eclipse.ui.application.IWorkbenchWindowConfigurer
+     */
+    public void setShellStyle(int shellStyle) {
+        this.shellStyle = shellStyle;
+    }
 }
diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/colors/ColorsPreferencePage.properties b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/colors/ColorsPreferencePage.properties
index 1c5b484..bcf7ad9 100644
--- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/colors/ColorsPreferencePage.properties
+++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/colors/ColorsPreferencePage.properties
@@ -15,5 +15,5 @@
 ColorsPreferencePage.value=&Value
 ColorsPreferencePage.colors=&Colors
 ColorsPreferencePage.comment=Co&mment
-ColorsPreferencePage.description=&Description
+ColorsPreferencePage.description=Descriptio&n
 ColorsPreferencePage.customValue=Currently set to a custom value.
diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/commands/CommandManager.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/commands/CommandManager.java
index f905162..9e2ec93 100644
--- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/commands/CommandManager.java
+++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/commands/CommandManager.java
@@ -439,7 +439,21 @@
 	}
 
 	public boolean isPartialMatch(KeySequence keySequence) {
-		return !getPartialMatches(keySequence).isEmpty();
+		for (Iterator iterator =
+			keySequenceBindingMachine
+				.getMatchesByKeySequence()
+				.entrySet()
+				.iterator();
+			iterator.hasNext();
+			) {
+			Map.Entry entry = (Map.Entry) iterator.next();
+			KeySequence keySequence2 = (KeySequence) entry.getKey();
+
+			if (keySequence2.startsWith(keySequence, false))
+				return true;
+		}
+		
+		return false;
 	}
 
 	public boolean isPerfectMatch(KeySequence keySequence) {
diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/commands/KeySequenceBindingMachine.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/commands/KeySequenceBindingMachine.java
index 4378240..2bb51f2 100644
--- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/commands/KeySequenceBindingMachine.java
+++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/commands/KeySequenceBindingMachine.java
@@ -80,14 +80,21 @@
 		return keySequenceBindingsByCommandId;
 	}
 
+	/**
+	 * Gets all of the active key bindings as a map of <code>KeySequence</code>
+	 * to command identifiers (<code>String</code>).  The map returned is not a
+	 * copy, and is not safe to modify.  <em>Do not modify the return 
+	 * value</em>. 
+	 * @return The active key bindings; never <code>null,/code>.  <em>Do not
+	 * modify the return value</em>.
+	 */
 	Map getMatchesByKeySequence() {
 		if (matchesByKeySequence == null) {
 			validateSolution();
 			matchesByKeySequence =
-				Collections.unmodifiableMap(
-					KeySequenceBindingNode.getMatchesByKeySequence(
-						tree,
-						KeySequence.getInstance()));
+				KeySequenceBindingNode.getMatchesByKeySequence(
+					tree,
+					KeySequence.getInstance());
 		}
 
 		return matchesByKeySequence;
diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/commands/ws/WorkbenchCommandSupport.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/commands/ws/WorkbenchCommandSupport.java
index b213c34..6b585c3 100644
--- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/commands/ws/WorkbenchCommandSupport.java
+++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/commands/ws/WorkbenchCommandSupport.java
@@ -127,10 +127,15 @@
 		return compoundCommandHandlerService;
 	}
 
-	/*
-	 * (non-Javadoc)
+	/**
+	 * <p>
+	 * An accessor for the keyboard interface this workbench is using. This can
+	 * be used by external class to get a reference with which they can
+	 * simulate key presses in the key binding architecture. This is used for
+	 * testing purposes currently.
+	 * </p>
 	 * 
-	 * @see org.eclipse.ui.commands.IWorkbenchCommandSupport#getKeyboard()
+	 * @return A reference to the workbench keyboard interface; never <code>null</code>.
 	 */
 	public WorkbenchKeyboard getKeyboard() {
 		return keyboard;
diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/dialogs/CustomizePerspectiveDialog.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/dialogs/CustomizePerspectiveDialog.java
index d49f862..08778f5 100644
--- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/dialogs/CustomizePerspectiveDialog.java
+++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/dialogs/CustomizePerspectiveDialog.java
@@ -634,7 +634,7 @@
 	
 	// Fill current actionBars in the "fake" workbench actionbars
 	window.fillActionBars(customizeWorkbenchActionBars, 
-		WorkbenchAdvisor.FILL_PROXY | WorkbenchAdvisor.FILL_MENU_BAR | WorkbenchAdvisor.FILL_TOOL_BAR );
+		WorkbenchAdvisor.FILL_PROXY | WorkbenchAdvisor.FILL_MENU_BAR | WorkbenchAdvisor.FILL_COOL_BAR );
 	
 	initializeActionSetInput();
 	initializeShortcutMenuInput();
diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/dialogs/EventLoopProgressMonitor.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/dialogs/EventLoopProgressMonitor.java
index 5155ded..1a75e48 100644
--- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/dialogs/EventLoopProgressMonitor.java
+++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/dialogs/EventLoopProgressMonitor.java
@@ -10,9 +10,14 @@
  *******************************************************************************/
 package org.eclipse.ui.internal.dialogs;
 
-import org.eclipse.core.runtime.*;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IProgressMonitorWithBlocking;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.ProgressMonitorWrapper;
+
 import org.eclipse.swt.widgets.Display;
-import org.eclipse.ui.internal.progress.ProgressMonitorJobsDialog;
+
+import org.eclipse.ui.internal.progress.BlockedJobsDialog;
 
 /**
  * Used to run an event loop whenever progress monitor methods
@@ -37,14 +42,9 @@
 	/**
 	 * The dialog that is shown when the operation is blocked
 	 */
-	private ProgressMonitorJobsDialog dialog;
+	private BlockedJobsDialog dialog;
 	
 	/**
-	 * The name of the task that is being executed
-	 */
-	private String taskName;
-
-	/**
 	 * Last time the event loop was spun.
 	 */
 	private long lastTime = System.currentTimeMillis();
@@ -59,7 +59,6 @@
  * @see IProgressMonitor#beginTask
  */
 public void beginTask(String name, int totalWork) {
-	this.taskName = name;
 	super.beginTask(name, totalWork);
 	runEventLoop();
 }
@@ -129,14 +128,10 @@
 public void setBlocked(IStatus reason) {
 	//The UI operation has been blocked.  Open a progress dialog
 	//to report the situation and give the user an opportunity to cancel.
-	dialog = new ProgressMonitorJobsDialog(null);
+	dialog = new BlockedJobsDialog(null,this);
 	dialog.setBlockOnOpen(false);
-	dialog.setCancelable(true);
+	dialog.setStatus(reason);
 	dialog.open();
-	IProgressMonitor monitor = dialog.getProgressMonitor();
-	monitor.beginTask(taskName, IProgressMonitor.UNKNOWN);
-	if (monitor instanceof IProgressMonitorWithBlocking) 
-		((IProgressMonitorWithBlocking)monitor).setBlocked(reason);
 }
 /**
  * @see IProgressMonitor#setCanceled
diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/dialogs/WorkbenchPreferenceDialog.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/dialogs/WorkbenchPreferenceDialog.java
index 9df7f45..6e69734 100644
--- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/dialogs/WorkbenchPreferenceDialog.java
+++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/dialogs/WorkbenchPreferenceDialog.java
@@ -10,37 +10,23 @@
  *******************************************************************************/
 package org.eclipse.ui.internal.dialogs;
 
-import java.io.File;
-import java.util.Iterator;
-
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IPath;
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.core.runtime.Path;
-import org.eclipse.core.runtime.Preferences;
-
 import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Point;
 import org.eclipse.swt.layout.GridData;
 import org.eclipse.swt.layout.GridLayout;
 import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.FileDialog;
 import org.eclipse.swt.widgets.Label;
 import org.eclipse.swt.widgets.Shell;
 
-import org.eclipse.jface.dialogs.ErrorDialog;
 import org.eclipse.jface.dialogs.IDialogConstants;
-import org.eclipse.jface.dialogs.MessageDialog;
-import org.eclipse.jface.preference.IPreferenceNode;
-import org.eclipse.jface.preference.IPreferencePage;
+import org.eclipse.jface.dialogs.IDialogSettings;
 import org.eclipse.jface.preference.PreferenceManager;
 import org.eclipse.jface.window.Window;
+import org.eclipse.jface.wizard.WizardDialog;
 
 import org.eclipse.ui.internal.WorkbenchMessages;
 import org.eclipse.ui.internal.WorkbenchPlugin;
 
-
-
-
 /**
  * Prefence dialog for the workbench including the ability 
  * to load/save preferences.
@@ -50,31 +36,16 @@
 	 * The Load button id.
 	 */
 	private final static int LOAD_ID = IDialogConstants.CLIENT_ID + 1;
-	/** 
-	 * The Load dialogs settings key
-	 */
-	private final static String LOAD_SETTING = "WorkbenchPreferenceDialog.load";	//$NON-NLS-1$
 
 	/**
 	 * The Save button id.
 	 */
 	private final static int SAVE_ID = IDialogConstants.CLIENT_ID + 2;
 	/** 
-	 * The Save dialogs settings key
+	 * The dialog settings key for the last used import/export path.
 	 */
-	private final static String SAVE_SETTING = "WorkbenchPreferenceDialog.save"; //$NON-NLS-1$
-	
-	/**
-	 * The extension for preferences files
-	 */
-	private final static String PREFERENCE_EXT = "epf"; //$NON-NLS-1$
-	
-	/**
-	 * The extensions for the file dialogs
-	 */
-	private final static String[] DIALOG_PREFERENCE_EXTENSIONS = new String[] {"*."+PREFERENCE_EXT, "*.*"}; //$NON-NLS-2$ //$NON-NLS-1$
-    
-  
+	final static String FILE_PATH_SETTING = "PreferenceImportExportFileSelectionPage.filePath"; //$NON-NLS-1$
+	 
 	/**
 	 * Creates a new preference dialog under the control of the given preference 
 	 * manager.
@@ -125,137 +96,58 @@
 	 * Handle a request to load preferences
 	 */
 	protected void loadPressed() {
-		// Get the file to load
-		String lastFilename = WorkbenchPlugin.getDefault().getDialogSettings().get(LOAD_SETTING);
-		FileDialog d = new FileDialog(getShell(), SWT.OPEN);
-		d.setFileName(lastFilename);
-		d.setFilterExtensions(DIALOG_PREFERENCE_EXTENSIONS);
-		String filename = d.open();
-		if (filename == null)
-			return;
-		// Append the default filename if none was specifed	and such a file does not exist
-		IPath path = new Path(filename);
-		if (path.getFileExtension() == null) {
-			if (!path.toFile().exists()) {
-				path = path.addFileExtension(PREFERENCE_EXT);			
-				filename = path.toOSString();
-			}
-		}
+		PreferenceImportExportWizard wizard = new PreferenceImportExportWizard(false, this);
+		IDialogSettings workbenchSettings = WorkbenchPlugin.getDefault().getDialogSettings();
+		IDialogSettings wizardSettings = workbenchSettings.getSection(FILE_PATH_SETTING); //$NON-NLS-1$
+		if (wizardSettings == null)
+			wizardSettings = workbenchSettings.addNewSection(FILE_PATH_SETTING); //$NON-NLS-1$
+		wizard.setDialogSettings(wizardSettings);
 
-		WorkbenchPlugin.getDefault().getDialogSettings().put(LOAD_SETTING, filename);
-			
-		// Verify the file
-		IStatus status = Preferences.validatePreferenceVersions(path);		
-		if (status.getSeverity() == IStatus.ERROR) {
-			// Show the error and about
-			ErrorDialog.openError(
-				getShell(), 
-				WorkbenchMessages.getString("WorkbenchPreferenceDialog.loadErrorTitle"), //$NON-NLS-1$
-				WorkbenchMessages.format("WorkbenchPreferenceDialog.verifyErrorMessage", new Object[]{filename}), //$NON-NLS-1$
-				status);
-			return;	
-		}
-		if (status.getSeverity() == IStatus.WARNING) {
-			// Show the warning and give the option to continue
-			int result = PreferenceErrorDialog.openError(
-				getShell(), 
-				WorkbenchMessages.getString("WorkbenchPreferenceDialog.loadErrorTitle"), //$NON-NLS-1$
-				WorkbenchMessages.format("WorkbenchPreferenceDialog.verifyWarningMessage", new Object[]{filename}), //$NON-NLS-1$
-				status);
-			if (result != Window.OK)
-				return;	
-		}
-		// Load file
-		try {
-			Preferences.importPreferences(path);
-		} catch (CoreException e) {
-			ErrorDialog.openError(
-				getShell(), 
-				WorkbenchMessages.getString("WorkbenchPreferenceDialog.loadErrorTitle"), //$NON-NLS-1$
-				WorkbenchMessages.format("WorkbenchPreferenceDialog.loadErrorMessage", new Object[]{filename}), //$NON-NLS-1$
-				e.getStatus());
-			return;	
-		}
+		Shell parent = getShell();
+		WizardDialog dialog = new WizardDialog(parent, wizard);
+		dialog.create();
+		Shell shell = dialog.getShell();
+		shell.setSize(Math.max(500, shell.getSize().x), 500);
+		Point childSize = shell.getSize();
+		Point parentSize = parent.getSize();
+		Point childLocation = new Point((parentSize.x - childSize.x) / 2, (parentSize.y - childSize.y) / 2);
+		shell.setLocation(parent.toDisplay(childLocation));
+		// TODO Provide a help context ID and content.
+		//WorkbenchHelp.setHelp(shell, IHelpContextIds.IMPORT_WIZARD);
+		int returnCode = dialog.open();
 		
-		MessageDialog.openInformation(
-			getShell(),
-			WorkbenchMessages.getString("WorkbenchPreferenceDialog.loadTitle"), //$NON-NLS-1$
-			WorkbenchMessages.format("WorkbenchPreferenceDialog.loadMessage", new Object[]{filename})); //$NON-NLS-1$
-			
-		// Close the dialog since it shows an invalid state
-		close();
+		/* All my values are messed up.  Reboot.  (oh, windows, you have taught 
+		 * us well.)
+		 */
+		if (returnCode == Window.OK) {
+			close();
+		}
 	}
 			
 	/**
 	 * Handle a request to save preferences
 	 */
 	protected void savePressed() {
-		// Get the file to save
-		String lastFilename = WorkbenchPlugin.getDefault().getDialogSettings().get(SAVE_SETTING);
-		FileDialog d = new FileDialog(getShell(), SWT.SAVE);
-		d.setFileName(lastFilename);
-		d.setFilterExtensions(DIALOG_PREFERENCE_EXTENSIONS);
-		String filename = d.open();
-		if (filename == null)
-			return;
-		// Append the default filename if none was specifed	
-		IPath path = new Path(filename);
-		if (path.getFileExtension() == null) {
-			path = path.addFileExtension(PREFERENCE_EXT);			
-			filename = path.toOSString();
-		}
-			
-		WorkbenchPlugin.getDefault().getDialogSettings().put(SAVE_SETTING, filename);
-		
-		// See if the file already exists
-		File file = path.toFile();
-		if(file.exists()) {
-			if(!MessageDialog.openConfirm(
-				getShell(),
-				WorkbenchMessages.getString("WorkbenchPreferenceDialog.saveTitle"), //$NON-NLS-1$
-				WorkbenchMessages.format("WorkbenchPreferenceDialog.existsErrorMessage", new Object[]{filename}))) //$NON-NLS-1$
-					return;
-		}			
+		PreferenceImportExportWizard wizard = new PreferenceImportExportWizard(true, this);
+		IDialogSettings workbenchSettings = WorkbenchPlugin.getDefault().getDialogSettings();
+		IDialogSettings wizardSettings = workbenchSettings.getSection(FILE_PATH_SETTING); //$NON-NLS-1$
+		if (wizardSettings == null)
+			wizardSettings = workbenchSettings.addNewSection("ExportPreferencesWizard"); //$NON-NLS-1$
+		wizard.setDialogSettings(wizardSettings);
+		wizard.setForcePreviousAndNextButtons(true);
 
-		// Save all the pages and give them a chance to abort
-		Iterator nodes = getPreferenceManager().getElements(PreferenceManager.PRE_ORDER).iterator();
-		while (nodes.hasNext()) {
-			IPreferenceNode node = (IPreferenceNode) nodes.next();
-			IPreferencePage page = node.getPage();
-			if (page != null) {
-				if(!page.performOk())
-					return;
-			}
-		}
-
-		long lastModified = file.lastModified();
-		// Save to file
-		try {
-			Preferences.exportPreferences(path); 
-		} catch (CoreException e) {
-			ErrorDialog.openError(
-				getShell(), 
-				WorkbenchMessages.getString("WorkbenchPreferenceDialog.saveErrorTitle"), //$NON-NLS-1$
-				WorkbenchMessages.format("WorkbenchPreferenceDialog.saveErrorMessage", new Object[]{filename}), //$NON-NLS-1$
-				e.getStatus());
-				return;
-		}
-		// See if we actually created a file (there where preferences to export).
-		if(file.exists() && file.lastModified() != lastModified) {
-			MessageDialog.openInformation(
-				getShell(),
-				WorkbenchMessages.getString("WorkbenchPreferenceDialog.saveTitle"), //$NON-NLS-1$
-				WorkbenchMessages.format("WorkbenchPreferenceDialog.saveMessage", new Object[]{filename})); //$NON-NLS-1$
-		} else {
-			MessageDialog.openError(
-				getShell(),
-				WorkbenchMessages.getString("WorkbenchPreferenceDialog.saveErrorTitle"), //$NON-NLS-1$
-				WorkbenchMessages.getString("WorkbenchPreferenceDialog.noPreferencesMessage")); //$NON-NLS-1$
-		}			
-		
-		
-		// Close since we have "performed Ok" and cancel is no longer valid
-		close();	
+		Shell parent = getShell();
+		WizardDialog dialog = new WizardDialog(parent, wizard);
+		dialog.create();
+		Shell shell = dialog.getShell();
+		shell.setSize(Math.max(500, shell.getSize().x), 500);
+		Point childSize = shell.getSize();
+		Point parentSize = parent.getSize();
+		Point childLocation = new Point((parentSize.x - childSize.x) / 2, (parentSize.y - childSize.y) / 2);
+		shell.setLocation(parent.toDisplay(childLocation));
+		// TODO Provide a help context ID and content.
+		//WorkbenchHelp.setHelp(shell, IHelpContextIds.EXPORT_WIZARD);
+		dialog.open();	
 	} 
 }
 
diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/keys/WorkbenchKeyboard.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/keys/WorkbenchKeyboard.java
index e3cf994..87062de 100644
--- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/keys/WorkbenchKeyboard.java
+++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/keys/WorkbenchKeyboard.java
@@ -72,7 +72,7 @@
  * 
  * @since 3.0
  */
-public class WorkbenchKeyboard {
+public final class WorkbenchKeyboard {
 
     /**
      * Whether the keyboard should kick into debugging mode. This causes real
@@ -110,6 +110,7 @@
      */
     private final static ResourceBundle RESOURCE_BUNDLE = ResourceBundle
             .getBundle(WorkbenchKeyboard.class.getName());
+
     static {
         initializeOutOfOrderKeys();
     }
@@ -126,23 +127,27 @@
      */
     public static List generatePossibleKeyStrokes(Event event) {
         final List keyStrokes = new ArrayList(3);
+
         /*
          * If this is not a keyboard event, then there are no key strokes. This
          * can happen if we are listening to focus traversal events.
          */
         if ((event.stateMask == 0) && (event.keyCode == 0)
                 && (event.character == 0)) { return keyStrokes; }
+
         // Add each unique key stroke to the list for consideration.
         final int firstAccelerator = SWTKeySupport
                 .convertEventToUnmodifiedAccelerator(event);
         keyStrokes.add(SWTKeySupport
                 .convertAcceleratorToKeyStroke(firstAccelerator));
+
         final int secondAccelerator = SWTKeySupport
                 .convertEventToUnshiftedModifiedAccelerator(event);
         if (secondAccelerator != firstAccelerator) {
             keyStrokes.add(SWTKeySupport
                     .convertAcceleratorToKeyStroke(secondAccelerator));
         }
+
         final int thirdAccelerator = SWTKeySupport
                 .convertEventToModifiedAccelerator(event);
         if ((thirdAccelerator != secondAccelerator)
@@ -150,6 +155,7 @@
             keyStrokes.add(SWTKeySupport
                     .convertAcceleratorToKeyStroke(thirdAccelerator));
         }
+
         return keyStrokes;
     }
 
@@ -161,6 +167,7 @@
         // Get the key strokes which should be out of order.
         String keysText = WorkbenchMessages.getString(OUT_OF_ORDER_KEYS);
         outOfOrderKeys = KeySequence.getInstance();
+
         try {
             outOfOrderKeys = KeySequence.getInstance(keysText);
         } catch (ParseException e) {
@@ -230,6 +237,7 @@
                         + ", character = 0x" //$NON-NLS-1$
                         + Integer.toHexString(event.character) + ")"); //$NON-NLS-1$
             }
+
             filterKeySequenceBindings(event);
         }
     };
@@ -323,6 +331,7 @@
      */
     public WorkbenchKeyboard(Workbench associatedWorkbench,
             ICommandManager associatedCommandManager) {
+
         workbench = associatedWorkbench;
         state = new KeyBindingState(associatedWorkbench);
         commandManager = associatedCommandManager;
@@ -393,12 +402,15 @@
                     .println("KEYS >>> WorkbenchKeyboard.executeCommand(commandId = '" //$NON-NLS-1$
                             + commandId + "')"); //$NON-NLS-1$
         }
+
         // Reset the key binding state (close window, clear status line, etc.)
         resetState();
+
         // Dispatch to the handler.
         Map actionsById = ((CommandManager) commandManager).getActionsById();
         org.eclipse.ui.commands.IHandler action = (org.eclipse.ui.commands.IHandler) actionsById
                 .get(commandId);
+
         if (DEBUG && DEBUG_VERBOSE) {
             if (action == null) {
                 System.out.println("KEYS >>>     action  = null"); //$NON-NLS-1$
@@ -409,6 +421,7 @@
                         + action.isEnabled());
             }
         }
+
         if (action != null && action.isEnabled()) {
             try {
                 action.execute(event);
@@ -419,6 +432,7 @@
                         WorkbenchPlugin.PI_WORKBENCH, 0, message, e));
             }
         }
+
         return (action != null);
     }
 
@@ -447,13 +461,14 @@
          * bindings.
          */
         if ((event.keyCode & SWT.MODIFIER_MASK) != 0) return;
+
         /*
          * There are three classes of shells: fully-managed, partially-managed,
          * and unmanaged. An unmanaged shell is a shell with no parent that has
          * not registered; it gets no key bindings. A partially-managed shell
          * is either a shell with a parent, or it is a shell with no parent
          * that has registered for partial service; it gets dialog key
-         * bindings. A fully0managed shell has no parent and has registered for
+         * bindings. A fully-managed shell has no parent and has registered for
          * full service; they get all key bindings.
          */
         boolean dialogOnly = false;
@@ -469,13 +484,17 @@
                     // There is no parent shell. The shell is unmanaged.
                     return;
                 }
+
             } else if (dialog.booleanValue()) {
                 // The window is managed, but requested partial management.
                 dialogOnly = true;
+
             } else {
                 // The window is fully-managed; leave dialogOnly=false.
+
             }
         }
+
         // Allow special key out-of-order processing.
         List keyStrokes = generatePossibleKeyStrokes(event);
         if (isOutOfOrderKey(keyStrokes)) {
@@ -496,13 +515,16 @@
                             this, dialogOnly));
                 }
             }
+
             /*
              * Otherwise, we count on a key down arriving eventually. Expecting
              * out of order handling on Ctrl+Tab, for example, is a bad idea
              * (stick to keys that are not window traversal keys).
              */
+
         } else {
             processKeyEvent(keyStrokes, event, dialogOnly);
+
         }
     }
 
@@ -544,10 +566,12 @@
         // Record the starting time.
         startTime = System.currentTimeMillis();
         final long myStartTime = startTime;
+
         // Update the state.
         state.setCurrentSequence(sequence);
         state.setAssociatedWindow(workbench.getActiveWorkbenchWindow());
-        // After 1s, open a shell displaying the possible completions.
+
+        // After some time, open a shell displaying the possible completions.
         final IPreferenceStore store = WorkbenchPlugin.getDefault()
                 .getPreferenceStore();
         if (store.getBoolean(IPreferenceConstants.MULTI_KEY_ASSIST)) {
@@ -608,11 +632,13 @@
         if (multiKeyAssistShell != null) {
             multiKeyAssistShell.close();
         }
+
         // Get the status line. If none, then abort.
         StatusLineContributionItem statusLine = state.getStatusLine();
         if (statusLine == null) { return; }
         Point statusLineLocation = statusLine.getDisplayLocation();
         if (statusLineLocation == null) { return; }
+
         // Set up the shell.
         multiKeyAssistShell = new Shell(display, SWT.NO_TRIM);
         GridLayout layout = new GridLayout();
@@ -621,6 +647,7 @@
         multiKeyAssistShell.setLayout(layout);
         multiKeyAssistShell.setBackground(display
                 .getSystemColor(SWT.COLOR_INFO_BACKGROUND));
+
         // Get the list of items.
         Map partialMatches = new TreeMap(new Comparator() {
 
@@ -644,6 +671,7 @@
                 partialMatchItr.remove();
             }
         }
+
         // Layout the partial matches.
         if (partialMatches.isEmpty()) {
             Label noMatchesLabel = new Label(multiKeyAssistShell, SWT.NULL);
@@ -651,6 +679,7 @@
                     "NoMatches.Message")); //$NON-NLS-1$
             noMatchesLabel.setLayoutData(new GridData(GridData.FILL_BOTH));
             noMatchesLabel.setBackground(multiKeyAssistShell.getBackground());
+
         } else {
             // Layout the table.
             final Table completionsTable = new Table(multiKeyAssistShell,
@@ -671,7 +700,7 @@
                 String commandId = (String) entry.getValue();
                 ICommand command = commandManager.getCommand(commandId);
                 try {
-                    String[] text = {sequence.format(), command.getName()};
+                    String[] text = { sequence.format(), command.getName()};
                     TableItem item = new TableItem(completionsTable, SWT.NULL);
                     item.setText(text);
                     commands.add(command);
@@ -698,7 +727,9 @@
                     // Do nothing
                 }
             });
+
         }
+
         // Size the shell.
         multiKeyAssistShell.pack();
         Point assistShellSize = multiKeyAssistShell.getSize();
@@ -709,6 +740,7 @@
             assistShellSize.y = MULTI_KEY_ASSIST_SHELL_MAX_HEIGHT;
         }
         multiKeyAssistShell.setSize(assistShellSize);
+
         // Position the shell.
         Point assistShellLocation = new Point(statusLineLocation.x,
                 statusLineLocation.y - assistShellSize.y);
@@ -726,6 +758,7 @@
             assistShellLocation.y = displayBottomEdge - assistShellSize.y;
         }
         multiKeyAssistShell.setLocation(assistShellLocation);
+
         // If the shell loses focus, it should be closed.
         multiKeyAssistShell.addListener(SWT.Deactivate, new Listener() {
 
@@ -733,6 +766,7 @@
                 closeMultiKeyAssistShell();
             }
         });
+
         // Open the shell.
         register(multiKeyAssistShell, false);
         multiKeyAssistShell.open();
@@ -763,8 +797,10 @@
                             + potentialKeyStrokes + ", dialogOnly = " //$NON-NLS-1$
                             + dialogOnly + ")"); //$NON-NLS-1$
         }
+
         // TODO Add proper dialog support
         if (dialogOnly) { return false; }
+
         KeySequence sequenceBeforeKeyStroke = state.getCurrentSequence();
         for (Iterator iterator = potentialKeyStrokes.iterator(); iterator
                 .hasNext();) {
@@ -773,18 +809,23 @@
             if (isPartialMatch(sequenceAfterKeyStroke)) {
                 incrementState(sequenceAfterKeyStroke);
                 return true;
+
             } else if (isPerfectMatch(sequenceAfterKeyStroke)) {
                 String commandId = getPerfectMatch(sequenceAfterKeyStroke);
                 return (executeCommand(commandId, event) || sequenceBeforeKeyStroke
                         .isEmpty());
+
             } else if ((multiKeyAssistShell != null)
                     && ((event.keyCode == SWT.ARROW_DOWN)
                             || (event.keyCode == SWT.ARROW_UP)
                             || (event.keyCode == SWT.ARROW_LEFT)
                             || (event.keyCode == SWT.ARROW_RIGHT) || (event.keyCode == SWT.CR))) { 
             // We don't want to swallow keyboard navigation keys.
-            return false; }
+            return false; 
+
+            }
         }
+
         resetState();
         return false;
     }
diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/messages.properties b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/messages.properties
index 7947947..ce34c54 100644
--- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/messages.properties
+++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/messages.properties
@@ -339,7 +339,6 @@
 WorkbenchPage.ErrorRecreatingPerspective = Unable to recreate perspective
 WorkbenchPage.UndefinedPerspective = Perspective ID is undefined
 
-
 # ==============================================================================
 # Navigator Actions
 # ==============================================================================
@@ -748,6 +747,31 @@
 PreferenceNode.errorMessage = Unable to create the selected preference page.
 Preference.note = Note:
 
+# --- Import/Export ---
+ImportExportPages.browseButton = Browse...
+ImportExportPages.deselectAll = Deselect All
+ImportExportPages.errorDirectoryDoesNotExist = The directory does not exist.
+ImportExportPages.errorImportFileDoesNotExist = The file to be imported does not exist.
+ImportExportPages.exportAllItems = Export all preferences
+ImportExportPages.exportFileSelect = Select a file to store your exported preferences.
+ImportExportPages.exportPageItems = Export preferences from this page
+ImportExportPages.exportSelectItems = Select preferences to export (Advanced)
+ImportExportPages.exportSettingsSelect = Select the preferences to export
+ImportExportPages.exportTitle = Export
+ImportExportPages.exportWindowTitle = Export Preferences
+ImportExportPages.fileLabel = File:
+ImportExportPages.importAllItems = Import all preferences
+ImportExportPages.importFileSelect = Select a file from which to import preferences.
+ImportExportPages.importSelectItems = Select preferences to import (Advanced)
+ImportExportPages.importSettingsSelect = Select the preferences to import
+ImportExportPages.importTitle = Import
+ImportExportPages.importWindowTitle = Import Preferences
+ImportExportPages.invertSelection = Invert Selection
+ImportExportPages.name = Name
+ImportExportPages.preferenceFileName = preferences
+ImportExportPages.selectAll = Select All
+ImportExportPages.value = Value
+
 # --- Workbench ---
 WorkbenchPreference.acceleratorConfiguration = &Key bindings: 
 WorkbenchPreference.autobuild = Perform &build automatically on resource modification
@@ -1220,6 +1244,7 @@
 ViewFactory.initException = Unable to instantiate view: {0}
 ViewFactory.siteException = View initialization failed: {0}.  Site is incorrect.
 ViewFactory.couldNotCreate = Could not create view: {0}
+ViewFactory.noMultiple = View does not allow multiple instances: {0}
 ViewFactory.couldNotSave = Could not save view: {0}
 ViewFactory.unableToRestoreViewTitle = Error Restoring View
 ViewFactory.unableToRestoreViewMessage = Unable to restore: {0}.
@@ -1274,6 +1299,7 @@
 # --- Workbench Errors/Problems ---
 WorkbenchWindow.exceptionMessage = Abnormal Workbench Condition
 WorkbenchPage.AbnormalWorkbenchCondition = Abnormal Workbench Condition
+WorkbenchPage.IllegalViewMode = Illegal view mode
 Abnormal_Workbench_Conditi = Abnormal Workbench Condition
 WorkbenchPage.ErrorActivatingView = An error has occurred when activating this view
 WorkbenchPage.ErrorExtractingEditorIDFromMarker = Error extracting editor ID from marker
diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/misc/WorkInProgress.properties b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/misc/WorkInProgress.properties
deleted file mode 100644
index 9e66fb2..0000000
--- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/misc/WorkInProgress.properties
+++ /dev/null
@@ -1,5 +0,0 @@
-WorkInProgressPreferencePage.0_label=&Machine Speed:
-WorkInProgressPreferencePage.SlowTitle=Slow
-WorkInProgressPreferencePage.FastTitle=Fast
-WorkInProgressPreferencePage.MediumTitle=Medium
-WorkInProgressPreferencePage.SpeedExplanation=Adjust the speed setting to limit the number of concurrent jobs.\nThe faster the setting the more jobs that can run concurrently.
diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/misc/WorkInProgressMessages.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/misc/WorkInProgressMessages.java
deleted file mode 100644
index a4c9eeb..0000000
--- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/misc/WorkInProgressMessages.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2003 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.internal.misc;
-
-import java.util.MissingResourceException;
-import java.util.ResourceBundle;
-
-/**
- * @since 3.0
- */
-public class WorkInProgressMessages {
-
-    private static final String BUNDLE_NAME = "org.eclipse.ui.internal.misc.WorkInProgress"; //$NON-NLS-1$
-
-    private static final ResourceBundle RESOURCE_BUNDLE = ResourceBundle.getBundle(BUNDLE_NAME);
-
-    /**
-     * 
-     * @since 3.0
-     */
-    private WorkInProgressMessages() {
-
-        // TODO Auto-generated constructor stub
-    }
-    /**
-     * @param key
-     * @return
-     * @since 3.0
-     */
-    public static String getString(String key) {
-        // TODO Auto-generated method stub
-        try {
-            return RESOURCE_BUNDLE.getString(key);
-        }
-        catch (MissingResourceException e) {
-            return '!' + key + '!';
-        }
-    }
-}
diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/misc/WorkInProgressPreferencePage.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/misc/WorkInProgressPreferencePage.java
deleted file mode 100644
index a2cde28..0000000
--- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/misc/WorkInProgressPreferencePage.java
+++ /dev/null
@@ -1,159 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2003 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.internal.misc;
-
-import org.eclipse.core.runtime.Platform;
-
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.SelectionEvent;
-import org.eclipse.swt.events.SelectionListener;
-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.Label;
-import org.eclipse.swt.widgets.Slider;
-
-import org.eclipse.jface.preference.PreferencePage;
-
-import org.eclipse.ui.IWorkbench;
-import org.eclipse.ui.IWorkbenchPreferencePage;
-
-/**
- * Temporary "Work in Progress" PreferencePage for Job control
- * 
- * @since 3.0
- */
-public class WorkInProgressPreferencePage extends PreferencePage implements IWorkbenchPreferencePage {
-
-	private static final int SLOW = Platform.MIN_PERFORMANCE;
-	private static final int FAST = Platform.MAX_PERFORMANCE;
-
-	private Slider slider;
-	private Label displayLabel;
-
-	/*
-	 * (non-Javadoc)
-	 * 
-	 * @see org.eclipse.jface.preference.PreferencePage#createContents(org.eclipse.swt.widgets.Composite)
-	 */
-	protected Control createContents(Composite parent) {
-		Composite composite = new Composite(parent, SWT.NONE);
-		GridLayout layout = new GridLayout(3, false);
-		layout.marginHeight = layout.marginWidth = 0;
-		composite.setLayout(layout);
-
-		Label label = new Label(composite, SWT.NONE);
-		label.setText(WorkInProgressMessages.getString("WorkInProgressPreferencePage.0_label")); //$NON-NLS-1$
-		GridData data = new GridData();
-		label.setLayoutData(data);
-		slider = new Slider(composite, SWT.HORIZONTAL);
-		data = new GridData(GridData.FILL_HORIZONTAL);
-		slider.setLayoutData(data);
-
-		displayLabel = new Label(composite, SWT.NONE);
-		data = new GridData(GridData.HORIZONTAL_ALIGN_CENTER);
-		data.widthHint = convertWidthInCharsToPixels(10);
-		displayLabel.setLayoutData(data);
-
-		Label description = new Label(composite, SWT.WRAP);
-		description.setText(
-			WorkInProgressMessages.getString("WorkInProgressPreferencePage.SpeedExplanation")); //$NON-NLS-1$
-
-		GridData descriptionData = new GridData();
-		descriptionData.horizontalSpan = 3;
-		description.setLayoutData(descriptionData);
-
-		slider.addSelectionListener(new SelectionListener() {
-
-			public void widgetSelected(SelectionEvent e) {
-				setLabelText(((Slider) e.widget).getSelection());
-			}
-
-			public void widgetDefaultSelected(SelectionEvent e) {
-				widgetSelected(e);
-			}
-		});
-
-		slider.setValues(getValue(), SLOW, FAST + 1, 1, 1, 1);
-		int value = getValue();
-		slider.setSelection(value);
-		setLabelText(value);
-
-		return composite;
-	}
-
-	/**
-	 * Sets the value of the label control.
-	 * 
-	 * @param value
-	 *            the integer value to set the label to.
-	 */
-	protected void setLabelText(int value) {
-		String string;
-		switch (value) {
-			case SLOW :
-				string = WorkInProgressMessages.getString("WorkInProgressPreferencePage.SlowTitle"); //$NON-NLS-1$
-				break;
-			case FAST :
-				string = WorkInProgressMessages.getString("WorkInProgressPreferencePage.FastTitle"); //$NON-NLS-1$
-				break;
-			default :
-				string = WorkInProgressMessages.getString("WorkInProgressPreferencePage.MediumTitle"); //$NON-NLS-1$
-		}
-		displayLabel.setText(string);
-		displayLabel.redraw();
-	}
-
-	/**
-	 * Gets the stored value.
-	 * 
-	 * @return the value for the slider, as pulled from preferences.
-	 */
-	private int getValue() {
-		int value = Platform.getPlugin(Platform.PI_RUNTIME).getPluginPreferences().getInt(Platform.PREF_PLATFORM_PERFORMANCE);
-		if (value < SLOW)
-			return FAST;
-		else
-			return value;
-	}
-
-	/*
-	 * (non-Javadoc)
-	 * 
-	 * @see org.eclipse.ui.IWorkbenchPreferencePage#init(org.eclipse.ui.IWorkbench)
-	 */
-	public void init(IWorkbench workbench) {
-	}
-
-	/*
-	 * (non-Javadoc)
-	 * 
-	 * @see org.eclipse.jface.preference.IPreferencePage#performOk()
-	 */
-	public boolean performOk() {
-
-		Platform.getPlugin(Platform.PI_RUNTIME).getPluginPreferences().setValue(Platform.PREF_PLATFORM_PERFORMANCE, slider.getSelection());
-		Platform.getPlugin(Platform.PI_RUNTIME).savePluginPreferences();
-
-		return super.performOk();
-	}
-
-	/*
-	 * (non-Javadoc)
-	 * 
-	 * @see org.eclipse.jface.preference.PreferencePage#performDefaults()
-	 */
-	protected void performDefaults() {
-		slider.setSelection(FAST);
-		setLabelText(FAST);
-	}
-}
diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/progress/AnimationItem.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/progress/AnimationItem.java
index 5be5a44..5005a5e 100644
--- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/progress/AnimationItem.java
+++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/progress/AnimationItem.java
@@ -8,9 +8,7 @@
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
-
 package org.eclipse.ui.internal.progress;
-
 import org.eclipse.core.runtime.IProgressMonitor;
 import org.eclipse.core.runtime.IStatus;
 import org.eclipse.core.runtime.Status;
@@ -34,17 +32,13 @@
 import org.eclipse.swt.widgets.Control;
 import org.eclipse.ui.internal.WorkbenchWindow;
 import org.eclipse.ui.progress.WorkbenchJob;
-
 public class AnimationItem {
-
 	WorkbenchWindow window;
 	private ProgressFloatingWindow floatingWindow;
-	private boolean showingDetails = true;
 	Canvas imageCanvas;
 	GC imageCanvasGC;
 	//An object used to preven concurrent modification issues
 	private Object windowLock = new Object();
-
 	/**
 	 * Create a new instance of the receiver.
 	 * 
@@ -53,41 +47,31 @@
 	 * @param manager
 	 *            the AnimationManager that will run this item.
 	 */
-
 	public AnimationItem(WorkbenchWindow workbenchWindow) {
 		this.window = workbenchWindow;
 	}
-
 	/**
 	 * Create the canvas that will display the image.
 	 * 
 	 * @param parent
 	 */
 	public void createControl(Composite parent) {
-
 		final AnimationManager manager = AnimationManager.getInstance();
 		// Canvas to show the image.
 		imageCanvas = new Canvas(parent, SWT.NONE);
-		imageCanvas.setBackground(
-			parent.getDisplay().getSystemColor(SWT.COLOR_WIDGET_BACKGROUND));
+		imageCanvas.setBackground(parent.getDisplay().getSystemColor(SWT.COLOR_WIDGET_BACKGROUND));
 		imageCanvas.setToolTipText(ProgressMessages.getString("AnimationItem.HoverHelp")); //$NON-NLS-1$
-
 		imageCanvas.addPaintListener(new PaintListener() {
 			public void paintControl(PaintEvent event) {
-				paintImage(
-					event,
-					manager.getImage(),
-					manager.getImageData()[0]);
+				paintImage(event, manager.getImage(), manager.getImageData()[0]);
 			}
 		});
-
 		imageCanvasGC = new GC(imageCanvas);
 		imageCanvas.addDisposeListener(new DisposeListener() {
 			public void widgetDisposed(DisposeEvent e) {
 				imageCanvasGC.dispose();
 			}
 		});
-
 		imageCanvas.addMouseListener(new MouseListener() {
 			/*
 			 * (non-Javadoc)
@@ -95,9 +79,8 @@
 			 * @see org.eclipse.swt.events.MouseListener#mouseDoubleClick(org.eclipse.swt.events.MouseEvent)
 			 */
 			public void mouseDoubleClick(MouseEvent arg0) {
-				toggleFloatingWindow();
+				AnimationManager.getInstance().toggleFloatingWindow();
 			}
-			
 			/*
 			 * (non-Javadoc)
 			 * 
@@ -113,13 +96,9 @@
 			 */
 			public void mouseUp(MouseEvent arg0) {
 				//Do nothing
-
 			}
 		});
-
-		imageCanvas
-			.getAccessible()
-			.addAccessibleControlListener(new AccessibleControlAdapter() {
+		imageCanvas.getAccessible().addAccessibleControlListener(new AccessibleControlAdapter() {
 			/*
 			 * (non-Javadoc)
 			 * 
@@ -132,7 +111,6 @@
 					arg0.result = ProgressMessages.getString("AnimationItem.NotRunningStatus"); //$NON-NLS-1$
 			}
 		});
-
 		imageCanvas.addHelpListener(new HelpListener() {
 			/*
 			 * (non-Javadoc)
@@ -141,14 +119,10 @@
 			 */
 			public void helpRequested(HelpEvent e) {
 				// XXX Auto-generated method stub
-
 			}
 		});
-
 		manager.addItem(this);
-
 	}
-
 	/**
 	 * Paint the image in the canvas.
 	 * 
@@ -160,23 +134,12 @@
 	 *            The array of ImageData. Required to show an animation.
 	 */
 	void paintImage(PaintEvent event, Image image, ImageData imageData) {
-
 		Image paintImage = image;
-
 		int w = imageData.width;
 		int h = imageData.height;
-		event.gc.drawImage(
-			paintImage,
-			0,
-			0,
-			imageData.width,
-			imageData.height,
-			imageData.x,
-			imageData.y,
-			w,
-			h);
+		event.gc.drawImage(paintImage, 0, 0, imageData.width, imageData.height, imageData.x,
+				imageData.y, w, h);
 	}
-
 	/**
 	 * Get the SWT control for the receiver.
 	 * 
@@ -185,7 +148,6 @@
 	public Control getControl() {
 		return imageCanvas;
 	}
-
 	/**
 	 * Get the bounds of the image being displayed here.
 	 * 
@@ -194,7 +156,6 @@
 	public Rectangle getImageBounds() {
 		return AnimationManager.getInstance().getImageBounds();
 	}
-
 	/**
 	 * Open a floating window for the receiver.
 	 * 
@@ -202,17 +163,14 @@
 	 */
 	void openFloatingWindow() {
 		//Do we already have one?
-		if(floatingWindow != null)
+		if (floatingWindow != null)
 			return;
-		
 		//Don't bother if there is nothing showing yet
-		if(!window.getShell().isVisible())
+		if (!window.getShell().isVisible())
 			return;
-		
-		floatingWindow =
-			new ProgressFloatingWindow(window, imageCanvas);
-
-		WorkbenchJob floatingJob = new WorkbenchJob(ProgressMessages.getString("AnimationItem.openFloatingWindowJob")) { //$NON-NLS-1$
+		floatingWindow = new ProgressFloatingWindow(window, imageCanvas);
+		WorkbenchJob floatingJob = new WorkbenchJob(ProgressMessages
+				.getString("AnimationItem.openFloatingWindowJob")) { //$NON-NLS-1$
 			/*
 			 * (non-Javadoc)
 			 * 
@@ -220,56 +178,56 @@
 			 */
 			public IStatus runInUIThread(IProgressMonitor monitor) {
 				synchronized (windowLock) {
+					//Clear the window if the parent is not visibile
+					if (window.getShell() == null 
+							|| !window.getShell().isVisible() 
+							|| getControl().isDisposed())
+						floatingWindow = null;
+					
 					if (floatingWindow == null)
 						return Status.CANCEL_STATUS;
-					else {
-						//Do not bother if the control is disposed
-						if(getControl().isDisposed()){
-							floatingWindow = null;
-							return Status.CANCEL_STATUS;
-						}
-						else{
-							floatingWindow.open();
-							return Status.OK_STATUS;
-						}
-					}
+					floatingWindow.open();
+					return Status.OK_STATUS;
 				}
-
+			}
+			/* (non-Javadoc)
+			 * @see org.eclipse.ui.progress.WorkbenchJob#shouldRun()
+			 */
+			public boolean shouldRun() {
+				if (AnimationManager.getInstance().isAnimated())
+					return true;
+				//If there is no window than do not run
+				floatingWindow = null;
+				return false;
 			}
 		};
 		floatingJob.setSystem(true);
 		floatingJob.schedule(500);
-
 	}
-
 	/**
 	 * The animation has begun.
 	 */
 	void animationStart() {
-		if (showingDetails)
+		if (AnimationManager.getInstance().showingDetails())
 			openFloatingWindow();
 	}
-
 	/**
 	 * The animation has ended.
 	 */
 	void animationDone() {
 		closeFloatingWindow();
 	}
-
 	/**
 	 * Close the floating window.
 	 */
-	private void closeFloatingWindow() {
+	void closeFloatingWindow() {
 		synchronized (windowLock) {
 			if (floatingWindow != null) {
 				floatingWindow.close();
 				floatingWindow = null;
 			}
 		}
-
 	}
-
 	/**
 	 * Get the preferred width of the receiver.
 	 * 
@@ -278,18 +236,4 @@
 	public int getPreferredWidth() {
 		return AnimationManager.getInstance().getPreferredWidth() + 5;
 	}
-	
-	/**
-	 * Toggle the floating window for the receiver.
-	 */
-	public void toggleFloatingWindow() {
-		if (showingDetails)
-			closeFloatingWindow();
-		else
-			openFloatingWindow();
-
-		//Toggle the details flag
-		showingDetails = !showingDetails;
-	}
-
 }
diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/progress/AnimationManager.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/progress/AnimationManager.java
index 3523dc6..f2a00da 100644
--- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/progress/AnimationManager.java
+++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/progress/AnimationManager.java
@@ -9,14 +9,12 @@
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
 package org.eclipse.ui.internal.progress;
-
 import java.net.MalformedURLException;
 import java.net.URL;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashSet;
 import java.util.List;
-
 import org.eclipse.core.runtime.IProgressMonitor;
 import org.eclipse.core.runtime.IStatus;
 import org.eclipse.core.runtime.Path;
@@ -25,7 +23,6 @@
 import org.eclipse.core.runtime.jobs.IJobChangeEvent;
 import org.eclipse.core.runtime.jobs.Job;
 import org.eclipse.core.runtime.jobs.JobChangeAdapter;
-
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.SWTException;
 import org.eclipse.swt.events.DisposeEvent;
@@ -38,75 +35,57 @@
 import org.eclipse.swt.graphics.RGB;
 import org.eclipse.swt.graphics.Rectangle;
 import org.eclipse.swt.widgets.Display;
-
 import org.eclipse.jface.resource.JFaceResources;
-
 import org.eclipse.ui.PlatformUI;
 import org.eclipse.ui.progress.UIJob;
 import org.eclipse.ui.progress.WorkbenchJob;
-
+import org.eclipse.ui.internal.IPreferenceConstants;
+import org.eclipse.ui.internal.WorkbenchPlugin;
 /**
  * The AnimationManager is the class that keeps track of the animation items
  * to update.
  */
-class AnimationManager {
-
+public class AnimationManager {
 	private static final String RUNNING_ICON = "running.gif"; //$NON-NLS-1$
 	private static final String BACKGROUND_ICON = "back.gif"; //$NON-NLS-1$
-
 	private static AnimationManager singleton;
-
 	private ImageData[] animatedData;
 	private ImageData[] disabledData;
-
 	private static String DISABLED_IMAGE_NAME = "ANIMATION_DISABLED_IMAGE"; //$NON-NLS-1$
 	private static String ANIMATED_IMAGE_NAME = "ANIMATION_ANIMATED_IMAGE"; //$NON-NLS-1$
-
 	Color background;
-
 	private ImageLoader runLoader = new ImageLoader();
 	boolean animated = false;
 	Job animateJob;
 	Job clearJob;
 	private IJobProgressManagerListener listener;
-
 	List items = Collections.synchronizedList(new ArrayList());
-
 	public static AnimationManager getInstance() {
 		if (singleton == null)
 			singleton = new AnimationManager();
 		return singleton;
 	}
-
 	AnimationManager() {
-		URL iconsRoot =
-			Platform.getPlugin(PlatformUI.PLUGIN_ID).find(
+		URL iconsRoot = Platform.getPlugin(PlatformUI.PLUGIN_ID).find(
 				new Path(ProgressManager.PROGRESS_FOLDER));
 		ProgressManager manager = ProgressManager.getInstance();
-
 		try {
 			URL runningRoot = new URL(iconsRoot, RUNNING_ICON);
 			URL backRoot = new URL(iconsRoot, BACKGROUND_ICON);
-
 			animatedData = manager.getImageData(runningRoot, runLoader);
 			if (animatedData != null)
-				JFaceResources.getImageRegistry().put(
-					ANIMATED_IMAGE_NAME,
-					manager.getImage(animatedData[0]));
-
+				JFaceResources.getImageRegistry().put(ANIMATED_IMAGE_NAME,
+						manager.getImage(animatedData[0]));
 			disabledData = manager.getImageData(backRoot, runLoader);
 			if (disabledData != null)
-				JFaceResources.getImageRegistry().put(
-					DISABLED_IMAGE_NAME,
-					manager.getImage(disabledData[0]));
-
+				JFaceResources.getImageRegistry().put(DISABLED_IMAGE_NAME,
+						manager.getImage(disabledData[0]));
 			listener = getProgressListener();
 			ProgressManager.getInstance().addListener(listener);
 		} catch (MalformedURLException exception) {
 			ProgressManagerUtil.logException(exception);
 		}
 	}
-
 	/**
 	 * Add an items to the list
 	 * @param item
@@ -124,7 +103,6 @@
 			}
 		});
 	}
-
 	/**
 	 * Get the current ImageData for the receiver.
 	 * @return ImageData[]
@@ -135,19 +113,16 @@
 		} else
 			return disabledData;
 	}
-
 	/**
 	 * Get the current Image for the receiver.
 	 * @return Image
 	 */
 	Image getImage() {
-
 		if (animated) {
 			return JFaceResources.getImageRegistry().get(ANIMATED_IMAGE_NAME);
 		} else
 			return JFaceResources.getImageRegistry().get(DISABLED_IMAGE_NAME);
 	}
-
 	/**
 	 * Return whether or not the current state is animated.
 	 * @return boolean
@@ -155,13 +130,11 @@
 	boolean isAnimated() {
 		return animated;
 	}
-
 	/**
 	 * Set whether or not the receiver is animated.
 	 * @param boolean
 	 */
 	void setAnimated(final boolean bool) {
-
 		animated = bool;
 		if (bool) {
 			ImageData[] imageDataArray = getImageData();
@@ -170,7 +143,6 @@
 			}
 		}
 	}
-
 	/**
 	 * Dispose the images in the receiver.
 	 */
@@ -178,7 +150,6 @@
 		setAnimated(false);
 		ProgressManager.getInstance().removeListener(listener);
 	}
-
 	/**
 	 * Loop through all of the images in a multi-image file
 	 * and display them one after another.
@@ -187,64 +158,39 @@
 	void animateLoop(IProgressMonitor monitor) {
 		// Create an off-screen image to draw on, and a GC to draw with.
 		// Both are disposed after the animation.
-
 		if (items.size() == 0)
 			return;
-
 		if (!PlatformUI.isWorkbenchRunning())
 			return;
-
 		AnimationItem[] animationItems = getAnimationItems();
-
 		Display display = PlatformUI.getWorkbench().getDisplay();
-
 		ImageData[] imageDataArray = getImageData();
 		ImageData imageData = imageDataArray[0];
 		Image image = ProgressManager.getInstance().getImage(imageData);
 		int imageDataIndex = 0;
-
 		ImageLoader loader = getLoader();
-
 		if (display.isDisposed()) {
 			monitor.setCanceled(true);
 			setAnimated(false);
 			return;
 		}
-
-		Image offScreenImage =
-			new Image(display, loader.logicalScreenWidth, loader.logicalScreenHeight);
+		Image offScreenImage = new Image(display, loader.logicalScreenWidth,
+				loader.logicalScreenHeight);
 		GC offScreenImageGC = new GC(offScreenImage);
-
 		try {
-
 			// Fill the off-screen image with the background color of the canvas.
 			offScreenImageGC.setBackground(background);
-			offScreenImageGC.fillRectangle(
-				0,
-				0,
-				loader.logicalScreenWidth,
-				loader.logicalScreenHeight);
-
+			offScreenImageGC.fillRectangle(0, 0, loader.logicalScreenWidth,
+					loader.logicalScreenHeight);
 			// Draw the current image onto the off-screen image.
-			offScreenImageGC.drawImage(
-				image,
-				0,
-				0,
-				imageData.width,
-				imageData.height,
-				imageData.x,
-				imageData.y,
-				imageData.width,
-				imageData.height);
-
+			offScreenImageGC.drawImage(image, 0, 0, imageData.width, imageData.height, imageData.x,
+					imageData.y, imageData.width, imageData.height);
 			if (loader.repeatCount > 0) {
 				while (isAnimated() && !monitor.isCanceled()) {
-
 					if (display.isDisposed()) {
 						monitor.setCanceled(true);
 						continue;
 					}
-
 					if (imageData.disposalMethod == SWT.DM_FILL_BACKGROUND) {
 						// Fill with the background color before drawing.
 						Color bgColor = null;
@@ -256,46 +202,25 @@
 						}
 						try {
 							offScreenImageGC.setBackground(bgColor != null ? bgColor : background);
-							offScreenImageGC.fillRectangle(
-								imageData.x,
-								imageData.y,
-								imageData.width,
-								imageData.height);
+							offScreenImageGC.fillRectangle(imageData.x, imageData.y,
+									imageData.width, imageData.height);
 						} finally {
 							if (bgColor != null)
 								bgColor.dispose();
 						}
 					} else if (imageData.disposalMethod == SWT.DM_FILL_PREVIOUS) {
 						// Restore the previous image before drawing.
-						offScreenImageGC.drawImage(
-							image,
-							0,
-							0,
-							imageData.width,
-							imageData.height,
-							imageData.x,
-							imageData.y,
-							imageData.width,
-							imageData.height);
+						offScreenImageGC.drawImage(image, 0, 0, imageData.width, imageData.height,
+								imageData.x, imageData.y, imageData.width, imageData.height);
 					}
-
 					// Get the next image data.
 					imageDataIndex = (imageDataIndex + 1) % imageDataArray.length;
 					imageData = imageDataArray[imageDataIndex];
 					image.dispose();
 					image = new Image(display, imageData);
-
 					// Draw the new image data.
-					offScreenImageGC.drawImage(
-						image,
-						0,
-						0,
-						imageData.width,
-						imageData.height,
-						imageData.x,
-						imageData.y,
-						imageData.width,
-						imageData.height);
+					offScreenImageGC.drawImage(image, 0, 0, imageData.width, imageData.height,
+							imageData.x, imageData.y, imageData.width, imageData.height);
 					boolean refreshItems = false;
 					for (int i = 0; i < animationItems.length; i++) {
 						AnimationItem item = animationItems[i];
@@ -307,7 +232,6 @@
 							item.imageCanvasGC.drawImage(offScreenImage, 0, 0);
 						}
 					}
-
 					if (refreshItems)
 						animationItems = getAnimationItems();
 					// Sleep for the specified delay time before drawing again.
@@ -316,7 +240,6 @@
 					} catch (InterruptedException e) {
 						//If it is interrupted end quietly
 					}
-
 				}
 			}
 		} finally {
@@ -326,7 +249,6 @@
 			animationDone();
 		}
 	}
-
 	/**
 	 * Get the animation items currently registered for the receiver.
 	 * @return
@@ -336,7 +258,6 @@
 		items.toArray(animationItems);
 		return animationItems;
 	}
-
 	/**
 	 * Return the specified number of milliseconds.
 	 * If the specified number of milliseconds is too small
@@ -351,7 +272,6 @@
 			return ms + 10;
 		return ms;
 	}
-
 	/**
 	 * Get the bounds of the image being displayed here.
 	 * @return Rectangle
@@ -359,20 +279,15 @@
 	public Rectangle getImageBounds() {
 		return JFaceResources.getImageRegistry().get(DISABLED_IMAGE_NAME).getBounds();
 	}
-
 	private IJobProgressManagerListener getProgressListener() {
 		return new IJobProgressManagerListener() {
-
 			HashSet jobs = new HashSet();
-
 			/* (non-Javadoc)
 			 * @see org.eclipse.ui.internal.progress.IJobProgressManagerListener#addJob(org.eclipse.ui.internal.progress.JobInfo)
 			 */
 			public void addJob(JobInfo info) {
 				incrementJobCount(info);
-
 			}
-			
 			/* (non-Javadoc)
 			 * @see org.eclipse.ui.internal.progress.IJobProgressManagerListener#refreshJobInfo(org.eclipse.ui.internal.progress.JobInfo)
 			 */
@@ -383,7 +298,6 @@
 				else
 					removeJob(info);
 			}
-
 			/* (non-Javadoc)
 			 * @see org.eclipse.ui.internal.progress.IJobProgressManagerListener#refreshAll()
 			 */
@@ -395,9 +309,7 @@
 				for (int i = 0; i < currentInfos.length; i++) {
 					addJob(currentInfos[i]);
 				}
-
 			}
-
 			/* (non-Javadoc)
 			 * @see org.eclipse.ui.internal.progress.IJobProgressManagerListener#remove(org.eclipse.ui.internal.progress.JobInfo)
 			 */
@@ -405,58 +317,46 @@
 				if (jobs.contains(info.getJob())) {
 					decrementJobCount(info.getJob());
 				}
-
 			}
-
 			/* (non-Javadoc)
 			 * @see org.eclipse.ui.internal.progress.IJobProgressManagerListener#showsDebug()
 			 */
 			public boolean showsDebug() {
 				return false;
 			}
-
 			private void incrementJobCount(JobInfo info) {
 				//Don't count the animate job itself
 				if (isNotTracked(info))
 					return;
-
 				if (jobs.isEmpty())
 					setAnimated(true);
 				jobs.add(info.getJob());
 			}
-
 			private void decrementJobCount(Job job) {
-
 				jobs.remove(job);
 				if (jobs.isEmpty())
 					setAnimated(false);
 			}
-
 			/** 
 			 * If this is one of our jobs or not running then don't bother.
 			 */
 			private boolean isNotTracked(JobInfo info) {
-
 				//We always track errors
 				Job job = info.getJob();
 				return job.getState() != Job.RUNNING || job == clearJob || job == animateJob;
 			}
-
 			/* (non-Javadoc)
 			 * @see org.eclipse.ui.internal.progress.IJobProgressManagerListener#addGroup(org.eclipse.ui.internal.progress.GroupInfo)
 			 */
 			public void addGroup(GroupInfo info) {
 				//Don't care about groups
-
 			}
-
 			/* (non-Javadoc)
 			 * @see org.eclipse.ui.internal.progress.IJobProgressManagerListener#removeGroup(org.eclipse.ui.internal.progress.GroupInfo)
 			 */
 			public void removeGroup(GroupInfo group) {
 				//Don't care about groups
 			}
-			
 			/* (non-Javadoc)
 			 * @see org.eclipse.ui.internal.progress.IJobProgressManagerListener#refreshGroup(org.eclipse.ui.internal.progress.GroupInfo)
 			 */
@@ -465,13 +365,12 @@
 			}
 		};
 	}
-
 	private Job getAnimateJob() {
 		if (animateJob == null) {
-				animateJob = new Job(ProgressMessages.getString("AnimateJob.JobName")) {//$NON-NLS-1$
-	/* (non-Javadoc)
-	 * @see org.eclipse.core.runtime.jobs.Job#run(org.eclipse.core.runtime.IProgressMonitor)
-	 */
+			animateJob = new Job(ProgressMessages.getString("AnimateJob.JobName")) {//$NON-NLS-1$
+				/* (non-Javadoc)
+				 * @see org.eclipse.core.runtime.jobs.Job#run(org.eclipse.core.runtime.IProgressMonitor)
+				 */
 				public IStatus run(IProgressMonitor monitor) {
 					try {
 						animationStarted();
@@ -481,13 +380,18 @@
 						return ProgressManagerUtil.exceptionStatus(exception);
 					}
 				}
-
 				/* (non-Javadoc)
 				 * @see org.eclipse.core.runtime.jobs.Job#shouldSchedule()
 				 */
 				public boolean shouldSchedule() {
 					return PlatformUI.isWorkbenchRunning();
 				}
+				/* (non-Javadoc)
+				 * @see org.eclipse.core.runtime.jobs.Job#shouldRun()
+				 */
+				public boolean shouldRun() {
+					return PlatformUI.isWorkbenchRunning();
+				}
 			};
 			animateJob.setSystem(true);
 			animateJob.setPriority(Job.DECORATE);
@@ -496,7 +400,6 @@
 				 * @see org.eclipse.core.runtime.jobs.JobChangeAdapter#done(org.eclipse.core.runtime.jobs.IJobChangeEvent)
 				 */
 				public void done(IJobChangeEvent event) {
-
 					//Only schedule the job if we are showing anything
 					if (isAnimated() && items.size() > 0)
 						animateJob.schedule();
@@ -508,20 +411,18 @@
 					}
 				}
 			});
-
 		}
 		return animateJob;
 	}
-
 	/**
 	 * Create the clear job if we haven't yet.
 	 * @return
 	 */
 	void createClearJob() {
-			clearJob = new UIJob(ProgressMessages.getString("AnimationItem.RedrawJob")) {//$NON-NLS-1$
-	/* (non-Javadoc)
-	* @see org.eclipse.ui.progress.UIJob#runInUIThread(org.eclipse.core.runtime.IProgressMonitor)
-	*/
+		clearJob = new UIJob(ProgressMessages.getString("AnimationItem.RedrawJob")) {//$NON-NLS-1$
+			/* (non-Javadoc)
+			 * @see org.eclipse.ui.progress.UIJob#runInUIThread(org.eclipse.core.runtime.IProgressMonitor)
+			 */
 			public IStatus runInUIThread(IProgressMonitor monitor) {
 				AnimationItem[] animationItems = getAnimationItems();
 				for (int i = 0; i < animationItems.length; i++)
@@ -533,7 +434,6 @@
 		clearJob.setSystem(true);
 		clearJob.setPriority(Job.DECORATE);
 	}
-
 	/**
 	 * Return the loader currently in use.
 	 * @return ImageLoader
@@ -541,18 +441,16 @@
 	ImageLoader getLoader() {
 		return runLoader;
 	}
-
 	/**
 	 * The animation is done. Get the items to clean up.
 	 */
 	private void animationDone() {
-
-			UIJob animationDoneJob = new WorkbenchJob(ProgressMessages.getString("AnimationManager.AnimationCleanUp")) {//$NON-NLS-1$
-	/* (non-Javadoc)
-	 * @see org.eclipse.ui.progress.UIJob#runInUIThread(org.eclipse.core.runtime.IProgressMonitor)
-	 */
+		UIJob animationDoneJob = new WorkbenchJob(ProgressMessages
+				.getString("AnimationManager.AnimationCleanUp")) {//$NON-NLS-1$
+			/* (non-Javadoc)
+			 * @see org.eclipse.ui.progress.UIJob#runInUIThread(org.eclipse.core.runtime.IProgressMonitor)
+			 */
 			public IStatus runInUIThread(IProgressMonitor monitor) {
-
 				AnimationItem[] animationItems = getAnimationItems();
 				for (int i = 0; i < animationItems.length; i++) {
 					AnimationItem item = animationItems[i];
@@ -563,21 +461,18 @@
 		};
 		animationDoneJob.setSystem(true);
 		animationDoneJob.schedule();
-
 	}
-
 	/**
 	 * The animation has started. Get the items to do any s
 	 * other start behaviour.
 	 */
 	private void animationStarted() {
-
-			UIJob animationDoneJob = new WorkbenchJob(ProgressMessages.getString("AnimationManager.AnimationStart")) {//$NON-NLS-1$
-	/* (non-Javadoc)
-	 * @see org.eclipse.ui.progress.UIJob#runInUIThread(org.eclipse.core.runtime.IProgressMonitor)
-	 */
+		UIJob animationDoneJob = new WorkbenchJob(ProgressMessages
+				.getString("AnimationManager.AnimationStart")) {//$NON-NLS-1$
+			/* (non-Javadoc)
+			 * @see org.eclipse.ui.progress.UIJob#runInUIThread(org.eclipse.core.runtime.IProgressMonitor)
+			 */
 			public IStatus runInUIThread(IProgressMonitor monitor) {
-
 				AnimationItem[] animationItems = getAnimationItems();
 				for (int i = 0; i < animationItems.length; i++) {
 					AnimationItem item = animationItems[i];
@@ -588,9 +483,7 @@
 		};
 		animationDoneJob.setSystem(true);
 		animationDoneJob.schedule();
-
 	}
-
 	/**
 	 * Get the preferred width for widgets displaying the 
 	 * animation.
@@ -601,7 +494,32 @@
 			return 0;
 		else
 			return animatedData[0].width;
-
 	}
-
+	/**
+	 * Return whether or not details are being shown.
+	 */
+	boolean showingDetails() {
+		return WorkbenchPlugin.getDefault().getPreferenceStore().getBoolean(
+				IPreferenceConstants.SHOW_FLOATING_PROGRESS);
+	}
+	/**
+	 * Toggle the floating windows for the receiver.
+	 */
+	public void toggleFloatingWindow() {
+		boolean detailsShowing = showingDetails();
+		
+		//Only both with windows if there are any
+		if (animated) {
+			AnimationItem[] animationItems = getAnimationItems();
+			for (int i = 0; i < animationItems.length; i++) {
+				AnimationItem item = animationItems[i];
+				if (detailsShowing)
+					item.closeFloatingWindow();
+				else
+					item.openFloatingWindow();
+			}
+		}
+		WorkbenchPlugin.getDefault().getPreferenceStore().setValue(
+				IPreferenceConstants.SHOW_FLOATING_PROGRESS, !detailsShowing);
+	}
 }
diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/progress/BlockedJobsDialog.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/progress/BlockedJobsDialog.java
index e3e6abd..a03f7a8 100644
--- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/progress/BlockedJobsDialog.java
+++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/progress/BlockedJobsDialog.java
@@ -9,7 +9,7 @@
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
 package org.eclipse.ui.internal.progress;
-
+import org.eclipse.core.runtime.IProgressMonitor;
 import org.eclipse.core.runtime.IStatus;
 import org.eclipse.jface.dialogs.Dialog;
 import org.eclipse.jface.dialogs.IconAndMessageDialog;
@@ -28,53 +28,54 @@
 import org.eclipse.swt.widgets.Composite;
 import org.eclipse.swt.widgets.Control;
 import org.eclipse.swt.widgets.Shell;
-
 /**
  * The BlockedJobsDialog class displays a dialog that provides information on the running jobs.
  */
 public class BlockedJobsDialog extends IconAndMessageDialog {
-
 	/**
 	 * The running jobs progress tree.
 	 * 
 	 * @see /org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/progress/ProgressTreeViewer.java (org.eclipse.ui.internal.progress)
 	 */
 	private ProgressTreeViewer viewer;
-
 	/**
 	 * Name to use for task when normal task name is empty string.
 	 */
-	private static String DEFAULT_TASKNAME = JFaceResources.getString("ProgressMonitorDialog.message"); //$NON-NLS-1$
-
+	private static String DEFAULT_TASKNAME = JFaceResources
+			.getString("ProgressMonitorDialog.message"); //$NON-NLS-1$
 	/**
 	 * The Cancel button control.
 	 */
-	protected Button cancel;
-
+	private Button cancelSelected;
 	/**
-	 * The cursor for the Cancel button.
+	 * The Cancel button control.
+	 */
+	private Button cancelBlocking;
+	/**
+	 * The cursor for the buttons.
 	 */
 	private Cursor arrowCursor;
-
 	/**
 	 * The cursor for the Shell.
 	 */
 	private Cursor waitCursor;
-
+	private IProgressMonitor blockingMonitor;
 	/**
 	 * Creates a progress monitor dialog under the given shell. It also sets the dialog's\ message. <code>open</code> is non-blocking.
 	 * 
 	 * @param parentShell
 	 *            The parent shell, or <code>null</code> to create a top-level shell.
+	 * @param blocking
+	 * 			The monitor that is blocking the job
 	 */
-	public BlockedJobsDialog(Shell parentShell) {
+	public BlockedJobsDialog(Shell parentShell, IProgressMonitor blocking) {
 		super(parentShell);
 		setMessage(DEFAULT_TASKNAME);
+		blockingMonitor = blocking;
 		setShellStyle(SWT.BORDER | SWT.TITLE | SWT.APPLICATION_MODAL);
 		// no close button
 		setBlockOnOpen(false);
 	}
-
 	/**
 	 * This method creates the dialog area under the parent composite.
 	 * 
@@ -88,17 +89,14 @@
 		setMessage(message);
 		createMessageArea(parent);
 		showJobDetails(parent);
-
 		return parent;
 	}
-
 	/* (non-Javadoc)
 	 * @see org.eclipse.jface.dialogs.IconAndMessageDialog#getMessageLabelStyle()
 	 */
 	protected int getMessageLabelStyle() {
 		return super.getMessageLabelStyle() | SWT.CENTER;
 	}
-
 	/**
 	 * This method creates a dialog area in the parent composite and displays a progress tree viewer of the running jobs.
 	 * 
@@ -106,12 +104,10 @@
 	 *            The parent Composite.
 	 */
 	void showJobDetails(Composite parent) {
-
-		viewer = new ProgressTreeViewer(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER);
-
+		viewer = new ProgressTreeViewer(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL
+				| SWT.BORDER);
 		viewer.setUseHashlookup(true);
 		viewer.setSorter(new ViewerSorter() {
-
 			/*
 			 * (non-Javadoc)
 			 * 
@@ -121,12 +117,10 @@
 				return ((Comparable) e1).compareTo(e2);
 			}
 		});
-
 		IContentProvider provider = new ProgressTreeContentProvider(viewer);
 		viewer.setContentProvider(provider);
 		viewer.setInput(provider);
 		viewer.setLabelProvider(new ProgressLabelProvider());
-
 		GridData data = new GridData();
 		data.horizontalSpan = 2;
 		int heightHint = convertHeightInCharsToPixels(10);
@@ -134,7 +128,6 @@
 		data.horizontalAlignment = GridData.FILL;
 		viewer.getControl().setLayoutData(data);
 	}
-	
 	/**
 	 * This method overrides the IconAndMessageDialog's method to create a Cancel button.
 	 * 
@@ -145,47 +138,54 @@
 	 * 			The parent Composite.
 	 */
 	protected Control createButtonBar(Composite parent) {
-		cancel = new Button(parent, SWT.PUSH);
-		cancel.setText(ProgressMessages.getString("CancelJobsButton.title")); //$NON-NLS-1$
-
-		cancel.addSelectionListener(new SelectionListener() {
-
-			public void widgetSelected(SelectionEvent e) {
-				ISelection selection = viewer.getSelection();
-				viewer.deleteJob(selection);
-
-			}
-
-			public void widgetDefaultSelected(SelectionEvent e) {
-				// Method used to set the default selection.
-			}
-
-		});
-
-		GridData data = new GridData();
-		data.horizontalSpan = 2;
-		data.horizontalAlignment = GridData.END;
-		data.verticalAlignment = GridData.END;
-		cancel.setLayoutData(data);
-
-		if (arrowCursor == null)
-			arrowCursor = new Cursor(cancel.getDisplay(), SWT.CURSOR_ARROW);
-		cancel.setCursor(arrowCursor);
+		cancelSelected = createButton(parent, ProgressMessages.getString("CancelJobsButton.title"), //$NON-NLS-1$
+				(new SelectionListener() {
+					public void widgetSelected(SelectionEvent e) {
+						ISelection selection = viewer.getSelection();
+						viewer.deleteJob(selection);
+					}
+					public void widgetDefaultSelected(SelectionEvent e) {
+						// Method used to set the default selection.
+					}
+				}));
+		
+		cancelBlocking = createButton(parent, ProgressMessages.getString("BlockedJobsDialog.CancelBlocking.title"), //$NON-NLS-1$
+				(new SelectionListener() {
+					public void widgetSelected(SelectionEvent e) {
+						blockingMonitor.setCanceled(true);
+						cancelBlocking.setEnabled(false);
+					}
+					public void widgetDefaultSelected(SelectionEvent e) {
+						// Method used to set the default selection.
+					}
+				}));
 		
 		return parent;
 	}
-
 	/**
-	 * This method clears the cursors in the dialog.
+	 * Create a button with the supplied parameters.
+	 * @param parent
+	 * @param text
+	 * @param listener
+	 * @return
 	 */
-	protected void clearCursors() {
-		if (cancel != null && !cancel.isDisposed()) {
-			cancel.setCursor(null);
-		}
-		Shell shell = getShell();
-		if (shell != null && !shell.isDisposed()) {
-			shell.setCursor(null);
-		}
+	private Button createButton(Composite parent, String text, SelectionListener listener) {
+		Button button = new Button(parent, SWT.PUSH);
+		button.setText(text); //$NON-NLS-1$
+		button.addSelectionListener(listener);
+		
+		if (arrowCursor == null)
+			arrowCursor = new Cursor(button.getDisplay(), SWT.CURSOR_ARROW);
+		button.setCursor(arrowCursor);
+		return button;
+	}
+	/**
+	 * Clear the cursors in the dialog.
+	 */
+	private void clearCursors() {
+		clearCursor(cancelBlocking);
+		clearCursor(cancelSelected);
+		clearCursor(getShell());
 		if (arrowCursor != null)
 			arrowCursor.dispose();
 		if (waitCursor != null)
@@ -193,7 +193,15 @@
 		arrowCursor = null;
 		waitCursor = null;
 	}
-
+	/**
+	 * Clear the cursor on the supplied control.
+	 * @param control
+	 */
+	private void clearCursor(Control control) {
+		if (control != null && !control.isDisposed()) {
+			control.setCursor(null);
+		}
+	}
 	/**
 	 * This method complements the Window's class' configureShell method by adding a title, and setting
 	 * the appropriate cursor.
@@ -210,8 +218,6 @@
 			waitCursor = new Cursor(shell.getDisplay(), SWT.CURSOR_WAIT);
 		shell.setCursor(waitCursor);
 	}
-
-
 	/**
 	 * This method sets the message in the message label.
 	 */
@@ -222,14 +228,12 @@
 			return;
 		messageLabel.setText(message);
 	}
-
 	/**
 	 * This method returns the dialog's lock image.
 	 */
 	protected Image getImage() {
 		return JFaceResources.getImageRegistry().get(Dialog.DLG_IMG_LOCKED);
 	}
-
 	/**
 	 * This method sets the dialog's message status.
 	 * 
@@ -241,5 +245,11 @@
 	public void setStatus(IStatus reason) {
 		setMessage(reason.getMessage());
 	}
-
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.dialogs.Dialog#close()
+	 */
+	public boolean close() {
+		clearCursors();
+		return super.close();
+	}
 }
diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/progress/ProgressFloatingWindow.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/progress/ProgressFloatingWindow.java
index ce08827..745aa87 100644
--- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/progress/ProgressFloatingWindow.java
+++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/progress/ProgressFloatingWindow.java
@@ -39,7 +39,6 @@
 class ProgressFloatingWindow extends AssociatedWindow {
 	TableViewer viewer;
 	WorkbenchWindow window;
-	private int maxSize = 500;
 	/**
 	 * Create a new instance of the receiver.
 	 * 
@@ -50,7 +49,12 @@
 			Control associatedControl) {
 		super(workbenchWindow.getShell(), associatedControl);
 		this.window = workbenchWindow;
-		setShellStyle(SWT.RESIZE);
+		
+		//Workaround for Bug 50917
+		if("carbon".equals(SWT.getPlatform())) //$NON-NLS-1$
+			setShellStyle(SWT.NO_TRIM | SWT.ON_TOP );
+		else
+			setShellStyle(SWT.NO_TRIM);
 	}
 	/*
 	 * (non-Javadoc)
@@ -98,7 +102,7 @@
 		setBackground(viewer.getControl());
 		FormData tableData = new FormData();
 		tableData.left = new FormAttachment(0);
-		tableData.right = new FormAttachment(100);
+		tableData.right = new FormAttachment(buttonBar,0);
 		tableData.top = new FormAttachment(0);
 		viewer.getTable().setLayoutData(tableData);
 		initContentProvider();
@@ -112,7 +116,7 @@
 	 */
 	private LabelProvider viewerLabelProvider() {
 		return new LabelProvider() {
-			private String ellipsis = "...";
+			private String ellipsis = ProgressMessages.getString("ProgressFloatingWindow.EllipsisValue"); //$NON-NLS-1$
 			/*
 			 * (non-Javadoc)
 			 * 
@@ -170,8 +174,7 @@
 		size.y += 5;
 		int maxSize = getMaximumSize(viewer.getTable().getDisplay());
 		if (size.x > maxSize)
-			;
-		size.x = maxSize;
+			size.x = maxSize;
 		getShell().setSize(size);
 		moveShell(getShell());
 		setRegion();
@@ -294,7 +297,7 @@
 			}
 		});
 		
-		minimize.setToolTipText("Close progress window");
+		minimize.setToolTipText(ProgressMessages.getString("ProgressFloatingWindow.CloseToolTip")); //$NON-NLS-1$
 		
 		ToolItem maximize = new ToolItem(buttonBar, SWT.NONE);
 		maximize
@@ -310,7 +313,7 @@
 			}
 		});
 		
-		maximize.setToolTipText("Open progress view");
+		maximize.setToolTipText(ProgressMessages.getString("ProgressFloatingWindow.OpenToolTip")); //$NON-NLS-1$
 		
 		FormData barData = new FormData();
 		barData.right = new FormAttachment(100);
diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/progress/ProgressManagerUtil.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/progress/ProgressManagerUtil.java
index 00e17de..80535fc 100644
--- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/progress/ProgressManagerUtil.java
+++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/progress/ProgressManagerUtil.java
@@ -23,7 +23,7 @@
  * the progress API.
  */
 class ProgressManagerUtil {
-	private static String PROGRESS_VIEW_ID = "org.eclipse.ui.views.ProgressView";
+	private static String PROGRESS_VIEW_ID = "org.eclipse.ui.views.ProgressView"; //$NON-NLS-1$
 	/**
 	 * Return a status for the exception.
 	 * 
diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/progress/ProgressView.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/progress/ProgressView.java
index d79edc3..32b0bf6 100644
--- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/progress/ProgressView.java
+++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/progress/ProgressView.java
@@ -117,6 +117,15 @@
 			}
 
 		});
+		
+		menuMgr.add(new Action(ProgressMessages.getString("ProgressView.ToggleWindowMessage")){ //$NON-NLS-1$
+			/* (non-Javadoc)
+			 * @see org.eclipse.jface.action.Action#run()
+			 */
+			public void run() {
+				AnimationManager.getInstance().toggleFloatingWindow();
+			}
+		});
 
 	}
 
diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/progress/messages.properties b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/progress/messages.properties
index c5ea8d1..d092de3 100644
--- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/progress/messages.properties
+++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/progress/messages.properties
@@ -31,7 +31,8 @@
 ProgressFeedbackDialog.DialogTitle=Jobs Awaiting Progress
 
 ProgressManager.openJobName=Open progress monitor
-CancelJobsButton.title = Cancel Selected Job(s)
+CancelJobsButton.title = Cancel &Selected
+BlockedJobsDialog.CancelBlocking.title=Cancel &Blocked
 
 MonitorProvider.oneValueMessage = {0}: {1}% done
 MonitorProvider.twoValueMessage = {0}: {1}: {2}% done
@@ -46,3 +47,8 @@
 AnimationItem.openFloatingWindowJob=Open Floating Window
 AnimationManager.AnimationCleanUp=Animation cleanup
 AnimationManager.AnimationStart=Animation start
+ProgressView.ToggleWindowMessage=&Toggle Floating Window
+ProgressFloatingWindow.EllipsisValue=...
+ProgressFloatingWindow.CloseToolTip=Close progress window
+ProgressFloatingWindow.OpenToolTip=Open progress view
+
diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/registry/IViewDescriptor.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/registry/IViewDescriptor.java
index a58b0c2..af6e403 100644
--- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/registry/IViewDescriptor.java
+++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/registry/IViewDescriptor.java
@@ -78,4 +78,11 @@
  */
 public float getFastViewWidthRatio(); 
 
+/**
+ * Returns whether this view allows multiple instances.
+ * 
+ * @since 3.0
+ */
+public boolean getAllowMultiple();
+
 }
diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/registry/PerspectiveDescriptor.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/registry/PerspectiveDescriptor.java
index 65584f6..9d9723d 100644
--- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/registry/PerspectiveDescriptor.java
+++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/registry/PerspectiveDescriptor.java
@@ -48,6 +48,8 @@
 	private String className;
 	private String description;
 	private boolean singleton;
+	private boolean fixed;
+	private String theme;
 	private ImageDescriptor image;
 	private IConfigurationElement configElement;
 	
@@ -57,6 +59,8 @@
 	private static final String ATT_ICON="icon";//$NON-NLS-1$
 	private static final String ATT_CLASS="class";//$NON-NLS-1$
 	private static final String ATT_SINGLETON="singleton";//$NON-NLS-1$
+	private static final String ATT_THEME="theme";//$NON-NLS-1$
+	private static final String ATT_FIXED="fixed";//$NON-NLS-1$
 	
 /**
  * Create a new empty descriptor.
@@ -83,6 +87,12 @@
 	label = configElement.getAttribute(ATT_NAME);
 	className = configElement.getAttribute(ATT_CLASS);
 	singleton = (configElement.getAttributeAsIs(ATT_SINGLETON) != null);
+	
+	String str = configElement.getAttribute(ATT_FIXED);
+	if (str != null && str.equalsIgnoreCase("true"))//$NON-NLS-1$
+		fixed = true;
+		
+	theme = configElement.getAttribute(ATT_THEME);
 	description = desc;
 
 	// Sanity check.
@@ -132,6 +142,13 @@
 	return description;
 }
 /**
+ * Returns whether or not this perspective
+ * is fixed.
+ */
+public boolean getFixed() {
+	return fixed;
+}
+/**
  * Returns the ID.
  */
 public String getId() {
@@ -157,6 +174,12 @@
 	return originalId;
 }
 /**
+ * Returns the theme id.
+ */
+public String getTheme() {
+	return theme;
+}
+/**
  * Returns true if this perspective has a custom file.
  */
 public boolean hasCustomDefinition() {
@@ -197,6 +220,7 @@
 		label = childMem.getString(IWorkbenchConstants.TAG_LABEL);
 		className = childMem.getString(IWorkbenchConstants.TAG_CLASS);
 		singleton = (childMem.getInteger(IWorkbenchConstants.TAG_SINGLETON) != null);
+		theme = childMem.getString(IWorkbenchConstants.TAG_THEME);		
 	
 		//Find a descriptor in the registry.
 		PerspectiveDescriptor descriptor = (PerspectiveDescriptor)WorkbenchPlugin.getDefault().
@@ -228,6 +252,8 @@
 	childMem.putString(IWorkbenchConstants.TAG_CLASS,className);
 	if (singleton)
 		childMem.putInteger(IWorkbenchConstants.TAG_SINGLETON, 1);
+	if (theme != null)
+		childMem.putString(IWorkbenchConstants.TAG_THEME,theme);	
 	return new Status(IStatus.OK,PlatformUI.PLUGIN_ID,0,"",null); //$NON-NLS-1$
 }
 
diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/registry/PreferencePageRegistryReader.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/registry/PreferencePageRegistryReader.java
index 4d95ce7..143ce22 100644
--- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/registry/PreferencePageRegistryReader.java
+++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/registry/PreferencePageRegistryReader.java
@@ -249,6 +249,14 @@
 	protected boolean readElement(IConfigurationElement element) {
 		if (element.getName().equals(TAG_PAGE) == false)
 			return false;
+		WorkbenchPreferenceNode node = createNode(workbench, element);
+		if (node != null)
+			nodes.add(node);
+		readElementChildren(element);
+		return true;
+	}
+	
+	public static WorkbenchPreferenceNode createNode(IWorkbench workbench, IConfigurationElement element) {
 		String name = element.getAttribute(ATT_NAME);
 		String id = element.getAttribute(ATT_ID);
 		String category = element.getAttribute(ATT_CATEGORY);
@@ -264,31 +272,29 @@
 			logMissingAttribute(element, ATT_CLASS);
 		}
 		if (name == null || id == null || className == null) {
-			return true;
+			return null;
 		}
 		ImageDescriptor image = null;
 		if (imageName != null) {
 			String contributingPluginId =
 				element
-					.getDeclaringExtension()
-					.getDeclaringPluginDescriptor()
-					.getUniqueIdentifier();
+				.getDeclaringExtension()
+				.getDeclaringPluginDescriptor()
+				.getUniqueIdentifier();
 			image =
 				AbstractUIPlugin.imageDescriptorFromPlugin(
-					contributingPluginId,
-					imageName);
+						contributingPluginId,
+						imageName);
 		}
 		WorkbenchPreferenceNode node =
 			new WorkbenchPreferenceNode(
-				id,
-				name,
-				category,
-				image,
-				element,
-				workbench);
-		nodes.add(node);
-		readElementChildren(element);
-		return true;
+					id,
+					name,
+					category,
+					image,
+					element,
+					workbench);
+		return node;		
 	}
 	
 	/**
diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/registry/PropertyPagesRegistryReader.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/registry/PropertyPagesRegistryReader.java
index 7f6ef0c..a46d85d 100644
--- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/registry/PropertyPagesRegistryReader.java
+++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/registry/PropertyPagesRegistryReader.java
@@ -105,8 +105,10 @@
 }
 /**
  * Reads the next contribution element.
+ * 
+ * public for dynamic UI
  */
-protected boolean readElement(IConfigurationElement element) {
+public boolean readElement(IConfigurationElement element) {
 	if (element.getName().equals(TAG_PAGE)) {
 		processPageElement(element);
 		readElementChildren(element);
diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/registry/RegistryReader.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/registry/RegistryReader.java
index 813c6af..eaec86e 100644
--- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/registry/RegistryReader.java
+++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/registry/RegistryReader.java
@@ -62,7 +62,7 @@
  * Logs the error in the workbench log using the provided
  * text and the information in the configuration element.
  */
-protected void logError(IConfigurationElement element, String text) {
+protected static void logError(IConfigurationElement element, String text) {
 	IExtension extension = element.getDeclaringExtension();
 	IPluginDescriptor descriptor = extension.getDeclaringPluginDescriptor();
 	StringBuffer buf = new StringBuffer();
@@ -73,21 +73,21 @@
 /**
  * Logs a very common registry error when a required attribute is missing.
  */
-protected void logMissingAttribute(IConfigurationElement element, String attributeName) {
+protected static void logMissingAttribute(IConfigurationElement element, String attributeName) {
 	logError(element, "Required attribute '"+attributeName+"' not defined");//$NON-NLS-2$//$NON-NLS-1$
 }
 
 /**
  * Logs a very common registry error when a required child is missing.
  */
-protected void logMissingElement(IConfigurationElement element, String elementName) {
+protected static void logMissingElement(IConfigurationElement element, String elementName) {
 	logError(element, "Required sub element '"+elementName+"' not defined");//$NON-NLS-2$//$NON-NLS-1$
 }
 
 /**
  * Logs a registry error when the configuration element is unknown.
  */
-protected void logUnknownElement(IConfigurationElement element) {
+protected static void logUnknownElement(IConfigurationElement element) {
 	logError(element, "Unknown extension tag found: " + element.getName());//$NON-NLS-1$
 }
 /**
diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/registry/ViewDescriptor.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/registry/ViewDescriptor.java
index bac9026..cbbfe49 100644
--- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/registry/ViewDescriptor.java
+++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/registry/ViewDescriptor.java
@@ -40,6 +40,7 @@
 	private static final String ATT_CATEGORY = "category"; //$NON-NLS-1$
 	private static final String ATT_CLASS = "class"; //$NON-NLS-1$
 	private static final String ATT_RATIO = "fastViewWidthRatio"; //$NON-NLS-1$
+	private static final String ATT_MULTIPLE = "allowMultiple"; //$NON-NLS-1$
 	private String label;
 	private String accelerator;
 	private String className;
@@ -47,6 +48,7 @@
 	private String[] categoryPath;
 	private String description;
 	private float fastViewWidthRatio;
+	private boolean allowMultiple;
     
 	/**
 	 * Create a new ViewDescriptor for an extension.
@@ -156,7 +158,8 @@
 		className = configElement.getAttribute(ATT_CLASS);
 		String category = configElement.getAttribute(ATT_CATEGORY);
 		String ratio = configElement.getAttribute(ATT_RATIO);
-
+		String mult = configElement.getAttribute(ATT_MULTIPLE);
+		
 		// Sanity check.
 		if ((label == null) || (className == null)) {
 			throw new CoreException(new Status(IStatus.ERROR, configElement.getDeclaringExtension().getDeclaringPluginDescriptor().getUniqueIdentifier(), 0, "Invalid extension (missing label or class name): " + id, //$NON-NLS-1$
@@ -184,6 +187,7 @@
 		} else {
 			fastViewWidthRatio = IPageLayout.DEFAULT_FASTVIEW_RATIO;
 		}
+		allowMultiple = mult != null && "true".equalsIgnoreCase(mult); //$NON-NLS-1$
 	}
 	/**
 	 * Returns a string representation of this descriptor. For debugging
@@ -219,4 +223,11 @@
 	public boolean fromPlugin() {
 		return true;
 	}
+
+    /* (non-Javadoc)
+     * @see org.eclipse.ui.internal.registry.IViewDescriptor#getAllowMultiple()
+     */
+    public boolean getAllowMultiple() {
+        return allowMultiple;
+    }
 }
diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/util/StatusLineContributionItem.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/util/StatusLineContributionItem.java
index 37cc778..a4fd534 100644
--- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/util/StatusLineContributionItem.java
+++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/util/StatusLineContributionItem.java
@@ -30,6 +30,12 @@
 
 	private int charWidth;
 	private CLabel label;
+	/**
+	 * The composite into which this contribution item has been placed. This
+	 * will be <code>null</code> if this instance has not yet been
+	 * initialized.
+	 */
+	private Composite statusLine = null;
 	private String text = Util.ZERO_LENGTH_STRING;
 	private int widthHint = -1;
 
@@ -44,17 +50,13 @@
 	}
 
 	public void fill(Composite parent) {
-		label = new CLabel(parent, SWT.NONE); //SWT.SHADOW_IN);
+		statusLine = parent;
+		label = new CLabel(statusLine, SWT.SHADOW_IN);
 		StatusLineLayoutData statusLineLayoutData = new StatusLineLayoutData();
-//		Color[] colors = new Color[2];
-//		colors[0] = parent.getDisplay().getSystemColor(SWT.COLOR_WIDGET_LIGHT_SHADOW);
-//		colors[1] = label.getBackground();
-//		int[] gradient = new int[] { JFaceColors.STATUS_PERCENT };
-//		label.setBackground(colors, gradient);
 
 		if (widthHint < 0) {
-			GC gc = new GC(parent);
-			gc.setFont(parent.getFont());
+			GC gc = new GC(statusLine);
+			gc.setFont(statusLine.getFont());
 			widthHint = gc.getFontMetrics().getAverageCharWidth() * charWidth;
 			gc.dispose();
 		}
@@ -72,12 +74,13 @@
 	 *         not yet initialized.
 	 */
 	public Point getDisplayLocation() {
-		if ((label != null)) {
-			return label.getLocation();
+		if ((label != null) && (statusLine != null)) {
+			return statusLine.toDisplay(label.getLocation());
 		}
 
 		return null;
 	}
+
 	public String getText() {
 		return text;
 	}
diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/part/intro/IntroPart.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/part/intro/IntroPart.java
index d3eeeed..df420bb 100644
--- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/part/intro/IntroPart.java
+++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/part/intro/IntroPart.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2003 IBM Corporation and others.
+ * Copyright (c) 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
diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/plugin/AbstractUIPlugin.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/plugin/AbstractUIPlugin.java
index d85a073..d1d9911 100644
--- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/plugin/AbstractUIPlugin.java
+++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/plugin/AbstractUIPlugin.java
@@ -497,6 +497,13 @@
 	public AbstractUIPlugin(IPluginDescriptor descriptor) {
 		super(descriptor);
 	}
+	
+	/*
+	 * @see Plugin()
+	 */
+	public AbstractUIPlugin() {
+		super();
+	}
 
 	/** 
 	 * Returns a new image registry for this plugin-in.  The registry will be
@@ -866,4 +873,5 @@
 			return null;
 		}
 	}
+	
 }