/*******************************************************************************
 * Copyright (c) 2000, 2005 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *        IBM Corporation - initial API and implementation
 *        Sebastian Davids <sdavids@gmx.de> - Fix for bug 19346 - Dialog font should be
 *        activated and used by other components.
 *******************************************************************************/
package org.eclipse.ui.internal.ide.misc;

import java.text.Collator;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Map;

import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.viewers.CheckStateChangedEvent;
import org.eclipse.jface.viewers.CheckboxTableViewer;
import org.eclipse.jface.viewers.ICheckStateListener;
import org.eclipse.jface.viewers.IContentProvider;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.ListViewer;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.Image;
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.Text;
import org.eclipse.ui.internal.ide.Category;
import org.eclipse.ui.internal.ide.IDEWorkbenchMessages;
import org.eclipse.ui.internal.ide.registry.Capability;
import org.eclipse.ui.internal.ide.registry.CapabilityRegistry;
import org.eclipse.ui.model.WorkbenchContentProvider;
import org.eclipse.ui.model.WorkbenchLabelProvider;

/**
 * A group of controls used to view and modify the
 * set of capabilities on a project.
 */
public class ProjectCapabilitySelectionGroup {
    private static final String EMPTY_DESCRIPTION = "\n\n\n"; //$NON-NLS-1$

    private CapabilityRegistry registry;

    private Category[] initialCategories;

    private Capability[] initialCapabilities;

    private Capability[] disabledCapabilities;

    private boolean modified = false;

    private Text descriptionText;

    private CheckboxTableViewer checkboxViewer;

    private ICheckStateListener checkStateListener;

    private ArrayList visibleCapabilities = new ArrayList();

    private ArrayList checkedCapabilities = new ArrayList();

    private Collection disabledCaps;

    // For a given capability as key, the value will be a list of
    // other capabilities that require the capability. Also,
    // it may include the capability key if it was selected by the
    // user before being required by other capabilities.
    private HashMap dependents = new HashMap();

    // For a given membership set id as key, the value is
    // a checked capability
    private HashMap memberships = new HashMap();

    // Sort categories
    private Comparator categoryComparator = new Comparator() {
        private Collator collator = Collator.getInstance();

        public int compare(Object ob1, Object ob2) {
            Category c1 = (Category) ob1;
            Category c2 = (Category) ob2;
            return collator.compare(c1.getLabel(), c2.getLabel());
        }
    };

    // Sort capabilities
    private Comparator capabilityComparator = new Comparator() {
        private Collator collator = Collator.getInstance();

        public int compare(Object ob1, Object ob2) {
            Capability c1 = (Capability) ob1;
            Capability c2 = (Capability) ob2;
            return collator.compare(c1.getName(), c2.getName());
        }
    };

    /**
     * Creates a new instance of the <code>ProjectCapabilitySelectionGroup</code>
     * 
     * @param categories the initial collection of valid categories to select
     * @param capabilities the intial collection of valid capabilities to select
     * @param registry all available capabilities registered by plug-ins
     */
    public ProjectCapabilitySelectionGroup(Category[] categories,
            Capability[] capabilities, CapabilityRegistry registry) {
        this(categories, capabilities, null, registry);
    }

    /**
     * Creates a new instance of the <code>ProjectCapabilitySelectionGroup</code>
     * 
     * @param categories the initial collection of valid categories to select
     * @param capabilities the intial collection of valid capabilities to select
     * @param disabledCapabilities the collection of capabilities to show as disabled
     * @param registry all available capabilities registered by plug-ins
     */
    public ProjectCapabilitySelectionGroup(Category[] categories,
            Capability[] capabilities, Capability[] disabledCapabilities,
            CapabilityRegistry registry) {
        super();
        this.initialCategories = categories;
        this.initialCapabilities = capabilities;
        this.disabledCapabilities = disabledCapabilities;
        this.registry = registry;
    }

