[88943] only enable folding for elements that span more than one line
diff --git a/bundles/org.eclipse.jst.jsp.ui/src/org/eclipse/jst/jsp/ui/internal/projection/ProjectionModelNodeAdapterHTML.java b/bundles/org.eclipse.jst.jsp.ui/src/org/eclipse/jst/jsp/ui/internal/projection/ProjectionModelNodeAdapterHTML.java
index 7f139c1..60a9501 100644
--- a/bundles/org.eclipse.jst.jsp.ui/src/org/eclipse/jst/jsp/ui/internal/projection/ProjectionModelNodeAdapterHTML.java
+++ b/bundles/org.eclipse.jst.jsp.ui/src/org/eclipse/jst/jsp/ui/internal/projection/ProjectionModelNodeAdapterHTML.java
@@ -22,10 +22,13 @@
 import org.eclipse.jface.text.source.projection.ProjectionAnnotation;
 import org.eclipse.jface.text.source.projection.ProjectionAnnotationModel;
 import org.eclipse.jface.text.source.projection.ProjectionViewer;
+import org.eclipse.swt.graphics.GC;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.widgets.Canvas;
+import org.eclipse.wst.html.ui.internal.Logger;
 import org.eclipse.wst.sse.core.INodeAdapter;
 import org.eclipse.wst.sse.core.INodeNotifier;
 import org.eclipse.wst.sse.core.IndexedRegion;
-import org.eclipse.wst.html.ui.internal.Logger;
 import org.w3c.dom.Node;
 
 /**
@@ -35,6 +38,7 @@
 public class ProjectionModelNodeAdapterHTML implements INodeAdapter {
 
 	private class TagProjectionAnnotation extends ProjectionAnnotation {
+		private boolean fIsVisible = false; /* workaround for BUG85874 */
 		private Node fNode;
 
 		public TagProjectionAnnotation(Node node, boolean isCollapsed) {
@@ -49,6 +53,48 @@
 		public void setNode(Node node) {
 			fNode = node;
 		}
+
+		/**
+		 * Does not paint hidden annotations. Annotations are hidden when they
+		 * only span one line.
+		 * 
+		 * @see ProjectionAnnotation#paint(org.eclipse.swt.graphics.GC,
+		 *      org.eclipse.swt.widgets.Canvas,
+		 *      org.eclipse.swt.graphics.Rectangle)
+		 */
+		public void paint(GC gc, Canvas canvas, Rectangle rectangle) {
+			/* workaround for BUG85874 */
+			/*
+			 * only need to check annotations that are expanded because hidden
+			 * annotations should never have been given the chance to
+			 * collapse.
+			 */
+			if (!isCollapsed()) {
+				// working with rectangle, so need the styledtext line height
+				int lineHeight = fAdapterFactory.getProjectionViewer().getTextWidget().getLineHeight();
+
+				// do not draw annotations that only span one line and mark
+				// them as not visible
+				if ((rectangle.height / lineHeight) <= 1) {
+					fIsVisible = false;
+					return;
+				}
+			}
+			fIsVisible = true;
+			super.paint(gc, canvas, rectangle);
+		}
+
+		/*
+		 * (non-Javadoc)
+		 * 
+		 * @see org.eclipse.jface.text.source.projection.ProjectionAnnotation#markCollapsed()
+		 */
+		public void markCollapsed() {
+			/* workaround for BUG85874 */
+			// do not mark collapsed if annotation is not visible
+			if (fIsVisible)
+				super.markCollapsed();
+		}
 	}
 
 	// copies of this class located in:
@@ -56,7 +102,7 @@
 	// org.eclipse.jst.jsp.ui.internal.projection
 	private final static boolean debugProjectionPerf = "true".equalsIgnoreCase(Platform.getDebugOption("org.eclipse.wst.html.ui/projectionperf")); //$NON-NLS-1$ //$NON-NLS-2$
 
