/*******************************************************************************
 * Copyright (c) 2000, 2006 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
 *     Gunnar Wagenknecht - fix for bug 21756 [PropertiesView] property view sorting
 *******************************************************************************/

package org.eclipse.ui.views.properties;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.eclipse.core.runtime.ListenerList;
import org.eclipse.jface.action.IStatusLineManager;
import org.eclipse.jface.viewers.CellEditor;
import org.eclipse.jface.viewers.ICellEditorListener;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.TreeEditor;
import org.eclipse.swt.events.ControlAdapter;
import org.eclipse.swt.events.ControlEvent;
import org.eclipse.swt.events.KeyAdapter;
import org.eclipse.swt.events.KeyEvent;
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.events.TreeEvent;
import org.eclipse.swt.events.TreeListener;
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.Tree;
import org.eclipse.swt.widgets.TreeColumn;
import org.eclipse.swt.widgets.TreeItem;
import org.eclipse.swt.widgets.Widget;
import org.eclipse.ui.internal.views.properties.PropertiesMessages;

/**
 * The PropertySheetViewer displays the properties of objects. The model for the
 * viewer consists of a hierarchy of <code>IPropertySheetEntry</code>.
 * <p>
 * This viewer also supports the optional catogorization of the first level
 * <code>IPropertySheetEntry</code> s by using instances of
 * <code>PropertySheetCategory</code>.
 *  
 */
/* package */
class PropertySheetViewer extends Viewer {
    // The input objects for the viewer
    private Object[] input;

    // The root entry of the viewer
    private IPropertySheetEntry rootEntry;

    // The current categories
    private PropertySheetCategory[] categories;

    // SWT widgets
    private Tree tree;

    private TreeEditor treeEditor;

    private static String[] columnLabels = {
            PropertiesMessages.PropertyViewer_property, PropertiesMessages.PropertyViewer_value };

    private static String MISCELLANEOUS_CATEGORY_NAME = PropertiesMessages.PropertyViewer_misc;

    // Cell editor support.
    private int columnToEdit = 1;

    private CellEditor cellEditor;

    private IPropertySheetEntryListener entryListener;

    private ICellEditorListener editorListener;

    // Flag to indicate if categories (if any) should be shown
    private boolean isShowingCategories = true;

    // Flag to indicate expert properties should be shown
    private boolean isShowingExpertProperties = false;

    // The status line manager for showing messages
    private IStatusLineManager statusLineManager;

    // Cell editor activation listeners
    private ListenerList activationListeners = new ListenerList();
    
    // the property sheet sorter
    private PropertySheetSorter sorter = new PropertySheetSorter();

    /**
     * Creates a property sheet viewer on a newly-created tree control
     * under the given parent. The viewer has no input, and no root entry.
     * 
     * @param parent
     *            the parent control
     */
    public PropertySheetViewer(Composite parent) {
        tree = new Tree(parent, SWT.FULL_SELECTION | SWT.SINGLE
                | SWT.HIDE_SELECTION);

        // configure the widget
        tree.setLinesVisible(true);
        tree.setHeaderVisible(true);

        // configure the columns
        addColumns();

        // add our listeners to the widget
        hookControl();

        // create a new tree editor
        treeEditor = new TreeEditor(tree);

        // create the entry and editor listener
        createEntryListener();
        createEditorListener();
    }

    /**
     * Activate a cell editor for the given selected tree item.
     * 
     * @param item
     *            the selected tree item
     */
    private void activateCellEditor(TreeItem item) {
        // ensure the cell editor is visible
        tree.showSelection();

        // Get the entry for this item
        IPropertySheetEntry activeEntry = (IPropertySheetEntry) item.getData();

        // Get the cell editor for the entry.
        // Note that the editor parent must be the Tree control
        cellEditor = activeEntry.getEditor(tree);

        if (cellEditor == null) {
			// unable to create the editor
            return;
		}

        // activate the cell editor
        cellEditor.activate();

        // if the cell editor has no control we can stop now
        Control control = cellEditor.getControl();
        if (control == null) {
            cellEditor.deactivate();
            cellEditor = null;
            return;
        }

        // add our editor listener
        cellEditor.addListener(editorListener);

        // set the layout of the tree editor to match the cell editor
        CellEditor.LayoutData layout = cellEditor.getLayoutData();
        treeEditor.horizontalAlignment = layout.horizontalAlignment;
        treeEditor.grabHorizontal = layout.grabHorizontal;
        treeEditor.minimumWidth = layout.minimumWidth;
        treeEditor.setEditor(control, item, columnToEdit);

        // set the error text from the cel editor
        setErrorMessage(cellEditor.getErrorMessage());

        // give focus to the cell editor
        cellEditor.setFocus();

        // notify of activation
        fireCellEditorActivated(cellEditor);
    }