    /**
     * Create the contents of this group. The basic layout is a checkbox
     * list with a text field at the bottom to display the capability
     * description.
     */
    public Control createContents(Composite parent) {
        Font font = parent.getFont();
        // Create the main composite for the other controls
        Composite composite = new Composite(parent, SWT.NONE);
        GridLayout layout = new GridLayout();
        layout.numColumns = 2;
        layout.makeColumnsEqualWidth = true;
        composite.setLayout(layout);
        composite.setLayoutData(new GridData(GridData.FILL_BOTH));

        // Composite for category label and list...
        Composite catComposite = new Composite(composite, SWT.NONE);
        catComposite.setLayout(new GridLayout());
        catComposite.setLayoutData(new GridData(GridData.FILL_BOTH));

        // Add a label to identify the list viewer of categories
        Label categoryLabel = new Label(catComposite, SWT.LEFT);
        categoryLabel.setText(IDEWorkbenchMessages.ProjectCapabilitySelectionGroup_categories);
        GridData data = new GridData();
        data.verticalAlignment = SWT.TOP;
        categoryLabel.setLayoutData(data);
        categoryLabel.setFont(font);

        // List viewer of all available categories
        ListViewer listViewer = new ListViewer(catComposite);
        listViewer.getList().setLayoutData(new GridData(GridData.FILL_BOTH));
        listViewer.getList().setFont(font);
        listViewer.setLabelProvider(new WorkbenchLabelProvider());
        listViewer.setContentProvider(getContentProvider());
        listViewer.setInput(getAvailableCategories());

        // Composite for capability label and table...
        Composite capComposite = new Composite(composite, SWT.NONE);
        capComposite.setLayout(new GridLayout());
        capComposite.setLayoutData(new GridData(GridData.FILL_BOTH));

        // Add a label to identify the checkbox tree viewer of capabilities
        Label capabilityLabel = new Label(capComposite, SWT.LEFT);
        capabilityLabel.setText(IDEWorkbenchMessages.ProjectCapabilitySelectionGroup_capabilities);
        data = new GridData();
        data.verticalAlignment = SWT.TOP;
        capabilityLabel.setLayoutData(data);
        capabilityLabel.setFont(font);

        // Checkbox tree viewer of capabilities in selected categories
        checkboxViewer = CheckboxTableViewer.newCheckList(capComposite,
                SWT.SINGLE | SWT.TOP | SWT.BORDER);
        checkboxViewer.getTable().setLayoutData(
                new GridData(GridData.FILL_BOTH));
        checkboxViewer.getTable().setFont(font);
        checkboxViewer.setLabelProvider(new CapabilityLabelProvider());
        checkboxViewer.setContentProvider(getContentProvider());
        checkboxViewer.setInput(visibleCapabilities);

        // Add a label to identify the text field of capability's description
        Label descLabel = new Label(composite, SWT.LEFT);
        descLabel.setText(IDEWorkbenchMessages.ProjectCapabilitySelectionGroup_description);
        data = new GridData();
        data.verticalAlignment = SWT.TOP;
        data.horizontalSpan = 2;
        descLabel.setLayoutData(data);
        descLabel.setFont(font);

        // Text field to display the capability's description
        descriptionText = new Text(composite, SWT.WRAP | SWT.MULTI
                | SWT.V_SCROLL | SWT.BORDER);
        descriptionText.setText(EMPTY_DESCRIPTION);
        descriptionText.setEditable(false);
        data = new GridData();
        data.horizontalAlignment = GridData.FILL;
        data.grabExcessHorizontalSpace = true;
        data.horizontalSpan = 2;
        descriptionText.setLayoutData(data);
        descriptionText.setFont(font);

        // Add a text field to explain grayed out items
        Label grayLabel = new Label(composite, SWT.LEFT);
        grayLabel.setText(IDEWorkbenchMessages.ProjectCapabilitySelectionGroup_grayItems);
        data = new GridData();
        data.verticalAlignment = SWT.TOP;
        data.horizontalSpan = 2;
        grayLabel.setLayoutData(data);
        grayLabel.setFont(font);

        // Setup initial context		
        populateDependents();
        populateMemberships();

        // Listen for selection changes to update the description field
        checkboxViewer
                .addSelectionChangedListener(new ISelectionChangedListener() {
                    public void selectionChanged(SelectionChangedEvent event) {
                        updateDescription(event.getSelection());
                    }
                });

        // Properly handle user checking and unchecking project features
        checkboxViewer.addCheckStateListener(new ICheckStateListener() {
            public void checkStateChanged(CheckStateChangedEvent event) {
                Capability cap = (Capability) event.getElement();
                if (event.getChecked())
                    handleCapabilityChecked(cap);
                else
                    handleCapabilityUnchecked(cap);
                checkboxViewer.setSelection(new StructuredSelection(cap));
            }
        });

        // Listen for category selection and update the list of capabilities
        listViewer.addSelectionChangedListener(new ISelectionChangedListener() {
            public void selectionChanged(SelectionChangedEvent event) {
                if (event.getSelection() instanceof IStructuredSelection) {
                    IStructuredSelection sel = (IStructuredSelection) event
                            .getSelection();
                    visibleCapabilities.clear();
                    Iterator itr = sel.iterator();
                    while (itr.hasNext()) {
                        Category cat = (Category) itr.next();
                        visibleCapabilities.addAll(cat.getElements());
                    }
                    Collections.sort(visibleCapabilities, capabilityComparator);
                    checkboxViewer.refresh();
                    itr = visibleCapabilities.iterator();
                    while (itr.hasNext()) {
                        Capability cap = (Capability) itr.next();
                        if (hasDependency(cap))
                            checkboxViewer.setGrayed(cap, true);
                        if (checkedCapabilities.contains(cap))
                            checkboxViewer.setChecked(cap, true);
                    }
                    updateDescription(checkboxViewer.getSelection());
                }
            }
        });

        // initialize
        if (initialCapabilities != null)
            checkedCapabilities.addAll(Arrays.asList(initialCapabilities));
        if (initialCategories != null)
            listViewer.setSelection(new StructuredSelection(initialCategories));

        return composite;
    }

