docs: function Tooltip(options) {
  		var currentSeries,
  			borderWidth = options.borderWidth,
  			crosshairsOptions = options.crosshairs,
  			crosshairs = [],
  			style = options.style,
  			shared = options.shared,
  			padding = pInt(style.padding),
  			boxOffLeft = borderWidth + padding, // off left/top position as IE can't
  				//properly handle negative positioned shapes
  			tooltipIsHidden = true,
  			boxWidth,
  			boxHeight,
  			currentX = 0,
  			currentY = 0;
  
  		// remove padding CSS and apply padding on box instead
  		style.padding = 0;
  
  		// create the elements
  		var group = renderer.g('tooltip')
  			.attr({	zIndex: 8 })
  			.add(),
  
  			box = renderer.rect(boxOffLeft, boxOffLeft, 0, 0, options.borderRadius, borderWidth)
  				.attr({
  					fill: options.backgroundColor,
  					'stroke-width': borderWidth
  				})
  				.add(group)
  				.shadow(options.shadow),
  			label = renderer.text('', padding + boxOffLeft, pInt(style.fontSize) + padding + boxOffLeft, options.useHTML)
  				.attr({ zIndex: 1 })
  				.css(style)
  				.add(group);
  
  		group.hide();
  
  		/**
  		 * Destroy the tooltip and its elements.
  		 */
  		function destroy() {
  			each(crosshairs, function (crosshair) {
  				if (crosshair) {
  					crosshair.destroy();
  				}
  			});
  
  			// Destroy and clear local variables
  			each([box, label, group], function (obj) {
  				if (obj) {
  					obj.destroy();
  				}
  			});
  			box = label = group = null;
  		}
  
  		/**
  		 * In case no user defined formatter is given, this will be used
  		 */
  		function defaultFormatter() {
  			var pThis = this,
  				items = pThis.points || splat(pThis),
  				xAxis = items[0].series.xAxis,
  				x = pThis.x,
  				isDateTime = xAxis && xAxis.options.type === 'datetime',
  				useHeader = isString(x) || isDateTime,
  				s;
  
  			// build the header
  			s = useHeader ?
  				['<span style="font-size: 10px">' +
  				(isDateTime ? dateFormat('%A, %b %e, %Y', x) :  x) +
  				'</span>'] : [];
  
  			// build the values
  			each(items, function (item) {
  				s.push(item.point.tooltipFormatter(useHeader));
  			});
  			return s.join('<br/>');
  		}
  
  		/**
  		 * Provide a soft movement for the tooltip
  		 *
  		 * @param {Number} finalX
  		 * @param {Number} finalY
  		 */
  		function move(finalX, finalY) {
  		    
  		    // PATCH here by Simon Fishel
              //
              // - currentX = tooltipIsHidden ? finalX : (2 * currentX + finalX) / 3;
              // - currentY = tooltipIsHidden ? finalY : (currentY + finalY) / 2;
              // + currentX = finalX;
              // + currentY = finalY;
              //
              // disable tooltip animation, instead just jump directly to the final location
              
              currentX = finalX;
              currentY = finalY;
  
  			group.translate(currentX, currentY);
  
  
  			// run on next tick of the mouse tracker
  			if (mathAbs(finalX - currentX) > 1 || mathAbs(finalY - currentY) > 1) {
  				tooltipTick = function () {
  					move(finalX, finalY);
  				};
  			} else {
  				tooltipTick = null;
  			}
  		}
  
  		/**
  		 * Hide the tooltip
  		 */
  		function hide() {
  			if (!tooltipIsHidden) {
  				var hoverPoints = chart.hoverPoints;
  
  				group.hide();
  
  				each(crosshairs, function (crosshair) {
  					if (crosshair) {
  						crosshair.hide();
  					}
  				});
  
  				// hide previous hoverPoints and set new
  				if (hoverPoints) {
  					each(hoverPoints, function (point) {
  						point.setState();
  					});
  				}
  				chart.hoverPoints = null;
  
  
  				tooltipIsHidden = true;
  			}
  
  		}
  
  		/**
  		 * Refresh the tooltip's text and position.
  		 * @param {Object} point
  		 *
  		 */
  		function refresh(point) {
  			var x,
  				y,
  				show,
  				bBox,
  				plotX,
  				plotY = 0,
  				textConfig = {},
  				text,
  				pointConfig = [],
  				tooltipPos = point.tooltipPos,
  				formatter = options.formatter || defaultFormatter,
  				hoverPoints = chart.hoverPoints,
  				placedTooltipPoint;
  
  			// shared tooltip, array is sent over
  			if (shared) {
  
  				// hide previous hoverPoints and set new
  				if (hoverPoints) {
  					each(hoverPoints, function (point) {
  						point.setState();
  					});
  				}
  				chart.hoverPoints = point;
  
  				each(point, function (item) {
  					/*var series = item.series,
  						hoverPoint = series.hoverPoint;
  					if (hoverPoint) {
  						hoverPoint.setState();
  					}
  					series.hoverPoint = item;*/
  					item.setState(HOVER_STATE);
  					plotY += item.plotY; // for average
  
  					pointConfig.push(item.getLabelConfig());
  				});
  
  				plotX = point[0].plotX;
  				plotY = mathRound(plotY) / point.length; // mathRound because Opera 10 has problems here
  
  				textConfig = {
  					x: point[0].category
  				};
  				textConfig.points = pointConfig;
  				point = point[0];
  
  			// single point tooltip
  			} else {
  				textConfig = point.getLabelConfig();
  			}
  			text = formatter.call(textConfig);
  
  			// register the current series
  			currentSeries = point.series;
  
  			// get the reference point coordinates (pie charts use tooltipPos)
  			plotX = shared ? plotX : point.plotX;
  			plotY = shared ? plotY : point.plotY;
  			
  			// PATCH here by Simon Fishel
              //
              // + if(point.series.chart.options.chart.type in {column: true, bar: true}) {
              // +     plotY = Math.max(plotY, 0);
              // + }
              //
              // adjust the y position so the tooltip will show up even if the value is off the chart
              // for column/bar charts
              
              if(point.series.chart.options.chart.type in {column: true, bar: true}) {
                  plotY = Math.max(plotY, 0);
              }
              
              // PATCH here by Simon Fishel
              //
              // + if(point.series.chart.options.chart.type === 'column') {
              // +     plotX = point.barX;
              // + }
              //
              // adjustment to the tooltip horizontal position for column charts
              
              if(point.series.chart.options.chart.type === 'column') {
                  plotX = point.barX;
              }
  			
  			x = mathRound(tooltipPos ? tooltipPos[0] : (inverted ? plotWidth - plotY : plotX));
  			y = mathRound(tooltipPos ? tooltipPos[1] : (inverted ? plotHeight - plotX : plotY));
  
  
  			// hide tooltip if the point falls outside the plot
  			show = shared || !point.series.isCartesian || isInsidePlot(x, y);
  
  			// update the inner HTML
  			if (text === false || !show) {
  				hide();
  			} else {
  
  				// show it
  				if (tooltipIsHidden) {
  					group.show();
  					tooltipIsHidden = false;
  				}
  
  				// update text
  				label.attr({
  					text: text
  				});
  
  				// get the bounding box
  				bBox = label.getBBox();
  				boxWidth = bBox.width + 2 * padding;
  				boxHeight = bBox.height + 2 * padding;
  
  				// set the size of the box
  				box.attr({
  					width: boxWidth,
  					height: boxHeight,
  					stroke: options.borderColor || point.color || currentSeries.color || '#606060'
  				});
  
  				placedTooltipPoint = placeBox(boxWidth, boxHeight, plotLeft, plotTop, plotWidth, plotHeight, {x: x, y: y});
  
  				// do the move
  				move(mathRound(placedTooltipPoint.x - boxOffLeft), mathRound(placedTooltipPoint.y - boxOffLeft));
  			}
  
  
  			// crosshairs
  			if (crosshairsOptions) {
  				crosshairsOptions = splat(crosshairsOptions); // [x, y]
  
  				var path,
  					i = crosshairsOptions.length,
  					attribs,
  					axis;
  
  				while (i--) {
  					axis = point.series[i ? 'yAxis' : 'xAxis'];
  					if (crosshairsOptions[i] && axis) {
  						path = axis
  							.getPlotLinePath(point[i ? 'y' : 'x'], 1);
  						if (crosshairs[i]) {
  							crosshairs[i].attr({ d: path, visibility: VISIBLE });
  
  						} else {
  							attribs = {
  								'stroke-width': crosshairsOptions[i].width || 1,
  								stroke: crosshairsOptions[i].color || '#C0C0C0',
  								zIndex: 2
  							};
  							if (crosshairsOptions[i].dashStyle) {
  								attribs.dashstyle = crosshairsOptions[i].dashStyle;
  							}
  							crosshairs[i] = renderer.path(path)
  								.attr(attribs)
  								.add();
  						}
  					}
  				}
  			}
  		}
  
  
  
  		// public members
  		return {
  			shared: shared,
  			refresh: refresh,
  			hide: hide,
  			destroy: destroy
  		};
  	}