[136902] source validation slows down formatter
diff --git a/bundles/org.eclipse.wst.sse.core/.options b/bundles/org.eclipse.wst.sse.core/.options
index d83ceee..94d01b5 100644
--- a/bundles/org.eclipse.wst.sse.core/.options
+++ b/bundles/org.eclipse.wst.sse.core/.options
@@ -15,3 +15,4 @@
 org.eclipse.wst.sse.core/tasks/time=false
 org.eclipse.wst.sse.core/tasks/preferences=false
 org.eclipse.wst.sse.core/tasks/registry=false
+org.eclipse.wst.sse.core/format=false
diff --git a/bundles/org.eclipse.wst.sse.core/META-INF/MANIFEST.MF b/bundles/org.eclipse.wst.sse.core/META-INF/MANIFEST.MF
index 3afdd0f..350d914 100644
--- a/bundles/org.eclipse.wst.sse.core/META-INF/MANIFEST.MF
+++ b/bundles/org.eclipse.wst.sse.core/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@
 Bundle-ManifestVersion: 2
 Bundle-Name: %pluginName
 Bundle-SymbolicName: org.eclipse.wst.sse.core; singleton:=true
-Bundle-Version: 1.1.200.qualifier
+Bundle-Version: 1.1.201.qualifier
 Bundle-Activator: org.eclipse.wst.sse.core.internal.SSECorePlugin
 Bundle-Vendor: %providerName
 Bundle-Localization: plugin
diff --git a/bundles/org.eclipse.wst.sse.core/src/org/eclipse/wst/sse/core/internal/Logger.java b/bundles/org.eclipse.wst.sse.core/src/org/eclipse/wst/sse/core/internal/Logger.java
index 2b65d7e..6219ddc 100644
--- a/bundles/org.eclipse.wst.sse.core/src/org/eclipse/wst/sse/core/internal/Logger.java
+++ b/bundles/org.eclipse.wst.sse.core/src/org/eclipse/wst/sse/core/internal/Logger.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2001, 2004 IBM Corporation and others.
+ * Copyright (c) 2001, 2006 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
@@ -46,6 +46,10 @@
 	 */
 	public static final boolean DEBUG_FILEBUFFERMODELMANAGEMENT = DEBUG && "true".equalsIgnoreCase(Platform.getDebugOption("org.eclipse.wst.sse.core/filebuffers/modelmanagement")); //$NON-NLS-1$ //$NON-NLS-2$
 	/**
+	 * true if platform and plugin are in debug mode and debugging formatting
+	 */
+	public static final boolean DEBUG_FORMAT = DEBUG && "true".equalsIgnoreCase(Platform.getDebugOption("org.eclipse.wst.sse.core/format")); //$NON-NLS-1$ //$NON-NLS-2$
+	/**
 	 * true if platform and plugin are in debug mode and debugging text buffer
 	 * lifecycle
 	 */
diff --git a/bundles/org.eclipse.wst.sse.core/src/org/eclipse/wst/sse/core/internal/format/AbstractStructuredFormatProcessor.java b/bundles/org.eclipse.wst.sse.core/src/org/eclipse/wst/sse/core/internal/format/AbstractStructuredFormatProcessor.java
index 148ec1e..bd18d11 100644
--- a/bundles/org.eclipse.wst.sse.core/src/org/eclipse/wst/sse/core/internal/format/AbstractStructuredFormatProcessor.java
+++ b/bundles/org.eclipse.wst.sse.core/src/org/eclipse/wst/sse/core/internal/format/AbstractStructuredFormatProcessor.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2001, 2004 IBM Corporation and others.
+ * Copyright (c) 2001, 2006 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
@@ -161,13 +161,15 @@
 				// Note: We are getting model for edit. Will save model if
 				// model changed.
 				structuredModel = StructuredModelManager.getModelManager().getExistingModelForEdit(document);