    /**
     * Adds a cell editor activation listener. Has no effect if an identical
     * activation listener is already registered.
     * 
     * @param listener
     *            a cell editor activation listener
     */
    /* package */
    void addActivationListener(ICellEditorActivationListener listener) {
        activationListeners.add(listener);
    }

    /**
     * Add columns to the tree and set up the layout manager accordingly.
     */
    private void addColumns() {

        // create the columns
        TreeColumn[] columns = tree.getColumns();
        for (int i = 0; i < columnLabels.length; i++) {
            String string = columnLabels[i];
            if (string != null) {
                TreeColumn column;
                if (i < columns.length) {
					column = columns[i];
				} else {
					column = new TreeColumn(tree, 0);
				}
                column.setText(string);
            }
        }

        tree.addControlListener(new ControlAdapter() {
            public void controlResized(ControlEvent e) {
                Rectangle area = tree.getClientArea();
                TreeColumn[] columns = tree.getColumns();
                if (area.width > 0) {
                    columns[0].setWidth(area.width * 40 / 100);
                    columns[1].setWidth(area.width - columns[0].getWidth() - 4);
                    tree.removeControlListener(this);
                }
            }
        });

    }

    /**
     * Asks the entry currently being edited to apply its current cell editor
     * value.
     */
    private void applyEditorValue() {
        TreeItem treeItem = treeEditor.getItem();
        // treeItem can be null when view is opened
        if (treeItem == null || treeItem.isDisposed()) {
			return;
		}
        IPropertySheetEntry entry = (IPropertySheetEntry) treeItem.getData();
        entry.applyEditorValue();
    }

    /**
     * Creates the child items for the given widget (item or tree). This
     * method is called when the item is expanded for the first time or when an
     * item is assigned as the root of the tree.
     * @param widget TreeItem or Tree to create the children in.
     */
    private void createChildren(Widget widget) {
        // get the current child items
        TreeItem[] childItems = getChildItems(widget);

        if (childItems.length > 0) {
            Object data = childItems[0].getData();
            if (data != null) {
				// children already there!
                return;
			}
            // remove the dummy
            childItems[0].dispose();
        }

        // get the children and create their tree items
        Object node = widget.getData();
        List children = getChildren(node);
        if (children.isEmpty()) {
			// this item does't actually have any children
            return;
		}
        for (int i = 0; i < children.size(); i++) {
            // create a new tree item
            createItem(children.get(i), widget, i);
        }
    }

    /**
     * Creates a new cell editor listener.
     */
    private void createEditorListener() {
        editorListener = new ICellEditorListener() {
            public void cancelEditor() {
                deactivateCellEditor();
            }

            public void editorValueChanged(boolean oldValidState,
                    boolean newValidState) {
                //Do nothing
            }

            public void applyEditorValue() {
                //Do nothing
            }
        };
    }

    /**
     * Creates a new property sheet entry listener.
     */
    private void createEntryListener() {
        entryListener = new IPropertySheetEntryListener() {
            public void childEntriesChanged(IPropertySheetEntry entry) {
                // update the children of the given entry
                if (entry == rootEntry) {
					updateChildrenOf(entry, tree);
				} else {
                    TreeItem item = findItem(entry);
                    if (item != null) {
						updateChildrenOf(entry, item);
					}
                }
            }

            public void valueChanged(IPropertySheetEntry entry) {
                // update the given entry
                TreeItem item = findItem(entry);
                if (item != null) {
					updateEntry(entry, item);
				}
            }

            public void errorMessageChanged(IPropertySheetEntry entry) {
                // update the error message
                setErrorMessage(entry.getErrorText());
            }
        };
    }

    /**
     * Creates a new tree item, sets the given entry or category (node)in
     * its user data field, and adds a listener to the node if it is an entry.
     * 
     * @param node
     *            the entry or category associated with this item
     * @param parent
     *            the parent widget
     * @param index
     *            indicates the position to insert the item into its parent
     */
    private void createItem(Object node, Widget parent, int index) {
        // create the item
        TreeItem item;
        if (parent instanceof TreeItem) {
			item = new TreeItem((TreeItem) parent, SWT.NONE, index);
		} else {
			item = new TreeItem((Tree) parent, SWT.NONE, index);
		}

        // set the user data field
        item.setData(node);

        // add our listener
        if (node instanceof IPropertySheetEntry) {
			((IPropertySheetEntry) node)
                    .addPropertySheetEntryListener(entryListener);
		}

        // update the visual presentation
        if (node instanceof IPropertySheetEntry) {
			updateEntry((IPropertySheetEntry) node, item);
		} else {
			updateCategory((PropertySheetCategory) node, item);
		}
    }

