[217755] as-you-type validation
diff --git a/plugins/org.eclipse.wst.validation/.options b/plugins/org.eclipse.wst.validation/.options
index 26da761..3d7608c 100644
--- a/plugins/org.eclipse.wst.validation/.options
+++ b/plugins/org.eclipse.wst.validation/.options
@@ -3,7 +3,9 @@
 # Set this to true if you wish performance information to be logged
 org.eclipse.wst.validation/timings=false
 
-# set this to a file name, if you wish the results to be logged to a file, otherwise
-# they will be written to stderr
-org.eclipse.wst.validation/timings/tracefile=
+# Set this to a file name, if you wish the results to be logged to a file, otherwise
+# they will be written to stderr. When logged to a file the results are in a
+# CSV (comma separated values) form. When logged to stderr they are in a more 
+# human readable form.
+# org.eclipse.wst.validation/timings/tracefile=
 
diff --git a/plugins/org.eclipse.wst.validation/build.properties b/plugins/org.eclipse.wst.validation/build.properties
index bb28623..7d09fdd 100644
--- a/plugins/org.eclipse.wst.validation/build.properties
+++ b/plugins/org.eclipse.wst.validation/build.properties
@@ -12,7 +12,8 @@
                plugin.properties,\
                META-INF/,\
                about.html,\
-               .
+               .,\
+               .options
 jars.compile.order = .
 src.includes = component.xml,\
                xsds/
diff --git a/plugins/org.eclipse.wst.validation/validate/org/eclipse/wst/validation/internal/ConfigurationManager.java b/plugins/org.eclipse.wst.validation/validate/org/eclipse/wst/validation/internal/ConfigurationManager.java
index a5cfdbe..1f83c54 100644
--- a/plugins/org.eclipse.wst.validation/validate/org/eclipse/wst/validation/internal/ConfigurationManager.java
+++ b/plugins/org.eclipse.wst.validation/validate/org/eclipse/wst/validation/internal/ConfigurationManager.java
@@ -258,4 +258,17 @@
 		return false;
 	}
 
+	/**
+	 * Answer the appropriate configuration based on whether the project has overridden the configuration
+	 * or not. If the project exists and is allowed to override the global configuration answer the
+	 * project configuration, otherwise answer the global configuration.
+	 * @param project it can be null
+	 */
+	public ValidationConfiguration getConfiguration(IProject project) throws InvocationTargetException {
+		if (project == null)return getGlobalConfiguration();
+		ProjectConfiguration pc = getProjectConfiguration(project);
+		if (pc != null && !pc.useGlobalPreference())return pc;
+		return getGlobalConfiguration();
+	}
+
 }
diff --git a/plugins/org.eclipse.wst.validation/validate/org/eclipse/wst/validation/internal/ValidatorMetaData.java b/plugins/org.eclipse.wst.validation/validate/org/eclipse/wst/validation/internal/ValidatorMetaData.java
index 922c308..c8cc483 100644
--- a/plugins/org.eclipse.wst.validation/validate/org/eclipse/wst/validation/internal/ValidatorMetaData.java
+++ b/plugins/org.eclipse.wst.validation/validate/org/eclipse/wst/validation/internal/ValidatorMetaData.java
@@ -298,8 +298,7 @@
 	public boolean isApplicableTo(IResource resource, int resourceDelta) {
 		// If no filters are specified, then every type of resource should be validated/trigger a
 		// rebuild of the model cache
-		if (_filters == null)
-			return true;
+		if (_filters == null)return true;
 
 		return isApplicableTo(resource, resourceDelta, _filters);
 	}
@@ -307,8 +306,7 @@
 	/**
 	 * Return true if the resource passes the name/type filters for this validator.
 	 */
