/*******************************************************************************
 * Copyright (c) 2009, 2018 Wind River Systems 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:
 *     Wind River Systems - initial API and implementation
 *     IBM Corporation - clean-up
 *******************************************************************************/
package org.eclipse.debug.tests.viewer.model;

import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;

import org.eclipse.debug.internal.ui.viewers.model.IInternalTreeModelViewer;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta;
import org.eclipse.debug.internal.ui.viewers.model.provisional.ModelDelta;
import org.eclipse.debug.tests.TestUtil;
import org.eclipse.debug.tests.viewer.model.TestModel.TestElement;
import org.eclipse.jface.viewers.ITreeSelection;
import org.eclipse.jface.viewers.TreePath;
import org.eclipse.jface.viewers.TreeSelection;

/**
 * Tests to verify that the viewer can save and restore correctly the expansion
 * state of elements.
 *
 * @since 3.6
 */
abstract public class StateTests extends AbstractViewerModelTest implements ITestModelUpdatesListenerConstants {

    public StateTests(String name) {
        super(name);
    }

    @Override
	protected TestModelUpdatesListener createListener(IInternalTreeModelViewer viewer) {
		return new TestModelUpdatesListener(viewer, false, false);
	}

    protected IInternalTreeModelViewer getInternalViewer() {
        return fViewer;
    }

	public void testUpdateViewer() throws Exception {
        //TreeModelViewerAutopopulateAgent autopopulateAgent = new TreeModelViewerAutopopulateAgent(fViewer);

        TestModel model = TestModel.simpleMultiLevel();

        // Create the listener
        fListener.reset();
        fListener.addChildreUpdate(TreePath.EMPTY, 0);
        fListener.addChildreUpdate(TreePath.EMPTY, 1);
        fListener.addChildreUpdate(TreePath.EMPTY, 2);

        // Set the input into the view and update the view.
        fViewer.setInput(model.getRootElement());
		waitWhile(t -> !fListener.isFinished(), createListenerErrorMessage());
        model.validateData(fViewer, TreePath.EMPTY, true);

        // Create the update delta
        TestElement element = model.getRootElement();
        TreePath path0 = TreePath.EMPTY;
        ModelDelta delta = new ModelDelta(model.getRootElement(), -1, IModelDelta.EXPAND, element.getChildren().length);
        ModelDelta updateDelta = delta;
        element = element.getChildren()[2];
        TreePath path1 = path0.createChildPath(element);
        delta = delta.addNode(element, 2, IModelDelta.EXPAND, element.fChildren.length);
        element = element.getChildren()[1];
        TreePath path2 = path1.createChildPath(element);
        delta = delta.addNode(element, 1, IModelDelta.EXPAND, element.fChildren.length);
        element = element.getChildren()[1];
        TreePath path3 = path2.createChildPath(element);
        delta = delta.addNode(element, 1, IModelDelta.SELECT);

        fListener.reset(false, false);

        fListener.addChildreUpdate(path0, 2);
        fListener.addHasChildrenUpdate(path1);
        fListener.addChildreCountUpdate(path1);
        fListener.addLabelUpdate(path1);
        fListener.addChildreUpdate(path1, 1);
        fListener.addHasChildrenUpdate(path2);
        fListener.addChildreCountUpdate(path2);
        fListener.addLabelUpdate(path2);
        fListener.addHasChildrenUpdate(path2);
        fListener.addChildreCountUpdate(path2);
        fListener.addChildreUpdate(path2, 1);
        fListener.addHasChildrenUpdate(path3);
        fListener.addLabelUpdate(path3);

        fViewer.updateViewer(updateDelta);
		waitWhile(t -> !fListener.isFinished(CONTENT_SEQUENCE_COMPLETE | LABEL_UPDATES), createListenerErrorMessage());

        // Extract the new state from viewer
        ModelDelta savedDelta = new ModelDelta(model.getRootElement(), IModelDelta.NO_CHANGE);
        fViewer.saveElementState(path0, savedDelta, IModelDelta.EXPAND | IModelDelta.SELECT);

        if (!deltaMatches(updateDelta, savedDelta) ) {
			fail("Expected:\n" + updateDelta.toString() + "\nGot:\n" + savedDelta); //$NON-NLS-1$ //$NON-NLS-2$
        }
    }

    boolean deltaMatches(ModelDelta requested, ModelDelta received) {
        if ( requested.getElement().equals(received.getElement()) &&
            requested.getFlags() == received.getFlags() &&
            ( requested.getChildCount() == -1 || requested.getChildCount() == received.getChildCount() )&&
            ( requested.getIndex() == -1 || requested.getIndex() == received.getIndex()) &&
             ((requested.getReplacementElement() != null && requested.getReplacementElement().equals(received.getReplacementElement())) ||
              (requested.getReplacementElement() == null && received.getReplacementElement() == null)) &&
              requested.getChildDeltas().length == received.getChildDeltas().length)
        {
            for (int i = 0; i < requested.getChildDeltas().length; i++) {
                ModelDelta requestedChildDelta = (ModelDelta)requested.getChildDeltas()[i];
                ModelDelta receivedChildDelta = received.getChildDelta(requestedChildDelta.getElement());
                if ( receivedChildDelta == null || !deltaMatches(requestedChildDelta, receivedChildDelta) ) {
                    return false;
                }
            }
            return true;
        }
        return false;
    }

    /**
     * Creates a model in the pattern of:
     *
     * root
     *   1
     *     1.1
     *       1.1.1
     *   2
     *     2.1
     *       2.1.1
     *   3
     *     3.1
     *       3.1.1
     * ...
     *   (size)
     *     (size).1
     *       (size).1.1
     */
    static TestModel alternatingSubsreesModel(int size) {
        TestModel model = new TestModel();

        TestElement[] elements = new TestElement[size];
        for (int i = 0; i < size; i++) {
            String text = Integer.toString(i + 1);
            elements[i] =
                new TestElement(model, text, new TestElement[] {
 new TestElement(model, text + ".1", new TestElement[] { //$NON-NLS-1$
			new TestElement(model, text + ".1.1", new TestElement[0]) //$NON-NLS-1$
                    })
                });
        }
		model.setRoot(new TestElement(model, "root", elements)); //$NON-NLS-1$

        return model;
    }

    static boolean areTreeSelectionsEqual(ITreeSelection sel1, ITreeSelection sel2) {
		Set<TreePath> sel1Set = new HashSet<TreePath>();
        sel1Set.addAll( Arrays.asList(sel1.getPaths()) );

		Set<TreePath> sel2Set = new HashSet<TreePath>();
        sel2Set.addAll( Arrays.asList(sel2.getPaths()) );

        return sel1Set.equals(sel2Set);
    }

