/*******************************************************************************
 * Copyright (c) 2009 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
 *******************************************************************************/
package org.eclipe.debug.tests.viewer.model;

import junit.framework.Assert;
import junit.framework.TestCase;

import org.eclipe.debug.tests.viewer.model.TestModel.TestElement;
import org.eclipse.debug.internal.ui.viewers.model.ITreeModelContentProviderTarget;
import org.eclipse.debug.internal.ui.viewers.model.ITreeModelViewer;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta;
import org.eclipse.debug.internal.ui.viewers.model.provisional.ModelDelta;
import org.eclipse.jface.viewers.TreePath;
import org.eclipse.jface.viewers.TreeSelection;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.PlatformUI;

/**
 * Tests to verify that the viewer can save and restore correctly the expansion 
 * state of elements.
 * 
 * @since 3.6
 */
abstract public class StateTests extends TestCase implements ITestModelUpdatesListenerConstants {
    Display fDisplay;
    Shell fShell;
    ITreeModelViewer fViewer;
    TestModelUpdatesListener fListener;
    
    public StateTests(String name) {
        super(name);
    }

    /**
     * @throws java.lang.Exception
     */
    protected void setUp() throws Exception {
        fDisplay = PlatformUI.getWorkbench().getDisplay();
        fShell = new Shell(fDisplay/*, SWT.ON_TOP | SWT.SHELL_TRIM*/);
        fShell.setMaximized(true);
        fShell.setLayout(new FillLayout());

        fViewer = createViewer(fDisplay, fShell);
        
        fListener = new TestModelUpdatesListener(false, false);
        fViewer.addViewerUpdateListener(fListener);
        fViewer.addLabelUpdateListener(fListener);
        fViewer.addModelChangedListener(fListener);
        fViewer.addStateUpdateListener(fListener);

        fShell.open ();
    }

    abstract protected ITreeModelViewer createViewer(Display display, Shell shell);
    
    /**
     * @throws java.lang.Exception
     */
    protected void tearDown() throws Exception {
        fViewer.removeLabelUpdateListener(fListener);
        fViewer.removeViewerUpdateListener(fListener);
        fViewer.removeModelChangedListener(fListener);
        fViewer.addStateUpdateListener(fListener);
        fViewer.getPresentationContext().dispose();
        
        // Close the shell and exit.
        fShell.close();
        while (!fShell.isDisposed()) if (!fDisplay.readAndDispatch ()) fDisplay.sleep ();
    }

    protected ITreeModelContentProviderTarget getCTargetViewer() {
        return (ITreeModelContentProviderTarget)fViewer;
    }
    
    public void testUpdateViewer() {
        //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());
        while (!fListener.isFinished()) if (!fDisplay.readAndDispatch ()) fDisplay.sleep ();
        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);
        while (!fListener.isFinished(CONTENT_UPDATES_COMPLETE | LABEL_UPDATES)) 
            if (!fDisplay.readAndDispatch ()) fDisplay.sleep ();