-	boolean isApplicableTo(IResource resource, int resourceDelta,
-			ValidatorFilter[] filters) {
+	boolean isApplicableTo(IResource resource, int resourceDelta, ValidatorFilter[] filters) {
 		// Are any of the filters satisfied? (i.e., OR them, not AND them.)
 		if (checkIfValidSourceFile(resource)) {
 			for (int i = 0; i < filters.length; i++) {
diff --git a/plugins/org.eclipse.wst.validation/validate/org/eclipse/wst/validation/internal/delegates/DelegatingValidator.java b/plugins/org.eclipse.wst.validation/validate/org/eclipse/wst/validation/internal/delegates/DelegatingValidator.java
index b474282..9375574 100644
--- a/plugins/org.eclipse.wst.validation/validate/org/eclipse/wst/validation/internal/delegates/DelegatingValidator.java
+++ b/plugins/org.eclipse.wst.validation/validate/org/eclipse/wst/validation/internal/delegates/DelegatingValidator.java
@@ -80,7 +80,7 @@
    */
   public void validate(IValidationContext helper, IReporter reporter) throws ValidationException
   {
-    // Apparently this method will not be called on an IValidatorJob.
+    validateInJob(helper, reporter);
   }
 
   /**
diff --git a/plugins/org.eclipse.wst.validation/validate/org/eclipse/wst/validation/internal/operations/ValidationOperation.java b/plugins/org.eclipse.wst.validation/validate/org/eclipse/wst/validation/internal/operations/ValidationOperation.java
index 4801cfa..0366434 100644
--- a/plugins/org.eclipse.wst.validation/validate/org/eclipse/wst/validation/internal/operations/ValidationOperation.java
+++ b/plugins/org.eclipse.wst.validation/validate/org/eclipse/wst/validation/internal/operations/ValidationOperation.java
@@ -594,7 +594,6 @@
 	 * The IProgressMonitor passed in must not be null.
 	 */
 	public void run(IProgressMonitor progressMonitor) throws OperationCanceledException {
-		long start = System.currentTimeMillis();
 		try {
 			// In order to check whether or not the monitor has been cancelled,
 			// the monitor must not be null.
@@ -1149,7 +1148,6 @@
 				// which the validator should validate.
 				((WorkbenchContext) helper).setRuleGroup(getRuleGroup());
 			}
-			long start = System.currentTimeMillis();
 			String message = ResourceHandler.getExternalizedMessage(ResourceConstants.VBF_STATUS_STARTING_VALIDATION, new String[]{getProject().getName(), vmd.getValidatorDisplayName()});
 			reporter.displaySubtask(message);
 			if (Misc.isLogging()) {
@@ -1158,7 +1156,6 @@
 			}
 			//initValidateContext(delta);
 			ValidatorLauncher.getLauncher().start(helper, validator, reporter);
-			long finish = System.currentTimeMillis();
 			//TODO GRK determine if timing info should be added here
 //			if (logger.isLoggingLevel(Level.INFO)) {
 //				TimeEntry entry = ValidationPlugin.getTimeEntry();
diff --git a/plugins/org.eclipse.wst.validation/vf2/org/eclipse/wst/validation/ReporterHelper.java b/plugins/org.eclipse.wst.validation/vf2/org/eclipse/wst/validation/ReporterHelper.java
index bf99db5..5ddaf17 100644
--- a/plugins/org.eclipse.wst.validation/vf2/org/eclipse/wst/validation/ReporterHelper.java
+++ b/plugins/org.eclipse.wst.validation/vf2/org/eclipse/wst/validation/ReporterHelper.java
@@ -80,38 +80,4 @@
 			}
 		}
 	}
-	
-	/**
-	 * Copy the messages from the reporter into validation result.
-	 */
-	public void updateResult(ValidationResult result){
-		for (IMessage message : _list){
-			Object target = message.getTargetObject();
-			if (target != null){
-				if (target instanceof IResource){
-					IResource res = (IResource)target;
-					ValidatorMessage vm = ValidatorMessage.create(message.getText(), res);
-					result.add(vm);
-					int markerSeverity = IMarker.SEVERITY_INFO;
-					int sev = message.getSeverity();
-					if ((sev & IMessage.HIGH_SEVERITY) != 0)markerSeverity = IMarker.SEVERITY_ERROR;
-					else if ((sev & IMessage.NORMAL_SEVERITY) != 0)markerSeverity = IMarker.SEVERITY_WARNING;
-					vm.setAttribute(IMarker.SEVERITY, markerSeverity);
-					vm.setAttribute(IMarker.LINE_NUMBER, message.getLineNumber());
-					int offset = message.getOffset();
-					if (offset != IMessage.OFFSET_UNSET){
-						vm.setAttribute(IMarker.CHAR_START, offset);
-						int len = message.getLength();
-						if (len != IMessage.OFFSET_UNSET){
-							vm.setAttribute(IMarker.CHAR_START, offset);
-							vm.setAttribute(IMarker.CHAR_END, offset+len);
-						}
-					}
-					
-				}
-			}
-		}
-		
-	}
-
 }
diff --git a/plugins/org.eclipse.wst.validation/vf2/org/eclipse/wst/validation/ValidationFramework.java b/plugins/org.eclipse.wst.validation/vf2/org/eclipse/wst/validation/ValidationFramework.java
index 148d6c9..a9f63a3 100644
--- a/plugins/org.eclipse.wst.validation/vf2/org/eclipse/wst/validation/ValidationFramework.java
+++ b/plugins/org.eclipse.wst.validation/vf2/org/eclipse/wst/validation/ValidationFramework.java
@@ -116,6 +116,31 @@
 	}
 	
 	/**
+	 * Answer the validator with the given id.
+	 * @param id
+	 * @return null if the validator is not found
+	 */
+	public Validator getValidator(String id){
+		return ValManager.getDefault().getValidatorWithId(id, null);
+	}
+	
+	/**
+	 * Answer all the validators that are applicable for the given resource.
+	 * By convention this is the method that is used
+	 * by the as-you-type validators, to determine if they should be validating the resource.
+	 * 
+	 * @param resource the resource that determines which validators are applicable.
+	 */
+	public Validator[] getValidatorsFor(IResource resource){
+		List<Validator> list = new LinkedList<Validator>();
+		for (Validator v : getValidatorsFor(resource, false, false)){
+			if (v.isBuildValidation() || v.isManualValidation())list.add(v);
+		}
+		Validator[] vals = new Validator[list.size()];
+		return list.toArray(vals);
+	}
+	
+	/**
 	 * Answer true if the resource has any enabled validators.
 	 * 
 	 * @param resource a file, folder or project.
diff --git a/plugins/org.eclipse.wst.validation/vf2/org/eclipse/wst/validation/ValidationResult.java b/plugins/org.eclipse.wst.validation/vf2/org/eclipse/wst/validation/ValidationResult.java
index fe81a5b..62bcab1 100644
--- a/plugins/org.eclipse.wst.validation/vf2/org/eclipse/wst/validation/ValidationResult.java
+++ b/plugins/org.eclipse.wst.validation/vf2/org/eclipse/wst/validation/ValidationResult.java
@@ -5,6 +5,9 @@
 
 import org.eclipse.core.resources.IMarker;
 import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.wst.validation.internal.core.ValidationException;
+import org.eclipse.wst.validation.internal.provisional.core.IReporter;
 
 /**
  * The result of running a validate operation.
@@ -39,6 +42,9 @@
 	/** A count of the number of resources that were validated. */
 	private int			_numberOfValidatedResources = 1;
 	