	static void expandAlternateElements(TestModelUpdatesListener listener, TestModel model, boolean waitForAllUpdates) throws Exception {
        listener.reset();
        listener.setFailOnRedundantUpdates(false);

        TestElement rootElement = model.getRootElement();
        TestElement[] children = rootElement.getChildren();
        ModelDelta rootDelta = new ModelDelta(rootElement, IModelDelta.NO_CHANGE);
        ModelDelta expandDelta = model.getBaseDelta(rootDelta);
        for (int i = 0; i < children.length; i++) {
            // Expand only odd children
            if (i % 2 == 1) {
                continue;
            }

            // Expand the element and the first child of each sub-element
            TestElement element = children[i];
            ModelDelta delta = expandDelta;
            int index = i;
            while (element.getChildren().length != 0) {
                TreePath elementPath = model.findElement(element.getLabel());
                listener.addUpdates(
                    elementPath, element, 1,
                    CHILD_COUNT_UPDATES | (waitForAllUpdates ? CHILDREN_UPDATES : 0) );
                delta = delta.addNode(element, index, IModelDelta.EXPAND, element.getChildren().length);
                element = element.getChildren()[0];
                index = 0;
            }
        }
        model.postDelta(rootDelta);

		TestUtil.waitWhile(t -> !listener.isFinished(CONTENT_SEQUENCE_COMPLETE | MODEL_CHANGED_COMPLETE), null, 30000, t -> "Listener not finished: " + listener);
    }

	public void testPreserveExpandedOnRemove() throws Exception {
        //TreeModelViewerAutopopulateAgent autopopulateAgent = new TreeModelViewerAutopopulateAgent(fViewer);
        TestModel model = alternatingSubsreesModel(6);

        // NOTE: WE ARE NOT EXPANDING ANY CHILDREN

        // Create the listener, only check the first level
        fListener.reset(TreePath.EMPTY, model.getRootElement(), 1, true, false);

        // Set the input into the view and update the view.
        fViewer.setInput(model.getRootElement());
		waitWhile(t -> !fListener.isFinished(), createListenerErrorMessage());
        model.validateData(fViewer, TreePath.EMPTY, true);

        expandAlternateElements(fListener, model, true);

        // Set a selection in view
		TreeSelection originalSelection = new TreeSelection(model.findElement("5.1")); //$NON-NLS-1$
        fViewer.setSelection(originalSelection);

        // Update the model
        ModelDelta delta = model.removeElementChild(TreePath.EMPTY, 0);

        // Remove delta should not generate any new updates
        fListener.reset();
        model.postDelta(delta);
		waitWhile(t -> !fListener.isFinished(MODEL_CHANGED_COMPLETE), createListenerErrorMessage());

        // Validate data
        model.validateData(fViewer, TreePath.EMPTY, true);
		assertTrue(getInternalViewer().getExpandedState(model.findElement("2")) == false); //$NON-NLS-1$
		assertTrue(getInternalViewer().getExpandedState(model.findElement("3")) == true); //$NON-NLS-1$
		assertTrue(getInternalViewer().getExpandedState(model.findElement("3.1")) == true); //$NON-NLS-1$
		assertTrue(getInternalViewer().getExpandedState(model.findElement("4")) == false); //$NON-NLS-1$
		assertTrue(getInternalViewer().getExpandedState(model.findElement("5")) == true); //$NON-NLS-1$
		assertTrue(getInternalViewer().getExpandedState(model.findElement("5.1")) == true); //$NON-NLS-1$
		assertTrue(getInternalViewer().getExpandedState(model.findElement("6")) == false); //$NON-NLS-1$
        assertTrue( areTreeSelectionsEqual(originalSelection, (ITreeSelection)fViewer.getSelection()) );
    }

	public void testPreserveExpandedOnInsert() throws Exception {
        //TreeModelViewerAutopopulateAgent autopopulateAgent = new TreeModelViewerAutopopulateAgent(fViewer);
        TestModel model = alternatingSubsreesModel(6);

        // NOTE: WE ARE NOT EXPANDING ANY CHILDREN

        // Create the listener, only check the first level
        fListener.reset(TreePath.EMPTY, model.getRootElement(), 1, true, false);

        // Set the input into the view and update the view.
        fViewer.setInput(model.getRootElement());
		waitWhile(t -> !fListener.isFinished(), createListenerErrorMessage());
        model.validateData(fViewer, TreePath.EMPTY, true);

        expandAlternateElements(fListener, model, true);

        // Set a selection in view
		TreeSelection originalSelection = new TreeSelection(model.findElement("5.1")); //$NON-NLS-1$
        fViewer.setSelection(originalSelection);

        // Update the model
		ModelDelta delta = model.insertElementChild(TreePath.EMPTY, 0, new TestElement(model, "0 - new", new TestElement[0])); //$NON-NLS-1$

        // Insert delta should generate updates only for the new element
		TreePath path = model.findElement("0 - new"); //$NON-NLS-1$
        // Note: redundant label updates on insert.
        fListener.reset(path, (TestElement)path.getLastSegment(), 0, false, false);
        fListener.addChildreUpdate(TreePath.EMPTY, 0);
        model.postDelta(delta);
		waitWhile(t -> !fListener.isFinished(MODEL_CHANGED_COMPLETE | ALL_UPDATES_COMPLETE), createListenerErrorMessage());

        // Validate data
        model.validateData(fViewer, TreePath.EMPTY, true);
		assertTrue(getInternalViewer().getExpandedState(model.findElement("1")) == true); //$NON-NLS-1$
		assertTrue(getInternalViewer().getExpandedState(model.findElement("1.1")) == true); //$NON-NLS-1$
		assertTrue(getInternalViewer().getExpandedState(model.findElement("2")) == false); //$NON-NLS-1$
		assertTrue(getInternalViewer().getExpandedState(model.findElement("3")) == true); //$NON-NLS-1$
		assertTrue(getInternalViewer().getExpandedState(model.findElement("3.1")) == true); //$NON-NLS-1$
		assertTrue(getInternalViewer().getExpandedState(model.findElement("4")) == false); //$NON-NLS-1$
		assertTrue(getInternalViewer().getExpandedState(model.findElement("5")) == true); //$NON-NLS-1$
		assertTrue(getInternalViewer().getExpandedState(model.findElement("5.1")) == true); //$NON-NLS-1$
		assertTrue(getInternalViewer().getExpandedState(model.findElement("6")) == false); //$NON-NLS-1$
        assertTrue( areTreeSelectionsEqual(originalSelection, (ITreeSelection)fViewer.getSelection()) );
    }

