[247859] Order of the validationStarting/Finishing(null) calls is still wrong
diff --git a/tests/org.eclipse.wst.common.tests.validation/plugin.xml b/tests/org.eclipse.wst.common.tests.validation/plugin.xml
index 2d36d48..9096f1c 100644
--- a/tests/org.eclipse.wst.common.tests.validation/plugin.xml
+++ b/tests/org.eclipse.wst.common.tests.validation/plugin.xml
@@ -386,6 +386,16 @@
       </validator>
    </extension>
    
+    <extension point="org.eclipse.wst.validation.validatorV2" id="T7A" name="T7A">
+      	<validator build="false" class="org.eclipse.wst.validation.tests.T7A">
+         <include>
+            <rules>
+               <fileext ext="t7a"></fileext>
+            </rules>
+         </include>
+      </validator>
+   </extension>
+   
  
  
 </plugin>
diff --git a/tests/org.eclipse.wst.common.tests.validation/src/org/eclipse/wst/validation/tests/testcase/TestEnvironment.java b/tests/org.eclipse.wst.common.tests.validation/src/org/eclipse/wst/validation/tests/testcase/TestEnvironment.java
index 24ab2df..bd0afe1 100644
--- a/tests/org.eclipse.wst.common.tests.validation/src/org/eclipse/wst/validation/tests/testcase/TestEnvironment.java
+++ b/tests/org.eclipse.wst.common.tests.validation/src/org/eclipse/wst/validation/tests/testcase/TestEnvironment.java
@@ -70,8 +70,8 @@
 	/**
 	 * Start a full build.
 	 */
-	public void fullBuild() throws CoreException{
-		getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
+	public void fullBuild2(IProgressMonitor monitor) throws CoreException{
+		getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, monitor);
 	}
 	
 	/**
@@ -79,12 +79,22 @@
 	 * @param monitor
 	 */
 	public void fullBuild(IProgressMonitor monitor) throws CoreException, InterruptedException {
-		fullBuild();
+		fullBuild2(monitor);
 		Thread.sleep(1000);
 		ValidationFramework.getDefault().join(monitor);
 		Thread.sleep(2000);  // we need to sleep here to give the "finished" job a chance to run.		
 	}
 	