-	private ProjectionModelNodeAdapterFactoryHTML fAdapterFactory;
+	ProjectionModelNodeAdapterFactoryHTML fAdapterFactory;
 	private Map fTagAnnotations = new HashMap();
 
 	public ProjectionModelNodeAdapterHTML(ProjectionModelNodeAdapterFactoryHTML factory) {
@@ -80,21 +126,30 @@
 				int end = inode.getEndOffset();
 				if (start >= 0 && start < end) {
 					try {
+//						// region-based
+//						// extra line when collapsed, but no region increase when add newline
+//						pos = new Position(start, end - start);
+						
+//						// line-based
+//						// extra line when collapsed, but no region increase when add newline
+//						IRegion startLineRegion = document.getLineInformationOfOffset(start);
+//						IRegion endLineRegion = document.getLineInformationOfOffset(end);
+//						int startOffset = startLineRegion.getOffset();
+//						int endOffset = endLineRegion.getOffset() + endLineRegion.getLength();
+//						if (endOffset > startOffset) {
+//							pos = new Position(startOffset, endOffset - startOffset);
+//						}
+						
+						// line-based
+						// no extra line when collapsed, but region increase when add newline
 						int startLine = document.getLineOfOffset(start);
 						int endLine = document.getLineOfOffset(end);
 						if (endLine + 1 < document.getNumberOfLines()) {
-							// projection_TODO allow only multi-line
-							// projection
-							// // check if projection start/end region is on
-							// the same line
-							// if (startLine < endLine) {
 							int offset = document.getLineOffset(startLine);
 							int endOffset = document.getLineOffset(endLine + 1);
 							pos = new Position(offset, endOffset - offset);
-							// }
 						}
-					} // }
-					catch (BadLocationException x) {
+					} catch (BadLocationException x) {
 						Logger.log(Logger.WARNING_DEBUG, null, x);
 					}
 				}
@@ -140,16 +195,6 @@
 		if ((eventType == INodeNotifier.STRUCTURE_CHANGED) && (notifier instanceof Node)) {
 			updateAdapter((Node) notifier);
 		}
-
-		// projection_TODO allow only multi-line projection
-		// if ((eventType == INodeNotifier.CONTENT_CHANGED) && (changedFeature
-		// instanceof Node)) {
-		// Node node = (Node) changedFeature;
-		// if (node.getNodeType() == Node.TEXT_NODE)
-		// node = node.getParentNode();
-		// if (node != null)
-		// updateOneNode(node);
-		// }
 	}
 
 	/**
@@ -179,8 +224,7 @@
 						projectionAnnotations.put(newAnnotation, newPos);
 						// add to map containing annotations to add
 						additions.put(newAnnotation, newPos);
-					}
-					else {
+					} else {
 						// add to map containing all annotations for this
 						// adapter
 						projectionAnnotations.put(existing, newPos);
@@ -216,25 +260,4 @@
 			System.out.println("ProjectionModelNodeAdapterHTML.updateAdapter (" + nodeName + "):" + (end - start));
 		}
 	}
-
-	// projection_TODO allow only multi-line projection
-	// private void updateOneNode(Node node) {
-	// TagProjectionAnnotation existing = getExistingAnnotation(node);
-	// if (isNodeProjectable(node)) {
-	// Position pos = createProjectionPosition(node);
-	// // if node > 1 line and not existing, create and add
-	// if (pos != null && existing == null) {
-	// TagProjectionAnnotation newAnnotation = new
-	// TagProjectionAnnotation(node, false);
-	// fAdapterFactory.getProjectionViewer().getProjectionAnnotationModel().addAnnotation(newAnnotation,
-	// pos);
-	// fTagAnnotations.put(newAnnotation, pos);
-	// }
-	// // if node == 1 line and existing, remove
-	// if (pos == null && existing != null) {
-	// fAdapterFactory.getProjectionViewer().getProjectionAnnotationModel().removeAnnotation(existing);
-	// fTagAnnotations.remove(existing);
-	// }
-	// }
-	// }
 }
diff --git a/bundles/org.eclipse.wst.css.ui/src/org/eclipse/wst/css/ui/internal/projection/ProjectionModelNodeAdapterCSS.java b/bundles/org.eclipse.wst.css.ui/src/org/eclipse/wst/css/ui/internal/projection/ProjectionModelNodeAdapterCSS.java
index cf3ee62..accb281 100644
--- a/bundles/org.eclipse.wst.css.ui/src/org/eclipse/wst/css/ui/internal/projection/ProjectionModelNodeAdapterCSS.java
+++ b/bundles/org.eclipse.wst.css.ui/src/org/eclipse/wst/css/ui/internal/projection/ProjectionModelNodeAdapterCSS.java
@@ -22,6 +22,9 @@
 import org.eclipse.jface.text.source.projection.ProjectionAnnotation;
 import org.eclipse.jface.text.source.projection.ProjectionAnnotationModel;
 import org.eclipse.jface.text.source.projection.ProjectionViewer;
+import org.eclipse.swt.graphics.GC;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.widgets.Canvas;
 import org.eclipse.wst.css.core.document.ICSSNode;
 import org.eclipse.wst.sse.core.INodeAdapter;
 import org.eclipse.wst.sse.core.INodeNotifier;
@@ -35,6 +38,7 @@
 public class ProjectionModelNodeAdapterCSS implements INodeAdapter {
 
 	private class TagProjectionAnnotation extends ProjectionAnnotation {
+		private boolean fIsVisible = false; /* workaround for BUG85874 */
 		private ICSSNode fNode;
 
 		public TagProjectionAnnotation(ICSSNode node, boolean isCollapsed) {
@@ -49,11 +53,52 @@
 		public void setNode(ICSSNode node) {
 			fNode = node;
 		}
+		/**
+		 * Does not paint hidden annotations. Annotations are hidden when they
+		 * only span one line.
+		 * 
+		 * @see ProjectionAnnotation#paint(org.eclipse.swt.graphics.GC,
+		 *      org.eclipse.swt.widgets.Canvas,
+		 *      org.eclipse.swt.graphics.Rectangle)
+		 */
+		public void paint(GC gc, Canvas canvas, Rectangle rectangle) {
+			/* workaround for BUG85874 */
+			/*
+			 * only need to check annotations that are expanded because hidden
+			 * annotations should never have been given the chance to
+			 * collapse.
+			 */
+			if (!isCollapsed()) {
+				// working with rectangle, so need the styledtext line height
+				int lineHeight = fAdapterFactory.getProjectionViewer().getTextWidget().getLineHeight();
+
+				// do not draw annotations that only span one line and mark
+				// them as not visible
+				if ((rectangle.height / lineHeight) <= 1) {
+					fIsVisible = false;
+					return;
+				}
+			}
+			fIsVisible = true;
+			super.paint(gc, canvas, rectangle);
+		}
+
+		/*
+		 * (non-Javadoc)
+		 * 
+		 * @see org.eclipse.jface.text.source.projection.ProjectionAnnotation#markCollapsed()
+		 */
+		public void markCollapsed() {
+			/* workaround for BUG85874 */
+			// do not mark collapsed if annotation is not visible
+			if (fIsVisible)
+				super.markCollapsed();
+		}
 	}
 
 	private final static boolean debugProjectionPerf = "true".equalsIgnoreCase(Platform.getDebugOption("org.eclipse.wst.css.ui/projectionperf")); //$NON-NLS-1$ //$NON-NLS-2$\
 