	public void testPreserveExpandedOnMultLevelContent() throws Exception {
        //TreeModelViewerAutopopulateAgent autopopulateAgent = new TreeModelViewerAutopopulateAgent(fViewer);
        TestModel model = alternatingSubsreesModel(6);

        // NOTE: WE ARE NOT EXPANDING ANY CHILDREN

        // Create the listener, only check the first level
        fListener.reset(TreePath.EMPTY, model.getRootElement(), 1, true, false);

        // Set the input into the view and update the view.
        fViewer.setInput(model.getRootElement());
		waitWhile(t -> !fListener.isFinished(), createListenerErrorMessage());
        model.validateData(fViewer, TreePath.EMPTY, true);

        expandAlternateElements(fListener, model, true);

        // Set a selection in view
        // Set a selection in view
        TreeSelection originalSelection = new TreeSelection(
new TreePath[] { model.findElement("5"), model.findElement("5.1"), model.findElement("6") }); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
        fViewer.setSelection(originalSelection);
        assertTrue( areTreeSelectionsEqual(originalSelection, (ITreeSelection)fViewer.getSelection()) );

        // Update the model
        model.removeElementChild(TreePath.EMPTY, 0);

        // Note: Re-expanding nodes causes redundant updates.
        fListener.reset(false, false);
        fListener.addUpdates(getInternalViewer(), TreePath.EMPTY, model.getRootElement(), -1, ALL_UPDATES_COMPLETE);

        // Create the delta which has nodes with CONTENT flag set at multiple levels.
        ModelDelta rootDelta = new ModelDelta(model.getRootElement(), IModelDelta.CONTENT);
		ModelDelta elementDelta = model.getElementDelta(rootDelta, model.findElement("3.1.1"), true); //$NON-NLS-1$
        elementDelta.setFlags(IModelDelta.CONTENT);

        // Post the multi-content update delta
        model.postDelta(rootDelta);
		waitWhile(t -> !fListener.isFinished(ALL_UPDATES_COMPLETE | STATE_RESTORE_COMPLETE), createListenerErrorMessage());

        // Validate data
        model.validateData(fViewer, TreePath.EMPTY, true);
		assertTrue(getInternalViewer().getExpandedState(model.findElement("2")) == false); //$NON-NLS-1$
		assertTrue(getInternalViewer().getExpandedState(model.findElement("3")) == true); //$NON-NLS-1$
		assertTrue(getInternalViewer().getExpandedState(model.findElement("3.1")) == true); //$NON-NLS-1$
		assertTrue(getInternalViewer().getExpandedState(model.findElement("4")) == false); //$NON-NLS-1$
		assertTrue(getInternalViewer().getExpandedState(model.findElement("5")) == true); //$NON-NLS-1$
		assertTrue(getInternalViewer().getExpandedState(model.findElement("5.1")) == true); //$NON-NLS-1$
		assertTrue(getInternalViewer().getExpandedState(model.findElement("6")) == false); //$NON-NLS-1$
        assertTrue( areTreeSelectionsEqual(originalSelection, (ITreeSelection)fViewer.getSelection()) );

        // Note: in past it was observed sub-optimal coalescing in this test due
        // to scattered update requests from viewer.
        assertTrue( fListener.checkCoalesced(TreePath.EMPTY, 0, 5) );
    }


	public void testPreserveExpandedOnSubTreeContent() throws Exception {
        //TreeModelViewerAutopopulateAgent autopopulateAgent = new TreeModelViewerAutopopulateAgent(fViewer);
        TestModel model = TestModel.simpleMultiLevel();

        // Expand all
        fViewer.setAutoExpandLevel(-1);

        // Create the listener,
        fListener.reset(TreePath.EMPTY, model.getRootElement(), -1, true, false);

        // Set the input into the view and update the view.
        fViewer.setInput(model.getRootElement());
		waitWhile(t -> !fListener.isFinished(), createListenerErrorMessage());
        model.validateData(fViewer, TreePath.EMPTY, true);

        // Turn off auto-expansion
        fViewer.setAutoExpandLevel(0);

        // Set a selection in view
		TreeSelection originalSelection = new TreeSelection(model.findElement("3.3.1")); //$NON-NLS-1$
        fViewer.setSelection(originalSelection);

        // Update the model
		model.addElementChild(model.findElement("3"), null, 0, new TestElement(model, "3.0 - new", new TestElement[0])); //$NON-NLS-1$ //$NON-NLS-2$

        // Create the delta for element "3" with content update.
		TreePath elementPath = model.findElement("3"); //$NON-NLS-1$
        ModelDelta rootDelta = new ModelDelta(model.getRootElement(), IModelDelta.NO_CHANGE);
        ModelDelta elementDelta = model.getElementDelta(rootDelta, elementPath, true);
        elementDelta.setFlags(IModelDelta.CONTENT);

        // Note: Re-expanding nodes causes redundant updates.
        fListener.reset(false, false);
        fListener.addUpdates(getInternalViewer(), elementPath, model.getElement(elementPath), -1, ALL_UPDATES_COMPLETE);

        // Post the sub-tree update
        model.postDelta(rootDelta);
		waitWhile(t -> !fListener.isFinished(ALL_UPDATES_COMPLETE | STATE_RESTORE_COMPLETE), createListenerErrorMessage());

        // Validate data
        model.validateData(fViewer, TreePath.EMPTY, true);
		assertTrue(getInternalViewer().getExpandedState(model.findElement("3")) == true); //$NON-NLS-1$
        // On windows, getExpandedState() may return true for an element with no children:
        // assertTrue(getCTargetViewer().getExpandedState(model.findElement("3.0 - new")) == false);
		assertTrue(getInternalViewer().getExpandedState(model.findElement("3.1")) == true); //$NON-NLS-1$
		assertTrue(getInternalViewer().getExpandedState(model.findElement("3.2")) == true); //$NON-NLS-1$
		assertTrue(getInternalViewer().getExpandedState(model.findElement("3.3")) == true); //$NON-NLS-1$
        assertTrue( areTreeSelectionsEqual(originalSelection, (ITreeSelection)fViewer.getSelection()) );
    }

	public void testPreserveExpandedOnContentStress() throws Exception {
        //TreeModelViewerAutopopulateAgent autopopulateAgent = new TreeModelViewerAutopopulateAgent(fViewer);
        TestModel model = alternatingSubsreesModel(6);

        // NOTE: WE ARE NOT EXPANDING ANY CHILDREN

        // Create the listener, only check the first level
        fListener.reset(TreePath.EMPTY, model.getRootElement(), 1, true, false);

        // Set the input into the view and update the view.
        fViewer.setInput(model.getRootElement());
		waitWhile(t -> !fListener.isFinished(), createListenerErrorMessage());
        model.validateData(fViewer, TreePath.EMPTY, true);

        expandAlternateElements(fListener, model, true);

        // Set a selection in view
//        TreeSelection originalSelection = new TreeSelection(
//            new TreePath[] { model.findElement("5"), model.findElement("5.1"), model.findElement("6") });
		TreeSelection originalSelection = new TreeSelection(model.findElement("5.1.1")); //$NON-NLS-1$
        fViewer.setSelection(originalSelection);
        assertTrue( areTreeSelectionsEqual(originalSelection, (ITreeSelection)fViewer.getSelection()) );

        // Run this test ten times as we've seen intermittent failures related
        // to timing in it.
        for (int i = 0; i < 10; i++) {
            // Update the model
            model.removeElementChild(TreePath.EMPTY, 0);

            // Note: Re-expanding nodes causes redundant updates.
            fListener.reset(false, false);
            fListener.addUpdates(getInternalViewer(), TreePath.EMPTY, model.getRootElement(), -1, ALL_UPDATES_COMPLETE);
            model.postDelta(new ModelDelta(model.getRootElement(), IModelDelta.CONTENT));
			waitWhile(t -> !fListener.isFinished(ALL_UPDATES_COMPLETE | STATE_RESTORE_COMPLETE), createListenerErrorMessage());

            // Validate data
            model.validateData(fViewer, TreePath.EMPTY, true);
			assertTrue(getInternalViewer().getExpandedState(model.findElement("2")) == false); //$NON-NLS-1$
			assertTrue(getInternalViewer().getExpandedState(model.findElement("3")) == true); //$NON-NLS-1$
			assertTrue(getInternalViewer().getExpandedState(model.findElement("3.1")) == true); //$NON-NLS-1$
			assertTrue(getInternalViewer().getExpandedState(model.findElement("4")) == false); //$NON-NLS-1$
			assertTrue(getInternalViewer().getExpandedState(model.findElement("5")) == true); //$NON-NLS-1$
			assertTrue(getInternalViewer().getExpandedState(model.findElement("5.1")) == true); //$NON-NLS-1$
			assertTrue(getInternalViewer().getExpandedState(model.findElement("6")) == false); //$NON-NLS-1$
            assertTrue( areTreeSelectionsEqual(originalSelection, (ITreeSelection)fViewer.getSelection()) );

            // Update the model again
			model.addElementChild(TreePath.EMPTY, null, 0, new TestElement(model, "1", new TestElement[0])); //$NON-NLS-1$

            // Note: Re-expanding nodes causes redundant updates.
            fListener.reset(false, false);
            fListener.addUpdates(getInternalViewer(), TreePath.EMPTY, model.getRootElement(), -1, ALL_UPDATES_COMPLETE);
            model.postDelta(new ModelDelta(model.getRootElement(), IModelDelta.CONTENT));
			waitWhile(t -> !fListener.isFinished(ALL_UPDATES_COMPLETE | STATE_RESTORE_COMPLETE), createListenerErrorMessage());

            // Validate data
            model.validateData(fViewer, TreePath.EMPTY, true);
			assertTrue(getInternalViewer().getExpandedState(model.findElement("2")) == false); //$NON-NLS-1$
			assertTrue(getInternalViewer().getExpandedState(model.findElement("3")) == true); //$NON-NLS-1$
			assertTrue(getInternalViewer().getExpandedState(model.findElement("3.1")) == true); //$NON-NLS-1$
			assertTrue(getInternalViewer().getExpandedState(model.findElement("4")) == false); //$NON-NLS-1$
			assertTrue(getInternalViewer().getExpandedState(model.findElement("5")) == true); //$NON-NLS-1$
			assertTrue(getInternalViewer().getExpandedState(model.findElement("5.1")) == true); //$NON-NLS-1$
			assertTrue(getInternalViewer().getExpandedState(model.findElement("6")) == false); //$NON-NLS-1$
            assertTrue( areTreeSelectionsEqual(originalSelection, (ITreeSelection)fViewer.getSelection()) );
        }
    }

