docs: function(state, source, target, points, result)
  	{
  		var view = state.view;
  		var pt = (points != null && points.length > 0) ? points[0] : null;
  		var pts = state.absolutePoints;
  		var p0 = pts[0];
  		var pe = pts[pts.length-1];
  		
  		if (pt != null)
  		{
  			pt = view.transformControlPoint(state, pt);
  		}
  		
  		if (p0 != null)
  		{
  			source = new mxCellState();
  			source.x = p0.x;
  			source.y = p0.y;
  		}
  		
  		if (pe != null)
  		{
  			target = new mxCellState();
  			target.x = pe.x;
  			target.y = pe.y;
  		}
  
  		if (source != null && target != null)
  		{
  			var t = Math.max(source.y, target.y);
  			var b = Math.min(source.y + source.height,
  							 target.y + target.height);
  	
  			var x = view.getRoutingCenterX(source);
  			
  			if (pt != null &&
  				pt.x >= source.x &&
  				pt.x <= source.x + source.width)
  			{
  				x = pt.x;
  			}
  			
  			var y = (pt != null) ? pt.y : Math.round(b + (t - b) / 2);
  			
  			if (!mxUtils.contains(target, x, y) &&
  				!mxUtils.contains(source, x, y))
  			{
  				result.push(new mxPoint(x, y));						
  			}
  			
  			if (pt != null &&
  				pt.x >= target.x &&
  				pt.x <= target.x + target.width)
  			{
  				x = pt.x;
  			}
  			else
  			{
  				x = view.getRoutingCenterX(target);
  			}
  			
  			if (!mxUtils.contains(target, x, y) &&
  				!mxUtils.contains(source, x, y))
  			{
  				result.push(new mxPoint(x, y));						
  			}
  			
  			if (result.length == 1)
  			{
  				if (pt != null && result.length == 1)
  				{
  					if (!mxUtils.contains(target, pt.x, y) &&
  						!mxUtils.contains(source, pt.x, y))
  					{
  						result.push(new mxPoint(pt.x, y));
  					}
  				}
  				else
  				{
  					var l = Math.max(source.x, target.x);
  					var r = Math.min(source.x + source.width,
  							 target.x + target.width);
  						 
  					result.push(new mxPoint(l + (r - l) / 2, y));
  				}
  			}
  		}
  	}