/*******************************************************************************
 * Copyright (c) 2000, 2015 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *     Alexander Kurtakov <akurtako@redhat.com> - Bug 459343
 *******************************************************************************/
package org.eclipse.core.tests.resources;

import java.util.*;
import org.eclipse.core.resources.*;
import org.eclipse.core.runtime.*;
import org.junit.Assert;

/**
 * Verifies the state of an <code>IResourceDelta</code> by comparing
 * it with a client's expectations.  The delta is considered valid
 * if it contains exactly the set of changes expected by the client,
 * and parents of those changes.
 *
 * <p>Example usage:
 * <code>
 * ResourceDeltaVerifier verifier = new ResourceDeltaComparer();
 * IResourceChangeListener listener = (IResourceChangeListener)verifier;
 * IWorkspace workspace = ResourcesPlugin.getWorkspace();
 * IProject proj = workspace.getRoot().getProject("MyProject");
 * // Assume the project is accessible
 * workspace.addResourceChangeListener(listener);
 * verifier.addExpectedChange(proj, REMOVED, 0);
 * try {
 * 		proj.delete(true, true, null);
 * } catch(CoreException e){
 *     fail("1.0", e);
 * }
 * assert("2.0 "+verifier.getMessage(), verifier.isDeltaValid());
 * </code>
 */
public class ResourceDeltaVerifier extends Assert implements IResourceChangeListener {
	private class ExpectedChange {
		IResource fResource;
		IPath movedFromPath;
		IPath movedToPath;
		int fKind;
		int fChangeFlags;

		public ExpectedChange(IResource resource, int kind, int changeFlags, IPath movedFromPath, IPath movedToPath) {
			fResource = resource;
			fKind = kind;
			fChangeFlags = changeFlags;
			this.movedFromPath = movedFromPath;
			this.movedToPath = movedToPath;
		}

		public int getChangeFlags() {
			return fChangeFlags;
		}

		public IPath getMovedFromPath() {
			if ((fChangeFlags & IResourceDelta.MOVED_FROM) != 0) {
				return movedFromPath;
			}
			return null;
		}

		public IPath getMovedToPath() {
			if ((fChangeFlags & IResourceDelta.MOVED_TO) != 0) {
				return movedToPath;
			}
			return null;
		}

		public int getKind() {
			return fKind;
		}

		@Override
		public String toString() {
			StringBuffer buf = new StringBuffer("ExpectedChange(");
			buf.append(fResource);
			buf.append(", ");
			buf.append(convertKind(fKind));
			buf.append(", ");
			buf.append(convertChangeFlags(fChangeFlags));
			buf.append(")");
			return buf.toString();
		}

	}

	/**
	 * Table of IPath -> ExpectedChange
	 */
	private Hashtable<IPath, ExpectedChange> fExpectedChanges = new Hashtable<>();
	boolean fIsDeltaValid = true;
	private StringBuffer fMessage = new StringBuffer();
	/**
	 * The verifier can be in one of three states.  In the initial
	 * state, the verifier is still receiving inputs via the
	 * addExpectedChange() methods, and the state is RECEIVING_INPUTS.
	 * After a call to verifyDelta(), the state becomes DELTA_VERIFIED
	 * The verifier remains in the second state for any number of delta
	 * verifications.  When a getMessage() or isDeltaValid() method is
	 * called, the verification completes, and the state becomes
	 * VERIFICATION_COMPLETE.  While in this state, any number of
	 * getMessage() and isDeltaValid() methods can be called.
	 * While in the third state, any call to addExpectedChange()
	 * resets the verifier and puts it back in its RECEIVING_INPUTS state.
	 */
	private static final int RECEIVING_INPUTS = 0;
	private static final int DELTA_VERIFIED = 1;
	private static final int VERIFICATION_COMPLETE = 2;

	private int fState = RECEIVING_INPUTS;

	/**
	 * @see #addExpectedChange
	 */
	public void addExpectedChange(IResource[] resources, int status, int changeFlags) {
		for (IResource resource : resources) {
			addExpectedChange(resource, null, status, changeFlags, null, null);
		}
	}