	public void testPreserveLargeModelOnContent() throws Exception {
        //TreeModelViewerAutopopulateAgent autopopulateAgent = new TreeModelViewerAutopopulateAgent(fViewer);
        TestModel model = alternatingSubsreesModel(100);

        // NOTE: WE ARE NOT EXPANDING ANY CHILDREN

        // Create the listener, only check the first level
        fListener.reset();

        // Set the input into the view and update the view.
        fViewer.setInput(model.getRootElement());
		TestUtil.waitForJobs(getName(), 300, 5000);
		waitWhile(t -> !fListener.isFinished(CONTENT_SEQUENCE_COMPLETE), createListenerErrorMessage());

        expandAlternateElements(fListener, model, false);

        // Set a selection in view
		TreeSelection originalSelection = new TreeSelection(model.findElement("5.1.1")); //$NON-NLS-1$
        fViewer.setSelection(originalSelection);
        assertTrue( areTreeSelectionsEqual(originalSelection, (ITreeSelection)fViewer.getSelection()) );

        // Update the model
        model.removeElementChild(TreePath.EMPTY, 0);

        // Note: Re-expanding nodes causes redundant updates.
        fListener.reset(false, false);
        model.postDelta(new ModelDelta(model.getRootElement(), IModelDelta.CONTENT));
		waitWhile(t -> !fListener.isFinished(CONTENT_SEQUENCE_COMPLETE), createListenerErrorMessage());

        // Validate data
		assertTrue(getInternalViewer().getExpandedState(model.findElement("2")) == false); //$NON-NLS-1$
		assertTrue(getInternalViewer().getExpandedState(model.findElement("3")) == true); //$NON-NLS-1$
		assertTrue(getInternalViewer().getExpandedState(model.findElement("3.1")) == true); //$NON-NLS-1$
		assertTrue(getInternalViewer().getExpandedState(model.findElement("4")) == false); //$NON-NLS-1$
		assertTrue(getInternalViewer().getExpandedState(model.findElement("5")) == true); //$NON-NLS-1$
		assertTrue(getInternalViewer().getExpandedState(model.findElement("5.1")) == true); //$NON-NLS-1$
		assertTrue(getInternalViewer().getExpandedState(model.findElement("6")) == false); //$NON-NLS-1$
        assertTrue( areTreeSelectionsEqual(originalSelection, (ITreeSelection)fViewer.getSelection()) );

        // Update the model again
		model.addElementChild(TreePath.EMPTY, null, 0, new TestElement(model, "1", new TestElement[0])); //$NON-NLS-1$

        // Note: Re-expanding nodes causes redundant updates.
        fListener.reset(false, false);
        model.postDelta(new ModelDelta(model.getRootElement(), IModelDelta.CONTENT));
		waitWhile(t -> !fListener.isFinished(CONTENT_SEQUENCE_COMPLETE), createListenerErrorMessage());

        // Validate data
		assertTrue(getInternalViewer().getExpandedState(model.findElement("2")) == false); //$NON-NLS-1$
		assertTrue(getInternalViewer().getExpandedState(model.findElement("3")) == true); //$NON-NLS-1$
		assertTrue(getInternalViewer().getExpandedState(model.findElement("3.1")) == true); //$NON-NLS-1$
		assertTrue(getInternalViewer().getExpandedState(model.findElement("4")) == false); //$NON-NLS-1$
		assertTrue(getInternalViewer().getExpandedState(model.findElement("5")) == true); //$NON-NLS-1$
		assertTrue(getInternalViewer().getExpandedState(model.findElement("5.1")) == true); //$NON-NLS-1$
		assertTrue(getInternalViewer().getExpandedState(model.findElement("6")) == false); //$NON-NLS-1$
        assertTrue( areTreeSelectionsEqual(originalSelection, (ITreeSelection)fViewer.getSelection()) );
    }

    /**
     * This test verifies that if the model selects a new element
     * following a content refresh, the state restore logic will
     * not override the selection requested by the model.
     */
	public void testPreserveSelectionDeltaAfterContent() throws Exception {
        //TreeModelViewerAutopopulateAgent autopopulateAgent = new TreeModelViewerAutopopulateAgent(fViewer);
        TestModel model = TestModel.simpleMultiLevel();

        // Expand all
        fViewer.setAutoExpandLevel(-1);

        // Create the listener.
        fListener.reset(TreePath.EMPTY, model.getRootElement(), -1, true, false);

        // Set the input into the view and update the view.
        fViewer.setInput(model.getRootElement());
		waitWhile(t -> !fListener.isFinished(), createListenerErrorMessage());
        model.validateData(fViewer, TreePath.EMPTY, true);

        // Set a selection in view
		fViewer.setSelection(new TreeSelection(model.findElement("3.1.1"))); //$NON-NLS-1$

        // Reset the listener (ignore redundant updates)
        fListener.reset(TreePath.EMPTY, model.getRootElement(), -1, false, false);

        // Refresh content.
        // Note: Wait only for the processing of the delta, not for all updates
        model.postDelta(new ModelDelta(model.getRootElement(), IModelDelta.CONTENT));
		waitWhile(t -> !fListener.isFinished(MODEL_CHANGED_COMPLETE), createListenerErrorMessage());

        // Update the viewer with new selection delta to something new in the view
		ModelDelta selectDelta = model.makeElementDelta(model.findElement("2.1"), IModelDelta.SELECT); //$NON-NLS-1$

        // Wait for the second model delta to process
        fListener.resetModelChanged();
        model.postDelta(selectDelta);
		waitWhile(t -> !fListener.isFinished(MODEL_CHANGED_COMPLETE), createListenerErrorMessage());

        // Wait for all the updates to complete (note: we're not resetting the listener.
        model.postDelta(new ModelDelta(model.getRootElement(), IModelDelta.CONTENT));
		waitWhile(t -> !fListener.isFinished(ALL_UPDATES_COMPLETE | STATE_RESTORE_COMPLETE), createListenerErrorMessage());

        // Check to make sure that the state restore didn't change the selection.
		assertEquals(new TreeSelection(model.findElement("2.1")), fViewer.getSelection()); //$NON-NLS-1$
    }

