/*******************************************************************************
 * Copyright (c) 2000, 2003 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials 
 * are made available under the terms of the Common Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/cpl-v10.html
 * 
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.ui.internal.ide.dialogs;

import java.util.*;

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.Platform;
import org.eclipse.jface.util.ListenerList;
import org.eclipse.jface.util.SafeRunnable;
import org.eclipse.jface.viewers.*;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.BusyIndicator;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.Table;

import java.io.File;

/**
 *	Workbench-level composite that combines a CheckboxTreeViewer and CheckboxListViewer.
 *	All viewer selection-driven interactions are handled within this object
 */
public class ResourceTreeAndListGroup implements ICheckStateListener, ISelectionChangedListener, ITreeViewerListener {
	private	Object			root;
	private	Object			currentTreeSelection;
	private	Collection		expandedTreeNodes = new HashSet();
	private	Map				checkedStateStore = new HashMap(9);
	private Collection		whiteCheckedTreeItems = new HashSet();
	private	ListenerList	listeners = new ListenerList();
	
	private	ITreeContentProvider		treeContentProvider;
	private	IStructuredContentProvider	listContentProvider;
	private ILabelProvider				treeLabelProvider;
	private ILabelProvider				listLabelProvider;
	
	// widgets
	private	CheckboxTreeViewer	treeViewer;
	private	CheckboxTableViewer	listViewer;
	