    /**
     * Marks the capability as being checked.
     */
    private void markCapabilityChecked(Capability target, Capability dependent) {
        // Check the target capability
        if (!checkedCapabilities.contains(target))
            checkedCapabilities.add(target);
        checkboxViewer.setChecked(target, true);

        // Gray the target to show the user its required
        // by another capability.
        if (target != dependent)
            checkboxViewer.setGrayed(target, true);

        // Update the dependent map for the target capability
        addDependency(target, dependent);

        // Update the membership set for the target capability
        String[] ids = registry.getMembershipSetIds(target);
        for (int j = 0; j < ids.length; j++)
            memberships.put(ids[j], target);
    }

    /**
     * Marks the capability as being unchecked.
     */
    private void markCapabilityUnchecked(Capability target) {
        // Uncheck the target capability
        checkedCapabilities.remove(target);
        checkboxViewer.setChecked(target, false);

        // Ungray the target as there is no dependency on it
        checkboxViewer.setGrayed(target, false);

        // Remove the dependency entry
        dependents.remove(target);

        // Update the membership set for the target capability
        String[] ids = registry.getMembershipSetIds(target);
        for (int j = 0; j < ids.length; j++) {
            if (memberships.get(ids[j]) == target)
                memberships.remove(ids[j]);
        }
    }

    /**
     * Returns the list of categories that have capabilities
     * registered against it.
     */
    private ArrayList getAvailableCategories() {
        ArrayList results = registry.getUsedCategories();
        Collections.sort(results, categoryComparator);
        if (registry.getMiscCategory() != null)
            results.add(registry.getMiscCategory());
        return results;
    }