	public void testPreserveCollapseDeltaAfterContent() throws Exception {
        //TreeModelViewerAutopopulateAgent autopopulateAgent = new TreeModelViewerAutopopulateAgent(fViewer);
        TestModel model = TestModel.simpleMultiLevel();

        // Expand all
        fViewer.setAutoExpandLevel(-1);

        // Create the listener.
        fListener.reset(TreePath.EMPTY, model.getRootElement(), -1, true, false);

        // Set the input into the view and update the view.
        fViewer.setInput(model.getRootElement());
		waitWhile(t -> !fListener.isFinished(), createListenerErrorMessage());
        model.validateData(fViewer, TreePath.EMPTY, true);

        // Turn off auto-expand
        fViewer.setAutoExpandLevel(0);

        // Reset the listener (ignore redundant updates)
        fListener.reset(TreePath.EMPTY, model.getRootElement(), -1, false, false);

        // Refresh content.
        // Note: Wait only for the processing of the delta, not for all updates
        model.postDelta(new ModelDelta(model.getRootElement(), IModelDelta.CONTENT));
		waitWhile(t -> !fListener.isFinished(MODEL_CHANGED_COMPLETE), createListenerErrorMessage());

        // Update the viewer to collapse an element
		ModelDelta collapseDelta = model.makeElementDelta(model.findElement("3.1"), IModelDelta.COLLAPSE); //$NON-NLS-1$

        // Remove updates for the collapsed element from listener, because they
        // will never happen if the element remains collapsed.
        fListener.resetModelChanged();
		fListener.removeLabelUpdate(model.findElement("3.1.1")); //$NON-NLS-1$
		fListener.removeLabelUpdate(model.findElement("3.1.2")); //$NON-NLS-1$
		fListener.removeLabelUpdate(model.findElement("3.1.3")); //$NON-NLS-1$
		fListener.removeHasChildrenUpdate(model.findElement("3.1.1")); //$NON-NLS-1$
		fListener.removeHasChildrenUpdate(model.findElement("3.1.2")); //$NON-NLS-1$
		fListener.removeHasChildrenUpdate(model.findElement("3.1.3")); //$NON-NLS-1$
		fListener.removeChildreCountUpdate(model.findElement("3.1")); //$NON-NLS-1$
		fListener.removeChildrenUpdate(model.findElement("3.1"), 0); //$NON-NLS-1$
		fListener.removeChildrenUpdate(model.findElement("3.1"), 1); //$NON-NLS-1$
		fListener.removeChildrenUpdate(model.findElement("3.1"), 2); //$NON-NLS-1$

        // Wait for the second model delta to process
        model.postDelta(collapseDelta);
		waitWhile(t -> !fListener.isFinished(MODEL_CHANGED_COMPLETE), createListenerErrorMessage());

        // Wait for all the updates to complete (note: we're not resetting the listener.
        model.postDelta(new ModelDelta(model.getRootElement(), IModelDelta.CONTENT));
		waitWhile(t -> !fListener.isFinished(ALL_UPDATES_COMPLETE | STATE_RESTORE_COMPLETE), createListenerErrorMessage());

        // Check to make sure that the state restore didn't change the selection.
		assertTrue(getInternalViewer().getExpandedState(model.findElement("3.1")) == false); //$NON-NLS-1$
    }

	public void testPreserveExpandDeltaAfterContent() throws Exception {
        //TreeModelViewerAutopopulateAgent autopopulateAgent = new TreeModelViewerAutopopulateAgent(fViewer);
        TestModel model = TestModel.simpleMultiLevel();

        // Note: Do not auto-expand!

        // Create the listener.
        fListener.reset(TreePath.EMPTY, model.getRootElement(), 1, true, false);

        // Set the input into the view and update the view.
        fViewer.setInput(model.getRootElement());
		waitWhile(t -> !fListener.isFinished(), createListenerErrorMessage());
        model.validateData(fViewer, TreePath.EMPTY, true);

        // Reset the listener (ignore redundant updates)
        fListener.reset(TreePath.EMPTY, model.getRootElement(), 1, false, false);

        // Refresh content.
        // Note: Wait only for the processing of the delta, not for all updates
        model.postDelta(new ModelDelta(model.getRootElement(), IModelDelta.CONTENT));
		waitWhile(t -> !fListener.isFinished(MODEL_CHANGED_COMPLETE), createListenerErrorMessage());

        // Update the viewer to expand an element
		ModelDelta expandDelta = model.makeElementDelta(model.findElement("3.1"), IModelDelta.EXPAND); //$NON-NLS-1$

        // Wait for the second model delta to process
        fListener.resetModelChanged();
        model.postDelta(expandDelta);
		waitWhile(t -> !fListener.isFinished(MODEL_CHANGED_COMPLETE), createListenerErrorMessage());

        // Wait for all the updates to complete (note: we're not resetting the listener.
        model.postDelta(new ModelDelta(model.getRootElement(), IModelDelta.CONTENT));
		waitWhile(t -> !fListener.isFinished(ALL_UPDATES_COMPLETE | STATE_RESTORE_COMPLETE), createListenerErrorMessage());

        // Check to make sure that the state restore didn't change the selection.
		assertTrue(getInternalViewer().getExpandedState(model.findElement("3.1")) == true); //$NON-NLS-1$
    }


	public void testSaveAndRestore1() throws Exception {
        //TreeModelViewerAutopopulateAgent autopopulateAgent = new TreeModelViewerAutopopulateAgent(fViewer);
        TestModel model = alternatingSubsreesModel(6);

        // NOTE: WE ARE NOT EXPANDING ANY CHILDREN

        // Create the listener, only check the first level
        fListener.reset(TreePath.EMPTY, model.getRootElement(), 1, true, false);

        // Set the input into the view and update the view.
        fViewer.setInput(model.getRootElement());
		waitWhile(t -> !fListener.isFinished(), createListenerErrorMessage());
        model.validateData(fViewer, TreePath.EMPTY, true);

        // Expand some, but not all elements
        expandAlternateElements(fListener, model, true);

        // Set a selection in view
		fViewer.setSelection(new TreeSelection(new TreePath[] { model.findElement("5.1"), model.findElement("5.1.1"), model.findElement("6.1.1") })); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$

        // Extract the original state from viewer
        ModelDelta originalState = new ModelDelta(model.getRootElement(), IModelDelta.NO_CHANGE);
        fViewer.saveElementState(TreePath.EMPTY, originalState, IModelDelta.EXPAND | IModelDelta.SELECT);

        // Set the viewer input to null.  This will trigger the view to save the viewer state.
        fListener.reset(false, false);
        fListener.addStateUpdates(getInternalViewer(), originalState, IModelDelta.EXPAND | IModelDelta.SELECT | IModelDelta.REVEAL);
        fViewer.setInput(null);
		waitWhile(t -> !fListener.isFinished(STATE_SAVE_COMPLETE | STATE_UPDATES), createListenerErrorMessage());

        // Set the viewer input back to the model.  When view updates are complete
        // the viewer
        // Note: disable redundant updates because the reveal delta triggers one.
        fListener.reset(TreePath.EMPTY, model.getRootElement(), 1, false, false);
        // TODO: add state updates somehow?
        fViewer.setInput(model.getRootElement());
		waitWhile(t -> !fListener.isFinished(), createListenerErrorMessage());

        // Extract the restored state from viewer
        ModelDelta restoredState = new ModelDelta(model.getRootElement(), IModelDelta.NO_CHANGE);
        fViewer.saveElementState(TreePath.EMPTY, restoredState, IModelDelta.EXPAND | IModelDelta.SELECT);

        if (!deltaMatches(originalState, restoredState)) {
			fail("Expected:\n" + originalState.toString() + "\nGot:\n" + restoredState); //$NON-NLS-1$ //$NON-NLS-2$
        }
    }