    /**
     * Deactivate the currently active cell editor.
     */
    /* package */
    void deactivateCellEditor() {
        treeEditor.setEditor(null, null, columnToEdit);
        if (cellEditor != null) {
            cellEditor.deactivate();
            fireCellEditorDeactivated(cellEditor);
            cellEditor.removeListener(editorListener);
            cellEditor = null;
        }
        // clear any error message from the editor
        setErrorMessage(null);
    }

    /**
     * Sends out a selection changed event for the entry tree to all registered
     * listeners.
     */
    private void entrySelectionChanged() {
        SelectionChangedEvent changeEvent = new SelectionChangedEvent(this,
                getSelection());
        fireSelectionChanged(changeEvent);
    }

    /**
     * Return a tree item in the property sheet that has the same entry in
     * its user data field as the supplied entry. Return <code>null</code> if
     * there is no such item.
     * 
     * @param entry
     *            the entry to serach for
     * @return the TreeItem for the entry or <code>null</code> if
     * there isn't one.
     */
    private TreeItem findItem(IPropertySheetEntry entry) {
        // Iterate through treeItems to find item
        TreeItem[] items = tree.getItems();
        for (int i = 0; i < items.length; i++) {
            TreeItem item = items[i];
            TreeItem findItem = findItem(entry, item);
            if (findItem != null) {
				return findItem;
			}
        }
        return null;
    }

    /**
     * Return a tree item in the property sheet that has the same entry in
     * its user data field as the supplied entry. Return <code>null</code> if
     * there is no such item.
     * 
     * @param entry
     *            the entry to search for
     * @param item
     *            the item look in
     * @return the TreeItem for the entry or <code>null</code> if
     * there isn't one.
     */
    private TreeItem findItem(IPropertySheetEntry entry, TreeItem item) {
        // compare with current item
        if (entry == item.getData()) {
			return item;
		}

        // recurse over children
        TreeItem[] items = item.getItems();
        for (int i = 0; i < items.length; i++) {
            TreeItem childItem = items[i];
            TreeItem findItem = findItem(entry, childItem);
            if (findItem != null) {
				return findItem;
			}
        }
        return null;
    }

    /**
     * Notifies all registered cell editor activation listeners of a cell editor
     * activation.
     * 
     * @param activatedCellEditor
     *            the activated cell editor
     */
    private void fireCellEditorActivated(CellEditor activatedCellEditor) {
        Object[] listeners = activationListeners.getListeners();
        for (int i = 0; i < listeners.length; ++i) {
            ((ICellEditorActivationListener) listeners[i])
                    .cellEditorActivated(activatedCellEditor);
        }
    }

    /**
     * Notifies all registered cell editor activation listeners of a cell editor
     * deactivation.
     * 
     * @param activatedCellEditor
     *            the deactivated cell editor
     */
    private void fireCellEditorDeactivated(CellEditor activatedCellEditor) {
        Object[] listeners = activationListeners.getListeners();
        for (int i = 0; i < listeners.length; ++i) {
            ((ICellEditorActivationListener) listeners[i])
                    .cellEditorDeactivated(activatedCellEditor);
        }
    }

    /**
     * Returns the active cell editor of this property sheet viewer or
     * <code>null</code> if no cell editor is active.
     * 
     * @return the active cell editor
     */
    public CellEditor getActiveCellEditor() {
        return cellEditor;
    }

    private TreeItem[] getChildItems(Widget widget) {
        if (widget instanceof Tree) {
            return ((Tree) widget).getItems();
        }
        else if (widget instanceof TreeItem) {
            return ((TreeItem) widget).getItems();
        }
        // shouldn't happen
        return new TreeItem[0];
    }
    
    /**
     * Returns the sorted children of the given category or entry
     *
     * @param node a category or entry
     * @return the children of the given category or entry
     *  (element type <code>IPropertySheetEntry</code> or 
     *  <code>PropertySheetCategory</code>)
     */
    private List getChildren(Object node) {
        // cast the entry or category
        IPropertySheetEntry entry = null;
        PropertySheetCategory category = null;
        if (node instanceof IPropertySheetEntry) {
			entry = (IPropertySheetEntry) node;
		} else {
			category = (PropertySheetCategory) node;
		}

        // get the child entries or categories
        List children;
        if (category == null) {
			children = getChildren(entry);
		} else {
			children = getChildren(category);
		}

        return children;
    }