	/**
	 * Adds an expected deletion for the given resource and all children.
	 */
	public void addExpectedDeletion(IResource resource) {
		addExpectedChange(resource, IResourceDelta.REMOVED, 0);
		if (resource instanceof IContainer) {
			try {
				IResource[] children = ((IContainer) resource).members(IContainer.INCLUDE_PHANTOMS | IContainer.INCLUDE_TEAM_PRIVATE_MEMBERS | IContainer.INCLUDE_HIDDEN);
				for (IResource element : children) {
					addExpectedDeletion(element);
				}
			} catch (CoreException e) {
				e.printStackTrace();
				fail("Failed to get children in addExpectedDeletion");
			}
		}
	}

	/**
	 * Signals to the comparer that the given resource is expected to
	 * change in the specified way.  The change flags should be set to
	 * zero if no change is expected.
	 * @param resource the resource that is expected to change
	 * @param status the type of change (ADDED, REMOVED, CHANGED)
	 * @param changeFlags the type of change (CONTENT, SYNC, etc)
	 * @see IResourceConstants
	 */
	public void addExpectedChange(IResource resource, int status, int changeFlags) {
		addExpectedChange(resource, null, status, changeFlags, null, null);
	}

	/**
	 * Signals to the comparer that the given resource is expected to
	 * change in the specified way.  The change flags should be set to
	 * zero if no change is expected.
	 * @param resource the resource that is expected to change
	 * @param status the type of change (ADDED, REMOVED, CHANGED)
	 * @param changeFlags the type of change (CONTENT, SYNC, etc)
	 * @param movedPath or null
	 * @see IResourceConstants
	 */
	public void addExpectedChange(IResource resource, int status, int changeFlags, IPath movedFromPath, IPath movedToPath) {
		addExpectedChange(resource, null, status, changeFlags, movedFromPath, movedToPath);
	}

	/**
	 * Signals to the comparer that the given resource is expected to
	 * change in the specified way.  The change flags should be set to
	 * zero if no change is expected.
	 * @param resource the resource that is expected to change
	 * @param topLevelParent Do not added expected changes above this parent
	 * @param status the type of change (ADDED, REMOVED, CHANGED)
	 * @param changeFlags the type of change (CONTENT, SYNC, etc)
	 * @param movedPath or null
	 * @see IResourceConstants
	 */
	public void addExpectedChange(IResource resource, IResource topLevelParent, int status, int changeFlags) {
		addExpectedChange(resource, topLevelParent, status, changeFlags, null, null);
	}

	/**
	 * Signals to the comparer that the given resource is expected to
	 * change in the specified way.  The change flags should be set to
	 * zero if no change is expected.
	 * @param resource the resource that is expected to change
	 * @param topLevelParent Do not added expected changes above this parent
	 * @param status the type of change (ADDED, REMOVED, CHANGED)
	 * @param changeFlags the type of change (CONTENT, SYNC, etc)
	 * @param movedPath or null
	 * @see IResourceConstants
	 */
	public void addExpectedChange(IResource resource, IResource topLevelParent, int status, int changeFlags, IPath movedFromPath, IPath movedToPath) {
		resetIfNecessary();

		ExpectedChange expectedChange = new ExpectedChange(resource, status, changeFlags, movedFromPath, movedToPath);
		fExpectedChanges.put(resource.getFullPath(), expectedChange);

		// Add changes for all resources above this one and limited by the topLevelParent
		IResource parentResource = resource.getParent();
		IResource limit = (topLevelParent == null) ? null : topLevelParent.getParent();
		while (parentResource != null && !parentResource.equals(limit)) {
			//change table is keyed by resource path
			IPath key = parentResource.getFullPath();
			if (fExpectedChanges.get(key) == null) {
				ExpectedChange parentExpectedChange = new ExpectedChange(parentResource, IResourceDelta.CHANGED, 0, null, null);
				fExpectedChanges.put(key, parentExpectedChange);
			}
			parentResource = parentResource.getParent();
		}
	}