+	private ReporterHelper	_reporter;
+	private ValidationException	_validationException;
+	
 	/**
 	 * This is an optional method, that a validator can use to return error messages. When the validation framework
 	 * is invoking the validator these will be converted into IMarkers. If the validator is being called directly then
@@ -49,7 +55,13 @@
 	 * because the resource hasn't even been saved. It needs to return something other than an IMarker. But when called
 	 * in batch mode, it does ultimately want IMarkers. By returning ValidatorMessages, it only needs to return one type
 	 * of message, and those messages can be either be directly used by the caller, or automatically converted into IMarkers by
-	 * the validation framework.   
+	 * the validation framework.
+	 * <p>
+	 * To make matters even more complicated there is a third way to return messages. To make it easier for 
+	 * old validators to port to the new framework, they can continue to use an IReporter. If a validator calls the
+	 * getReporter() method then it is assumed by the framework that that is the approach that they have chosen.  
+	 * 
+	 * @see #getReporter(IProgressMonitor)
 	 * 
 	 * @param message a message
 	 */
@@ -58,6 +70,25 @@
 	}
 	
 	/**
+	 * Answer an IReporter for handing error messages.
+	 * <p>
+	 * This is a transition method, to help old validators port to the new validation framework. If this method
+	 * is called it is assumed by the framework, that this IReport will be used as the only way of passing messages
+	 * back to the framework.
+	 * 
+	 * @see #add(ValidatorMessage)
+	 * @param monitor
+	 */
+	public IReporter getReporter(IProgressMonitor monitor){
+		if (_reporter == null)_reporter = new ReporterHelper(monitor);
+		return _reporter;
+	}
+	
+	ReporterHelper getReporterHelper(){
+		return _reporter;
+	}
+	
+	/**
 	 * Merge the message counts and messages from an individual validator into this result.
 	 * @param result it can be null, in which case it is ignored.
 	 */
