/*******************************************************************************
 * 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.jface.action;

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;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.CoolBar;
import org.eclipse.swt.widgets.CoolItem;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Menu;

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.
 * <p>
 * This class may be instantiated; it may also be subclassed.
 * </p>
 * 
 * @see #ICoolBarManager
 * @since 3.0
 */
public class CoolBarManager extends ContributionManager implements
        ICoolBarManager {

    /**
     * A separator created by the end user.
     */
    public final static String USER_SEPARATOR = "UserSeparator"; //$NON-NLS-1$

    /**
     * The original creation order of the contribution items.
     */
    private ArrayList cbItemsCreationOrder = new ArrayList();

    /**
     * MenuManager for cool bar pop-up menu, or null if none.
     */
    private MenuManager contextMenuManager = null;

    /**
     * The cool bar control; <code>null</code> before creation and after
     * disposal.
     */
    private CoolBar coolBar = null;

    /**
     * The cool bar items style; <code>SWT.NONE</code> by default.
     */
    private int itemStyle = SWT.NONE;

    /**
     * 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() //$NON-NLS-1$
                        + " - is Visible: " //$NON-NLS-1$
                        + 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 {
            coolBar.setRedraw(false);

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

            // 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++;
                        sourceItem.update();
                        continue;

                    } else if ((destinationItem.isSeparator())
                            && (sourceItem.isSeparator())) {
                        coolItems[sourceIndex].setData(sourceItem);
                        sourceIndex++;
                        destinationIndex++;
                        sourceItem.update();
                        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;
                }
            }

            // Update wrap indices.
            updateWrapIndices();

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

            }
        }
    }

    private void updateWrapIndices() {
        final IContributionItem[] items = getItems();
        final int numRows = getNumRows(items) - 1;

        // Generate the list of wrap indices.
        final int[] wrapIndices = new int[numRows];
        boolean foundSeparator = false;
        int j = 0;
        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;
            }
        }

        /*
         * Check to see if these new wrap indices are different than the old
         * ones.
         */
        final int[] oldIndices = coolBar.getWrapIndices();
        boolean shouldUpdate = false;
        if (oldIndices.length == wrapIndices.length) {
            for (int i = 0; i < oldIndices.length; i++) {
                if (oldIndices[i] != wrapIndices[i]) {
                    shouldUpdate = true;
                    break;
                }
            }
        } else {
            shouldUpdate = true;
        }

        if (shouldUpdate) {
            coolBar.setWrapIndices(wrapIndices);
        }
    }
}