	private void checkChanges(IResourceDelta delta) {
		IResource resource = delta.getResource();

		ExpectedChange expectedChange = fExpectedChanges.remove(resource.getFullPath());

		int status = delta.getKind();
		int changeFlags = delta.getFlags();

		if (status == IResourceDelta.NO_CHANGE) {
			return;
		}

		if (expectedChange == null) {
			recordMissingExpectedChange(status, changeFlags);
		} else {
			int expectedStatus = expectedChange.getKind();
			int expectedChangeFlags = expectedChange.getChangeFlags();
			if (status != expectedStatus || changeFlags != expectedChangeFlags) {
				recordConflictingChange(expectedStatus, status, expectedChangeFlags, changeFlags);
			}
		}
	}

	private void checkChildren(IResourceDelta delta) {
		IResourceDelta[] affectedChildren = delta.getAffectedChildren(IResourceDelta.ALL_WITH_PHANTOMS, IContainer.INCLUDE_TEAM_PRIVATE_MEMBERS | IContainer.INCLUDE_HIDDEN);
		IResourceDelta[] addedChildren = delta.getAffectedChildren(IResourceDelta.ADDED, IContainer.INCLUDE_TEAM_PRIVATE_MEMBERS | IContainer.INCLUDE_HIDDEN);
		IResourceDelta[] changedChildren = delta.getAffectedChildren(IResourceDelta.CHANGED, IContainer.INCLUDE_TEAM_PRIVATE_MEMBERS | IContainer.INCLUDE_HIDDEN);
		IResourceDelta[] removedChildren = delta.getAffectedChildren(IResourceDelta.REMOVED, IContainer.INCLUDE_TEAM_PRIVATE_MEMBERS | IContainer.INCLUDE_HIDDEN);

		Hashtable<IResource, IResourceDelta> h = new Hashtable<>(affectedChildren.length + 1);

		for (IResourceDelta childDelta1 : addedChildren) {
			IResource childResource = childDelta1.getResource();
			IResourceDelta childDelta2 = h.get(childResource);
			if (childDelta2 != null) {
				recordDuplicateChild(childResource.getFullPath(), childDelta2.getKind(), childDelta1.getKind(), IResourceDelta.ADDED);
			} else {
				h.put(childResource, childDelta1);
			}
			if (childDelta1.getKind() != IResourceDelta.ADDED) {
				recordIllegalChild(childResource.getFullPath(), IResourceDelta.ADDED, childDelta1.getKind());
			}
		}

		for (IResourceDelta childDelta1 : changedChildren) {
			IResource childResource = childDelta1.getResource();
			IResourceDelta childDelta2 = h.get(childResource);
			if (childDelta2 != null) {
				recordDuplicateChild(childResource.getFullPath(), childDelta2.getKind(), childDelta1.getKind(), IResourceDelta.CHANGED);
			} else {
				h.put(childResource, childDelta1);
			}
			if (childDelta1.getKind() != IResourceDelta.CHANGED) {
				recordIllegalChild(childResource.getFullPath(), IResourceDelta.CHANGED, childDelta1.getKind());
			}
		}

		for (IResourceDelta childDelta1 : removedChildren) {
			IResource childResource = childDelta1.getResource();
			IResourceDelta childDelta2 = h.get(childResource);
			if (childDelta2 != null) {
				recordDuplicateChild(childResource.getFullPath(), childDelta2.getKind(), childDelta1.getKind(), IResourceDelta.REMOVED);
			} else {
				h.put(childResource, childDelta1);
			}
			if (childDelta1.getKind() != IResourceDelta.REMOVED) {
				recordIllegalChild(childResource.getFullPath(), IResourceDelta.REMOVED, childDelta1.getKind());
			}
		}

		for (IResourceDelta childDelta1 : affectedChildren) {
			IResource childResource = childDelta1.getResource();
			IResourceDelta childDelta2 = h.remove(childResource);
			if (childDelta2 == null) {
				int kind = childDelta1.getKind();
				//these kinds should have been added to h earlier
				if (kind == IResourceDelta.ADDED || kind == IResourceDelta.REMOVED || kind == IResourceDelta.CHANGED) {
					recordMissingChild(childResource.getFullPath(), childDelta1.getKind(), false);
				}
			}
		}

		for (Map.Entry<IResource, IResourceDelta> entry : h.entrySet()) {
			IResource childResource = entry.getKey();
			IResourceDelta childDelta = entry.getValue();
			recordMissingChild(childResource.getFullPath(), childDelta.getKind(), true);
		}

		for (IResourceDelta element : affectedChildren) {
			internalVerifyDelta(element);
		}

		for (IResourceDelta childDelta : h.values()) {
			internalVerifyDelta(childDelta);
		}
	}