@@ -261,4 +292,17 @@
 		return _numberOfValidatedResources + _validated.length;
 	}
 
+	public ValidationException getValidationException() {
+		return _validationException;
+	}
+
+	/**
+	 * If the validation failed with an exception, it can be recorded here.
+	 * <p>
+	 * This method is provided for old validators to ease their transition to the new framework.
+	 * @param validationException
+	 */
+	public void setValidationException(ValidationException validationException) {
+		_validationException = validationException;
+	}
 }
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 1dad260..1f322b7 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
@@ -23,6 +23,7 @@
 import org.eclipse.wst.validation.internal.operations.IWorkbenchContext;
 import org.eclipse.wst.validation.internal.operations.WorkbenchContext;
 import org.eclipse.wst.validation.internal.plugin.ValidationPlugin;
+import org.eclipse.wst.validation.internal.provisional.core.IMessage;
 import org.eclipse.wst.validation.internal.provisional.core.IValidator;
 
 /**
@@ -38,6 +39,12 @@
 	/** If this is a delegating validator, then this field holds the validator that will be delegated to. */
 	private String 		_delegatingId;
 	
+	/** 
+	 * If this validator is also used to control an ISource validator, the id of the ISource validator is
+	 * registered here.
+	 */
+	private String		_sourceId;
+	
 	protected boolean 	_manualValidation = true;
 	
 	/** 
@@ -179,6 +186,10 @@
 	public void validationFinishing(IProject project, ValidationState state, IProgressMonitor monitor){		
 		// subclasses need to override this, if they wish to let their validators know about this event
 	}
+	
+	public IValidator asIValidator(){
+		return null;
+	}
 
 	
 	protected abstract boolean shouldValidate(IResource resource);
@@ -226,6 +237,10 @@
 		_buildValidation = buildValidation;
 	}
 
+	/**
+	 * Get the id of the "real" validator, that is the validator that will be called when this delegating
+	 * validator is asked to validate something. If this isn't a delegating validator answer null.
+	 */
 	public String getDelegatingId() {
 		return _delegatingId;
 	}
@@ -262,7 +277,7 @@
  * @author karasiuk
  *
  */ 
