[129906] [editor] StructuredTextEditor does not throw SelectionChanged event when contents of active document is replaced by builder.
diff --git a/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/StructuredTextEditor.java b/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/StructuredTextEditor.java
index db9e5a5..2e1199d 100644
--- a/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/StructuredTextEditor.java
+++ b/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/StructuredTextEditor.java
@@ -74,6 +74,7 @@
 import org.eclipse.jface.text.information.IInformationPresenter;
 import org.eclipse.jface.text.information.IInformationProvider;
 import org.eclipse.jface.text.information.InformationPresenter;
+import org.eclipse.jface.text.reconciler.DirtyRegion;
 import org.eclipse.jface.text.reconciler.IReconciler;
 import org.eclipse.jface.text.source.Annotation;
 import org.eclipse.jface.text.source.DefaultCharacterPairMatcher;
@@ -200,6 +201,7 @@
 import org.eclipse.wst.sse.ui.internal.provisional.preferences.CommonEditorPreferenceNames;
 import org.eclipse.wst.sse.ui.internal.quickoutline.QuickOutlineHandler;
 import org.eclipse.wst.sse.ui.internal.quickoutline.QuickOutlinePopupDialog;
+import org.eclipse.wst.sse.ui.internal.reconcile.DirtyRegionProcessor;
 import org.eclipse.wst.sse.ui.internal.reconcile.DocumentRegionProcessor;
 import org.eclipse.wst.sse.ui.internal.selection.SelectionHistory;
 import org.eclipse.wst.sse.ui.internal.style.SemanticHighlightingManager;
@@ -2371,6 +2373,26 @@
 		updateStatusField(StructuredTextEditorActionConstants.STATUS_CATEGORY_OFFSET);
 	}
 	
+	protected void handleElementContentReplaced() {
+		super.handleElementContentReplaced();
+
+		// queue a full revalidation of content
+		IDocument document = getDocumentProvider().getDocument(getEditorInput());
+		SourceViewerConfiguration sourceViewerConfiguration = getSourceViewerConfiguration();
+		if (document != null && sourceViewerConfiguration != null && sourceViewerConfiguration.getReconciler(getSourceViewer()) instanceof DirtyRegionProcessor) {
+			((DirtyRegionProcessor) sourceViewerConfiguration.getReconciler(getSourceViewer())).processDirtyRegion(new DirtyRegion(0, document.getLength(), DirtyRegion.INSERT, document.get()));
+		}
+		
+		// https://bugs.eclipse.org/bugs/show_bug.cgi?id=129906 - update selection to listeners
+		ISelectionProvider selectionProvider = getSelectionProvider();
+		ISelection originalSelection = selectionProvider.getSelection();
+		if (selectionProvider instanceof StructuredSelectionProvider && originalSelection instanceof ITextSelection) {
+			SelectionChangedEvent syntheticEvent = new SelectionChangedEvent(selectionProvider, new TextSelection(((ITextSelection) originalSelection).getOffset(), ((ITextSelection) originalSelection).getLength()));
+			((StructuredSelectionProvider) selectionProvider).handleSelectionChanged(syntheticEvent);
+			((StructuredSelectionProvider) selectionProvider).handlePostSelectionChanged(syntheticEvent);
+		}
+	}
+	
 	/*
 	 * (non-Javadoc)
 	 * 
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 7861f66..03b2dde 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
@@ -31,7 +31,6 @@
  * 
  */
 public class StructuredRegionProcessor extends DocumentRegionProcessor {
-
 	class ModelLifecycleListener implements IModelLifecycleListener {
 		IStructuredModel changing = null;
 		/**
@@ -88,6 +87,9 @@
 	private IModelLifecycleListener fLifeCycleListener = new ModelLifecycleListener();
 	/** Used to get the current model on demand so a model does not need to be held by permanently */
 	private IDocument fCurrentDoc = null;
+	
+	/** Only to be used for content type and IModelLifecycleListener registration.  All other uses should "get" the model. */
+	private IStructuredModel fCurrentModel = null;
 
 	/*
 	 * (non-Javadoc)
@@ -194,6 +196,14 @@
 	 * use that.
 	 */
 	protected String getContentType(IDocument doc) {
+		if (fCurrentModel != null && doc == fCurrentModel.getStructuredDocument()) {
+			/*
+			 * Avoid "get"ting a model if we can, it may require lock
+			 * acquisition
+			 */
+			return fCurrentModel.getContentTypeIdentifier();
+		}
+
 		String contentTypeId = null;
 		IStructuredModel sModel = null;
 		try {
@@ -269,36 +279,30 @@
 	}
 
 	public void setDocument(IDocument newDocument) {
-		// unhook old lifecycle listener
-		if(fCurrentDoc != null) {
-			IStructuredModel oldModel = null;
-			try {
-				oldModel = getStructuredModelForRead(fCurrentDoc);
-				if(oldModel != null) {
-					oldModel.removeModelLifecycleListener(fLifeCycleListener);
-				}
-			} finally {
-				if(oldModel != null) {
-					oldModel.releaseFromRead();
-				}
-			}
+		/*
+		 * unhook old lifecycle listener; it is important not to re-get the
+		 * model at this point as we may be shutting down
+		 */
+		if (fCurrentModel != null) {
+			fCurrentModel.removeModelLifecycleListener(fLifeCycleListener);
+			fCurrentModel = null;
 		}
-		
-		//set the new document
+
+		// set the new document
 		super.setDocument(newDocument);
 		fCurrentDoc = newDocument;
-		
+
 		// add new lifecycle listener
-		if (newDocument != null) {
-			IStructuredModel newModel = null;
+		if (fCurrentDoc != null) {
 			try {
-				newModel = getStructuredModelForRead(newDocument);
-				if(newModel != null) {
-					newModel.addModelLifecycleListener(fLifeCycleListener);
+				fCurrentModel = getStructuredModelForRead(fCurrentDoc);
+				if (fCurrentModel != null) {
+					fCurrentModel.addModelLifecycleListener(fLifeCycleListener);
 				}
-			} finally {
-				if(newModel != null) {
-					newModel.releaseFromRead();
+			}
+			finally {
+				if (fCurrentModel != null) {
+					fCurrentModel.releaseFromRead();
 				}
 			}
 		}