Index: D:/eclipse/workspace/mapbuilder/lib/widget/TipWidgetOL.js
===================================================================
--- D:/eclipse/workspace/mapbuilder/lib/widget/TipWidgetOL.js	(revision 2967)
+++ D:/eclipse/workspace/mapbuilder/lib/widget/TipWidgetOL.js	(working copy)
@@ -16,7 +16,7 @@
  * @param model  The ButtonBar widget.
  */
 function TipWidgetOL(widgetNode, model) {
-   WidgetBaseXSL.apply(this, new Array(widgetNode, model));
+  WidgetBaseXSL.apply(this, new Array(widgetNode, model));
 
   var width = widgetNode.selectSingleNode('mb:width');
   this.width = width ? width.firstChild.nodeValue : 200;
@@ -31,28 +31,70 @@
 
   /**
    * This method is triggered when a user clicks on a feature.
-   * It called by OpenLayers event handling in the context
-   * of a feature. This means that 'this' in this method refers
-   * to an {OpenLayers.Feature}
-   * @param evt OpenLayers event
+   * @param objRef reference to this widget
    */
   this.onClick = function(objRef) {
     var evt = objRef.model.getParam("olFeatureSelect");
+		var popup = objRef.displayPopup(objRef, evt, false);
+    evt.feature.mbClickPopup = popup;
+  }
+  
+  /**
+   * This method is triggered when the mouse is over a feature.
+   * @param objRef reference to this widget
+   */
+  this.onMouseover = function(objRef) {
+    var evt = objRef.model.getParam("olFeatureHover");
+    // only create popup if there is no visible click popup
+    if (!evt.feature.mbClickPopup || !evt.feature.mbClickPopup.visible()) {
+      var popup = objRef.displayPopup(objRef, evt, true);
+      evt.feature.mbHoverPopup = popup;
+    }
+  }
+  
+  /**
+   * This method is triggered when the mouse moves out of a feature.
+   * @param objRef reference to this widget
+   */
+  this.onMouseout = function(objRef) {
+    var feature = objRef.model.getParam("olFeatureOut");
+    if (feature.mbHoverPopup) {
+      feature.mbHoverPopup.destroy();
+      feature.mbHoverPopup = null;
+    }
+  }
+  
+  /**
+   * Displays a popup.
+   * @param objRef reference to this widget
+   * @param evt OpenLayers.Event that triggered the popup action
+   * @param hover true if the popup should be styled as a hover popup,
+   * false if it is a click popup.
+   * @return reference to the created popup
+   */
+  this.displayPopup = function(objRef, evt, hover) {
     var feature = evt.feature;
     objRef.stylesheet.setParameter('fid', feature.fid);
     var lonlat = feature.layer.map.getLonLatFromPixel(evt.xy);
     var popup = new OpenLayers.Popup.Anchored();
+    
     popup.padding = 0;
     popup.initialize(null, lonlat, new OpenLayers.Size(objRef.width, objRef.height),
         new XMLSerializer().serializeToString(objRef.stylesheet.transformNodeToObject(objRef.model.doc)),
-        null, true);
+        null, hover == false);
     popup.setOpacity(objRef.opacity);
     popup.setBackgroundColor(objRef.backgroundColor);
     popup.setBorder(objRef.border);
+    var quadrant = feature.layer.map.getExtent().determineQuadrant(lonlat);
+    var lonOffset = quadrant.charAt(1) == 'r' ? -5 : 5;
+    var latOffset = quadrant.charAt(0) == 't' ? 5 : -5;
+    popup.anchor = { size: new OpenLayers.Size(0,0), offset: new OpenLayers.Pixel(lonOffset, latOffset)};    
+    
     feature.layer.map.addPopup(popup, true);
     // stop the event so other tools will not be triggered
     // when the user clicked on a feature.
     OpenLayers.Event.stop(evt);
+    return popup;
   }
   
 }