-public static class V1 extends Validator {
+public final static class V1 extends Validator {
 	private ValidatorMetaData _vmd;
 	
 	/**
@@ -279,6 +294,19 @@
 		setDelegatingId(ValidatorDelegatesRegistry.getInstance().getDefaultDelegate(getValidatorClassname()));
 	}
 	
+	@Override
+	public IValidator asIValidator() {
+		IValidator v = null;
+		try {
+			v = _vmd.getValidator();
+		}
+		catch (InstantiationException e){
+			ValidationPlugin.getPlugin().handleException(e);
+			return null;
+		}
+		return v;
+	}
+	
 	public V1 asV1Validator() {
 		return this;
 	}
@@ -342,14 +370,8 @@
 		if (monitor == null)monitor = new NullProgressMonitor();
 		
 		ValidationResult vr = new ValidationResult();
-		IValidator v = null;
-		try {
-			v = _vmd.getValidator();
-		}
-		catch (InstantiationException e){
-			ValidationPlugin.getPlugin().handleException(e);
-			return null;
-		}
+		IValidator v = asIValidator();
+		if (v == null)return null;
 		
 		try {
 			IProject project = resource.getProject();
@@ -383,7 +405,7 @@
  * @author karasiuk
  *
  */
-public static class V2 extends Validator implements IAdaptable {
+public final static class V2 extends Validator implements IAdaptable {
 	private AbstractValidator	_validator;
 	
 	private List<FilterGroup>	_groups = new LinkedList<FilterGroup>();
@@ -411,6 +433,13 @@
 		_groups.add(fg);
 	}
 	
+	@Override
+	public IValidator asIValidator() {
+		AbstractValidator av = getDelegatedValidator();
+		if (av instanceof IValidator)return (IValidator)av;
+		return super.asIValidator();
+	}
+	
 	public V2 asV2Validator() {
 		return this;
 	}
@@ -552,6 +581,10 @@
 		}
 		
 		if (vr != null){
+			if (vr.getValidationException() != null){
+				ValidationPlugin.getPlugin().handleException(vr.getValidationException());
+			}
+			updateResults(vr);
 			if (vr.getDependsOn() != null){
 				ValidationFramework.getDefault().getDependencyIndex().set(getDependencyId(), resource, vr.getDependsOn());
 			}
@@ -577,6 +610,36 @@
 		return vr;		
 	}
 	
+	private void updateResults(ValidationResult vr) {
+		ReporterHelper rh = vr.getReporterHelper();
+		if (rh == null)return;
+		for (IMessage message : rh.getMessages()){
+			Object target = message.getTargetObject();
+			if (target != null){
+				if (target instanceof IResource){
+					IResource res = (IResource)target;
+					ValidatorMessage vm = ValidatorMessage.create(message.getText(), res);
+					vr.add(vm);
+					int markerSeverity = IMarker.SEVERITY_INFO;
+					int sev = message.getSeverity();
+					if ((sev & IMessage.HIGH_SEVERITY) != 0)markerSeverity = IMarker.SEVERITY_ERROR;
+					else if ((sev & IMessage.NORMAL_SEVERITY) != 0)markerSeverity = IMarker.SEVERITY_WARNING;
+					vm.setAttribute(IMarker.SEVERITY, markerSeverity);
+					vm.setAttribute(IMarker.LINE_NUMBER, message.getLineNumber());
+					int offset = message.getOffset();
+					if (offset != IMessage.OFFSET_UNSET){
+						vm.setAttribute(IMarker.CHAR_START, offset);
+						int len = message.getLength();
+						if (len != IMessage.OFFSET_UNSET){
+							vm.setAttribute(IMarker.CHAR_START, offset);
+							vm.setAttribute(IMarker.CHAR_END, offset+len);
+						}
+					}					
+				}
+			}
+		}		
+	}
+
 	@Override
 	public void validationStarting(IProject project, ValidationState state, IProgressMonitor monitor) {
 		_validator.validationStarting(project, state, monitor);
@@ -605,4 +668,12 @@
 		return true;
 	}
 }
+
+public String getSourceId() {
+	return _sourceId;
+}
+
+public void setSourceId(String sourceId) {
+	_sourceId = sourceId;
+}
 }