    /**
     * Return <code>true</code> if the user may have made changes
     * to the capabilities of the project. Otherwise <code>false</code>
     * if no changes were made.
     * 
     * @return <code>true</true> when possible changes may have been made,
     *    <code>false</code> otherwise
     */
    public boolean getCapabilitiesModified() {
        return modified;
    }

    /**
     * Returns the content provider for the viewers
     */
    private IContentProvider getContentProvider() {
        return new WorkbenchContentProvider() {
            public Object[] getChildren(Object parentElement) {
                if (parentElement instanceof ArrayList)
                    return ((ArrayList) parentElement).toArray();
                else
                    return null;
            }
        };
    }

    /**
     * The user has changed the project capability selection.
     * Set the modified flag and clear the caches.
     */
    private void capabilitiesModified() {
        modified = true;
    }

    /**
     * Add a dependency between the target and dependent
     * capabilities
     */
    private void addDependency(Capability target, Capability dependent) {
        ArrayList descriptors = (ArrayList) dependents.get(target);
        if (descriptors == null) {
            descriptors = new ArrayList();
            descriptors.add(dependent);
            dependents.put(target, descriptors);
        } else if (!descriptors.contains(dependent)) {
            descriptors.add(dependent);
        }
    }

    /**
     * Returns true if the capability has any
     * dependencies on it.
     */
    private boolean hasDependency(Capability capability) {
        ArrayList descriptors = (ArrayList) dependents.get(capability);
        if (descriptors == null)
            return false;
        if (descriptors.size() == 1 && descriptors.get(0) == capability)
            return false;
        return true;
    }

    /**
     * Returns whether the category is considered disabled
     */
    private boolean isDisabledCapability(Capability cap) {
        if (disabledCaps == null) {
            if (disabledCapabilities == null)
                disabledCaps = new ArrayList(0);
            else
                disabledCaps = Arrays.asList(disabledCapabilities);
        }
        return disabledCaps.contains(cap);
    }

    /**
     * Populate the dependents map based on the
     * current set of capabilities.
     */
    private void populateDependents() {
        if (initialCapabilities == null)
            return;

        LinkedList capabilities = new LinkedList();
        capabilities.addAll(Arrays.asList(initialCapabilities));

        while (!capabilities.isEmpty()) {
            // Retrieve the target capability
            Capability target;
            target = (Capability) capabilities.removeFirst();
            // Add the capability as a dependent of itself.
            // It will indicate to the uncheck handler to not uncheck this
            // capability automatically even if a another capability which
            // depended on it is unchecked.
            addDependency(target, target);

            if (registry.hasPrerequisites(target)) {
                // Retrieve the prerequisite capabilities...
                String[] prereqIds = registry.getPrerequisiteIds(target);
                Capability[] prereqCapabilities;
                prereqCapabilities = registry.findCapabilities(prereqIds);
                // For each prerequisite capability...
                for (int i = 0; i < prereqCapabilities.length; i++) {
                    // Update the dependent map for the prerequisite capability
                    addDependency(prereqCapabilities[i], target);
                    // Recursive if prerequisite capability also has prerequisites
                    if (registry.hasPrerequisites(prereqCapabilities[i]))
                        capabilities.addLast(prereqCapabilities[i]);
                }
            }
        }
    }

    /**
     * Populate the memberships map based on the
     * current set of capabilities.
     */
    private void populateMemberships() {
        if (initialCapabilities == null)
            return;

        Iterator itr = (Arrays.asList(initialCapabilities)).iterator();
        while (itr.hasNext()) {
            Capability cap = (Capability) itr.next();
            String[] ids = registry.getMembershipSetIds(cap);
            for (int j = 0; j < ids.length; j++) {
                memberships.put(ids[j], cap);
            }
        }
    }