    /**
     * Returns the child entries of the given entry
     * @param entry The entry to search
     * 
     * @return the children of the given entry (element type
     *         <code>IPropertySheetEntry</code>)
     */
    private List getChildren(IPropertySheetEntry entry) {
        // if the entry is the root and we are showing categories, and we have
        // more than the
        // defualt category, return the categories
        if (entry == rootEntry && isShowingCategories) {
            if (categories.length > 1
                    || (categories.length == 1 && !categories[0]
                            .getCategoryName().equals(
                                    MISCELLANEOUS_CATEGORY_NAME))) {
				return Arrays.asList(categories);
			}
        }

        // return the sorted & filtered child entries
        return getSortedEntries(getFilteredEntries(entry.getChildEntries()));
    }

    /**
     * Returns the child entries of the given category
     * 
     * @param category The category to search
     * 
     * @return the children of the given category (element type
     *         <code>IPropertySheetEntry</code>)
     */
    private List getChildren(PropertySheetCategory category) {
        return getSortedEntries(getFilteredEntries(category.getChildEntries()));
    }

    /*
     * (non-Javadoc) Method declared on Viewer.
     */
    public Control getControl() {
        return tree;
    }

    /**
     * Returns the entries which match the current filter.
     *
     * @param entries the entries to filter
     * @return the entries which match the current filter
     *  (element type <code>IPropertySheetEntry</code>)
     */
    private List getFilteredEntries(IPropertySheetEntry[] entries) {
        // if no filter just return all entries
        if (isShowingExpertProperties) {
			return Arrays.asList(entries);
		}

        // check each entry for the filter
        List filteredEntries = new ArrayList(entries.length);
        for (int i = 0; i < entries.length; i++) {
            IPropertySheetEntry entry = entries[i];
            if (entry != null) {
                String[] filters = entry.getFilters();
                boolean expert = false;
                if (filters != null) {
                    for (int j = 0; j < filters.length; j++) {
                        if (filters[j].equals(IPropertySheetEntry.FILTER_ID_EXPERT)) {
                            expert = true;
                            break;
                        }
                    }
                }
                if (!expert) {
					filteredEntries.add(entry);
				}
            }
        }
        return filteredEntries;
    }
    
    /**
	 * Returns a sorted list of <code>IPropertySheetEntry</code> entries.
	 * 
	 * @param unsortedEntries
	 *            unsorted list of <code>IPropertySheetEntry</code>
	 * @return a sorted list of the specified entries
	 */
	private List getSortedEntries(List unsortedEntries) {
		IPropertySheetEntry[] propertySheetEntries = (IPropertySheetEntry[]) unsortedEntries
				.toArray(new IPropertySheetEntry[unsortedEntries.size()]);
		sorter.sort(propertySheetEntries);
		return Arrays.asList(propertySheetEntries);
	}
    

    /**
	 * The <code>PropertySheetViewer</code> implementation of this method
	 * declared on <code>IInputProvider</code> returns the objects for which
	 * the viewer is currently showing properties. It returns an
	 * <code>Object[]</code> or <code>null</code>.
	 */
    public Object getInput() {
        return input;
    }

    /**
     * Returns the root entry for this property sheet viewer. The root entry is
     * not visible in the viewer.
     * 
     * @return the root entry or <code>null</code>.
     */
    public IPropertySheetEntry getRootEntry() {
        return rootEntry;
    }

    /**
     * The <code>PropertySheetViewer</code> implementation of this
     * <code>ISelectionProvider</code> method returns the result as a
     * <code>StructuredSelection</code>.
     * <p>
     * Note that this method only includes <code>IPropertySheetEntry</code> in
     * the selection (no categories).
     * </p>
     */
    public ISelection getSelection() {
        if (tree.getSelectionCount() == 0) {
			return StructuredSelection.EMPTY;
		}
        TreeItem[] sel = tree.getSelection();
        List entries = new ArrayList(sel.length);
        for (int i = 0; i < sel.length; i++) {
            TreeItem ti = sel[i];
            Object data = ti.getData();
            if (data instanceof IPropertySheetEntry) {
				entries.add(data);
			}
        }
        return new StructuredSelection(entries);
    }

