/*******************************************************************************
 * 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= this.buildCheckedStateStore();
	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= this.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
	 */
	public 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 HashMap buildCheckedStateStore() {
		return new HashMap(9);
	}
	
	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);
	}
}