merged from HEAD (TCL html::author documentation bug)
diff --git a/tcl/plugins/org.eclipse.dltk.tcl.ui/src/org/eclipse/dltk/tcl/internal/ui/documentation/TclCommentDocumentationProvider.java b/tcl/plugins/org.eclipse.dltk.tcl.ui/src/org/eclipse/dltk/tcl/internal/ui/documentation/TclCommentDocumentationProvider.java
index 20de05a..70edf65 100644
--- a/tcl/plugins/org.eclipse.dltk.tcl.ui/src/org/eclipse/dltk/tcl/internal/ui/documentation/TclCommentDocumentationProvider.java
+++ b/tcl/plugins/org.eclipse.dltk.tcl.ui/src/org/eclipse/dltk/tcl/internal/ui/documentation/TclCommentDocumentationProvider.java
@@ -11,6 +11,8 @@
 
 import java.io.Reader;
 import java.io.StringReader;
+import java.util.ArrayList;
+import java.util.List;
 
 import org.eclipse.dltk.core.IBuffer;
 import org.eclipse.dltk.core.IMember;
@@ -18,17 +20,20 @@
 import org.eclipse.dltk.core.ISourceRange;
 import org.eclipse.dltk.core.ModelException;
 import org.eclipse.dltk.ui.documentation.IScriptDocumentationProvider;
+import org.eclipse.dltk.utils.TextUtils;
 import org.eclipse.jface.text.BadLocationException;
 import org.eclipse.jface.text.Document;
 
-public class TclCommentDocumentationProvider extends
-		ScriptDocumentationProvider implements IScriptDocumentationProvider {
+public class TclCommentDocumentationProvider implements
+		IScriptDocumentationProvider {
+
+	private static final char COMMENT_SIGN = '#';
 
 	protected String getLine(Document d, int line) throws BadLocationException {
 		return d.get(d.getLineOffset(line), d.getLineLength(line));
 	}
 
-	protected String getHeaderComment(IMember member) {
+	protected List getHeaderComment(IMember member) {
 		// if (member instanceof IField) {
 		// return null;
 		// }
@@ -55,77 +60,100 @@
 				contents = member.getSourceModule().getSource();
 			}
 
-			String result = "";
-
 			Document doc = new Document(contents);
 			try {
 				int line = doc.getLineOfOffset(start);
-				line--;
-				if (line < 0)
-					return null;
-				boolean emptyEnd = true;
-				while (line >= 0) {
-					String curLine = getLine(doc, line);
-					String curLineTrimmed = curLine.trim();
-					if ((curLineTrimmed.length() == 0 && emptyEnd)
-							|| curLineTrimmed.startsWith("#")) {
-						if (curLineTrimmed.length() != 0)
-							emptyEnd = false;
-						result = curLine + result;
-					} else
-						break;
-
-					line--;
+				--line; // look on the previous line
+				if (line >= 0) {
+					final List result = new ArrayList();
+					do {
+						final String curLine = getLine(doc, line).trim();
+						if (curLine.length() > 0
+								&& curLine.charAt(0) == COMMENT_SIGN) {
+							result.add(0, curLine);
+						} else if (!(curLine.length() == 0 && result.isEmpty())) {
+							// skip empty lines between comment and code only
+							break;
+						}
+					} while (--line >= 0);
+					return result;
 				}
 			} catch (BadLocationException e) {
-				return null;
+				// ignore
 			}
 
-			return result;
-
 		} catch (ModelException e) {
+			// ignore
 		}
 		return null;
 	}
 
 	public Reader getInfo(IMember member, boolean lookIntoParents,
 			boolean lookIntoExternal) {
-		String header = getHeaderComment(member);
-		return new StringReader(convertToHTML(header));
+		final List header = getHeaderComment(member);
+		if (header != null && !header.isEmpty()) {
+			return new StringReader(convertToHTML(header));
+		} else {
+			return null;
+		}
 	}
 
-	protected String convertToHTML(String header) {
-		StringBuffer result = new StringBuffer();
-		// result.append("<p>\n");
-		Document d = new Document(header);
-		for (int line = 0;; line++) {
-			try {
-				String str = getLine(d, line).trim();
-				if (str == null)
-					break;
-				while (str.length() > 0 && str.startsWith("#"))
-					str = str.substring(1);
-				while (str.length() > 0 && str.endsWith("#"))
-					str = str.substring(0, str.length() - 1);
-				if (str.length() == 0)
-					result.append("<p>");
-				else {
-					if (str.trim().matches("\\w*:")) {
-						result.append("<h4>");
-						result.append(str);
-						result.append("</h4>");
-					} else
-						result.append(str + "<br>");
-				}
-			} catch (BadLocationException e) {
-				break;
+	protected String convertToHTML(List header) {
+		final StringBuffer result = new StringBuffer();
+		boolean paragraphStarted = false;
+		for (int line = 0; line < header.size(); line++) {
+			String str = (String) header.get(line);
+			int begin = 0;
+			int end = str.length();
+			while (begin < end && str.charAt(begin) == COMMENT_SIGN) {
+				++begin;
 			}
-
+			while (begin < end && Character.isWhitespace(str.charAt(begin))) {
+				++begin;
+			}
+			while (begin < end && str.charAt(end - 1) == COMMENT_SIGN) {
+				--end;
+			}
+			while (begin < end && Character.isWhitespace(str.charAt(end - 1))) {
+				--end;
+			}
+			if (begin == end) {
+				if (paragraphStarted) {
+					result.append(P_END);
+					paragraphStarted = false;
+				}
+			} else {
+				str = str.substring(begin, end);
+				if (str.matches("\\w+(\\s+\\w+)*:")) { //$NON-NLS-1$
+					if (paragraphStarted) {
+						result.append(P_END);
+						paragraphStarted = false;
+					}
+					result.append("<h4>"); //$NON-NLS-1$
+					result.append(TextUtils.escapeHTML(str));
+					result.append("</h4>\n"); //$NON-NLS-1$
+				} else {
+					if (!paragraphStarted) {
+						result.append(P_BEGIN);
+						paragraphStarted = true;
+					} else {
+						result.append(LINE_BREAK);
+					}
+					result.append(TextUtils.escapeHTML(str));
+				}
+			}
 		}
-		// result.append("</p>\n");
+		if (paragraphStarted) {
+			result.append(P_END);
+		}
 		return result.toString();
 	}
 
+	private static final String P_BEGIN = "<p>"; //$NON-NLS-1$
+	private static final String P_END = "</p>"; //$NON-NLS-1$
+
+	private static final String LINE_BREAK = "<br>\n"; //$NON-NLS-1$
+
 	public Reader getInfo(String content) {
 		return null;
 	}