/*******************************************************************************
 * Copyright (c) 2006, 2016 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
 *     Wind River Systems - Fix for viewer state save/restore [188704]
 *     Pawel Piech (Wind River) - added support for a virtual tree model viewer (Bug 242489)
 *     Dorin Ciuca - Top index fix (Bug 324100)
 *     Anton Leherbauer (Wind River) - REVEAL delta does not always work reliably (Bug 438724)
 *******************************************************************************/
package org.eclipse.debug.internal.ui.viewers.model;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.ISafeRunnable;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.ListenerList;
import org.eclipse.core.runtime.SafeRunner;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.debug.internal.ui.DebugUIPlugin;
import org.eclipse.debug.internal.ui.viewers.model.provisional.ICheckboxModelProxy;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementContentProvider;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelChangedListener;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelProxy;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelProxy2;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelProxyFactory;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelProxyFactory2;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IStateUpdateListener;
import org.eclipse.debug.internal.ui.viewers.model.provisional.ITreeModelViewer;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerUpdate;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerUpdateListener;
import org.eclipse.debug.internal.ui.viewers.model.provisional.TreeModelViewerFilter;
import org.eclipse.jface.viewers.IContentProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.TreePath;
import org.eclipse.jface.viewers.TreeSelection;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerFilter;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.progress.WorkbenchJob;

/**
 * Content provider for a virtual tree.
 *
 * @since 3.3
 */
public class TreeModelContentProvider implements ITreeModelContentProvider, IContentProvider, IModelChangedListener {

    /**
     * Tree model viewer that this content provider is used with.
     */
    private IInternalTreeModelViewer fViewer;

    /**
     * Mask used to filter delta updates coming from the model.
     */
    private int fModelDeltaMask = ~0;

    /**
     * Map tree paths to model proxy responsible for element
     *
     * Used to install different model proxy instances for one element depending
     * on the tree path.
     */
	private Map<TreePath, IModelProxy> fTreeModelProxies = new HashMap<TreePath, IModelProxy>(); // tree
																									// model
																									// proxy
																									// by
                                                   // element tree path

    /**
     * Map element to model proxy responsible for it.
     *
     * Used to install a single model proxy which is responsible for all
     * instances of an element in the model tree.
     */
	private Map<Object, IModelProxy> fModelProxies = new HashMap<Object, IModelProxy>(); // model
																							// proxy
																							// by
																							// element

    /**
     * Map of nodes that have been filtered from the viewer.
     */
    private FilterTransform fTransform = new FilterTransform();

    /**
     * Model listeners
     */
	private ListenerList<IModelChangedListener> fModelListeners = new ListenerList<>();

    /**
     * Viewer update listeners
     */
	private ListenerList<IViewerUpdateListener> fUpdateListeners = new ListenerList<>();

    /**
     * Flag indicating whether we are currently in a model sequence.
     * @see IViewerUpdateListener
     */
    private boolean fModelSequenceRunning = false;

    /**
     * Map of updates in progress: element path -> list of requests
     */
	private Map<TreePath, List<ViewerUpdateMonitor>> fRequestsInProgress = new HashMap<TreePath, List<ViewerUpdateMonitor>>();

    /**
     * Map of dependent requests waiting for parent requests to complete:
     * element path -> list of requests
     */
	private Map<TreePath, List<ViewerUpdateMonitor>> fWaitingRequests = new HashMap<TreePath, List<ViewerUpdateMonitor>>();

	private List<ViewerUpdateMonitor> fCompletedUpdates = new ArrayList<ViewerUpdateMonitor>();

    private Runnable fCompletedUpdatesRunnable;

    private ViewerStateTracker fStateTracker = new ViewerStateTracker(this);

	private TreePath fRevealPath;

	private int fRevealIndex;

    /**
     * Update type constants
     */
    static final int UPDATE_SEQUENCE_BEGINS = 0;

    static final int UPDATE_SEQUENCE_COMPLETE = 1;

    static final int UPDATE_BEGINS = 2;

    static final int UPDATE_COMPLETE = 3;


    /**
     * Constant for an empty tree path.
     */
    static final TreePath EMPTY_TREE_PATH = new TreePath(new Object[] {});

    @Override
	public void dispose() {
        if (fViewer == null) {
			return;
		}
		fDelayedDoModelChangeJob.shutdown();

        Assert.isTrue( getViewer().getDisplay().getThread() == Thread.currentThread() );

        // cancel pending updates
		for (List<ViewerUpdateMonitor> requests : fRequestsInProgress.values()) {
			for (ViewerUpdateMonitor vu : requests) {
				vu.cancel();
            }
        }
        fWaitingRequests.clear();

        fStateTracker.dispose();
        fModelListeners.clear();
        fUpdateListeners.clear();
        disposeAllModelProxies();

        synchronized(this) {
            fViewer = null;
        }
    }

    /**
     * @return Returns whether the content provider is disposed.
     */
    boolean isDisposed() {
        synchronized(this) {
            return fViewer == null;
        }
    }

    @Override
	public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
        synchronized(this) {
            fViewer = (IInternalTreeModelViewer) viewer;
        }

        Assert.isTrue( fViewer.getDisplay().getThread() == Thread.currentThread() );

