[216765] protect validation from junit env
diff --git a/plugins/org.eclipse.wst.validation/validate/org/eclipse/wst/validation/internal/plugin/ValidationPlugin.java b/plugins/org.eclipse.wst.validation/validate/org/eclipse/wst/validation/internal/plugin/ValidationPlugin.java
index 8a5f348..b8b01dc 100644
--- a/plugins/org.eclipse.wst.validation/validate/org/eclipse/wst/validation/internal/plugin/ValidationPlugin.java
+++ b/plugins/org.eclipse.wst.validation/validate/org/eclipse/wst/validation/internal/plugin/ValidationPlugin.java
@@ -20,6 +20,9 @@
 import org.eclipse.wst.validation.ValidationFramework;
 import org.eclipse.wst.validation.internal.DependencyIndex;
 import org.eclipse.wst.validation.internal.EventManager;
+import org.eclipse.wst.validation.internal.Misc;
+import org.eclipse.wst.validation.internal.ProjectUnavailableError;
+import org.eclipse.wst.validation.internal.ResourceUnavailableError;
 import org.eclipse.wst.validation.internal.ValOperationManager;
 import org.eclipse.wst.validation.internal.core.Message;
 import org.eclipse.wst.validation.internal.provisional.core.IMessage;
@@ -134,6 +137,14 @@
 		getLog().log(status);
 	}
 	
+	public void handleProjectUnavailableError(ProjectUnavailableError e){
+		if (Misc.isLogging())handleException(e);
+	}
+	
+	public void handleResourceUnavailableError(ResourceUnavailableError e){
+		if (Misc.isLogging())handleException(e);
+	}
+	
 	/** 
 	 * Write a message into the log. 
 	 * 
diff --git a/plugins/org.eclipse.wst.validation/vf2/org/eclipse/wst/validation/Validator.java b/plugins/org.eclipse.wst.validation/vf2/org/eclipse/wst/validation/Validator.java
index 4ae6930..1dad260 100644
--- a/plugins/org.eclipse.wst.validation/vf2/org/eclipse/wst/validation/Validator.java
+++ b/plugins/org.eclipse.wst.validation/vf2/org/eclipse/wst/validation/Validator.java
@@ -9,6 +9,7 @@
 import org.eclipse.core.runtime.CoreException;
 import org.eclipse.core.runtime.IAdaptable;
 import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.NullProgressMonitor;
 import org.eclipse.core.runtime.Platform;
 import org.eclipse.wst.validation.internal.SummaryReporter;
 import org.eclipse.wst.validation.internal.ValOperation;
@@ -139,8 +140,8 @@
 	 * 
 	 * @param resource the resource to be validated
 	 * @param kind the kind of resource change, see IResourceDelta for values.
-	 * @param operation the operation that this validation is running under.
-	 * @param monitor a way to report progress 
+	 * @param operation the operation that this validation is running under. This can be null.
+	 * @param monitor a way to report progress. This can be null.
 	 * 
 	 * @return the result of doing the validation, it can be, but usually isn't null.
 	 */