-	private ProjectionModelNodeAdapterFactoryCSS fAdapterFactory;
+	ProjectionModelNodeAdapterFactoryCSS fAdapterFactory;
 	private Map fTagAnnotations = new HashMap();
 
 	public ProjectionModelNodeAdapterCSS(ProjectionModelNodeAdapterFactoryCSS factory) {
@@ -77,21 +122,30 @@
 				int end = inode.getEndOffset();
 				if (start >= 0 && start < end) {
 					try {
+//						// region-based
+//						// extra line when collapsed, but no region increase when add newline
+//						pos = new Position(start, end - start);
+						
+//						// line-based
+//						// extra line when collapsed, but no region increase when add newline
+//						IRegion startLineRegion = document.getLineInformationOfOffset(start);
+//						IRegion endLineRegion = document.getLineInformationOfOffset(end);
+//						int startOffset = startLineRegion.getOffset();
+//						int endOffset = endLineRegion.getOffset() + endLineRegion.getLength();
+//						if (endOffset > startOffset) {
+//							pos = new Position(startOffset, endOffset - startOffset);
+//						}
+						
+						// line-based
+						// no extra line when collapsed, but region increase when add newline
 						int startLine = document.getLineOfOffset(start);
 						int endLine = document.getLineOfOffset(end);
 						if (endLine + 1 < document.getNumberOfLines()) {
-							// projection_TODO allow only multi-line
-							// projection
-							// // check if projection start/end region is on
-							// the same line
-							// if (startLine < endLine) {
 							int offset = document.getLineOffset(startLine);
 							int endOffset = document.getLineOffset(endLine + 1);
 							pos = new Position(offset, endOffset - offset);
-							// }
 						}
-					} // }
-					catch (BadLocationException x) {
+					} catch (BadLocationException x) {
 						Logger.log(Logger.WARNING_DEBUG, null, x);
 					}
 				}
@@ -156,16 +210,6 @@
 		if ((eventType == INodeNotifier.ADD || eventType == INodeNotifier.REMOVE) && (notifier instanceof ICSSNode)) {
 			updateAdapter((ICSSNode) notifier);
 		}
-
-		// projection_TODO allow only multi-line projection
-		// if ((eventType == INodeNotifier.CONTENT_CHANGED) && (changedFeature
-		// instanceof Node)) {
-		// Node node = (Node) changedFeature;
-		// if (node.getNodeType() == Node.TEXT_NODE)
-		// node = node.getParentNode();
-		// if (node != null)
-		// updateOneNode(node);
-		// }
 	}
 
 	/**
@@ -195,8 +239,7 @@
 						projectionAnnotations.put(newAnnotation, newPos);
 						// add to map containing annotations to add
 						additions.put(newAnnotation, newPos);
-					}
-					else {
+					} else {
 						// add to map containing all annotations for this
 						// adapter
 						projectionAnnotations.put(existing, newPos);
@@ -232,25 +275,4 @@
 			System.out.println("ProjectionModelNodeAdapterCSS.updateAdapter (" + nodeName + "):" + (end - start));
 		}
 	}
-
-	// projection_TODO allow only multi-line projection
-	// private void updateOneNode(Node node) {
-	// TagProjectionAnnotation existing = getExistingAnnotation(node);
-	// if (isNodeProjectable(node)) {
-	// Position pos = createProjectionPosition(node);
-	// // if node > 1 line and not existing, create and add
-	// if (pos != null && existing == null) {
-	// TagProjectionAnnotation newAnnotation = new
-	// TagProjectionAnnotation(node, false);
-	// fAdapterFactory.getProjectionViewer().getProjectionAnnotationModel().addAnnotation(newAnnotation,
-	// pos);
-	// fTagAnnotations.put(newAnnotation, pos);
-	// }
-	// // if node == 1 line and existing, remove
-	// if (pos == null && existing != null) {
-	// fAdapterFactory.getProjectionViewer().getProjectionAnnotationModel().removeAnnotation(existing);
-	// fTagAnnotations.remove(existing);
-	// }
-	// }
-	// }
 }
diff --git a/bundles/org.eclipse.wst.html.ui/src/org/eclipse/wst/html/ui/internal/projection/ProjectionModelNodeAdapterHTML.java b/bundles/org.eclipse.wst.html.ui/src/org/eclipse/wst/html/ui/internal/projection/ProjectionModelNodeAdapterHTML.java
index 69e4961..621132f 100644
--- a/bundles/org.eclipse.wst.html.ui/src/org/eclipse/wst/html/ui/internal/projection/ProjectionModelNodeAdapterHTML.java
+++ b/bundles/org.eclipse.wst.html.ui/src/org/eclipse/wst/html/ui/internal/projection/ProjectionModelNodeAdapterHTML.java
@@ -22,6 +22,9 @@
 import org.eclipse.jface.text.source.projection.ProjectionAnnotation;
 import org.eclipse.jface.text.source.projection.ProjectionAnnotationModel;
 import org.eclipse.jface.text.source.projection.ProjectionViewer;
+import org.eclipse.swt.graphics.GC;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.widgets.Canvas;
 import org.eclipse.wst.sse.core.INodeAdapter;
 import org.eclipse.wst.sse.core.INodeNotifier;
 import org.eclipse.wst.sse.core.IndexedRegion;
@@ -35,6 +38,7 @@
 public class ProjectionModelNodeAdapterHTML implements INodeAdapter {
 
 	private class TagProjectionAnnotation extends ProjectionAnnotation {
+		private boolean fIsVisible = false; /* workaround for BUG85874 */
 		private Node fNode;
 
 		public TagProjectionAnnotation(Node node, boolean isCollapsed) {
@@ -49,6 +53,48 @@
 		public void setNode(Node node) {
 			fNode = node;
 		}
+
+		/**
+		 * Does not paint hidden annotations. Annotations are hidden when they
+		 * only span one line.
+		 * 
+		 * @see ProjectionAnnotation#paint(org.eclipse.swt.graphics.GC,
+		 *      org.eclipse.swt.widgets.Canvas,
+		 *      org.eclipse.swt.graphics.Rectangle)
+		 */
+		public void paint(GC gc, Canvas canvas, Rectangle rectangle) {
+			/* workaround for BUG85874 */
+			/*
+			 * only need to check annotations that are expanded because hidden
+			 * annotations should never have been given the chance to
+			 * collapse.
+			 */
+			if (!isCollapsed()) {
+				// working with rectangle, so need the styledtext line height
+				int lineHeight = fAdapterFactory.getProjectionViewer().getTextWidget().getLineHeight();
+
+				// do not draw annotations that only span one line and mark
+				// them as not visible
+				if ((rectangle.height / lineHeight) <= 1) {
+					fIsVisible = false;
+					return;
+				}
+			}
+			fIsVisible = true;
+			super.paint(gc, canvas, rectangle);
+		}
+
+		/*
+		 * (non-Javadoc)
+		 * 
+		 * @see org.eclipse.jface.text.source.projection.ProjectionAnnotation#markCollapsed()
+		 */
+		public void markCollapsed() {
+			/* workaround for BUG85874 */
+			// do not mark collapsed if annotation is not visible
+			if (fIsVisible)
+				super.markCollapsed();
+		}
 	}
 
 	// copies of this class located in:
@@ -56,7 +102,7 @@
 	// org.eclipse.jst.jsp.ui.internal.projection
 	private final static boolean debugProjectionPerf = "true".equalsIgnoreCase(Platform.getDebugOption("org.eclipse.wst.html.ui/projectionperf")); //$NON-NLS-1$ //$NON-NLS-2$
 
-	private ProjectionModelNodeAdapterFactoryHTML fAdapterFactory;
+	ProjectionModelNodeAdapterFactoryHTML fAdapterFactory;
 	private Map fTagAnnotations = new HashMap();
 
 	public ProjectionModelNodeAdapterHTML(ProjectionModelNodeAdapterFactoryHTML factory) {
@@ -80,21 +126,30 @@
 				int end = inode.getEndOffset();
 				if (start >= 0 && start < end) {
 					try {
+//						// region-based
+//						// extra line when collapsed, but no region increase when add newline
+//						pos = new Position(start, end - start);
+						
+//						// line-based
+//						// extra line when collapsed, but no region increase when add newline
+//						IRegion startLineRegion = document.getLineInformationOfOffset(start);
+//						IRegion endLineRegion = document.getLineInformationOfOffset(end);
+//						int startOffset = startLineRegion.getOffset();
+//						int endOffset = endLineRegion.getOffset() + endLineRegion.getLength();
+//						if (endOffset > startOffset) {
+//							pos = new Position(startOffset, endOffset - startOffset);
+//						}
+						
+						// line-based
+						// no extra line when collapsed, but region increase when add newline
 						int startLine = document.getLineOfOffset(start);
 						int endLine = document.getLineOfOffset(end);
 						if (endLine + 1 < document.getNumberOfLines()) {
-							// projection_TODO allow only multi-line
-							// projection
-							// // check if projection start/end region is on
-							// the same line
-							// if (startLine < endLine) {
 							int offset = document.getLineOffset(startLine);
 							int endOffset = document.getLineOffset(endLine + 1);
 							pos = new Position(offset, endOffset - offset);
-							// }
 						}
-					} // }
-					catch (BadLocationException x) {
+					} catch (BadLocationException x) {
 						Logger.log(Logger.WARNING_DEBUG, null, x);
 					}
 				}
@@ -140,16 +195,6 @@
 		if ((eventType == INodeNotifier.STRUCTURE_CHANGED) && (notifier instanceof Node)) {
 			updateAdapter((Node) notifier);
 		}
-
-		// projection_TODO allow only multi-line projection
-		// if ((eventType == INodeNotifier.CONTENT_CHANGED) && (changedFeature
-		// instanceof Node)) {
-		// Node node = (Node) changedFeature;
-		// if (node.getNodeType() == Node.TEXT_NODE)
-		// node = node.getParentNode();
-		// if (node != null)
-		// updateOneNode(node);
-		// }
 	}
 
 	/**
@@ -179,8 +224,7 @@
 						projectionAnnotations.put(newAnnotation, newPos);
 						// add to map containing annotations to add
 						additions.put(newAnnotation, newPos);
-					}
-					else {
+					} else {
 						// add to map containing all annotations for this
 						// adapter
 						projectionAnnotations.put(existing, newPos);
@@ -216,25 +260,4 @@
 			System.out.println("ProjectionModelNodeAdapterHTML.updateAdapter (" + nodeName + "):" + (end - start));
 		}
 	}
-
-	// projection_TODO allow only multi-line projection
-	// private void updateOneNode(Node node) {
-	// TagProjectionAnnotation existing = getExistingAnnotation(node);
-	// if (isNodeProjectable(node)) {
-	// Position pos = createProjectionPosition(node);
-	// // if node > 1 line and not existing, create and add
-	// if (pos != null && existing == null) {
-	// TagProjectionAnnotation newAnnotation = new
-	// TagProjectionAnnotation(node, false);
-	// fAdapterFactory.getProjectionViewer().getProjectionAnnotationModel().addAnnotation(newAnnotation,
-	// pos);
-	// fTagAnnotations.put(newAnnotation, pos);
-	// }
-	// // if node == 1 line and existing, remove
-	// if (pos == null && existing != null) {
-	// fAdapterFactory.getProjectionViewer().getProjectionAnnotationModel().removeAnnotation(existing);
-	// fTagAnnotations.remove(existing);
-	// }
-	// }
-	// }
 }
diff --git a/bundles/org.eclipse.wst.xml.ui/src/org/eclipse/wst/xml/ui/internal/projection/ProjectionModelNodeAdapterXML.java b/bundles/org.eclipse.wst.xml.ui/src/org/eclipse/wst/xml/ui/internal/projection/ProjectionModelNodeAdapterXML.java
index 043135b..7817f0d 100644
--- a/bundles/org.eclipse.wst.xml.ui/src/org/eclipse/wst/xml/ui/internal/projection/ProjectionModelNodeAdapterXML.java
+++ b/bundles/org.eclipse.wst.xml.ui/src/org/eclipse/wst/xml/ui/internal/projection/ProjectionModelNodeAdapterXML.java
@@ -22,6 +22,9 @@
 import org.eclipse.jface.text.source.projection.ProjectionAnnotation;
 import org.eclipse.jface.text.source.projection.ProjectionAnnotationModel;
 import org.eclipse.jface.text.source.projection.ProjectionViewer;
+import org.eclipse.swt.graphics.GC;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.widgets.Canvas;
 import org.eclipse.wst.sse.core.INodeAdapter;
 import org.eclipse.wst.sse.core.INodeNotifier;
 import org.eclipse.wst.sse.core.IndexedRegion;
@@ -35,6 +38,7 @@
 public class ProjectionModelNodeAdapterXML implements INodeAdapter {
 
 	private class TagProjectionAnnotation extends ProjectionAnnotation {
+		private boolean fIsVisible = false; /* workaround for BUG85874 */
 		private Node fNode;
 
 		public TagProjectionAnnotation(Node node, boolean isCollapsed) {
@@ -49,11 +53,53 @@
 		public void setNode(Node node) {
 			fNode = node;
 		}
+		
+		/**
+		 * Does not paint hidden annotations. Annotations are hidden when they
+		 * only span one line.
+		 * 
+		 * @see ProjectionAnnotation#paint(org.eclipse.swt.graphics.GC,
+		 *      org.eclipse.swt.widgets.Canvas,
+		 *      org.eclipse.swt.graphics.Rectangle)
+		 */
+		public void paint(GC gc, Canvas canvas, Rectangle rectangle) {
+			/* workaround for BUG85874 */
+			/*
+			 * only need to check annotations that are expanded because hidden
+			 * annotations should never have been given the chance to
+			 * collapse.
+			 */
+			if (!isCollapsed()) {
+				// working with rectangle, so need the styledtext line height
+				int lineHeight = fAdapterFactory.getProjectionViewer().getTextWidget().getLineHeight();
+
+				// do not draw annotations that only span one line and mark
+				// them as not visible
+				if ((rectangle.height / lineHeight) <= 1) {
+					fIsVisible = false;
+					return;
+				}
+			}
+			fIsVisible = true;
+			super.paint(gc, canvas, rectangle);
+		}
+
+		/*
+		 * (non-Javadoc)
+		 * 
+		 * @see org.eclipse.jface.text.source.projection.ProjectionAnnotation#markCollapsed()
+		 */
+		public void markCollapsed() {
+			/* workaround for BUG85874 */
+			// do not mark collapsed if annotation is not visible
+			if (fIsVisible)
+				super.markCollapsed();
+		}
 	}
 
 	private final static boolean debugProjectionPerf = "true".equalsIgnoreCase(Platform.getDebugOption("org.eclipse.wst.xml.ui/projectionperf")); //$NON-NLS-1$ //$NON-NLS-2$
 