    /**
     * Selection in the viewer occurred. Check if there is an active cell
     * editor. If yes, deactivate it and check if a new cell editor must be
     * activated.
     * 
     * @param selection
     *            the TreeItem that is selected
     */
    private void handleSelect(TreeItem selection) {
        // deactivate the current cell editor
        if (cellEditor != null) {
            applyEditorValue();
            deactivateCellEditor();
        }

        // get the new selection
        TreeItem[] sel = new TreeItem[] { selection };
        if (sel.length == 0) {
            setMessage(null);
            setErrorMessage(null);
        } else {
            Object object = sel[0].getData(); // assume single selection
            if (object instanceof IPropertySheetEntry) {
                // get the entry for this item
                IPropertySheetEntry activeEntry = (IPropertySheetEntry) object;

                // display the description for the item
                setMessage(activeEntry.getDescription());

                // activate a cell editor on the selection
                activateCellEditor(sel[0]);
            }
        }
        entrySelectionChanged();
    }

    /**
     * The expand icon for a node in this viewer has been selected to collapse a
     * subtree. Deactivate the cell editor
     * 
     * @param event
     *            the SWT tree event
     */
    private void handleTreeCollapse(TreeEvent event) {
        if (cellEditor != null) {
            applyEditorValue();
            deactivateCellEditor();
        }
    }

    /**
     * The expand icon for a node in this viewer has been selected to expand the
     * subtree. Create the children 1 level deep.
     * <p>
     * Note that we use a "dummy" item (no user data) to show a "+" icon beside
     * an item which has children before the item is expanded now that it is
     * being expanded we have to create the real child items
     * </p>
     * 
     * @param event
     *            the SWT tree event
     */
    private void handleTreeExpand(TreeEvent event) {
        createChildren(event.item);
    }

    /**
     * Hides the categories.
     */
    /* package */
    void hideCategories() {
        isShowingCategories = false;
        categories = null;
        refresh();
    }

    /**
     * Hides the expert properties.
     */
    /* package */
    void hideExpert() {
        isShowingExpertProperties = false;
        refresh();
    }

    /**
     * Establish this viewer as a listener on the control
     */
    private void hookControl() {
        // Handle selections in the Tree
        // Part1: Double click only (allow traversal via keyboard without
        // activation
        tree.addSelectionListener(new SelectionAdapter() {
            /* (non-Javadoc)
             * @see org.eclipse.swt.events.SelectionListener#widgetSelected(org.eclipse.swt.events.SelectionEvent)
             */
            public void widgetSelected(SelectionEvent e) {
            	// The viewer only owns the status line when there is
            	// no 'active' cell editor
            	if (cellEditor == null || !cellEditor.isActivated()) {
					updateStatusLine(e.item);
				}
			}

			/* (non-Javadoc)
			 * @see org.eclipse.swt.events.SelectionListener#widgetDefaultSelected(org.eclipse.swt.events.SelectionEvent)
			 */
			public void widgetDefaultSelected(SelectionEvent e) {
                handleSelect((TreeItem) e.item);
            }
        });
        // Part2: handle single click activation of cell editor
        tree.addMouseListener(new MouseAdapter() {
            public void mouseDown(MouseEvent event) {
                // only activate if there is a cell editor
                Point pt = new Point(event.x, event.y);
                TreeItem item = tree.getItem(pt);
                if (item != null) {
                    handleSelect(item);
                }
            }
        });

        // Add a tree listener to expand and collapse which
        // allows for lazy creation of children
        tree.addTreeListener(new TreeListener() {
            public void treeExpanded(final TreeEvent event) {
                handleTreeExpand(event);
            }

            public void treeCollapsed(final TreeEvent event) {
                handleTreeCollapse(event);
            }
        });

        // Refresh the tree when F5 pressed
        tree.addKeyListener(new KeyAdapter() {
            public void keyReleased(KeyEvent e) {
                if (e.character == SWT.ESC) {
					deactivateCellEditor();
				} else if (e.keyCode == SWT.F5) {
					// The following will simulate a reselect
                    setInput(getInput());
				}
            }
        });
    }

    /**
     * Update the status line based on the data of item.
     * @param item
     */
    protected void updateStatusLine(Widget item) {
    	setMessage(null);
    	setErrorMessage(null);
    	
    	// Update the status line
    	if (item != null) {
    		if (item.getData() instanceof PropertySheetEntry) {
    			PropertySheetEntry psEntry = (PropertySheetEntry) item.getData();
    			
    			// For entries, show the description if any, else show the label
    			String desc = psEntry.getDescription();
    			if (desc != null && desc.length() > 0) {
					setMessage(psEntry.getDescription());
				} else {
					setMessage(psEntry.getDisplayName());
				}
    		}
    			
    		else if (item.getData() instanceof PropertySheetCategory) {
    			PropertySheetCategory psCat = (PropertySheetCategory) item.getData();
    			setMessage(psCat.getCategoryName());
    		}
    	}
	}