    /**
     * Handle the case of a capability being checked
     * by ensuring the action is allowed and the prerequisite
     * capabilities are also checked.
     */
    private void handleCapabilityChecked(Capability capability) {
        // Cannot allow a disabled capability to be checked
        if (isDisabledCapability(capability)) {
            MessageDialog
                    .openWarning(
                            checkboxViewer.getControl().getShell(),
                            IDEWorkbenchMessages.ProjectCapabilitySelectionGroup_errorTitle,
                            NLS.bind(IDEWorkbenchMessages.ProjectCapabilitySelectionGroup_disabledCapability, capability.getName()));
            checkboxViewer.setChecked(capability, false);
            return;
        }

        // Cannot allow an invalid capability to be checked
        if (!capability.isValid()) {
            MessageDialog
                    .openWarning(
                            checkboxViewer.getControl().getShell(),
                            IDEWorkbenchMessages.ProjectCapabilitySelectionGroup_errorTitle,
                            NLS.bind(IDEWorkbenchMessages.ProjectCapabilitySelectionGroup_invalidCapability, capability.getName()));
            checkboxViewer.setChecked(capability, false);
            return;
        }

        // Is there a membership set problem...
        String[] ids = registry.getMembershipSetIds(capability);
        for (int i = 0; i < ids.length; i++) {
            Capability member = (Capability) memberships.get(ids[i]);
            if (member != null && member != capability) {
                MessageDialog
                        .openWarning(
                                checkboxViewer.getControl().getShell(),
                                IDEWorkbenchMessages.ProjectCapabilitySelectionGroup_errorTitle,
                                NLS.bind(IDEWorkbenchMessages.ProjectCapabilitySelectionGroup_membershipConflict, capability.getName(), member.getName()));
                checkboxViewer.setChecked(capability, false);
                return;
            }
        }

        // Handle prerequisite by auto-checking them if possible
        if (registry.hasPrerequisites(capability)) {
            // Check for any prerequisite problems...
            // Retrieve all the prerequisite capabilities, including
            // any prerequisite of the prerequisites!
            LinkedList capabilities = new LinkedList();
            capabilities.addLast(capability);
            while (!capabilities.isEmpty()) {
                Capability target;
                target = (Capability) capabilities.removeFirst();
                // Retrieve the capability's immediate prerequisites
                String[] prereqIds = registry.getPrerequisiteIds(target);
                Capability[] prereqCapabilities;
                prereqCapabilities = registry.findCapabilities(prereqIds);
                for (int i = 0; i < prereqCapabilities.length; i++) {
                    // If the prerequisite is missing, warn the user and
                    // do not allow the check to proceed.
                    if (prereqCapabilities[i] == null
                            || isDisabledCapability(prereqCapabilities[i])
                            || !prereqCapabilities[i].isValid()) {
                        MessageDialog
                                .openWarning(
                                        checkboxViewer.getControl().getShell(),
                                        IDEWorkbenchMessages.ProjectCapabilitySelectionGroup_errorTitle,
                                        NLS.bind(IDEWorkbenchMessages.ProjectCapabilitySelectionGroup_missingPrereqs, capability.getName(), prereqIds[i]));
                        checkboxViewer.setChecked(capability, false);
                        return;
                    }
                    // If there is a membership problem, warn the user and
                    // do not allow the check to proceed
                    ids = registry.getMembershipSetIds(prereqCapabilities[i]);
                    for (int j = 0; j < ids.length; j++) {
                        Capability member = (Capability) memberships
                                .get(ids[j]);
                        if (member != null && member != prereqCapabilities[i]) {
                            MessageDialog
                                    .openWarning(
                                            checkboxViewer.getControl()
                                                    .getShell(),
                                            IDEWorkbenchMessages.ProjectCapabilitySelectionGroup_errorTitle,
                                            NLS.bind(IDEWorkbenchMessages.ProjectCapabilitySelectionGroup_membershipPrereqConflict, new Object[] {capability.getName(), prereqCapabilities[i].getName(), member.getName()}));
                            checkboxViewer.setChecked(capability, false);
                            return;
                        }
                    }
                    // If the prerequisite capability has prerequisites
                    // also, then add it to be processed.
                    if (registry.hasPrerequisites(prereqCapabilities[i]))
                        capabilities.addLast(prereqCapabilities[i]);
                }
            }

            // Auto-check all prerequisite capabilities
            capabilities = new LinkedList();
            capabilities.addLast(capability);
            // For each capability that has prerequisites...
            while (!capabilities.isEmpty()) {
                Capability target;
                target = (Capability) capabilities.removeFirst();
                // Retrieve the prerequisite capabilities...
                String[] prereqIds = registry.getPrerequisiteIds(target);
                Capability[] prereqCapabilities;
                prereqCapabilities = registry.findCapabilities(prereqIds);
                // For each prerequisite capability...
                for (int i = 0; i < prereqCapabilities.length; i++) {
                    // Mark it as being checked
                    markCapabilityChecked(prereqCapabilities[i], target);
                    // Recursive if prerequisite capability also has prerequisites
                    if (registry.hasPrerequisites(prereqCapabilities[i]))
                        capabilities.addLast(prereqCapabilities[i]);
                }
            }
        }

        // Mark the capability as checked. Adds itself as a
        // dependent - this will indicate to the uncheck handler
        // to not uncheck this capability automatically even if
        // another capability which depends on it is unchecked.
        markCapabilityChecked(capability, capability);

        // Notify those interested
        capabilitiesModified();
        notifyCheckStateListner();
    }

