docs: function (bounds, vertex, next, orthogonal)
  	{
  		var direction = (vertex != null) ?
  			vertex.style[mxConstants.STYLE_DIRECTION] : null;
  		var vertical = direction == mxConstants.DIRECTION_NORTH ||
  			direction == mxConstants.DIRECTION_SOUTH;
  
  		var x = bounds.x;
  		var y = bounds.y;
  		var w = bounds.width;
  		var h = bounds.height;
  		
  		var cx = x + w / 2;
  		var cy = y + h / 2;
  		
  		var start = new mxPoint(x, y);
  		var corner = new mxPoint(x + w, cy);
  		var end = new mxPoint(x, y + h);
  		
  		if (direction == mxConstants.DIRECTION_NORTH)
  		{
  			start = end;
  			corner = new mxPoint(cx, y);
  			end = new mxPoint(x + w, y + h);
  		}
  		else if (direction == mxConstants.DIRECTION_SOUTH)
  		{
  			corner = new mxPoint(cx, y + h);
  			end = new mxPoint(x + w, y);
  		}
  		else if (direction == mxConstants.DIRECTION_WEST)
  		{
  			start = new mxPoint(x + w, y);
  			corner = new mxPoint(x, cy);
  			end = new mxPoint(x + w, y + h);
  		}
  
  		var dx = next.x - cx;
  		var dy = next.y - cy;
  
  		var alpha = (vertical) ? Math.atan2(dx, dy) : Math.atan2(dy, dx);
  		var t = (vertical) ? Math.atan2(w, h) : Math.atan2(h, w);
  		
  		var base = false;
  		
  		if (direction == mxConstants.DIRECTION_NORTH ||
  			direction == mxConstants.DIRECTION_WEST)
  		{
  			base = alpha > -t && alpha < t;
  		}
  		else
  		{
  			base = alpha < -Math.PI + t || alpha > Math.PI - t;	
  		}
  
  		var result = null;			
  
  		if (base)
  		{
  			if (orthogonal && ((vertical && next.x >= start.x && next.x <= end.x) ||
  				(!vertical && next.y >= start.y && next.y <= end.y)))
  			{
  				if (vertical)
  				{
  					result = new mxPoint(next.x, start.y);
  				}
  				else
  				{
  					result = new mxPoint(start.x, next.y);
  				}
  			}
  			else
  			{
  				if (direction == mxConstants.DIRECTION_NORTH)
  				{
  					result = new mxPoint(x + w / 2 + h * Math.tan(alpha) / 2,
  						y + h);
  				}
  				else if (direction == mxConstants.DIRECTION_SOUTH)
  				{
  					result = new mxPoint(x + w / 2 - h * Math.tan(alpha) / 2,
  						y);
  				}
  				else if (direction == mxConstants.DIRECTION_WEST)
  				{
  					result = new mxPoint(x + w, y + h / 2 +
  						w * Math.tan(alpha) / 2);
  				}
  				else
  				{
  					result = new mxPoint(x, y + h / 2 -
  						w * Math.tan(alpha) / 2);
  				}
  			}
  		}
  		else
  		{
  			if (orthogonal)
  			{
  				var pt = new mxPoint(cx, cy);
  		
  				if (next.y >= y && next.y <= y + h)
  				{
  					pt.x = (vertical) ? cx : (
  						(direction == mxConstants.DIRECTION_WEST) ?
  							x + w : x);
  					pt.y = next.y;
  				}
  				else if (next.x >= x && next.x <= x + w)
  				{
  					pt.x = next.x;
  					pt.y = (!vertical) ? cy : (
  						(direction == mxConstants.DIRECTION_NORTH) ?
  							y + h : y);
  				}
  				
  				// Compute angle
  				dx = next.x - pt.x;
  				dy = next.y - pt.y;
  				
  				cx = pt.x;
  				cy = pt.y;
  			}
  
  			if ((vertical && next.x <= x + w / 2) ||
  				(!vertical && next.y <= y + h / 2))
  			{
  				result = mxUtils.intersection(next.x, next.y, cx, cy,
  					start.x, start.y, corner.x, corner.y);
  			}
  			else
  			{
  				result = mxUtils.intersection(next.x, next.y, cx, cy,
  					corner.x, corner.y, end.x, end.y);
  			}
  		}
  		
  		if (result == null)
  		{
  			result = new mxPoint(cx, cy);
  		}
  		
  		return result;
  	}