	private void checkPaths(IResourceDelta delta) {
		IResource resource = delta.getResource();

		IPath expectedFullPath = resource.getFullPath();
		IPath actualFullPath = delta.getFullPath();
		if (!expectedFullPath.equals(actualFullPath)) {
			recordConflictingFullPaths(expectedFullPath, actualFullPath);
		}

		IPath expectedProjectRelativePath = resource.getProjectRelativePath();
		IPath actualProjectRelativePath = delta.getProjectRelativePath();
		if (expectedProjectRelativePath != actualProjectRelativePath) {
			if (expectedProjectRelativePath == null || !expectedProjectRelativePath.equals(actualProjectRelativePath)) {
				recordConflictingProjectRelativePaths(expectedProjectRelativePath, actualProjectRelativePath);
			}
		}

		ExpectedChange expectedChange = fExpectedChanges.get(resource.getFullPath());

		if (expectedChange != null) {
			IPath expectedMovedFromPath = expectedChange.getMovedFromPath();
			IPath actualMovedFromPath = delta.getMovedFromPath();
			if (expectedMovedFromPath != actualMovedFromPath) {
				if (expectedMovedFromPath == null || !expectedMovedFromPath.equals(actualMovedFromPath)) {
					recordConflictingMovedFromPaths(expectedMovedFromPath, actualMovedFromPath);
				}
			}

			IPath expectedMovedToPath = expectedChange.getMovedToPath();
			IPath actualMovedToPath = delta.getMovedToPath();
			if (expectedMovedToPath != actualMovedToPath) {
				if (expectedMovedToPath == null || !expectedMovedToPath.equals(actualMovedToPath)) {
					recordConflictingMovedToPaths(expectedMovedToPath, actualMovedToPath);
				}
			}
		}
	}

	String convertChangeFlags(int changeFlags) {
		if (changeFlags == 0) {
			return "0";
		}
		StringBuffer buf = new StringBuffer();

		if ((changeFlags & IResourceDelta.CONTENT) != 0) {
			changeFlags ^= IResourceDelta.CONTENT;
			buf.append("CONTENT | ");
		}
		if ((changeFlags & IResourceDelta.MOVED_FROM) != 0) {
			changeFlags ^= IResourceDelta.MOVED_FROM;
			buf.append("MOVED_FROM | ");
		}
		if ((changeFlags & IResourceDelta.MOVED_TO) != 0) {
			changeFlags ^= IResourceDelta.MOVED_TO;
			buf.append("MOVED_TO | ");
		}
		if ((changeFlags & IResourceDelta.OPEN) != 0) {
			changeFlags ^= IResourceDelta.OPEN;
			buf.append("OPEN | ");
		}
		if ((changeFlags & IResourceDelta.TYPE) != 0) {
			changeFlags ^= IResourceDelta.TYPE;
			buf.append("TYPE | ");
		}
		if ((changeFlags & IResourceDelta.MARKERS) != 0) {
			changeFlags ^= IResourceDelta.MARKERS;
			buf.append("MARKERS | ");
		}
		if ((changeFlags & IResourceDelta.REPLACED) != 0) {
			changeFlags ^= IResourceDelta.REPLACED;
			buf.append("REPLACED | ");
		}
		if ((changeFlags & IResourceDelta.ENCODING) != 0) {
			changeFlags ^= IResourceDelta.ENCODING;
			buf.append("ENCODING | ");
		}
		if ((changeFlags & IResourceDelta.DERIVED_CHANGED) != 0) {
			changeFlags ^= IResourceDelta.DERIVED_CHANGED;
			buf.append("DERIVED_CHANGED | ");
		}
		if ((changeFlags & IResourceDelta.DESCRIPTION) != 0) {
			changeFlags ^= IResourceDelta.DESCRIPTION;
			buf.append("DESCRIPTION | ");
		}
		if ((changeFlags & IResourceDelta.SYNC) != 0) {
			changeFlags ^= IResourceDelta.SYNC;
			buf.append("SYNC | ");
		}

		if (changeFlags != 0) {
			buf.append(changeFlags);
			buf.append(" | ");
		}

		String result = buf.toString();

		if (result.length() != 0) {
			result = result.substring(0, result.length() - 3);
		}

		return result;
	}