@@ -338,6 +339,8 @@
 	public ValidationResult validate(IResource resource, int kind, ValOperation operation, 
 		IProgressMonitor monitor) {
 		
+		if (monitor == null)monitor = new NullProgressMonitor();
+		
 		ValidationResult vr = new ValidationResult();
 		IValidator v = null;
 		try {
@@ -361,11 +364,6 @@
 				wc.setValidationFileURIs(files);
 			}
 			ValidatorLauncher.getLauncher().start(helper, v, reporter);
-//			if (v instanceof IValidatorJob) {
-//				IValidatorJob vj = (IValidatorJob) v;
-//				vj.validateInJob(helper, reporter);
-//			}
-//			else v.validate(helper, reporter);
 			
 			vr.incrementError(reporter.getSeverityHigh());
 			vr.incrementWarning(reporter.getSeverityNormal());
@@ -540,19 +538,12 @@
 	public void setName(String name) {
 		_name = name;
 	}
-
-	/**
-	 * Validate the resource.
-	 * 
-	 * @param resource the resource to be validated
-	 * @param kind the kind of resource change, see IResourceDelta for values.
-	 * @param operation the operation that this validation is running under.
-	 * @param monitor a way to report progress 
-	 * 
-	 * @return the result of doing the validation, it can be, but usually isn't null.
-	 */
+	
+	@Override
 	public ValidationResult validate(IResource resource, int kind, ValOperation operation, IProgressMonitor monitor) {
 		ValidationResult vr = null;
+		if (operation == null)operation = new ValOperation();
+		if (monitor == null)monitor = new NullProgressMonitor();
 		try {
 			vr = getDelegatedValidator().validate(resource, kind, operation.getState(), monitor);
 		}
diff --git a/plugins/org.eclipse.wst.validation/vf2/org/eclipse/wst/validation/internal/ProjectUnavailableError.java b/plugins/org.eclipse.wst.validation/vf2/org/eclipse/wst/validation/internal/ProjectUnavailableError.java
new file mode 100644
index 0000000..e163c91
--- /dev/null
+++ b/plugins/org.eclipse.wst.validation/vf2/org/eclipse/wst/validation/internal/ProjectUnavailableError.java
@@ -0,0 +1,31 @@
+package org.eclipse.wst.validation.internal;
+
+import org.eclipse.core.resources.IProject;
+
+/**
+ * This internal error is used to signal that a project is now unavailable.
+ * <p>
+ * We could be in the middle of validating a large project, and the project could be closed. 
+ * This error is used to "exit" the validation framework.
+ * <p>
+ * This is an error rather than a runtime exception, because some parts of Eclipse like to
+ * trap RuntimeExceptions and log them.
+ * @author karasiuk
+ *
+ */
+public class ProjectUnavailableError extends Error {
+	
+	private IProject _project;
+
+	private static final long serialVersionUID = 200801281118L;
+	
+	public ProjectUnavailableError(IProject project){
+		super();
+		_project = project;
+	}
+
+	public IProject getProject() {
+		return _project;
+	}
+
+}
diff --git a/plugins/org.eclipse.wst.validation/vf2/org/eclipse/wst/validation/internal/ResourceUnavailableError.java b/plugins/org.eclipse.wst.validation/vf2/org/eclipse/wst/validation/internal/ResourceUnavailableError.java
new file mode 100644
index 0000000..89ae6c1
--- /dev/null
+++ b/plugins/org.eclipse.wst.validation/vf2/org/eclipse/wst/validation/internal/ResourceUnavailableError.java
@@ -0,0 +1,30 @@
+package org.eclipse.wst.validation.internal;
+
+import org.eclipse.core.resources.IResource;
+
+/**
+ * This internal error is used to signal that a resource is now unavailable.
+ * <p>
+ * This error is used to "exit" the validation framework. 
+ * <p>
+ * This is an error rather than a runtime exception, because some parts of Eclipse like to
+ * trap RuntimeExceptions and log them.
+ * @author karasiuk
+ *
+ */
+public class ResourceUnavailableError extends Error {
+
+	private static final long serialVersionUID = 200801290853L;
+	
+	private IResource _resource;
+	
+	public ResourceUnavailableError(IResource resource){
+		super();
+		_resource = resource;
+	}
+
+	public IResource getResource() {
+		return _resource;
+	}
+
+}
diff --git a/plugins/org.eclipse.wst.validation/vf2/org/eclipse/wst/validation/internal/ValBuilderJob.java b/plugins/org.eclipse.wst.validation/vf2/org/eclipse/wst/validation/internal/ValBuilderJob.java
index 7a12eba..13226c7 100644
--- a/plugins/org.eclipse.wst.validation/vf2/org/eclipse/wst/validation/internal/ValBuilderJob.java
+++ b/plugins/org.eclipse.wst.validation/vf2/org/eclipse/wst/validation/internal/ValBuilderJob.java
@@ -91,6 +91,12 @@
 			else deltaBuild();
 			
 		}
+		catch (ProjectUnavailableError e){
+			ValidationPlugin.getPlugin().handleProjectUnavailableError(e);
+		}
+		catch (ResourceUnavailableError e){
+			ValidationPlugin.getPlugin().handleResourceUnavailableError(e);
+		}
 		catch (CoreException e){
 			ValidationPlugin.getPlugin().handleException(e);
 		}
diff --git a/plugins/org.eclipse.wst.validation/vf2/org/eclipse/wst/validation/internal/ValManager.java b/plugins/org.eclipse.wst.validation/vf2/org/eclipse/wst/validation/internal/ValManager.java
index def245c..72c0ae2 100644
--- a/plugins/org.eclipse.wst.validation/vf2/org/eclipse/wst/validation/internal/ValManager.java
+++ b/plugins/org.eclipse.wst.validation/vf2/org/eclipse/wst/validation/internal/ValManager.java
@@ -65,7 +65,7 @@
 	 * @return Answer an empty array if there are no validators.
 	 */
 	public Validator[] getValidators(){
-		return getValidators(false, null);
+		return getValidators(false);
 	}
 	
 	/**
@@ -81,7 +81,7 @@
 	 * @param project this may be null, in which case the global preferences are used.
 	 * @return
 	 */
-	public Validator[] getValidators(IProject project){
+	public Validator[] getValidators(IProject project) throws ProjectUnavailableError {
 		if (project == null)return getValidators();
 		if (!getGlobalPreferences().getOverride())return getValidators(false, project);
 		
@@ -133,6 +133,17 @@
 		}
 		return false;
 	}
+	
+	Validator[] getValidators(boolean forceDefaults){
+		Validator[] vals = null;
+		try {
+			vals = getValidators(forceDefaults, null);
+		}
+		catch (ProjectUnavailableError e){
+			// can't happen since the project is null
+		}
+		return vals;
+	}
 		
 	/**
 	 * Answer all the registered validators.
@@ -145,7 +156,7 @@
 	 * 
 	 * @return Answer an empty array if there are no validators.
 	 */
-	Validator[] getValidators(boolean forceDefaults, IProject project){
+	Validator[] getValidators(boolean forceDefaults, IProject project) throws ProjectUnavailableError {
 		// If I use a local variable I don't need to synchronize the method.
 		Validator[] validators = _validators;
 		if (!forceDefaults && project == null && validators != null)return validators;
@@ -187,6 +198,7 @@
 			}
 		}
 		catch (InvocationTargetException e){
+			if (!project.exists() || !project.isOpen())throw new ProjectUnavailableError(project);
 			ValidationPlugin.getPlugin().handleException(e);
 		}
 		
@@ -261,7 +273,7 @@
 	public synchronized void restoreDefaults() {
 		getGlobalPreferences().resetToDefault();
 		_validators = null;
-		getValidators(true, null);
+		getValidators(true);
 	}
 	
 
@@ -387,6 +399,9 @@
 			resource.deleteMarkers(ValConstants.ProblemMarker, false, IResource.DEPTH_ZERO);
 		}
 		catch (CoreException e){
+			IProject project = resource.getProject();
+			if (!project.exists() || !project.isOpen())throw new ProjectUnavailableError(project);
+			if (!resource.exists())throw new ResourceUnavailableError(resource);
 			ValidationPlugin.getPlugin().handleException(e);
 		}