	//height hint for viewers
	private static int PREFERRED_HEIGHT = 150;
	
/**
 *	Create an instance of this class.  Use this constructor if you wish to specify
 *	the width and/or height of the combined widget (to only hardcode one of the
 *	sizing dimensions, specify the other dimension's value as -1)
 *
 *	@param parent org.eclipse.swt.widgets.Composite
 *	@param style int
 *  @param rootObject java.lang.Object
 *	@param childPropertyName java.lang.String
 *	@param parentPropertyName java.lang.String
 *	@param listPropertyName java.lang.String
 *	@param useHeightHint If true then use the height hint
 *				to make this group big enough
 */
public ResourceTreeAndListGroup(
	Composite parent,Object rootObject,
	ITreeContentProvider treeContentProvider,ILabelProvider treeLabelProvider,
	IStructuredContentProvider listContentProvider,ILabelProvider listLabelProvider,
	int style,
	boolean useHeightHint) {

	root = rootObject;
	this.treeContentProvider = treeContentProvider;
	this.listContentProvider = listContentProvider;
	this.treeLabelProvider = treeLabelProvider;
	this.listLabelProvider = listLabelProvider;
	createContents(parent, style,useHeightHint);
}
/**
 * This method must be called just before this window becomes visible.
 */
public void aboutToOpen() {
	determineWhiteCheckedDescendents(root);
	checkNewTreeElements(treeContentProvider.getElements(root));
	currentTreeSelection = null;

	//select the first element in the list
	Object[] elements = treeContentProvider.getElements(root);
	Object primary = elements.length > 0 ? elements[0] : null;
	if (primary != null) {
		treeViewer.setSelection(new StructuredSelection(primary));
	}
	treeViewer.getControl().setFocus();
}
/**
 *	Add the passed listener to self's collection of clients
 *	that listen for changes to element checked states
 *
 *	@param listener ICheckStateListener
 */
public void addCheckStateListener(ICheckStateListener listener) {
	listeners.add(listener);
}
/**
 *	Return a boolean indicating whether all children of the passed tree element
 *	are currently white-checked
 *
 *	@return boolean
 *	@param treeElement java.lang.Object
 */
protected boolean areAllChildrenWhiteChecked(Object treeElement) {
	Object[] children = treeContentProvider.getChildren(treeElement);
	for (int i = 0; i < children.length; ++i) {
		if (!whiteCheckedTreeItems.contains(children[i]))
			return false;
	}
	
	return true;
}
/**
 *	Return a boolean indicating whether all list elements associated with
 *	the passed tree element are currently checked
 *
 *	@return boolean
 *	@param treeElement java.lang.Object
 */
protected boolean areAllElementsChecked(Object treeElement) {
	List checkedElements = (List)checkedStateStore.get(treeElement);
	if (checkedElements == null)	// ie.- tree item not even gray-checked
		return false;

	return getListItemsSize(treeElement) == checkedElements.size();
}
/**
 *	Iterate through the passed elements which are being realized for the first
 *	time and check each one in the tree viewer as appropriate
 */
protected void checkNewTreeElements(Object[] elements) {
	for (int i = 0; i < elements.length; ++i) {
		Object currentElement = elements[i];
		boolean checked = checkedStateStore.containsKey(currentElement);
		treeViewer.setChecked(currentElement,checked);
		treeViewer.setGrayed(currentElement,checked && !whiteCheckedTreeItems.contains(currentElement));
	}
}
/**
*	An item was checked in one of self's two views.  Determine which
*	view this occurred in and delegate appropriately
*
*	@param event CheckStateChangedEvent
*/
public void checkStateChanged(final CheckStateChangedEvent event) {

	//Potentially long operation - show a busy cursor
	BusyIndicator.showWhile(treeViewer.getControl().getDisplay(), new Runnable() {
		public void run() {
			if (event.getCheckable().equals(treeViewer))
				treeItemChecked(event.getElement(), event.getChecked());
			else
				listItemChecked(event.getElement(), event.getChecked(), true);

			notifyCheckStateChangeListeners(event);
		}
	});
}
/**
 *	Lay out and initialize self's visual components.
 *
 *	@param parent org.eclipse.swt.widgets.Composite
 *	@param useHeightHint. If true yse the preferredHeight.
 */
protected void createContents(Composite parent, int style, boolean useHeightHint) {
	// group pane
	Composite composite = new Composite(parent,style);
	composite.setFont(parent.getFont());
	GridLayout layout = new GridLayout();
	layout.numColumns = 2;
	layout.makeColumnsEqualWidth = true;
	layout.marginHeight = 0;
	layout.marginWidth = 0;
	composite.setLayout(layout);
	composite.setLayoutData(new GridData(GridData.FILL_BOTH));
	
	createTreeViewer(composite,useHeightHint);
	createListViewer(composite,useHeightHint);
	
	initialize();
}
/**
 *	Create this group's list viewer.
 */
protected void createListViewer(Composite parent, boolean useHeightHint) {
	listViewer = CheckboxTableViewer.newCheckList(parent, SWT.BORDER);
	GridData data = new GridData(GridData.FILL_BOTH);
	if(useHeightHint)
		data.heightHint = PREFERRED_HEIGHT;
	listViewer.getTable().setLayoutData(data);
	listViewer.getTable().setFont(parent.getFont());
	listViewer.setContentProvider(listContentProvider);
	listViewer.setLabelProvider(listLabelProvider);
	listViewer.addCheckStateListener(this);
}
/**
 *	Create this group's tree viewer.
 */
protected void createTreeViewer(Composite parent, boolean useHeightHint) {
	Tree tree = new Tree(parent, SWT.CHECK | SWT.BORDER);
	GridData data = new GridData(GridData.FILL_BOTH);
	if(useHeightHint)
		data.heightHint = PREFERRED_HEIGHT;
	tree.setLayoutData(data);
	tree.setFont(parent.getFont());
	
	treeViewer = new CheckboxTreeViewer(tree);
	treeViewer.setContentProvider(treeContentProvider);
	treeViewer.setLabelProvider(treeLabelProvider);
	treeViewer.addTreeListener(this);
	treeViewer.addCheckStateListener(this);
	treeViewer.addSelectionChangedListener(this);
}
/**
 * Returns a boolean indicating whether the passed tree element should be
 * at LEAST gray-checked.  Note that this method does not consider whether
 * it should be white-checked, so a specified tree item which should be
 * white-checked will result in a <code>true</code> answer from this method.
 * To determine whether a tree item should be white-checked use method
 * #determineShouldBeWhiteChecked(Object).
 *
 * @param element java.lang.Object
 * @return boolean
 * @see #determineShouldBeWhiteChecked(java.lang.Object)
 */
protected boolean determineShouldBeAtLeastGrayChecked(Object treeElement) {
	// if any list items associated with treeElement are checked then it
	// retains its gray-checked status regardless of its children
	List checked = (List) checkedStateStore.get(treeElement);
	if (checked != null && (!checked.isEmpty()))
		return true;

	// if any children of treeElement are still gray-checked then treeElement
	// must remain gray-checked as well. Only ask expanded nodes
	if (expandedTreeNodes.contains(treeElement)) {
		Object[] children = treeContentProvider.getChildren(treeElement);
		for (int i = 0; i < children.length; ++i) {
			if (checkedStateStore.containsKey(children[i]))
				return true;
		}
	}

	return false;
}
/**
 * Returns a boolean indicating whether the passed tree item should be
 * white-checked.
 *
 * @return boolean
 * @param treeElement java.lang.Object
 */
protected boolean determineShouldBeWhiteChecked(Object treeElement) {
	return areAllChildrenWhiteChecked(treeElement) && areAllElementsChecked(treeElement);
}
/**
 *	Recursively add appropriate tree elements to the collection of
 *	known white-checked tree elements.
 *
 *	@param treeElement java.lang.Object
 */
protected void determineWhiteCheckedDescendents(Object treeElement) {
	// always go through all children first since their white-checked
	// statuses will be needed to determine the white-checked status for
	// this tree element
	Object[] children = treeContentProvider.getElements(treeElement);
	for (int i = 0; i < children.length; ++i)
		determineWhiteCheckedDescendents(children[i]);

	// now determine the white-checked status for this tree element
	if (determineShouldBeWhiteChecked(treeElement))
		setWhiteChecked(treeElement,true);
}
/**
 * Cause the tree viewer to expand all its items
 */
public void expandAll() {
	treeViewer.expandAll();
}
/**
 *	Expand an element in a tree viewer
 */
private void expandTreeElement(final Object item) {
	BusyIndicator.showWhile(treeViewer.getControl().getDisplay(), new Runnable() {
		public void run() {

			// First see if the children need to be given their checked state at all.  If they've
			// already been realized then this won't be necessary
			if (expandedTreeNodes.contains(item))
				checkNewTreeElements(treeContentProvider.getChildren(item));
			else {

				expandedTreeNodes.add(item);
				if (whiteCheckedTreeItems.contains(item)) {
					//If this is the first expansion and this is a white checked node then check the children
					Object[] children = treeContentProvider.getChildren(item);
					for (int i = 0; i < children.length; ++i) {
						if (!whiteCheckedTreeItems.contains(children[i])) {
							Object child = children[i];
							setWhiteChecked(child, true);
							treeViewer.setChecked(child, true);
							checkedStateStore.put(child, new ArrayList());
						}
					}

					//Now be sure to select the list of items too
					setListForWhiteSelection(item);
				}
			}

		}
	});
}
/**
 * Add all of the selected children of nextEntry to result recursively.
 * This does not set any values in the checked state.
 * @param The treeElement being queried
 * @param addAll a boolean to indicate if the checked state store needs to be queried
 * @param filter IElementFilter - the filter being used on the data
 * @param monitor IProgressMonitor or null that the cancel is polled for 
*/
private void findAllSelectedListElements(
	Object treeElement,
	String parentLabel,
	boolean addAll,
	IElementFilter filter,
	IProgressMonitor monitor) throws InterruptedException{
		
	String fullLabel = null;
	if(monitor != null && monitor.isCanceled())
		return;
	if(monitor != null){
		fullLabel = getFullLabel(treeElement,parentLabel);
		monitor.subTask(fullLabel);
	}

	if (addAll) 
		filter.filterElements(listContentProvider.getElements(treeElement),monitor);
	else { //Add what we have stored
		if (checkedStateStore.containsKey(treeElement))
			filter.filterElements((Collection) checkedStateStore.get(treeElement),monitor);
	}

	Object[] treeChildren = treeContentProvider.getChildren(treeElement);
	for (int i = 0; i < treeChildren.length; i++) {
		Object child = treeChildren[i];
		if (addAll)
			findAllSelectedListElements(child, fullLabel,true, filter,monitor);
		else { //Only continue for those with checked state
			if (checkedStateStore.containsKey(child))
				findAllSelectedListElements(
					child,
					fullLabel,
					whiteCheckedTreeItems.contains(child),
					filter,
					monitor);
		}

	}
}
/**
 * Find all of the white checked children of the treeElement and add them to the collection.
 * If the element itself is white select add it. If not then add any selected list elements
 * and recurse down to the children.
 * @param treeElement java.lang.Object
 * @param result java.util.Collection
 */
private void findAllWhiteCheckedItems(Object treeElement, Collection result) {

	if (whiteCheckedTreeItems.contains(treeElement))
		result.add(treeElement);
	else {
		Collection listChildren = (Collection) checkedStateStore.get(treeElement);
		//if it is not in the store then it and it's children are not interesting
		if (listChildren == null)
			return;
		result.addAll(listChildren);
		Object[] children = treeContentProvider.getChildren(treeElement);
		for (int i = 0; i < children.length; ++i) {
			findAllWhiteCheckedItems(children[i], result);
		}
	}
}
/**
 * Returns a flat list of all of the leaf elements which
 * are checked. Filter then based on the supplied ElementFilter.
 * If monitor is cancelled then return null
 * @param filter - the filter for the data
 * @param monitor IProgressMonitor or null
 * @return all of the leaf elements which are checked
 */
public void getAllCheckedListItems(IElementFilter filter, IProgressMonitor monitor) throws InterruptedException{

	//Iterate through the children of the root as the root is not in the store
	Object[] children = treeContentProvider.getChildren(root);
	for (int i = 0; i < children.length; ++i) {
		findAllSelectedListElements(
			children[i],
			null,
			whiteCheckedTreeItems.contains(children[i]),
			filter,			
			monitor);
	}
}

/**
 *	Returns a flat list of all of the leaf elements which are checked.
 *
 *	@return all of the leaf elements which are checked. This API does not
 * 	return null in order to keep backwards compatibility.
 */
public List getAllCheckedListItems() {
	
	final ArrayList returnValue = new ArrayList();
	
	IElementFilter passThroughFilter = new IElementFilter() {
		
		public void filterElements(Collection elements,IProgressMonitor monitor) throws InterruptedException{
			returnValue.addAll(elements);
		}
		
		public void filterElements(Object[] elements,IProgressMonitor monitor) throws InterruptedException{
			for(int i =0; i < elements.length; i ++){
				returnValue.add(elements[i]);
			}
		}
	};
	
	try{
		getAllCheckedListItems(passThroughFilter,null);
	}
	catch (InterruptedException exception){
		return new ArrayList();
	}
	return returnValue;
		
}

/**
 *	Returns a list of all of the items that are white checked.
 * 	Any folders that are white checked are added and then any files
 *  from white checked folders are added. 
 *
 *	@return the list of all of the items that are white checked
 */
public List getAllWhiteCheckedItems() {

	List result = new ArrayList();

	//Iterate through the children of the root as the root is not in the store
	Object[] children = treeContentProvider.getChildren(root);
	for (int i = 0; i < children.length; ++i) {
		findAllWhiteCheckedItems(children[i], result);
	}

	return result;
}
/**
 *	Answer the number of elements that have been checked by the
 *	user.
 *
 *	@return int
 */
public int getCheckedElementCount() {
	return checkedStateStore.size();
}
/**
 * Get the full label of the treeElement (its name and its parent's name).
 * @param treeElement - the element being exported
 * @param parentLabel - the label of the parent, can be null
 * @return String
 */
protected String getFullLabel(Object treeElement,String parentLabel) {
	String parentName = parentLabel;
	
	if (parentLabel == null) 
		parentName = ""; //$NON-NLS-1$
		
	if (parentName.length() > 0 && (!parentName.endsWith(File.separator))) {
		parentName += File.separatorChar;
	}
	return parentName + treeLabelProvider.getText(treeElement);
}
/**
 *	Return a count of the number of list items associated with a
 *	given tree item.
 *
 *	@return int
 *	@param treeElement java.lang.Object
 */
protected int getListItemsSize(Object treeElement) {
	Object[] elements = listContentProvider.getElements(treeElement);
	return elements.length;
}
/**
 * Get the table the list viewer uses.
 * @return org.eclipse.swt.widgets.Table
 */
public Table getListTable() {
	return this.listViewer.getTable();
}
/**
 *	Logically gray-check all ancestors of treeItem by ensuring that they
 *	appear in the checked table
 */
protected void grayCheckHierarchy(Object treeElement) {

	//expand the element first to make sure we have populated for it
	expandTreeElement(treeElement);
	
	// if this tree element is already gray then its ancestors all are as well
	if (checkedStateStore.containsKey(treeElement))
		return;		// no need to proceed upwards from here

	checkedStateStore.put(treeElement,new ArrayList());
	Object parent = treeContentProvider.getParent(treeElement);
	if (parent != null)
		grayCheckHierarchy(parent);
}
/**
 *	Set the checked state of self and all ancestors appropriately. Do not white check anyone - this is
 *  only done down a hierarchy.
 */
private void grayUpdateHierarchy(Object treeElement) {

	boolean shouldBeAtLeastGray = determineShouldBeAtLeastGrayChecked(treeElement);

	treeViewer.setGrayChecked(treeElement, shouldBeAtLeastGray);

	if (whiteCheckedTreeItems.contains(treeElement))
		whiteCheckedTreeItems.remove(treeElement);

	// proceed up the tree element hierarchy
	Object parent = treeContentProvider.getParent(treeElement);
	if (parent != null) {
		grayUpdateHierarchy(parent);
	}
}
/**
 *	Set the initial checked state of the passed list element to true.
 */
public void initialCheckListItem(Object element) {
	Object parent = treeContentProvider.getParent(element);
	selectAndReveal(parent);
	//Check the element in the viewer as if it had been manually checked
	listViewer.setChecked(element,true);
	//As this is not done from the UI then set the box for updating from the selection to false 
	listItemChecked(element, true, false);
	grayUpdateHierarchy(parent);
}
/**
 *	Set the initial checked state of the passed element to true,
 *	as well as to all of its children and associated list elements
 */
public void initialCheckTreeItem(Object element) {
	treeItemChecked(element, true);
	selectAndReveal(element);
}

private void selectAndReveal(Object treeElement){
	treeViewer.reveal(treeElement);
	IStructuredSelection selection = new StructuredSelection(treeElement);
	treeViewer.setSelection(selection);
}
	
/**
 *	Initialize this group's viewers after they have been laid out.
 */
protected void initialize() {
	treeViewer.setInput(root);
	this.expandedTreeNodes = new ArrayList();
	this.expandedTreeNodes.add(root);

}
/**
 *	Callback that's invoked when the checked status of an item in the list
 *	is changed by the user. Do not try and update the hierarchy if we are building the
 *  initial list.
 */
protected void listItemChecked(
	Object listElement,
	boolean state,
	boolean updatingFromSelection) {
	List checkedListItems = (List) checkedStateStore.get(currentTreeSelection);
	//If it has not been expanded do so as the selection of list items will affect gray state
	if (!expandedTreeNodes.contains(currentTreeSelection))
		expandTreeElement(currentTreeSelection);

	if (state) {
		if (checkedListItems == null) {
			// since the associated tree item has gone from 0 -> 1 checked
			// list items, tree checking may need to be updated
			grayCheckHierarchy(currentTreeSelection);
			checkedListItems = (List) checkedStateStore.get(currentTreeSelection);
		}
		checkedListItems.add(listElement);
	} else {
		checkedListItems.remove(listElement);
		if (checkedListItems.isEmpty()) {
			// since the associated tree item has gone from 1 -> 0 checked
			// list items, tree checking may need to be updated
			ungrayCheckHierarchy(currentTreeSelection);
		}
	}

	//Update the list with the selections if there are any
	if (checkedListItems.size() > 0)
		checkedStateStore.put(currentTreeSelection, checkedListItems);
	if (updatingFromSelection)
		grayUpdateHierarchy(currentTreeSelection);
}
/**
 *	Notify all checked state listeners that the passed element has had
 *	its checked state changed to the passed state
 */
protected void notifyCheckStateChangeListeners(final CheckStateChangedEvent event) {
	Object[] array = listeners.getListeners();
	for (int i = 0; i < array.length; i ++) {
		final ICheckStateListener l = (ICheckStateListener)array[i];
		Platform.run(new SafeRunnable() {
			public void run() {
				l.checkStateChanged(event);
			}
			public void handleException(Throwable e) {
				super.handleException(e);
				//If and unexpected exception happens, remove it
				//to make sure the workbench keeps running.
				removeCheckStateListener(l);
			}
		});
	}		
}
/**
 *Set the contents of the list viewer based upon the specified selected
 *tree element.  This also includes checking the appropriate list items.
 *
 *@param treeElement java.lang.Object
 */
protected void populateListViewer(final Object treeElement) {
	listViewer.setInput(treeElement);

	//If the element is white checked but not expanded we have not set up all of the children yet
	if (!(expandedTreeNodes.contains(treeElement))
		&& whiteCheckedTreeItems.contains(treeElement)) {

		//Potentially long operation - show a busy cursor
		BusyIndicator.showWhile(treeViewer.getControl().getDisplay(), new Runnable() {
			public void run() {
				setListForWhiteSelection(treeElement);
				listViewer.setAllChecked(true);
			}
		});

	} else {
		List listItemsToCheck = (List) checkedStateStore.get(treeElement);

		if (listItemsToCheck != null) {
			Iterator listItemsEnum = listItemsToCheck.iterator();
			while (listItemsEnum.hasNext())
				listViewer.setChecked(listItemsEnum.next(), true);
		}
	}
}
/**
 *	Logically gray-check all ancestors of treeItem by ensuring that they
 *	appear in the checked table. Add any elements to the selectedNodes
 *  so we can track that has been done.
 */
private void primeHierarchyForSelection(Object item, Set selectedNodes) {

	//Only prime it if we haven't visited yet
	if (selectedNodes.contains(item)) return;

	checkedStateStore.put(item, new ArrayList());

	//mark as expanded as we are going to populate it after this
	expandedTreeNodes.add(item);
	selectedNodes.add(item);

	Object parent = treeContentProvider.getParent(item);
	if (parent != null)
		primeHierarchyForSelection(parent, selectedNodes);
}
/**
 *	Remove the passed listener from self's collection of clients
 *	that listen for changes to element checked states
 *
 *	@param listener ICheckStateListener
 */
public void removeCheckStateListener(ICheckStateListener listener) {
	listeners.remove(listener);
}
/**
 *	Handle the selection of an item in the tree viewer
 *
 *	@param selection ISelection
 */
public void selectionChanged(SelectionChangedEvent event) {
	IStructuredSelection selection = (IStructuredSelection) event.getSelection();
	Object selectedElement = selection.getFirstElement();
	if (selectedElement == null) {
		currentTreeSelection = null;
		listViewer.setInput(currentTreeSelection);
		return;
	}

	// ie.- if not an item deselection
	if (selectedElement != currentTreeSelection)
		populateListViewer(selectedElement);
	
	currentTreeSelection = selectedElement;
}
/**
 * Select or deselect all of the elements in the tree depending on the value of the selection
 * boolean. Be sure to update the displayed files as well.
 */
public void setAllSelections(final boolean selection) {

	//If there is no root there is nothing to select
	if(root == null)
		return;

	//Potentially long operation - show a busy cursor
	BusyIndicator.showWhile(treeViewer.getControl().getDisplay(), new Runnable() {
		public void run() {
			setTreeChecked(root, selection);
			listViewer.setAllChecked(selection);
		}
	});
}
/**
 * The treeElement has been white selected. Get the list for the element and
 * set it in the checked state store.
 * @param treeElement the element being updated
 */
private void setListForWhiteSelection(Object treeElement) {

	Object[] listItems = listContentProvider.getElements(treeElement);
	List listItemsChecked = new ArrayList();
	for (int i = 0; i < listItems.length; ++i) {
		listItemsChecked.add(listItems[i]);
	}

	checkedStateStore.put(treeElement, listItemsChecked);
}
/**
 *	Set the list viewer's providers to those passed
 *
 *	@param contentProvider ITreeContentProvider
 *	@param labelProvider ILabelProvider
 */
public void setListProviders(IStructuredContentProvider contentProvider, ILabelProvider labelProvider) {
	listViewer.setContentProvider(contentProvider);
	listViewer.setLabelProvider(labelProvider);
}
/**
 *	Set the sorter that is to be applied to self's list viewer
 */
public void setListSorter(ViewerSorter sorter) {
	listViewer.setSorter(sorter);
}
/**
 * Set the root of the widget to be new Root. Regenerate all of the tables and lists from this
 * value.
 * @param newRoot 
 */
public void setRoot(Object newRoot) {
	this.root = newRoot;
	initialize();
}
/**
 *	Set the checked state of the passed tree element appropriately, and
 *	do so recursively to all of its child tree elements as well
 */
protected void setTreeChecked(Object treeElement, boolean state) {

	if (treeElement.equals(currentTreeSelection)) {
		listViewer.setAllChecked(state);
	}

	if (state) {
		setListForWhiteSelection(treeElement);
	} else
		checkedStateStore.remove(treeElement);

	setWhiteChecked(treeElement, state);
	treeViewer.setChecked(treeElement, state);
	treeViewer.setGrayed(treeElement, false);

	// now logically check/uncheck all children as well if it has been expanded
	if (expandedTreeNodes.contains(treeElement)) {
		Object[] children = treeContentProvider.getChildren(treeElement);
		for (int i = 0; i < children.length; ++i) {
			setTreeChecked(children[i], state);
		}
	}
}
/**
 *	Set the tree viewer's providers to those passed
 *
 *	@param contentProvider ITreeContentProvider
 *	@param labelProvider ILabelProvider
 */
public void setTreeProviders(ITreeContentProvider contentProvider, ILabelProvider labelProvider) {
	treeViewer.setContentProvider(contentProvider);
	treeViewer.setLabelProvider(labelProvider);
}
/**
 *	Set the sorter that is to be applied to self's tree viewer
 */
public void setTreeSorter(ViewerSorter sorter) {
	treeViewer.setSorter(sorter);
}
/**
 *	Adjust the collection of references to white-checked tree elements appropriately.
 *
 *	@param treeElement java.lang.Object
 *	@param isWhiteChecked boolean
 */
protected void setWhiteChecked(Object treeElement, boolean isWhiteChecked) {
	if (isWhiteChecked) {
		if (!whiteCheckedTreeItems.contains(treeElement))
			whiteCheckedTreeItems.add(treeElement);
	} else
		whiteCheckedTreeItems.remove(treeElement);
}
/**
 *	Handle the collapsing of an element in a tree viewer
 */
public void treeCollapsed(TreeExpansionEvent event) {
	// We don't need to do anything with this
}
/**
 *	Handle the expansionsion of an element in a tree viewer
 */
public void treeExpanded(TreeExpansionEvent event) {
	expandTreeElement(event.getElement());
}
/**
 *  Callback that's invoked when the checked status of an item in the tree
 *  is changed by the user.
 */
protected void treeItemChecked(Object treeElement,boolean state) {

	// recursively adjust all child tree elements appropriately
	setTreeChecked(treeElement,state);

	Object parent = treeContentProvider.getParent(treeElement);
	if (parent == null)
		return;

	// now update upwards in the tree hierarchy 
	if (state)
		grayCheckHierarchy(parent);
	else
		ungrayCheckHierarchy(parent);

	//Update the hierarchy but do not white select the parent
	grayUpdateHierarchy(parent);
}
/**
 *	Logically un-gray-check all ancestors of treeItem iff appropriate.
 */
protected void ungrayCheckHierarchy(Object treeElement) {
	if (!determineShouldBeAtLeastGrayChecked(treeElement))
		checkedStateStore.remove(treeElement);

	Object parent = treeContentProvider.getParent(treeElement);
	if (parent != null)
		ungrayCheckHierarchy(parent);
}
/**
 *	Set the checked state of self and all ancestors appropriately
 */
protected void updateHierarchy(Object treeElement) {

	boolean whiteChecked = determineShouldBeWhiteChecked(treeElement);
	boolean shouldBeAtLeastGray = determineShouldBeAtLeastGrayChecked(treeElement);

	treeViewer.setChecked(treeElement, shouldBeAtLeastGray);
	setWhiteChecked(treeElement, whiteChecked);
	if (whiteChecked)
		treeViewer.setGrayed(treeElement, false);
	else
		treeViewer.setGrayed(treeElement, shouldBeAtLeastGray);

	// proceed up the tree element hierarchy but gray select all of them
	Object parent = treeContentProvider.getParent(treeElement);
	if (parent != null) {
		grayUpdateHierarchy(parent);
	}
}
/**
 * Update the selections of the tree elements in items to reflect the new
 * selections provided.
 * @param Map with keys of Object (the tree element) and values of List (the selected
 * list elements).  NOTE: This method does not special case keys with no values (i.e., 
 * a tree element with an empty list).  If a tree element does not have any selected
 * items, do not include the element in the Map.
 */
public void updateSelections(Map items) {
	// We are replacing all selected items with the given selected items,
	// so reinitialize everything.
	this.listViewer.setAllChecked(false);
	this.treeViewer.setCheckedElements(new Object[0]);
	this.whiteCheckedTreeItems = new HashSet();
	Set selectedNodes = new HashSet();
	checkedStateStore = new HashMap();

	//Update the store before the hierarchy to prevent updating parents before all of the children are done
	Iterator keyIterator = items.keySet().iterator();
	while (keyIterator.hasNext()) {
		Object key = keyIterator.next();
		List selections = (List) items.get(key);
		//Replace the items in the checked state store with those from the supplied items			
		checkedStateStore.put(key, selections);
		selectedNodes.add(key);
		// proceed up the tree element hierarchy
		Object parent = treeContentProvider.getParent(key);
		if (parent != null) {
			// proceed up the tree element hierarchy and make sure everything is in the table		
			primeHierarchyForSelection(parent, selectedNodes);
		}
	}

	// Update the checked tree items.  Since each tree item has a selected
	// item, all the tree items will be gray checked.
	treeViewer.setCheckedElements(checkedStateStore.keySet().toArray());
	treeViewer.setGrayedElements(checkedStateStore.keySet().toArray());
	
	// Update the listView of the currently selected tree item.
	if (currentTreeSelection != null) {
		Object displayItems = items.get(currentTreeSelection);
		if (displayItems != null)
			listViewer.setCheckedElements(((List) displayItems).toArray());
	}
}
/** 
 * Set the focus on to the list widget.
 */
public void setFocus(){
	
	this.treeViewer.getTree().setFocus();
}

}