-
-				// format
-				formatModel(structuredModel, start, length);
-
-				// save model if needed
-				if (!structuredModel.isSharedForEdit() && structuredModel.isSaveNeeded())
-					structuredModel.save();
+				
+				if (structuredModel != null) {
+					// format
+					formatModel(structuredModel, start, length);
+	
+					// save model if needed
+					if (!structuredModel.isSharedForEdit() && structuredModel.isSaveNeeded())
+						structuredModel.save();
+				}
 			}
 			finally {
 				// ensureClosed(outputStream, null);
@@ -301,6 +303,9 @@
 
 	public void formatModel(IStructuredModel structuredModel, int start, int length) {
 		if (structuredModel != null) {
+			// for debugging purposes
+			long startTime = System.currentTimeMillis();
+
 			IDocumentExtension4 docExt4 = null;
 			if (structuredModel.getStructuredDocument() instanceof IDocumentExtension4) {
 				docExt4 = (IDocumentExtension4) structuredModel.getStructuredDocument();
@@ -368,6 +373,11 @@
 					structuredModel.changedModel();
 				}
 			}
+			
+			if (Logger.DEBUG_FORMAT) {
+				long endTime = System.currentTimeMillis();
+				System.out.println("formatModel time: " + (endTime - startTime)); //$NON-NLS-1$
+			}
 		}
 	}
 
