[116119] I think this partially fixes the flakiness, but batch validation doesn't seem to be working for jsp actions (eg. jsp:forward).
diff --git a/bundles/org.eclipse.wst.html.ui/src-html-validation/org/eclipse/wst/html/internal/validation/HTMLValidator.java b/bundles/org.eclipse.wst.html.ui/src-html-validation/org/eclipse/wst/html/internal/validation/HTMLValidator.java
index 756566a..8e8eb83 100644
--- a/bundles/org.eclipse.wst.html.ui/src-html-validation/org/eclipse/wst/html/internal/validation/HTMLValidator.java
+++ b/bundles/org.eclipse.wst.html.ui/src-html-validation/org/eclipse/wst/html/internal/validation/HTMLValidator.java
@@ -40,6 +40,8 @@
 import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;
 import org.eclipse.wst.sse.core.internal.provisional.IndexedRegion;
 import org.eclipse.wst.sse.core.internal.provisional.StructuredModelManager;
+import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocument;
+import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocumentRegion;
 import org.eclipse.wst.sse.core.internal.util.URIResolver;
 import org.eclipse.wst.sse.core.internal.validate.ValidationAdapter;
 import org.eclipse.wst.sse.ui.internal.reconcile.validator.ISourceValidator;
@@ -204,75 +206,78 @@
 		}
 	}
 	
+
 	/**
-	 * This validate call is for the ISourceValidator partial document validation approach
+	 * This validate call is for the ISourceValidator partial document
+	 * validation approach
+	 * 
 	 * @param dirtyRegion
 	 * @param helper
 	 * @param reporter
-	 *  @see org.eclipse.wst.sse.ui.internal.reconcile.validator.ISourceValidator
+	 * @see org.eclipse.wst.sse.ui.internal.reconcile.validator.ISourceValidator
 	 */
 	public void validate(IRegion dirtyRegion, IValidationContext helper, IReporter reporter) {
-		
+
 		if (helper == null || fDocument == null)
 			return;
-		
+
 		if ((reporter != null) && (reporter.isCancelled() == true)) {
 			throw new OperationCanceledException();
 		}
-		
+
 		IStructuredModel model = StructuredModelManager.getModelManager().getExistingModelForRead(fDocument);
 		if (model == null)
 			return; // error
-	
+
 		try {
-		
+
 			IDOMDocument document = null;
-			if(model instanceof IDOMModel) {
-				document = ((IDOMModel)model).getDocument();
+			if (model instanceof IDOMModel) {
+				document = ((IDOMModel) model).getDocument();
 			}
 
 			if (document == null || !hasHTMLFeature(document))
-				return ; // ignore
-	
+				return; // ignore
+
 			ITextFileBuffer fb = FileBufferModelManager.getInstance().getBuffer(fDocument);
-			if(fb == null)
+			if (fb == null)
 				return;
-			
+
 			IFile file = ResourcesPlugin.getWorkspace().getRoot().getFile(fb.getLocation());
-			if(file == null || !file.exists())
+			if (file == null || !file.exists())
 				return;
-			
+
 			// this will be the wrong region if it's Text (instead of Element)
 			// we don't know how to validate Text
-			IndexedRegion ir = model.getIndexedRegion(dirtyRegion.getOffset());
-			if(ir instanceof Text) {
-				while(ir != null && ir instanceof Text) {
+			IndexedRegion ir = getCoveringNode(dirtyRegion); //  model.getIndexedRegion(dirtyRegion.getOffset());
+			if (ir instanceof Text) {
+				while (ir != null && ir instanceof Text) {
 					// it's assumed that this gets the IndexedRegion to
 					// the right of the end offset
 					ir = model.getIndexedRegion(ir.getEndOffset());
 				}
 			}
 			
-			if(ir instanceof INodeNotifier) {
-				
+			if (ir instanceof INodeNotifier) {
+
 				INodeAdapterFactory factory = HTMLValidationAdapterFactory.getInstance();
-				ValidationAdapter adapter = (ValidationAdapter) factory.adapt((INodeNotifier)ir);
+				ValidationAdapter adapter = (ValidationAdapter) factory.adapt((INodeNotifier) ir);
 				if (adapter == null)
 					return; // error
-				
+
 				if (reporter != null) {
 					HTMLValidationReporter rep = null;
-					rep = getReporter(reporter, file, (IDOMModel)model);
+					rep = getReporter(reporter, file, (IDOMModel) model);
 					rep.clear();
 					adapter.setReporter(rep);
-					
+
 					String fileName = ""; //$NON-NLS-1$
 					IPath filePath = file.getFullPath();
 					if (filePath != null) {
 						fileName = filePath.toString();
 					}
 					String args[] = new String[]{fileName};
-		
+
 					Message mess = new LocalizedMessage(IMessage.LOW_SEVERITY, NLS.bind(HTMLUIMessages.MESSAGE_HTML_VALIDATION_MESSAGE_UI_, args));
 					mess.setParams(args);
 					reporter.displaySubtask(this, mess);
@@ -281,11 +286,67 @@
 			}
 		}
 		finally {
-			if(model != null)
+			if (model != null)
 				model.releaseFromRead();
 		}
 	}
 
+	private IndexedRegion getCoveringNode(IRegion dirtyRegion) {
+		
+		IndexedRegion largestRegion = null;
+		if(fDocument instanceof IStructuredDocument) {
+			IStructuredModel sModel = StructuredModelManager.getModelManager().getExistingModelForRead(fDocument);
+			try {
+				if(sModel != null) {
+					IStructuredDocumentRegion[] regions = ((IStructuredDocument)fDocument).getStructuredDocumentRegions(dirtyRegion.getOffset(), dirtyRegion.getLength());
+				    largestRegion = getLargest(regions);
+				}
+			}
+			finally {
+				if(sModel != null)
+					sModel.releaseFromRead();
+			}
+		}
+		return largestRegion;
+	}
+	protected IndexedRegion getLargest(IStructuredDocumentRegion[] sdRegions) {
+		
+		if(sdRegions == null || sdRegions.length == 0)
+			return null;
+		 
+		IndexedRegion currentLargest = getCorrespondingNode(sdRegions[0]);
+		for (int i = 0; i < sdRegions.length; i++) {
+		    if(!sdRegions[i].isDeleted()) {
+    			IndexedRegion corresponding = getCorrespondingNode(sdRegions[i]);
+    			
+    			if(currentLargest instanceof Text)
+    				currentLargest = corresponding;
+    			
+                if(corresponding != null) {
+                	if(!(corresponding instanceof Text)) {
+	        			if (corresponding.getStartOffset() <= currentLargest.getStartOffset()  
+	        						&&  corresponding.getEndOffset() >= currentLargest.getEndOffset() )
+	        				currentLargest = corresponding;
+                	}
+                }
+                
+            }
+		}
+		return currentLargest;
+	}
+	protected IndexedRegion getCorrespondingNode(IStructuredDocumentRegion sdRegion) {
+		IStructuredModel sModel = StructuredModelManager.getModelManager().getExistingModelForRead(fDocument);
+        IndexedRegion indexedRegion = null;
+        try {
+            if (sModel != null) 
+                indexedRegion = sModel.getIndexedRegion(sdRegion.getStart());    
+        } finally {
+            if (sModel != null)
+                sModel.releaseFromRead();
+        }
+        return indexedRegion;
+    }
+
 	/**
 	 * @see org.eclipse.wst.sse.ui.internal.reconcile.validator.ISourceValidator
 	 */