    /**
     * Updates all of the items in the tree.
     * <p>
     * Note that this means ensuring that the tree items reflect the state of
     * the model (entry tree) it does not mean telling the model to update
     * itself.
     * </p>
     */
    public void refresh() {
        if (rootEntry != null) {
            updateChildrenOf(rootEntry, tree);
        }
    }

    /**
     * Removes the given cell editor activation listener from this viewer. Has
     * no effect if an identical activation listener is not registered.
     * 
     * @param listener
     *            a cell editor activation listener
     */
    /* package */
    void removeActivationListener(ICellEditorActivationListener listener) {
        activationListeners.remove(listener);
    }

    /**
     * Remove the given item from the tree. Remove our listener if the
     * item's user data is a an entry then set the user data to null
     * 
     * @param item
     *            the item to remove
     */
    private void removeItem(TreeItem item) {
        Object data = item.getData();
        if (data instanceof IPropertySheetEntry) {
			((IPropertySheetEntry) data)
                    .removePropertySheetEntryListener(entryListener);
		}
        item.setData(null);
        item.dispose();
    }

    /**
     * Reset the selected properties to their default values.
     */
    public void resetProperties() {
        // Determine the selection
        IStructuredSelection selection = (IStructuredSelection) getSelection();

        // Iterate over entries and reset them
        Iterator itr = selection.iterator();
        while (itr.hasNext()) {
			((IPropertySheetEntry) itr.next()).resetPropertyValue();
		}
    }

    /**
     * Sets the error message to be displayed in the status line.
     * 
     * @param errorMessage
     *            the message to be displayed, or <code>null</code>
     */
    private void setErrorMessage(String errorMessage) {
        // show the error message
        if (statusLineManager != null) {
			statusLineManager.setErrorMessage(errorMessage);
		}
    }

    /**
     * The <code>PropertySheetViewer</code> implementation of this method
     * declared on <code>Viewer</code> method sets the objects for which the
     * viewer is currently showing properties.
     * <p>
     * The input must be an <code>Object[]</code> or <code>null</code>.
     * </p>
     * 
     * @param newInput
     *            the input of this viewer, or <code>null</code> if none
     */
    public void setInput(Object newInput) {
        // need to save any changed value when user clicks elsewhere
        applyEditorValue();
        // deactivate our cell editor
        deactivateCellEditor();

        // set the new input to the root entry
        input = (Object[]) newInput;
        if (input == null) {
			input = new Object[0];
		}

        if (rootEntry != null) {
            rootEntry.setValues(input);
            // ensure first level children are visible
            updateChildrenOf(rootEntry, tree);
        }
    }

    /**
     * Sets the message to be displayed in the status line. This message is
     * displayed when there is no error message.
     * 
     * @param message
     *            the message to be displayed, or <code>null</code>
     */
    private void setMessage(String message) {
        // show the message
        if (statusLineManager != null) {
			statusLineManager.setMessage(message);
		}
    }

    /**
     * Sets the root entry for this property sheet viewer. The root entry is not
     * visible in the viewer.
     * 
     * @param root
     *            the root entry
     */
    public void setRootEntry(IPropertySheetEntry root) {
        // If we have a root entry, remove our entry listener
        if (rootEntry != null) {
			rootEntry.removePropertySheetEntryListener(entryListener);
		}

        rootEntry = root;

        // Set the root as user data on the tree
        tree.setData(rootEntry);

        // Add an IPropertySheetEntryListener to listen for entry change
        // notifications
        rootEntry.addPropertySheetEntryListener(entryListener);

        // Pass our input to the root, this will trigger entry change
        // callbacks to update this viewer
        setInput(input);
    }

    /*
     *  (non-Javadoc)
     * @see org.eclipse.jface.viewers.Viewer#setSelection(org.eclipse.jface.viewers.ISelection, boolean)
     */
    public void setSelection(ISelection selection, boolean reveal) {
        //Do nothing by default
    }

    /**
	 * Sets the sorter for this viewer.
	 * <p>
	 * The default sorter sorts categories and entries alphabetically. 
	 * A viewer update needs to be triggered after the sorter has changed.
	 * </p>
	 * @param sorter the sorter to set (<code>null</code> will reset to the
	 * default sorter)
     * @since 3.1
	 */
	public void setSorter(PropertySheetSorter sorter) {
		if (null == sorter) {
			sorter = new PropertySheetSorter();
		}
		this.sorter = sorter;
	}

    /**
     * Sets the status line manager this view will use to show messages.
     * 
     * @param manager
     *            the status line manager
     */
    public void setStatusLineManager(IStatusLineManager manager) {
        statusLineManager = manager;
    }

    /**
     * Shows the categories.
     */
    /* package */
    void showCategories() {
        isShowingCategories = true;
        refresh();
    }

