/*******************************************************************************
 * Copyright (c) 2000, 2018 IBM Corporation and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.ui.internal.editors.text;

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

import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.BusyIndicator;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Tree;

import org.eclipse.core.runtime.ListenerList;
import org.eclipse.core.runtime.SafeRunner;

import org.eclipse.core.resources.IContainer;

import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.util.SafeRunnable;
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.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;

/*
 * XXX: This is an copy of the internal ResourceTreeAndListGroup class, see http://bugs.eclipse.org/147027
 */

/**
 * Workbench-level composite that combines a CheckboxTreeViewer and
 * CheckboxListViewer. All viewer selection-driven interactions are handled
 * within this object
 */
class SelectResourcesBlock implements ICheckStateListener, ISelectionChangedListener, ITreeViewerListener {


	/**
	 * The IElementFilter is a interface that defines
	 * the API for filtering the current selection of
	 * a ResourceTreeAndListGroup in order to find a
	 * subset to update as the result of a type filtering.
	 * This is meant as an internal class and is used exclusively
	 * by the import dialog.
	 */
	interface IElementFilter {

		void filterElements(Collection<Object> elements) throws InterruptedException;

		void filterElements(Object[] elements) throws InterruptedException;
	}


	private Object root;

	private Object currentTreeSelection;

	private Collection<Object> expandedTreeNodes= new HashSet<>();

	private Map<Object, List<Object>> checkedStateStore= new HashMap<>(9);

	private Collection<Object> whiteCheckedTreeItems= new HashSet<>();