        if (oldInput != null) {
            fStateTracker.saveViewerState(oldInput);
        }
    }

    @Override
	public void postInputChanged(IInternalTreeModelViewer viewer, Object oldInput, Object newInput) {
        Assert.isTrue( getViewer().getDisplay().getThread() == Thread.currentThread() );

        cancelSubtreeUpdates(TreePath.EMPTY);
        disposeAllModelProxies();
        cancelSubtreeUpdates(TreePath.EMPTY);
        fTransform.clear();
        if (newInput != null) {
            installModelProxy(newInput, TreePath.EMPTY);
            fStateTracker.restoreViewerState(newInput);
        }
    }

    @Override
	public void addViewerUpdateListener(IViewerUpdateListener listener) {
        fUpdateListeners.add(listener);
    }

    @Override
	public void removeViewerUpdateListener(IViewerUpdateListener listener) {
        fUpdateListeners.remove(listener);
    }

    @Override
	public void addStateUpdateListener(IStateUpdateListener listener) {
        fStateTracker.addStateUpdateListener(listener);
    }

    @Override
	public void preserveState(TreePath path) {
        fStateTracker.appendToPendingStateDelta(path);
    }

    @Override
	public void removeStateUpdateListener(IStateUpdateListener listener) {
        fStateTracker.removeStateUpdateListener(listener);
    }

    @Override
	public void addModelChangedListener(IModelChangedListener listener) {
        fModelListeners.add(listener);
    }

    @Override
	public void removeModelChangedListener(IModelChangedListener listener) {
        fModelListeners.remove(listener);
    }

    @Override
	public void cancelRestore(final TreePath path, final int flags) {
        fStateTracker.cancelRestore(path, flags);
    }

    @Override
	public boolean setChecked(TreePath path, boolean checked) {
        IModelProxy elementProxy = getElementProxy(path);
        if (elementProxy instanceof ICheckboxModelProxy) {
            return ((ICheckboxModelProxy) elementProxy).setChecked(getPresentationContext(), getViewer().getInput(), path, checked);
        }
        return false;
    }

    /**
     * Installs the model proxy for the given element into this content provider
     * if not already installed.
     * @param input the input to install the model proxy on
     * @param path the {@link TreePath} to install the proxy for
     */
    private void installModelProxy(Object input, TreePath path) {

        if (!fTreeModelProxies.containsKey(path) && !fModelProxies.containsKey(path.getLastSegment())) {
            Object element = path.getSegmentCount() != 0 ? path.getLastSegment() : input;
            IModelProxy proxy = null;
            IModelProxyFactory2 modelProxyFactory2 = ViewerAdapterService.getModelProxyFactory2(element);
            if (modelProxyFactory2 != null) {
                proxy = modelProxyFactory2.createTreeModelProxy(input, path, getPresentationContext());
                if (proxy != null) {
                    fTreeModelProxies.put(path, proxy);
                }
            }
            if (proxy == null) {
                IModelProxyFactory modelProxyFactory = ViewerAdapterService.getModelProxyFactory(element);
                if (modelProxyFactory != null) {
                    proxy = modelProxyFactory.createModelProxy(element, getPresentationContext());
                    if (proxy != null) {
                        fModelProxies.put(element, proxy);
                    }
                }
            }

            if (proxy instanceof IModelProxy2) {
                proxy.addModelChangedListener(this);
                ((IModelProxy2)proxy).initialize(getViewer());
            } else if (proxy != null) {
                final IModelProxy finalProxy = proxy;
                Job job = new Job("Model Proxy installed notification job") {//$NON-NLS-1$
                    @Override
					protected IStatus run(IProgressMonitor monitor) {
                        if (!monitor.isCanceled()) {
                            IPresentationContext context = null;
                            Viewer viewer = null;
                            synchronized (TreeModelContentProvider.this) {
                                if (!isDisposed()) {
                                    context = getPresentationContext();
                                    viewer = (Viewer) getViewer();
                                }
                            }
                            if (viewer != null && context != null && !finalProxy.isDisposed()) {
                                finalProxy.init(context);
                                finalProxy.addModelChangedListener(TreeModelContentProvider.this);
                                finalProxy.installed(viewer);
                            }
                        }
                        return Status.OK_STATUS;
                    }

                    @Override
					public boolean shouldRun() {
                        return !isDisposed();
                    }
                };
                job.setSystem(true);
                job.schedule();
            }
        }
    }

    /**
     * Finds the model proxy that an element with a given path is associated with.
     * @param path Path of the element.
     * @return Element's model proxy.
     */
    private IModelProxy getElementProxy(TreePath path) {
        while (path != null) {
            IModelProxy proxy = fTreeModelProxies.get(path);
            if (proxy != null) {
                return proxy;
            }

            Object element = path.getSegmentCount() == 0 ? getViewer().getInput() : path.getLastSegment();
            proxy = fModelProxies.get(element);
            if (proxy != null) {
                return proxy;
            }

            path = path.getParentPath();
        }
        return null;
    }

    /**
     * Removes all model proxies
     */
    private void disposeAllModelProxies() {
        Assert.isTrue( getViewer().getDisplay().getThread() == Thread.currentThread() );
		for (IModelProxy proxy : fModelProxies.values()) {
            proxy.dispose();
        }
        fModelProxies.clear();
		for (IModelProxy proxy : fTreeModelProxies.values()) {
            proxy.dispose();
        }
        fTreeModelProxies.clear();
    }

    /**
     * Removes the model proxy installed for the given element, if any.
     * @param path the {@link TreePath} to dispose the model proxy for
     */
    private void disposeModelProxy(TreePath path) {
        IModelProxy proxy = fTreeModelProxies.remove(path);
        if (proxy != null) {
            proxy.dispose();
        }
        proxy = fModelProxies.remove(path.getLastSegment());
        if (proxy != null) {
            proxy.dispose();
        }
    }

	private static class DelayedDoModelChange {
		public final IModelDelta delta;
		public final IModelProxy proxy;

		public DelayedDoModelChange(final IModelDelta delta, final IModelProxy proxy) {
			this.delta = delta;
			this.proxy = proxy;
		}
	}

	private class DelayedDoModelChangedJob extends WorkbenchJob {

		// queue of submitted deltas to process
		private final List<DelayedDoModelChange> fQueue = new ArrayList<>();
		private boolean shutdown;

		public DelayedDoModelChangedJob() {
			super("Delayed model change job"); //$NON-NLS-1$
			setSystem(true);
			setUser(false);
		}

		@Override
		public IStatus runInUIThread(IProgressMonitor monitor) {
			List<DelayedDoModelChange> currentBatch = new ArrayList<>();
			synchronized (fQueue) {
				if (shutdown || fQueue.isEmpty()) {
					return Status.OK_STATUS;
				}
				currentBatch = new ArrayList<>(fQueue);
				fQueue.clear();
			}
			if (DebugUIPlugin.DEBUG_CONTENT_PROVIDER) {
				DebugUIPlugin.trace("Delayed batch size: " + currentBatch.size()); //$NON-NLS-1$
			}
			for (Iterator<DelayedDoModelChange> iterator = currentBatch.iterator(); iterator.hasNext();) {
				DelayedDoModelChange change = iterator.next();
				if (monitor.isCanceled()) {
					restoreQueue(currentBatch);
					return Status.CANCEL_STATUS;
				}
				if (!change.proxy.isDisposed()) {
					doModelChanged(change.delta, change.proxy);
				}
				iterator.remove();
			}
			return Status.OK_STATUS;
		}

		private void restoreQueue(List<DelayedDoModelChange> currentBatch) {
			synchronized (fQueue) {
				currentBatch.addAll(fQueue);
				fQueue.clear();
				fQueue.addAll(currentBatch);
			}
		}

		public void runDelayed(final IModelDelta delta, final IModelProxy proxy) {
			synchronized (fQueue) {
				if (shutdown) {
					return;
				}
				fQueue.add(new DelayedDoModelChange(delta, proxy));
				if (DebugUIPlugin.DEBUG_CONTENT_PROVIDER) {
					DebugUIPlugin.trace("Delayed queue size: " + fQueue.size()); //$NON-NLS-1$
				}
			}
			schedule(50);
		}

		public void shutdown() {
			synchronized (fQueue) {
				shutdown = true;
				fQueue.clear();
			}
			cancel();
		}

		@Override
		public boolean belongsTo(Object family) {
			return family == TreeModelContentProvider.this || family == TreeModelContentProvider.class;
		}
	}

	private final DelayedDoModelChangedJob fDelayedDoModelChangeJob = new DelayedDoModelChangedJob();

    @Override
	public void modelChanged(final IModelDelta delta, final IModelProxy proxy) {
        Display display = null;

        // Check if the viewer is still available, i.e. if the content provider
        // is not disposed.
        synchronized(this) {
            if (fViewer != null && !proxy.isDisposed()) {
                display = fViewer.getDisplay();
            }
        }
        if (display != null) {
            // If we're in display thread, process the delta immediately to
            // avoid "skid" in processing events.
            if (Thread.currentThread().equals(display.getThread())) {
                doModelChanged(delta, proxy);
            }
            else {
				fDelayedDoModelChangeJob.runDelayed(delta, proxy);
            }
        }
    }

    /**
     * Executes the model proxy in UI thread.
     * @param delta Delta to process
     * @param proxy Proxy that fired the delta.
     */
    private void doModelChanged(IModelDelta delta, IModelProxy proxy) {
        if (!proxy.isDisposed()) {
            if (DebugUIPlugin.DEBUG_DELTAS && DebugUIPlugin.DEBUG_TEST_PRESENTATION_ID(getPresentationContext())) {
                DebugUIPlugin.trace("RECEIVED DELTA: " + delta.toString()); //$NON-NLS-1$
            }

            updateModel(delta, getModelDeltaMask());

            // Initiate model update sequence before notifying of the model changed.
            trigger(null);

            // Call model listeners after updating the viewer model.
			for (IModelChangedListener iModelChangedListener : fModelListeners) {
				iModelChangedListener.modelChanged(delta, proxy);
			}
        }
    }

    @Override
	public void setModelDeltaMask(int mask) {
        fModelDeltaMask = mask;
    }

    @Override
	public int getModelDeltaMask() {
        return fModelDeltaMask;
    }

    @Override
	public void updateModel(IModelDelta delta, int mask) {
    	// Processing deltas with null input leads to NPEs
    	// (Bug 380288 - NPE switching to the Breakpoints View)
    	if (getViewer() == null || getViewer().getInput() == null) {
			return;
		}

		fRevealPath = null;
        IModelDelta[] deltaArray = new IModelDelta[] { delta };
        updateNodes(deltaArray, mask & (IModelDelta.REMOVED | IModelDelta.UNINSTALL));
        updateNodes(deltaArray, mask & ITreeModelContentProvider.UPDATE_MODEL_DELTA_FLAGS
            & ~(IModelDelta.REMOVED | IModelDelta.UNINSTALL));
        updateNodes(deltaArray, mask & ITreeModelContentProvider.CONTROL_MODEL_DELTA_FLAGS);

        fStateTracker.checkIfRestoreComplete();
    }

    /**
     * Returns a tree path for the node including the root element.
     *
     * @param node
     *            model delta
     * @return corresponding tree path
     */
    TreePath getFullTreePath(IModelDelta node) {
		ArrayList<Object> list = new ArrayList<Object>();
        while (node.getParentDelta() != null) {
            list.add(0, node.getElement());
            node = node.getParentDelta();
        }
        return new TreePath(list.toArray());
    }

    /**
     * Returns a tree path for the node, *not* including the root element.
     *
     * @param node
     *            model delta
     * @return corresponding tree path
     */
    TreePath getViewerTreePath(IModelDelta node) {
		ArrayList<Object> list = new ArrayList<Object>();
        IModelDelta parentDelta = node.getParentDelta();
        while (parentDelta != null) {
            list.add(0, node.getElement());
            node = parentDelta;
            parentDelta = node.getParentDelta();
        }
        return new TreePath(list.toArray());
    }

    /**
     * Returns the viewer this content provider is working for.
     *
     * @return viewer
     */
    protected IInternalTreeModelViewer getViewer() {
        synchronized(this) {
            return fViewer;
        }
    }

    @Override
	public int viewToModelIndex(TreePath parentPath, int index) {
        return fTransform.viewToModelIndex(parentPath, index);
    }

    @Override
	public int viewToModelCount(TreePath parentPath, int count) {
        return fTransform.viewToModelCount(parentPath, count);
    }

    @Override
	public int modelToViewIndex(TreePath parentPath, int index) {
        return fTransform.modelToViewIndex(parentPath, index);
    }

    @Override
	public int modelToViewChildCount(TreePath parentPath, int count) {
        return fTransform.modelToViewCount(parentPath, count);
    }

    @Override
	public boolean areTreeModelViewerFiltersApplicable(Object parentElement) {
        ViewerFilter[] filters = fViewer.getFilters();
        if (filters.length > 0) {
            for (int j = 0; j < filters.length; j++) {
                if (filters[j] instanceof TreeModelViewerFilter &&
                    ((TreeModelViewerFilter)filters[j]).isApplicable(fViewer, parentElement))
                {
                    return true;
                }
            }
        }
        return false;
    }

    @Override
	public boolean shouldFilter(Object parentElementOrTreePath, Object element) {
        ViewerFilter[] filters = fViewer.getFilters();
        if (filters.length > 0) {
            for (int j = 0; j < filters.length; j++) {
                if (filters[j] instanceof TreeModelViewerFilter) {
                    // Skip the filter if not applicable to parent element
                    Object parentElement = parentElementOrTreePath instanceof TreePath
                        ? ((TreePath)parentElementOrTreePath).getLastSegment() : parentElementOrTreePath;
                    if (parentElement == null) {
						parentElement = fViewer.getInput();
					}
                    if (!((TreeModelViewerFilter)filters[j]).isApplicable(fViewer, parentElement)) {
                        continue;
                    }
                }

                if (!(filters[j].select((Viewer) fViewer, parentElementOrTreePath, element))) {
                    return true;
                }
            }
        }
        return false;
    }

    @Override
	public void unmapPath(TreePath path) {
        Assert.isTrue( getViewer().getDisplay().getThread() == Thread.currentThread() );
        fTransform.clear(path);
        cancelSubtreeUpdates(path);
    }


    boolean addFilteredIndex(TreePath parentPath, int index, Object element) {
        Assert.isTrue( getViewer().getDisplay().getThread() == Thread.currentThread() );
        return fTransform.addFilteredIndex(parentPath, index, element);
    }

    void removeElementFromFilters(TreePath parentPath, int index) {
        Assert.isTrue( getViewer().getDisplay().getThread() == Thread.currentThread() );
        fTransform.removeElementFromFilters(parentPath, index);
    }

    boolean removeElementFromFilters(TreePath parentPath, Object element) {
        Assert.isTrue( getViewer().getDisplay().getThread() == Thread.currentThread() );
        return fTransform.removeElementFromFilters(parentPath, element);
    }

    void setModelChildCount(TreePath parentPath, int childCount) {
        Assert.isTrue( getViewer().getDisplay().getThread() == Thread.currentThread() );
        fTransform.setModelChildCount(parentPath, childCount);
    }

    boolean isFiltered(TreePath parentPath, int index) {
        Assert.isTrue( getViewer().getDisplay().getThread() == Thread.currentThread() );
        return fTransform.isFiltered(parentPath, index);
    }

    int[] getFilteredChildren(TreePath parent) {
        Assert.isTrue( getViewer().getDisplay().getThread() == Thread.currentThread() );
        return fTransform.getFilteredChildren(parent);
    }

    void clearFilteredChild(TreePath parent, int modelIndex) {
        Assert.isTrue( getViewer().getDisplay().getThread() == Thread.currentThread() );
        fTransform.clear(parent, modelIndex);
    }

    void clearFilters(TreePath parent) {
        Assert.isTrue( getViewer().getDisplay().getThread() == Thread.currentThread() );
        fTransform.clear(parent);
    }

    /**
     * Notification an update request has started
     *
     * @param update the update to notify about
     */
    void updateStarted(ViewerUpdateMonitor update) {
        Assert.isTrue( getViewer().getDisplay().getThread() == Thread.currentThread() );

		List<ViewerUpdateMonitor> requests = fRequestsInProgress.get(update.getSchedulingPath());
        if (requests == null) {
			requests = new ArrayList<ViewerUpdateMonitor>();
            fRequestsInProgress.put(update.getSchedulingPath(), requests);
        }
        requests.add(update);
        if (!fModelSequenceRunning) {
        	fModelSequenceRunning = true;
            if (DebugUIPlugin.DEBUG_UPDATE_SEQUENCE && DebugUIPlugin.DEBUG_TEST_PRESENTATION_ID(getPresentationContext())) {
                DebugUIPlugin.trace("MODEL SEQUENCE BEGINS"); //$NON-NLS-1$
            }
            notifyUpdate(UPDATE_SEQUENCE_BEGINS, null);
        }
        if (DebugUIPlugin.DEBUG_UPDATE_SEQUENCE && DebugUIPlugin.DEBUG_TEST_PRESENTATION_ID(getPresentationContext())) {
            DebugUIPlugin.trace("\tBEGIN - " + update); //$NON-NLS-1$
        }
        notifyUpdate(UPDATE_BEGINS, update);
    }

    /**
     * Notification an update request has completed
     *
     * @param updates the updates to notify
     */
	void updatesComplete(final List<ViewerUpdateMonitor> updates) {
    	for (int i = 0; i < updates.size(); i++) {
    		ViewerUpdateMonitor update = updates.get(i);
	        notifyUpdate(UPDATE_COMPLETE, update);
	        if (DebugUIPlugin.DEBUG_UPDATE_SEQUENCE && DebugUIPlugin.DEBUG_TEST_PRESENTATION_ID(getPresentationContext())) {
	            DebugUIPlugin.trace("\tEND - " + update); //$NON-NLS-1$
	        }
    	}

    	// Wait a single cycle to allow viewer to queue requests triggered by completed updates.
        getViewer().getDisplay().asyncExec(new Runnable() {
            @Override
			public void run() {
                if (isDisposed()) {
					return;
				}

            	for (int i = 0; i < updates.size(); i++) {
            		ViewerUpdateMonitor update = updates.get(i);

            		// Search for update in list using identity test.  Otherwise a completed canceled
            		// update may trigger removal of up-to-date running update on the same element.
					List<ViewerUpdateMonitor> requests = fRequestsInProgress.get(update.getSchedulingPath());
	            	boolean found = false;
	            	if (requests != null) {
    	            	for (int j = 0; j < requests.size(); j++) {
    	            		if (requests.get(j) == update) {
    	            			found = true;
    	            			requests.remove(j);
    	            			break;
    	            		}
    	            	}
	            	}

	            	if (found) {
	                    // Trigger may initiate new updates, so wait to remove requests array from
	                    // fRequestsInProgress map.  This way updateStarted() will not send a
	                    // redundant "UPDATE SEQUENCE STARTED" notification.
	                    trigger(update.getSchedulingPath());
	            	} else {
	            		// Update may be removed from in progress list if it was canceled by schedule().
	                    Assert.isTrue( update.isCanceled() );
	            	}
                    if (requests != null && requests.isEmpty()) {
                        fRequestsInProgress.remove(update.getSchedulingPath());
                    }
            	}
                if (fRequestsInProgress.isEmpty() && fWaitingRequests.isEmpty() && fModelSequenceRunning) {
                	fModelSequenceRunning = false;
                    if (fRevealPath != null) {
						getViewer().reveal(fRevealPath, fRevealIndex);
                    	fRevealPath = null;
                    }
                    if (DebugUIPlugin.DEBUG_UPDATE_SEQUENCE && DebugUIPlugin.DEBUG_TEST_PRESENTATION_ID(getPresentationContext())) {
                        DebugUIPlugin.trace("MODEL SEQUENCE ENDS"); //$NON-NLS-1$
                    }
                    notifyUpdate(UPDATE_SEQUENCE_COMPLETE, null);
                }
            }
        });

    }

    /**
     * @return Returns true if there are outstanding updates in the viewer.
     */
    boolean areRequestsPending() {
        return !fRequestsInProgress.isEmpty() || !fWaitingRequests.isEmpty();
    }

    /**
     * @return Returns the state tracker for the content provider.
     */
    ViewerStateTracker getStateTracker() {
        return fStateTracker;
    }

    /**
     * Notifies listeners about given update.
     * @param type Type of update to call listeners with.
     * @param update Update to notify about.
     */
    private void notifyUpdate(final int type, final IViewerUpdate update) {
        if (!fUpdateListeners.isEmpty()) {
			for (IViewerUpdateListener iViewerUpdateListener : fUpdateListeners) {
				final IViewerUpdateListener listener = iViewerUpdateListener;
                SafeRunner.run(new ISafeRunnable() {
                    @Override
					public void run() throws Exception {
                        switch (type) {
                        case UPDATE_SEQUENCE_BEGINS:
                            listener.viewerUpdatesBegin();
                            break;
                        case UPDATE_SEQUENCE_COMPLETE:
                            listener.viewerUpdatesComplete();
                            break;
                        case UPDATE_BEGINS:
                            listener.updateStarted(update);
                            break;
                        case UPDATE_COMPLETE:
                            listener.updateComplete(update);
                            break;
							default:
								break;
                        }
                    }

                    @Override
					public void handleException(Throwable exception) {
                        DebugUIPlugin.log(exception);
                    }
                });
            }
        }
    }

    /**
     * Cancels outstanding updates for the element at given path and its
     * children.
     * @param path Path of element.
     */
    private void cancelSubtreeUpdates(TreePath path) {
        Assert.isTrue( getViewer().getDisplay().getThread() == Thread.currentThread() );
		for (Entry<TreePath, List<ViewerUpdateMonitor>> entry : fRequestsInProgress.entrySet()) {
            TreePath entryPath = entry.getKey();
            if (entryPath.startsWith(path, null)) {
				List<ViewerUpdateMonitor> requests = entry.getValue();
				Iterator<ViewerUpdateMonitor> reqIter = requests.iterator();
                while (reqIter.hasNext()) {
                    // Cancel update and remove from requests list.  Removing from
                    // fRequestsInProgress ensures that isRequestBlocked() won't be triggered
                    // by a canceled update.
					reqIter.next().cancel();
                    reqIter.remove();
                }
            }
        }
		List<TreePath> purge = new ArrayList<TreePath>();
		for (TreePath entryPath : fWaitingRequests.keySet()) {
            if (entryPath.startsWith(path, null)) {
                purge.add(entryPath);
            }
        }
		for (TreePath tp : purge) {
			fWaitingRequests.remove(tp);
        }

        fStateTracker.cancelStateSubtreeUpdates(path);
    }

    /**
     * Returns whether this given request should be run, or should wait for
     * parent update to complete.
     *
     * @param update the update the schedule
     */
    private void schedule(final ViewerUpdateMonitor update) {
    	Assert.isTrue(getViewer().getDisplay().getThread() == Thread.currentThread());

        TreePath schedulingPath = update.getSchedulingPath();
		List<ViewerUpdateMonitor> requests = fWaitingRequests.get(schedulingPath);
        if (requests == null) {
			requests = new LinkedList<ViewerUpdateMonitor>();
            requests.add(update);
            fWaitingRequests.put(schedulingPath, requests);

			List<ViewerUpdateMonitor> inProgressList = fRequestsInProgress.get(schedulingPath);
            if (inProgressList != null) {
                int staleUpdateIndex = inProgressList.indexOf(update);
                if (staleUpdateIndex >= 0) {
                    // Cancel update and remove from requests list.  Removing from
                    // fRequestsInProgress ensures that isRequestBlocked() won't be triggered
                    // by a canceled update.
                    ViewerUpdateMonitor staleUpdate = inProgressList.remove(staleUpdateIndex);
                    staleUpdate.cancel();
                    // Note: Do not reset the inProgressList to null.  This would cause the
                    // updateStarted() method to think that a new update sequence is
                    // being started.  Since there are waiting requests for this scheduling
                    // path, the list will be cleaned up later.
                }
            }
            if (inProgressList == null || inProgressList.isEmpty()) {
                getViewer().getDisplay().asyncExec(new Runnable() {
                    @Override
					public void run() {
                    	if (isDisposed()) {
							return;
						}
                        trigger(update.getSchedulingPath());
                    }
                });
            }
        } else {
            // there are waiting requests: coalesce with existing request and add to list
            requests.add(coalesce(requests, update));
        }
    }

    /**
     * Tries to coalesce the given request with any request in the list.  If a match is found,
     * the resulting request is then coalesced again with candidates in list.
     * @param requests List of waiting requests to coalesce with
     * @param toCoalesce request to coalesce
     * @return Returns either the coalesced request.  If no match was found it returns the
     * toCoalesce parameter request.  Either way the returned request needs to be added to the
     * waiting requests list.
     */
	private ViewerUpdateMonitor coalesce(List<ViewerUpdateMonitor> requests, ViewerUpdateMonitor toCoalesce) {
		for (ViewerUpdateMonitor waiting : requests) {
            if (waiting.coalesce(toCoalesce)) {
                requests.remove(waiting);
                // coalesced with existing request, done
                // try to coalesce the combined requests with other waiting requests
                return coalesce(requests, waiting);
            }
        }
        return toCoalesce;
    }

    /**
     * Returns whether there are outstanding ChildrenUpdate updates for the given path.
     * This method is expected to be called during processing of a ChildrenRequest,
     * therefore one running children request is ignored.
     * @param path Path of element to check.
     * @return True if there are outstanding children updates for given element.
     */
    boolean areChildrenUpdatesPending(TreePath path) {
        Assert.isTrue( getViewer().getDisplay().getThread() == Thread.currentThread() );
		List<ViewerUpdateMonitor> requests = fWaitingRequests.get(path);
        if (requests != null) {
            for (int i = 0; i < requests.size(); i++) {
                if (requests.get(i) instanceof ChildrenUpdate) {
                    return true;
                }
            }
        }
        requests = fRequestsInProgress.get(path);
        if (requests != null) {
            int numChildrenUpdateRequests = 0;
            for (int i = 0; i < requests.size(); i++) {
                if (requests.get(i) instanceof ChildrenUpdate) {
                    if (++numChildrenUpdateRequests > 1) {
                        return true;
                    }
                }
            }
        }
        return false;
    }

    /**
     * Triggers waiting requests based on the given request that just
     * completed.
     * <p>
     * Requests are processed in order such that updates to
     * children are delayed until updates for parent elements are completed.
     * This allows the expansion/selection state of the elements to be
     * properly restored as new elements are retrieved from model.
     * </p>
     * @param schedulingPath schedulingPath path or requests to start processing.  May
     * be <code>null</code> to start the shortest path request.
     */
    private void trigger(TreePath schedulingPath) {
    	Assert.isTrue(getViewer().getDisplay().getThread() == Thread.currentThread());

        if (fWaitingRequests.isEmpty()) {
            return;
        }
		List<ViewerUpdateMonitor> waiting = fWaitingRequests.get(schedulingPath);
        if (waiting == null) {
            // no waiting, update the entry with the shortest path
            int length = Integer.MAX_VALUE;
			Entry<TreePath, List<ViewerUpdateMonitor>> candidate = null;
			for (Entry<TreePath, List<ViewerUpdateMonitor>> entry : fWaitingRequests.entrySet()) {
                TreePath key = entry.getKey();
                if (key.getSegmentCount() < length && !isRequestBlocked(key)) {
                    candidate = entry;
                    length = key.getSegmentCount();
                }
            }
            if (candidate != null) {
                startHighestPriorityRequest(candidate.getKey(), candidate.getValue());
            }
        } else if (!isRequestBlocked(schedulingPath)) {
            // start the highest priority request
            startHighestPriorityRequest(schedulingPath, waiting);
        }
    }

    /**
     * Returns true if there are running requests for any parent element of
     * the given tree path.
     * @param requestPath Path of element to check.
     * @return Returns true if requests are running.
     */
    private boolean isRequestBlocked(TreePath requestPath) {
        TreePath parentPath = requestPath;
		List<ViewerUpdateMonitor> parentRequests = fRequestsInProgress.get(parentPath);
        while (parentRequests == null || parentRequests.isEmpty()) {
            parentPath = parentPath.getParentPath();
            if (parentPath == null) {
                // no running requests: start request
                return false;
            }
            parentRequests = fRequestsInProgress.get(parentPath);
        }
        return true;
    }

    /**
     * @param key the {@link TreePath}
     * @param waiting the list of waiting requests
     */
	private void startHighestPriorityRequest(TreePath key, List<ViewerUpdateMonitor> waiting) {
        int priority = 4;
        ViewerUpdateMonitor next = null;
		for (ViewerUpdateMonitor vu : waiting) {
            if (vu.getPriority() < priority) {
                next = vu;
                priority = next.getPriority();
            }
        }
        if (next != null) {
            waiting.remove(next);
            if (waiting.isEmpty()) {
                fWaitingRequests.remove(key);
            }
            next.start();
        }
    }

    /**
     * Returns the element corresponding to the given tree path.
     *
     * @param path
     *            tree path
     * @return model element
     */
    protected Object getElement(TreePath path) {
        if (path.getSegmentCount() > 0) {
            return path.getLastSegment();
        }
        return getViewer().getInput();
    }

    /**
     * Reschedule any children updates in progress for the given parent that
     * have a start index greater than the given index. An element has been
     * removed at this index, invalidating updates in progress.
     *
     * @param parentPath
     *            view tree path to parent element
     * @param modelIndex
     *            index at which an element was removed
     */
    private void rescheduleUpdates(TreePath parentPath, int modelIndex) {
        Assert.isTrue( getViewer().getDisplay().getThread() == Thread.currentThread() );

		List<ViewerUpdateMonitor> requests = fRequestsInProgress.get(parentPath);
		List<IChildrenUpdate> reCreate = null;
        if (requests != null) {
			Iterator<ViewerUpdateMonitor> iterator = requests.iterator();
            while (iterator.hasNext()) {
				ViewerUpdateMonitor update = iterator.next();
                if (update instanceof IChildrenUpdate) {
                    IChildrenUpdate childrenUpdate = (IChildrenUpdate) update;
                    if (childrenUpdate.getOffset() > modelIndex) {
                        // Cancel update and remove from requests list.  Removing from
                        // fRequestsInProgress ensures that isRequestBlocked() won't be triggered
                        // by a canceled update.
                        childrenUpdate.cancel();
                        iterator.remove();
                        if (reCreate == null) {
							reCreate = new ArrayList<IChildrenUpdate>();
                        }
                        reCreate.add(childrenUpdate);
                        if (DebugUIPlugin.DEBUG_CONTENT_PROVIDER && DebugUIPlugin.DEBUG_TEST_PRESENTATION_ID(getPresentationContext())) {
                            DebugUIPlugin.trace("canceled update in progress handling REMOVE: " + childrenUpdate); //$NON-NLS-1$
                        }
                    }
                }
            }
        }
        requests = fWaitingRequests.get(parentPath);
        if (requests != null) {
			for (ViewerUpdateMonitor update : requests) {
                if (update instanceof IChildrenUpdate) {
                    IChildrenUpdate childrenUpdate = (IChildrenUpdate) update;
                    if (childrenUpdate.getOffset() > modelIndex) {
                        ((ChildrenUpdate) childrenUpdate).setOffset(childrenUpdate.getOffset() - 1);
                        if (DebugUIPlugin.DEBUG_CONTENT_PROVIDER && DebugUIPlugin.DEBUG_TEST_PRESENTATION_ID(getPresentationContext())) {
                            DebugUIPlugin.trace("modified waiting update handling REMOVE: " + childrenUpdate); //$NON-NLS-1$
                        }
                    }
                }
            }
        }
        // re-schedule canceled updates at new position.
        // have to do this last else the requests would be waiting and
        // get modified.
        if (reCreate != null) {
			for (IChildrenUpdate childrenUpdate : reCreate) {
                int start = childrenUpdate.getOffset() - 1;
                int end = start + childrenUpdate.getLength();
                for (int i = start; i < end; i++) {
                    doUpdateElement(parentPath, i);
                }
            }
        }
    }

	private void doUpdateChildCount(TreePath path) {
        Assert.isTrue( getViewer().getDisplay().getThread() == Thread.currentThread() );

		Object element = getElement(path);
		IElementContentProvider contentAdapter = ViewerAdapterService.getContentProvider(element);
		if (contentAdapter != null) {
			ChildrenCountUpdate request = new ChildrenCountUpdate(this, getViewer().getInput(), path, element, contentAdapter);
			schedule(request);
		}
	}

	void doUpdateElement(TreePath parentPath, int modelIndex) {
        Assert.isTrue( getViewer().getDisplay().getThread() == Thread.currentThread() );

		Object parent = getElement(parentPath);
		IElementContentProvider contentAdapter = ViewerAdapterService.getContentProvider(parent);
		if (contentAdapter != null) {
			ChildrenUpdate request = new ChildrenUpdate(this, getViewer().getInput(), parentPath, parent, modelIndex, contentAdapter);
			schedule(request);
		}
	}

	private void doUpdateHasChildren(TreePath path) {
        Assert.isTrue( getViewer().getDisplay().getThread() == Thread.currentThread() );

		Object element = getElement(path);
		IElementContentProvider contentAdapter = ViewerAdapterService.getContentProvider(element);
		if (contentAdapter != null) {
			HasChildrenUpdate request = new HasChildrenUpdate(this, getViewer().getInput(), path, element, contentAdapter);
			schedule(request);
		}
	}

	/**
	 * Checks if there are outstanding updates that may replace the element
	 * at given path.
	 * @param path Path of element to check.
	 * @return Returns true if there are outstanding updates.
	 */
    boolean areElementUpdatesPending(TreePath path) {
        Assert.isTrue( getViewer().getDisplay().getThread() == Thread.currentThread() );

        TreePath parentPath = path.getParentPath();
		List<ViewerUpdateMonitor> requests = fWaitingRequests.get(path);
        if (requests != null) {
            for (int i = 0; i < requests.size(); i++) {
                ViewerUpdateMonitor update = requests.get(i);
                if (update instanceof ChildrenUpdate) {
                    return true;
                }
            }
        }
        requests = fWaitingRequests.get(parentPath);
        if (requests != null) {
            for (int i = 0; i < requests.size(); i++) {
                ViewerUpdateMonitor update = requests.get(i);
                if (update.containsUpdate(path)) {
                    return true;
                }
            }
        }
        requests = fRequestsInProgress.get(path);
        if (requests != null) {
            for (int i = 0; i < requests.size(); i++) {
                ViewerUpdateMonitor update = requests.get(i);
                if (update instanceof ChildrenUpdate) {
                    return true;
                }
            }
        }
        requests = fRequestsInProgress.get(parentPath);
        if (requests != null) {
            for (int i = 0; i < requests.size(); i++) {
                ViewerUpdateMonitor update = requests.get(i);
                if (update.getElement().equals(path.getLastSegment())) {
                    return true;
                }
            }
        }
        return false;
    }

    /**
     * Returns the presentation context for this content provider.
     *
     * @return presentation context
     */
	protected IPresentationContext getPresentationContext() {
	    ITreeModelViewer viewer = getViewer();
	    if (viewer != null) {
	        return viewer.getPresentationContext();
	    }
	    return null;
	}

    /**
     * Updates the viewer with the following deltas.
     *
     * @param nodes Model deltas to be processed.
     * @param mask the model delta mask
     * @see IModelDelta for a list of masks
     */
    protected void updateNodes(IModelDelta[] nodes, int mask) {
        for (int i = 0; i < nodes.length; i++) {
            IModelDelta node = nodes[i];
            int flags = node.getFlags() & mask;

            if ((flags & IModelDelta.ADDED) != 0) {
                handleAdd(node);
            }
            if ((flags & IModelDelta.REMOVED) != 0) {
                handleRemove(node);
            }
            if ((flags & IModelDelta.CONTENT) != 0) {
                handleContent(node);
            }
            if ((flags & IModelDelta.STATE) != 0) {
                handleState(node);
            }
            if ((flags & IModelDelta.INSERTED) != 0) {
                handleInsert(node);
            }
            if ((flags & IModelDelta.REPLACED) != 0) {
                handleReplace(node);
            }
            if ((flags & IModelDelta.INSTALL) != 0) {
                handleInstall(node);
            }
            if ((flags & IModelDelta.UNINSTALL) != 0) {
                handleUninstall(node);
            }
            if ((flags & IModelDelta.EXPAND) != 0) {
                handleExpand(node);
            }
            if ((flags & IModelDelta.COLLAPSE) != 0) {
                handleCollapse(node);
            }
            if ((flags & IModelDelta.SELECT) != 0) {
                handleSelect(node);
            }
            if ((flags & IModelDelta.REVEAL) != 0) {
                handleReveal(node);
            }
            updateNodes(node.getChildDeltas(), mask);
        }
    }

    protected void handleInstall(IModelDelta delta) {
        installModelProxy(getViewer().getInput(), getFullTreePath(delta));
    }

    protected void handleUninstall(IModelDelta delta) {
        disposeModelProxy(getFullTreePath(delta));
    }

 	protected void handleAdd(IModelDelta delta) {
		IModelDelta parentDelta = delta.getParentDelta();
		if (parentDelta == null) {
		    DebugUIPlugin.log(new Status(IStatus.ERROR, DebugUIPlugin.getUniqueIdentifier(), "Invalid viewer update: " + delta + ", in " + getPresentationContext().getId(), null )); //$NON-NLS-1$ //$NON-NLS-2$
		    return;
		}

		TreePath parentPath = getViewerTreePath(parentDelta);
		Object element = delta.getElement();
		int count = parentDelta.getChildCount();
		if (count > 0) {
		    setModelChildCount(parentPath, count);
		    int modelIndex = count - 1;
		    if (delta.getIndex() != -1) {
		    	// assume addition at end, unless index specified by delta
		    	modelIndex = delta.getIndex();
		    }
			if (shouldFilter(parentPath, element)) {
				addFilteredIndex(parentPath, modelIndex, element);
				if (DebugUIPlugin.DEBUG_CONTENT_PROVIDER && DebugUIPlugin.DEBUG_TEST_PRESENTATION_ID(getPresentationContext())) {
					DebugUIPlugin.trace("[filtered] handleAdd(" + delta.getElement() + ") > modelIndex: " + modelIndex); //$NON-NLS-1$ //$NON-NLS-2$
				}
				// it was filtered so the child count does not change
			} else {
				if (isFiltered(parentPath, modelIndex)) {
					clearFilteredChild(parentPath, modelIndex);
				}
                int viewIndex = modelToViewIndex(parentPath, modelIndex);
				int viewCount = modelToViewChildCount(parentPath, count);
				if (DebugUIPlugin.DEBUG_CONTENT_PROVIDER && DebugUIPlugin.DEBUG_TEST_PRESENTATION_ID(getPresentationContext())) {
					DebugUIPlugin.trace("handleAdd(" + delta.getElement() + ") viewIndex: " + viewIndex + " modelIndex: " + modelIndex + " viewCount: " + viewCount + " modelCount: " + count); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
				}
				getViewer().setChildCount(parentPath, viewCount);
				getViewer().autoExpand(parentPath);
				getViewer().replace(parentPath, viewIndex, element);
				TreePath childPath = parentPath.createChildPath(element);
				updateHasChildren(childPath);
				fStateTracker.restorePendingStateOnUpdate(childPath, modelIndex, false, false, false);
			}
		} else {
			if (DebugUIPlugin.DEBUG_CONTENT_PROVIDER && DebugUIPlugin.DEBUG_TEST_PRESENTATION_ID(getPresentationContext())) {
				DebugUIPlugin.trace("handleAdd(" + delta.getElement() + ")"); //$NON-NLS-1$ //$NON-NLS-2$
			}
		    doUpdateChildCount(getViewerTreePath(delta.getParentDelta()));
		}
	}

	/* (non-Javadoc)
	 * @see org.eclipse.debug.internal.ui.viewers.model.provisional.viewers.ModelContentProvider#handleContent(org.eclipse.debug.internal.ui.viewers.provisional.IModelDelta)
	 */
 	protected void handleContent(IModelDelta delta) {
		if (delta.getParentDelta() == null && delta.getChildCount() == 0) {
			// if the delta is for the root, ensure the root still matches viewer input
			if (!delta.getElement().equals(getViewer().getInput())) {
				return;
			}
		}
		TreePath treePath = getViewerTreePath(delta);
		cancelSubtreeUpdates(treePath);
		getViewer().refresh(getElement(treePath));
	}

	/* (non-Javadoc)
	 * @see org.eclipse.debug.internal.ui.viewers.model.ModelContentProvider#handleCollapse(org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta)
	 */
 	protected void handleCollapse(IModelDelta delta) {
		TreePath elementPath = getViewerTreePath(delta);
		getViewer().setExpandedState(elementPath, false);
        cancelRestore(elementPath, IModelDelta.EXPAND);
	}

	/* (non-Javadoc)
	 * @see org.eclipse.debug.internal.ui.viewers.model.provisional.viewers.ModelContentProvider#handleExpand(org.eclipse.debug.internal.ui.viewers.provisional.IModelDelta)
	 */
 	protected void handleExpand(IModelDelta delta) {
		// expand each parent, then this node
		IModelDelta parentDelta = delta.getParentDelta();
		if (parentDelta != null) {
			if ((parentDelta.getFlags() & IModelDelta.EXPAND) == 0) {
				handleExpand(parentDelta);
			}
			expand(delta);
		} else {
	        int childCount = delta.getChildCount();
	        TreePath elementPath = getViewerTreePath(delta);
	        if (childCount > 0) {
	            int viewCount = modelToViewChildCount(elementPath, childCount);
	            if (DebugUIPlugin.DEBUG_CONTENT_PROVIDER && DebugUIPlugin.DEBUG_TEST_PRESENTATION_ID(getPresentationContext())) {
	                DebugUIPlugin.trace("[expand] setChildCount(" + delta.getElement() + ", (model) " + childCount + " (view) " + viewCount); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
	            }
	            getViewer().setChildCount(elementPath, viewCount);
	        }
		}
	}

 	/**
 	 * Expands the element pointed to by given delta.
 	 * @param delta Delta that points to the element to expand.
 	 */
	private void expand(IModelDelta delta) {
		int childCount = delta.getChildCount();
		int modelIndex = delta.getIndex();
		IInternalTreeModelViewer treeViewer = getViewer();
		TreePath elementPath = getViewerTreePath(delta);
		if (modelIndex >= 0) {
			TreePath parentPath = elementPath.getParentPath();
			if (parentPath == null) {
				parentPath = TreePath.EMPTY;
			}
			int viewIndex = modelToViewIndex(parentPath, modelIndex);
			if (viewIndex >= 0) {
				if (DebugUIPlugin.DEBUG_CONTENT_PROVIDER && DebugUIPlugin.DEBUG_TEST_PRESENTATION_ID(getPresentationContext())) {
					DebugUIPlugin.trace("[expand] replace(" + delta.getParentDelta().getElement() + ", (model) " + modelIndex + " (view) " + viewIndex + ", " + delta.getElement()); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
				}
				treeViewer.replace(parentPath, viewIndex, delta.getElement());
			} else {
				// Element is filtered - if no longer filtered, insert the element
				viewIndex = unfilterElement(parentPath, delta.getElement(), modelIndex);
				if (viewIndex < 0) {
					// insert did not complete
					return;
				}
			}
		}
		if (childCount > 0) {
			int viewCount = modelToViewChildCount(elementPath, childCount);
			if (DebugUIPlugin.DEBUG_CONTENT_PROVIDER && DebugUIPlugin.DEBUG_TEST_PRESENTATION_ID(getPresentationContext())) {
				DebugUIPlugin.trace("[expand] setChildCount(" + delta.getElement() + ", (model) " + childCount + " (view) " + viewCount); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
			}
			treeViewer.setChildCount(elementPath, viewCount);
	        if (!treeViewer.getExpandedState(elementPath)) {
	            treeViewer.expandToLevel(elementPath, 1);
	            cancelRestore(elementPath, IModelDelta.COLLAPSE);
	        }
		}
	}

	/**
	 * Inserts the given child element of the specified parent into the tree if the element
	 * should *no* longer be filtered. Returns the view index of the newly inserted element
	 * or -1 if not inserted.
	 *
	 * @param parentPath viewer tree path to parent element
	 * @param element element to insert
	 * @param modelIndex index of the element in the model
	 * @return Returns the view index of the newly inserted element
     * or -1 if not inserted.
	 */
	private int unfilterElement(TreePath parentPath, Object element, int modelIndex) {
		// Element is filtered - if no longer filtered, insert the element
		if (shouldFilter(parentPath, element)) {
			if (DebugUIPlugin.DEBUG_CONTENT_PROVIDER && DebugUIPlugin.DEBUG_TEST_PRESENTATION_ID(getPresentationContext())) {
				DebugUIPlugin.trace("[unfilter] abort unfilter element: " + element + ", (model) " + modelIndex);  //$NON-NLS-1$ //$NON-NLS-2$
			}
			// still filtered, stop
			return -1;
		}
		// clear the filter an insert the element
		clearFilteredChild(parentPath, modelIndex);
		int viewIndex = modelToViewIndex(parentPath, modelIndex);
		if (viewIndex >= 0) {
			if (DebugUIPlugin.DEBUG_CONTENT_PROVIDER && DebugUIPlugin.DEBUG_TEST_PRESENTATION_ID(getPresentationContext())) {
				DebugUIPlugin.trace("[unfilter] insert(" + parentPath.getLastSegment() + ", (model) " + modelIndex + " (view) " + viewIndex + ", " + element); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
			}
			getViewer().insert(parentPath, element, viewIndex);
			return viewIndex;
		} else {
			// still filtered - should not happen
			return -1;
		}
	}

	protected void handleInsert(IModelDelta delta) {
        IModelDelta parentDelta = delta.getParentDelta();
        if (parentDelta == null) {
            DebugUIPlugin.log(new Status(IStatus.ERROR, DebugUIPlugin.getUniqueIdentifier(), "Invalid viewer update: " + delta + ", in " + getPresentationContext().getId(), null )); //$NON-NLS-1$ //$NON-NLS-2$
            return;
        }

		TreePath parentPath = getViewerTreePath(delta.getParentDelta());
		Object element = delta.getElement();
		int modelIndex = delta.getIndex();
		int viewIndex = modelIndex >= 0 ? modelToViewIndex(parentPath, modelIndex) : -1;
		int viewCount = getViewer().getChildCount(parentPath);
		if (viewIndex >= 0 && viewIndex <= viewCount) {
			// Index in range, insert.
			if (DebugUIPlugin.DEBUG_CONTENT_PROVIDER && DebugUIPlugin.DEBUG_TEST_PRESENTATION_ID(getPresentationContext())) {
				DebugUIPlugin.trace("handleInsert(" + parentPath.getLastSegment() + ", (model) " + modelIndex + " (view) " + viewIndex + ", " + element); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
			}
			getViewer().insert(parentPath, element, viewIndex);
		} else if (modelIndex >= 0 && viewIndex < 0) {
			// Element is filtered - do not insert
			if (DebugUIPlugin.DEBUG_CONTENT_PROVIDER && DebugUIPlugin.DEBUG_TEST_PRESENTATION_ID(getPresentationContext())) {
				DebugUIPlugin.trace("[filtered] handleInsert(" + delta.getElement() + ") > modelIndex: " + modelIndex); //$NON-NLS-1$ //$NON-NLS-2$
			}
		} else {
			// Invalid index given, do a refresh instead.
			if (DebugUIPlugin.DEBUG_CONTENT_PROVIDER && DebugUIPlugin.DEBUG_TEST_PRESENTATION_ID(getPresentationContext())) {
				DebugUIPlugin.trace("handleInsert(" + delta.getElement() + ")"); //$NON-NLS-1$ //$NON-NLS-2$
			}
		    doUpdateChildCount(getViewerTreePath(delta.getParentDelta()));
		}
	}

	protected void handleRemove(IModelDelta delta) {
		if (DebugUIPlugin.DEBUG_CONTENT_PROVIDER && DebugUIPlugin.DEBUG_TEST_PRESENTATION_ID(getPresentationContext())) {
			DebugUIPlugin.trace("handleRemove(" + delta.getElement() + ")"); //$NON-NLS-1$ //$NON-NLS-2$
		}
		IModelDelta parentDelta = delta.getParentDelta();
		if (parentDelta == null) {
            DebugUIPlugin.log(new Status(IStatus.ERROR, DebugUIPlugin.getUniqueIdentifier(), "Invalid viewer update: " + delta + ", in " + getPresentationContext().getId(), null )); //$NON-NLS-1$ //$NON-NLS-2$
		    return;
		}
		IInternalTreeModelViewer treeViewer = getViewer();
		TreePath parentPath = getViewerTreePath(parentDelta);
		Object element = delta.getElement();
		if (removeElementFromFilters(parentPath, element)) {
			// element was filtered - done
			return;
		}
		int viewIndex = -1;
		int modelIndex = delta.getIndex();
		int unmappedIndex = -1;
		int itemCount = -1;
		if (modelIndex < 0) {
		    itemCount = treeViewer.getChildCount(parentPath);
		    if (itemCount == -1) {
		        clearFilters(parentPath);
		    }
		    viewIndex = treeViewer.findElementIndex(parentPath, element);
		    if (viewIndex >= 0) {
		        modelIndex = viewToModelIndex(parentPath, viewIndex);
		    } else {
		        unmappedIndex = treeViewer.findElementIndex(parentPath, null);
		    }
		} else {
			viewIndex = modelToViewIndex(parentPath, modelIndex);
		}
		if (modelIndex >= 0) {
			// found the element
			if (DebugUIPlugin.DEBUG_CONTENT_PROVIDER && DebugUIPlugin.DEBUG_TEST_PRESENTATION_ID(getPresentationContext())) {
				DebugUIPlugin.trace(" - (found) remove(" + parentPath.getLastSegment() + ", viewIndex: " + viewIndex + " modelIndex: " + modelIndex); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
			}
			rescheduleUpdates(parentPath, modelIndex);
			getViewer().remove(parentPath, viewIndex);
			removeElementFromFilters(parentPath, modelIndex);
			return;
		}
		if (unmappedIndex >= 0) {
			// did not find the element, but found an unmapped item.
			// remove the unmapped item in it's place and update filters
			if (DebugUIPlugin.DEBUG_CONTENT_PROVIDER && DebugUIPlugin.DEBUG_TEST_PRESENTATION_ID(getPresentationContext())) {
				DebugUIPlugin.trace(" - (not found) remove(" + parentPath.getLastSegment() + ", viewIndex: " + viewIndex + " modelIndex: " + modelIndex + " unmapped index: " + unmappedIndex); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
			}
			modelIndex = viewToModelIndex(parentPath, unmappedIndex);
			rescheduleUpdates(parentPath, modelIndex);
			getViewer().remove(parentPath, unmappedIndex);
			removeElementFromFilters(parentPath, modelIndex);
			return;
		}
		int modelCount = parentDelta.getChildCount();
		if (itemCount >= 0 && modelCount >= 0) {
			if (modelToViewChildCount(parentPath, modelCount) == itemCount) {
				// item count matches the parent's child count, don't do anything
				return;
			}
		}
		// failing that, refresh the parent to properly update for non-visible/unmapped children
		// and update filtered indexes
		if (DebugUIPlugin.DEBUG_CONTENT_PROVIDER && DebugUIPlugin.DEBUG_TEST_PRESENTATION_ID(getPresentationContext())) {
			DebugUIPlugin.trace(" - (not found) remove/refresh(" + delta.getElement()); //$NON-NLS-1$
		}
		getViewer().remove(getViewerTreePath(delta));
		clearFilters(parentPath);
		getViewer().refresh(parentDelta.getElement());
	}

	protected void handleReplace(IModelDelta delta) {
	    IModelDelta parentDelta = delta.getParentDelta();
	    if (parentDelta == null) {
	        DebugUIPlugin.log(new Status(IStatus.ERROR, DebugUIPlugin.getUniqueIdentifier(), "Invalid viewer update: " + delta + ", in " + getPresentationContext().getId(), null )); //$NON-NLS-1$ //$NON-NLS-2$
	        return;
	    }
		TreePath parentPath = getViewerTreePath(parentDelta);
		int index = delta.getIndex();
		if (index < 0) {
		    index = fTransform.indexOfFilteredElement(parentPath, delta.getElement());
		}
		if (index >= 0) {
		    boolean filtered = isFiltered(parentPath, index);
		    boolean shouldFilter = shouldFilter(parentPath, delta.getReplacementElement());

		    // Update the filter transform
		    if (filtered) {
                clearFilteredChild(parentPath, index);
		    }
		    if (shouldFilter) {
		        addFilteredIndex(parentPath, index, delta.getElement());
		    }

		    // Update the viewer
		    if (filtered) {
		        if (!shouldFilter) {
		            getViewer().insert(parentPath, delta.getReplacementElement(), modelToViewIndex(parentPath, index));
		        }
		        //else do nothing
		    } else {
		        if (shouldFilter) {
		            getViewer().remove(parentPath, modelToViewIndex(parentPath, index));
		        } else {
		            getViewer().replace(parentPath, delta.getIndex(), delta.getReplacementElement());
		        }
		    }
		}
	}

	protected void handleSelect(IModelDelta delta) {
		int modelIndex = delta.getIndex();
		IInternalTreeModelViewer treeViewer = getViewer();
		// check if selection is allowed
		IStructuredSelection candidate = new TreeSelection(getViewerTreePath(delta));
		if ((delta.getFlags() & IModelDelta.FORCE) == 0 &&
		    !treeViewer.overrideSelection(treeViewer.getSelection(), candidate))
		{
			return;
		}
		// empty the selection before replacing elements to avoid materializing elements (@see bug 305739)
		treeViewer.clearSelectionQuiet();
		if (modelIndex >= 0) {
	        IModelDelta parentDelta = delta.getParentDelta();
	        if (parentDelta == null) {
	            DebugUIPlugin.log(new Status(IStatus.ERROR, DebugUIPlugin.getUniqueIdentifier(), "Invalid viewer update: " + delta + ", in " + getPresentationContext().getId(), null )); //$NON-NLS-1$ //$NON-NLS-2$
	            return;
	        }
			TreePath parentPath = getViewerTreePath(parentDelta);
			int viewIndex = modelToViewIndex(parentPath, modelIndex);
			if (viewIndex >= 0) {
				// when viewIndex < 0, the element has been filtered - so we should not try to replace
				int modelCount = parentDelta.getChildCount();
				if (modelCount > 0) {
					int viewCount = modelToViewChildCount(parentPath, modelCount);
					if (DebugUIPlugin.DEBUG_CONTENT_PROVIDER && DebugUIPlugin.DEBUG_TEST_PRESENTATION_ID(getPresentationContext())) {
						DebugUIPlugin.trace("[select] setChildCount(" + parentDelta.getElement() + ", (model) " + parentDelta.getChildCount() + " (view) " + viewCount ); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
					}
					treeViewer.setChildCount(parentPath, viewCount);
				}
				if (DebugUIPlugin.DEBUG_CONTENT_PROVIDER && DebugUIPlugin.DEBUG_TEST_PRESENTATION_ID(getPresentationContext())) {
					DebugUIPlugin.trace("[select] replace(" + parentDelta.getElement() + ", (model) " + modelIndex + " (view) " + viewIndex + ", " + delta.getElement()); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
				}
				treeViewer.replace(parentPath, viewIndex, delta.getElement());
			}
		}
		TreePath selectionPath = getViewerTreePath(delta);
		if (treeViewer.trySelection(new TreeSelection(selectionPath), false, (delta.getFlags() | IModelDelta.FORCE) == 0)) {
	        cancelRestore(selectionPath, IModelDelta.SELECT);
		}
	}

	protected void handleState(IModelDelta delta) {
		getViewer().update(delta.getElement());
	}

	protected void handleReveal(IModelDelta delta) {
		IModelDelta parentDelta = delta.getParentDelta();
        if (parentDelta == null) {
            DebugUIPlugin.log(new Status(IStatus.ERROR, DebugUIPlugin.getUniqueIdentifier(), "Invalid viewer update: " + delta + ", in " + getPresentationContext().getId(), null )); //$NON-NLS-1$ //$NON-NLS-2$
            return;
        }
        handleExpand(parentDelta);
        reveal(delta);
        cancelRestore(getViewerTreePath(delta), IModelDelta.REVEAL);
	}

	/**
	 * Reveals the element pointed to by given delta.
	 * @param delta Delta pointing to the element to reveal.
	 */
	private void reveal(IModelDelta delta) {
		int modelIndex = delta.getIndex();
		IInternalTreeModelViewer treeViewer = getViewer();
		TreePath elementPath = getViewerTreePath(delta);
		if (modelIndex >= 0) {
			TreePath parentPath = elementPath.getParentPath();
			if (parentPath == null) {
				parentPath = TreePath.EMPTY;
			}
			int viewIndex = modelToViewIndex(parentPath, modelIndex);
			if (viewIndex >= 0) {
				if (DebugUIPlugin.DEBUG_CONTENT_PROVIDER && DebugUIPlugin.DEBUG_TEST_PRESENTATION_ID(getPresentationContext())) {
					DebugUIPlugin.trace("[reveal] replace(" + delta.getParentDelta().getElement() + ", (model) " + modelIndex + " (view) " + viewIndex + ", " + delta.getElement()); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
				}
				treeViewer.replace(parentPath, viewIndex, delta.getElement());
			} else {
				// Element is filtered - insert if filter state changed
				viewIndex = unfilterElement(parentPath, delta.getElement(), modelIndex);
				if (viewIndex < 0) {
					// insert did not complete
					return;
				}
			}

			// only move tree based on force flag and selection policy
			if ((delta.getFlags() & IModelDelta.FORCE) != 0 ||
			    treeViewer.overrideSelection(treeViewer.getSelection(), new TreeSelection(elementPath)))
			{
				/*
				 * Bug 438724 - Save reveal parameters and redo reveal on
				 * updatesComplete() in case intermediate content updates have
				 * shifted the revealed element again.
				 */
				fRevealPath = parentPath;
				fRevealIndex = viewIndex;
			    treeViewer.reveal(parentPath, viewIndex);
			}
		}
	}


	/* (non-Javadoc)
	 * @see org.eclipse.jface.viewers.ILazyTreePathContentProvider#getParents(java.lang.Object)
	 */
	@Override
	public TreePath[] getParents(Object element) {
		return null;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jface.viewers.ILazyTreePathContentProvider#updateChildCount(org.eclipse.jface.viewers.TreePath, int)
	 */
	@Override
	public void updateChildCount(TreePath treePath, int currentChildCount) {
        Assert.isTrue( getViewer().getDisplay().getThread() == Thread.currentThread() );

		if (DebugUIPlugin.DEBUG_CONTENT_PROVIDER && DebugUIPlugin.DEBUG_TEST_PRESENTATION_ID(getPresentationContext())) {
			DebugUIPlugin.trace("updateChildCount(" + getElement(treePath) + ", " + currentChildCount + ")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
		}
		doUpdateChildCount(treePath);
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jface.viewers.ILazyTreePathContentProvider#updateElement(org.eclipse.jface.viewers.TreePath, int)
	 */
	@Override
	public void updateElement(TreePath parentPath, int viewIndex) {
        Assert.isTrue( getViewer().getDisplay().getThread() == Thread.currentThread() );

		int modelIndex = viewToModelIndex(parentPath, viewIndex);
		if (DebugUIPlugin.DEBUG_CONTENT_PROVIDER && DebugUIPlugin.DEBUG_TEST_PRESENTATION_ID(getPresentationContext())) {
			DebugUIPlugin.trace("updateElement("+ getElement(parentPath) + ", " + viewIndex + ") > modelIndex = " + modelIndex); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
		}
		doUpdateElement(parentPath, modelIndex);
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jface.viewers.ILazyTreePathContentProvider#updateHasChildren(org.eclipse.jface.viewers.TreePath)
	 */
	@Override
	public void updateHasChildren(TreePath path) {
        Assert.isTrue( getViewer().getDisplay().getThread() == Thread.currentThread() );

		if (DebugUIPlugin.DEBUG_CONTENT_PROVIDER && DebugUIPlugin.DEBUG_TEST_PRESENTATION_ID(getPresentationContext())) {
			DebugUIPlugin.trace("updateHasChildren(" + getElement(path)); //$NON-NLS-1$
		}
		doUpdateHasChildren(path);
	}

	/**
	 * Schedules given update to be performed on the viewer.
	 * Updates are queued up if they are completed in the same
	 * UI cycle.
	 * @param update Update to perform.
	 */
	void scheduleViewerUpdate(ViewerUpdateMonitor update) {
	    Display display;
	    Runnable updateJob = null;
	    synchronized(this) {
	        if (isDisposed()) {
				return;
			}
	        display = getViewer().getDisplay();
	        fCompletedUpdates.add(update);
            if (fCompletedUpdatesRunnable == null) {
	            fCompletedUpdatesRunnable = new Runnable() {
	                @Override
					public void run() {
	                    if (!isDisposed()) {
	                        performUpdates();
	                    }
	                }
	            };
	            updateJob = fCompletedUpdatesRunnable;
            }
	    }

	    if (updateJob != null) {
            if (Thread.currentThread() == display.getThread()) {
            	performUpdates();
            } else {
            	display.asyncExec(updateJob);
            }
	    }
	}

	/**
	 * Perform the updates pointed to by given array on the viewer.
	 */
	private void performUpdates() {
        Assert.isTrue( getViewer().getDisplay().getThread() == Thread.currentThread() );

		List<ViewerUpdateMonitor> jobCompletedUpdates;
        synchronized(this) {
            if (isDisposed()) {
                return;
            }
            jobCompletedUpdates = fCompletedUpdates;
            fCompletedUpdatesRunnable = null;
			fCompletedUpdates = new ArrayList<ViewerUpdateMonitor>();
        }
        // necessary to check if viewer is disposed
        try {
	        for (int i = 0; i < jobCompletedUpdates.size(); i++) {
	        	ViewerUpdateMonitor completedUpdate = jobCompletedUpdates.get(i);
                if (!completedUpdate.isCanceled() && !isDisposed()) {
                    IStatus status = completedUpdate.getStatus();
                    if (status == null || status.isOK()) {
                        completedUpdate.performUpdate();
                    }
                }
	        }
        } finally {
            updatesComplete(jobCompletedUpdates);
        }
	}
}
