/*******************************************************************************
 * Copyright (c) 2000, 2008 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
 * Code originate from org.eclipse.jdt.internal.ui.jarpackager
 *******************************************************************************/
package org.eclipse.jpt.jaxb.ui.internal.wizards.schemagen;

import java.util.ArrayList;
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.jface.viewers.CheckStateChangedEvent;
import org.eclipse.jface.viewers.CheckboxTableViewer;
import org.eclipse.jface.viewers.CheckboxTreeViewer;
import org.eclipse.jface.viewers.ICheckStateListener;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.ITreeViewerListener;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TreeExpansionEvent;
import org.eclipse.jface.viewers.ViewerComparator;
import org.eclipse.jface.viewers.ViewerFilter;
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.Table;
import org.eclipse.swt.widgets.Tree;

/**
 *	Combines a CheckboxTreeViewer and CheckboxListViewer.
 *	All viewer selection-driven interactions are handled within this viewer
 */
public class CheckboxTreeAndListGroup implements ICheckStateListener, ISelectionChangedListener, ITreeViewerListener {

	private Object fRoot;
	private Object fCurrentTreeSelection;
	private List fExpandedTreeNodes= new ArrayList();
	private Map fCheckedStateStore= new HashMap(9);
	private List fWhiteCheckedTreeItems= new ArrayList();
	private List fListeners= new ArrayList();

	private ITreeContentProvider fTreeContentProvider;
	private IStructuredContentProvider fListContentProvider;
	private ILabelProvider fTreeLabelProvider;
	private ILabelProvider fListLabelProvider;

	// widgets
	private CheckboxTreeViewer fTreeViewer;
	private CheckboxTableViewer fListViewer;

