Sophie

Sophie

distrib > * > 2008.0 > x86_64 > by-pkgid > d061baaa6d8251d8c45491c96ae2d045 > files > 1

eclipse-phpeclipse-1.1.8-16.4.2mdv2008.0.src.rpm

Index: src/net/sourceforge/phpdt/internal/compiler/parser/Scanner.java
===================================================================
RCS file: /cvsroot/phpeclipse/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/parser/Scanner.java,v
retrieving revision 1.58
diff -u -r1.58 Scanner.java
--- src/net/sourceforge/phpdt/internal/compiler/parser/Scanner.java	23 Jan 2006 19:04:11 -0000	1.58
+++ src/net/sourceforge/phpdt/internal/compiler/parser/Scanner.java	11 Aug 2006 17:59:55 -0000
@@ -3054,50 +3054,42 @@
 				// as
 				if ((data[++index] == 's')) {
 					return TokenNameas;
-				} else {
-					return TokenNameIdentifier;
 				}
+				return TokenNameIdentifier;
 			case 3:
 				// and
 				if ((data[++index] == 'n') && (data[++index] == 'd')) {
 					return TokenNameand;
-				} else {
-					return TokenNameIdentifier;
 				}
+				return TokenNameIdentifier;
 			case 5:
 				// array
 				if ((data[++index] == 'r') && (data[++index] == 'r') && (data[++index] == 'a') && (data[++index] == 'y'))
 					return TokenNamearray;
-				else
-					return TokenNameIdentifier;
+				return TokenNameIdentifier;
 			case 8:
 				if ((data[++index] == 'b') && (data[++index] == 's') && (data[++index] == 't') && (data[++index] == 'r')
 						&& (data[++index] == 'a') && (data[++index] == 'c') && (data[++index] == 't'))
 					return TokenNameabstract;
-				else
-					return TokenNameIdentifier;
-			default:
 				return TokenNameIdentifier;
 			}
+			return TokenNameIdentifier;
 		case 'b':
 			// break
 			switch (length) {
 			case 5:
 				if ((data[++index] == 'r') && (data[++index] == 'e') && (data[++index] == 'a') && (data[++index] == 'k'))
 					return TokenNamebreak;
-				else
-					return TokenNameIdentifier;
-			default:
 				return TokenNameIdentifier;
 			}
+			return TokenNameIdentifier;
 		case 'c':
 			// case catch class clone const continue
 			switch (length) {
 			case 4:
 				if ((data[++index] == 'a') && (data[++index] == 's') && (data[++index] == 'e'))
 					return TokenNamecase;
-				else
-					return TokenNameIdentifier;
+				return TokenNameIdentifier;
 			case 5:
 				if ((data[++index] == 'a') && (data[++index] == 't') && (data[++index] == 'c') && (data[++index] == 'h'))
 					return TokenNamecatch;
@@ -3110,17 +3102,14 @@
 				index = 0;
 				if ((data[++index] == 'o') && (data[++index] == 'n') && (data[++index] == 's') && (data[++index] == 't'))
 					return TokenNameconst;
-				else
-					return TokenNameIdentifier;
+				return TokenNameIdentifier;
 			case 8:
 				if ((data[++index] == 'o') && (data[++index] == 'n') && (data[++index] == 't') && (data[++index] == 'i')
 						&& (data[++index] == 'n') && (data[++index] == 'u') && (data[++index] == 'e'))
 					return TokenNamecontinue;
-				else
-					return TokenNameIdentifier;
-			default:
 				return TokenNameIdentifier;
 			}
+			return TokenNameIdentifier;
 		case 'd':
 			// declare default do die
 			// TODO delete define ==> no keyword !
@@ -3128,8 +3117,7 @@
 			case 2:
 				if ((data[++index] == 'o'))
 					return TokenNamedo;
-				else
-					return TokenNameIdentifier;
+				return TokenNameIdentifier;
 			// case 6 :
 			// if ((data[++index] == 'e')
 			// && (data[++index] == 'f')
@@ -3147,11 +3135,9 @@
 				if ((data[++index] == 'e') && (data[++index] == 'f') && (data[++index] == 'a') && (data[++index] == 'u')
 						&& (data[++index] == 'l') && (data[++index] == 't'))
 					return TokenNamedefault;
-				else
-					return TokenNameIdentifier;
-			default:
 				return TokenNameIdentifier;
 			}
+			return TokenNameIdentifier;
 		case 'e':
 			// echo else exit elseif extends eval
 			switch (length) {
@@ -3164,16 +3150,14 @@
 					return TokenNameexit;
 				else if ((data[index] == 'v') && (data[++index] == 'a') && (data[++index] == 'l'))
 					return TokenNameeval;
-				else
-					return TokenNameIdentifier;
+				return TokenNameIdentifier;
 			case 5:
 				// endif empty
 				if ((data[++index] == 'n') && (data[++index] == 'd') && (data[++index] == 'i') && (data[++index] == 'f'))
 					return TokenNameendif;
 				if ((data[index] == 'm') && (data[++index] == 'p') && (data[++index] == 't') && (data[++index] == 'y'))
 					return TokenNameempty;
-				else
-					return TokenNameIdentifier;
+				return TokenNameIdentifier;
 			case 6:
 				// endfor
 				if ((data[++index] == 'n') && (data[++index] == 'd') && (data[++index] == 'f') && (data[++index] == 'o')
@@ -3182,28 +3166,24 @@
 				else if ((data[index] == 'l') && (data[++index] == 's') && (data[++index] == 'e') && (data[++index] == 'i')
 						&& (data[++index] == 'f'))
 					return TokenNameelseif;
-				else
-					return TokenNameIdentifier;
+				return TokenNameIdentifier;
 			case 7:
 				if ((data[++index] == 'x') && (data[++index] == 't') && (data[++index] == 'e') && (data[++index] == 'n')
 						&& (data[++index] == 'd') && (data[++index] == 's'))
 					return TokenNameextends;
-				else
-					return TokenNameIdentifier;
+				return TokenNameIdentifier;
 			case 8:
 				// endwhile
 				if ((data[++index] == 'n') && (data[++index] == 'd') && (data[++index] == 'w') && (data[++index] == 'h')
 						&& (data[++index] == 'i') && (data[++index] == 'l') && (data[++index] == 'e'))
 					return TokenNameendwhile;
-				else
-					return TokenNameIdentifier;
+				return TokenNameIdentifier;
 			case 9:
 				// endswitch
 				if ((data[++index] == 'n') && (data[++index] == 'd') && (data[++index] == 's') && (data[++index] == 'w')
 						&& (data[++index] == 'i') && (data[++index] == 't') && (data[++index] == 'c') && (data[++index] == 'h'))
 					return TokenNameendswitch;
-				else
-					return TokenNameIdentifier;
+				return TokenNameIdentifier;
 			case 10:
 				// enddeclare
 				if ((data[++index] == 'n') && (data[++index] == 'd') && (data[++index] == 'd') && (data[++index] == 'e')
@@ -3215,44 +3195,37 @@
 						&& (data[++index] == 'd') && (data[++index] == 'f') && (data[++index] == 'o') && (data[++index] == 'r')
 						&& (data[++index] == 'e') && (data[++index] == 'a') && (data[++index] == 'c') && (data[++index] == 'h'))
 					return TokenNameendforeach;
-				else
-					return TokenNameIdentifier;
-			default:
 				return TokenNameIdentifier;
 			}
+			return TokenNameIdentifier;
 		case 'f':
 			// for false final function
 			switch (length) {
 			case 3:
 				if ((data[++index] == 'o') && (data[++index] == 'r'))
 					return TokenNamefor;
-				else
-					return TokenNameIdentifier;
+				return TokenNameIdentifier;
 			case 5:
 				// if ((data[++index] == 'a') && (data[++index] == 'l')
 				// && (data[++index] == 's') && (data[++index] == 'e'))
 				// return TokenNamefalse;
 				if ((data[++index] == 'i') && (data[++index] == 'n') && (data[++index] == 'a') && (data[++index] == 'l'))
 					return TokenNamefinal;
-				else
-					return TokenNameIdentifier;
+				return TokenNameIdentifier;
 			case 7:
 				// foreach
 				if ((data[++index] == 'o') && (data[++index] == 'r') && (data[++index] == 'e') && (data[++index] == 'a')
 						&& (data[++index] == 'c') && (data[++index] == 'h'))
 					return TokenNameforeach;
-				else
-					return TokenNameIdentifier;
+				return TokenNameIdentifier;
 			case 8:
 				// function
 				if ((data[++index] == 'u') && (data[++index] == 'n') && (data[++index] == 'c') && (data[++index] == 't')
 						&& (data[++index] == 'i') && (data[++index] == 'o') && (data[++index] == 'n'))
 					return TokenNamefunction;
-				else
-					return TokenNameIdentifier;
-			default:
 				return TokenNameIdentifier;
 			}
+			return TokenNameIdentifier;
 		case 'g':
 			// global
 			if (length == 6) {
@@ -3268,8 +3241,7 @@
 			case 2:
 				if (data[++index] == 'f')
 					return TokenNameif;
-				else
-					return TokenNameIdentifier;
+				return TokenNameIdentifier;
 			// case 3 :
 			// if ((data[++index] == 'n') && (data[++index] == 't'))
 			// return TokenNameint;
@@ -3278,21 +3250,18 @@
 			case 5:
 				if ((data[++index] == 's') && (data[++index] == 's') && (data[++index] == 'e') && (data[++index] == 't'))
 					return TokenNameisset;
-				else
-					return TokenNameIdentifier;
+				return TokenNameIdentifier;
 			case 7:
 				if ((data[++index] == 'n') && (data[++index] == 'c') && (data[++index] == 'l') && (data[++index] == 'u')
 						&& (data[++index] == 'd') && (data[++index] == 'e'))
 					return TokenNameinclude;
-				else
-					return TokenNameIdentifier;
+				return TokenNameIdentifier;
 			case 9:
 				// interface
 				if ((data[++index] == 'n') && (data[++index] == 't') && (data[++index] == 'e') && (data[++index] == 'r')
 						&& (data[++index] == 'f') && (data[++index] == 'a') && (data[++index] == 'c') && (data[++index] == 'e'))
 					return TokenNameinterface;
-				else
-					return TokenNameIdentifier;
+				return TokenNameIdentifier;
 			case 10:
 				// instanceof
 				if ((data[++index] == 'n') && (data[++index] == 's') && (data[++index] == 't') && (data[++index] == 'a')
@@ -3303,18 +3272,15 @@
 						&& (data[++index] == 'm') && (data[++index] == 'e') && (data[++index] == 'n') && (data[++index] == 't')
 						&& (data[++index] == 's'))
 					return TokenNameimplements;
-				else
-					return TokenNameIdentifier;
+				return TokenNameIdentifier;
 			case 12:
 				if ((data[++index] == 'n') && (data[++index] == 'c') && (data[++index] == 'l') && (data[++index] == 'u')
 						&& (data[++index] == 'd') && (data[++index] == 'e') && (data[++index] == '_') && (data[++index] == 'o')
 						&& (data[++index] == 'n') && (data[++index] == 'c') && (data[++index] == 'e'))
 					return TokenNameinclude_once;
-				else
-					return TokenNameIdentifier;
-			default:
 				return TokenNameIdentifier;
 			}
+			return TokenNameIdentifier;
 		case 'l':
 			// list
 			if (length == 4) {
@@ -3329,17 +3295,15 @@
 			case 3:
 				if ((data[++index] == 'e') && (data[++index] == 'w'))
 					return TokenNamenew;
-				else
-					return TokenNameIdentifier;
+				return TokenNameIdentifier;
 			// case 4 :
 			// if ((data[++index] == 'u') && (data[++index] == 'l')
 			// && (data[++index] == 'l'))
 			// return TokenNamenull;
 			// else
 			// return TokenNameIdentifier;
-			default:
-				return TokenNameIdentifier;
 			}
+			return TokenNameIdentifier;
 		case 'o':
 			// or old_function
 			if (length == 2) {
@@ -3369,26 +3333,26 @@
 			case 5:
 				if ((data[++index] == 'r') && (data[++index] == 'i') && (data[++index] == 'n') && (data[++index] == 't')) {
 					return TokenNameprint;
-				} else
-					return TokenNameIdentifier;
+				}
+				return TokenNameIdentifier;
 			case 6:
 				if ((data[++index] == 'u') && (data[++index] == 'b') && (data[++index] == 'l') && (data[++index] == 'i')
 						&& (data[++index] == 'c')) {
 					return TokenNamepublic;
-				} else
-					return TokenNameIdentifier;
+				}
+				return TokenNameIdentifier;
 			case 7:
 				if ((data[++index] == 'r') && (data[++index] == 'i') && (data[++index] == 'v') && (data[++index] == 'a')
 						&& (data[++index] == 't') && (data[++index] == 'e')) {
 					return TokenNameprivate;
-				} else
-					return TokenNameIdentifier;
+				}
+				return TokenNameIdentifier;
 			case 9:
 				if ((data[++index] == 'r') && (data[++index] == 'o') && (data[++index] == 't') && (data[++index] == 'e')
 						&& (data[++index] == 'c') && (data[++index] == 't') && (data[++index] == 'e') && (data[++index] == 'd')) {
 					return TokenNameprotected;
-				} else
-					return TokenNameIdentifier;
+				}
+				return TokenNameIdentifier;
 			}
 			return TokenNameIdentifier;
 		case 'r':