	private ListenerList<ICheckStateListener> listeners= new ListenerList<>(ListenerList.IDENTITY);

	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 hard code one of the sizing dimensions, specify
	 * the other dimension's value as -1)
	 *
	 * @param parent the parent composite
	 * @param rootObject the root object
	 * @param treeContentProvider the tree content provider
	 * @param treeLabelProvider the tree label provider
	 * @param listContentProvider the list content provider
	 * @param listLabelProvider the list label provider
	 * @param style the style flags for the new Composite
	 * @param useHeightHint If true then use the height hint to make this group big enough
	 */
	public SelectResourcesBlock(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);
	}

	/**
	 * 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);
	}

	/**
	 * Iterates over the passed elements which are being realized for the
	 * first time and check each one in the tree viewer as appropriate.
	 *
	 * @param elements the elements
	 */
	private 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 the check state event
	 * @see org.eclipse.jface.viewers.ICheckStateListener#checkStateChanged(org.eclipse.jface.viewers.CheckStateChangedEvent)
	 */
	@Override
	public void checkStateChanged(final CheckStateChangedEvent event) {

		//Potentially long operation - show a busy cursor
		BusyIndicator.showWhile(treeViewer.getControl().getDisplay(), () -> {
			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 style the style flags for the new Composite
	 * @param useHeightHint If true use the preferredHeight.
	 */
	private 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();
	}

	/**
	 * Creates this block's list viewer.
	 *
	 * @param parent the parent control
	 * @param useHeightHint if <code>true</code> use the height hints
	 */
	private 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;
		data.widthHint= getViewerWidthHint(parent);
		listViewer.getTable().setLayoutData(data);
		listViewer.getTable().setFont(parent.getFont());
		listViewer.setContentProvider(listContentProvider);
		listViewer.setLabelProvider(listLabelProvider);
		listViewer.addCheckStateListener(this);
	}

	/**
	 * Create this block's tree viewer.
	 *
	 * @param parent the parent control
	 * @param useHeightHint if <code>true</code> use the height hints
	 */
	private 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;
		data.widthHint= getViewerWidthHint(parent);
		tree.setLayoutData(data);
		tree.setFont(parent.getFont());

		treeViewer= new CheckboxTreeViewer(tree);
		treeViewer.setUseHashlookup(true);
		treeViewer.setContentProvider(treeContentProvider);
		treeViewer.setLabelProvider(treeLabelProvider);
		treeViewer.addTreeListener(this);
		treeViewer.addCheckStateListener(this);
		treeViewer.addSelectionChangedListener(this);
	}

	private int getViewerWidthHint(Control control) {
		GC gc= new GC(control);
		int width= Dialog.convertWidthInCharsToPixels(gc.getFontMetrics(), 50);
		gc.dispose();
		return width;
	}
	
	/**
	 * 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.
	 *
	 * @param treeElement java.lang.Object
	 * @return boolean
	 */
	private 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<Object> checked= 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;
	}

	/**
	 * Expands an element in a tree viewer.
	 *
	 * @param element the element to be expanded
	 */
	private void expandTreeElement(final Object element) {
		BusyIndicator.showWhile(treeViewer.getControl().getDisplay(), () -> {

			// 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(element))
				checkNewTreeElements(treeContentProvider.getChildren(element));
			else {

				expandedTreeNodes.add(element);
				if (whiteCheckedTreeItems.contains(element)) {
					//If this is the first expansion and this is a white
					// checked node then check the children
					Object[] children= treeContentProvider.getChildren(element);
					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(element);
				}
			}

		});
	}

	/**
	 * Adds all of the selected children of <code>treeElement</code> to result recursively. This
	 * does not set any values in the checked state.
	 *
	 * @param  treeElement the tree element being queried
	 * @param parentLabel the parent label
	 * @param addAll a boolean to indicate if the checked state store needs to be queried
	 * @param filter the filter being used on the data
	 * @throws InterruptedException in case of interruption
	 */
	private void findAllSelectedListElements(Object treeElement, String parentLabel, boolean addAll, IElementFilter filter) throws InterruptedException {

		String fullLabel= null;

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

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

		}
	}

	/**
	 * 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<Object> result) {

		if (whiteCheckedTreeItems.contains(treeElement))
			result.add(treeElement);
		else {
			Collection<Object> listChildren= checkedStateStore.get(treeElement);
			//if it is not in the store then it and its 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 canceled then
	 * return null
	 *
	 * @param filter - the filter for the data
	 * @throws InterruptedException in case of interruption
	 */
	private void getAllCheckedListItems(IElementFilter filter) 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);
		}
	}

	/**
	 * 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<Object> getAllCheckedListItems() {

		final ArrayList<Object> returnValue= new ArrayList<>();

		IElementFilter passThroughFilter= new IElementFilter() {

			@Override
			public void filterElements(Collection<Object> elements) throws InterruptedException {
				returnValue.addAll(elements);
			}

			@Override
			public void filterElements(Object[] elements) throws InterruptedException {
				for (int i= 0; i < elements.length; i++) {
					returnValue.add(elements[i]);
				}
			}
		};

		try {
			getAllCheckedListItems(passThroughFilter);
		} 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<Object> getAllWhiteCheckedItems() {

		List<Object> 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;
	}

	/**
	 * Logically gray-check all ancestors of <code>treeElement</code> by ensuring that they
	 * appear in the checked table.
	 *
	 * @param treeElement the tree element
	 */
	private 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.
	 *
	 * @param treeElement the tree element
	 */
	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);
		}
	}

	public 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.
	 */
	private void initialize() {
		treeViewer.setInput(root);
		this.expandedTreeNodes= new ArrayList<>();
		this.expandedTreeNodes.add(root);
		Object[] topElements= treeContentProvider.getElements(root);
		if (topElements.length == 1)
			treeViewer.setExpandedState(topElements[0], true);
	}

	/**
	 * 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 the list element
	 * @param state the checked state
	 * @param updatingFromSelection <code>true</code> if we are inside an
	 *            update caused by selection
	 */
	private void listItemChecked(Object listElement, boolean state, boolean updatingFromSelection) {
		List<Object> checkedListItems= 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= 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 with the given event.
	 *
	 * @param event the event
	 */
	private void notifyCheckStateChangeListeners(final CheckStateChangedEvent event) {
		for (ICheckStateListener l : listeners) {
			SafeRunner.run(new SafeRunnable() {
				@Override
				public void run() {
					l.checkStateChanged(event);
				}
			});
		}
	}

	/**
	 * 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
	 */
	private 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(), () -> {
				setListForWhiteSelection(treeElement);
				listViewer.setAllChecked(true);
			});

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

			if (listItemsToCheck != null) {
				Iterator<Object> listItemsEnum= listItemsToCheck.iterator();
				while (listItemsEnum.hasNext())
					listViewer.setChecked(listItemsEnum.next(), true);
			}
		}
	}

	/**
	 * Logically gray-check all ancestors of <code>item</code> by ensuring
	 * that they appear in the checked table. Add any elements to the
	 * <code>selectedNodes</code> so we can track that has been done.
	 *
	 * @param item the tree item
	 * @param selectedNodes the set of selected nodes
	 */
	private void primeHierarchyForSelection(Object item, Set<Object> 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 event SelectionChangedEvent
	 */
	@Override
	public void selectionChanged(SelectionChangedEvent event) {
		IStructuredSelection selection= event.getStructuredSelection();
		Object selectedElement= selection.getFirstElement();
		if (selectedElement == null) {
			currentTreeSelection= null;
			listViewer.setInput(null);
			return;
		}

		// i.e.- 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 <code>selection</code>. Be sure to update the displayed files as
	 * well.
	 *
	 * @param selection <code>true</code> if selection should be set,
	 *            <code>false</code> if it should be removed
	 */
	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(), () -> {
			setTreeChecked(root, selection);
			listViewer.setAllChecked(selection);
		});
	}
	
	public void refresh() {
		//Potentially long operation - show a busy cursor
		BusyIndicator.showWhile(treeViewer.getControl().getDisplay(), () -> {
			treeViewer.refresh();
			populateListViewer(currentTreeSelection);
		});
	}

	/**
	 * 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<Object> listItemsChecked= new ArrayList<>();
		for (int i= 0; i < listItems.length; ++i) {
			listItemsChecked.add(listItems[i]);
		}

		checkedStateStore.put(treeElement, listItemsChecked);
	}

	/**
	 * Set the <code>comparator</code> that is to be applied to self's list viewer
	 *
	 * @param comparator the comparator to be set
	 */
	public void setListComparator(ViewerComparator comparator) {
		listViewer.setComparator(comparator);
	}

	/**
	 * Set the checked state of the passed <code>treeElement</code>
	 * appropriately, and do so recursively to all of its child tree elements as
	 * well.
	 *
	 * @param treeElement the root of the subtree
	 * @param state <code>true</code> if checked, <code>false</code> otherwise
	 */
	private 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 comparator that is to be applied to self's tree viewer.
	 *
	 * @param comparator the comparator to be set
	 */
	public void setTreeComparator(ViewerComparator comparator) {
		treeViewer.setComparator(comparator);
	}

	/**
	 * Adjust the collection of references to white-checked tree elements
	 * appropriately.
	 *
	 * @param treeElement the root of the subtree
	 * @param isWhiteChecked <code>true</code> if white checked,
	 *            <code>false</code> otherwise
	 */
	private 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.
	 *
	 * @param event the collapse event
	 */
	@Override
	public void treeCollapsed(TreeExpansionEvent event) {
		// We don't need to do anything with this
	}

	/**
	 * Handle the expansion of an element in a tree viewer.
	 *
	 * @param event the expansion event
	 */
	@Override
	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.
	 *
	 * @param treeElement the tree element that has been checked/unchecked
	 * @param state <code>true</code> if checked, <code>false</code> if
	 *            unchecked
	 */
	private 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 <code>treeElement</code> if
	 * appropriate.
	 *
	 * @param treeElement the root of the subtree
	 */
	private void ungrayCheckHierarchy(Object treeElement) {
		if (!determineShouldBeAtLeastGrayChecked(treeElement))
			checkedStateStore.remove(treeElement);

		Object parent= treeContentProvider.getParent(treeElement);
		if (parent != null)
			ungrayCheckHierarchy(parent);
	}

	/**
	 * Update the selections of the tree elements in items to reflect the new
	 * selections provided.
	 *
	 * @param items 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<IContainer, List<Object>> 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<Object> selectedNodes= new HashSet<>();
		checkedStateStore= new HashMap<>();

		// Update the store before the hierarchy to prevent updating parents
		// before all of the children are done
		
		for (Entry<IContainer, List<Object>> entry : items.entrySet()) {
			Object key = entry.getKey();
			primeHierarchyForSelection(key, selectedNodes);
			checkedStateStore.put(key, entry.getValue());
		}
			

		// 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());
		}
	}
}