	public void testSaveAndRestore2() throws Exception {
        //TreeModelViewerAutopopulateAgent autopopulateAgent = new TreeModelViewerAutopopulateAgent(fViewer);
        TestModel model = TestModel.simpleMultiLevel();

        // expand all elements
        fViewer.setAutoExpandLevel(-1);

        // Create the listener, only check the first level
        fListener.reset(TreePath.EMPTY, model.getRootElement(), -1, true, false);

        // Set the input into the view and update the view.
        fViewer.setInput(model.getRootElement());
		waitWhile(t -> !fListener.isFinished(), createListenerErrorMessage());
        model.validateData(fViewer, TreePath.EMPTY);

        // Set a selection in view
		fViewer.setSelection(new TreeSelection(new TreePath[] { model.findElement("3.2"), model.findElement("3.2.1"), model.findElement("2") })); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
		fViewer.setSelection(new TreeSelection(model.findElement("3.2.3"))); //$NON-NLS-1$

        // Turn off the auto-expand now since we want to text the auto-expand logic
        fViewer.setAutoExpandLevel(-1);

        // Extract the original state from viewer
        ModelDelta originalState = new ModelDelta(model.getRootElement(), IModelDelta.NO_CHANGE);
        fViewer.saveElementState(TreePath.EMPTY, originalState, IModelDelta.EXPAND | IModelDelta.SELECT);

        // Set the viewer input to null.  This will trigger the view to save the viewer state.
        fListener.reset(true, false);
        fListener.addStateUpdates(getInternalViewer(), originalState, IModelDelta.EXPAND | IModelDelta.SELECT | IModelDelta.REVEAL);

        fViewer.setInput(null);
		waitWhile(t -> !fListener.isFinished(STATE_SAVE_COMPLETE | STATE_UPDATES), createListenerErrorMessage());

        // Set the viewer input back to the model.  When view updates are complete
        // the viewer
        // Note: disable redundant updates because the reveal delta triggers one.
        fListener.reset(TreePath.EMPTY, model.getRootElement(), 1, false, false);
        // TODO: add state updates somehow?
        fViewer.setInput(model.getRootElement());
		waitWhile(t -> !fListener.isFinished(), createListenerErrorMessage());

        // Extract the restored state from viewer
        ModelDelta restoredState = new ModelDelta(model.getRootElement(), IModelDelta.NO_CHANGE);
        fViewer.saveElementState(TreePath.EMPTY, restoredState, IModelDelta.EXPAND | IModelDelta.SELECT);

        if (!deltaMatches(originalState, restoredState)) {
			fail("Expected:\n" + originalState.toString() + "\nGot:\n" + restoredState); //$NON-NLS-1$ //$NON-NLS-2$
        }
    }

	public void testSaveAndRestoreInputInstance() throws Exception {
        //TreeModelViewerAutopopulateAgent autopopulateAgent = new TreeModelViewerAutopopulateAgent(fViewer);
        TestModel model = alternatingSubsreesModel(6);

        // NOTE: WE ARE NOT EXPANDING ANY CHILDREN

        // Create the listener, only check the first level
        fListener.reset(TreePath.EMPTY, model.getRootElement(), 1, true, false);

        // Set the input into the view and update the view.
        fViewer.setInput(model.getRootElement());
		waitWhile(t -> !fListener.isFinished(), createListenerErrorMessage());
        model.validateData(fViewer, TreePath.EMPTY, true);

        // Expand some, but not all elements
        expandAlternateElements(fListener, model, true);

        // Set a selection in view
		fViewer.setSelection(new TreeSelection(new TreePath[] { model.findElement("5.1"), model.findElement("5.1.1"), model.findElement("6.1.1") })); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$

        // Extract the original state from viewer
        ModelDelta originalState = new ModelDelta(model.getRootElement(), IModelDelta.NO_CHANGE);
        fViewer.saveElementState(TreePath.EMPTY, originalState, IModelDelta.EXPAND | IModelDelta.SELECT);

        // Do not reset to null, just reset input to the same object.

        // Set the viewer input back to the model.  When view updates are complete
        // the viewer
        // Note: disable redundant updates because the reveal delta triggers one.
        fListener.reset(TreePath.EMPTY, model.getRootElement(), 1, false, false);
        fViewer.setInput(model.getRootElement());
		waitWhile(t -> !fListener.isFinished(), createListenerErrorMessage());

        // Extract the restored state from viewer
        ModelDelta restoredState = new ModelDelta(model.getRootElement(), IModelDelta.NO_CHANGE);
        fViewer.saveElementState(TreePath.EMPTY, restoredState, IModelDelta.EXPAND | IModelDelta.SELECT);

        if (!deltaMatches(originalState, restoredState)) {
			fail("Expected:\n" + originalState.toString() + "\nGot:\n" + restoredState); //$NON-NLS-1$ //$NON-NLS-2$
        }
    }

	public void testSaveAndRestoreInputInstanceEquals() throws Exception {
        //TreeModelViewerAutopopulateAgent autopopulateAgent = new TreeModelViewerAutopopulateAgent(fViewer);
        TestModel model = alternatingSubsreesModel(6);

        // NOTE: WE ARE NOT EXPANDING ANY CHILDREN

        // Create the listener, only check the first level
        fListener.reset(TreePath.EMPTY, model.getRootElement(), 1, true, false);

        // Set the input into the view and update the view.
        fViewer.setInput(model.getRootElement());
		waitWhile(t -> !fListener.isFinished(), createListenerErrorMessage());
        model.validateData(fViewer, TreePath.EMPTY, true);

        // Expand some, but not all elements
        expandAlternateElements(fListener, model, true);

        // Set a selection in view
		fViewer.setSelection(new TreeSelection(new TreePath[] { model.findElement("5.1"), model.findElement("5.1.1"), model.findElement("6.1.1") })); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$

        // Extract the original state from viewer
        ModelDelta originalState = new ModelDelta(model.getRootElement(), IModelDelta.NO_CHANGE);
        fViewer.saveElementState(TreePath.EMPTY, originalState, IModelDelta.EXPAND | IModelDelta.SELECT);

        // Create a copy of the input object and set it to model.
        TestElement newRoot = new TestElement(model, model.getRootElement().getID(), model.getRootElement().getChildren());
        model.setRoot(newRoot);

        // Set the viewer input back to the model.  When view updates are complete
        // the viewer
        // Note: disable redundant updates because the reveal delta triggers one.
        fListener.reset(TreePath.EMPTY, model.getRootElement(), 1, false, false);

        fViewer.setInput(model.getRootElement());
		waitWhile(t -> !fListener.isFinished(), createListenerErrorMessage());

        // Extract the restored state from viewer
        ModelDelta restoredState = new ModelDelta(model.getRootElement(), IModelDelta.NO_CHANGE);
        fViewer.saveElementState(TreePath.EMPTY, restoredState, IModelDelta.EXPAND | IModelDelta.SELECT);

        if (!deltaMatches(originalState, restoredState)) {
			fail("Expected:\n" + originalState.toString() + "\nGot:\n" + restoredState); //$NON-NLS-1$ //$NON-NLS-2$
        }
    }