diff --git a/bundles/org.eclipse.wst.sse.core/src/org/eclipse/wst/sse/core/internal/model/AbstractStructuredModel.java b/bundles/org.eclipse.wst.sse.core/src/org/eclipse/wst/sse/core/internal/model/AbstractStructuredModel.java
index 8053245..1bf561d 100644
--- a/bundles/org.eclipse.wst.sse.core/src/org/eclipse/wst/sse/core/internal/model/AbstractStructuredModel.java
+++ b/bundles/org.eclipse.wst.sse.core/src/org/eclipse/wst/sse/core/internal/model/AbstractStructuredModel.java
@@ -319,7 +319,7 @@
 
 		if (fLockObject != null && fLockObject != documentLock) {
 			fLockObject.release();
-			if (Logger.DEBUG) {
+			if (Logger.DEBUG_MODELSTATE) {
 				Logger.log(Logger.INFO, "Model lock released early" + fLockObject + " apparently document switched?"); //$NON-NLS-1$ //$NON-NLS-2$
 			}
 
@@ -327,7 +327,7 @@
 		fLockObject = documentLock;
 		if (fLockObject != null) {
 			fLockObject.acquire();
-			if (Logger.DEBUG) {
+			if (Logger.DEBUG_MODELSTATE) {
 				Logger.log(Logger.INFO, "Model lock acquired: " + fLockObject); //$NON-NLS-1$
 			}
 		}
@@ -478,7 +478,7 @@
 	protected final void endLock() {
 		if (fLockObject != null) {
 			fLockObject.release();
-			if (Logger.DEBUG) {
+			if (Logger.DEBUG_MODELSTATE) {
 				Logger.log(Logger.INFO, "Model lock released: " + fLockObject); //$NON-NLS-1$
 			}
 
@@ -1008,7 +1008,7 @@
 			}
 		}
 		else {
-			if (Logger.DEBUG) {
+			if (Logger.DEBUG_MODELSTATE) {
 				Logger.log(Logger.INFO, "indeed!!!"); //$NON-NLS-1$
 			}
 		}
diff --git a/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/internal/reconcile/DirtyRegionProcessor.java b/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/internal/reconcile/DirtyRegionProcessor.java
index 4bdfe29..b6c42b2 100644
--- a/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/internal/reconcile/DirtyRegionProcessor.java
+++ b/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/internal/reconcile/DirtyRegionProcessor.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2001, 2004 IBM Corporation and others.
+ * Copyright (c) 2001, 2006 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
@@ -27,9 +27,12 @@
 import org.eclipse.core.runtime.jobs.Job;
 import org.eclipse.jface.text.BadLocationException;
 import org.eclipse.jface.text.DocumentEvent;
+import org.eclipse.jface.text.DocumentRewriteSessionEvent;
 import org.eclipse.jface.text.IDocument;
 import org.eclipse.jface.text.IDocumentExtension3;
+import org.eclipse.jface.text.IDocumentExtension4;
 import org.eclipse.jface.text.IDocumentListener;
+import org.eclipse.jface.text.IDocumentRewriteSessionListener;
 import org.eclipse.jface.text.ITextInputListener;
 import org.eclipse.jface.text.ITextViewer;
 import org.eclipse.jface.text.ITypedRegion;
@@ -51,11 +54,24 @@
 public class DirtyRegionProcessor extends Job implements IReconciler, IReconcilerExtension, IConfigurableReconciler {
 	class DocumentListener implements IDocumentListener {
 		public void documentAboutToBeChanged(DocumentEvent event) {
+			/* 
+			 * if in rewrite session and already going to reprocess
+			 * entire document after rewrite session, do nothing
+			 */
+			if (isInRewriteSession() && fReprocessAfterRewrite)
+				return;
 			// save partition type (to see if it changes in documentChanged())
 			fLastPartitions = getPartitions(event.getOffset(), event.getLength());
 		}
 
 		public void documentChanged(DocumentEvent event) {
+			/* 
+			 * if in rewrite session and already going to reprocess
+			 * entire document after rewrite session, do nothing
+			 */
+			if (isInRewriteSession() && fReprocessAfterRewrite)
+				return;
+
 			if (partitionsChanged(event)) {
 				// pa_TODO
 				// this is a simple way to ensure old
@@ -87,7 +103,18 @@
 						dr = createDirtyRegion(event.getOffset(), event.getLength(), DirtyRegion.INSERT);
 					}
 				}
-				processDirtyRegion(dr);
+				if (isInRewriteSession()) {
+					/*
+					 * while in rewrite session, found a dirty region, so flag
+					 * that entire document needs to be reprocesed after rewrite
+					 * session
+					 */
+					if (!fReprocessAfterRewrite && (dr != null)) {
+						fReprocessAfterRewrite = true;
+					}
+				} else {
+					processDirtyRegion(dr);
+				}
 			}
 		}
 
@@ -146,6 +173,39 @@
 		}
 	}
 
+	class DocumentRewriteSessionListener implements IDocumentRewriteSessionListener {
+		long time0 = 0;
+		
+		public void documentRewriteSessionChanged(DocumentRewriteSessionEvent event) {
+			boolean oldValue = fInRewriteSession;
+			fInRewriteSession = event != null && event.getChangeType().equals(DocumentRewriteSessionEvent.SESSION_START);
+
+			if (event.getChangeType().equals(DocumentRewriteSessionEvent.SESSION_START)) {
+				if(DEBUG) {
+					time0 = System.currentTimeMillis();
+				}
+				flushDirtyRegionQueue();
+				fReprocessAfterRewrite = false;
+			}
+			else if (event.getChangeType().equals(DocumentRewriteSessionEvent.SESSION_STOP)) {
+				if (fInRewriteSession ^ oldValue && fDocument != null) {
+					if(DEBUG) {
+						Logger.log(Logger.INFO, "Rewrite session lasted " + (System.currentTimeMillis() - time0) + "ms");
+						time0 = System.currentTimeMillis();
+					}
+					if (fReprocessAfterRewrite) {
+						DirtyRegion entireDocument = createDirtyRegion(0, fDocument.getLength(), DirtyRegion.INSERT);
+						processDirtyRegion(entireDocument);
+					}
+					if (DEBUG) {
+						Logger.log(Logger.INFO, "Full document reprocess took " + (System.currentTimeMillis() - time0) + "ms");
+					}
+					fReprocessAfterRewrite = false;
+				}
+			}
+		}
+	}
+
 	/** debug flag */
 	protected static final boolean DEBUG;
 	private static final long UPDATE_DELAY = 750;
@@ -165,6 +225,8 @@
 	private IDocument fDocument = null;
 
 	private IDocumentListener fDocumentListener = new DocumentListener();
+	private IDocumentRewriteSessionListener fDocumentRewriteSessionListener = new DocumentRewriteSessionListener();
+
 	/**
 	 * set true after first install to prevent duplicate work done in the
 	 * install method (since install gets called multiple times)
@@ -189,6 +251,12 @@
 	private TextInputListener fTextInputListener = null;
 	/** the text viewer */
 	private ITextViewer fViewer;
+	boolean fInRewriteSession = false;
+	/**
+	 * true if entire document needs to be reprocessed after
+	 * rewrite session
+	 */
+	boolean fReprocessAfterRewrite = false;
 
 	/**
 	 * Creates a new StructuredRegionProcessor
@@ -481,6 +549,10 @@
 		return fIsInstalled;
 	}
 
+	boolean isInRewriteSession() {
+		return fInRewriteSession;
+	}
+
 	/**
 	 * Subclasses should implement for specific handling of dirty regions. The
 	 * method is invoked for each dirty region in the Job's queue.
@@ -488,6 +560,9 @@
 	 * @param dirtyRegion
 	 */
 	protected void process(DirtyRegion dirtyRegion) {
+		if (isInRewriteSession()) {
+			return;
+		}
 		/*
 		 * Break the dirty region into a sequence of partitions and find the
 		 * corresponding strategy to reconcile those partitions. If a strategy
@@ -576,7 +651,15 @@
 	}
 
 	public void setDocument(IDocument doc) {
+		if (fDocument != null && fDocument instanceof IDocumentExtension4) {
+			((IDocumentExtension4) fDocument).removeDocumentRewriteSessionListener(fDocumentRewriteSessionListener);
+		}
+
 		fDocument = doc;
+
+		if (fDocument != null && fDocument instanceof IDocumentExtension4) {
+			((IDocumentExtension4) fDocument).addDocumentRewriteSessionListener(fDocumentRewriteSessionListener);
+		}
 	}
 
 	/**
@@ -601,7 +684,7 @@
 		if (document != null && isInstalled()) {
 
 			// since we're marking the entire doc dirty
-			getDirtyRegionQueue().clear();
+			flushDirtyRegionQueue();
 			DirtyRegion entireDocument = createDirtyRegion(0, document.getLength(), DirtyRegion.INSERT);
 			processDirtyRegion(entireDocument);
 		}
diff --git a/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/internal/reconcile/DocumentRegionProcessor.java b/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/internal/reconcile/DocumentRegionProcessor.java
index 80b3f9b..fe472cb 100644
--- a/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/internal/reconcile/DocumentRegionProcessor.java
+++ b/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/internal/reconcile/DocumentRegionProcessor.java
@@ -54,6 +54,7 @@
 
 	private final String SSE_UI_ID = "org.eclipse.wst.sse.ui"; //$NON-NLS-1$
 
+
 	protected void beginProcessing() {
 		super.beginProcessing();
 		ValidatorStrategy validatorStrategy = getValidatorStrategy();
@@ -165,7 +166,7 @@
 	 * @param dirtyRegion
 	 */
 	protected void process(DirtyRegion dirtyRegion) {
-		if (!isInstalled())
+		if (!isInstalled() || isInRewriteSession())
 			return;
 
 		super.process(dirtyRegion);
diff --git a/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/internal/reconcile/StructuredRegionProcessor.java b/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/internal/reconcile/StructuredRegionProcessor.java
index 270f397..a3c0963 100644
--- a/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/internal/reconcile/StructuredRegionProcessor.java
+++ b/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/internal/reconcile/StructuredRegionProcessor.java
@@ -235,7 +235,7 @@
 	}
 
 	protected void process(DirtyRegion dirtyRegion) {
-		if (getDocument() == null)
+		if (getDocument() == null || isInRewriteSession())
 			return;
 
 		// use structured model to determine area to process