	String convertKind(int kind) {
		switch (kind) {
			case IResourceDelta.ADDED :
				return "ADDED";
			case IResourceDelta.CHANGED :
				return "CHANGED";
			case IResourceDelta.REMOVED :
				return "REMOVED";
			case IResourceDelta.ADDED_PHANTOM :
				return "ADDED_PHANTOM";
			case IResourceDelta.REMOVED_PHANTOM :
				return "REMOVED_PHANTOM";
			default :
				return "Unknown(" + kind + ")";
		}
	}

	/**
	 * Called to cleanup internal state and make sure expectations
	 * are met after iterating over a resource delta.
	 */
	private void finishVerification() {
		HashSet<IPath> resourcePaths = new HashSet<>(fExpectedChanges.keySet());

		for (IPath resourcePath : resourcePaths) {
			fMessage.append("Checking expectations for ");
			fMessage.append(resourcePath);
			fMessage.append("\n");

			ExpectedChange expectedChange = fExpectedChanges.remove(resourcePath);
			if (expectedChange != null) {
				recordMissingActualChange(expectedChange.getKind(), expectedChange.getChangeFlags());
			}
		}
	}

	/**
	 * Returns a message that describes the result of the resource
	 * delta verification checks.
	 */
	public String getMessage() {
		if (fState == RECEIVING_INPUTS) {
			if (hasExpectedChanges()) {
				fail("Verifier has not yet been given a resource delta");
			} else {
				fState = DELTA_VERIFIED;
			}
		}
		if (fState == DELTA_VERIFIED) {
			finishVerification();
			fState = VERIFICATION_COMPLETE;
		}
		return fMessage.toString();
	}

	/**
	 * Returns true if this verifier has received a delta notification
	 * since the last reset, and false otherwise.
	 */
	public boolean hasBeenNotified() {
		return fState == DELTA_VERIFIED;
	}

	/**
	 * Returns true if this verifier currently has an expected
	 * changes, and false otherwise.
	 */
	public boolean hasExpectedChanges() {
		return !fExpectedChanges.isEmpty();
	}

	/**
	 * Compares the given delta with the expected changes.  Recursively
	 * compares child deltas.
	 */
	void internalVerifyDelta(IResourceDelta delta) {
		try {
			// FIXME: bogus
			if (delta == null) {
				return;
			}
			fMessage.append("Verifying delta for ");
			fMessage.append(delta.getFullPath());
			fMessage.append("\n");

			/* don't check changes for the workspace */
			if (delta.getResource() != null) {
				checkPaths(delta);
				checkChanges(delta);
			}
			checkChildren(delta);
		} catch (Exception e) {
			e.printStackTrace();
			fMessage.append("Exception during event notification:" + e.getMessage());
			fIsDeltaValid = false;
		}
	}

	/**
	 * Returns whether the resource delta passed all verification
	 * checks.
	 */
	public boolean isDeltaValid() {
		if (fState == RECEIVING_INPUTS) {
			if (hasExpectedChanges()) {
				fail("Verifier has not yet been given a resource delta");
			} else {
				fState = DELTA_VERIFIED;
			}
		}
		if (fState == DELTA_VERIFIED) {
			finishVerification();
			fState = VERIFICATION_COMPLETE;
		}
		return fIsDeltaValid;
	}