    /**
     * Handle the case of a capability being unchecked
     * by ensuring the action is allowed. 
     */
    private void handleCapabilityUnchecked(Capability capability) {
        ArrayList descriptors = (ArrayList) dependents.get(capability);

        // Note, there is no need to handle the case where descriptors size
        // is zero because it cannot happen. For this method to be called, the
        // item must have been checked previously. If it was checked by the user,
        // then the item itself would be a dependent. If the item was checked
        // because it was required by another capability, then that other capability
        // would be a dependent.

        if (descriptors.size() == 1 && descriptors.get(0) == capability) {
            // If the only dependent is itself, then its ok to uncheck
            capabilitiesModified();
            markCapabilityUnchecked(capability);

            // Remove this capability as a dependent on its prerequisite
            // capabilities. Recursive if a prerequisite capability
            // no longer has any dependents.
            if (registry.hasPrerequisites(capability)) {
                LinkedList capabilities = new LinkedList();
                capabilities.addLast(capability);
                // For each capability that has prerequisite capabilities
                while (!capabilities.isEmpty()) {
                    Capability target;
                    target = (Capability) capabilities.removeFirst();
                    // Retrieve the prerequisite capabilities...
                    String[] prereqIds = registry.getPrerequisiteIds(target);
                    Capability[] prereqCapabilities;
                    prereqCapabilities = registry.findCapabilities(prereqIds);
                    // For each prerequisite capability...
                    for (int i = 0; i < prereqCapabilities.length; i++) {
                        // Retrieve the list of dependents on the prerequisite capability...
                        Capability prereqCap = prereqCapabilities[i];
                        ArrayList prereqDependents = (ArrayList) dependents
                                .get(prereqCap);
                        // Remove the dependent target capability...
                        prereqDependents.remove(target);
                        if (prereqDependents.isEmpty()) {
                            // Unchecked the prerequisite capability
                            markCapabilityUnchecked(prereqCap);
                            // Recursive if prerequisite capability also has
                            // prerequisite capabilities
                            if (registry.hasPrerequisites(prereqCap))
                                capabilities.addLast(prereqCap);
                        } else if (prereqDependents.size() == 1
                                && prereqDependents.get(0) == prereqCap) {
                            // Only dependent is itself so ungray the item to let the
                            // user know no other capability is dependent on it
                            checkboxViewer.setGrayed(prereqCap, false);
                        }
                    }
                }
            }

            // Notify those interested
            notifyCheckStateListner();
        } else {
            // At least one other capability depends on it being checked
            // so force it to remain checked and warn the user.
            checkboxViewer.setChecked(capability, true);
            // Get a copy and remove the target capability
            ArrayList descCopy = (ArrayList) descriptors.clone();
            descCopy.remove(capability);
            // Show the prereq problem to the user
            if (descCopy.size() == 1) {
                Capability cap = (Capability) descCopy.get(0);
                MessageDialog
                        .openWarning(
                                checkboxViewer.getControl().getShell(),
                                IDEWorkbenchMessages.ProjectCapabilitySelectionGroup_errorTitle,
                                NLS.bind(IDEWorkbenchMessages.ProjectCapabilitySelectionGroup_requiredPrereq, capability.getName(), cap.getName()));
            } else {
                StringBuffer msg = new StringBuffer();
                Iterator itr = descCopy.iterator();
                while (itr.hasNext()) {
                    Capability cap = (Capability) itr.next();
                    msg.append("\n    "); //$NON-NLS-1$
                    msg.append(cap.getName());
                }
                MessageDialog
                        .openWarning(
                                checkboxViewer.getControl().getShell(),
                                IDEWorkbenchMessages.ProjectCapabilitySelectionGroup_errorTitle,
                                NLS.bind(IDEWorkbenchMessages.ProjectCapabilitySelectionGroup_requiredPrereqs, capability.getName(), msg));
            }
        }
    }