Index: D:/eclipse/workspace/mapbuilder/lib/widget/GmlRendererOL.js
===================================================================
--- D:/eclipse/workspace/mapbuilder/lib/widget/GmlRendererOL.js	(revision 2967)
+++ D:/eclipse/workspace/mapbuilder/lib/widget/GmlRendererOL.js	(working copy)
@@ -269,6 +269,12 @@
       var clickWidget = config.objects[clickWidgetNode.firstChild.nodeValue];
       objRef.model.addListener("olFeatureSelect", clickWidget.onClick, clickWidget);
     }
+    var hoverWidgetNode =  widgetNode.selectSingleNode("mb:featureOnHover");
+    if (hoverWidgetNode) {
+      var hoverWidget = config.objects[hoverWidgetNode.firstChild.nodeValue];
+      objRef.model.addListener("olFeatureHover", hoverWidget.onMouseover, hoverWidget);
+      objRef.model.addListener("olFeatureOut", hoverWidget.onMouseout, hoverWidget);
+    }
     objRef.targetModel.addListener("aoi", objRef.removeHiddenFeatures, objRef);
   }
   this.model.addListener("init", this.init, this);
Index: D:/eclipse/workspace/mapbuilder/lib/tool/FeatureSelectHandler.js
===================================================================
--- D:/eclipse/workspace/mapbuilder/lib/tool/FeatureSelectHandler.js	(revision 2967)
+++ D:/eclipse/workspace/mapbuilder/lib/tool/FeatureSelectHandler.js	(working copy)
@@ -109,10 +109,10 @@
   
   /**
    * This method is triggered when the mouse is over a vector
-   * feature. It registers a priority event onmousedown, which
-   * will call this widget's onClick method in the context
-   * of a feature. This way we address two problems with
-   * the OpenLayers SelectFeature control:<pre>
+   * feature. It registers priority events mousedown and
+   * mousemove, which will call this widget's onClick/onHover
+   * method in the context of a feature. This way we address
+   * two problems with the OpenLayers SelectFeature control:<pre>
    *      - for the info popup, we need the screen coordinates
    *        which we do not get from the handler directly.
    *      - when the active tool changes, something in the
@@ -133,6 +133,7 @@
     feature.mbFeatureSelectHandler = objRef;
     if (feature.layer.events) {
       feature.layer.events.registerPriority('mousedown', feature, objRef.onClick);
+      feature.layer.events.registerPriority('mousemove', feature, objRef.onHover);
     }
   }
   
@@ -148,6 +149,7 @@
     for (var i in objRef.sourceModels) {
       objRef.sourceModels[i].setParam("mouseoutFeature", feature.fid);
     }
+    objRef.model.setParam("olFeatureOut", feature);
     if (feature.layer.events) {
       feature.layer.events.unregister('mousedown', feature, objRef.onClick);
     }
@@ -166,9 +168,28 @@
     // pass the feature to the event object
     evt.feature = this;
     var objRef = this.mbFeatureSelectHandler;
-    for (var i in objRef.sourceModels) {
-      objRef.sourceModels[i].setParam("olFeatureSelect", evt);
+    objRef.model.setParam("olFeatureSelect", evt);
+    OpenLayers.Event.stop(evt);
+  }
+  
+  /**
+   * This method is triggered when the mouse is over a feature.
+   * It is called by OpenLayers event handling in the context
+   * of a feature. This means that 'this' in this method refers
+   * to an {OpenLayers.Feature}. Widgets listening to the
+   * olFeatureHover have access to the event, because setParam
+   * is used to set the reference to the event.
+   * @param evt OpenLayers event
+   */
+  this.onHover = function(evt) {
+    evt.feature = this;
+    var objRef = this.mbFeatureSelectHandler;
+    if (evt.feature.layer.events) {
+      // unregister the mousemove event, because we already know that
+      // the mouse moved and we can then proceed to our hover popup.
+      evt.feature.layer.events.unregister('mousemove', evt.feature, objRef.onHover);
     }
+    objRef.model.setParam("olFeatureHover", evt);
     OpenLayers.Event.stop(evt);
   }
 