	/**
	 * Tests message formatting.  This main method does not represent the
	 * intended use of the ResourceDeltaVerifier.  See the class comment
	 * for instructions on using the verifier.
	 */
	public static void main(String[] args) {
		ResourceDeltaVerifier comparer = new ResourceDeltaVerifier();

		int status = IResourceDelta.CHANGED;
		int changeFlags = IResourceDelta.CONTENT;
		int expectedStatus = IResourceDelta.CHANGED;
		int actualStatus = IResourceDelta.REMOVED;
		int expectedChangeFlags = IResourceDelta.OPEN;
		int actualChangeFlags = 0;
		int formerChildStatus = expectedStatus;
		int latterChildStatus = actualStatus;

		IPath path = new Path("/a/b/c");
		IPath path2 = new Path("/a/b/d");
		IPath expectedFullPath = path;
		IPath actualFullPath = path2;
		IPath expectedMovedFromPath = path;
		IPath actualMovedFromPath = path2;
		IPath expectedMovedToPath = path;
		IPath actualMovedToPath = path2;
		IPath expectedProjectRelativePath = new Path("b/c");
		IPath actualProjectRelativePath = new Path("b/d");

		comparer.fMessage.append("Checking delta for ");
		comparer.fMessage.append(path);
		comparer.fMessage.append("\n");

		comparer.recordConflictingChange(expectedStatus, actualStatus, expectedChangeFlags, actualChangeFlags);
		comparer.recordConflictingFullPaths(expectedFullPath, actualFullPath);
		comparer.recordConflictingMovedFromPaths(expectedMovedFromPath, actualMovedFromPath);
		comparer.recordConflictingMovedToPaths(expectedMovedToPath, actualMovedToPath);
		comparer.recordConflictingProjectRelativePaths(expectedProjectRelativePath, actualProjectRelativePath);
		comparer.recordDuplicateChild(path, formerChildStatus, latterChildStatus, expectedStatus);
		comparer.recordIllegalChild(path, expectedStatus, actualStatus);
		comparer.recordMissingActualChange(status, changeFlags);
		comparer.recordMissingChild(path, status, true);
		comparer.recordMissingChild(path, status, false);
		comparer.recordMissingExpectedChange(status, changeFlags);

		System.out.print(comparer.fMessage.toString());
	}

	private void recordConflictingChange(int expectedKind, int kind, int expectedChangeFlags, int changeFlags) {
		fIsDeltaValid = false;

		fMessage.append("\tConflicting change\n");

		if (expectedKind != kind) {
			fMessage.append("\t\tExpected kind: <");
			fMessage.append(convertKind(expectedKind));
			fMessage.append("> actual kind: <");
			fMessage.append(convertKind(kind));
			fMessage.append(">\n");
		}

		if (expectedChangeFlags != changeFlags) {
			fMessage.append("\t\tExpected change flags: <");
			fMessage.append(convertChangeFlags(expectedChangeFlags));
			fMessage.append("> actual change flags: <");
			fMessage.append(convertChangeFlags(changeFlags));
			fMessage.append(">\n");
		}
	}

	private void recordConflictingFullPaths(IPath expectedFullPath, IPath actualFullPath) {
		fIsDeltaValid = false;

		fMessage.append("\tConflicting full paths\n");

		fMessage.append("\t\tExpected full path: ");
		fMessage.append(expectedFullPath);
		fMessage.append("\n");

		fMessage.append("\t\tActual full path: ");
		fMessage.append(actualFullPath);
		fMessage.append("\n");
	}

	private void recordConflictingMovedFromPaths(IPath expectedMovedFromPath, IPath actualMovedFromPath) {
		fIsDeltaValid = false;

		fMessage.append("\tConflicting moved from paths\n");

		fMessage.append("\t\tExpected moved from path: ");
		fMessage.append(expectedMovedFromPath);
		fMessage.append("\n");

		fMessage.append("\t\tActual moved from path: ");
		fMessage.append(actualMovedFromPath);
		fMessage.append("\n");
	}

	private void recordConflictingMovedToPaths(IPath expectedMovedToPath, IPath actualMovedToPath) {
		fIsDeltaValid = false;

		fMessage.append("\tConflicting moved to paths\n");

		fMessage.append("\t\tExpected moved to path: ");
		fMessage.append(expectedMovedToPath);
		fMessage.append("\n");

		fMessage.append("\t\tActual moved to path: ");
		fMessage.append(actualMovedToPath);
		fMessage.append("\n");
	}

	private void recordConflictingProjectRelativePaths(IPath expectedProjectRelativePath, IPath actualProjectRelativePath) {
		fIsDeltaValid = false;

		fMessage.append("\tConflicting project relative paths\n");

		fMessage.append("\t\tExpected project relative path: ");
		fMessage.append(expectedProjectRelativePath);
		fMessage.append("\n");

		fMessage.append("\t\tActual project relative path: ");
		fMessage.append(actualProjectRelativePath);
		fMessage.append("\n");
	}