@@ -3409,8 +3373,8 @@
 						&& (data[++index] == 'n') && (data[++index] == 'c') && (data[++index] == 'e')) {
 					return TokenNamerequire_once;
 				}
-			} else
-				return TokenNameIdentifier;
+			}
+			return TokenNameIdentifier;
 		case 's':
 			// self static switch
 			switch (length) {
@@ -3429,19 +3393,14 @@
 				else if ((data[index] == 'w') && (data[++index] == 'i') && (data[++index] == 't') && (data[++index] == 'c')
 						&& (data[++index] == 'h'))
 					return TokenNameswitch;
-				else
-					return TokenNameIdentifier;
-			default:
-				return TokenNameIdentifier;
 			}
+			return TokenNameIdentifier;
 		case 't':
 			// try true throw
 			switch (length) {
 			case 3:
 				if ((data[++index] == 'r') && (data[++index] == 'y'))
 					return TokenNametry;
-				else
-					return TokenNameIdentifier;
 			// case 4 :
 			// if ((data[++index] == 'r') && (data[++index] == 'u')
 			// && (data[++index] == 'e'))
@@ -3451,55 +3410,41 @@
 			case 5:
 				if ((data[++index] == 'h') && (data[++index] == 'r') && (data[++index] == 'o') && (data[++index] == 'w'))
 					return TokenNamethrow;
-				else
-					return TokenNameIdentifier;
-			default:
-				return TokenNameIdentifier;
 			}
+			return TokenNameIdentifier;
 		case 'u':
 			// use unset
 			switch (length) {
 			case 3:
 				if ((data[++index] == 's') && (data[++index] == 'e'))
 					return TokenNameuse;
-				else
-					return TokenNameIdentifier;
 			case 5:
 				if ((data[++index] == 'n') && (data[++index] == 's') && (data[++index] == 'e') && (data[++index] == 't'))
 					return TokenNameunset;
-				else
-					return TokenNameIdentifier;
-			default:
-				return TokenNameIdentifier;
 			}
+			return TokenNameIdentifier;
 		case 'v':
 			// var
 			switch (length) {
 			case 3:
 				if ((data[++index] == 'a') && (data[++index] == 'r'))
 					return TokenNamevar;
-				else
-					return TokenNameIdentifier;
-			default:
-				return TokenNameIdentifier;
 			}
+			return TokenNameIdentifier;
 		case 'w':
 			// while
 			switch (length) {
 			case 5:
 				if ((data[++index] == 'h') && (data[++index] == 'i') && (data[++index] == 'l') && (data[++index] == 'e'))
 					return TokenNamewhile;
-				else
-					return TokenNameIdentifier;
 			// case 6:if ( (data[++index] =='i') && (data[++index]=='d') &&
 			// (data[++index]=='e') && (data[++index]=='f')&&
 			// (data[++index]=='p'))
 			// return TokenNamewidefp ;
 			// else
 			// return TokenNameIdentifier;
-			default:
-				return TokenNameIdentifier;
 			}
+			return TokenNameIdentifier;
 		case 'x':
 			// xor
 			switch (length) {
@@ -3508,12 +3453,10 @@
 					return TokenNamexor;
 				else
 					return TokenNameIdentifier;
-			default:
-				return TokenNameIdentifier;
 			}
-		default:
 			return TokenNameIdentifier;
 		}