	public void testSaveAndRestoreLarge() throws Exception {
        //TreeModelViewerAutopopulateAgent autopopulateAgent = new TreeModelViewerAutopopulateAgent(fViewer);
        TestModel model = alternatingSubsreesModel(100);

        // NOTE: WE ARE NOT EXPANDING ANY CHILDREN

        // Create the listener, only check the first level
        fListener.reset();

        // Set the input into the view and update the view.
        fViewer.setInput(model.getRootElement());
		TestUtil.waitForJobs(getName(), 300, 5000);
		waitWhile(t -> !fListener.isFinished(CONTENT_SEQUENCE_COMPLETE), createListenerErrorMessage());

        expandAlternateElements(fListener, model, false);

        // Set a selection in view
		TreeSelection originalSelection = new TreeSelection(model.findElement("5.1.1")); //$NON-NLS-1$
        fViewer.setSelection(originalSelection);
        assertTrue( areTreeSelectionsEqual(originalSelection, (ITreeSelection)fViewer.getSelection()) );

        // Extract the original state from viewer
        ModelDelta originalState = new ModelDelta(model.getRootElement(), IModelDelta.NO_CHANGE);
        fViewer.saveElementState(TreePath.EMPTY, originalState, IModelDelta.EXPAND | IModelDelta.SELECT);

        // Set the viewer input to null.  This will trigger the view to save the viewer state.
        fListener.reset();
        fListener.addStateUpdates(getInternalViewer(), originalState, IModelDelta.EXPAND | IModelDelta.SELECT | IModelDelta.REVEAL);

        fViewer.setInput(null);
		TestUtil.waitForJobs(getName(), 300, 5000);
		waitWhile(t -> !fListener.isFinished(STATE_SAVE_COMPLETE | STATE_UPDATES), createListenerErrorMessage());

        // Set the viewer input back to the model.  When view updates are complete
        // the viewer
        // Note: disable redundant updates because the reveal delta triggers one.
        fListener.reset();
        fViewer.setInput(model.getRootElement());
		TestUtil.waitForJobs(getName(), 300, 5000);
		waitWhile(t -> !fListener.isFinished(CONTENT_SEQUENCE_COMPLETE), createListenerErrorMessage());

        // Validate data (only select visible elements).
		assertTrue(getInternalViewer().getExpandedState(model.findElement("1")) == true); //$NON-NLS-1$
		assertTrue(getInternalViewer().getExpandedState(model.findElement("1.1")) == true); //$NON-NLS-1$
		assertTrue(getInternalViewer().getExpandedState(model.findElement("2")) == false); //$NON-NLS-1$
		assertTrue(getInternalViewer().getExpandedState(model.findElement("3")) == true); //$NON-NLS-1$
		assertTrue(getInternalViewer().getExpandedState(model.findElement("3.1")) == true); //$NON-NLS-1$
		assertTrue(getInternalViewer().getExpandedState(model.findElement("4")) == false); //$NON-NLS-1$
		assertTrue(getInternalViewer().getExpandedState(model.findElement("5")) == true); //$NON-NLS-1$
		assertTrue(getInternalViewer().getExpandedState(model.findElement("5.1")) == true); //$NON-NLS-1$
		assertTrue(getInternalViewer().getExpandedState(model.findElement("6")) == false); //$NON-NLS-1$
        assertTrue( areTreeSelectionsEqual(originalSelection, (ITreeSelection)fViewer.getSelection()) );
    }

    /**
     * This test saves state of a large tree.  Then the tree is modified
     * to contain much fewer elements.  The restore logic should discard the
     * rest of the saved state delta once all the elements are visible.
     */
	public void testSaveAndRestorePartialStateLarge() throws Exception {
        //TreeModelViewerAutopopulateAgent autopopulateAgent = new TreeModelViewerAutopopulateAgent(fViewer);
        TestModel model = alternatingSubsreesModel(100);

        // NOTE: WE ARE NOT EXPANDING ANY CHILDREN

        // Create the listener, only check the first level
        fListener.reset();

        // Set the input into the view and update the view.
        fViewer.setInput(model.getRootElement());
		TestUtil.waitForJobs(getName(), 300, 5000);
		waitWhile(t -> !fListener.isFinished(CONTENT_SEQUENCE_COMPLETE), createListenerErrorMessage());

        expandAlternateElements(fListener, model, false);

        // Set a selection in view
		TreeSelection originalSelection = new TreeSelection(model.findElement("5.1.1")); //$NON-NLS-1$
        fViewer.setSelection(originalSelection);
        assertTrue( areTreeSelectionsEqual(originalSelection, (ITreeSelection)fViewer.getSelection()) );

        // Extract the original state from viewer
        ModelDelta originalState = new ModelDelta(model.getRootElement(), IModelDelta.NO_CHANGE);
        fViewer.saveElementState(TreePath.EMPTY, originalState, IModelDelta.EXPAND | IModelDelta.SELECT);

        // Set the viewer input to null.  This will trigger the view to save the viewer state.
        fListener.reset();
        fListener.addStateUpdates(getInternalViewer(), originalState, IModelDelta.EXPAND | IModelDelta.SELECT | IModelDelta.REVEAL);

        fViewer.setInput(null);
		TestUtil.waitForJobs(getName(), 300, 5000);
		waitWhile(t -> !fListener.isFinished(STATE_SAVE_COMPLETE | STATE_UPDATES), createListenerErrorMessage());


        TestElement[] elements = model.getRootElement().getChildren();
        TestElement[] newElements = new TestElement[10];
        System.arraycopy(elements, 0, newElements, 0, newElements.length);
        model.setElementChildren(TreePath.EMPTY, newElements);

        // Set the viewer input back to the model.  When view updates are complete
        // the viewer
        // Note: disable redundant updates because the reveal delta triggers one.
        fListener.reset();
        fViewer.setInput(model.getRootElement());
		TestUtil.waitForJobs(getName(), 300, 5000);

        // MONITOR FOR THE STATE RESTORE TO COMPLETE
		waitWhile(t -> !fListener.isFinished(CONTENT_SEQUENCE_COMPLETE | STATE_RESTORE_COMPLETE), createListenerErrorMessage());

        // Validate data
		assertTrue(getInternalViewer().getExpandedState(model.findElement("1")) == true); //$NON-NLS-1$
		assertTrue(getInternalViewer().getExpandedState(model.findElement("1.1")) == true); //$NON-NLS-1$
		assertTrue(getInternalViewer().getExpandedState(model.findElement("2")) == false); //$NON-NLS-1$
		assertTrue(getInternalViewer().getExpandedState(model.findElement("3")) == true); //$NON-NLS-1$
		assertTrue(getInternalViewer().getExpandedState(model.findElement("3.1")) == true); //$NON-NLS-1$
		assertTrue(getInternalViewer().getExpandedState(model.findElement("4")) == false); //$NON-NLS-1$
		assertTrue(getInternalViewer().getExpandedState(model.findElement("5")) == true); //$NON-NLS-1$
		assertTrue(getInternalViewer().getExpandedState(model.findElement("5.1")) == true); //$NON-NLS-1$
		assertTrue(getInternalViewer().getExpandedState(model.findElement("6")) == false); //$NON-NLS-1$
        assertTrue( areTreeSelectionsEqual(originalSelection, (ITreeSelection)fViewer.getSelection()) );
    }