diff --git a/plugins/org.eclipse.wst.validation/vf2/org/eclipse/wst/validation/internal/ExtensionConstants.java b/plugins/org.eclipse.wst.validation/vf2/org/eclipse/wst/validation/internal/ExtensionConstants.java
index becfc4c..fd29e31 100644
--- a/plugins/org.eclipse.wst.validation/vf2/org/eclipse/wst/validation/internal/ExtensionConstants.java
+++ b/plugins/org.eclipse.wst.validation/vf2/org/eclipse/wst/validation/internal/ExtensionConstants.java
@@ -20,6 +20,14 @@
 	String manual = "manual"; //$NON-NLS-1$
 	
 	/** 
+	 * sourceid - If this validator also serves as an as-you-type validator (also know as an ISourceValidator) 
+	 * then it's source id is specified here, so that the two validators can be associated with one 
+	 * another. By source id, we mean the id that is used in the org.eclipse.wst.sse.ui.sourceValidation 
+	 * extension point.
+	 */
+	String sourceId = "sourceid"; //$NON-NLS-1$
+	
+	/** 
 	 * version - the version of this definition. The attribute is a simple integer, and if not specified it
 	 * is assumed to be 1. This allows the filter settings to be changed in the future.
 	 */
diff --git a/plugins/org.eclipse.wst.validation/vf2/org/eclipse/wst/validation/internal/PerformanceMonitor.java b/plugins/org.eclipse.wst.validation/vf2/org/eclipse/wst/validation/internal/PerformanceMonitor.java
index 1b625b9..e789acc 100644
--- a/plugins/org.eclipse.wst.validation/vf2/org/eclipse/wst/validation/internal/PerformanceMonitor.java
+++ b/plugins/org.eclipse.wst.validation/vf2/org/eclipse/wst/validation/internal/PerformanceMonitor.java
@@ -23,13 +23,16 @@
 	/**
 	 * Create a performance monitor.
 	 * 
-	 * @param traceTimes should the monitor be turned on?
-	 * @param file should the events be logged to a file. If this is null the events will be written to stderr.
-	 * If it is not null then the the events are appended to a file with this name.
+	 * @param traceTimes
+	 *            should the monitor be turned on?
+	 * @param file
+	 *            should the events be logged to a file. If this is null or the
+	 *            empty string the events will be written to stderr. Otherwise
+	 *            the events are appended to a file with this name.
 	 */
 	public static PerformanceMonitor create(boolean traceTimes, String file){
 		PerformanceMonitor pm = null;
-		if (file == null)pm = new PerformanceMonitor();
+		if (file == null || file.length() == 0)pm = new PerformanceMonitor();
 		else pm = new ToFile(file);
 		
 		if (traceTimes)pm.setCollectionLevel(CollectionLevel.Default);
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 72c0ae2..3f286f9 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
@@ -40,6 +40,7 @@
 
 	/** All the known, global, validators. If this is null it means that the validators have not been loaded yet. */
 	private Validator[] _validators;
+
 		
 	/**
 	 * Projects may be allowed to override the global validation settings. If that is the case then those
@@ -93,18 +94,34 @@
 	/**
 	 * Answer the validator with the given id that is in effect for the given project.
 	 * 
-	 * @param id validator dependency id.
+	 * @param dependencyId validator dependency id.
 	 * @param project
 	 * @return null if the validator is not found
 	 */
-	public Validator getValidator(String id, IProject project){
+	public Validator getValidator(String dependencyId, IProject project){
 		Validator[] vals = getValidators(project);
 		for (Validator v : vals){
-			if (v.getDependencyId().equals(id))return v;
+			if (v.getDependencyId().equals(dependencyId))return v;
 		}
 		return null;
 	}
-		
+	
+	/**
+	 * Answer the validator with the given id that is in effect for the given project.
+	 * 
+	 * @param id validator id.
+	 * @param project this can be null, in which case all the registered validators are checked.
+	 * @return null if the validator is not found
+	 */
+	public Validator getValidatorWithId(String id, IProject project){
+		Validator[] vals = getValidators(project);
+		for (Validator v : vals){
+			if (v.getId().equals(id))return v;
+		}
+		return null;
+	}
+	
+			
 	/**
 	 * Answer true if the resource has any enabled validators.
 	 * 
@@ -182,20 +199,11 @@
 		for (Validator v : val)set.add(v);
 		
 		List<Validator> list = new LinkedList<Validator>();
-		ValidationConfiguration vc = null;
 		try {
-			if (project == null){
-				vc = ConfigurationManager.getManager().getGlobalConfiguration();
-				for (ValidatorMetaData vmd : ValidationRegistryReader.getReader().getAllValidators()){
-					list.add(Validator.create(vmd, vc));
-				}			
-			}
-			else {
-				vc = ConfigurationManager.getManager().getProjectConfiguration(project);
-				for (ValidatorMetaData vmd : vc.getValidators()){
-					list.add(Validator.create(vmd, vc));
-				}							
-			}
+			ValidationConfiguration vc = ConfigurationManager.getManager().getConfiguration(project);
+			for (ValidatorMetaData vmd : vc.getValidators()){
+				list.add(Validator.create(vmd, vc));
+			}							
 		}
 		catch (InvocationTargetException e){
 			if (!project.exists() || !project.isOpen())throw new ProjectUnavailableError(project);
diff --git a/plugins/org.eclipse.wst.validation/vf2/org/eclipse/wst/validation/internal/ValidatorExtensionReader.java b/plugins/org.eclipse.wst.validation/vf2/org/eclipse/wst/validation/internal/ValidatorExtensionReader.java
index 9f4e0bb..c0787ac 100644
--- a/plugins/org.eclipse.wst.validation/vf2/org/eclipse/wst/validation/internal/ValidatorExtensionReader.java
+++ b/plugins/org.eclipse.wst.validation/vf2/org/eclipse/wst/validation/internal/ValidatorExtensionReader.java
@@ -91,6 +91,7 @@
 			v.setBuildValidation(getAttribute(validator, ExtensionConstants.build, true));
 			v.setManualValidation(getAttribute(validator, ExtensionConstants.manual, true));
 			v.setVersion(getAttribute(validator, ExtensionConstants.version, 1));
+			v.setSourceId(validator.getAttribute(ExtensionConstants.sourceId));
 			if (deep){
 				IConfigurationElement[] children = validator.getChildren();
 				for (int i=0; i<children.length; i++)processValidatorChildren(v, children[i]);
diff --git a/plugins/org.eclipse.wst.validation/xsds/validator.exsd b/plugins/org.eclipse.wst.validation/xsds/validator.exsd
index 98b7384..286545e 100644
--- a/plugins/org.eclipse.wst.validation/xsds/validator.exsd
+++ b/plugins/org.eclipse.wst.validation/xsds/validator.exsd
@@ -79,6 +79,14 @@
                </documentation>
             </annotation>
          </attribute>
+         <attribute name="sourceid" type="string">
+            <annotation>
+               <documentation>
+                  If this validator also serves as an as-you-type validator (also know as an ISourceValidator) then it&apos;s source id is specified here, so that the two validators can be associated with one another.
+By source id, we mean the id that is used in the org.eclipse.wst.sse.ui.sourceValidation extension point
+               </documentation>
+            </annotation>
+         </attribute>
       </complexType>
    </element>
 
@@ -261,22 +269,6 @@
       </documentation>
    </annotation>
 
-   <annotation>
-      <appInfo>
-         <meta.section type="implementation"/>
-      </appInfo>
-      <documentation>
-         
-      </documentation>
-   </annotation>
 
-   <annotation>
-      <appInfo>
-         <meta.section type="copyright"/>
-      </appInfo>
-      <documentation>
-         
-      </documentation>
-   </annotation>
 
 </schema>