-	private ProjectionModelNodeAdapterFactoryXML fAdapterFactory;
+	ProjectionModelNodeAdapterFactoryXML fAdapterFactory;
 	private Map fTagAnnotations = new HashMap();
 
 	public ProjectionModelNodeAdapterXML(ProjectionModelNodeAdapterFactoryXML factory) {
@@ -77,21 +123,30 @@
 				int end = inode.getEndOffset();
 				if (start >= 0 && start < end) {
 					try {
+//						// region-based
+//						// extra line when collapsed, but no region increase when add newline
+//						pos = new Position(start, end - start);
+						
+//						// line-based
+//						// extra line when collapsed, but no region increase when add newline
+//						IRegion startLineRegion = document.getLineInformationOfOffset(start);
+//						IRegion endLineRegion = document.getLineInformationOfOffset(end);
+//						int startOffset = startLineRegion.getOffset();
+//						int endOffset = endLineRegion.getOffset() + endLineRegion.getLength();
+//						if (endOffset > startOffset) {
+//							pos = new Position(startOffset, endOffset - startOffset);
+//						}
+						
+						// line-based
+						// no extra line when collapsed, but region increase when add newline
 						int startLine = document.getLineOfOffset(start);
 						int endLine = document.getLineOfOffset(end);
 						if (endLine + 1 < document.getNumberOfLines()) {
-							// projection_TODO allow only multi-line
-							// projection
-							// // check if projection start/end region is on
-							// the same line
-							// if (startLine < endLine) {
 							int offset = document.getLineOffset(startLine);
 							int endOffset = document.getLineOffset(endLine + 1);
 							pos = new Position(offset, endOffset - offset);
-							// }
 						}
-					} // }
-					catch (BadLocationException x) {
+					} catch (BadLocationException x) {
 						Logger.log(Logger.WARNING_DEBUG, null, x);
 					}
 				}
@@ -150,16 +205,6 @@
 		if ((eventType == INodeNotifier.STRUCTURE_CHANGED) && (notifier instanceof Node)) {
 			updateAdapter((Node) notifier);
 		}
-
-		// projection_TODO allow only multi-line projection
-		// if ((eventType == INodeNotifier.CONTENT_CHANGED) && (changedFeature
-		// instanceof Node)) {
-		// Node node = (Node) changedFeature;
-		// if (node.getNodeType() == Node.TEXT_NODE)
-		// node = node.getParentNode();
-		// if (node != null)
-		// updateOneNode(node);
-		// }
 	}
 
 	/**
@@ -189,8 +234,7 @@
 						projectionAnnotations.put(newAnnotation, newPos);
 						// add to map containing annotations to add
 						additions.put(newAnnotation, newPos);
-					}
-					else {
+					} else {
 						// add to map containing all annotations for this
 						// adapter
 						projectionAnnotations.put(existing, newPos);
@@ -226,25 +270,4 @@
 			System.out.println("ProjectionModelNodeAdapterXML.updateAdapter (" + nodeName + "):" + (end - start));
 		}
 	}
-
-	// projection_TODO allow only multi-line projection
-	// private void updateOneNode(Node node) {
-	// TagProjectionAnnotation existing = getExistingAnnotation(node);
-	// if (isNodeProjectable(node)) {
-	// Position pos = createProjectionPosition(node);
-	// // if node > 1 line and not existing, create and add
-	// if (pos != null && existing == null) {
-	// TagProjectionAnnotation newAnnotation = new
-	// TagProjectionAnnotation(node, false);
-	// fAdapterFactory.getProjectionViewer().getProjectionAnnotationModel().addAnnotation(newAnnotation,
-	// pos);
-	// fTagAnnotations.put(newAnnotation, pos);
-	// }
-	// // if node == 1 line and existing, remove
-	// if (pos == null && existing != null) {
-	// fAdapterFactory.getProjectionViewer().getProjectionAnnotationModel().removeAnnotation(existing);
-	// fTagAnnotations.remove(existing);
-	// }
-	// }
-	// }
 }