[103896] Memory leak in BasicStructuredDocument
diff --git a/bundles/org.eclipse.wst.css.core/src/org/eclipse/wst/css/core/internal/document/CSSModelImpl.java b/bundles/org.eclipse.wst.css.core/src/org/eclipse/wst/css/core/internal/document/CSSModelImpl.java
index 8236b68..c130c40 100644
--- a/bundles/org.eclipse.wst.css.core/src/org/eclipse/wst/css/core/internal/document/CSSModelImpl.java
+++ b/bundles/org.eclipse.wst.css.core/src/org/eclipse/wst/css/core/internal/document/CSSModelImpl.java
@@ -231,9 +231,9 @@
 		if (ownerNode == null) {
 			// this case is external CSS file
 			doc = (CSSStyleSheetImpl) DOMCSSImpl.createCSSStyleSheet(null, null); // parameters
-																					// are
-																					// for
-																					// STYLE-tag
+			// are
+			// for
+			// STYLE-tag
 			parserMode = CSSSourceParser.MODE_STYLESHEET;
 		}
 		else if (ownerNode instanceof org.w3c.dom.Element && ((Element) ownerNode).getTagName().toUpperCase().equals("STYLE")) {//$NON-NLS-1$
@@ -544,11 +544,13 @@
 		if (oldStructuredDocument != null)
 			oldStructuredDocument.removeDocumentChangingListener(this);
 		super.setStructuredDocument(newStructuredDocument);
-		if (newStructuredDocument.getLength() > 0) {
-			newModel(new NewDocumentEvent(newStructuredDocument, this));
-		}
-		if (newStructuredDocument != null)
+
+		if (newStructuredDocument != null) {
+			if (newStructuredDocument.getLength() > 0) {
+				newModel(new NewDocumentEvent(newStructuredDocument, this));
+			}
 			newStructuredDocument.addDocumentChangingListener(this);
+		}
 	}
 
 	/**
diff --git a/bundles/org.eclipse.wst.dtd.core/src/org/eclipse/wst/dtd/core/internal/document/DTDModelImpl.java b/bundles/org.eclipse.wst.dtd.core/src/org/eclipse/wst/dtd/core/internal/document/DTDModelImpl.java
index 5778e82..e33ca24 100644
--- a/bundles/org.eclipse.wst.dtd.core/src/org/eclipse/wst/dtd/core/internal/document/DTDModelImpl.java
+++ b/bundles/org.eclipse.wst.dtd.core/src/org/eclipse/wst/dtd/core/internal/document/DTDModelImpl.java
@@ -263,10 +263,11 @@
 		if (oldStructuredDocument != null)
 			oldStructuredDocument.removeDocumentChangingListener(this);
 		super.setStructuredDocument(newStructuredDocument);
-		if (newStructuredDocument.getLength() > 0) {
-			newModel(new NewDocumentEvent(newStructuredDocument, this));
-		}
-		if (newStructuredDocument != null)
+		if (newStructuredDocument != null) {
+			if (newStructuredDocument.getLength() > 0) {
+				newModel(new NewDocumentEvent(newStructuredDocument, this));
+			}
 			newStructuredDocument.addDocumentChangingListener(this);
+		}
 	}
 }
diff --git a/bundles/org.eclipse.wst.sse.core/src/org/eclipse/wst/sse/core/internal/model/ModelManagerImpl.java b/bundles/org.eclipse.wst.sse.core/src/org/eclipse/wst/sse/core/internal/model/ModelManagerImpl.java
index 7e8aee8..0ae8feb 100644
--- a/bundles/org.eclipse.wst.sse.core/src/org/eclipse/wst/sse/core/internal/model/ModelManagerImpl.java
+++ b/bundles/org.eclipse.wst.sse.core/src/org/eclipse/wst/sse/core/internal/model/ModelManagerImpl.java
@@ -1399,12 +1399,20 @@
 		if (sharedObject != null) {
 			sharedObject.referenceCountForEdit--;
 			if ((sharedObject.referenceCountForRead == 0) && (sharedObject.referenceCountForEdit == 0)) {
-				fManagedObjects.remove(id);
-				FileBufferModelManager.getInstance().releaseModel(sharedObject.theSharedModel.getStructuredDocument());
+				discardModel(id, sharedObject);
 			}
 		}
 	}
 
+	private void discardModel(Object id, SharedObject sharedObject) {
+		fManagedObjects.remove(id);
+		FileBufferModelManager.getInstance().releaseModel(sharedObject.theSharedModel.getStructuredDocument());
+		// setting the document to null is required since some subclasses 
+		// of model might have "cleanup" of listners, etc., to remove, 
+		// which were initialized during the intial setStructuredDocument
+		sharedObject.theSharedModel.setStructuredDocument(null);
+	}
+
 	/**
 	 * default for use in same package, not subclasses
 	 * 
@@ -1418,8 +1426,7 @@
 		if (sharedObject != null) {
 			sharedObject.referenceCountForRead--;
 			if ((sharedObject.referenceCountForRead == 0) && (sharedObject.referenceCountForEdit == 0)) {
-				fManagedObjects.remove(id);
-				FileBufferModelManager.getInstance().releaseModel(sharedObject.theSharedModel.getStructuredDocument());
+				discardModel(id, sharedObject);
 			}
 		}
 	}
diff --git a/bundles/org.eclipse.wst.xml.core/src/org/eclipse/wst/xml/core/internal/document/DOMModelImpl.java b/bundles/org.eclipse.wst.xml.core/src/org/eclipse/wst/xml/core/internal/document/DOMModelImpl.java
index f997151..172ef13 100644
--- a/bundles/org.eclipse.wst.xml.core/src/org/eclipse/wst/xml/core/internal/document/DOMModelImpl.java
+++ b/bundles/org.eclipse.wst.xml.core/src/org/eclipse/wst/xml/core/internal/document/DOMModelImpl.java
@@ -791,7 +791,7 @@
 	public void releaseFromEdit() {
 		if (!isShared()) {
 			// this.document.releaseStyleSheets();
-			//this.document.releaseDocumentType();
+			// this.document.releaseDocumentType();
 		}
 		super.releaseFromEdit();
 	}
@@ -801,7 +801,7 @@
 	public void releaseFromRead() {
 		if (!isShared()) {
 			// this.document.releaseStyleSheets();
-			//this.document.releaseDocumentType();
+			// this.document.releaseDocumentType();
 		}
 		super.releaseFromRead();
 	}
@@ -858,11 +858,12 @@
 		if (oldStructuredDocument != null)
 			oldStructuredDocument.removeDocumentChangingListener(this);
 		super.setStructuredDocument(structuredDocument);
-		if (structuredDocument.getLength() > 0) {
-			newModel(new NewDocumentEvent(structuredDocument, this));
-		}
-		if (structuredDocument != null)
+		if (structuredDocument != null) {
+			if (structuredDocument.getLength() > 0) {
+				newModel(new NewDocumentEvent(structuredDocument, this));
+			}
 			structuredDocument.addDocumentChangingListener(this);
+		}
 	}
 
 	/**