	/**
	 *	Creates 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 parent composite
	 * @param rootObject
	 * @param treeContentProvider
	 * @param treeLabelProvider
	 * @param listContentProvider
	 * @param listLabelProvider
	 * @param style
	 * @param width the width
	 * @param height the height
	 */
	public CheckboxTreeAndListGroup(
			Composite parent,
			Object rootObject,
			ITreeContentProvider treeContentProvider,
			ILabelProvider treeLabelProvider,
			IStructuredContentProvider listContentProvider,
			ILabelProvider listLabelProvider,
			int style,
			int width,
			int height) {
		fRoot= rootObject;
		fTreeContentProvider= treeContentProvider;
		fListContentProvider= listContentProvider;
		fTreeLabelProvider= treeLabelProvider;
		fListLabelProvider= listLabelProvider;
		createContents(parent, width, height, style);
	}
	/**
	 * This method must be called just before this window becomes visible.
	 */
	public void aboutToOpen() {
		determineWhiteCheckedDescendents(fRoot);
		checkNewTreeElements(getTreeChildren(fRoot));
		fCurrentTreeSelection= null;

		//select the first element in the list
		Object[] elements= getTreeChildren(fRoot);
		Object primary= elements.length > 0 ? elements[0] : null;
		if (primary != null) {
			fTreeViewer.setSelection(new StructuredSelection(primary));
		}
		fTreeViewer.getControl().setFocus();
	}
	/**
	 *	Adds 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) {
		fListeners.add(listener);
	}
	/**
	 * Adds the receiver and all of it's ancestors to the checkedStateStore if they
	 * are not already there.
	 * @param treeElement
	 */
	private void addToHierarchyToCheckedStore(Object treeElement) {

		// if this tree element is already gray then its ancestors all are as well
		if (!fCheckedStateStore.containsKey(treeElement))
			fCheckedStateStore.put(treeElement, new ArrayList());

		Object parent= fTreeContentProvider.getParent(treeElement);
		if (parent != null)
			addToHierarchyToCheckedStore(parent);
	}
	/**
	 *	Returns 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= getTreeChildren(treeElement);
		for (int i= 0; i < children.length; ++i) {
			if (!fWhiteCheckedTreeItems.contains(children[i]))
				return false;
		}

		return true;
	}
	/**
	 *	Returns 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)fCheckedStateStore.get(treeElement);
		if (checkedElements == null) // ie.- tree item not even gray-checked
			return false;

		return getListItemsSize(treeElement) == checkedElements.size();
	}
	/**
	 *	Iterates through the passed elements which are being realized for the first
	 *	time and check each one in the tree viewer as appropriate
	 * @param elements
	 */
	protected void checkNewTreeElements(Object[] elements) {
		for (int i= 0; i < elements.length; ++i) {
			Object currentElement= elements[i];
			boolean checked= fCheckedStateStore.containsKey(currentElement);
			fTreeViewer.setChecked(currentElement, checked);
			fTreeViewer.setGrayed(
				currentElement,
				checked && !fWhiteCheckedTreeItems.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(fTreeViewer.getControl().getDisplay(), new Runnable() {
			public void run() {
				if (event.getCheckable().equals(fTreeViewer))
					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 width int
	 *	@param height int
	 * @param style
	 */
	protected void createContents(
		Composite parent,
		int width,
		int height,
		int style) {
		// group pane
		Composite composite= new Composite(parent, style);
		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, width / 2, height);
		createListViewer(composite, width / 2, height);

		initialize();
	}
	/**
	 *	Creates this group's list viewer.
	 * @param parent the parent composite
	 * @param width the width
	 * @param height the height
	 */
	protected void createListViewer(Composite parent, int width, int height) {
		fListViewer= CheckboxTableViewer.newCheckList(parent, SWT.BORDER);
		fListViewer.setUseHashlookup(true);
		GridData data= new GridData(GridData.FILL_BOTH);
		data.widthHint= width;
		data.heightHint= height;
		fListViewer.getTable().setLayoutData(data);
		fListViewer.setContentProvider(fListContentProvider);
		fListViewer.setLabelProvider(fListLabelProvider);
		fListViewer.addCheckStateListener(this);
	}
	/**
	 *	Creates this group's tree viewer.
	 * @param parent parent composite
	 * @param width the width
	 * @param height the height
	 */
	protected void createTreeViewer(Composite parent, int width, int height) {
		Tree tree= new Tree(parent, SWT.CHECK | SWT.BORDER);
		GridData data= new GridData(GridData.FILL_BOTH);
		data.widthHint= width;
		data.heightHint= height;
		tree.setLayoutData(data);

		fTreeViewer= new CheckboxTreeViewer(tree);
		fTreeViewer.setUseHashlookup(true);
		fTreeViewer.setContentProvider(fTreeContentProvider);
		fTreeViewer.setLabelProvider(fTreeLabelProvider);
		fTreeViewer.addTreeListener(this);
		fTreeViewer.addCheckStateListener(this);
		fTreeViewer.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 treeElement 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) fCheckedStateStore.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
		Object[] children= getTreeChildren(treeElement);
		for (int i= 0; i < children.length; ++i) {
			if (fCheckedStateStore.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 adds 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= getTreeChildren(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);
	}
	/**
	 * Causes the tree viewer to expand all its items
	 */
	public void expandAll() {
		fTreeViewer.expandAll();
	}
	/**
	 *	Answers a flat collection of all of the checked elements in the
	 *	list portion of self
	 *
	 *	@return java.util.Vector
	 */
	public Iterator getAllCheckedListItems() {
		Set result= new HashSet();
		Iterator listCollectionsEnum= fCheckedStateStore.values().iterator();
		while (listCollectionsEnum.hasNext())
			result.addAll((List)listCollectionsEnum.next());
		return result.iterator();
	}
	/**
	 *	Answer a collection of all of the checked elements in the tree portion
	 *	of self
	 *
	 *	@return java.util.Vector
	 */
	public Set getAllCheckedTreeItems() {
		return new HashSet(fCheckedStateStore.keySet());
	}
	/**
	 *	Answers the number of elements that have been checked by the
	 *	user.
	 *
	 *	@return int
	 */
	public int getCheckedElementCount() {
		return fCheckedStateStore.size();
	}
	/**
	 *	Returns 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= getListElements(treeElement);
		return elements.length;
	}
	/**
	 * Gets the table that displays the folder content
	 *
	 * @return the table used to show the list
	 */
	public Table getTable() {
		return fListViewer.getTable();
	}
	/**
	 * Gets the tree that displays the list for a folder
	 *
	 * @return the tree used to show the folders
	 */
	public Tree getTree() {
		return fTreeViewer.getTree();
	}
	/**
	 * Adds the given filter to the tree viewer and
	 * triggers refiltering and resorting of the elements.
	 *
	 * @param filter a viewer filter
	 */
	public void addTreeFilter(ViewerFilter filter) {
		fTreeViewer.addFilter(filter);
	}
	
	public void removeTreeFilter(ViewerFilter filter) {
		fTreeViewer.removeFilter(filter);
	}

	/**
	 * Adds the given filter to the list viewer and
	 * triggers refiltering and resorting of the elements.
	 *
	 * @param filter a viewer filter
	 */
	public void addListFilter(ViewerFilter filter) {
		fListViewer.addFilter(filter);
	}

	/**
	 *	Logically gray-check all ancestors of treeItem by ensuring that they
	 *	appear in the checked table
	 * @param treeElement
	 */
	protected void grayCheckHierarchy(Object treeElement) {

		// if this tree element is already gray then its ancestors all are as well
		if (fCheckedStateStore.containsKey(treeElement))
			return; // no need to proceed upwards from here

		fCheckedStateStore.put(treeElement, new ArrayList());
		if (determineShouldBeWhiteChecked(treeElement)) {
			setWhiteChecked(treeElement, true);
		}
		Object parent= fTreeContentProvider.getParent(treeElement);
		if (parent != null)
			grayCheckHierarchy(parent);
	}
	/**
	 *	Sets the initial checked state of the passed list element to true.
	 * @param element
	 */
	public void initialCheckListItem(Object element) {
		Object parent= fTreeContentProvider.getParent(element);
		fCurrentTreeSelection= parent;
		//As this is not done from the UI then set the box for updating from the selection to false
		listItemChecked(element, true, false);
		updateHierarchy(parent);
	}
	/**
	 *	Sets the initial checked state of the passed element to true,
	 *	as well as to all of its children and associated list elements
	 * @param element
	 */
	public void initialCheckTreeItem(Object element) {
		treeItemChecked(element, true);
	}
	/**
	 *	Initializes this group's viewers after they have been laid out.
	 */
	protected void initialize() {
		fTreeViewer.setInput(fRoot);
	}
	/**
	 *	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.
	 * @param listElement
	 * @param state
	 * @param updatingFromSelection
	 */
	protected void listItemChecked(
		Object listElement,
		boolean state,
		boolean updatingFromSelection) {
		List checkedListItems= (List) fCheckedStateStore.get(fCurrentTreeSelection);

		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(fCurrentTreeSelection);
				checkedListItems= (List) fCheckedStateStore.get(fCurrentTreeSelection);
			}
			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(fCurrentTreeSelection);
			}
		}

		if (updatingFromSelection)
			updateHierarchy(fCurrentTreeSelection);
	}
	/**
	 *	Notifies all checked state listeners that the passed element has had
	 *	its checked state changed to the passed state
	 * @param event
	 */
	protected void notifyCheckStateChangeListeners(CheckStateChangedEvent event) {
		Iterator listenersEnum= fListeners.iterator();
		while (listenersEnum.hasNext())
			 ((ICheckStateListener) listenersEnum.next()).checkStateChanged(event);
	}
	/**
	 *Sets 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) {
		if (treeElement == fCurrentTreeSelection)
			return;
		fCurrentTreeSelection= treeElement;
		fListViewer.setInput(treeElement);
		List listItemsToCheck= (List) fCheckedStateStore.get(treeElement);

		if (listItemsToCheck != null) {
			Iterator listItemsEnum= listItemsToCheck.iterator();
			while (listItemsEnum.hasNext())
				fListViewer.setChecked(listItemsEnum.next(), true);
		}
	}
	/**
	 *	Removes 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) {
		fListeners.remove(listener);
	}
	/**
	 *	Handles the selection of an item in the tree viewer
	 *
	 *	@param event ISelection
	 */
	public void selectionChanged(final SelectionChangedEvent event) {
		BusyIndicator.showWhile(getTable().getShell().getDisplay(), new Runnable() {
			public void run() {
				IStructuredSelection selection= (IStructuredSelection) event.getSelection();
				Object selectedElement= selection.getFirstElement();
				if (selectedElement == null) {
					fCurrentTreeSelection= null;
					fListViewer.setInput(fCurrentTreeSelection);
					return;
				}
				populateListViewer(selectedElement);
			}
		});
	}

	/**
	 * Selects 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.
	 * @param selection
	 */
	public void setAllSelections(final boolean selection) {

		//Potentially long operation - show a busy cursor
		BusyIndicator.showWhile(fTreeViewer.getControl().getDisplay(), new Runnable() {
			public void run() {
				setTreeChecked(fRoot, selection);
				fListViewer.setAllChecked(selection);
			}
		});
	}

	/**
	 *	Sets the list viewer's providers to those passed
	 *
	 *	@param contentProvider ITreeContentProvider
	 *	@param labelProvider ILabelProvider
	 */
	public void setListProviders(
		IStructuredContentProvider contentProvider,
		ILabelProvider labelProvider) {
		fListViewer.setContentProvider(contentProvider);
		fListViewer.setLabelProvider(labelProvider);
	}
	/**
	 *	Sets the sorter that is to be applied to self's list viewer
	 * @param comparator
	 */
	public void setListComparator(ViewerComparator comparator) {
		fListViewer.setComparator(comparator);
	}
	/**
	 * Sets 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.fRoot= newRoot;
		initialize();
	}
	/**
	 *	Sets the checked state of the passed tree element appropriately, and
	 *	do so recursively to all of its child tree elements as well
	 * @param treeElement
	 * @param state
	 */
	protected void setTreeChecked(Object treeElement, boolean state) {

		if (treeElement.equals(fCurrentTreeSelection)) {
			fListViewer.setAllChecked(state);
		}

		if (state) {
			Object[] listItems= getListElements(treeElement);
			List listItemsChecked= new ArrayList();
			for (int i= 0; i < listItems.length; ++i)
				listItemsChecked.add(listItems[i]);

			fCheckedStateStore.put(treeElement, listItemsChecked);
		} else
			fCheckedStateStore.remove(treeElement);

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

		// now logically check/uncheck all children as well
		Object[] children= getTreeChildren(treeElement);
		for (int i= 0; i < children.length; ++i) {
			setTreeChecked(children[i], state);
		}
	}
	/**
	 *	Sets the tree viewer's providers to those passed
	 *
	 *	@param contentProvider ITreeContentProvider
	 *	@param labelProvider ILabelProvider
	 */
	public void setTreeProviders(
		ITreeContentProvider contentProvider,
		ILabelProvider labelProvider) {
		fTreeViewer.setContentProvider(contentProvider);
		fTreeViewer.setLabelProvider(labelProvider);
	}
	/**
	 *	Sets the sorter that is to be applied to self's tree viewer
	 * @param sorter
	 */
	public void setTreeComparator(ViewerComparator sorter) {
		fTreeViewer.setComparator(sorter);
	}
	/**
	 *	Adjusts 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 (!fWhiteCheckedTreeItems.contains(treeElement))
				fWhiteCheckedTreeItems.add(treeElement);
		} else
			fWhiteCheckedTreeItems.remove(treeElement);
	}
	/**
	 *	Handle the collapsing of an element in a tree viewer
	 * @param event
	 */
	public void treeCollapsed(TreeExpansionEvent event) {
		// We don't need to do anything with this
	}

	/**
	 *	Handles the expansionsion of an element in a tree viewer
	 * @param event
	 */
	public void treeExpanded(TreeExpansionEvent event) {

		Object item= event.getElement();

		// 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 (!fExpandedTreeNodes.contains(item)) {
			fExpandedTreeNodes.add(item);
			checkNewTreeElements(getTreeChildren(item));
		}
	}

	/**
	 *  Callback that's invoked when the checked status of an item in the tree
	 *  is changed by the user.
	 * @param treeElement
	 * @param state
	 */
	protected void treeItemChecked(Object treeElement, boolean state) {

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

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

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

		updateHierarchy(treeElement);
	}
	/**
	 *	Logically un-gray-check all ancestors of treeItem iff appropriate.
	 * @param treeElement
	 */
	protected void ungrayCheckHierarchy(Object treeElement) {
		if (!determineShouldBeAtLeastGrayChecked(treeElement))
			fCheckedStateStore.remove(treeElement);

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

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

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

		// proceed up the tree element hierarchy
		Object parent= fTreeContentProvider.getParent(treeElement);
		if (parent != null) {
			updateHierarchy(parent);
		}
	}
	/**
	 * Update the selections of the tree elements in items to reflect the new
	 * selections provided.
	 *
	 * @param items with keys of Object (the tree element) and values of List (the selected
	 * list elements).
	 */
	public void updateSelections(final Map items) {

		//Potentially long operation - show a busy cursor
		BusyIndicator.showWhile(fTreeViewer.getControl().getDisplay(), new Runnable() {
			public void run() {
				handleUpdateSelection(items);
			}
		});
	}
	/**
	 * Returns the result of running the given elements through the filters.
	 * @param filters
	 *
	 * @param elements the elements to filter
	 * @return only the elements which all filters accept
	 */
	protected Object[] filter(ViewerFilter[] filters, Object[] elements) {
		if (filters != null) {
			ArrayList filtered = new ArrayList(elements.length);
			for (int i = 0; i < elements.length; i++) {
				boolean add = true;
				for (int j = 0; j < filters.length; j++) {
					add = filters[j].select(null, null, elements[i]);
					if (!add)
						break;
				}
				if (add)
					filtered.add(elements[i]);
			}
			return filtered.toArray();
		}
		return elements;
	}

	private Object[] getTreeChildren(Object element) {
		return filter(fTreeViewer.getFilters(), fTreeContentProvider.getChildren(element));
	}

	private Object[] getListElements(Object element) {
		return filter(fListViewer.getFilters(), fListContentProvider.getElements(element));
	}

	public Set getWhiteCheckedTreeItems() {
		return new HashSet(fWhiteCheckedTreeItems);
	}

	private void handleUpdateSelection(Map items) {
		Iterator keyIterator= items.keySet().iterator();

		//Update the store before the hierarchy to prevent updating parents before all of the children are done
		while (keyIterator.hasNext()) {
			Object key= keyIterator.next();
			//Replace the items in the checked state store with those from the supplied items
			List selections= (List) items.get(key);
			if (selections.size() == 0)
				//If it is empty remove it from the list
				fCheckedStateStore.remove(key);
			else {
				fCheckedStateStore.put(key, selections);
				// proceed up the tree element hierarchy
				Object parent= fTreeContentProvider.getParent(key);
				if (parent != null) {
					addToHierarchyToCheckedStore(parent);
				}
			}
		}

		//Now update hierarchies
		keyIterator= items.keySet().iterator();

		while (keyIterator.hasNext()) {
			Object key= keyIterator.next();
			updateHierarchy(key);
			if (fCurrentTreeSelection != null && fCurrentTreeSelection.equals(key)) {
				fListViewer.setAllChecked(false);
				fListViewer.setCheckedElements(((List) items.get(key)).toArray());
			}
		}
	}

	/**
	 * Checks if an element is grey checked.
	 * @param object
	 * @return if an element is grey checked.
	 */
	public boolean isTreeItemGreyChecked(Object object) {
		return fTreeViewer.getGrayed(object);
	}

	/**
	 * For a given element, expand its chidren to a level.
	 * @param object
	 * @param level
	 */
	public void expandTreeToLevel(Object object, int level) {
		fTreeViewer.expandToLevel(object, level);
	}
	/**
	 * @param selection
	 */
	public void setTreeSelection(ISelection selection) {
		fTreeViewer.setSelection(selection);
	}
}