        // 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) ) {
            Assert.fail("Expected:\n" + updateDelta.toString() + "\nGot:\n" + savedDelta); 
        }
    }

    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;
    }
    
    private TestModel alternatingSubsreesModel() {
        TestModel model = new TestModel();
        model.setRoot( new TestElement(model, "root", new TestElement[] {
            new TestElement(model, "1", new TestElement[] {
                new TestElement(model, "1.1", new TestElement[] {
                    new TestElement(model, "1.1.1", new TestElement[0]),
                }),
            }),
            new TestElement(model, "2", new TestElement[] {
                new TestElement(model, "2.1", new TestElement[] {
                    new TestElement(model, "2.1.1", new TestElement[0]),
                }),
            }),
            new TestElement(model, "3", new TestElement[] {
                new TestElement(model, "3.1", new TestElement[] {
                    new TestElement(model, "3.1.1", new TestElement[0]),
                }),
            }),
            new TestElement(model, "4", new TestElement[] {
                new TestElement(model, "4.1", new TestElement[] {
                    new TestElement(model, "4.1.1", new TestElement[0]),
                }),
            }),
            new TestElement(model, "5", new TestElement[] {
                new TestElement(model, "5.1", new TestElement[] {
                    new TestElement(model, "5.1.1", new TestElement[0]),
                }),
            }),
            new TestElement(model, "6", new TestElement[] {
                new TestElement(model, "6.1", new TestElement[] {
                    new TestElement(model, "6.1.1", new TestElement[0]),
                }),
            })
        }) );
        return model;
    }

    private void expandAlternateElements(TestModel model) {
        // Expand every other child
        fListener.reset(); 
        fListener.setFailOnRedundantUpdates(false);
        ITreeModelContentProviderTarget viewer = (ITreeModelContentProviderTarget)fViewer; 
        TreePath path;
        fListener.addUpdates(path = model.findElement("1"), (TestElement)path.getLastSegment(), 1, CHILDREN_COUNT_UPDATES | CHILDREN_UPDATES);
        viewer.setExpandedState(path, true);
        fListener.addUpdates(path = model.findElement("3"), (TestElement)path.getLastSegment(), 1, CHILDREN_COUNT_UPDATES | CHILDREN_UPDATES);
        viewer.setExpandedState(path, true);
        fListener.addUpdates(path = model.findElement("5"), (TestElement)path.getLastSegment(), 1, CHILDREN_COUNT_UPDATES | CHILDREN_UPDATES);
        viewer.setExpandedState(path, true);
             
        while (!fListener.isFinished()) if (!fDisplay.readAndDispatch ()) fDisplay.sleep ();
        model.validateData(fViewer, TreePath.EMPTY, true);

        // Expand the sub-children as well (so that the expanded nodes go 2 levels down.
        fListener.reset(); 
        fListener.addUpdates(path = model.findElement("1.1"), (TestElement)path.getLastSegment(), 1, CHILDREN_COUNT_UPDATES | CHILDREN_UPDATES);
        viewer.setExpandedState(path, true);
        fListener.addUpdates(path = model.findElement("3.1"), (TestElement)path.getLastSegment(), 1, CHILDREN_COUNT_UPDATES | CHILDREN_UPDATES);
        viewer.setExpandedState(path, true);
        fListener.addUpdates(path = model.findElement("5.1"), (TestElement)path.getLastSegment(), 1, CHILDREN_COUNT_UPDATES | CHILDREN_UPDATES);
        viewer.setExpandedState(path, true);
        while (!fListener.isFinished()) if (!fDisplay.readAndDispatch ()) fDisplay.sleep ();
        model.validateData(fViewer, TreePath.EMPTY, true);
    }
    
    public void testPreserveExpandedOnRemove() {
        //TreeModelViewerAutopopulateAgent autopopulateAgent = new TreeModelViewerAutopopulateAgent(fViewer);
        TestModel model = alternatingSubsreesModel();

        // 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());
        while (!fListener.isFinished()) if (!fDisplay.readAndDispatch ()) fDisplay.sleep ();
        model.validateData(fViewer, TreePath.EMPTY, true);

        expandAlternateElements(model);
        
        // Set a selection in view
        TreeSelection originalSelection = new TreeSelection(model.findElement("5.1.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);
        while (!fListener.isFinished(MODEL_CHANGED_COMPLETE)) 
            if (!fDisplay.readAndDispatch ()) fDisplay.sleep ();
        
        // Validate data
        model.validateData(fViewer, TreePath.EMPTY, true);
        Assert.assertTrue(getCTargetViewer().getExpandedState(model.findElement("2")) == false);
        Assert.assertTrue(getCTargetViewer().getExpandedState(model.findElement("3")) == true);
        Assert.assertTrue(getCTargetViewer().getExpandedState(model.findElement("3.1")) == true);
        Assert.assertTrue(getCTargetViewer().getExpandedState(model.findElement("4")) == false);
        Assert.assertTrue(getCTargetViewer().getExpandedState(model.findElement("5")) == true);
        Assert.assertTrue(getCTargetViewer().getExpandedState(model.findElement("5.1")) == true);
        Assert.assertTrue(getCTargetViewer().getExpandedState(model.findElement("6")) == false);
        Assert.assertEquals(originalSelection, fViewer.getSelection());
    }

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

        // 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());
        while (!fListener.isFinished()) if (!fDisplay.readAndDispatch ()) fDisplay.sleep ();
        model.validateData(fViewer, TreePath.EMPTY, true);

        expandAlternateElements(model);
        
        // Set a selection in view
        TreeSelection originalSelection = new TreeSelection(model.findElement("5.1.1"));
        fViewer.setSelection(originalSelection);
        
        // Update the model
        ModelDelta delta = model.insertElementChild(TreePath.EMPTY, 0, new TestElement(model, "0 - new", new TestElement[0]));
        
        // Insert delta should generate updates only for the new element
        TreePath path = model.findElement("0 - new");
        // Note: redundant label updates on insert.
        fListener.reset(path, (TestElement)path.getLastSegment(), 0, false, false); 
        fListener.addChildreUpdate(TreePath.EMPTY, 0);
        model.postDelta(delta);
        while (!fListener.isFinished(MODEL_CHANGED_COMPLETE | ALL_UPDATES_COMPLETE)) 
            if (!fDisplay.readAndDispatch ()) fDisplay.sleep ();
        
        // Validate data
        model.validateData(fViewer, TreePath.EMPTY, true);
        Assert.assertTrue(getCTargetViewer().getExpandedState(model.findElement("1")) == true);
        Assert.assertTrue(getCTargetViewer().getExpandedState(model.findElement("1.1")) == true);
        Assert.assertTrue(getCTargetViewer().getExpandedState(model.findElement("2")) == false);
        Assert.assertTrue(getCTargetViewer().getExpandedState(model.findElement("3")) == true);
        Assert.assertTrue(getCTargetViewer().getExpandedState(model.findElement("3.1")) == true);
        Assert.assertTrue(getCTargetViewer().getExpandedState(model.findElement("4")) == false);
        Assert.assertTrue(getCTargetViewer().getExpandedState(model.findElement("5")) == true);
        Assert.assertTrue(getCTargetViewer().getExpandedState(model.findElement("5.1")) == true);
        Assert.assertTrue(getCTargetViewer().getExpandedState(model.findElement("6")) == false);
        Assert.assertEquals(originalSelection, fViewer.getSelection());
    }

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

        // 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());
        while (!fListener.isFinished()) if (!fDisplay.readAndDispatch ()) fDisplay.sleep ();
        model.validateData(fViewer, TreePath.EMPTY, true);

        expandAlternateElements(model);
        
        // Set a selection in view
        TreeSelection originalSelection = new TreeSelection(model.findElement("5.1.1"));
        fViewer.setSelection(originalSelection);

        // Update the model
        model.removeElementChild(TreePath.EMPTY, 0);
        
        // Note: Re-expanding nodes causes redundant updates.
        fListener.reset(false, false);
        fListener.addUpdates(getCTargetViewer(), 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);
        elementDelta.setFlags(IModelDelta.CONTENT);
        
        // Post the multi-content update delta
        model.postDelta(rootDelta);
        while (!fListener.isFinished(ALL_UPDATES_COMPLETE | STATE_RESTORE_COMPLETE)) 
            if (!fDisplay.readAndDispatch ()) fDisplay.sleep ();

        // Validate data
        model.validateData(fViewer, TreePath.EMPTY, true);
        Assert.assertTrue(getCTargetViewer().getExpandedState(model.findElement("2")) == false);
        Assert.assertTrue(getCTargetViewer().getExpandedState(model.findElement("3")) == true);
        Assert.assertTrue(getCTargetViewer().getExpandedState(model.findElement("3.1")) == true);
        Assert.assertTrue(getCTargetViewer().getExpandedState(model.findElement("4")) == false);
        Assert.assertTrue(getCTargetViewer().getExpandedState(model.findElement("5")) == true);
        Assert.assertTrue(getCTargetViewer().getExpandedState(model.findElement("5.1")) == true);
        Assert.assertTrue(getCTargetViewer().getExpandedState(model.findElement("6")) == false);
        Assert.assertEquals(originalSelection, fViewer.getSelection());
    }


    public void testPreserveExpandedOnSubTreeContent() {
        //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());
        while (!fListener.isFinished()) if (!fDisplay.readAndDispatch ()) fDisplay.sleep ();
        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"));
        fViewer.setSelection(originalSelection);

        // Update the model
        model.addElementChild(model.findElement("3"), 0, new TestElement(model, "3.0 - new", new TestElement[0]));
        
        // Create the delta for element "3" with content update.
        TreePath elementPath = model.findElement("3");
        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(getCTargetViewer(), elementPath, model.getElement(elementPath), -1, ALL_UPDATES_COMPLETE);
        
        // Post the sub-tree update
        model.postDelta(rootDelta);
        while (!fListener.isFinished(ALL_UPDATES_COMPLETE | STATE_RESTORE_COMPLETE)) 
            if (!fDisplay.readAndDispatch ()) fDisplay.sleep ();

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

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

        // 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());
        while (!fListener.isFinished()) if (!fDisplay.readAndDispatch ()) fDisplay.sleep ();
        model.validateData(fViewer, TreePath.EMPTY, true);

        expandAlternateElements(model);
        
        // Set a selection in view
        TreeSelection originalSelection = new TreeSelection(model.findElement("5.1.1"));
        fViewer.setSelection(originalSelection);
        Assert.assertEquals(originalSelection, 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(getCTargetViewer(), TreePath.EMPTY, model.getRootElement(), -1, ALL_UPDATES_COMPLETE); 
            model.postDelta(new ModelDelta(model.getRootElement(), IModelDelta.CONTENT));
            while (!fListener.isFinished(ALL_UPDATES_COMPLETE | STATE_RESTORE_COMPLETE)) 
                if (!fDisplay.readAndDispatch ()) fDisplay.sleep ();

            // Validate data
            model.validateData(fViewer, TreePath.EMPTY, true);
            Assert.assertTrue(getCTargetViewer().getExpandedState(model.findElement("2")) == false);
            Assert.assertTrue(getCTargetViewer().getExpandedState(model.findElement("3")) == true);
            Assert.assertTrue(getCTargetViewer().getExpandedState(model.findElement("3.1")) == true);
            Assert.assertTrue(getCTargetViewer().getExpandedState(model.findElement("4")) == false);
            Assert.assertTrue(getCTargetViewer().getExpandedState(model.findElement("5")) == true);
            Assert.assertTrue(getCTargetViewer().getExpandedState(model.findElement("5.1")) == true);
            Assert.assertTrue(getCTargetViewer().getExpandedState(model.findElement("6")) == false);
            Assert.assertEquals(originalSelection, fViewer.getSelection());
            
            // Update the model again
            model.addElementChild(TreePath.EMPTY, 0, new TestElement(model, "1", new TestElement[0]));
            
            // Note: Re-expanding nodes causes redundant updates.
            fListener.reset(false, false);
            fListener.addUpdates(getCTargetViewer(), TreePath.EMPTY, model.getRootElement(), -1, ALL_UPDATES_COMPLETE); 
            model.postDelta(new ModelDelta(model.getRootElement(), IModelDelta.CONTENT));
            while (!fListener.isFinished(ALL_UPDATES_COMPLETE | STATE_RESTORE_COMPLETE)) 
                if (!fDisplay.readAndDispatch ()) fDisplay.sleep ();

            // Validate data
            model.validateData(fViewer, TreePath.EMPTY, true);
            Assert.assertTrue(getCTargetViewer().getExpandedState(model.findElement("2")) == false);
            Assert.assertTrue(getCTargetViewer().getExpandedState(model.findElement("3")) == true);
            Assert.assertTrue(getCTargetViewer().getExpandedState(model.findElement("3.1")) == true);
            Assert.assertTrue(getCTargetViewer().getExpandedState(model.findElement("4")) == false);
            Assert.assertTrue(getCTargetViewer().getExpandedState(model.findElement("5")) == true);
            Assert.assertTrue(getCTargetViewer().getExpandedState(model.findElement("5.1")) == true);
            Assert.assertTrue(getCTargetViewer().getExpandedState(model.findElement("6")) == false);
            Assert.assertEquals(originalSelection, fViewer.getSelection());
        }
    }
    
    public void testPreserveSelectionDeltaAfterContent() {
        //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());
        while (!fListener.isFinished()) if (!fDisplay.readAndDispatch ()) fDisplay.sleep ();
        model.validateData(fViewer, TreePath.EMPTY, true);

        // Set a selection in view
        fViewer.setSelection(new TreeSelection(model.findElement("3.1.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, nto for all updates
        model.postDelta(new ModelDelta(model.getRootElement(), IModelDelta.CONTENT));
        while (!fListener.isFinished(MODEL_CHANGED_COMPLETE)) 
            if (!fDisplay.readAndDispatch ()) fDisplay.sleep ();

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

        // Wait for the second model dleta to process
        fListener.resetModelChanged();
        model.postDelta(selectDelta);
        while (!fListener.isFinished(MODEL_CHANGED_COMPLETE)) 
            if (!fDisplay.readAndDispatch ()) fDisplay.sleep ();
        
        // Wait for all the updates to cimplete (note: we're not resetting the listener.
        model.postDelta(new ModelDelta(model.getRootElement(), IModelDelta.CONTENT));
        while (!fListener.isFinished(ALL_UPDATES_COMPLETE | STATE_RESTORE_COMPLETE)) 
            if (!fDisplay.readAndDispatch ()) fDisplay.sleep ();

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

    public void testPreserveCollapseDeltaAfterContent() {
        //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());
        while (!fListener.isFinished()) if (!fDisplay.readAndDispatch ()) fDisplay.sleep ();
        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));
        while (!fListener.isFinished(MODEL_CHANGED_COMPLETE)) 
            if (!fDisplay.readAndDispatch ()) fDisplay.sleep ();

        // Update the viewer to collapse an element
        ModelDelta collapseDelta = model.makeElementDelta(model.findElement("3.1"), IModelDelta.COLLAPSE);
        
        // 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"));
        fListener.removeLabelUpdate(model.findElement("3.1.2"));
        fListener.removeLabelUpdate(model.findElement("3.1.3"));
        fListener.removeHasChildrenUpdate(model.findElement("3.1.1"));
        fListener.removeHasChildrenUpdate(model.findElement("3.1.2"));
        fListener.removeHasChildrenUpdate(model.findElement("3.1.3"));
        fListener.removeChildreCountUpdate(model.findElement("3.1"));
        fListener.removeChildrenUpdate(model.findElement("3.1"), 0);
        fListener.removeChildrenUpdate(model.findElement("3.1"), 1);
        fListener.removeChildrenUpdate(model.findElement("3.1"), 2);

        // Wait for the second model delta to process
        model.postDelta(collapseDelta);
        while (!fListener.isFinished(MODEL_CHANGED_COMPLETE)) 
            if (!fDisplay.readAndDispatch ()) fDisplay.sleep ();
        
        // Wait for all the updates to complete (note: we're not resetting the listener.
        model.postDelta(new ModelDelta(model.getRootElement(), IModelDelta.CONTENT));
        while (!fListener.isFinished(ALL_UPDATES_COMPLETE | STATE_RESTORE_COMPLETE)) 
            if (!fDisplay.readAndDispatch ()) fDisplay.sleep ();

        // Check to make sure that the state restore didn't change the selection.
        Assert.assertTrue(getCTargetViewer().getExpandedState(model.findElement("3.1")) == false);
    }

    public void testPreserveExpandDeltaAfterContent() {
        //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());
        while (!fListener.isFinished()) if (!fDisplay.readAndDispatch ()) fDisplay.sleep ();
        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));
        while (!fListener.isFinished(MODEL_CHANGED_COMPLETE)) 
            if (!fDisplay.readAndDispatch ()) fDisplay.sleep ();

        // Update the viewer to expand an element
        ModelDelta expandDelta = model.makeElementDelta(model.findElement("3.1"), IModelDelta.EXPAND);
        
        // Wait for the second model delta to process
        fListener.resetModelChanged();
        model.postDelta(expandDelta);
        while (!fListener.isFinished(MODEL_CHANGED_COMPLETE)) 
            if (!fDisplay.readAndDispatch ()) fDisplay.sleep ();
        
        // Wait for all the updates to complete (note: we're not resetting the listener.
        model.postDelta(new ModelDelta(model.getRootElement(), IModelDelta.CONTENT));
        while (!fListener.isFinished(ALL_UPDATES_COMPLETE | STATE_RESTORE_COMPLETE)) 
            if (!fDisplay.readAndDispatch ()) fDisplay.sleep ();

        // Check to make sure that the state restore didn't change the selection.
        Assert.assertTrue(getCTargetViewer().getExpandedState(model.findElement("3.1")) == true);
    }

    
    public void testSaveAndRstore1() {
        //TreeModelViewerAutopopulateAgent autopopulateAgent = new TreeModelViewerAutopopulateAgent(fViewer);
        TestModel model = alternatingSubsreesModel();

        // 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());
        while (!fListener.isFinished()) if (!fDisplay.readAndDispatch ()) fDisplay.sleep ();
        model.validateData(fViewer, TreePath.EMPTY, true);

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

        // Set a selection in view
        fViewer.setSelection(new TreeSelection(model.findElement("5.1.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(getCTargetViewer(), TreePath.EMPTY, model.getRootElement());
        fViewer.setInput(null);
        while (!fListener.isFinished(STATE_SAVE_COMPLETE)) if (!fDisplay.readAndDispatch ()) fDisplay.sleep ();
                
        // 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());
        while (!fListener.isFinished()) if (!fDisplay.readAndDispatch ()) fDisplay.sleep ();

        // 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)) {
            Assert.fail("Expected:\n" + originalState.toString() + "\nGot:\n" + restoredState);
        }
    }

    public void testSaveAndRstore2() {
        //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());
        while (!fListener.isFinished()) if (!fDisplay.readAndDispatch ()) fDisplay.sleep ();
        model.validateData(fViewer, TreePath.EMPTY);

        // Set a selection in view
        fViewer.setSelection(new TreeSelection(model.findElement("3.2.3")));
                
        // 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(getCTargetViewer(), TreePath.EMPTY, model.getRootElement());

        fViewer.setInput(null);
        while (!fListener.isFinished(STATE_SAVE_COMPLETE)) if (!fDisplay.readAndDispatch ()) fDisplay.sleep ();

        // 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());
        while (!fListener.isFinished()) if (!fDisplay.readAndDispatch ()) fDisplay.sleep ();

        // 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)) {
            Assert.fail("Expected:\n" + originalState.toString() + "\nGot:\n" + restoredState);
        }
    }

}