	public void testPreserveCollapseAndSelectDeltaAfterSaveAndRestore() throws Exception {
        //TreeModelViewerAutopopulateAgent autopopulateAgent = new TreeModelViewerAutopopulateAgent(fViewer);
        TestModel model = TestModel.simpleMultiLevel();

        // Expand all
        fViewer.setAutoExpandLevel(-1);

        // Create the listener.
        fListener.reset(TreePath.EMPTY, model.getRootElement(), -1, true, false);

        // Set the input into the view and update the view.
        fViewer.setInput(model.getRootElement());
		waitWhile(t -> !fListener.isFinished(), createListenerErrorMessage());
        model.validateData(fViewer, TreePath.EMPTY, true);

		fViewer.setSelection(new TreeSelection(model.findElement("3"))); //$NON-NLS-1$

        // Turn off auto-expand
        fViewer.setAutoExpandLevel(0);

        // Set the viewer input to null.  This will trigger the view to save the viewer state.
        fListener.reset(false, false);
        fViewer.setInput(null);
		waitWhile(t -> !fListener.isFinished(STATE_SAVE_COMPLETE), createListenerErrorMessage());

        // Set the viewer input back to the model.  When view updates are complete
        // the viewer
        // Note: disable redundant updates because the reveal delta triggers one.
        fListener.reset(TreePath.EMPTY, model.getRootElement(), 1, false, false);
        fViewer.setInput(model.getRootElement());
		TreePath path = model.findElement("2"); //$NON-NLS-1$
        fListener.addUpdates(null, path, (TestElement)path.getLastSegment(), 0, STATE_UPDATES);
		path = model.findElement("3"); //$NON-NLS-1$
        fListener.addUpdates(null, path, (TestElement)path.getLastSegment(), 0, STATE_UPDATES);

        // Wait till we restore state of elements we want to collapse and select
        // Bug 372619 - Need to wait until proxy installed delta is processed before
        // posting the next delta.
		waitWhile(t -> !fListener.isFinished(STATE_RESTORE_STARTED | STATE_UPDATES | CHILDREN_UPDATES | MODEL_CHANGED_COMPLETE), createListenerErrorMessage());

        // Post first collapse delta
        fListener.resetModelChanged();
		model.postDelta(model.makeElementDelta(model.findElement("2"), IModelDelta.COLLAPSE)); //$NON-NLS-1$
		waitWhile(t -> !fListener.isFinished(MODEL_CHANGED_COMPLETE), createListenerErrorMessage());

        // Post second collapse delta
        fListener.resetModelChanged();
		model.postDelta(model.makeElementDelta(model.findElement("3"), IModelDelta.COLLAPSE)); //$NON-NLS-1$
		waitWhile(t -> !fListener.isFinished(MODEL_CHANGED_COMPLETE), createListenerErrorMessage());

        // Post select delta
		model.postDelta(model.makeElementDelta(model.findElement("1"), IModelDelta.SELECT)); //$NON-NLS-1$
		waitWhile(t -> !fListener.isFinished(MODEL_CHANGED_COMPLETE), createListenerErrorMessage());

        // Wait for all the updates to complete (note: we're not resetting the listener).
		waitWhile(t -> !fListener.isFinished(STATE_RESTORE_COMPLETE), createListenerErrorMessage());

        // Check to make sure that the state restore didn't change the selection.
		assertTrue(getInternalViewer().getExpandedState(model.findElement("2")) == false); //$NON-NLS-1$
		assertTrue(getInternalViewer().getExpandedState(model.findElement("3")) == false); //$NON-NLS-1$
		assertEquals(new TreeSelection(model.findElement("1")), fViewer.getSelection()); //$NON-NLS-1$
    }

    /**
     * Test for bug 359859.<br>
     * This test verifies that RESTORE state is handled after SAVE previous state was completed
     */
	public void testSaveRestoreOrder() throws Exception {
        //TreeModelViewerAutopopulateAgent autopopulateAgent = new TreeModelViewerAutopopulateAgent(fViewer);
        TestModel model = TestModel.simpleMultiLevel();
        model.setDelayUpdates(true);

        // Expand all
        fViewer.setAutoExpandLevel(-1);

        // Create the listener.
        fListener.reset(TreePath.EMPTY, model.getRootElement(), -1, false, false);

        // Set the input into the view and update the view.
        fViewer.setInput(model.getRootElement());
		waitWhile(t -> !fListener.isFinished(), createListenerErrorMessage());
        model.validateData(fViewer, TreePath.EMPTY, true);

        // a new similar model
        TestModel copyModel = TestModel.simpleMultiLevel();

        // Trigger save - restore sequence.
        fListener.reset();
        fListener.expectRestoreAfterSaveComplete();
        fViewer.setInput(copyModel.getRootElement());
		waitWhile(t -> !fListener.isFinished(STATE_RESTORE_STARTED), createListenerErrorMessage());
		assertTrue("RESTORE started before SAVE to complete", fListener.isFinished(STATE_SAVE_COMPLETE)); //$NON-NLS-1$
    }

    /**
     * This test tries to restore a viewer state while input == null.
     * See: Bug 380288 - NPE switching to the Breakpoints View
     */
	public void testUpdateWithNullInput() throws Exception {
        TestModel model = TestModel.simpleMultiLevel();
        fViewer.setAutoExpandLevel(-1);

        // Create the listener
        fListener.reset(TreePath.EMPTY, model.getRootElement(), -1, false, false);

        // Set the input into the view and update the view.
        fViewer.setInput(model.getRootElement());
		waitWhile(t -> !fListener.isFinished(), createListenerErrorMessage());
        model.validateData(fViewer, TreePath.EMPTY);

        ModelDelta expandedState = new ModelDelta(model.getRootElement(), IModelDelta.NO_CHANGE);
        fViewer.saveElementState(TreePath.EMPTY, expandedState, IModelDelta.EXPAND);

        // Refresh the viewer so that updates are generated.
        fListener.reset();
        fListener.addChildreCountUpdate(TreePath.EMPTY);
        model.postDelta(new ModelDelta(model.getRootElement(), IModelDelta.CONTENT));

        // Wait for the delta to be processed.
		waitWhile(t -> !fListener.isFinished(MODEL_CHANGED_COMPLETE | CHILD_COUNT_UPDATES), createListenerErrorMessage());

        fViewer.setInput(null);
        fViewer.updateViewer(expandedState);

		waitWhile(t -> !fListener.isFinished(CONTENT_COMPLETE | VIEWER_UPDATES_RUNNING), createListenerErrorMessage());

    }
}