+		return TokenNameIdentifier;
 	}
 
 	public int scanNumber(boolean dotPrefix) throws InvalidInputException {
Index: src/net/sourceforge/phpdt/internal/compiler/parser/Parser.java
===================================================================
RCS file: /cvsroot/phpeclipse/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/parser/Parser.java,v
retrieving revision 1.97
diff -u -r1.97 Parser.java
--- src/net/sourceforge/phpdt/internal/compiler/parser/Parser.java	11 Feb 2006 10:56:15 -0000	1.97
+++ src/net/sourceforge/phpdt/internal/compiler/parser/Parser.java	11 Aug 2006 17:59:54 -0000
@@ -1193,7 +1193,7 @@
 				// /* empty */
 				// | T_EXTENDS fully_qualified_class_name
 				if (token == TokenNameextends) {
-					interface_extends_list(typeDecl);
+					class_extends_list(typeDecl);
 					// getNextToken();
 					// if (token != TokenNameIdentifier) {
 					// throwSyntaxError("Class name expected after keyword
@@ -1275,6 +1275,15 @@
 		// | T_EXTENDS interface_list
 		if (token == TokenNameextends) {
 			getNextToken();
+			interface_list(typeDecl);
+		}
+	}
+
+	private void class_extends_list(TypeDeclaration typeDecl) {
+		// /* empty */
+		// | T_EXTENDS interface_list
+		if (token == TokenNameextends) {
+			getNextToken();
 			class_list(typeDecl);
 		}
 	}
@@ -1305,7 +1314,7 @@
 				throwSyntaxError("Classname expected after keyword 'extends'.");
 			}
 			if (token == TokenNameCOMMA) {
-				reportSyntaxError("No multiple inheritence allowed. Expected token 'implements' or '{'.");
+				reportSyntaxError("No multiple inheritance allowed. Expected token 'implements' or '{'.");
 				getNextToken();
 				continue;
 			} else {
Index: src/net/sourceforge/phpdt/internal/ui/text/java/JavaExpandHover.java
===================================================================
RCS file: src/net/sourceforge/phpdt/internal/ui/text/java/JavaExpandHover.java
diff -N src/net/sourceforge/phpdt/internal/ui/text/java/JavaExpandHover.java
--- src/net/sourceforge/phpdt/internal/ui/text/java/JavaExpandHover.java	6 Mar 2005 20:56:36 -0000	1.2
+++ /dev/null	1 Jan 1970 00:00:00 -0000
@@ -1,188 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
- * Contributors:
- *     IBM Corporation - initial API and implementation
- *******************************************************************************/
-package net.sourceforge.phpdt.internal.ui.text.java;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-
-import net.sourceforge.phpdt.internal.ui.PHPUiImages;
-import net.sourceforge.phpeclipse.PHPeclipsePlugin;
-import net.sourceforge.phpeclipse.phpeditor.JavaMarkerAnnotation;
-
-import org.eclipse.jface.preference.IPreferenceStore;
-import org.eclipse.jface.text.IDocument;
-import org.eclipse.jface.text.IInformationControlExtension2;
-import org.eclipse.jface.text.Position;
-import org.eclipse.jface.text.source.Annotation;
-import org.eclipse.jface.text.source.CompositeRuler;
-import org.eclipse.jface.text.source.IAnnotationAccess;
-import org.eclipse.jface.text.source.IAnnotationAccessExtension;
-import org.eclipse.jface.text.source.IAnnotationModel;
-import org.eclipse.jface.text.source.IAnnotationPresentation;
-import org.eclipse.jface.text.source.ISourceViewer;
-import org.eclipse.jface.text.source.ImageUtilities;
-import org.eclipse.jface.viewers.IDoubleClickListener;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.graphics.GC;
-import org.eclipse.swt.graphics.Image;
-import org.eclipse.swt.graphics.Rectangle;
-import org.eclipse.swt.widgets.Canvas;
-import org.eclipse.ui.internal.texteditor.AnnotationExpandHover;
-import org.eclipse.ui.internal.texteditor.AnnotationExpansionControl;
-import org.eclipse.ui.internal.texteditor.AnnotationExpansionControl.AnnotationHoverInput;
-import org.eclipse.ui.texteditor.AnnotationPreference;
-import org.eclipse.ui.texteditor.AnnotationPreferenceLookup;
-
-/**
- * 
- * 
- * @since 3.0
- */
-public class JavaExpandHover extends AnnotationExpandHover {
-	
-	/** Id of the no breakpoint fake annotation */
-	public static final String NO_BREAKPOINT_ANNOTATION= "net.sourceforge.phpdt.internal.ui.NoBreakpointAnnotation"; //$NON-NLS-1$
-
-	private static class NoBreakpointAnnotation extends Annotation implements IAnnotationPresentation {
-		
-		public NoBreakpointAnnotation() {
-			super(NO_BREAKPOINT_ANNOTATION, false, JavaHoverMessages.getString("NoBreakpointAnnotation.addBreakpoint")); //$NON-NLS-1$
-		}
-		
-		/*
-		 * @see org.eclipse.jface.text.source.IAnnotationPresentation#paint(org.eclipse.swt.graphics.GC, org.eclipse.swt.widgets.Canvas, org.eclipse.swt.graphics.Rectangle)
-		 */
-		public void paint(GC gc, Canvas canvas, Rectangle bounds) {
-			// draw affordance so the user know she can click here to get a breakpoint
-			Image fImage= PHPUiImages.get(PHPUiImages.IMG_FIELD_PUBLIC);
-			ImageUtilities.drawImage(fImage, gc, canvas, bounds, SWT.CENTER);
-		}
-		
-		/*
-		 * @see org.eclipse.jface.text.source.IAnnotationPresentation#getLayer()
-		 */
-		public int getLayer() {
-			return IAnnotationPresentation.DEFAULT_LAYER;
-		}
-	}
-	
-	private AnnotationPreferenceLookup fLookup= new AnnotationPreferenceLookup();
-	private IPreferenceStore fStore= PHPeclipsePlugin.getDefault().getCombinedPreferenceStore();
-	
-	public JavaExpandHover(CompositeRuler ruler, IAnnotationAccess access, IDoubleClickListener doubleClickListener) {
-		super(ruler, access, doubleClickListener);
-	}
-	
-	/*
-	 * @see org.eclipse.ui.internal.texteditor.AnnotationExpandHover#getHoverInfoForLine(org.eclipse.jface.text.source.ISourceViewer, int)
-	 */
-	protected Object getHoverInfoForLine(final ISourceViewer viewer, final int line) {
-		IAnnotationModel model= viewer.getAnnotationModel();
-		IDocument document= viewer.getDocument();
-		
-		if (model == null)
-			return null;
-		
-		List exact= new ArrayList();
-		HashMap messagesAtPosition= new HashMap();
-		
-		Iterator e= model.getAnnotationIterator();
-		while (e.hasNext()) {
-			Annotation annotation= (Annotation) e.next();
-			
-			// don't prune deleted ones as we don't get many errors this way
-//			if (annotation.isMarkedDeleted())
-//				continue;
-			
-			if (fAnnotationAccess instanceof IAnnotationAccessExtension)
-				if (!((IAnnotationAccessExtension)fAnnotationAccess).isPaintable(annotation))
-					continue;
-				
-// TODO need a new check the this one is not OK
-//
-//			if (annotation instanceof IJavaAnnotation && annotation instanceof IAnnotationPresentation)
-//				if (((IJavaAnnotation) annotation).getImage(display) == null)
-//					continue;
-				
-			AnnotationPreference pref= fLookup.getAnnotationPreference(annotation);
-			if (pref != null) {
-				String key= pref.getVerticalRulerPreferenceKey();
-				if (key != null && !fStore.getBoolean(key))
-					continue;
-			}
-			
-			Position position= model.getPosition(annotation);
-			if (position == null)
-				continue;
-			
-			if (compareRulerLine(position, document, line) == 1) {
-				
-				if (isDuplicateMessage(messagesAtPosition, position, annotation.getText()))
-					continue;
-				
-				exact.add(annotation);
-			}
-		}
-		
-		sort(exact, model);
-		
-		if (exact.size() > 0)
-			setLastRulerMouseLocation(viewer, line);
-		
-		if (exact.size() > 0) {
-			Annotation first= (Annotation) exact.get(0);
-			if (!isBreakpointAnnotation(first))
-				exact.add(0, new NoBreakpointAnnotation());
-		}
-		
-		if (exact.size() <= 1)
-//		if (exact.size() < 1)
-			return null;
-		
-		AnnotationHoverInput input= new AnnotationHoverInput();
-		input.fAnnotations= (Annotation[]) exact.toArray(new Annotation[0]);
-		input.fViewer= viewer;
-		input.fRulerInfo= fCompositeRuler;
-		input.fAnnotationListener= fgListener;
-		input.fDoubleClickListener= fDblClickListener;
-		input.redoAction= new AnnotationExpansionControl.ICallback() {
-
-			public void run(IInformationControlExtension2 control) {
-				control.setInput(getHoverInfoForLine(viewer, line));
-			}
-			
-		};
-		input.model= model;
-		
-		return input;
-	}
-	
-	/*
-	 * @see org.eclipse.ui.internal.texteditor.AnnotationExpandHover#getOrder(org.eclipse.jface.text.source.Annotation)
-	 */
-	protected int getOrder(Annotation annotation) {
-		if (isBreakpointAnnotation(annotation)) //$NON-NLS-1$
-			return 1000;
-		else
-			return super.getOrder(annotation);
-	}
-
-	private boolean isBreakpointAnnotation(Annotation a) {
-		if (a instanceof JavaMarkerAnnotation) {
-			JavaMarkerAnnotation jma= (JavaMarkerAnnotation) a;
-			// HACK to get breakpoints to show up first
-			return jma.getType().equals("org.eclipse.debug.core.breakpoint"); //$NON-NLS-1$
-		}
-		return false;
-	}
-}
Index: src/net/sourceforge/phpdt/internal/ui/text/java/hover/JavaHoverMessages.properties
===================================================================
RCS file: /cvsroot/phpeclipse/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/java/hover/JavaHoverMessages.properties,v
retrieving revision 1.1
diff -u -r1.1 JavaHoverMessages.properties
--- src/net/sourceforge/phpdt/internal/ui/text/java/hover/JavaHoverMessages.properties	22 Dec 2003 14:12:32 -0000	1.1
+++ src/net/sourceforge/phpdt/internal/ui/text/java/hover/JavaHoverMessages.properties	11 Aug 2006 17:59:55 -0000
@@ -11,4 +11,8 @@
 
 TypeHover.more_to_come=\ ...
 
-JavaTextHover.createTextHover=Could not create java text hover
+JavaTextHover.createTextHover= Could not create PHP text hover
+
+JavaTextHover.makeStickyHint= Press ''{0}'' for focus.
+
+NoBreakpointAnnotation.addBreakpoint= Add a breakpoint
\ No newline at end of file
Index: src/net/sourceforge/phpeclipse/phpeditor/PHPEditor.java
===================================================================
RCS file: /cvsroot/phpeclipse/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/PHPEditor.java,v
retrieving revision 1.57
diff -u -r1.57 PHPEditor.java
--- src/net/sourceforge/phpeclipse/phpeditor/PHPEditor.java	21 Jan 2006 12:58:34 -0000	1.57
+++ src/net/sourceforge/phpeclipse/phpeditor/PHPEditor.java	11 Aug 2006 17:59:57 -0000
@@ -48,7 +48,7 @@
 import net.sourceforge.phpdt.internal.ui.text.JavaWordIterator;
 import net.sourceforge.phpdt.internal.ui.text.PHPPairMatcher;
 import net.sourceforge.phpdt.internal.ui.text.PreferencesAdapter;
-import net.sourceforge.phpdt.internal.ui.text.java.JavaExpandHover;
+import net.sourceforge.phpdt.internal.ui.text.java.hover.JavaExpandHover;
 import net.sourceforge.phpdt.internal.ui.viewsupport.ISelectionListenerWithAST;
 import net.sourceforge.phpdt.internal.ui.viewsupport.IViewPartInputProvider;
 import net.sourceforge.phpdt.internal.ui.viewsupport.SelectionListenerWithASTManager;
@@ -118,6 +118,7 @@
 import org.eclipse.jface.text.source.ISourceViewer;
 import org.eclipse.jface.text.source.ISourceViewerExtension2;
 import org.eclipse.jface.text.source.IVerticalRuler;
+import org.eclipse.jface.text.source.IVerticalRulerColumn;
 import org.eclipse.jface.text.source.OverviewRuler;
 import org.eclipse.jface.text.source.SourceViewerConfiguration;
 import org.eclipse.jface.text.source.projection.ProjectionSupport;
@@ -5394,12 +5395,53 @@
 	/*
 	 * @see org.eclipse.ui.texteditor.AbstractDecoratedTextEditor#createCompositeRuler()
 	 */
-	protected CompositeRuler createCompositeRuler() {
+//	protected CompositeRuler createCompositeRuler() {
+//		if (!getPreferenceStore().getBoolean(PreferenceConstants.EDITOR_ANNOTATION_ROLL_OVER))
+//			return super.createCompositeRuler();
+//
+//		CompositeRuler ruler = new CompositeRuler();
+//		AnnotationRulerColumn column = new AnnotationRulerColumn(VERTICAL_RULER_WIDTH, getAnnotationAccess());
+//		column.setHover(new JavaExpandHover(ruler, getAnnotationAccess(), new IDoubleClickListener() {
+//
+//			public void doubleClick(DoubleClickEvent event) {
+//				// for now: just invoke ruler double click action
+//				triggerAction(ITextEditorActionConstants.RULER_DOUBLE_CLICK);
+//			}
+//
+//			private void triggerAction(String actionID) {
+//				IAction action = getAction(actionID);
+//				if (action != null) {
+//					if (action instanceof IUpdate)
+//						((IUpdate) action).update();
+//					// hack to propagate line change
+//					if (action instanceof ISelectionListener) {
+//						((ISelectionListener) action).selectionChanged(null, null);
+//					}
+//					if (action.isEnabled())
+//						action.run();
+//				}
+//			}
+//
+//		}));
+//		ruler.addDecorator(0, column);
+//
+//		if (isLineNumberRulerVisible())
+//			ruler.addDecorator(1, createLineNumberRulerColumn());
+//		else if (isPrefQuickDiffAlwaysOn())
+//			ruler.addDecorator(1, createChangeRulerColumn());
+//
+//		return ruler;
+//	}
+
+	/*
+	 * @see org.eclipse.ui.texteditor.AbstractDecoratedTextEditor#createAnnotationRulerColumn(org.eclipse.jface.text.source.CompositeRuler)
+	 * @since 3.2
+	 */
+	protected IVerticalRulerColumn createAnnotationRulerColumn(CompositeRuler ruler) {
 		if (!getPreferenceStore().getBoolean(PreferenceConstants.EDITOR_ANNOTATION_ROLL_OVER))
-			return super.createCompositeRuler();
+			return super.createAnnotationRulerColumn(ruler);
 
-		CompositeRuler ruler = new CompositeRuler();
-		AnnotationRulerColumn column = new AnnotationRulerColumn(VERTICAL_RULER_WIDTH, getAnnotationAccess());
+		AnnotationRulerColumn column= new AnnotationRulerColumn(VERTICAL_RULER_WIDTH, getAnnotationAccess());
 		column.setHover(new JavaExpandHover(ruler, getAnnotationAccess(), new IDoubleClickListener() {
 
 			public void doubleClick(DoubleClickEvent event) {
@@ -5408,13 +5450,13 @@
 			}
 
 			private void triggerAction(String actionID) {
-				IAction action = getAction(actionID);
+				IAction action= getAction(actionID);
 				if (action != null) {
 					if (action instanceof IUpdate)
 						((IUpdate) action).update();
 					// hack to propagate line change
 					if (action instanceof ISelectionListener) {
-						((ISelectionListener) action).selectionChanged(null, null);
+						((ISelectionListener)action).selectionChanged(null, null);
 					}
 					if (action.isEnabled())
 						action.run();
@@ -5422,16 +5464,9 @@
 			}
 
 		}));
-		ruler.addDecorator(0, column);
-
-		if (isLineNumberRulerVisible())
-			ruler.addDecorator(1, createLineNumberRulerColumn());
-		else if (isPrefQuickDiffAlwaysOn())
-			ruler.addDecorator(1, createChangeRulerColumn());
-
-		return ruler;
+		
+		return column;
 	}
-
 	/**
 	 * Returns the folding action group, or <code>null</code> if there is none.
 	 *
Index: src/net/sourceforge/phpeclipse/phpeditor/PHPDocumentProvider.java
===================================================================
RCS file: /cvsroot/phpeclipse/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/PHPDocumentProvider.java,v
retrieving revision 1.19
diff -u -r1.19 PHPDocumentProvider.java
--- src/net/sourceforge/phpeclipse/phpeditor/PHPDocumentProvider.java	30 Sep 2005 18:20:41 -0000	1.19
+++ src/net/sourceforge/phpeclipse/phpeditor/PHPDocumentProvider.java	11 Aug 2006 17:59:56 -0000
@@ -466,7 +466,7 @@
   /**
 	 * Annotation representating an <code>IProblem</code>.
 	 */
-	static protected class ProblemAnnotation extends Annotation implements IJavaAnnotation, IAnnotationPresentation {
+	static public class ProblemAnnotation extends Annotation implements IJavaAnnotation, IAnnotationPresentation {
 
 		private static final String SPELLING_ANNOTATION_TYPE= "org.eclipse.ui.workbench.texteditor.spelling";
 
Index: src/net/sourceforge/phpeclipse/phpeditor/php/PHPCompletionProcessor.java
===================================================================
RCS file: /cvsroot/phpeclipse/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/php/PHPCompletionProcessor.java,v
retrieving revision 1.44
diff -u -r1.44 PHPCompletionProcessor.java
--- src/net/sourceforge/phpeclipse/phpeditor/php/PHPCompletionProcessor.java	17 Jan 2006 21:49:46 -0000	1.44
+++ src/net/sourceforge/phpeclipse/phpeditor/php/PHPCompletionProcessor.java	11 Aug 2006 17:59:57 -0000
@@ -68,6 +68,7 @@
 import org.eclipse.jface.text.templates.TemplateContextType;
 import org.eclipse.swt.graphics.Image;
 import org.eclipse.swt.graphics.Point;
+import org.eclipse.ui.IEditorInput;
 import org.eclipse.ui.IEditorPart;
 import org.eclipse.ui.IFileEditorInput;
 
@@ -484,8 +485,14 @@
 			PHPEditor editor = null;
 			if (fEditor != null && (fEditor instanceof PHPEditor)) {
 				editor = (PHPEditor) fEditor;
-				file = ((IFileEditorInput) editor.getEditorInput()).getFile();
-				project = file.getProject();
+				IEditorInput editorInput=editor.getEditorInput();
+				if (editorInput instanceof IFileEditorInput) {
+					file = ((IFileEditorInput) editorInput).getFile();
+					project = file.getProject();
+				}
+				else {
+					return new ICompletionProposal[0];
+				}
 			}
 		}
 
Index: .cvsignore
===================================================================
RCS file: /cvsroot/phpeclipse/net.sourceforge.phpeclipse/.cvsignore,v
retrieving revision 1.1
diff -u -r1.1 .cvsignore
--- .cvsignore	15 Aug 2004 08:55:03 -0000	1.1
+++ .cvsignore	11 Aug 2006 17:59:53 -0000
@@ -1 +1,4 @@
 bin
+build.xml
+temp.folder
+phpeclipse.jar
Index: src/net/sourceforge/phpdt/internal/ui/text/java/hover/AnnotationExpansionControl.java
===================================================================
RCS file: src/net/sourceforge/phpdt/internal/ui/text/java/hover/AnnotationExpansionControl.java
diff -N src/net/sourceforge/phpdt/internal/ui/text/java/hover/AnnotationExpansionControl.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ src/net/sourceforge/phpdt/internal/ui/text/java/hover/AnnotationExpansionControl.java	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,849 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.text.java.hover;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.StyleRange;
+import org.eclipse.swt.custom.StyledText;
+import org.eclipse.swt.events.DisposeEvent;
+import org.eclipse.swt.events.DisposeListener;
+import org.eclipse.swt.events.FocusListener;
+import org.eclipse.swt.events.MenuEvent;
+import org.eclipse.swt.events.MenuListener;
+import org.eclipse.swt.events.MouseAdapter;
+import org.eclipse.swt.events.MouseEvent;
+import org.eclipse.swt.events.MouseTrackAdapter;
+import org.eclipse.swt.events.MouseTrackListener;
+import org.eclipse.swt.events.PaintEvent;
+import org.eclipse.swt.events.PaintListener;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Cursor;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Canvas;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Layout;
+import org.eclipse.swt.widgets.Listener;
+import org.eclipse.swt.widgets.Menu;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Widget;
+
+import org.eclipse.jface.viewers.IDoubleClickListener;
+
+import org.eclipse.jface.text.AbstractInformationControlManager;
+import org.eclipse.jface.text.DefaultInformationControl;
+import org.eclipse.jface.text.IInformationControl;
+import org.eclipse.jface.text.IInformationControlCreator;
+import org.eclipse.jface.text.IInformationControlExtension;
+import org.eclipse.jface.text.IInformationControlExtension2;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.IViewportListener;
+import org.eclipse.jface.text.Position;
+import org.eclipse.jface.text.Region;
+import org.eclipse.jface.text.TextViewer;
+import org.eclipse.jface.text.source.Annotation;
+import org.eclipse.jface.text.source.IAnnotationAccess;
+import org.eclipse.jface.text.source.IAnnotationAccessExtension;
+import org.eclipse.jface.text.source.IAnnotationModel;
+import org.eclipse.jface.text.source.ISourceViewer;
+import org.eclipse.jface.text.source.IVerticalRulerInfo;
+import org.eclipse.jface.text.source.IVerticalRulerListener;
+import org.eclipse.jface.text.source.VerticalRulerEvent;
+
+
+/**
+ * A control that can display a number of annotations. The control can decide how it layouts the
+ * annotations to present them to the user.
+ * <p>
+ * This class got moved here form Platform Text since it was not used there
+ * and caused discouraged access warnings. It will be moved down again once
+ * annotation roll-over support is provided by Platform Text.
+ * </p>
+ * <p>Each annotation can have its custom context menu and hover.</p>
+ *
+ * @since 3.2
+ */
+public class AnnotationExpansionControl implements IInformationControl, IInformationControlExtension, IInformationControlExtension2 {
+
+
+	public interface ICallback {
+		void run(IInformationControlExtension2 control);
+	}
+
+	/**
+	 * Input used by the control to display the annotations.
+	 * TODO move to top-level class
+	 * TODO encapsulate fields
+	 *
+	 * @since 3.0
+	 */
+	public static class AnnotationHoverInput {
+		public Annotation[] fAnnotations;
+		public ISourceViewer fViewer;
+		public IVerticalRulerInfo fRulerInfo;
+		public IVerticalRulerListener fAnnotationListener;
+		public IDoubleClickListener fDoubleClickListener;
+		public ICallback redoAction;
+		public IAnnotationModel model;
+	}
+
+	private final class Item {
+		Annotation fAnnotation;
+		Canvas canvas;
+		StyleRange[] oldStyles;
+
+		public void selected() {
+			Display disp= fShell.getDisplay();
+			canvas.setCursor(fHandCursor);
+			// TODO: shade - for now: set grey background
+			canvas.setBackground(getSelectionColor(disp));
+
+			// highlight the viewer background at its position
+			oldStyles= setViewerBackground(fAnnotation);
+
+			// set the selection
+			fSelection= this;
+
+			if (fHoverManager != null)
+				fHoverManager.showInformation();
+
+			if (fInput.fAnnotationListener != null) {
+				VerticalRulerEvent event= new VerticalRulerEvent(fAnnotation);
+				fInput.fAnnotationListener.annotationSelected(event);
+			}
+
+		}
+
+		public void defaultSelected() {
+			if (fInput.fAnnotationListener != null) {
+				VerticalRulerEvent event= new VerticalRulerEvent(fAnnotation);
+				fInput.fAnnotationListener.annotationDefaultSelected(event);
+			}
+
+			dispose();
+		}
+
+		public void showContextMenu(Menu menu) {
+			if (fInput.fAnnotationListener != null) {
+				VerticalRulerEvent event= new VerticalRulerEvent(fAnnotation);
+				fInput.fAnnotationListener.annotationContextMenuAboutToShow(event, menu);
+			}
+		}
+
+		public void deselect() {
+			// hide the popup
+//			fHoverManager.disposeInformationControl();
+
+			// deselect
+			fSelection= null;
+
+			resetViewerBackground(oldStyles);
+			oldStyles= null;
+
+			Display disp= fShell.getDisplay();
+			canvas.setCursor(null);
+			// TODO: remove shading - for now: set standard background
+			canvas.setBackground(disp.getSystemColor(SWT.COLOR_INFO_BACKGROUND));
+
+		}
+
+	}
+
+	/**
+	 * Disposes of an item
+	 */
+	private final static class MyDisposeListener implements DisposeListener {
+		/*
+		 * @see org.eclipse.swt.events.DisposeListener#widgetDisposed(org.eclipse.swt.events.DisposeEvent)
+		 */
+		public void widgetDisposed(DisposeEvent e) {
+			Item item= (Item) ((Widget) e.getSource()).getData();
+			item.deselect();
+			item.canvas= null;
+			item.fAnnotation= null;
+			item.oldStyles= null;
+
+			((Widget) e.getSource()).setData(null);
+		}
+	}
+
+	/**
+	 * Listener on context menu invocation on the items
+	 */
+	private final class MyMenuDetectListener implements Listener {
+		/*
+		 * @see org.eclipse.swt.widgets.Listener#handleEvent(org.eclipse.swt.widgets.Event)
+		 */
+		public void handleEvent(Event event) {
+			if (event.type == SWT.MenuDetect) {
+				// TODO: show per-item menu
+				// for now: show ruler context menu
+				if (fInput != null) {
+					Control ruler= fInput.fRulerInfo.getControl();
+					if (ruler != null && !ruler.isDisposed()) {
+						Menu menu= ruler.getMenu();
+						if (menu != null && !menu.isDisposed()) {
+							menu.setLocation(event.x, event.y);
+							menu.addMenuListener(new MenuListener() {
+
+								public void menuHidden(MenuEvent e) {
+									dispose();
+								}
+
+								public void menuShown(MenuEvent e) {
+								}
+
+							});
+							menu.setVisible(true);
+						}
+					}
+				}
+			}
+		}
+	}
+
+	
+	/**
+	 * Listener on mouse events on the items.
+	 */
+	private final class MyMouseListener extends MouseAdapter {
+		/*
+		 * @see org.eclipse.swt.events.MouseListener#mouseDoubleClick(org.eclipse.swt.events.MouseEvent)
+		 */
+		public void mouseDoubleClick(MouseEvent e) {
+			Item item= (Item) ((Widget) e.getSource()).getData();
+			if (e.button == 1 && item.fAnnotation == fInput.fAnnotations[0] && fInput.fDoubleClickListener != null) {
+				fInput.fDoubleClickListener.doubleClick(null);
+				// special code for JDT to renew the annotation set.
+				if (fInput.redoAction != null)
+					fInput.redoAction.run(AnnotationExpansionControl.this);
+			}
+//			dispose();
+			// TODO special action to invoke double-click action on the vertical ruler
+			// how about
+//					Canvas can= (Canvas) e.getSource();
+//					Annotation a= (Annotation) can.getData();
+//					if (a != null) {
+//						a.getDoubleClickAction().run();
+//					}
+		}
+
+		/*
+		 * @see org.eclipse.swt.events.MouseListener#mouseUp(org.eclipse.swt.events.MouseEvent)
+		 */
+		public void mouseUp(MouseEvent e) {
+			Item item= (Item) ((Widget) e.getSource()).getData();
+			// TODO for now, to make double click work: disable single click on the first item
+			// disable later when the annotationlistener selectively handles input
+			if (item != null && e.button == 1) // && item.fAnnotation != fInput.fAnnotations[0])
+				item.defaultSelected();
+		}
+
+		/*
+		 * @see org.eclipse.swt.events.MouseAdapter#mouseDown(org.eclipse.swt.events.MouseEvent)
+		 */
+		public void mouseDown(MouseEvent e) {
+			super.mouseDown(e);
+		}
+	}
+
+	/**
+	 * Listener on mouse track events on the items.
+	 */
+	private final class MyMouseTrackListener implements MouseTrackListener {
+		/*
+		 * @see org.eclipse.swt.events.MouseTrackListener#mouseEnter(org.eclipse.swt.events.MouseEvent)
+		 */
+		public void mouseEnter(MouseEvent e) {
+			Item item= (Item) ((Widget) e.getSource()).getData();
+			if (item != null)
+				item.selected();
+		}
+
+		/*
+		 * @see org.eclipse.swt.events.MouseTrackListener#mouseExit(org.eclipse.swt.events.MouseEvent)
+		 */
+		public void mouseExit(MouseEvent e) {
+
+			Item item= (Item) ((Widget) e.getSource()).getData();
+			if (item != null)
+				item.deselect();
+
+			// if the event lies outside the entire popup, dispose
+			org.eclipse.swt.graphics.Region region= fShell.getRegion();
+			Canvas can= (Canvas) e.getSource();
+			Point p= can.toDisplay(e.x, e.y);
+			if (region == null) {
+				Rectangle bounds= fShell.getBounds();
+//				p= fShell.toControl(p);
+				if (!bounds.contains(p))
+					dispose();
+			} else {
+				p= fShell.toControl(p);
+				if (!region.contains(p))
+					dispose();
+			}
+
+
+		}
+
+		/*
+		 * @see org.eclipse.swt.events.MouseTrackListener#mouseHover(org.eclipse.swt.events.MouseEvent)
+		 */
+		public void mouseHover(MouseEvent e) {
+			if (fHoverManager == null) {
+				fHoverManager= new HoverManager();
+				fHoverManager.takesFocusWhenVisible(false);
+				fHoverManager.install(fComposite);
+				fHoverManager.showInformation();
+			}
+		}
+	}
+
+	
+	/**
+	 *
+	 *
+	 * @since 3.0
+	 */
+	public class LinearLayouter {
+
+		private static final int ANNOTATION_SIZE= 14;
+		private static final int BORDER_WIDTH= 2;
+
+		public Layout getLayout(int itemCount) {
+			// simple layout: a row of items
+			GridLayout layout= new GridLayout(itemCount, true);
+			layout.horizontalSpacing= 1;
+			layout.verticalSpacing= 0;
+			layout.marginHeight= 1;
+			layout.marginWidth= 1;
+			return layout;
+		}
+
+		public Object getLayoutData() {
+			GridData gridData= new GridData(ANNOTATION_SIZE + 2 * BORDER_WIDTH, ANNOTATION_SIZE + 2 * BORDER_WIDTH);
+			gridData.horizontalAlignment= GridData.CENTER;
+			gridData.verticalAlignment= GridData.CENTER;
+			return gridData;
+		}
+
+		public int getAnnotationSize() {
+			return ANNOTATION_SIZE;
+		}
+
+		public int getBorderWidth() {
+			return BORDER_WIDTH;
+		}
+
+		public org.eclipse.swt.graphics.Region getShellRegion(int itemCount) {
+			// no special region - set to null for default shell size
+			return null;
+		}
+
+	}
+	
+	
+	/**
+	 * Listener on paint events on the items. Paints the annotation image on the given <code>GC</code>.
+	 */
+	private final class MyPaintListener implements PaintListener {
+		/*
+		 * @see org.eclipse.swt.events.PaintListener#paintControl(org.eclipse.swt.events.PaintEvent)
+		 */
+		public void paintControl(PaintEvent e) {
+			Canvas can= (Canvas) e.getSource();
+			Annotation a= ((Item) can.getData()).fAnnotation;
+			if (a != null) {
+				Rectangle rect= new Rectangle(fLayouter.getBorderWidth(), fLayouter.getBorderWidth(), fLayouter.getAnnotationSize(), fLayouter.getAnnotationSize());
+				if (fAnnotationAccessExtension != null)
+					fAnnotationAccessExtension.paint(a, e.gc, can, rect);
+			}
+		}
+	}
+
+	/**
+	 * Our own private hover manager used to shop per-item pop-ups.
+	 */
+	private final class HoverManager extends AbstractInformationControlManager {
+
+		/**
+		 *
+		 */
+		public HoverManager() {
+			super(new IInformationControlCreator() {
+				public IInformationControl createInformationControl(Shell parent) {
+					return new DefaultInformationControl(parent);
+				}
+			});
+
+			setMargins(5, 10);
+			setAnchor(ANCHOR_BOTTOM);
+			setFallbackAnchors(new Anchor[] {ANCHOR_BOTTOM, ANCHOR_LEFT, ANCHOR_RIGHT} );
+		}
+
+		/*
+		 * @see org.eclipse.jface.text.AbstractInformationControlManager#computeInformation()
+		 */
+		protected void computeInformation() {
+			if (fSelection != null) {
+				Rectangle subjectArea= fSelection.canvas.getBounds();
+				Annotation annotation= fSelection.fAnnotation;
+				String msg;
+				if (annotation != null)
+					msg= annotation.getText();
+				else
+					msg= null;
+
+				setInformation(msg, subjectArea);
+			}
+		}
+
+
+	}
+
+	/** Model data. */
+	protected AnnotationHoverInput fInput;
+	/** The control's shell */
+	private Shell fShell;
+	/** The composite combining all the items. */
+	protected Composite fComposite;
+	/** The hand cursor. */
+	private Cursor fHandCursor;
+	/** The currently selected item, or <code>null</code> if none is selected. */
+	private Item fSelection;
+	/** The hover manager for the per-item hovers. */
+	private HoverManager fHoverManager;
+	/** The annotation access extension. */
+	private IAnnotationAccessExtension fAnnotationAccessExtension;
+
+
+	/* listener legion */
+	private final MyPaintListener fPaintListener;
+	private final MyMouseTrackListener fMouseTrackListener;
+	private final MyMouseListener fMouseListener;
+	private final MyMenuDetectListener fMenuDetectListener;
+	private final DisposeListener fDisposeListener;
+	private final IViewportListener fViewportListener;
+
+	private LinearLayouter fLayouter;
+
+	/**
+	 * Creates a new control.
+	 *
+	 * @param parent
+	 * @param shellStyle
+	 * @param access
+	 */
+	public AnnotationExpansionControl(Shell parent, int shellStyle, IAnnotationAccess access) {
+		fPaintListener= new MyPaintListener();
+		fMouseTrackListener= new MyMouseTrackListener();
+		fMouseListener= new MyMouseListener();
+		fMenuDetectListener= new MyMenuDetectListener();
+		fDisposeListener= new MyDisposeListener();
+		fViewportListener= new IViewportListener() {
+
+			public void viewportChanged(int verticalOffset) {
+				dispose();
+			}
+
+		};
+		fLayouter= new LinearLayouter();
+
+		if (access instanceof IAnnotationAccessExtension)
+			fAnnotationAccessExtension= (IAnnotationAccessExtension) access;
+
+		fShell= new Shell(parent, shellStyle | SWT.NO_FOCUS | SWT.ON_TOP);
+		Display display= fShell.getDisplay();
+		fShell.setBackground(display.getSystemColor(SWT.COLOR_BLACK));
+		fComposite= new Composite(fShell, SWT.NO_FOCUS | SWT.NO_REDRAW_RESIZE | SWT.NO_TRIM);
+//		fComposite= new Composite(fShell, SWT.NO_FOCUS | SWT.NO_REDRAW_RESIZE | SWT.NO_TRIM | SWT.V_SCROLL);
+
+		GridLayout layout= new GridLayout(1, true);
+		layout.marginHeight= 0;
+		layout.marginWidth= 0;
+		fShell.setLayout(layout);
+
+		GridData data= new GridData(GridData.FILL_BOTH);
+		data.heightHint= fLayouter.getAnnotationSize() + 2 * fLayouter.getBorderWidth() + 4;
+		fComposite.setLayoutData(data);
+		fComposite.addMouseTrackListener(new MouseTrackAdapter() {
+
+			public void mouseExit(MouseEvent e) {
+				if (fComposite == null)
+						return;
+				Control[] children= fComposite.getChildren();
+				Rectangle bounds= null;
+				for (int i= 0; i < children.length; i++) {
+					if (bounds == null)
+						bounds= children[i].getBounds();
+					else
+						bounds.add(children[i].getBounds());
+					if (bounds.contains(e.x, e.y))
+						return;
+				}
+
+				// if none of the children contains the event, we leave the popup
+				dispose();
+			}
+
+		});
+
+//		fComposite.getVerticalBar().addListener(SWT.Selection, new Listener() {
+//
+//			public void handleEvent(Event event) {
+//				Rectangle bounds= fShell.getBounds();
+//				int x= bounds.x - fLayouter.getAnnotationSize() - fLayouter.getBorderWidth();
+//				int y= bounds.y;
+//				fShell.setBounds(x, y, bounds.width, bounds.height);
+//			}
+//
+//		});
+
+		fHandCursor= new Cursor(display, SWT.CURSOR_HAND);
+		fShell.setCursor(fHandCursor);
+		fComposite.setCursor(fHandCursor);
+
+		setInfoSystemColor();
+	}
+
+	private void setInfoSystemColor() {
+		Display display= fShell.getDisplay();
+		setForegroundColor(display.getSystemColor(SWT.COLOR_INFO_FOREGROUND));
+		setBackgroundColor(display.getSystemColor(SWT.COLOR_INFO_BACKGROUND));
+	}
+
+	/*
+	 * @see org.eclipse.jface.text.IInformationControl#setInformation(java.lang.String)
+	 */
+	public void setInformation(String information) {
+		setInput(null);
+	}
+
+
+	/*
+	 * @see org.eclipse.jface.text.IInformationControlExtension2#setInput(java.lang.Object)
+	 */
+	public void setInput(Object input) {
+		if (fInput != null && fInput.fViewer != null)
+			fInput.fViewer.removeViewportListener(fViewportListener);
+
+		if (input instanceof AnnotationHoverInput)
+			fInput= (AnnotationHoverInput) input;
+		else
+			fInput= null;
+
+		inputChanged(fInput, null);
+	}
+
+	protected void inputChanged(Object newInput, Object newSelection) {
+		refresh();
+	}
+
+	protected void refresh() {
+		adjustItemNumber();
+
+		if (fInput == null)
+			return;
+
+		if (fInput.fAnnotations == null)
+			return;
+
+		if (fInput.fViewer != null)
+			fInput.fViewer.addViewportListener(fViewportListener);
+
+		fShell.setRegion(fLayouter.getShellRegion(fInput.fAnnotations.length));
+
+		Layout layout= fLayouter.getLayout(fInput.fAnnotations.length);
+		fComposite.setLayout(layout);
+
+		Control[] children= fComposite.getChildren();
+		for (int i= 0; i < fInput.fAnnotations.length; i++) {
+			Canvas canvas= (Canvas) children[i];
+			Item item= new Item();
+			item.canvas= canvas;
+			item.fAnnotation= fInput.fAnnotations[i];
+			canvas.setData(item);
+			canvas.redraw();
+		}
+
+	}
+
+	protected void adjustItemNumber() {
+		if (fComposite == null)
+			return;
+
+		Control[] children= fComposite.getChildren();
+		int oldSize= children.length;
+		int newSize= fInput == null ? 0 : fInput.fAnnotations.length;
+
+		Display display= fShell.getDisplay();
+
+		// add missing items
+		for (int i= oldSize; i < newSize; i++) {
+			Canvas canvas= new Canvas(fComposite, SWT.NONE);
+			Object gridData= fLayouter.getLayoutData();
+			canvas.setLayoutData(gridData);
+			canvas.setBackground(display.getSystemColor(SWT.COLOR_INFO_BACKGROUND));
+
+			canvas.addPaintListener(fPaintListener);
+
+			canvas.addMouseTrackListener(fMouseTrackListener);
+
+			canvas.addMouseListener(fMouseListener);
+
+			canvas.addListener(SWT.MenuDetect, fMenuDetectListener);
+
+			canvas.addDisposeListener(fDisposeListener);
+		}
+
+		// dispose of exceeding resources
+		for (int i= oldSize; i > newSize; i--) {
+			Item item= (Item) children[i - 1].getData();
+			item.deselect();
+			children[i - 1].dispose();
+		}
+
+	}
+
+	/*
+	 * @see IInformationControl#setVisible(boolean)
+	 */
+	public void setVisible(boolean visible) {
+		fShell.setVisible(visible);
+	}
+
+	/*
+	 * @see IInformationControl#dispose()
+	 */
+	public void dispose() {
+		if (fShell != null) {
+			if (!fShell.isDisposed())
+				fShell.dispose();
+			fShell= null;
+			fComposite= null;
+			if (fHandCursor != null)
+				fHandCursor.dispose();
+			fHandCursor= null;
+			if (fHoverManager != null)
+				fHoverManager.dispose();
+			fHoverManager= null;
+			fSelection= null;
+		}
+	}
+
+	/*
+	 * @see org.eclipse.jface.text.IInformationControlExtension#hasContents()
+	 */
+	public boolean hasContents() {
+		return fInput.fAnnotations != null && fInput.fAnnotations.length > 0;
+	}
+
+	/*
+	 * @see org.eclipse.jface.text.IInformationControl#setSizeConstraints(int, int)
+	 */
+	public void setSizeConstraints(int maxWidth, int maxHeight) {
+		//fMaxWidth= maxWidth;
+		//fMaxHeight= maxHeight;
+	}
+
+	/*
+	 * @see org.eclipse.jface.text.IInformationControl#computeSizeHint()
+	 */
+	public Point computeSizeHint() {
+		return fShell.computeSize(SWT.DEFAULT, SWT.DEFAULT);
+	}
+
+	/*
+	 * @see IInformationControl#setLocation(Point)
+	 */
+	public void setLocation(Point location) {
+		fShell.setLocation(location);
+	}
+
+	/*
+	 * @see IInformationControl#setSize(int, int)
+	 */
+	public void setSize(int width, int height) {
+		fShell.setSize(width, height);
+	}
+
+	/*
+	 * @see IInformationControl#addDisposeListener(DisposeListener)
+	 */
+	public void addDisposeListener(DisposeListener listener) {
+		fShell.addDisposeListener(listener);
+	}
+
+	/*
+	 * @see IInformationControl#removeDisposeListener(DisposeListener)
+	 */
+	public void removeDisposeListener(DisposeListener listener) {
+		fShell.removeDisposeListener(listener);
+	}
+
+	/*
+	 * @see IInformationControl#setForegroundColor(Color)
+	 */
+	public void setForegroundColor(Color foreground) {
+		fComposite.setForeground(foreground);
+	}
+
+	/*
+	 * @see IInformationControl#setBackgroundColor(Color)
+	 */
+	public void setBackgroundColor(Color background) {
+		fComposite.setBackground(background);
+	}
+
+	/*
+	 * @see IInformationControl#isFocusControl()
+	 */
+	public boolean isFocusControl() {
+		if (fComposite.isFocusControl())
+			return true;
+
+		Control[] children= fComposite.getChildren();
+		for (int i= 0; i < children.length; i++) {
+			if (children[i].isFocusControl())
+				return true;
+		}
+		return false;
+	}
+
+	/*
+	 * @see IInformationControl#setFocus()
+	 */
+	public void setFocus() {
+		fShell.forceFocus();
+	}
+
+	/*
+	 * @see IInformationControl#addFocusListener(FocusListener)
+	 */
+	public void addFocusListener(FocusListener listener) {
+		fShell.addFocusListener(listener);
+	}
+
+	/*
+	 * @see IInformationControl#removeFocusListener(FocusListener)
+	 */
+	public void removeFocusListener(FocusListener listener) {
+		fShell.removeFocusListener(listener);
+	}
+
+	private StyleRange[] setViewerBackground(Annotation annotation) {
+		StyledText text= fInput.fViewer.getTextWidget();
+		if (text == null || text.isDisposed())
+			return null;
+
+		Display disp= text.getDisplay();
+
+		Position pos= fInput.model.getPosition(annotation);
+		if (pos == null)
+			return null;
+
+		IRegion region= ((TextViewer)fInput.fViewer).modelRange2WidgetRange(new Region(pos.offset, pos.length));
+		if (region == null)
+			return null;
+
+		StyleRange[] ranges= text.getStyleRanges(region.getOffset(), region.getLength());
+
+		List undoRanges= new ArrayList(ranges.length);
+		for (int i= 0; i < ranges.length; i++) {
+			undoRanges.add(ranges[i].clone());
+		}
+
+		int offset= region.getOffset();
+		StyleRange current= undoRanges.size() > 0 ? (StyleRange) undoRanges.get(0) : null;
+		int curStart= current != null ? current.start : region.getOffset() + region.getLength();
+		int curEnd= current != null ? current.start + current.length : -1;
+		int index= 0;
+
+		// fill no-style regions
+		while (curEnd < region.getOffset() + region.getLength()) {
+			// add empty range
+			if (curStart > offset) {
+				StyleRange undoRange= new StyleRange(offset, curStart - offset, null, null);
+				undoRanges.add(index, undoRange);
+				index++;
+			}
+
+			// step
+			index++;
+			if (index < undoRanges.size()) {
+				offset= curEnd;
+				current= (StyleRange) undoRanges.get(index);
+				curStart= current.start;
+				curEnd= current.start + current.length;
+			} else if (index == undoRanges.size()) {
+				// last one
+				offset= curEnd;
+				current= null;
+				curStart= region.getOffset() + region.getLength();
+				curEnd= -1;
+			} else
+				curEnd= region.getOffset() + region.getLength();
+		}
+
+		// create modified styles (with background)
+		List shadedRanges= new ArrayList(undoRanges.size());
+		for (Iterator it= undoRanges.iterator(); it.hasNext(); ) {
+			StyleRange range= (StyleRange) ((StyleRange) it.next()).clone();
+			shadedRanges.add(range);
+			range.background= getHighlightColor(disp);
+		}
+
+		// set the ranges one by one
+		for (Iterator iter= shadedRanges.iterator(); iter.hasNext(); ) {
+			text.setStyleRange((StyleRange) iter.next());
+
+		}
+
+		return (StyleRange[]) undoRanges.toArray(undoRanges.toArray(new StyleRange[0]));
+	}
+
+	private void resetViewerBackground(StyleRange[] oldRanges) {
+
+		if (oldRanges == null)
+			return;
+
+		if (fInput == null)
+			return;
+
+		StyledText text= fInput.fViewer.getTextWidget();
+		if (text == null || text.isDisposed())
+			return;
+
+		// set the ranges one by one
+		for (int i= 0; i < oldRanges.length; i++) {
+			text.setStyleRange(oldRanges[i]);
+		}
+	}
+
+	private Color getHighlightColor(Display disp) {
+		return disp.getSystemColor(SWT.COLOR_GRAY);
+	}
+
+	private Color getSelectionColor(Display disp) {
+		return disp.getSystemColor(SWT.COLOR_GRAY);
+	}
+
+}
Index: src/net/sourceforge/phpdt/internal/ui/text/java/hover/AnnotationExpandHover.java
===================================================================
RCS file: src/net/sourceforge/phpdt/internal/ui/text/java/hover/AnnotationExpandHover.java
diff -N src/net/sourceforge/phpdt/internal/ui/text/java/hover/AnnotationExpandHover.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ src/net/sourceforge/phpdt/internal/ui/text/java/hover/AnnotationExpandHover.java	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,311 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.text.java.hover;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.StyledText;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.widgets.Menu;
+import org.eclipse.swt.widgets.Shell;
+
+import org.eclipse.jface.viewers.IDoubleClickListener;
+
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IInformationControl;
+import org.eclipse.jface.text.IInformationControlCreator;
+import org.eclipse.jface.text.IInformationControlCreatorExtension;
+import org.eclipse.jface.text.ITextViewerExtension5;
+import org.eclipse.jface.text.Position;
+import org.eclipse.jface.text.TextViewer;
+import org.eclipse.jface.text.source.Annotation;
+import org.eclipse.jface.text.source.CompositeRuler;
+import org.eclipse.jface.text.source.IAnnotationAccess;
+import org.eclipse.jface.text.source.IAnnotationAccessExtension;
+import org.eclipse.jface.text.source.IAnnotationHover;
+import org.eclipse.jface.text.source.IAnnotationHoverExtension;
+import org.eclipse.jface.text.source.IAnnotationModel;
+import org.eclipse.jface.text.source.ILineRange;
+import org.eclipse.jface.text.source.ISourceViewer;
+import org.eclipse.jface.text.source.IVerticalRulerListener;
+import org.eclipse.jface.text.source.LineRange;
+import org.eclipse.jface.text.source.VerticalRulerEvent;
+
+import net.sourceforge.phpdt.internal.ui.text.java.hover.AnnotationExpansionControl.AnnotationHoverInput;
+
+
+/**
+ * This class got moved here form Platform Text since it was not used there
+ * and caused discouraged access warnings. It will be moved down again once
+ * annotation roll-over support is provided by Platform Text.
+ *   
+ * @since 3.2
+ */
+public class AnnotationExpandHover implements IAnnotationHover, IAnnotationHoverExtension {
+
+	private class InformationControlCreator implements IInformationControlCreator, IInformationControlCreatorExtension {
+
+		/*
+		 * @see org.eclipse.jface.text.IInformationControlCreator#createInformationControl(org.eclipse.swt.widgets.Shell)
+		 */
+		public IInformationControl createInformationControl(Shell parent) {
+			return new AnnotationExpansionControl(parent, SWT.NONE, fAnnotationAccess);
+		}
+
+		/*
+		 * @see org.eclipse.jface.text.IInformationControlCreatorExtension#canReuse(org.eclipse.jface.text.IInformationControl)
+		 */
+		public boolean canReuse(IInformationControl control) {
+			return control instanceof AnnotationExpansionControl;
+		}
+
+		/*
+		 * @see org.eclipse.jface.text.IInformationControlCreatorExtension#canReplace(org.eclipse.jface.text.IInformationControlCreator)
+		 */
+		public boolean canReplace(IInformationControlCreator creator) {
+			return creator == this;
+		}
+	}
+
+	private class VerticalRulerListener implements IVerticalRulerListener {
+
+		/*
+		 * @see org.eclipse.jface.text.source.IVerticalRulerListener#annotationSelected(org.eclipse.jface.text.source.VerticalRulerEvent)
+		 */
+		public void annotationSelected(VerticalRulerEvent event) {
+			fCompositeRuler.fireAnnotationSelected(event);
+		}
+
+		/*
+		 * @see org.eclipse.jface.text.source.IVerticalRulerListener#annotationDefaultSelected(org.eclipse.jface.text.source.VerticalRulerEvent)
+		 */
+		public void annotationDefaultSelected(VerticalRulerEvent event) {
+			fCompositeRuler.fireAnnotationDefaultSelected(event);
+		}
+
+		/*
+		 * @see org.eclipse.jface.text.source.IVerticalRulerListener#annotationContextMenuAboutToShow(org.eclipse.jface.text.source.VerticalRulerEvent, org.eclipse.swt.widgets.Menu)
+		 */
+		public void annotationContextMenuAboutToShow(VerticalRulerEvent event, Menu menu) {
+			fCompositeRuler.fireAnnotationContextMenuAboutToShow(event, menu);
+		}
+	}
+
+
+	private final IInformationControlCreator fgCreator= new InformationControlCreator();
+	protected final IVerticalRulerListener fgListener= new VerticalRulerListener();
+	protected CompositeRuler fCompositeRuler;
+	protected IDoubleClickListener fDblClickListener;
+	protected IAnnotationAccess fAnnotationAccess;
+
+	/**
+	 * Creates a new hover instance.
+	 *
+	 * @param ruler
+	 * @param access
+	 * @param doubleClickListener
+	 */
+	public AnnotationExpandHover(CompositeRuler ruler, IAnnotationAccess access, IDoubleClickListener doubleClickListener) {
+		fCompositeRuler= ruler;
+		fAnnotationAccess= access;
+		fDblClickListener= doubleClickListener;
+	}
+
+	/*
+	 * @see org.eclipse.jface.text.source.IAnnotationHover#getHoverInfo(org.eclipse.jface.text.source.ISourceViewer, int)
+	 */
+	public String getHoverInfo(ISourceViewer sourceViewer, int line) {
+		// we don't have any sensible return value as text
+		return null;
+	}
+
+	protected Object getHoverInfoForLine(ISourceViewer viewer, int line) {
+		IAnnotationModel model= viewer.getAnnotationModel();
+		IDocument document= viewer.getDocument();
+
+		if (model == null)
+			return null;
+
+		List exact= new ArrayList();
+		HashMap messagesAtPosition= new HashMap();
+
+		Iterator e= model.getAnnotationIterator();
+		while (e.hasNext()) {
+			Annotation annotation= (Annotation) e.next();
+			Position position= model.getPosition(annotation);
+			if (position == null)
+				continue;
+
+			if (compareRulerLine(position, document, line) == 1) {
+				if (isDuplicateMessage(messagesAtPosition, position, annotation.getText()))
+					continue;
+
+				exact.add(annotation);
+			}
+		}
+
+		if (exact.size() < 1)
+			return null;
+
+		sort(exact, model);
+
+		if (exact.size() > 0)
+			setLastRulerMouseLocation(viewer, line);
+
+		AnnotationHoverInput input= new AnnotationHoverInput();
+		input.fAnnotations= (Annotation[]) exact.toArray(new Annotation[0]);
+		input.fViewer= viewer;
+		input.fRulerInfo= fCompositeRuler;
+		input.fAnnotationListener= fgListener;
+		input.fDoubleClickListener= fDblClickListener;
+		input.model= model;
+
+		return input;
+	}
+
+	protected void sort(List exact, final IAnnotationModel model) {
+		class AnnotationComparator implements Comparator {
+
+			/*
+			 * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
+			 */
+			public int compare(Object o1, Object o2) {
+				Annotation a1= (Annotation) o1;
+				Annotation a2= (Annotation) o2;
+
+				Position p1= model.getPosition(a1);
+				Position p2= model.getPosition(a2);
+
+				// annotation order:
+				// primary order: by position in line
+				// secondary: annotation importance
+				if (p1.offset == p2.offset)
+					return getOrder(a2) - getOrder(a1);
+				return p1.offset - p2.offset;
+			}
+		}
+
+		Collections.sort(exact, new AnnotationComparator());
+
+	}
+
+	protected int getOrder(Annotation annotation) {
+		if (fAnnotationAccess instanceof IAnnotationAccessExtension) {
+			IAnnotationAccessExtension extension= (IAnnotationAccessExtension) fAnnotationAccess;
+			return extension.getLayer(annotation);
+		}
+		return IAnnotationAccessExtension.DEFAULT_LAYER;
+	}
+
+	protected boolean isDuplicateMessage(Map messagesAtPosition, Position position, String message) {
+		if (message == null)
+			return false;
+		
+		if (messagesAtPosition.containsKey(position)) {
+			Object value= messagesAtPosition.get(position);
+			if (message == null || message.equals(value))
+				return true;
+
+			if (value instanceof List) {
+				List messages= (List)value;
+				if  (messages.contains(message))
+					return true;
+				messages.add(message);
+			} else {
+				ArrayList messages= new ArrayList();
+				messages.add(value);
+				messages.add(message);
+				messagesAtPosition.put(position, messages);
+			}
+		} else
+			messagesAtPosition.put(position, message);
+		return false;
+	}
+
+	protected void setLastRulerMouseLocation(ISourceViewer viewer, int line) {
+		// set last mouse activity in order to get the correct context menu
+		if (fCompositeRuler != null) {
+			StyledText st= viewer.getTextWidget();
+			if (st != null && !st.isDisposed()) {
+				if (viewer instanceof ITextViewerExtension5) {
+					int widgetLine= ((ITextViewerExtension5)viewer).modelLine2WidgetLine(line);
+					Point loc= st.getLocationAtOffset(st.getOffsetAtLine(widgetLine));
+					fCompositeRuler.setLocationOfLastMouseButtonActivity(0, loc.y);
+				} else if (viewer instanceof TextViewer) {
+					// TODO remove once TextViewer implements the extension
+					int widgetLine= ((TextViewer)viewer).modelLine2WidgetLine(line);
+					Point loc= st.getLocationAtOffset(st.getOffsetAtLine(widgetLine));
+					fCompositeRuler.setLocationOfLastMouseButtonActivity(0, loc.y);
+				}
+			}
+		}
+	}
+
+	/**
+	 * Returns the distance to the ruler line.
+	 *
+	 * @param position the position
+	 * @param document the document
+	 * @param line the line number
+	 * @return the distance to the ruler line
+	 */
+	protected int compareRulerLine(Position position, IDocument document, int line) {
+
+		if (position.getOffset() > -1 && position.getLength() > -1) {
+			try {
+				int firstLine= document.getLineOfOffset(position.getOffset());
+				if (line == firstLine)
+					return 1;
+				if (firstLine <= line && line <= document.getLineOfOffset(position.getOffset() + position.getLength()))
+					return 2;
+			} catch (BadLocationException x) {
+			}
+		}
+
+		return 0;
+	}
+
+	/*
+	 * @see org.eclipse.jface.text.source.IAnnotationHoverExtension#getHoverControlCreator()
+	 */
+	public IInformationControlCreator getHoverControlCreator() {
+		return fgCreator;
+	}
+
+	/*
+	 * @see org.eclipse.jface.text.source.IAnnotationHoverExtension#getHoverInfo(org.eclipse.jface.text.source.ISourceViewer, org.eclipse.jface.text.source.ILineRange, int)
+	 */
+	public Object getHoverInfo(ISourceViewer sourceViewer, ILineRange lineRange, int visibleLines) {
+		return getHoverInfoForLine(sourceViewer, lineRange.getStartLine());
+	}
+
+	/*
+	 * @see org.eclipse.jface.text.source.IAnnotationHoverExtension#getHoverLineRange(org.eclipse.jface.text.source.ISourceViewer, int)
+	 */
+	public ILineRange getHoverLineRange(ISourceViewer viewer, int lineNumber) {
+		return new LineRange(lineNumber, 1);
+	}
+
+	/*
+	 * @see org.eclipse.jface.text.source.IAnnotationHoverExtension#canHandleMouseCursor()
+	 */
+	public boolean canHandleMouseCursor() {
+		return true;
+	}
+}
Index: src/net/sourceforge/phpdt/internal/ui/text/java/hover/JavaExpandHover.java
===================================================================
RCS file: src/net/sourceforge/phpdt/internal/ui/text/java/hover/JavaExpandHover.java
diff -N src/net/sourceforge/phpdt/internal/ui/text/java/hover/JavaExpandHover.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ src/net/sourceforge/phpdt/internal/ui/text/java/hover/JavaExpandHover.java	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,204 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.text.java.hover;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+
+import net.sourceforge.phpdt.internal.ui.PHPUiImages;
+import net.sourceforge.phpdt.internal.ui.text.java.hover.AnnotationExpansionControl.AnnotationHoverInput;
+import net.sourceforge.phpdt.ui.PreferenceConstants;
+import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+import net.sourceforge.phpeclipse.phpeditor.IJavaAnnotation;
+import net.sourceforge.phpeclipse.phpeditor.JavaMarkerAnnotation;
+import net.sourceforge.phpeclipse.phpeditor.PHPDocumentProvider.ProblemAnnotation;
+
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IInformationControlExtension2;
+import org.eclipse.jface.text.Position;
+import org.eclipse.jface.text.source.Annotation;
+import org.eclipse.jface.text.source.CompositeRuler;
+import org.eclipse.jface.text.source.IAnnotationAccess;
+import org.eclipse.jface.text.source.IAnnotationAccessExtension;
+import org.eclipse.jface.text.source.IAnnotationModel;
+import org.eclipse.jface.text.source.IAnnotationPresentation;
+import org.eclipse.jface.text.source.ISourceViewer;
+import org.eclipse.jface.text.source.ImageUtilities;
+import org.eclipse.jface.viewers.IDoubleClickListener;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.GC;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.widgets.Canvas;
+import org.eclipse.ui.texteditor.AnnotationPreference;
+import org.eclipse.ui.texteditor.AnnotationPreferenceLookup;
+
+/**
+ *
+ *
+ * @since 3.0
+ */
+public class JavaExpandHover extends AnnotationExpandHover {
+
+	/** Id of the no breakpoint fake annotation */
+	public static final String NO_BREAKPOINT_ANNOTATION= "net.sourceforge.phpdt.internal.ui.NoBreakpointAnnotation"; //$NON-NLS-1$
+
+	private static class NoBreakpointAnnotation extends Annotation implements IAnnotationPresentation {
+
+		public NoBreakpointAnnotation() {
+			super(NO_BREAKPOINT_ANNOTATION, false, JavaHoverMessages.getString("NoBreakpointAnnotation.addBreakpoint"));
+		}
+
+		/*
+		 * @see org.eclipse.jface.text.source.IAnnotationPresentation#paint(org.eclipse.swt.graphics.GC, org.eclipse.swt.widgets.Canvas, org.eclipse.swt.graphics.Rectangle)
+		 */
+		public void paint(GC gc, Canvas canvas, Rectangle bounds) {
+			// draw affordance so the user know she can click here to get a breakpoint
+			Image fImage= PHPUiImages.get(PHPUiImages.IMG_FIELD_PUBLIC);
+			ImageUtilities.drawImage(fImage, gc, canvas, bounds, SWT.CENTER);
+		}
+
+		/*
+		 * @see org.eclipse.jface.text.source.IAnnotationPresentation#getLayer()
+		 */
+		public int getLayer() {
+			return IAnnotationPresentation.DEFAULT_LAYER;
+		}
+	}
+
+	private AnnotationPreferenceLookup fLookup= new AnnotationPreferenceLookup();
+	private IPreferenceStore fStore= PHPeclipsePlugin.getDefault().getCombinedPreferenceStore();
+
+	public JavaExpandHover(CompositeRuler ruler, IAnnotationAccess access, IDoubleClickListener doubleClickListener) {
+		super(ruler, access, doubleClickListener);
+	}
+
+	/*
+	 * @see org.eclipse.ui.internal.texteditor.AnnotationExpandHover#getHoverInfoForLine(org.eclipse.jface.text.source.ISourceViewer, int)
+	 */
+	protected Object getHoverInfoForLine(final ISourceViewer viewer, final int line) {
+		final boolean showTemporaryProblems= PreferenceConstants.getPreferenceStore().getBoolean(PreferenceConstants.EDITOR_CORRECTION_INDICATION);
+		IAnnotationModel model= viewer.getAnnotationModel();
+		IDocument document= viewer.getDocument();
+
+		if (model == null)
+			return null;
+
+		List exact= new ArrayList();
+		HashMap messagesAtPosition= new HashMap();
+
+		Iterator e= model.getAnnotationIterator();
+		while (e.hasNext()) {
+			Annotation annotation= (Annotation) e.next();
+
+			if (fAnnotationAccess instanceof IAnnotationAccessExtension)
+				if (!((IAnnotationAccessExtension)fAnnotationAccess).isPaintable(annotation))
+					continue;
+			
+			if (annotation instanceof IJavaAnnotation && !isIncluded((IJavaAnnotation)annotation, showTemporaryProblems))
+				continue;
+
+			AnnotationPreference pref= fLookup.getAnnotationPreference(annotation);
+			if (pref != null) {
+				String key= pref.getVerticalRulerPreferenceKey();
+				if (key != null && !fStore.getBoolean(key))
+					continue;
+			}
+
+			Position position= model.getPosition(annotation);
+			if (position == null)
+				continue;
+
+			if (compareRulerLine(position, document, line) == 1) {
+
+				if (isDuplicateMessage(messagesAtPosition, position, annotation.getText()))
+					continue;
+
+				exact.add(annotation);
+			}
+		}
+
+		sort(exact, model);
+
+		if (exact.size() > 0)
+			setLastRulerMouseLocation(viewer, line);
+
+		if (exact.size() > 0) {
+			Annotation first= (Annotation) exact.get(0);
+			if (!isBreakpointAnnotation(first))
+				exact.add(0, new NoBreakpointAnnotation());
+		}
+
+		if (exact.size() <= 1)
+			return null;
+
+		AnnotationHoverInput input= new AnnotationHoverInput();
+		input.fAnnotations= (Annotation[]) exact.toArray(new Annotation[0]);
+		input.fViewer= viewer;
+		input.fRulerInfo= fCompositeRuler;
+		input.fAnnotationListener= fgListener;
+		input.fDoubleClickListener= fDblClickListener;
+		input.redoAction= new AnnotationExpansionControl.ICallback() {
+
+			public void run(IInformationControlExtension2 control) {
+				control.setInput(getHoverInfoForLine(viewer, line));
+			}
+
+		};
+		input.model= model;
+
+		return input;
+	}
+
+	private boolean isIncluded(IJavaAnnotation annotation, boolean showTemporaryProblems) {
+		
+		// XXX: see https://bugs.eclipse.org/bugs/show_bug.cgi?id=138601
+		if (annotation instanceof ProblemAnnotation && JavaMarkerAnnotation.TASK_ANNOTATION_TYPE.equals(annotation.getType()))
+			return false;
+		
+		if (!annotation.isProblem())
+			return true;
+		
+		if (annotation.isMarkedDeleted() && !annotation.hasOverlay())
+			return true;
+		
+		if (annotation.hasOverlay() && !annotation.isMarkedDeleted())
+			return true;
+		
+		
+		if (annotation.hasOverlay())
+			return (!isIncluded(annotation.getOverlay(), showTemporaryProblems));
+		
+		return showTemporaryProblems; //&& JavaCorrectionProcessor.hasCorrections((Annotation)annotation);
+	}
+
+	/*
+	 * @see org.eclipse.ui.internal.texteditor.AnnotationExpandHover#getOrder(org.eclipse.jface.text.source.Annotation)
+	 */
+	protected int getOrder(Annotation annotation) {
+		if (isBreakpointAnnotation(annotation)) 
+			return 1000;
+		else
+			return super.getOrder(annotation);
+	}
+
+	private boolean isBreakpointAnnotation(Annotation a) {
+		if (a instanceof JavaMarkerAnnotation) {
+			JavaMarkerAnnotation jma= (JavaMarkerAnnotation) a;
+			// HACK to get breakpoints to show up first
+			return jma.getType().equals("org.eclipse.debug.core.breakpoint"); //$NON-NLS-1$
+		}
+		return false;
+	}
+}