	private void recordDuplicateChild(IPath path, int formerChildKind, int latterChildKind, int expectedKind) {
		fIsDeltaValid = false;

		fMessage.append("\tDuplicate child: ");
		fMessage.append(path);
		fMessage.append("\n");

		fMessage.append("\t\tProduced by IResourceDelta.get");

		switch (expectedKind) {
			case IResourceDelta.ADDED :
				fMessage.append("Added");
				break;
			case IResourceDelta.CHANGED :
				fMessage.append("Changed");
				break;
			case IResourceDelta.REMOVED :
				fMessage.append("Removed");
				break;
		}

		fMessage.append("Children()\n");

		fMessage.append("\t\tFormer child's status: ");
		fMessage.append(convertKind(formerChildKind));
		fMessage.append("\n");

		fMessage.append("\t\tLatter child's status: ");
		fMessage.append(convertKind(latterChildKind));
		fMessage.append("\n");
	}

	private void recordIllegalChild(IPath path, int expectedKind, int actualKind) {
		fIsDeltaValid = false;

		fMessage.append("\tIllegal child: ");
		fMessage.append(path);
		fMessage.append("\n");

		fMessage.append("\t\tProduced by IResourceDelta.get");

		switch (expectedKind) {
			case IResourceDelta.ADDED :
				fMessage.append("Added");
				break;
			case IResourceDelta.CHANGED :
				fMessage.append("Changed");
				break;
			case IResourceDelta.REMOVED :
				fMessage.append("Removed");
				break;
		}

		fMessage.append("Children()\n");

		fMessage.append("\t\tIlleagal child's status: ");
		fMessage.append(convertKind(actualKind));
		fMessage.append("\n");
	}

	private void recordMissingActualChange(int kind, int changeFlags) {
		fIsDeltaValid = false;

		fMessage.append("\tMissing actual change\n");
		fMessage.append("\t\tExpected kind: <");
		fMessage.append(convertKind(kind));
		fMessage.append(">\n");
		fMessage.append("\t\tExpected change flags: <");
		fMessage.append(convertChangeFlags(changeFlags));
		fMessage.append(">\n");
	}

	private void recordMissingChild(IPath path, int kind, boolean isMissingFromAffectedChildren) {
		fIsDeltaValid = false;

		fMessage.append("\tMissing child: ");
		fMessage.append(path);
		fMessage.append("\n");

		fMessage.append("\t\tfrom IResourceDelta.getAffectedChildren(");

		if (!isMissingFromAffectedChildren) {
			switch (kind) {
				case IResourceDelta.ADDED :
					fMessage.append("ADDED");
					break;
				case IResourceDelta.CHANGED :
					fMessage.append("CHANGED");
					break;
				case IResourceDelta.REMOVED :
					fMessage.append("REMOVED");
					break;
				default :
					fMessage.append(kind);
			}
		}

		fMessage.append(")\n");
	}

	private void recordMissingExpectedChange(int kind, int changeFlags) {
		fIsDeltaValid = false;

		fMessage.append("\tMissing expected change\n");
		fMessage.append("\t\tActual kind: <");
		fMessage.append(convertKind(kind));
		fMessage.append(">\n");
		fMessage.append("\t\tActual change flags: <");
		fMessage.append(convertChangeFlags(changeFlags));
		fMessage.append(">\n");
	}

	/**
	 * Resets the listener to its initial state.
	 */
	public void reset() {
		fExpectedChanges.clear();
		fIsDeltaValid = true;
		fMessage.setLength(0);
		fState = RECEIVING_INPUTS;
	}

	private void resetIfNecessary() {
		if (fState == DELTA_VERIFIED) {
			reset();
		}
	}

	/**
	 * Part of the <code>IResourceChangedListener</code> interface.
	 * @see IResourceChangedListener
	 */
	@Override
	public void resourceChanged(IResourceChangeEvent e) {
		verifyDelta(e.getDelta());
	}

	/**
	 * Compares the given delta with the expected changes.  Recursively
	 * compares child deltas.
	 */
	public void verifyDelta(IResourceDelta delta) {
		internalVerifyDelta(delta);
		fState = DELTA_VERIFIED;
	}
}