    /**
     * Returns the collection of capabilities selected
     * by the user. The collection is not in prerequisite
     * order.
     * 
     * @return array of selected capabilities
     */
    public Capability[] getSelectedCapabilities() {
        Capability[] capabilities = new Capability[checkedCapabilities.size()];
        checkedCapabilities.toArray(capabilities);
        return capabilities;
    }

    /**
     * Return the current listener interested when the check
     * state of a capability actually changes.
     * 
     * @return Returns a ICheckStateListener
     */
    public ICheckStateListener getCheckStateListener() {
        return checkStateListener;
    }

    /**
     * Set the current listener interested when the check
     * state of a capability actually changes.
     * 
     * @param checkStateListener The checkStateListener to set
     */
    public void setCheckStateListener(ICheckStateListener checkStateListener) {
        this.checkStateListener = checkStateListener;
    }

    /**
     * Notify the check state listener that a capability
     * check state has changed. The event past will
     * always be <code>null</code> as it could be
     * triggered by code instead of user input.
     */
    private void notifyCheckStateListner() {
        if (checkStateListener != null)
            checkStateListener.checkStateChanged(null);
    }

    /**
     * Updates the description field for the selected capability
     */
    private void updateDescription(ISelection selection) {
        String text = EMPTY_DESCRIPTION;
        if (selection instanceof IStructuredSelection) {
            IStructuredSelection sel = (IStructuredSelection) selection;
            Capability cap = (Capability) sel.getFirstElement();
            if (cap != null)
                text = cap.getDescription();
        }
        descriptionText.setText(text);
    }

    class CapabilityLabelProvider extends LabelProvider {
        private Map imageTable;

        public void dispose() {
            if (imageTable != null) {
                Iterator itr = imageTable.values().iterator();
                while (itr.hasNext())
                    ((Image) itr.next()).dispose();
                imageTable = null;
            }
        }

        public Image getImage(Object element) {
            ImageDescriptor descriptor = ((Capability) element)
                    .getIconDescriptor();
            if (descriptor == null)
                return null;

            //obtain the cached image corresponding to the descriptor
            if (imageTable == null) {
                imageTable = new Hashtable(40);
            }
            Image image = (Image) imageTable.get(descriptor);
            if (image == null) {
                image = descriptor.createImage();
                imageTable.put(descriptor, image);
            }
            return image;
        }

        public String getText(Object element) {
            Capability cap = (Capability) element;
            String text = cap.getName();
            if (isDisabledCapability(cap))
                text = NLS.bind(IDEWorkbenchMessages.ProjectCapabilitySelectionGroup_disabledLabel, text );
            return text;
        }
    }
}