    /**
     * Shows the expert properties.
     */
    /* package */
    void showExpert() {
        isShowingExpertProperties = true;
        refresh();
    }

    /**
     * Updates the categories. Reuses old categories if possible.
     */
    private void updateCategories() {
        // lazy initialize
        if (categories == null) {
			categories = new PropertySheetCategory[0];
		}

        // get all the filtered child entries of the root
        List childEntries = getFilteredEntries(rootEntry.getChildEntries());

        // if the list is empty, just set an empty categories array
        if (childEntries.size() == 0) {
            categories = new PropertySheetCategory[0];
            return;
        }

        // cache old categories by their descriptor name
        Map categoryCache = new HashMap(categories.length * 2 + 1);
        for (int i = 0; i < categories.length; i++) {
            categories[i].removeAllEntries();
            categoryCache.put(categories[i].getCategoryName(), categories[i]);
        }

        // create a list of categories to get rid of
        List categoriesToRemove = new ArrayList(Arrays.asList(categories));

        // Determine the categories
        PropertySheetCategory misc = (PropertySheetCategory) categoryCache
                .get(MISCELLANEOUS_CATEGORY_NAME);
        if (misc == null) {
			misc = new PropertySheetCategory(MISCELLANEOUS_CATEGORY_NAME);
		}
        boolean addMisc = false;

        for (int i = 0; i < childEntries.size(); i++) {
            IPropertySheetEntry childEntry = (IPropertySheetEntry) childEntries
                    .get(i);
            String categoryName = childEntry.getCategory();
            if (categoryName == null) {
                misc.addEntry(childEntry);
                addMisc = true;
                categoriesToRemove.remove(misc);
            } else {
                PropertySheetCategory category = (PropertySheetCategory) categoryCache
                        .get(categoryName);
                if (category == null) {
                    category = new PropertySheetCategory(categoryName);
                    categoryCache.put(categoryName, category);
                } else {
                    categoriesToRemove.remove(category);
                }
                category.addEntry(childEntry);
            }
        }

        // Add the PSE_MISC category if it has entries
        if (addMisc) {
			categoryCache.put(MISCELLANEOUS_CATEGORY_NAME, misc);
		}
        
        // Sort the categories.
        // Rather than just sorting categoryCache.values(), we'd like the original order to be preserved
        // (with misc added at the end, if needed) before passing to the sorter.
        ArrayList categoryList = new ArrayList();
        Set seen = new HashSet(childEntries.size());
        for (int i = 0; i < childEntries.size(); i++) {
            IPropertySheetEntry childEntry = (IPropertySheetEntry) childEntries
                    .get(i);
            String categoryName = childEntry.getCategory();
            if (categoryName != null && !seen.contains(categoryName)) {
                seen.add(categoryName);
                PropertySheetCategory category = (PropertySheetCategory) categoryCache
                        .get(categoryName);
                if (category != null) { 
                    categoryList.add(category);
                }
            }
        }
        if (addMisc && !seen.contains(MISCELLANEOUS_CATEGORY_NAME)) {
            categoryList.add(misc);
        }
        
        PropertySheetCategory[] categoryArray = (PropertySheetCategory[]) categoryList
        	.toArray(new PropertySheetCategory[categoryList.size()]);
        sorter.sort(categoryArray);
        categories = categoryArray;
    }

    /**
     * Update the category (but not its parent or children).
     * 
     * @param category
     *            the category to update
     * @param item
     *            the tree item for the given entry
     */
    private void updateCategory(PropertySheetCategory category,
            TreeItem item) {
        // ensure that backpointer is correct
        item.setData(category);

        // Update the name and value columns
        item.setText(0, category.getCategoryName());
        item.setText(1, ""); //$NON-NLS-1$

        // update the "+" icon
        if (category.getAutoExpand()) {
            // we auto expand categories when they first appear
            createChildren(item);
            item.setExpanded(true);
            category.setAutoExpand(false);
        } else {
            // we do not want to auto expand categories if the user has
            // collpased them
            updatePlus(category, item);
        }
    }