+	/**
+	 * Do a clean build, and wait until all the validation has finished.
+	 * @param monitor
+	 */
+	public void cleanBuild(IProgressMonitor monitor) throws CoreException, InterruptedException {
+		getWorkspace().build(IncrementalProjectBuilder.CLEAN_BUILD, monitor);
+		Thread.sleep(1000);
+		ValidationFramework.getDefault().join(monitor);
+	}
+	
 	private IFolder createFolder(IPath path) throws CoreException {
 		if (path.segmentCount() <= 1)return null;
 		
diff --git a/tests/org.eclipse.wst.common.tests.validation/src/org/eclipse/wst/validation/tests/testcase/TestSuite1.java b/tests/org.eclipse.wst.common.tests.validation/src/org/eclipse/wst/validation/tests/testcase/TestSuite1.java
index 9a12c9d..85eaea4 100644
--- a/tests/org.eclipse.wst.common.tests.validation/src/org/eclipse/wst/validation/tests/testcase/TestSuite1.java
+++ b/tests/org.eclipse.wst.common.tests.validation/src/org/eclipse/wst/validation/tests/testcase/TestSuite1.java
@@ -272,7 +272,7 @@
 		t7.reset();
 		
 		long start = System.currentTimeMillis();
-		_env.fullBuild();
+		_env.fullBuild2(null);
 		Thread.sleep(1000);
 		vf.join(null);
 		long first = System.currentTimeMillis();
@@ -285,7 +285,7 @@
 		assertEquals("We expected the validation to be suspended after the first call", 1, t7.getSet().size());
 		
 		vf.suspendAllValidation(true);
-		_env.fullBuild();
+		_env.fullBuild2(null);
 		Thread.sleep(1000);
 		vf.join(null);
 		long second = System.currentTimeMillis();
diff --git a/tests/org.eclipse.wst.common.tests.validation/src/org/eclipse/wst/validation/tests/testcase/TestSuite2.java b/tests/org.eclipse.wst.common.tests.validation/src/org/eclipse/wst/validation/tests/testcase/TestSuite2.java
index 874f8c7..d994da5 100644
--- a/tests/org.eclipse.wst.common.tests.validation/src/org/eclipse/wst/validation/tests/testcase/TestSuite2.java
+++ b/tests/org.eclipse.wst.common.tests.validation/src/org/eclipse/wst/validation/tests/testcase/TestSuite2.java
@@ -105,8 +105,8 @@
 //		IWorkspace workspace = ResourcesPlugin.getWorkspace();
 		try {
 //			workspace.addResourceChangeListener(listener);
-			_env.fullBuild();
 			IProgressMonitor monitor = new NullProgressMonitor();
+			_env.fullBuild2(monitor);
 			
 			vf.join(monitor);
 			Thread.sleep(1000);
diff --git a/tests/org.eclipse.wst.common.tests.validation/src/org/eclipse/wst/validation/tests/testcase/TestSuite7.java b/tests/org.eclipse.wst.common.tests.validation/src/org/eclipse/wst/validation/tests/testcase/TestSuite7.java
new file mode 100644
index 0000000..1157090
--- /dev/null
+++ b/tests/org.eclipse.wst.common.tests.validation/src/org/eclipse/wst/validation/tests/testcase/TestSuite7.java
@@ -0,0 +1,95 @@
+package org.eclipse.wst.validation.tests.testcase;
+
+import java.io.UnsupportedEncodingException;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.wst.validation.internal.Tracing;
+import org.eclipse.wst.validation.tests.T7A;
+import org.eclipse.wst.validation.tests.T7A.ValEntryPoint;
+
+/** Test the order of validation events. */
+public class TestSuite7 extends TestCase {
+	
+	private TestEnvironment _env;
+	private IProject		_projectA;
+	private IProject		_projectB;
+	
+	public static Test suite() {
+		return new TestSuite(TestSuite7.class);
+	} 
+	
+	public TestSuite7(String name){
+		super(name);
+	}
+	
+
+	protected void setUp() throws Exception {
+		super.setUp();
+		TestEnvironment.enableOnlyThisValidator("org.eclipse.wst.validation.tests.T7A");
+		_env = new TestEnvironment();
+		_projectA = _env.createProject("TestSuite7a");
+		_projectB = _env.createProject("TestSuite7b");
+		makeFiles(_projectA);
+		makeFiles(_projectB);
+		
+	}
+	
+	private void makeFiles(IProject project) throws Exception{
+		IPath first = _env.addFolder(project.getFullPath(), "some-folder");
+		_env.addFile(first, "first.t7a",	"# a dummy file");		
+		_env.addFile(first, "second.t7a", "# a dummy file");
+		
+	}
+	
+	protected void tearDown() throws Exception {
+		_projectA.delete(true, null);
+		_projectB.delete(true, null);
+		_env.dispose();
+		super.tearDown();
+	}
+	
+	/**
+	 * Test the order of a clean build.
+	 */
+	public void testClean() throws CoreException, UnsupportedEncodingException, InterruptedException {
+		Tracing.log("TestSuite7-01: testClean starting");
+		IProgressMonitor monitor = new NullProgressMonitor();
+		_env.turnOnAutoBuild();
+		_env.cleanBuild(monitor);
+
+		T7A.resetList();
+		
+		_env.cleanBuild(monitor);
+		ValEntryPoint[] array = T7A.getArray();
+		int start = 0;
+		int finish = 0;
+		for (ValEntryPoint vep : array){
+			switch (vep.getType()){
+			case Starting:
+				if (start == 0)assertNull("First starting entry must be null", vep.getResource());
+				start++;
+				break;
+			case Finishing:
+				finish++;
+				break;		
+			case Normal:
+				assertEquals("All normal validation events must be two levels deep", 2, start-finish);
+			}
+		}
+		assertEquals("Starting must equal finishing", start, finish);
+		assertNull("Last entry must be null", array[array.length-1].getResource());
+		
+		Tracing.log("TestSuite7-02:testClean finished");
+	}
+	
+
+
+}
diff --git a/tests/org.eclipse.wst.common.tests.validation/src/org/eclipse/wst/validation/tests/testcase/ValidationTestSuite.java b/tests/org.eclipse.wst.common.tests.validation/src/org/eclipse/wst/validation/tests/testcase/ValidationTestSuite.java
index c1fa0ae..eff56fe 100644
--- a/tests/org.eclipse.wst.common.tests.validation/src/org/eclipse/wst/validation/tests/testcase/ValidationTestSuite.java
+++ b/tests/org.eclipse.wst.common.tests.validation/src/org/eclipse/wst/validation/tests/testcase/ValidationTestSuite.java
@@ -21,6 +21,7 @@
 		suite.addTest(TestSuite4.suite());
 		suite.addTest(TestSuite5.suite());
 		suite.addTest(TestSuite6.suite());
+		suite.addTest(TestSuite7.suite());
         return suite;
     }
 
diff --git a/tests/org.eclipse.wst.common.tests.validation/validators/org/eclipse/wst/validation/tests/T7A.java b/tests/org.eclipse.wst.common.tests.validation/validators/org/eclipse/wst/validation/tests/T7A.java
new file mode 100644
index 0000000..c8236c3
--- /dev/null
+++ b/tests/org.eclipse.wst.common.tests.validation/validators/org/eclipse/wst/validation/tests/T7A.java
@@ -0,0 +1,88 @@
+package org.eclipse.wst.validation.tests;
+
+import java.util.LinkedList;
+import java.util.List;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.wst.validation.AbstractValidator;
+import org.eclipse.wst.validation.ValidationResult;
+import org.eclipse.wst.validation.ValidationState;
+
+/**
+ * A validator that tests the order of the validate calls.
+ * @author karasiuk
+ *
+ */
+public final class T7A extends AbstractValidator {
+	
+	private static List<ValEntryPoint> _list = new LinkedList<ValEntryPoint>();
+	
+	public static void resetList(){
+		_list.clear();
+	}
+	
+	public static List<ValEntryPoint> getList(){
+		return _list;
+	}
+	
+	public static ValEntryPoint[] getArray(){
+		ValEntryPoint[] array = new ValEntryPoint[_list.size()];
+		_list.toArray(array);
+		return array;
+	}
+	
+	@Override
+	public void validationStarting(IProject project, ValidationState state,	IProgressMonitor monitor) {
+		_list.add(new ValEntryPoint(EntryType.Starting, project));
+	}
+	
+	@Override
+	public void validationFinishing(IProject project, ValidationState state, IProgressMonitor monitor) {
+		_list.add(new ValEntryPoint(EntryType.Finishing, project));
+	}
+	
+	@Override
+	public ValidationResult validate(IResource resource, int kind, ValidationState state, IProgressMonitor monitor) {
+		_list.add(new ValEntryPoint(EntryType.Normal, resource));
+		return null;
+	}
+	
+	@Override
+	public void clean(IProject project, ValidationState state, IProgressMonitor monitor) {
+		_list.add(new ValEntryPoint(EntryType.Clean, project));
+	}
+	
+	/**
+	 * An immutible object that records an entry into the validator.
+	 * @author karasiuk
+	 *
+	 */
+	public final static class ValEntryPoint {
+		private final EntryType 	_type;
+		private final IResource 	_resource;
+		
+		public ValEntryPoint(EntryType type, IResource resource){
+			_type = type;
+			_resource = resource;
+		}
+		
+		@Override
+		public String toString() {
+			String resource = _resource == null ? "null" : _resource.getName();
+			return "ValEntryPoint: " + _type + " " + resource;
+		}
+		
+		public EntryType getType() {
+			return _type;
+		}
+
+		public IResource getResource() {
+			return _resource;
+		}		
+	}
+	
+	public enum EntryType {Starting, Normal, Finishing, Clean}
+
+}