    /**
     * Update the child entries or categories of the given entry or category. If
     * the given node is the root entry and we are showing categories then the
     * child entries are categories, otherwise they are entries.
     * 
     * @param node
     *            the entry or category whose children we will update
     * @param widget
     *            the widget for the given entry, either a
     *            <code>TableTree</code> if the node is the root node or a
     *            <code>TreeItem</code> otherwise.
     */
    private void updateChildrenOf(Object node, Widget widget) {
        // cast the entry or category
        IPropertySheetEntry entry = null;
        PropertySheetCategory category = null;
        if (node instanceof IPropertySheetEntry) {
			entry = (IPropertySheetEntry) node;
		} else {
			category = (PropertySheetCategory) node;
		}

        // get the current child tree items
        TreeItem[] childItems = getChildItems(widget);

        // optimization! prune collapsed subtrees
        TreeItem item = null;
        if (widget instanceof TreeItem) {
            item = (TreeItem) widget;
        }
        if (item != null && !item.getExpanded()) {
            // remove all children
            for (int i = 0; i < childItems.length; i++) {
                if (childItems[i].getData() != null) {
                    removeItem(childItems[i]);
                }
            }

            // append a dummy if necessary
            if (category != null || entry.hasChildEntries()) {
                // may already have a dummy
                // It is either a category (which always has at least one child)
                // or an entry with chidren.
                // Note that this test is not perfect, if we have filtering on
                // then there in fact may be no entires to show when the user
                // presses the "+" expand icon. But this is an acceptable
                // compromise.
                childItems = getChildItems(widget);
                if (childItems.length == 0) {
                    new TreeItem(item, SWT.NULL);
                }
            }
            return;
        }

        // get the child entries or categories
        if (node == rootEntry && isShowingCategories) {
			// update the categories
            updateCategories();
		}
        List children = getChildren(node);

        // remove items
        Set set = new HashSet(childItems.length * 2 + 1);

        for (int i = 0; i < childItems.length; i++) {
            Object data = childItems[i].getData();
            if (data != null) {
                Object e = data;
                int ix = children.indexOf(e);
                if (ix < 0) { // not found
                    removeItem(childItems[i]);
                } else { // found
                    set.add(e);
                }
            } else if (data == null) { // the dummy
                childItems[i].dispose();
            }
        }

        // WORKAROUND
        int oldCnt = -1;
        if (widget == tree) {
			oldCnt = tree.getItemCount();
		}

        // add new items
        int newSize = children.size();
        for (int i = 0; i < newSize; i++) {
            Object el = children.get(i);
            if (!set.contains(el)) {
				createItem(el, widget, i);
			}
        }

        // WORKAROUND
        if (widget == tree && oldCnt == 0 && tree.getItemCount() == 1) {
            tree.setRedraw(false);
            tree.setRedraw(true);
        }

        // get the child tree items after our changes
        childItems = getChildItems(widget);

        // update the child items
        // This ensures that the children are in the correct order
        // are showing the correct values.
        for (int i = 0; i < newSize; i++) {
            Object el = children.get(i);
            if (el instanceof IPropertySheetEntry) {
				updateEntry((IPropertySheetEntry) el, childItems[i]);
			} else {
                updateCategory((PropertySheetCategory) el, childItems[i]);
                updateChildrenOf(el, childItems[i]);
            }
        }
        // The tree's original selection may no longer apply after the update,
        // so fire the selection changed event.
        entrySelectionChanged();
    }

    /**
     * Update the given entry (but not its children or parent)
     * 
     * @param entry
     *            the entry we will update
     * @param item
     *            the tree item for the given entry
     */
    private void updateEntry(IPropertySheetEntry entry, TreeItem item) {
        // ensure that backpointer is correct
        item.setData(entry);

        // update the name and value columns
        item.setText(0, entry.getDisplayName());
        item.setText(1, entry.getValueAsString());
        Image image = entry.getImage();
        if (item.getImage(1) != image) {
			item.setImage(1, image);
		}

        // update the "+" icon
        updatePlus(entry, item);
    }

    /**
     * Updates the "+"/"-" icon of the tree item from the given entry
     * or category.
     *
     * @param node the entry or category
     * @param item the tree item being updated
     */
    private void updatePlus(Object node, TreeItem item) {
        // cast the entry or category
        IPropertySheetEntry entry = null;
        PropertySheetCategory category = null;
        if (node instanceof IPropertySheetEntry) {
			entry = (IPropertySheetEntry) node;
		} else {
			category = (PropertySheetCategory) node;
		}

        boolean hasPlus = item.getItemCount() > 0;
        boolean needsPlus = category != null || entry.hasChildEntries();
        boolean removeAll = false;
        boolean addDummy = false;

        if (hasPlus != needsPlus) {
            if (needsPlus) {
                addDummy = true;
            } else {
                removeAll = true;
            }
        }
        if (removeAll) {
            // remove all children
            TreeItem[] items = item.getItems();
            for (int i = 0; i < items.length; i++) {
                removeItem(items[i]);
            }
        }

        if (addDummy) {
            new TreeItem(item, SWT.NULL); // append a dummy to create the
            // plus sign
        }
    }
}
