/**
 * Copyright (c) 2006-2015, JGraph Ltd
 * Copyright (c) 2006-2015, Gaudenz Alder
 */
/**
 * Class: mxGraph
 *
 * Extends <mxEventSource> to implement a graph component for
 * the browser. This is the main class of the package. To activate
 * panning and connections use <setPanning> and <setConnectable>.
 * For rubberband selection you must create a new instance of
 * <mxRubberband>. The following listeners are added to
 * <mouseListeners> by default:
 * 
 * - <tooltipHandler>: <mxTooltipHandler> that displays tooltips
 * - <panningHandler>: <mxPanningHandler> for panning and popup menus
 * - <connectionHandler>: <mxConnectionHandler> for creating connections
 * - <graphHandler>: <mxGraphHandler> for moving and cloning cells
 * 
 * These listeners will be called in the above order if they are enabled.
 *
 * Background Images:
 * 
 * To display a background image, set the image, image width and
 * image height using <setBackgroundImage>. If one of the
 * above values has changed then the <view>'s <mxGraphView.validate>
 * should be invoked.
 * 
 * Cell Images:
 * 
 * To use images in cells, a shape must be specified in the default
 * vertex style (or any named style). Possible shapes are
 * <mxConstants.SHAPE_IMAGE> and <mxConstants.SHAPE_LABEL>.
 * The code to change the shape used in the default vertex style,
 * the following code is used:
 * 
 * (code)
 * var style = graph.getStylesheet().getDefaultVertexStyle();
 * style[mxConstants.STYLE_SHAPE] = mxConstants.SHAPE_IMAGE;
 * (end)
 * 
 * For the default vertex style, the image to be displayed can be
 * specified in a cell's style using the <mxConstants.STYLE_IMAGE>
 * key and the image URL as a value, for example:
 * 
 * (code)
 * image=http://www.example.com/image.gif
 * (end)
 * 
 * For a named style, the the stylename must be the first element
 * of the cell style:
 * 
 * (code)
 * stylename;image=http://www.example.com/image.gif
 * (end)
 * 
 * A cell style can have any number of key=value pairs added, divided
 * by a semicolon as follows:
 * 
 * (code)
 * [stylename;|key=value;]
 * (end)
 *
 * Labels:
 * 
 * The cell labels are defined by <getLabel> which uses <convertValueToString>
 * if <labelsVisible> is true. If a label must be rendered as HTML markup, then
 * <isHtmlLabel> should return true for the respective cell. If all labels
 * contain HTML markup, <htmlLabels> can be set to true. NOTE: Enabling HTML
 * labels carries a possible security risk (see the section on security in
 * the manual).
 * 
 * If wrapping is needed for a label, then <isHtmlLabel> and <isWrapping> must
 * return true for the cell whose label should be wrapped. See <isWrapping> for
 * an example.
 * 
 * If clipping is needed to keep the rendering of a HTML label inside the
 * bounds of its vertex, then <isClipping> should return true for the
 * respective cell.
 * 
 * By default, edge labels are movable and vertex labels are fixed. This can be
 * changed by setting <edgeLabelsMovable> and <vertexLabelsMovable>, or by
 * overriding <isLabelMovable>.
 *
 * In-place Editing:
 * 
 * In-place editing is started with a doubleclick or by typing F2.
 * Programmatically, <edit> is used to check if the cell is editable
 * (<isCellEditable>) and call <startEditingAtCell>, which invokes
 * <mxCellEditor.startEditing>. The editor uses the value returned
 * by <getEditingValue> as the editing value.
 * 
 * After in-place editing, <labelChanged> is called, which invokes
 * <mxGraphModel.setValue>, which in turn calls
 * <mxGraphModel.valueForCellChanged> via <mxValueChange>.
 * 
 * The event that triggers in-place editing is passed through to the
 * <cellEditor>, which may take special actions depending on the type of the
 * event or mouse location, and is also passed to <getEditingValue>. The event
 * is then passed back to the event processing functions which can perform
 * specific actions based on the trigger event.
 * 
 * Tooltips:
 * 
 * Tooltips are implemented by <getTooltip>, which calls <getTooltipForCell>
 * if a cell is under the mousepointer. The default implementation checks if
 * the cell has a getTooltip function and calls it if it exists. Hence, in order
 * to provide custom tooltips, the cell must provide a getTooltip function, or 
 * one of the two above functions must be overridden.
 * 
 * Typically, for custom cell tooltips, the latter function is overridden as
 * follows:
 * 
 * (code)
 * graph.getTooltipForCell = function(cell)
 * {
 *   var label = this.convertValueToString(cell);
 *   return 'Tooltip for '+label;
 * }
 * (end)
 * 
 * When using a config file, the function is overridden in the mxGraph section
 * using the following entry:
 * 
 * (code)
 * <add as="getTooltipForCell"><![CDATA[
 *   function(cell)
 *   {
 *     var label = this.convertValueToString(cell);
 *     return 'Tooltip for '+label;
 *   }
 * ]]></add>
 * (end)
 * 
 * "this" refers to the graph in the implementation, so for example to check if 
 * a cell is an edge, you use this.getModel().isEdge(cell)
 *
 * For replacing the default implementation of <getTooltipForCell> (rather than 
 * replacing the function on a specific instance), the following code should be 
 * used after loading the JavaScript files, but before creating a new mxGraph 
 * instance using <mxGraph>:
 * 
 * (code)
 * mxGraph.prototype.getTooltipForCell = function(cell)
 * {
 *   var label = this.convertValueToString(cell);
 *   return 'Tooltip for '+label;
 * }
 * (end)
 * 
 * Shapes & Styles:
 * 
 * The implementation of new shapes is demonstrated in the examples. We'll assume
 * that we have implemented a custom shape with the name BoxShape which we want
 * to use for drawing vertices. To use this shape, it must first be registered in
 * the cell renderer as follows:
 * 
 * (code)
 * mxCellRenderer.registerShape('box', BoxShape);
 * (end)
 * 
 * The code registers the BoxShape constructor under the name box in the cell
 * renderer of the graph. The shape can now be referenced using the shape-key in
 * a style definition. (The cell renderer contains a set of additional shapes,
 * namely one for each constant with a SHAPE-prefix in <mxConstants>.)
 *
 * Styles are a collection of key, value pairs and a stylesheet is a collection
 * of named styles. The names are referenced by the cellstyle, which is stored
 * in <mxCell.style> with the following format: [stylename;|key=value;]. The
 * string is resolved to a collection of key, value pairs, where the keys are
 * overridden with the values in the string.
 *
 * When introducing a new shape, the name under which the shape is registered
 * must be used in the stylesheet. There are three ways of doing this:
 * 
 *   - By changing the default style, so that all vertices will use the new
 * 		shape
 *   - By defining a new style, so that only vertices with the respective
 * 		cellstyle will use the new shape
 *   - By using shape=box in the cellstyle's optional list of key, value pairs
 * 		to be overridden
 *
 * In the first case, the code to fetch and modify the default style for
 * vertices is as follows:
 * 
 * (code)
 * var style = graph.getStylesheet().getDefaultVertexStyle();
 * style[mxConstants.STYLE_SHAPE] = 'box';
 * (end)
 * 
 * The code takes the default vertex style, which is used for all vertices that
 * do not have a specific cellstyle, and modifies the value for the shape-key
 * in-place to use the new BoxShape for drawing vertices. This is done by
 * assigning the box value in the second line, which refers to the name of the
 * BoxShape in the cell renderer.
 * 
 * In the second case, a collection of key, value pairs is created and then
 * added to the stylesheet under a new name. In order to distinguish the
 * shapename and the stylename we'll use boxstyle for the stylename:
 * 
 * (code)
 * var style = new Object();
 * style[mxConstants.STYLE_SHAPE] = 'box';
 * style[mxConstants.STYLE_STROKECOLOR] = '#000000';
 * style[mxConstants.STYLE_FONTCOLOR] = '#000000';
 * graph.getStylesheet().putCellStyle('boxstyle', style);
 * (end)
 * 
 * The code adds a new style with the name boxstyle to the stylesheet. To use
 * this style with a cell, it must be referenced from the cellstyle as follows:
 * 
 * (code)
 * var vertex = graph.insertVertex(parent, null, 'Hello, World!', 20, 20, 80, 20,
 * 				'boxstyle');
 * (end)
 * 
 * To summarize, each new shape must be registered in the <mxCellRenderer> with
 * a unique name. That name is then used as the value of the shape-key in a
 * default or custom style. If there are multiple custom shapes, then there
 * should be a separate style for each shape.
 * 
 * Inheriting Styles:
 * 
 * For fill-, stroke-, gradient- and indicatorColors special keywords can be
 * used. The inherit keyword for one of these colors will inherit the color
 * for the same key from the parent cell. The swimlane keyword does the same,
 * but inherits from the nearest swimlane in the ancestor hierarchy. Finally,
 * the indicated keyword will use the color of the indicator as the color for
 * the given key.
 * 
 * Scrollbars:
 * 
 * The <containers> overflow CSS property defines if scrollbars are used to
 * display the graph. For values of 'auto' or 'scroll', the scrollbars will
 * be shown. Note that the <resizeContainer> flag is normally not used
 * together with scrollbars, as it will resize the container to match the
 * size of the graph after each change.
 * 
 * Multiplicities and Validation:
 * 
 * To control the possible connections in mxGraph, <getEdgeValidationError> is
 * used. The default implementation of the function uses <multiplicities>,
 * which is an array of <mxMultiplicity>. Using this class allows to establish
 * simple multiplicities, which are enforced by the graph.
 * 
 * The <mxMultiplicity> uses <mxCell.is> to determine for which terminals it
 * applies. The default implementation of <mxCell.is> works with DOM nodes (XML
 * nodes) and checks if the given type parameter matches the nodeName of the
 * node (case insensitive). Optionally, an attributename and value can be
 * specified which are also checked.
 * 
 * <getEdgeValidationError> is called whenever the connectivity of an edge
 * changes. It returns an empty string or an error message if the edge is
 * invalid or null if the edge is valid. If the returned string is not empty
 * then it is displayed as an error message.
 * 
 * <mxMultiplicity> allows to specify the multiplicity between a terminal and
 * its possible neighbors. For example, if any rectangle may only be connected
 * to, say, a maximum of two circles you can add the following rule to
 * <multiplicities>:
 * 
 * (code)
 * graph.multiplicities.push(new mxMultiplicity(
 *   true, 'rectangle', null, null, 0, 2, ['circle'],
 *   'Only 2 targets allowed',
 *   'Only shape targets allowed'));
 * (end)
 * 
 * This will display the first error message whenever a rectangle is connected
 * to more than two circles and the second error message if a rectangle is
 * connected to anything but a circle.
 * 
 * For certain multiplicities, such as a minimum of 1 connection, which cannot
 * be enforced at cell creation time (unless the cell is created together with
 * the connection), mxGraph offers <validate> which checks all multiplicities
 * for all cells and displays the respective error messages in an overlay icon
 * on the cells.
 * 
 * If a cell is collapsed and contains validation errors, a respective warning
 * icon is attached to the collapsed cell.
 * 
 * Auto-Layout:
 * 
 * For automatic layout, the <getLayout> hook is provided in <mxLayoutManager>.
 * It can be overridden to return a layout algorithm for the children of a
 * given cell.
 * 
 * Unconnected edges:
 * 
 * The default values for all switches are designed to meet the requirements of
 * general diagram drawing applications. A very typical set of settings to
 * avoid edges that are not connected is the following:
 * 
 * (code)
 * graph.setAllowDanglingEdges(false);
 * graph.setDisconnectOnMove(false);
 * (end)
 * 
 * Setting the <cloneInvalidEdges> switch to true is optional. This switch
 * controls if edges are inserted after a copy, paste or clone-drag if they are
 * invalid. For example, edges are invalid if copied or control-dragged without 
 * having selected the corresponding terminals and allowDanglingEdges is
 * false, in which case the edges will not be cloned if the switch is false.
 * 
 * Output:
 * 
 * To produce an XML representation for a diagram, the following code can be
 * used.
 * 
 * (code)
 * var enc = new mxCodec(mxUtils.createXmlDocument());
 * var node = enc.encode(graph.getModel());
 * (end)
 * 
 * This will produce an XML node than can be handled using the DOM API or
 * turned into a string representation using the following code:
 * 
 * (code)
 * var xml = mxUtils.getXml(node);
 * (end)
 * 
 * To obtain a formatted string, mxUtils.getPrettyXml can be used instead.
 * 
 * This string can now be stored in a local persistent storage (for example
 * using Google Gears) or it can be passed to a backend using mxUtils.post as
 * follows. The url variable is the URL of the Java servlet, PHP page or HTTP
 * handler, depending on the server.
 * 
 * (code)
 * var xmlString = encodeURIComponent(mxUtils.getXml(node));
 * mxUtils.post(url, 'xml='+xmlString, function(req)
 * {
 *   // Process server response using req of type mxXmlRequest
 * });
 * (end)
 * 
 * Input:
 * 
 * To load an XML representation of a diagram into an existing graph object
 * mxUtils.load can be used as follows. The url variable is the URL of the Java
 * servlet, PHP page or HTTP handler that produces the XML string.
 * 
 * (code)
 * var xmlDoc = mxUtils.load(url).getXml();
 * var node = xmlDoc.documentElement;
 * var dec = new mxCodec(node.ownerDocument);
 * dec.decode(node, graph.getModel());
 * (end)
 * 
 * For creating a page that loads the client and a diagram using a single
 * request please refer to the deployment examples in the backends.
 * 
 * Functional dependencies:
 * 
 * (see images/callgraph.png)
 * 
 * Resources:
 *
 * resources/graph - Language resources for mxGraph
 *
 * Group: Events
 * 
 * Event: mxEvent.ROOT
 * 
 * Fires if the root in the model has changed. This event has no properties.
 * 
 * Event: mxEvent.ALIGN_CELLS
 * 
 * Fires between begin- and endUpdate in <alignCells>. The <code>cells</code>
 * and <code>align</code> properties contain the respective arguments that were
 * passed to <alignCells>.
 *
 * Event: mxEvent.FLIP_EDGE
 *
 * Fires between begin- and endUpdate in <flipEdge>. The <code>edge</code>
 * property contains the edge passed to <flipEdge>.
 * 
 * Event: mxEvent.ORDER_CELLS
 * 
 * Fires between begin- and endUpdate in <orderCells>. The <code>cells</code>
 * and <code>back</code> properties contain the respective arguments that were
 * passed to <orderCells>.
 *
 * Event: mxEvent.CELLS_ORDERED
 *
 * Fires between begin- and endUpdate in <cellsOrdered>. The <code>cells</code>
 * and <code>back</code> arguments contain the respective arguments that were
 * passed to <cellsOrdered>.
 * 
 * Event: mxEvent.GROUP_CELLS
 * 
 * Fires between begin- and endUpdate in <groupCells>. The <code>group</code>,
 * <code>cells</code> and <code>border</code> arguments contain the respective
 * arguments that were passed to <groupCells>.
 * 
 * Event: mxEvent.UNGROUP_CELLS
 * 
 * Fires between begin- and endUpdate in <ungroupCells>. The <code>cells</code>
 * property contains the array of cells that was passed to <ungroupCells>.
 * 
 * Event: mxEvent.REMOVE_CELLS_FROM_PARENT
 * 
 * Fires between begin- and endUpdate in <removeCellsFromParent>. The
 * <code>cells</code> property contains the array of cells that was passed to
 * <removeCellsFromParent>.
 * 
 * Event: mxEvent.ADD_CELLS
 * 
 * Fires between begin- and endUpdate in <addCells>. The <code>cells</code>,
 * <code>parent</code>, <code>index</code>, <code>source</code> and
 * <code>target</code> properties contain the respective arguments that were
 * passed to <addCells>.
 * 
 * Event: mxEvent.CELLS_ADDED
 * 
 * Fires between begin- and endUpdate in <cellsAdded>. The <code>cells</code>,
 * <code>parent</code>, <code>index</code>, <code>source</code>,
 * <code>target</code> and <code>absolute</code> properties contain the
 * respective arguments that were passed to <cellsAdded>.
 * 
 * Event: mxEvent.REMOVE_CELLS
 * 
 * Fires between begin- and endUpdate in <removeCells>. The <code>cells</code>
 * and <code>includeEdges</code> arguments contain the respective arguments
 * that were passed to <removeCells>.
 * 
 * Event: mxEvent.CELLS_REMOVED
 * 
 * Fires between begin- and endUpdate in <cellsRemoved>. The <code>cells</code>
 * argument contains the array of cells that was removed.
 * 
 * Event: mxEvent.SPLIT_EDGE
 * 
 * Fires between begin- and endUpdate in <splitEdge>. The <code>edge</code>
 * property contains the edge to be splitted, the <code>cells</code>,
 * <code>newEdge</code>, <code>dx</code> and <code>dy</code> properties contain
 * the respective arguments that were passed to <splitEdge>.
 * 
 * Event: mxEvent.TOGGLE_CELLS
 * 
 * Fires between begin- and endUpdate in <toggleCells>. The <code>show</code>,
 * <code>cells</code> and <code>includeEdges</code> properties contain the
 * respective arguments that were passed to <toggleCells>.
 * 
 * Event: mxEvent.FOLD_CELLS
 * 
 * Fires between begin- and endUpdate in <foldCells>. The
 * <code>collapse</code>, <code>cells</code> and <code>recurse</code>
 * properties contain the respective arguments that were passed to <foldCells>.
 * 
 * Event: mxEvent.CELLS_FOLDED
 * 
 * Fires between begin- and endUpdate in cellsFolded. The
 * <code>collapse</code>, <code>cells</code> and <code>recurse</code>
 * properties contain the respective arguments that were passed to
 * <cellsFolded>.
 * 
 * Event: mxEvent.UPDATE_CELL_SIZE
 * 
 * Fires between begin- and endUpdate in <updateCellSize>. The
 * <code>cell</code> and <code>ignoreChildren</code> properties contain the
 * respective arguments that were passed to <updateCellSize>.
 * 
 * Event: mxEvent.RESIZE_CELLS
 * 
 * Fires between begin- and endUpdate in <resizeCells>. The <code>cells</code>
 * and <code>bounds</code> properties contain the respective arguments that
 * were passed to <resizeCells>.
 * 
 * Event: mxEvent.CELLS_RESIZED
 * 
 * Fires between begin- and endUpdate in <cellsResized>. The <code>cells</code>
 * and <code>bounds</code> properties contain the respective arguments that
 * were passed to <cellsResized>.
 * 
 * Event: mxEvent.MOVE_CELLS
 * 
 * Fires between begin- and endUpdate in <moveCells>. The <code>cells</code>,
 * <code>dx</code>, <code>dy</code>, <code>clone</code>, <code>target</code>
 * and <code>event</code> properties contain the respective arguments that
 * were passed to <moveCells>.
 * 
 * Event: mxEvent.CELLS_MOVED
 * 
 * Fires between begin- and endUpdate in <cellsMoved>. The <code>cells</code>,
 * <code>dx</code>, <code>dy</code> and <code>disconnect</code> properties
 * contain the respective arguments that were passed to <cellsMoved>.
 * 
 * Event: mxEvent.CONNECT_CELL
 * 
 * Fires between begin- and endUpdate in <connectCell>. The <code>edge</code>,
 * <code>terminal</code> and <code>source</code> properties contain the
 * respective arguments that were passed to <connectCell>.
 * 
 * Event: mxEvent.CELL_CONNECTED
 * 
 * Fires between begin- and endUpdate in <cellConnected>. The
 * <code>edge</code>, <code>terminal</code> and <code>source</code> properties
 * contain the respective arguments that were passed to <cellConnected>.
 * 
 * Event: mxEvent.REFRESH
 * 
 * Fires after <refresh> was executed. This event has no properties.
 *
 * Event: mxEvent.CLICK
 * 
 * Fires in <click> after a click event. The <code>event</code> property
 * contains the original mouse event and <code>cell</code> property contains
 * the cell under the mouse or null if the background was clicked.
 * 
 * Event: mxEvent.DOUBLE_CLICK
 *
 * Fires in <dblClick> after a double click. The <code>event</code> property
 * contains the original mouse event and the <code>cell</code> property
 * contains the cell under the mouse or null if the background was clicked.
 * 
 * Event: mxEvent.GESTURE
 *
 * Fires in <fireGestureEvent> after a touch gesture. The <code>event</code>
 * property contains the original gesture end event and the <code>cell</code>
 * property contains the optional cell associated with the gesture.
 *
 * Event: mxEvent.TAP_AND_HOLD
 *
 * Fires in <tapAndHold> if a tap and hold event was detected. The <code>event</code>
 * property contains the initial touch event and the <code>cell</code> property
 * contains the cell under the mouse or null if the background was clicked.
 *
 * Event: mxEvent.FIRE_MOUSE_EVENT
 *
 * Fires in <fireMouseEvent> before the mouse listeners are invoked. The
 * <code>eventName</code> property contains the event name and the
 * <code>event</code> property contains the <mxMouseEvent>.
 *
 * Event: mxEvent.SIZE
 *
 * Fires after <sizeDidChange> was executed. The <code>bounds</code> property
 * contains the new graph bounds.
 *
 * Event: mxEvent.START_EDITING
 *
 * Fires before the in-place editor starts in <startEditingAtCell>. The
 * <code>cell</code> property contains the cell that is being edited and the
 * <code>event</code> property contains the optional event argument that was
 * passed to <startEditingAtCell>.
 * 
 * Event: mxEvent.EDITING_STARTED
 *
 * Fires after the in-place editor starts in <startEditingAtCell>. The
 * <code>cell</code> property contains the cell that is being edited and the
 * <code>event</code> property contains the optional event argument that was
 * passed to <startEditingAtCell>.
 * 
 * Event: mxEvent.EDITING_STOPPED
 *
 * Fires after the in-place editor stops in <stopEditing>.
 *
 * Event: mxEvent.LABEL_CHANGED
 *
 * Fires between begin- and endUpdate in <cellLabelChanged>. The
 * <code>cell</code> property contains the cell, the <code>value</code>
 * property contains the new value for the cell, the <code>old</code> property
 * contains the old value and the optional <code>event</code> property contains
 * the mouse event that started the edit.
 * 
 * Event: mxEvent.ADD_OVERLAY
 *
 * Fires after an overlay is added in <addCellOverlay>. The <code>cell</code>
 * property contains the cell and the <code>overlay</code> property contains
 * the <mxCellOverlay> that was added.
 *
 * Event: mxEvent.REMOVE_OVERLAY
 *
 * Fires after an overlay is removed in <removeCellOverlay> and
 * <removeCellOverlays>. The <code>cell</code> property contains the cell and
 * the <code>overlay</code> property contains the <mxCellOverlay> that was
 * removed.
 * 
 * Constructor: mxGraph
 * 
 * Constructs a new mxGraph in the specified container. Model is an optional
 * mxGraphModel. If no model is provided, a new mxGraphModel instance is 
 * used as the model. The container must have a valid owner document prior 
 * to calling this function in Internet Explorer. RenderHint is a string to
 * affect the display performance and rendering in IE, but not in SVG-based 
 * browsers. The parameter is mapped to <dialect>, which may 
 * be one of <mxConstants.DIALECT_SVG> for SVG-based browsers, 
 * <mxConstants.DIALECT_STRICTHTML> for fastest display mode,
 * <mxConstants.DIALECT_PREFERHTML> for faster display mode,
 * <mxConstants.DIALECT_MIXEDHTML> for fast and <mxConstants.DIALECT_VML> 
 * for exact display mode (slowest). The dialects are defined in mxConstants.
 * The default values are DIALECT_SVG for SVG-based browsers and
 * DIALECT_MIXED for IE.
 *
 * The possible values for the renderingHint parameter are explained below:
 * 
 * fast - The parameter is based on the fact that the display performance is 
 * highly improved in IE if the VML is not contained within a VML group 
 * element. The lack of a group element only slightly affects the display while 
 * panning, but improves the performance by almost a factor of 2, while keeping 
 * the display sufficiently accurate. This also allows to render certain shapes as HTML 
 * if the display accuracy is not affected, which is implemented by 
 * <mxShape.isMixedModeHtml>. This is the default setting and is mapped to
 * DIALECT_MIXEDHTML.
 * faster - Same as fast, but more expensive shapes are avoided. This is 
 * controlled by <mxShape.preferModeHtml>. The default implementation will 
 * avoid gradients and rounded rectangles, but more significant shapes, such 
 * as rhombus, ellipse, actor and cylinder will be rendered accurately. This 
 * setting is mapped to DIALECT_PREFERHTML.
 * fastest - Almost anything will be rendered in Html. This allows for 
 * rectangles, labels and images. This setting is mapped to
 * DIALECT_STRICTHTML.
 * exact - If accurate panning is required and if the diagram is small (up
 * to 100 cells), then this value should be used. In this mode, a group is 
 * created that contains the VML. This allows for accurate panning and is 
 * mapped to DIALECT_VML.
 *
 * Example:
 * 
 * To create a graph inside a DOM node with an id of graph:
 * (code)
 * var container = document.getElementById('graph');
 * var graph = new mxGraph(container);
 * (end)
 * 
 * Parameters:
 * 
 * container - Optional DOM node that acts as a container for the graph.
 * If this is null then the container can be initialized later using
 * <init>.
 * model - Optional <mxGraphModel> that constitutes the graph data.
 * renderHint - Optional string that specifies the display accuracy and
 * performance. Default is mxConstants.DIALECT_MIXEDHTML (for IE).
 * stylesheet - Optional <mxStylesheet> to be used in the graph.
 */
function mxGraph(container, model, renderHint, stylesheet)
{
	// Initializes the variable in case the prototype has been
	// modified to hold some listeners (which is possible because
	// the createHandlers call is executed regardless of the
	// arguments passed into the ctor).
	this.mouseListeners = null;
	
	// Converts the renderHint into a dialect
	this.renderHint = renderHint;

	if (mxClient.IS_SVG)
	{
		this.dialect = mxConstants.DIALECT_SVG;
	}
	else if (renderHint == mxConstants.RENDERING_HINT_EXACT && mxClient.IS_VML)
	{
		this.dialect = mxConstants.DIALECT_VML;
	}
	else if (renderHint == mxConstants.RENDERING_HINT_FASTEST)
	{
		this.dialect = mxConstants.DIALECT_STRICTHTML;
	}
	else if (renderHint == mxConstants.RENDERING_HINT_FASTER)
	{
		this.dialect = mxConstants.DIALECT_PREFERHTML;
	}
	else // default for VML
	{
		this.dialect = mxConstants.DIALECT_MIXEDHTML;
	}
	
	// Initializes the main members that do not require a container
	this.model = (model != null) ? model : new mxGraphModel();
	this.multiplicities = [];
	this.imageBundles = [];
	this.cellRenderer = this.createCellRenderer();
	this.setSelectionModel(this.createSelectionModel());
	this.setStylesheet((stylesheet != null) ? stylesheet : this.createStylesheet());
	this.view = this.createGraphView();
	
	// Adds a graph model listener to update the view
	this.graphModelChangeListener = mxUtils.bind(this, function(sender, evt)
	{
		this.graphModelChanged(evt.getProperty('edit').changes);
	});
	
	this.model.addListener(mxEvent.CHANGE, this.graphModelChangeListener);

	// Installs basic event handlers with disabled default settings.
	this.createHandlers();
	
	// Initializes the display if a container was specified
	if (container != null)
	{
		this.init(container);
	}
	
	this.view.revalidate();
};

/**
 * Installs the required language resources at class
 * loading time.
 */
if (mxLoadResources)
{
	mxResources.add(mxClient.basePath+'/resources/graph');
}

/**
 * Extends mxEventSource.
 */
mxGraph.prototype = new mxEventSource();
mxGraph.prototype.constructor = mxGraph;

/**
 * Variable: EMPTY_ARRAY
 *
 * Immutable empty array instance.
 */
mxGraph.prototype.EMPTY_ARRAY = [];

/**
 * Group: Variables
 */

/**
 * Variable: mouseListeners
 * 
 * Holds the mouse event listeners. See <fireMouseEvent>.
 */
mxGraph.prototype.mouseListeners = null;

/**
 * Variable: isMouseDown
 * 
 * Holds the state of the mouse button.
 */
mxGraph.prototype.isMouseDown = false;

/**
 * Variable: model
 * 
 * Holds the <mxGraphModel> that contains the cells to be displayed.
 */
mxGraph.prototype.model = null;

/**
 * Variable: view
 * 
 * Holds the <mxGraphView> that caches the <mxCellStates> for the cells.
 */
mxGraph.prototype.view = null;

/**
 * Variable: stylesheet
 * 
 * Holds the <mxStylesheet> that defines the appearance of the cells.
 * 
 * 
 * Example:
 * 
 * Use the following code to read a stylesheet into an existing graph.
 * 
 * (code)
 * var req = mxUtils.load('stylesheet.xml');
 * var root = req.getDocumentElement();
 * var dec = new mxCodec(root.ownerDocument);
 * dec.decode(root, graph.stylesheet);
 * (end)
 */
mxGraph.prototype.stylesheet = null;
	
/**
 * Variable: selectionModel
 * 
 * Holds the <mxGraphSelectionModel> that models the current selection.
 */
mxGraph.prototype.selectionModel = null;

/**
 * Variable: cellEditor
 * 
 * Holds the <mxCellEditor> that is used as the in-place editing.
 */
mxGraph.prototype.cellEditor = null;

/**
 * Variable: cellRenderer
 * 
 * Holds the <mxCellRenderer> for rendering the cells in the graph.
 */
mxGraph.prototype.cellRenderer = null;

/**
 * Variable: multiplicities
 * 
 * An array of <mxMultiplicities> describing the allowed
 * connections in a graph.
 */
mxGraph.prototype.multiplicities = null;

/**
 * Variable: renderHint
 * 
 * RenderHint as it was passed to the constructor.
 */
mxGraph.prototype.renderHint = null;

/**
 * Variable: dialect
 * 
 * Dialect to be used for drawing the graph. Possible values are all
 * constants in <mxConstants> with a DIALECT-prefix.
 */
mxGraph.prototype.dialect = null;

/**
 * Variable: gridSize
 * 
 * Specifies the grid size. Default is 10.
 */
mxGraph.prototype.gridSize = 10;
	
/**
 * Variable: gridEnabled
 * 
 * Specifies if the grid is enabled. This is used in <snap>. Default is
 * true.
 */
mxGraph.prototype.gridEnabled = true;

/**
 * Variable: portsEnabled
 * 
 * Specifies if ports are enabled. This is used in <cellConnected> to update
 * the respective style. Default is true.
 */
mxGraph.prototype.portsEnabled = true;

/**
 * Variable: nativeDoubleClickEnabled
 * 
 * Specifies if native double click events should be detected. Default is true.
 */
mxGraph.prototype.nativeDblClickEnabled = true;

/**
 * Variable: doubleTapEnabled
 * 
 * Specifies if double taps on touch-based devices should be handled as a
 * double click. Default is true.
 */
mxGraph.prototype.doubleTapEnabled = true;

/**
 * Variable: doubleTapTimeout
 * 
 * Specifies the timeout for double taps and non-native double clicks. Default
 * is 500 ms.
 */
mxGraph.prototype.doubleTapTimeout = 500;

/**
 * Variable: doubleTapTolerance
 * 
 * Specifies the tolerance for double taps and double clicks in quirks mode.
 * Default is 25 pixels.
 */
mxGraph.prototype.doubleTapTolerance = 25;

/**
 * Variable: lastTouchX
 * 
 * Holds the x-coordinate of the last touch event for double tap detection.
 */
mxGraph.prototype.lastTouchY = 0;

/**
 * Variable: lastTouchX
 * 
 * Holds the y-coordinate of the last touch event for double tap detection.
 */
mxGraph.prototype.lastTouchY = 0;

/**
 * Variable: lastTouchTime
 * 
 * Holds the time of the last touch event for double click detection.
 */
mxGraph.prototype.lastTouchTime = 0;

/**
 * Variable: tapAndHoldEnabled
 * 
 * Specifies if tap and hold should be used for starting connections on touch-based
 * devices. Default is true.
 */
mxGraph.prototype.tapAndHoldEnabled = true;

/**
 * Variable: tapAndHoldDelay
 * 
 * Specifies the time for a tap and hold. Default is 500 ms.
 */
mxGraph.prototype.tapAndHoldDelay = 500;

/**
 * Variable: tapAndHoldInProgress
 * 
 * True if the timer for tap and hold events is running.
 */
mxGraph.prototype.tapAndHoldInProgress = false;

/**
 * Variable: tapAndHoldValid
 * 
 * True as long as the timer is running and the touch events
 * stay within the given <tapAndHoldTolerance>.
 */
mxGraph.prototype.tapAndHoldValid = false;

/**
 * Variable: initialTouchX
 * 
 * Holds the x-coordinate of the intial touch event for tap and hold.
 */
mxGraph.prototype.initialTouchX = 0;

/**
 * Variable: initialTouchY
 * 
 * Holds the y-coordinate of the intial touch event for tap and hold.
 */
mxGraph.prototype.initialTouchY = 0;

/**
 * Variable: tolerance
 * 
 * Tolerance for a move to be handled as a single click.
 * Default is 4 pixels.
 */
mxGraph.prototype.tolerance = 4;

/**
 * Variable: defaultOverlap
 * 
 * Value returned by <getOverlap> if <isAllowOverlapParent> returns
 * true for the given cell. <getOverlap> is used in <constrainChild> if
 * <isConstrainChild> returns true. The value specifies the
 * portion of the child which is allowed to overlap the parent.
 */
mxGraph.prototype.defaultOverlap = 0.5;

/**
 * Variable: defaultParent
 * 
 * Specifies the default parent to be used to insert new cells.
 * This is used in <getDefaultParent>. Default is null.
 */
mxGraph.prototype.defaultParent = null;

/**
 * Variable: alternateEdgeStyle
 * 
 * Specifies the alternate edge style to be used if the main control point
 * on an edge is being doubleclicked. Default is null.
 */
mxGraph.prototype.alternateEdgeStyle = null;

/**
 * Variable: backgroundImage
 *
 * Specifies the <mxImage> to be returned by <getBackgroundImage>. Default
 * is null.
 * 
 * Example:
 *
 * (code)
 * var img = new mxImage('http://www.example.com/maps/examplemap.jpg', 1024, 768);
 * graph.setBackgroundImage(img);
 * graph.view.validate();
 * (end)
 */
mxGraph.prototype.backgroundImage = null;

/**
 * Variable: pageVisible
 *
 * Specifies if the background page should be visible. Default is false.
 * Not yet implemented.
 */
mxGraph.prototype.pageVisible = false;

/**
 * Variable: pageBreaksVisible
 * 
 * Specifies if a dashed line should be drawn between multiple pages. Default
 * is false. If you change this value while a graph is being displayed then you
 * should call <sizeDidChange> to force an update of the display.
 */
mxGraph.prototype.pageBreaksVisible = false;

/**
 * Variable: pageBreakColor
 * 
 * Specifies the color for page breaks. Default is 'gray'.
 */
mxGraph.prototype.pageBreakColor = 'gray';

/**
 * Variable: pageBreakDashed
 * 
 * Specifies the page breaks should be dashed. Default is true.
 */
mxGraph.prototype.pageBreakDashed = true;

/**
 * Variable: minPageBreakDist
 * 
 * Specifies the minimum distance for page breaks to be visible. Default is
 * 20 (in pixels).
 */
mxGraph.prototype.minPageBreakDist = 20;

/**
 * Variable: preferPageSize
 * 
 * Specifies if the graph size should be rounded to the next page number in
 * <sizeDidChange>. This is only used if the graph container has scrollbars.
 * Default is false.
 */
mxGraph.prototype.preferPageSize = false;

/**
 * Variable: pageFormat
 *
 * Specifies the page format for the background page. Default is
 * <mxConstants.PAGE_FORMAT_A4_PORTRAIT>. This is used as the default in
 * <mxPrintPreview> and for painting the background page if <pageVisible> is
 * true and the pagebreaks if <pageBreaksVisible> is true.
 */
mxGraph.prototype.pageFormat = mxConstants.PAGE_FORMAT_A4_PORTRAIT;

/**
 * Variable: pageScale
 *
 * Specifies the scale of the background page. Default is 1.5.
 * Not yet implemented.
 */
mxGraph.prototype.pageScale = 1.5;

/**
 * Variable: enabled
 * 
 * Specifies the return value for <isEnabled>. Default is true.
 */
mxGraph.prototype.enabled = true;

/**
 * Variable: escapeEnabled
 * 
 * Specifies if <mxKeyHandler> should invoke <escape> when the escape key
 * is pressed. Default is true.
 */
mxGraph.prototype.escapeEnabled = true;

/**
 * Variable: invokesStopCellEditing
 * 
 * If true, when editing is to be stopped by way of selection changing,
 * data in diagram changing or other means stopCellEditing is invoked, and
 * changes are saved. This is implemented in a focus handler in
 * <mxCellEditor>. Default is true.
 */
mxGraph.prototype.invokesStopCellEditing = true;

/**
 * Variable: enterStopsCellEditing
 * 
 * If true, pressing the enter key without pressing control or shift will stop
 * editing and accept the new value. This is used in <mxCellEditor> to stop
 * cell editing. Note: You can always use F2 and escape to stop editing.
 * Default is false.
 */
mxGraph.prototype.enterStopsCellEditing = false;

/**
 * Variable: useScrollbarsForPanning
 * 
 * Specifies if scrollbars should be used for panning in <panGraph> if
 * any scrollbars are available. If scrollbars are enabled in CSS, but no
 * scrollbars appear because the graph is smaller than the container size,
 * then no panning occurs if this is true. Default is true.
 */
mxGraph.prototype.useScrollbarsForPanning = true;

/**
 * Variable: exportEnabled
 * 
 * Specifies the return value for <canExportCell>. Default is true.
 */
mxGraph.prototype.exportEnabled = true;

/**
 * Variable: importEnabled
 * 
 * Specifies the return value for <canImportCell>. Default is true.
 */
mxGraph.prototype.importEnabled = true;

/**
 * Variable: cellsLocked
 * 
 * Specifies the return value for <isCellLocked>. Default is false.
 */
mxGraph.prototype.cellsLocked = false;

/**
 * Variable: cellsCloneable
 * 
 * Specifies the return value for <isCellCloneable>. Default is true.
 */
mxGraph.prototype.cellsCloneable = true;

/**
 * Variable: foldingEnabled
 * 
 * Specifies if folding (collapse and expand via an image icon in the graph
 * should be enabled). Default is true.
 */
mxGraph.prototype.foldingEnabled = true;

/**
 * Variable: cellsEditable
 * 
 * Specifies the return value for <isCellEditable>. Default is true.
 */
mxGraph.prototype.cellsEditable = true;
		
/**
 * Variable: cellsDeletable
 * 
 * Specifies the return value for <isCellDeletable>. Default is true.
 */
mxGraph.prototype.cellsDeletable = true;

/**
 * Variable: cellsMovable
 * 
 * Specifies the return value for <isCellMovable>. Default is true.
 */
mxGraph.prototype.cellsMovable = true;
	
/**
 * Variable: edgeLabelsMovable
 * 
 * Specifies the return value for edges in <isLabelMovable>. Default is true.
 */
mxGraph.prototype.edgeLabelsMovable = true;
	
/**
 * Variable: vertexLabelsMovable
 * 
 * Specifies the return value for vertices in <isLabelMovable>. Default is false.
 */
mxGraph.prototype.vertexLabelsMovable = false;

/**
 * Variable: dropEnabled
 * 
 * Specifies the return value for <isDropEnabled>. Default is false.
 */
mxGraph.prototype.dropEnabled = false;

/**
 * Variable: splitEnabled
 * 
 * Specifies if dropping onto edges should be enabled. This is ignored if
 * <dropEnabled> is false. If enabled, it will call <splitEdge> to carry
 * out the drop operation. Default is true.
 */
mxGraph.prototype.splitEnabled = true;

/**
 * Variable: cellsResizable
 * 
 * Specifies the return value for <isCellResizable>. Default is true.
 */
mxGraph.prototype.cellsResizable = true;

/**
 * Variable: cellsBendable
 * 
 * Specifies the return value for <isCellsBendable>. Default is true.
 */
mxGraph.prototype.cellsBendable = true;

/**
 * Variable: cellsSelectable
 * 
 * Specifies the return value for <isCellSelectable>. Default is true.
 */
mxGraph.prototype.cellsSelectable = true;

/**
 * Variable: cellsDisconnectable
 * 
 * Specifies the return value for <isCellDisconntable>. Default is true.
 */
mxGraph.prototype.cellsDisconnectable = true;

/**
 * Variable: autoSizeCells
 * 
 * Specifies if the graph should automatically update the cell size after an
 * edit. This is used in <isAutoSizeCell>. Default is false.
 */
mxGraph.prototype.autoSizeCells = false;

/**
 * Variable: autoSizeCellsOnAdd
 * 
 * Specifies if autoSize style should be applied when cells are added. Default is false.
 */
mxGraph.prototype.autoSizeCellsOnAdd = false;

/**
 * Variable: autoScroll
 * 
 * Specifies if the graph should automatically scroll if the mouse goes near
 * the container edge while dragging. This is only taken into account if the
 * container has scrollbars. Default is true.
 * 
 * If you need this to work without scrollbars then set <ignoreScrollbars> to
 * true. Please consult the <ignoreScrollbars> for details. In general, with
 * no scrollbars, the use of <allowAutoPanning> is recommended.
 */
mxGraph.prototype.autoScroll = true;

/**
 * Variable: ignoreScrollbars
 * 
 * Specifies if the graph should automatically scroll regardless of the
 * scrollbars. This will scroll the container using positive values for
 * scroll positions (ie usually only rightwards and downwards). To avoid
 * possible conflicts with panning, set <translateToScrollPosition> to true.
 */
mxGraph.prototype.ignoreScrollbars = false;

/**
 * Variable: translateToScrollPosition
 * 
 * Specifies if the graph should automatically convert the current scroll
 * position to a translate in the graph view when a mouseUp event is received.
 * This can be used to avoid conflicts when using <autoScroll> and
 * <ignoreScrollbars> with no scrollbars in the container.
 */
mxGraph.prototype.translateToScrollPosition = false;

/**
 * Variable: timerAutoScroll
 * 
 * Specifies if autoscrolling should be carried out via mxPanningManager even
 * if the container has scrollbars. This disables <scrollPointToVisible> and
 * uses <mxPanningManager> instead. If this is true then <autoExtend> is
 * disabled. It should only be used with a scroll buffer or when scollbars
 * are visible and scrollable in all directions. Default is false.
 */
mxGraph.prototype.timerAutoScroll = false;

/**
 * Variable: allowAutoPanning
 * 
 * Specifies if panning via <panGraph> should be allowed to implement autoscroll
 * if no scrollbars are available in <scrollPointToVisible>. To enable panning
 * inside the container, near the edge, set <mxPanningManager.border> to a
 * positive value. Default is false.
 */
mxGraph.prototype.allowAutoPanning = false;

/**
 * Variable: autoExtend
 * 
 * Specifies if the size of the graph should be automatically extended if the
 * mouse goes near the container edge while dragging. This is only taken into
 * account if the container has scrollbars. Default is true. See <autoScroll>.
 */
mxGraph.prototype.autoExtend = true;

/**
 * Variable: maximumGraphBounds
 * 
 * <mxRectangle> that specifies the area in which all cells in the diagram
 * should be placed. Uses in <getMaximumGraphBounds>. Use a width or height of
 * 0 if you only want to give a upper, left corner.
 */
mxGraph.prototype.maximumGraphBounds = null;

/**
 * Variable: minimumGraphSize
 * 
 * <mxRectangle> that specifies the minimum size of the graph. This is ignored
 * if the graph container has no scrollbars. Default is null.
 */
mxGraph.prototype.minimumGraphSize = null;

/**
 * Variable: minimumContainerSize
 * 
 * <mxRectangle> that specifies the minimum size of the <container> if
 * <resizeContainer> is true.
 */
mxGraph.prototype.minimumContainerSize = null;
		
/**
 * Variable: maximumContainerSize
 * 
 * <mxRectangle> that specifies the maximum size of the container if
 * <resizeContainer> is true.
 */
mxGraph.prototype.maximumContainerSize = null;

/**
 * Variable: resizeContainer
 * 
 * Specifies if the container should be resized to the graph size when
 * the graph size has changed. Default is false.
 */
mxGraph.prototype.resizeContainer = false;

/**
 * Variable: border
 * 
 * Border to be added to the bottom and right side when the container is
 * being resized after the graph has been changed. Default is 0.
 */
mxGraph.prototype.border = 0;
		
/**
 * Variable: keepEdgesInForeground
 * 
 * Specifies if edges should appear in the foreground regardless of their order
 * in the model. If <keepEdgesInForeground> and <keepEdgesInBackground> are
 * both true then the normal order is applied. Default is false.
 */
mxGraph.prototype.keepEdgesInForeground = false;

/**
 * Variable: keepEdgesInBackground
 * 
 * Specifies if edges should appear in the background regardless of their order
 * in the model. If <keepEdgesInForeground> and <keepEdgesInBackground> are
 * both true then the normal order is applied. Default is false.
 */
mxGraph.prototype.keepEdgesInBackground = false;

/**
 * Variable: allowNegativeCoordinates
 * 
 * Specifies if negative coordinates for vertices are allowed. Default is true.
 */
mxGraph.prototype.allowNegativeCoordinates = true;

/**
 * Variable: constrainChildren
 * 
 * Specifies if a child should be constrained inside the parent bounds after a
 * move or resize of the child. Default is true.
 */
mxGraph.prototype.constrainChildren = true;

/**
 * Variable: constrainRelativeChildren
 * 
 * Specifies if child cells with relative geometries should be constrained
 * inside the parent bounds, if <constrainChildren> is true, and/or the
 * <maximumGraphBounds>. Default is false.
 */
mxGraph.prototype.constrainRelativeChildren = false;

/**
 * Variable: extendParents
 * 
 * Specifies if a parent should contain the child bounds after a resize of
 * the child. Default is true. This has precedence over <constrainChildren>.
 */
mxGraph.prototype.extendParents = true;

/**
 * Variable: extendParentsOnAdd
 * 
 * Specifies if parents should be extended according to the <extendParents>
 * switch if cells are added. Default is true.
 */
mxGraph.prototype.extendParentsOnAdd = true;

/**
 * Variable: extendParentsOnAdd
 * 
 * Specifies if parents should be extended according to the <extendParents>
 * switch if cells are added. Default is false for backwards compatiblity.
 */
mxGraph.prototype.extendParentsOnMove = false;

/**
 * Variable: recursiveResize
 * 
 * Specifies the return value for <isRecursiveResize>. Default is
 * false for backwards compatiblity.
 */
mxGraph.prototype.recursiveResize = false;

/**
 * Variable: collapseToPreferredSize
 * 
 * Specifies if the cell size should be changed to the preferred size when
 * a cell is first collapsed. Default is true.
 */
mxGraph.prototype.collapseToPreferredSize = true;

/**
 * Variable: zoomFactor
 * 
 * Specifies the factor used for <zoomIn> and <zoomOut>. Default is 1.2
 * (120%).
 */
mxGraph.prototype.zoomFactor = 1.2;

/**
 * Variable: keepSelectionVisibleOnZoom
 * 
 * Specifies if the viewport should automatically contain the selection cells
 * after a zoom operation. Default is false.
 */
mxGraph.prototype.keepSelectionVisibleOnZoom = false;

/**
 * Variable: centerZoom
 * 
 * Specifies if the zoom operations should go into the center of the actual
 * diagram rather than going from top, left. Default is true.
 */
mxGraph.prototype.centerZoom = true;

/**
 * Variable: resetViewOnRootChange
 * 
 * Specifies if the scale and translate should be reset if the root changes in
 * the model. Default is true.
 */
mxGraph.prototype.resetViewOnRootChange = true;

/**
 * Variable: resetEdgesOnResize
 * 
 * Specifies if edge control points should be reset after the resize of a
 * connected cell. Default is false.
 */
mxGraph.prototype.resetEdgesOnResize = false;

/**
 * Variable: resetEdgesOnMove
 * 
 * Specifies if edge control points should be reset after the move of a
 * connected cell. Default is false.
 */
mxGraph.prototype.resetEdgesOnMove = false;

/**
 * Variable: resetEdgesOnConnect
 * 
 * Specifies if edge control points should be reset after the the edge has been
 * reconnected. Default is true.
 */
mxGraph.prototype.resetEdgesOnConnect = true;

/**
 * Variable: allowLoops
 * 
 * Specifies if loops (aka self-references) are allowed. Default is false.
 */
mxGraph.prototype.allowLoops = false;
	
/**
 * Variable: defaultLoopStyle
 * 
 * <mxEdgeStyle> to be used for loops. This is a fallback for loops if the
 * <mxConstants.STYLE_LOOP> is undefined. Default is <mxEdgeStyle.Loop>.
 */
mxGraph.prototype.defaultLoopStyle = mxEdgeStyle.Loop;

/**
 * Variable: multigraph
 * 
 * Specifies if multiple edges in the same direction between the same pair of
 * vertices are allowed. Default is true.
 */
mxGraph.prototype.multigraph = true;

/**
 * Variable: connectableEdges
 * 
 * Specifies if edges are connectable. Default is false. This overrides the
 * connectable field in edges.
 */
mxGraph.prototype.connectableEdges = false;

/**
 * Variable: allowDanglingEdges
 * 
 * Specifies if edges with disconnected terminals are allowed in the graph.
 * Default is true.
 */
mxGraph.prototype.allowDanglingEdges = true;

/**
 * Variable: cloneInvalidEdges
 * 
 * Specifies if edges that are cloned should be validated and only inserted
 * if they are valid. Default is true.
 */
mxGraph.prototype.cloneInvalidEdges = false;

/**
 * Variable: disconnectOnMove
 * 
 * Specifies if edges should be disconnected from their terminals when they
 * are moved. Default is true.
 */
mxGraph.prototype.disconnectOnMove = true;

/**
 * Variable: labelsVisible
 * 
 * Specifies if labels should be visible. This is used in <getLabel>. Default
 * is true.
 */
mxGraph.prototype.labelsVisible = true;
	
/**
 * Variable: htmlLabels
 * 
 * Specifies the return value for <isHtmlLabel>. Default is false.
 */
mxGraph.prototype.htmlLabels = false;

/**
 * Variable: swimlaneSelectionEnabled
 * 
 * Specifies if swimlanes should be selectable via the content if the
 * mouse is released. Default is true.
 */
mxGraph.prototype.swimlaneSelectionEnabled = true;

/**
 * Variable: swimlaneNesting
 * 
 * Specifies if nesting of swimlanes is allowed. Default is true.
 */
mxGraph.prototype.swimlaneNesting = true;
	
/**
 * Variable: swimlaneIndicatorColorAttribute
 * 
 * The attribute used to find the color for the indicator if the indicator
 * color is set to 'swimlane'. Default is <mxConstants.STYLE_FILLCOLOR>.
 */
mxGraph.prototype.swimlaneIndicatorColorAttribute = mxConstants.STYLE_FILLCOLOR;

/**
 * Variable: imageBundles
 * 
 * Holds the list of image bundles.
 */
mxGraph.prototype.imageBundles = null;

/**
 * Variable: minFitScale
 * 
 * Specifies the minimum scale to be applied in <fit>. Default is 0.1. Set this
 * to null to allow any value.
 */
mxGraph.prototype.minFitScale = 0.1;

/**
 * Variable: maxFitScale
 * 
 * Specifies the maximum scale to be applied in <fit>. Default is 8. Set this
 * to null to allow any value.
 */
mxGraph.prototype.maxFitScale = 8;

/**
 * Variable: panDx
 * 
 * Current horizontal panning value. Default is 0.
 */
mxGraph.prototype.panDx = 0;

/**
 * Variable: panDy
 * 
 * Current vertical panning value. Default is 0.
 */
mxGraph.prototype.panDy = 0;

/**
 * Variable: collapsedImage
 * 
 * Specifies the <mxImage> to indicate a collapsed state.
 * Default value is mxClient.imageBasePath + '/collapsed.gif'
 */
mxGraph.prototype.collapsedImage = new mxImage(mxClient.imageBasePath + '/collapsed.gif', 9, 9);

/**
 * Variable: expandedImage
 * 
 * Specifies the <mxImage> to indicate a expanded state.
 * Default value is mxClient.imageBasePath + '/expanded.gif'
 */
mxGraph.prototype.expandedImage = new mxImage(mxClient.imageBasePath + '/expanded.gif', 9, 9);

/**
 * Variable: warningImage
 * 
 * Specifies the <mxImage> for the image to be used to display a warning
 * overlay. See <setCellWarning>. Default value is mxClient.imageBasePath +
 * '/warning'.  The extension for the image depends on the platform. It is
 * '.png' on the Mac and '.gif' on all other platforms.
 */
mxGraph.prototype.warningImage = new mxImage(mxClient.imageBasePath + '/warning'+
	((mxClient.IS_MAC) ? '.png' : '.gif'), 16, 16);

/**
 * Variable: alreadyConnectedResource
 * 
 * Specifies the resource key for the error message to be displayed in
 * non-multigraphs when two vertices are already connected. If the resource
 * for this key does not exist then the value is used as the error message.
 * Default is 'alreadyConnected'.
 */
mxGraph.prototype.alreadyConnectedResource = (mxClient.language != 'none') ? 'alreadyConnected' : '';

/**
 * Variable: containsValidationErrorsResource
 * 
 * Specifies the resource key for the warning message to be displayed when
 * a collapsed cell contains validation errors. If the resource for this
 * key does not exist then the value is used as the warning message.
 * Default is 'containsValidationErrors'.
 */
mxGraph.prototype.containsValidationErrorsResource = (mxClient.language != 'none') ? 'containsValidationErrors' : '';

/**
 * Variable: collapseExpandResource
 * 
 * Specifies the resource key for the tooltip on the collapse/expand icon.
 * If the resource for this key does not exist then the value is used as
 * the tooltip. Default is 'collapse-expand'.
 */
mxGraph.prototype.collapseExpandResource = (mxClient.language != 'none') ? 'collapse-expand' : '';

/**
 * Function: init
 * 
 * Initializes the <container> and creates the respective datastructures.
 * 
 * Parameters:
 * 
 * container - DOM node that will contain the graph display.
 */
mxGraph.prototype.init = function(container)
{
	this.container = container;
	
	// Initializes the in-place editor
	this.cellEditor = this.createCellEditor();	

	// Initializes the container using the view
	this.view.init();
	
	// Updates the size of the container for the current graph
	this.sizeDidChange();
	
	// Hides tooltips and resets tooltip timer if mouse leaves container
	mxEvent.addListener(container, 'mouseleave', mxUtils.bind(this, function()
	{
		if (this.tooltipHandler != null)
		{
			this.tooltipHandler.hide();
		}
	}));

	// Automatic deallocation of memory
	if (mxClient.IS_IE)
	{
		mxEvent.addListener(window, 'unload', mxUtils.bind(this, function()
		{
			this.destroy();
		}));
		
		// Disable shift-click for text
		mxEvent.addListener(container, 'selectstart',
			mxUtils.bind(this, function(evt)
			{
				return this.isEditing() || (!this.isMouseDown && !mxEvent.isShiftDown(evt));
			})
		);
	}
	
	// Workaround for missing last shape and connect preview in IE8 standards
	// mode if no initial graph displayed or no label for shape defined
	if (document.documentMode == 8)
	{
		container.insertAdjacentHTML('beforeend', '<' + mxClient.VML_PREFIX + ':group' +
			' style="DISPLAY: none;"></' + mxClient.VML_PREFIX + ':group>');
	}
};

/**
 * Function: createHandlers
 * 
 * Creates the tooltip-, panning-, connection- and graph-handler (in this
 * order). This is called in the constructor before <init> is called.
 */
mxGraph.prototype.createHandlers = function()
{
	this.tooltipHandler = this.createTooltipHandler();
	this.tooltipHandler.setEnabled(false);
	this.selectionCellsHandler = this.createSelectionCellsHandler();
	this.connectionHandler = this.createConnectionHandler();
	this.connectionHandler.setEnabled(false);
	this.graphHandler = this.createGraphHandler();
	this.panningHandler = this.createPanningHandler();
	this.panningHandler.panningEnabled = false;
	this.popupMenuHandler = this.createPopupMenuHandler();
};

/**
 * Function: createTooltipHandler
 * 
 * Creates and returns a new <mxTooltipHandler> to be used in this graph.
 */
mxGraph.prototype.createTooltipHandler = function()
{
	return new mxTooltipHandler(this);
};

/**
 * Function: createSelectionCellsHandler
 * 
 * Creates and returns a new <mxTooltipHandler> to be used in this graph.
 */
mxGraph.prototype.createSelectionCellsHandler = function()
{
	return new mxSelectionCellsHandler(this);
};

/**
 * Function: createConnectionHandler
 * 
 * Creates and returns a new <mxConnectionHandler> to be used in this graph.
 */
mxGraph.prototype.createConnectionHandler = function()
{
	return new mxConnectionHandler(this);
};

/**
 * Function: createGraphHandler
 * 
 * Creates and returns a new <mxGraphHandler> to be used in this graph.
 */
mxGraph.prototype.createGraphHandler = function()
{
	return new mxGraphHandler(this);
};

/**
 * Function: createPanningHandler
 * 
 * Creates and returns a new <mxPanningHandler> to be used in this graph.
 */
mxGraph.prototype.createPanningHandler = function()
{
	return new mxPanningHandler(this);
};

/**
 * Function: createPopupMenuHandler
 * 
 * Creates and returns a new <mxPopupMenuHandler> to be used in this graph.
 */
mxGraph.prototype.createPopupMenuHandler = function()
{
	return new mxPopupMenuHandler(this);
};

/**
 * Function: createSelectionModel
 * 
 * Creates a new <mxGraphSelectionModel> to be used in this graph.
 */
mxGraph.prototype.createSelectionModel = function()
{
	return new mxGraphSelectionModel(this);
};

/**
 * Function: createStylesheet
 * 
 * Creates a new <mxGraphSelectionModel> to be used in this graph.
 */
mxGraph.prototype.createStylesheet = function()
{
	return new mxStylesheet();
};

/**
 * Function: createGraphView
 * 
 * Creates a new <mxGraphView> to be used in this graph.
 */
mxGraph.prototype.createGraphView = function()
{
	return new mxGraphView(this);
};
 
/**
 * Function: createCellRenderer
 * 
 * Creates a new <mxCellRenderer> to be used in this graph.
 */
mxGraph.prototype.createCellRenderer = function()
{
	return new mxCellRenderer();
};

/**
 * Function: createCellEditor
 * 
 * Creates a new <mxCellEditor> to be used in this graph.
 */
mxGraph.prototype.createCellEditor = function()
{
	return new mxCellEditor(this);
};

/**
 * Function: getModel
 * 
 * Returns the <mxGraphModel> that contains the cells.
 */
mxGraph.prototype.getModel = function()
{
	return this.model;
};

/**
 * Function: getView
 * 
 * Returns the <mxGraphView> that contains the <mxCellStates>.
 */
mxGraph.prototype.getView = function()
{
	return this.view;
};

/**
 * Function: getStylesheet
 * 
 * Returns the <mxStylesheet> that defines the style.
 */
mxGraph.prototype.getStylesheet = function()
{
	return this.stylesheet;
};

/**
 * Function: setStylesheet
 * 
 * Sets the <mxStylesheet> that defines the style.
 */
mxGraph.prototype.setStylesheet = function(stylesheet)
{
	this.stylesheet = stylesheet;
};

/**
 * Function: getSelectionModel
 * 
 * Returns the <mxGraphSelectionModel> that contains the selection.
 */
mxGraph.prototype.getSelectionModel = function()
{
	return this.selectionModel;
};

/**
 * Function: setSelectionModel
 * 
 * Sets the <mxSelectionModel> that contains the selection.
 */
mxGraph.prototype.setSelectionModel = function(selectionModel)
{
	this.selectionModel = selectionModel;
};

/**
 * Function: getSelectionCellsForChanges
 * 
 * Returns the cells to be selected for the given array of changes.
 */
mxGraph.prototype.getSelectionCellsForChanges = function(changes)
{
	var cells = [];
	
	for (var i = 0; i < changes.length; i++)
	{
		var change = changes[i];
		
		if (change.constructor != mxRootChange)
		{
			var cell = null;

			if (change instanceof mxChildChange && change.previous == null)
			{
				cell = change.child;
			}
			else if (change.cell != null && change.cell instanceof mxCell)
			{
				cell = change.cell;
			}
			
			if (cell != null && mxUtils.indexOf(cells, cell) < 0)
			{
				cells.push(cell);
			}
		}
	}
	
	return this.getModel().getTopmostCells(cells);
};

/**
 * Function: graphModelChanged
 * 
 * Called when the graph model changes. Invokes <processChange> on each
 * item of the given array to update the view accordingly.
 * 
 * Parameters:
 * 
 * changes - Array that contains the individual changes.
 */
mxGraph.prototype.graphModelChanged = function(changes)
{
	for (var i = 0; i < changes.length; i++)
	{
		this.processChange(changes[i]);
	}
	
	this.removeSelectionCells(this.getRemovedCellsForChanges(changes));
	
	this.view.validate();
	this.sizeDidChange();
};

/**
 * Function: getRemovedCellsForChanges
 * 
 * Returns the cells that have been removed from the model.
 */
mxGraph.prototype.getRemovedCellsForChanges = function(changes)
{
	var result = [];
	
	for (var i = 0; i < changes.length; i++)
	{
		var change = changes[i];
		
		// Resets the view settings, removes all cells and clears
		// the selection if the root changes.
		if (change instanceof mxRootChange)
		{
			break;
		}
		else if (change instanceof mxChildChange)
		{
			if (change.previous != null && change.parent == null)
			{
				result = result.concat(this.model.getDescendants(change.child));
			}
		}
		else if (change instanceof mxVisibleChange)
		{
			result = result.concat(this.model.getDescendants(change.cell));
		}
	}
	
	return result;
};

/**
 * Function: processChange
 * 
 * Processes the given change and invalidates the respective cached data
 * in <view>. This fires a <root> event if the root has changed in the
 * model.
 * 
 * Parameters:
 * 
 * change - Object that represents the change on the model.
 */
mxGraph.prototype.processChange = function(change)
{
	// Resets the view settings, removes all cells and clears
	// the selection if the root changes.
	if (change instanceof mxRootChange)
	{
		this.clearSelection();
		this.setDefaultParent(null);
		this.removeStateForCell(change.previous);
		
		if (this.resetViewOnRootChange)
		{
			this.view.scale = 1;
			this.view.translate.x = 0;
			this.view.translate.y = 0;
		}

		this.fireEvent(new mxEventObject(mxEvent.ROOT));
	}
	
	// Adds or removes a child to the view by online invaliding
	// the minimal required portions of the cache, namely, the
	// old and new parent and the child.
	else if (change instanceof mxChildChange)
	{
		var newParent = this.model.getParent(change.child);
		this.view.invalidate(change.child, true, true);

		if (newParent == null || this.isCellCollapsed(newParent))
		{
			this.view.invalidate(change.child, true, true);
			this.removeStateForCell(change.child);
			
			// Handles special case of current root of view being removed
			if (this.view.currentRoot == change.child)
			{
				this.home();
			}
		}
 
		if (newParent != change.previous)
		{
			// Refreshes the collapse/expand icons on the parents
			if (newParent != null)
			{
				this.view.invalidate(newParent, false, false);
			}
			
			if (change.previous != null)
			{
				this.view.invalidate(change.previous, false, false);
			}
		}
	}

	// Handles two special cases where the shape does not need to be
	// recreated from scratch, it only needs to be invalidated.
	else if (change instanceof mxTerminalChange || change instanceof mxGeometryChange)
	{
		// Checks if the geometry has changed to avoid unnessecary revalidation
		if (change instanceof mxTerminalChange || ((change.previous == null && change.geometry != null) ||
			(change.previous != null && !change.previous.equals(change.geometry))))
		{
			this.view.invalidate(change.cell);
		}
	}

	// Handles two special cases where only the shape, but no
	// descendants need to be recreated
	else if (change instanceof mxValueChange)
	{
		this.view.invalidate(change.cell, false, false);
	}
	
	// Requires a new mxShape in JavaScript
	else if (change instanceof mxStyleChange)
	{
		this.view.invalidate(change.cell, true, true);
		var state = this.view.getState(change.cell);
		
		if (state != null)
		{
			state.style = null;
		}
	}
	
	// Removes the state from the cache by default
	else if (change.cell != null && change.cell instanceof mxCell)
	{
		this.removeStateForCell(change.cell);
	}
};

/**
 * Function: removeStateForCell
 * 
 * Removes all cached information for the given cell and its descendants.
 * This is called when a cell was removed from the model.
 * 
 * Paramters:
 * 
 * cell - <mxCell> that was removed from the model.
 */
mxGraph.prototype.removeStateForCell = function(cell)
{
	var childCount = this.model.getChildCount(cell);
	
	for (var i = 0; i < childCount; i++)
	{
		this.removeStateForCell(this.model.getChildAt(cell, i));
	}

	this.view.invalidate(cell, false, true);
	this.view.removeState(cell);
};

/**
 * Group: Overlays
 */

/**
 * Function: addCellOverlay
 * 
 * Adds an <mxCellOverlay> for the specified cell. This method fires an
 * <addoverlay> event and returns the new <mxCellOverlay>.
 * 
 * Parameters:
 * 
 * cell - <mxCell> to add the overlay for.
 * overlay - <mxCellOverlay> to be added for the cell.
 */
mxGraph.prototype.addCellOverlay = function(cell, overlay)
{
	if (cell.overlays == null)
	{
		cell.overlays = [];
	}
	
	cell.overlays.push(overlay);

	var state = this.view.getState(cell);

	// Immediately updates the cell display if the state exists
	if (state != null)
	{
		this.cellRenderer.redraw(state);
	}
	
	this.fireEvent(new mxEventObject(mxEvent.ADD_OVERLAY,
			'cell', cell, 'overlay', overlay));
	
	return overlay;
};

/**
 * Function: getCellOverlays
 * 
 * Returns the array of <mxCellOverlays> for the given cell or null, if
 * no overlays are defined.
 * 
 * Parameters:
 * 
 * cell - <mxCell> whose overlays should be returned.
 */
mxGraph.prototype.getCellOverlays = function(cell)
{
	return cell.overlays;
};

/**
 * Function: removeCellOverlay
 * 
 * Removes and returns the given <mxCellOverlay> from the given cell. This
 * method fires a <removeoverlay> event. If no overlay is given, then all
 * overlays are removed using <removeOverlays>.
 * 
 * Parameters:
 * 
 * cell - <mxCell> whose overlay should be removed.
 * overlay - Optional <mxCellOverlay> to be removed.
 */
mxGraph.prototype.removeCellOverlay = function(cell, overlay)
{
	if (overlay == null)
	{
		this.removeCellOverlays(cell);
	}
	else
	{
		var index = mxUtils.indexOf(cell.overlays, overlay);
		
		if (index >= 0)
		{
			cell.overlays.splice(index, 1);
			
			if (cell.overlays.length == 0)
			{
				cell.overlays = null;
			}
			
			// Immediately updates the cell display if the state exists
			var state = this.view.getState(cell);
			
			if (state != null)
			{
				this.cellRenderer.redraw(state);
			}
			
			this.fireEvent(new mxEventObject(mxEvent.REMOVE_OVERLAY,
					'cell', cell, 'overlay', overlay));	
		}
		else
		{
			overlay = null;
		}
	}
	
	return overlay;
};

/**
 * Function: removeCellOverlays
 * 
 * Removes all <mxCellOverlays> from the given cell. This method
 * fires a <removeoverlay> event for each <mxCellOverlay> and returns
 * the array of <mxCellOverlays> that was removed from the cell.
 * 
 * Parameters:
 * 
 * cell - <mxCell> whose overlays should be removed
 */
mxGraph.prototype.removeCellOverlays = function(cell)
{
	var overlays = cell.overlays;
	
	if (overlays != null)
	{
		cell.overlays = null;
		
		// Immediately updates the cell display if the state exists
		var state = this.view.getState(cell);
		
		if (state != null)
		{
			this.cellRenderer.redraw(state);
		}
		
		for (var i = 0; i < overlays.length; i++)
		{
			this.fireEvent(new mxEventObject(mxEvent.REMOVE_OVERLAY,
					'cell', cell, 'overlay', overlays[i]));
		}
	}
	
	return overlays;
};

/**
 * Function: clearCellOverlays
 * 
 * Removes all <mxCellOverlays> in the graph for the given cell and all its
 * descendants. If no cell is specified then all overlays are removed from
 * the graph. This implementation uses <removeCellOverlays> to remove the
 * overlays from the individual cells.
 * 
 * Parameters:
 * 
 * cell - Optional <mxCell> that represents the root of the subtree to
 * remove the overlays from. Default is the root in the model.
 */
mxGraph.prototype.clearCellOverlays = function(cell)
{
	cell = (cell != null) ? cell : this.model.getRoot();
	this.removeCellOverlays(cell);
	
	// Recursively removes all overlays from the children
	var childCount = this.model.getChildCount(cell);
	
	for (var i = 0; i < childCount; i++)
	{
		var child = this.model.getChildAt(cell, i);
		this.clearCellOverlays(child); // recurse
	}
};

/**
 * Function: setCellWarning
 * 
 * Creates an overlay for the given cell using the warning and image or
 * <warningImage> and returns the new <mxCellOverlay>. The warning is
 * displayed as a tooltip in a red font and may contain HTML markup. If
 * the warning is null or a zero length string, then all overlays are
 * removed from the cell.
 * 
 * Example:
 * 
 * (code)
 * graph.setCellWarning(cell, '<b>Warning:</b>: Hello, World!');
 * (end)
 * 
 * Parameters:
 * 
 * cell - <mxCell> whose warning should be set.
 * warning - String that represents the warning to be displayed.
 * img - Optional <mxImage> to be used for the overlay. Default is
 * <warningImage>.
 * isSelect - Optional boolean indicating if a click on the overlay
 * should select the corresponding cell. Default is false.
 */
mxGraph.prototype.setCellWarning = function(cell, warning, img, isSelect)
{
	if (warning != null && warning.length > 0)
	{
		img = (img != null) ? img : this.warningImage;
		
		// Creates the overlay with the image and warning
		var overlay = new mxCellOverlay(img,
			'<font color=red>'+warning+'</font>');
		
		// Adds a handler for single mouseclicks to select the cell
		if (isSelect)
		{
			overlay.addListener(mxEvent.CLICK,
				mxUtils.bind(this, function(sender, evt)
				{
					if (this.isEnabled())
					{
						this.setSelectionCell(cell);
					}
				})
			);
		}
		
		// Sets and returns the overlay in the graph
		return this.addCellOverlay(cell, overlay);
	}
	else
	{
		this.removeCellOverlays(cell);
	}
	
	return null;
};

/**
 * Group: In-place editing
 */

/**
 * Function: startEditing
 * 
 * Calls <startEditingAtCell> using the given cell or the first selection
 * cell.
 * 
 * Parameters:
 * 
 * evt - Optional mouse event that triggered the editing.
 */
mxGraph.prototype.startEditing = function(evt)
{
	this.startEditingAtCell(null, evt);
};

/**
 * Function: startEditingAtCell
 * 
 * Fires a <startEditing> event and invokes <mxCellEditor.startEditing>
 * on <editor>. After editing was started, a <editingStarted> event is
 * fired.
 * 
 * Parameters:
 * 
 * cell - <mxCell> to start the in-place editor for.
 * evt - Optional mouse event that triggered the editing.
 */
mxGraph.prototype.startEditingAtCell = function(cell, evt)
{
	if (evt == null || !mxEvent.isMultiTouchEvent(evt))
	{
		if (cell == null)
		{
			cell = this.getSelectionCell();
			
			if (cell != null && !this.isCellEditable(cell))
			{
				cell = null;
			}
		}
	
		if (cell != null)
		{
			this.fireEvent(new mxEventObject(mxEvent.START_EDITING,
					'cell', cell, 'event', evt));
			this.cellEditor.startEditing(cell, evt);
			this.fireEvent(new mxEventObject(mxEvent.EDITING_STARTED,
					'cell', cell, 'event', evt));
		}
	}
};

/**
 * Function: getEditingValue
 * 
 * Returns the initial value for in-place editing. This implementation
 * returns <convertValueToString> for the given cell. If this function is
 * overridden, then <mxGraphModel.valueForCellChanged> should take care
 * of correctly storing the actual new value inside the user object.
 * 
 * Parameters:
 * 
 * cell - <mxCell> for which the initial editing value should be returned.
 * evt - Optional mouse event that triggered the editor.
 */
mxGraph.prototype.getEditingValue = function(cell, evt)
{
	return this.convertValueToString(cell);
};

/**
 * Function: stopEditing
 * 
 * Stops the current editing  and fires a <editingStopped> event.
 * 
 * Parameters:
 * 
 * cancel - Boolean that specifies if the current editing value
 * should be stored.
 */
mxGraph.prototype.stopEditing = function(cancel)
{
	this.cellEditor.stopEditing(cancel);
	this.fireEvent(new mxEventObject(mxEvent.EDITING_STOPPED, 'cancel', cancel));
};

/**
 * Function: labelChanged
 * 
 * Sets the label of the specified cell to the given value using
 * <cellLabelChanged> and fires <mxEvent.LABEL_CHANGED> while the
 * transaction is in progress. Returns the cell whose label was changed.
 * 
 * Parameters:
 * 
 * cell - <mxCell> whose label should be changed.
 * value - New label to be assigned.
 * evt - Optional event that triggered the change.
 */
mxGraph.prototype.labelChanged = function(cell, value, evt)
{
	this.model.beginUpdate();
	try
	{
		var old = cell.value;
		this.cellLabelChanged(cell, value, this.isAutoSizeCell(cell));
		this.fireEvent(new mxEventObject(mxEvent.LABEL_CHANGED,
			'cell', cell, 'value', value, 'old', old, 'event', evt));
	}
	finally
	{
		this.model.endUpdate();
	}
	
	return cell;
};

/**
 * Function: cellLabelChanged
 * 
 * Sets the new label for a cell. If autoSize is true then
 * <cellSizeUpdated> will be called.
 * 
 * In the following example, the function is extended to map changes to
 * attributes in an XML node, as shown in <convertValueToString>.
 * Alternatively, the handling of this can be implemented as shown in
 * <mxGraphModel.valueForCellChanged> without the need to clone the
 * user object.
 * 
 * (code)
 * var graphCellLabelChanged = graph.cellLabelChanged;
 * graph.cellLabelChanged = function(cell, newValue, autoSize)
 * {
 * 	// Cloned for correct undo/redo
 * 	var elt = cell.value.cloneNode(true);
 *  elt.setAttribute('label', newValue);
 *  
 *  newValue = elt;
 *  graphCellLabelChanged.apply(this, arguments);
 * };
 * (end) 
 * 
 * Parameters:
 * 
 * cell - <mxCell> whose label should be changed.
 * value - New label to be assigned.
 * autoSize - Boolean that specifies if <cellSizeUpdated> should be called.
 */
mxGraph.prototype.cellLabelChanged = function(cell, value, autoSize)
{
	this.model.beginUpdate();
	try
	{
		this.model.setValue(cell, value);
		
		if (autoSize)
		{
			this.cellSizeUpdated(cell, false);
		}
	}
	finally
	{
		this.model.endUpdate();
	}
};

/**
 * Group: Event processing
 */

/**
 * Function: escape
 * 
 * Processes an escape keystroke.
 * 
 * Parameters:
 * 
 * evt - Mouseevent that represents the keystroke.
 */
mxGraph.prototype.escape = function(evt)
{
	this.fireEvent(new mxEventObject(mxEvent.ESCAPE, 'event', evt));
};

/**
 * Function: click
 * 
 * Processes a singleclick on an optional cell and fires a <click> event.
 * The click event is fired initially. If the graph is enabled and the
 * event has not been consumed, then the cell is selected using
 * <selectCellForEvent> or the selection is cleared using
 * <clearSelection>. The events consumed state is set to true if the
 * corresponding <mxMouseEvent> has been consumed.
 *
 * To handle a click event, use the following code.
 * 
 * (code)
 * graph.addListener(mxEvent.CLICK, function(sender, evt)
 * {
 *   var e = evt.getProperty('event'); // mouse event
 *   var cell = evt.getProperty('cell'); // cell may be null
 *   
 *   if (cell != null)
 *   {
 *     // Do something useful with cell and consume the event
 *     evt.consume();
 *   }
 * });
 * (end)
 * 
 * Parameters:
 * 
 * me - <mxMouseEvent> that represents the single click.
 */
mxGraph.prototype.click = function(me)
{
	var evt = me.getEvent();
	var cell = me.getCell();
	var mxe = new mxEventObject(mxEvent.CLICK, 'event', evt, 'cell', cell);
	
	if (me.isConsumed())
	{
		mxe.consume();
	}
	
	this.fireEvent(mxe);
	
	// Handles the event if it has not been consumed
	if (this.isEnabled() && !mxEvent.isConsumed(evt) && !mxe.isConsumed())
	{
		if (cell != null)
		{
			if (this.isTransparentClickEvent(evt))
			{
				var active = false;
				
				var tmp = this.getCellAt(me.graphX, me.graphY, null, null, null, mxUtils.bind(this, function(state)
				{
					var selected = this.isCellSelected(state.cell);
					active = active || selected;
					
					return !active || selected;
				}));
				
				if (tmp != null)
				{
					cell = tmp;
				}
			}
			
			this.selectCellForEvent(cell, evt);
		}
		else
		{
			var swimlane = null;
			
			if (this.isSwimlaneSelectionEnabled())
			{
				// Gets the swimlane at the location (includes
				// content area of swimlanes)
				swimlane = this.getSwimlaneAt(me.getGraphX(), me.getGraphY());
			}

			// Selects the swimlane and consumes the event
			if (swimlane != null)
			{
				this.selectCellForEvent(swimlane, evt);
			}
			
			// Ignores the event if the control key is pressed
			else if (!this.isToggleEvent(evt))
			{
				this.clearSelection();
			}
		}
	}
};

/**
 * Function: dblClick
 * 
 * Processes a doubleclick on an optional cell and fires a <dblclick>
 * event. The event is fired initially. If the graph is enabled and the
 * event has not been consumed, then <edit> is called with the given
 * cell. The event is ignored if no cell was specified.
 *
 * Example for overriding this method.
 *
 * (code)
 * graph.dblClick = function(evt, cell)
 * {
 *   var mxe = new mxEventObject(mxEvent.DOUBLE_CLICK, 'event', evt, 'cell', cell);
 *   this.fireEvent(mxe);
 *   
 *   if (this.isEnabled() && !mxEvent.isConsumed(evt) && !mxe.isConsumed())
 *   {
 * 	   mxUtils.alert('Hello, World!');
 *     mxe.consume();
 *   }
 * }
 * (end)
 * 
 * Example listener for this event.
 * 
 * (code)
 * graph.addListener(mxEvent.DOUBLE_CLICK, function(sender, evt)
 * {
 *   var cell = evt.getProperty('cell');
 *   // do something with the cell and consume the
 *   // event to prevent in-place editing from start
 * });
 * (end) 
 * 
 * Parameters:
 * 
 * evt - Mouseevent that represents the doubleclick.
 * cell - Optional <mxCell> under the mousepointer.
 */
mxGraph.prototype.dblClick = function(evt, cell)
{
	var mxe = new mxEventObject(mxEvent.DOUBLE_CLICK, 'event', evt, 'cell', cell);
	this.fireEvent(mxe);
	
	// Handles the event if it has not been consumed
	if (this.isEnabled() && !mxEvent.isConsumed(evt) && !mxe.isConsumed() &&
		cell != null && this.isCellEditable(cell) && !this.isEditing(cell))
	{
		this.startEditingAtCell(cell, evt);
		mxEvent.consume(evt);
	}
};

/**
 * Function: tapAndHold
 * 
 * Handles the <mxMouseEvent> by highlighting the <mxCellState>.
 * 
 * Parameters:
 * 
 * me - <mxMouseEvent> that represents the touch event.
 * state - Optional <mxCellState> that is associated with the event.
 */
mxGraph.prototype.tapAndHold = function(me)
{
	var evt = me.getEvent();
	var mxe = new mxEventObject(mxEvent.TAP_AND_HOLD, 'event', evt, 'cell', me.getCell());

	// LATER: Check if event should be consumed if me is consumed
	this.fireEvent(mxe);

	if (mxe.isConsumed())
	{
		// Resets the state of the panning handler
		this.panningHandler.panningTrigger = false;
	}
	
	// Handles the event if it has not been consumed
	if (this.isEnabled() && !mxEvent.isConsumed(evt) && !mxe.isConsumed() && this.connectionHandler.isEnabled())
	{
		var state = this.view.getState(this.connectionHandler.marker.getCell(me));

		if (state != null)
		{
			this.connectionHandler.marker.currentColor = this.connectionHandler.marker.validColor;
			this.connectionHandler.marker.markedState = state;
			this.connectionHandler.marker.mark();
			
			this.connectionHandler.first = new mxPoint(me.getGraphX(), me.getGraphY());
			this.connectionHandler.edgeState = this.connectionHandler.createEdgeState(me);
			this.connectionHandler.previous = state;
			this.connectionHandler.fireEvent(new mxEventObject(mxEvent.START, 'state', this.connectionHandler.previous));
		}
	}
};

/**
 * Function: scrollPointToVisible
 * 
 * Scrolls the graph to the given point, extending the graph container if
 * specified.
 */
mxGraph.prototype.scrollPointToVisible = function(x, y, extend, border)
{
	if (!this.timerAutoScroll && (this.ignoreScrollbars || mxUtils.hasScrollbars(this.container)))
	{
		var c = this.container;
		border = (border != null) ? border : 20;
		
		if (x >= c.scrollLeft && y >= c.scrollTop && x <= c.scrollLeft + c.clientWidth &&
			y <= c.scrollTop + c.clientHeight)
		{
			var dx = c.scrollLeft + c.clientWidth - x;
			
			if (dx < border)
			{
				var old = c.scrollLeft;
				c.scrollLeft += border - dx;

				// Automatically extends the canvas size to the bottom, right
				// if the event is outside of the canvas and the edge of the
				// canvas has been reached. Notes: Needs fix for IE.
				if (extend && old == c.scrollLeft)
				{
					if (this.dialect == mxConstants.DIALECT_SVG)
					{
						var root = this.view.getDrawPane().ownerSVGElement;
						var width = this.container.scrollWidth + border - dx;
						
						// Updates the clipping region. This is an expensive
						// operation that should not be executed too often.
						root.style.width = width + 'px';
					}
					else
					{
						var width = Math.max(c.clientWidth, c.scrollWidth) + border - dx;
						var canvas = this.view.getCanvas();
						canvas.style.width = width + 'px';
					}
					
					c.scrollLeft += border - dx;
				}
			}
			else
			{
				dx = x - c.scrollLeft;
				
				if (dx < border)
				{
					c.scrollLeft -= border - dx;
				}
			}
			
			var dy = c.scrollTop + c.clientHeight - y;
			
			if (dy < border)
			{
				var old = c.scrollTop;
				c.scrollTop += border - dy;

				if (old == c.scrollTop && extend)
				{
					if (this.dialect == mxConstants.DIALECT_SVG)
					{
						var root = this.view.getDrawPane().ownerSVGElement;
						var height = this.container.scrollHeight + border - dy;
						
						// Updates the clipping region. This is an expensive
						// operation that should not be executed too often.
						root.style.height = height + 'px';
					}
					else
					{
						var height = Math.max(c.clientHeight, c.scrollHeight) + border - dy;
						var canvas = this.view.getCanvas();
						canvas.style.height = height + 'px';
					}
					
					c.scrollTop += border - dy;
				}
			}
			else
			{
				dy = y - c.scrollTop;
				
				if (dy < border)
				{
					c.scrollTop -= border - dy;
				}
			}
		}
	}
	else if (this.allowAutoPanning && !this.panningHandler.isActive())
	{
		if (this.panningManager == null)
		{
			this.panningManager = this.createPanningManager();
		}

		this.panningManager.panTo(x + this.panDx, y + this.panDy);
	}
};


/**
 * Function: createPanningManager
 * 
 * Creates and returns an <mxPanningManager>.
 */
mxGraph.prototype.createPanningManager = function()
{
	return new mxPanningManager(this);
};

/**
 * Function: getBorderSizes
 * 
 * Returns the size of the border and padding on all four sides of the
 * container. The left, top, right and bottom borders are stored in the x, y,
 * width and height of the returned <mxRectangle>, respectively.
 */
mxGraph.prototype.getBorderSizes = function()
{
	var css = mxUtils.getCurrentStyle(this.container);
	
	return new mxRectangle(mxUtils.parseCssNumber(css.paddingLeft) +
			((css.borderLeftStyle != 'none') ? mxUtils.parseCssNumber(css.borderLeftWidth) : 0),
		mxUtils.parseCssNumber(css.paddingTop) +
			((css.borderTopStyle != 'none') ? mxUtils.parseCssNumber(css.borderTopWidth) : 0),
		mxUtils.parseCssNumber(css.paddingRight) +
			((css.borderRightStyle != 'none') ? mxUtils.parseCssNumber(css.borderRightWidth) : 0),
		mxUtils.parseCssNumber(css.paddingBottom) +
			((css.borderBottomStyle != 'none') ? mxUtils.parseCssNumber(css.borderBottomWidth) : 0));
};

/**
 * Function: getPreferredPageSize
 * 
 * Returns the preferred size of the background page if <preferPageSize> is true.
 */
mxGraph.prototype.getPreferredPageSize = function(bounds, width, height)
{
	var scale = this.view.scale;
	var tr = this.view.translate;
	var fmt = this.pageFormat;
	var ps = this.pageScale;
	var page = new mxRectangle(0, 0, Math.ceil(fmt.width * ps), Math.ceil(fmt.height * ps));
	
	var hCount = (this.pageBreaksVisible) ? Math.ceil(width / page.width) : 1;
	var vCount = (this.pageBreaksVisible) ? Math.ceil(height / page.height) : 1;
	
	return new mxRectangle(0, 0, hCount * page.width + 2 + tr.x, vCount * page.height + 2 + tr.y);
};

/**
 * Function: fit
 *
 * Scales the graph such that the complete diagram fits into <container> and
 * returns the current scale in the view. To fit an initial graph prior to
 * rendering, set <mxGraphView.rendering> to false prior to changing the model
 * and execute the following after changing the model.
 * 
 * (code)
 * graph.fit();
 * graph.view.rendering = true;
 * graph.refresh();
 * (end)
 * 
 * To fit and center the graph, the following code can be used.
 * 
 * (code)
 * var margin = 2;
 * var max = 3;
 * 
 * var bounds = graph.getGraphBounds();
 * var cw = graph.container.clientWidth - margin;
 * var ch = graph.container.clientHeight - margin;
 * var w = bounds.width / graph.view.scale;
 * var h = bounds.height / graph.view.scale;
 * var s = Math.min(max, Math.min(cw / w, ch / h));
 * 
 * graph.view.scaleAndTranslate(s,
 *   (margin + cw - w * s) / (2 * s) - bounds.x / graph.view.scale,
 *   (margin + ch - h * s) / (2 * s) - bounds.y / graph.view.scale);
 * (end)
 * 
 * Parameters:
 * 
 * border - Optional number that specifies the border. Default is <border>.
 * keepOrigin - Optional boolean that specifies if the translate should be
 * changed. Default is false.
 * margin - Optional margin in pixels. Default is 0.
 * enabled - Optional boolean that specifies if the scale should be set or
 * just returned. Default is true.
 * ignoreWidth - Optional boolean that specifies if the width should be
 * ignored. Default is false.
 * ignoreHeight - Optional boolean that specifies if the height should be
 * ignored. Default is false.
 */
mxGraph.prototype.fit = function(border, keepOrigin, margin, enabled, ignoreWidth, ignoreHeight)
{
	if (this.container != null)
	{
		border = (border != null) ? border : this.getBorder();
		keepOrigin = (keepOrigin != null) ? keepOrigin : false;
		margin = (margin != null) ? margin : 0;
		enabled = (enabled != null) ? enabled : true;
		ignoreWidth = (ignoreWidth != null) ? ignoreWidth : false;
		ignoreHeight = (ignoreHeight != null) ? ignoreHeight : false;
		
		// Adds spacing and border from css
		var cssBorder = this.getBorderSizes();
		var w1 = this.container.offsetWidth - cssBorder.x - cssBorder.width - 1;
		var h1 = this.container.offsetHeight - cssBorder.y - cssBorder.height - 1;
		var bounds = this.view.getGraphBounds();
		
		if (bounds.width > 0 && bounds.height > 0)
		{
			if (keepOrigin && bounds.x != null && bounds.y != null)
			{
				bounds = bounds.clone();
				bounds.width += bounds.x;
				bounds.height += bounds.y;
				bounds.x = 0;
				bounds.y = 0;
			}
			
			// LATER: Use unscaled bounding boxes to fix rounding errors
			var s = this.view.scale;
			var w2 = bounds.width / s;
			var h2 = bounds.height / s;
			
			// Fits to the size of the background image if required
			if (this.backgroundImage != null)
			{
				w2 = Math.max(w2, this.backgroundImage.width - bounds.x / s);
				h2 = Math.max(h2, this.backgroundImage.height - bounds.y / s);
			}
			
			var b = ((keepOrigin) ? border : 2 * border) + margin;

			w1 -= b;
			h1 -= b;
			
			var s2 = (((ignoreWidth) ? h1 / h2 : (ignoreHeight) ? w1 / w2 :
				Math.min(w1 / w2, h1 / h2)));
			
			if (this.minFitScale != null)
			{
				s2 = Math.max(s2, this.minFitScale);
			}
			
			if (this.maxFitScale != null)
			{
				s2 = Math.min(s2, this.maxFitScale);
			}
	
			if (enabled)
			{
				if (!keepOrigin)
				{
					if (!mxUtils.hasScrollbars(this.container))
					{
						var x0 = (bounds.x != null) ? Math.floor(this.view.translate.x - bounds.x / s + border / s2 + margin / 2) : border;
						var y0 = (bounds.y != null) ? Math.floor(this.view.translate.y - bounds.y / s + border / s2 + margin / 2) : border;

						this.view.scaleAndTranslate(s2, x0, y0);
					}
					else
					{
						this.view.setScale(s2);
						var b2 = this.getGraphBounds();
						
						if (b2.x != null)
						{
							this.container.scrollLeft = b2.x;
						}
						
						if (b2.y != null)
						{
							this.container.scrollTop = b2.y;
						}
					}
				}
				else if (this.view.scale != s2)
				{
					this.view.setScale(s2);
				}
			}
			else
			{
				return s2;
			}
		}
	}

	return this.view.scale;
};

/**
 * Function: sizeDidChange
 * 
 * Called when the size of the graph has changed. This implementation fires
 * a <size> event after updating the clipping region of the SVG element in
 * SVG-bases browsers.
 */
mxGraph.prototype.sizeDidChange = function()
{
	var bounds = this.getGraphBounds();
	
	if (this.container != null)
	{
		var border = this.getBorder();
		
		var width = Math.max(0, bounds.x + bounds.width + border);
		var height = Math.max(0, bounds.y + bounds.height + border);
		
		if (this.minimumContainerSize != null)
		{
			width = Math.max(width, this.minimumContainerSize.width);
			height = Math.max(height, this.minimumContainerSize.height);
		}

		if (this.resizeContainer)
		{
			this.doResizeContainer(width, height);
		}

		if (this.preferPageSize || (!mxClient.IS_IE && this.pageVisible))
		{
			var size = this.getPreferredPageSize(bounds, Math.max(1, width), Math.max(1, height));
			
			if (size != null)
			{
				width = size.width * this.view.scale;
				height = size.height * this.view.scale;
			}
		}
		
		if (this.minimumGraphSize != null)
		{
			width = Math.max(width, this.minimumGraphSize.width * this.view.scale);
			height = Math.max(height, this.minimumGraphSize.height * this.view.scale);
		}

		width = Math.ceil(width);
		height = Math.ceil(height);

		if (this.dialect == mxConstants.DIALECT_SVG)
		{
			var root = this.view.getDrawPane().ownerSVGElement;
			
			root.style.minWidth = Math.max(1, width) + 'px';
			root.style.minHeight = Math.max(1, height) + 'px';
			root.style.width = '100%';
			root.style.height = '100%';
		}
		else
		{
			if (mxClient.IS_QUIRKS)
			{
				// Quirks mode does not support minWidth/-Height
				this.view.updateHtmlCanvasSize(Math.max(1, width), Math.max(1, height));
			}
			else
			{
				this.view.canvas.style.minWidth = Math.max(1, width) + 'px';
				this.view.canvas.style.minHeight = Math.max(1, height) + 'px';
			}
		}
		
		this.updatePageBreaks(this.pageBreaksVisible, width, height);
	}

	this.fireEvent(new mxEventObject(mxEvent.SIZE, 'bounds', bounds));
};

/**
 * Function: doResizeContainer
 * 
 * Resizes the container for the given graph width and height.
 */
mxGraph.prototype.doResizeContainer = function(width, height)
{
	if (this.maximumContainerSize != null)
	{
		width = Math.min(this.maximumContainerSize.width, width);
		height = Math.min(this.maximumContainerSize.height, height);
	}

	this.container.style.width = Math.ceil(width) + 'px';
	this.container.style.height = Math.ceil(height) + 'px';
};

/**
 * Function: updatePageBreaks
 * 
 * Invokes from <sizeDidChange> to redraw the page breaks.
 * 
 * Parameters:
 * 
 * visible - Boolean that specifies if page breaks should be shown.
 * width - Specifies the width of the container in pixels.
 * height - Specifies the height of the container in pixels.
 */
mxGraph.prototype.updatePageBreaks = function(visible, width, height)
{
	var scale = this.view.scale;
	var tr = this.view.translate;
	var fmt = this.pageFormat;
	var ps = scale * this.pageScale;
	var bounds = new mxRectangle(0, 0, fmt.width * ps, fmt.height * ps);

	var gb = mxRectangle.fromRectangle(this.getGraphBounds());
	gb.width = Math.max(1, gb.width);
	gb.height = Math.max(1, gb.height);
	
	bounds.x = Math.floor((gb.x - tr.x * scale) / bounds.width) * bounds.width + tr.x * scale;
	bounds.y = Math.floor((gb.y - tr.y * scale) / bounds.height) * bounds.height + tr.y * scale;
	
	gb.width = Math.ceil((gb.width + (gb.x - bounds.x)) / bounds.width) * bounds.width;
	gb.height = Math.ceil((gb.height + (gb.y - bounds.y)) / bounds.height) * bounds.height;
	
	// Does not show page breaks if the scale is too small
	visible = visible && Math.min(bounds.width, bounds.height) > this.minPageBreakDist;

	var horizontalCount = (visible) ? Math.ceil(gb.height / bounds.height) + 1 : 0;
	var verticalCount = (visible) ? Math.ceil(gb.width / bounds.width) + 1 : 0;
	var right = (verticalCount - 1) * bounds.width;
	var bottom = (horizontalCount - 1) * bounds.height;
	
	if (this.horizontalPageBreaks == null && horizontalCount > 0)
	{
		this.horizontalPageBreaks = [];
	}

	if (this.verticalPageBreaks == null && verticalCount > 0)
	{
		this.verticalPageBreaks = [];
	}
	
	var drawPageBreaks = mxUtils.bind(this, function(breaks)
	{
		if (breaks != null)
		{
			var count = (breaks == this.horizontalPageBreaks) ? horizontalCount : verticalCount; 
			
			for (var i = 0; i <= count; i++)
			{
				var pts = (breaks == this.horizontalPageBreaks) ?
					[new mxPoint(Math.round(bounds.x), Math.round(bounds.y + i * bounds.height)),
			         new mxPoint(Math.round(bounds.x + right), Math.round(bounds.y + i * bounds.height))] :
			        [new mxPoint(Math.round(bounds.x + i * bounds.width), Math.round(bounds.y)),
			         new mxPoint(Math.round(bounds.x + i * bounds.width), Math.round(bounds.y + bottom))];

				if (breaks[i] != null)
				{
					breaks[i].points = pts;
					breaks[i].redraw();
				}
				else
				{
					var pageBreak = new mxPolyline(pts, this.pageBreakColor);
					pageBreak.dialect = this.dialect;
					pageBreak.pointerEvents = false;
					pageBreak.isDashed = this.pageBreakDashed;
					pageBreak.init(this.view.backgroundPane);
					pageBreak.redraw();
					
					breaks[i] = pageBreak;
				}
			}
			
			for (var i = count; i < breaks.length; i++)
			{
				breaks[i].destroy();
			}
			
			breaks.splice(count, breaks.length - count);
		}
	});
	
	drawPageBreaks(this.horizontalPageBreaks);
	drawPageBreaks(this.verticalPageBreaks);
};

/**
 * Group: Cell styles
 */

/**
 * Function: getCellStyle
 * 
 * Returns an array of key, value pairs representing the cell style for the
 * given cell. If no string is defined in the model that specifies the
 * style, then the default style for the cell is returned or <EMPTY_ARRAY>,
 * if not style can be found. Note: You should try and get the cell state
 * for the given cell and use the cached style in the state before using
 * this method.
 * 
 * Parameters:
 * 
 * cell - <mxCell> whose style should be returned as an array.
 */
mxGraph.prototype.getCellStyle = function(cell)
{
	var stylename = this.model.getStyle(cell);
	var style = null;
	
	// Gets the default style for the cell
	if (this.model.isEdge(cell))
	{
		style = this.stylesheet.getDefaultEdgeStyle();
	}
	else
	{
		style = this.stylesheet.getDefaultVertexStyle();
	}
	
	// Resolves the stylename using the above as the default
	if (stylename != null)
	{
		style = this.postProcessCellStyle(this.stylesheet.getCellStyle(stylename, style));
	}
	
	// Returns a non-null value if no style can be found
	if (style == null)
	{
		style = mxGraph.prototype.EMPTY_ARRAY;
	}
	
	return style;
};

/**
 * Function: postProcessCellStyle
 * 
 * Tries to resolve the value for the image style in the image bundles and
 * turns short data URIs as defined in mxImageBundle to data URIs as
 * defined in RFC 2397 of the IETF.
 */
mxGraph.prototype.postProcessCellStyle = function(style)
{
	if (style != null)
	{
		var key = style[mxConstants.STYLE_IMAGE];
		var image = this.getImageFromBundles(key);

		if (image != null)
		{
			style[mxConstants.STYLE_IMAGE] = image;
		}
		else
		{
			image = key;
		}
		
		// Converts short data uris to normal data uris
		if (image != null && image.substring(0, 11) == 'data:image/')
		{
			if (image.substring(0, 20) == 'data:image/svg+xml,<')
			{
				// Required for FF and IE11
				image = image.substring(0, 19) + encodeURIComponent(image.substring(19));
			}
			else if (image.substring(0, 22) != 'data:image/svg+xml,%3C')
			{
				var comma = image.indexOf(',');
				
				// Adds base64 encoding prefix if needed
				if (comma > 0 && image.substring(comma - 7, comma + 1) != ';base64,')
				{
					image = image.substring(0, comma) + ';base64,'
						+ image.substring(comma + 1);
				}
			}
			
			style[mxConstants.STYLE_IMAGE] = image;
		}
	}

	return style;
};

/**
 * Function: setCellStyle
 * 
 * Sets the style of the specified cells. If no cells are given, then the
 * selection cells are changed.
 * 
 * Parameters:
 * 
 * style - String representing the new style of the cells.
 * cells - Optional array of <mxCells> to set the style for. Default is the
 * selection cells.
 */
mxGraph.prototype.setCellStyle = function(style, cells)
{
	cells = cells || this.getSelectionCells();
	
	if (cells != null)
	{
		this.model.beginUpdate();
		try
		{
			for (var i = 0; i < cells.length; i++)
			{
				this.model.setStyle(cells[i], style);
			}
		}
		finally
		{
			this.model.endUpdate();
		}
	}
};

/**
 * Function: toggleCellStyle
 * 
 * Toggles the boolean value for the given key in the style of the given cell
 * and returns the new value as 0 or 1. If no cell is specified then the
 * selection cell is used.
 * 
 * Parameter:
 * 
 * key - String representing the key for the boolean value to be toggled.
 * defaultValue - Optional boolean default value if no value is defined.
 * Default is false.
 * cell - Optional <mxCell> whose style should be modified. Default is
 * the selection cell.
 */
mxGraph.prototype.toggleCellStyle = function(key, defaultValue, cell)
{
	cell = cell || this.getSelectionCell();
	
	return this.toggleCellStyles(key, defaultValue, [cell]);
};

/**
 * Function: toggleCellStyles
 * 
 * Toggles the boolean value for the given key in the style of the given cells
 * and returns the new value as 0 or 1. If no cells are specified, then the
 * selection cells are used. For example, this can be used to toggle
 * <mxConstants.STYLE_ROUNDED> or any other style with a boolean value.
 * 
 * Parameter:
 * 
 * key - String representing the key for the boolean value to be toggled.
 * defaultValue - Optional boolean default value if no value is defined.
 * Default is false.
 * cells - Optional array of <mxCells> whose styles should be modified.
 * Default is the selection cells.
 */
mxGraph.prototype.toggleCellStyles = function(key, defaultValue, cells)
{
	defaultValue = (defaultValue != null) ? defaultValue : false;
	cells = cells || this.getSelectionCells();
	var value = null;
	
	if (cells != null && cells.length > 0)
	{
		var state = this.view.getState(cells[0]);
		var style = (state != null) ? state.style : this.getCellStyle(cells[0]);
		
		if (style != null)
		{
			value = (mxUtils.getValue(style, key, defaultValue)) ? 0 : 1;
			this.setCellStyles(key, value, cells);
		}
	}
	
	return value;
};

/**
 * Function: setCellStyles
 * 
 * Sets the key to value in the styles of the given cells. This will modify
 * the existing cell styles in-place and override any existing assignment
 * for the given key. If no cells are specified, then the selection cells
 * are changed. If no value is specified, then the respective key is
 * removed from the styles.
 * 
 * Parameters:
 * 
 * key - String representing the key to be assigned.
 * value - String representing the new value for the key.
 * cells - Optional array of <mxCells> to change the style for. Default is
 * the selection cells.
 */
mxGraph.prototype.setCellStyles = function(key, value, cells)
{
	cells = cells || this.getSelectionCells();
	mxUtils.setCellStyles(this.model, cells, key, value);
};

/**
 * Function: toggleCellStyleFlags
 * 
 * Toggles the given bit for the given key in the styles of the specified
 * cells.
 * 
 * Parameters:
 * 
 * key - String representing the key to toggle the flag in.
 * flag - Integer that represents the bit to be toggled.
 * cells - Optional array of <mxCells> to change the style for. Default is
 * the selection cells.
 */
mxGraph.prototype.toggleCellStyleFlags = function(key, flag, cells)
{
	this.setCellStyleFlags(key, flag, null, cells);
};

/**
 * Function: setCellStyleFlags
 * 
 * Sets or toggles the given bit for the given key in the styles of the
 * specified cells.
 * 
 * Parameters:
 * 
 * key - String representing the key to toggle the flag in.
 * flag - Integer that represents the bit to be toggled.
 * value - Boolean value to be used or null if the value should be toggled.
 * cells - Optional array of <mxCells> to change the style for. Default is
 * the selection cells.
 */
mxGraph.prototype.setCellStyleFlags = function(key, flag, value, cells)
{
	cells = cells || this.getSelectionCells();
	
	if (cells != null && cells.length > 0)
	{
		if (value == null)
		{
			var state = this.view.getState(cells[0]);
			var style = (state != null) ? state.style : this.getCellStyle(cells[0]);
			
			if (style != null)
			{
				var current = parseInt(style[key] || 0);
				value = !((current & flag) == flag);
			}
		}

		mxUtils.setCellStyleFlags(this.model, cells, key, flag, value);
	}
};

/**
 * Group: Cell alignment and orientation
 */

/**
 * Function: alignCells
 * 
 * Aligns the given cells vertically or horizontally according to the given
 * alignment using the optional parameter as the coordinate.
 * 
 * Parameters:
 * 
 * align - Specifies the alignment. Possible values are all constants in
 * mxConstants with an ALIGN prefix.
 * cells - Array of <mxCells> to be aligned.
 * param - Optional coordinate for the alignment.
 */
mxGraph.prototype.alignCells = function(align, cells, param)
{
	if (cells == null)
	{
		cells = this.getSelectionCells();
	}
	
	if (cells != null && cells.length > 1)
	{
		// Finds the required coordinate for the alignment
		if (param == null)
		{
			for (var i = 0; i < cells.length; i++)
			{
				var state = this.view.getState(cells[i]);
				
				if (state != null && !this.model.isEdge(cells[i]))
				{
					if (param == null)
					{
						if (align == mxConstants.ALIGN_CENTER)
						{
							param = state.x + state.width / 2;
							break;
						}
						else if (align == mxConstants.ALIGN_RIGHT)
						{
							param = state.x + state.width;
						}
						else if (align == mxConstants.ALIGN_TOP)
						{
							param = state.y;
						}
						else if (align == mxConstants.ALIGN_MIDDLE)
						{
							param = state.y + state.height / 2;
							break;
						}
						else if (align == mxConstants.ALIGN_BOTTOM)
						{
							param = state.y + state.height;
						}
						else
						{
							param = state.x;
						}
					}
					else
					{
						if (align == mxConstants.ALIGN_RIGHT)
						{
							param = Math.max(param, state.x + state.width);
						}
						else if (align == mxConstants.ALIGN_TOP)
						{
							param = Math.min(param, state.y);
						}
						else if (align == mxConstants.ALIGN_BOTTOM)
						{
							param = Math.max(param, state.y + state.height);
						}
						else
						{
							param = Math.min(param, state.x);
						}
					}
				}
			}
		}

		// Aligns the cells to the coordinate
		if (param != null)
		{
			var s = this.view.scale;

			this.model.beginUpdate();
			try
			{
				for (var i = 0; i < cells.length; i++)
				{
					var state = this.view.getState(cells[i]);
					
					if (state != null)
					{
						var geo = this.getCellGeometry(cells[i]);
						
						if (geo != null && !this.model.isEdge(cells[i]))
						{
							geo = geo.clone();
							
							if (align == mxConstants.ALIGN_CENTER)
							{
								geo.x += (param - state.x - state.width / 2) / s;
							}
							else if (align == mxConstants.ALIGN_RIGHT)
							{
								geo.x += (param - state.x - state.width) / s;
							}
							else if (align == mxConstants.ALIGN_TOP)
							{
								geo.y += (param - state.y) / s;
							}
							else if (align == mxConstants.ALIGN_MIDDLE)
							{
								geo.y += (param - state.y - state.height / 2) / s;
							}
							else if (align == mxConstants.ALIGN_BOTTOM)
							{
								geo.y += (param - state.y - state.height) / s;
							}
							else
							{
								geo.x += (param - state.x) / s;
							}
							
							this.resizeCell(cells[i], geo);
						}
					}
				}
				
				this.fireEvent(new mxEventObject(mxEvent.ALIGN_CELLS,
						'align', align, 'cells', cells));
			}
			finally
			{
				this.model.endUpdate();
			}
		}
	}
	
	return cells;
};

/**
 * Function: flipEdge
 * 
 * Toggles the style of the given edge between null (or empty) and
 * <alternateEdgeStyle>. This method fires <mxEvent.FLIP_EDGE> while the
 * transaction is in progress. Returns the edge that was flipped.
 * 
 * Here is an example that overrides this implementation to invert the
 * value of <mxConstants.STYLE_ELBOW> without removing any existing styles.
 * 
 * (code)
 * graph.flipEdge = function(edge)
 * {
 *   if (edge != null)
 *   {
 *     var state = this.view.getState(edge);
 *     var style = (state != null) ? state.style : this.getCellStyle(edge);
 *     
 *     if (style != null)
 *     {
 *       var elbow = mxUtils.getValue(style, mxConstants.STYLE_ELBOW,
 *           mxConstants.ELBOW_HORIZONTAL);
 *       var value = (elbow == mxConstants.ELBOW_HORIZONTAL) ?
 *           mxConstants.ELBOW_VERTICAL : mxConstants.ELBOW_HORIZONTAL;
 *       this.setCellStyles(mxConstants.STYLE_ELBOW, value, [edge]);
 *     }
 *   }
 * };
 * (end)
 * 
 * Parameters:
 * 
 * edge - <mxCell> whose style should be changed.
 */
mxGraph.prototype.flipEdge = function(edge)
{
	if (edge != null &&
		this.alternateEdgeStyle != null)
	{
		this.model.beginUpdate();
		try
		{
			var style = this.model.getStyle(edge);

			if (style == null || style.length == 0)
			{
				this.model.setStyle(edge, this.alternateEdgeStyle);
			}
			else
			{
				this.model.setStyle(edge, null);
			}

			// Removes all existing control points
			this.resetEdge(edge);
			this.fireEvent(new mxEventObject(mxEvent.FLIP_EDGE, 'edge', edge));
		}
		finally
		{
			this.model.endUpdate();
		}
	}

	return edge;
};

/**
 * Function: addImageBundle
 *
 * Adds the specified <mxImageBundle>.
 */
mxGraph.prototype.addImageBundle = function(bundle)
{
	this.imageBundles.push(bundle);
};

/**
 * Function: removeImageBundle
 * 
 * Removes the specified <mxImageBundle>.
 */
mxGraph.prototype.removeImageBundle = function(bundle)
{
	var tmp = [];
	
	for (var i = 0; i < this.imageBundles.length; i++)
	{
		if (this.imageBundles[i] != bundle)
		{
			tmp.push(this.imageBundles[i]);
		}
	}
	
	this.imageBundles = tmp;
};

/**
 * Function: getImageFromBundles
 *
 * Searches all <imageBundles> for the specified key and returns the value
 * for the first match or null if the key is not found.
 */
mxGraph.prototype.getImageFromBundles = function(key)
{
	if (key != null)
	{
		for (var i = 0; i < this.imageBundles.length; i++)
		{
			var image = this.imageBundles[i].getImage(key);
			
			if (image != null)
			{
				return image;
			}
		}
	}
	
	return null;
};

/**
 * Group: Order
 */

/**
 * Function: orderCells
 * 
 * Moves the given cells to the front or back. The change is carried out
 * using <cellsOrdered>. This method fires <mxEvent.ORDER_CELLS> while the
 * transaction is in progress.
 * 
 * Parameters:
 * 
 * back - Boolean that specifies if the cells should be moved to back.
 * cells - Array of <mxCells> to move to the background. If null is
 * specified then the selection cells are used.
 */
mxGraph.prototype.orderCells = function(back, cells)
{
	if (cells == null)
	{
		cells = mxUtils.sortCells(this.getSelectionCells(), true);
	}

	this.model.beginUpdate();
	try
	{
		this.cellsOrdered(cells, back);
		this.fireEvent(new mxEventObject(mxEvent.ORDER_CELLS,
				'back', back, 'cells', cells));
	}
	finally
	{
		this.model.endUpdate();
	}

	return cells;
};

/**
 * Function: cellsOrdered
 * 
 * Moves the given cells to the front or back. This method fires
 * <mxEvent.CELLS_ORDERED> while the transaction is in progress.
 * 
 * Parameters:
 * 
 * cells - Array of <mxCells> whose order should be changed.
 * back - Boolean that specifies if the cells should be moved to back.
 */
mxGraph.prototype.cellsOrdered = function(cells, back)
{
	if (cells != null)
	{
		this.model.beginUpdate();
		try
		{
			for (var i = 0; i < cells.length; i++)
			{
				var parent = this.model.getParent(cells[i]);

				if (back)
				{
					this.model.add(parent, cells[i], i);
				}
				else
				{
					this.model.add(parent, cells[i],
							this.model.getChildCount(parent) - 1);
				}
			}
			
			this.fireEvent(new mxEventObject(mxEvent.CELLS_ORDERED,
					'back', back, 'cells', cells));
		}
		finally
		{
			this.model.endUpdate();
		}
	}
};

/**
 * Group: Grouping
 */

/**
 * Function: groupCells
 * 
 * Adds the cells into the given group. The change is carried out using
 * <cellsAdded>, <cellsMoved> and <cellsResized>. This method fires
 * <mxEvent.GROUP_CELLS> while the transaction is in progress. Returns the
 * new group. A group is only created if there is at least one entry in the
 * given array of cells.
 * 
 * Parameters:
 * 
 * group - <mxCell> that represents the target group. If null is specified
 * then a new group is created using <createGroupCell>.
 * border - Optional integer that specifies the border between the child
 * area and the group bounds. Default is 0.
 * cells - Optional array of <mxCells> to be grouped. If null is specified
 * then the selection cells are used.
 */
mxGraph.prototype.groupCells = function(group, border, cells)
{
	if (cells == null)
	{
		cells = mxUtils.sortCells(this.getSelectionCells(), true);
	}

	cells = this.getCellsForGroup(cells);

	if (group == null)
	{
		group = this.createGroupCell(cells);
	}

	var bounds = this.getBoundsForGroup(group, cells, border);

	if (cells.length > 0 && bounds != null)
	{
		// Uses parent of group or previous parent of first child
		var parent = this.model.getParent(group);
		
		if (parent == null)
		{
			parent = this.model.getParent(cells[0]);
		}

		this.model.beginUpdate();
		try
		{
			// Checks if the group has a geometry and
			// creates one if one does not exist
			if (this.getCellGeometry(group) == null)
			{
				this.model.setGeometry(group, new mxGeometry());
			}

			// Adds the group into the parent
			var index = this.model.getChildCount(parent);
			this.cellsAdded([group], parent, index, null, null, false, false, false);

			// Adds the children into the group and moves
			index = this.model.getChildCount(group);
			this.cellsAdded(cells, group, index, null, null, false, false, false);
			this.cellsMoved(cells, -bounds.x, -bounds.y, false, false, false);

			// Resizes the group
			this.cellsResized([group], [bounds], false);

			this.fireEvent(new mxEventObject(mxEvent.GROUP_CELLS,
					'group', group, 'border', border, 'cells', cells));
		}
		finally
		{
			this.model.endUpdate();
		}
	}

	return group;
};

/**
 * Function: getCellsForGroup
 * 
 * Returns the cells with the same parent as the first cell
 * in the given array.
 */
mxGraph.prototype.getCellsForGroup = function(cells)
{
	var result = [];

	if (cells != null && cells.length > 0)
	{
		var parent = this.model.getParent(cells[0]);
		result.push(cells[0]);

		// Filters selection cells with the same parent
		for (var i = 1; i < cells.length; i++)
		{
			if (this.model.getParent(cells[i]) == parent)
			{
				result.push(cells[i]);
			}
		}
	}

	return result;
};

/**
 * Function: getBoundsForGroup
 * 
 * Returns the bounds to be used for the given group and children.
 */
mxGraph.prototype.getBoundsForGroup = function(group, children, border)
{
	var result = this.getBoundingBoxFromGeometry(children, true);
	
	if (result != null)
	{
		if (this.isSwimlane(group))
		{
			var size = this.getStartSize(group);
			
			result.x -= size.width;
			result.y -= size.height;
			result.width += size.width;
			result.height += size.height;
		}
		
		// Adds the border
		if (border != null)
		{
			result.x -= border;
			result.y -= border;
			result.width += 2 * border;
			result.height += 2 * border;
		}
	}			
	
	return result;
};

/**
 * Function: createGroupCell
 * 
 * Hook for creating the group cell to hold the given array of <mxCells> if
 * no group cell was given to the <group> function.
 * 
 * The following code can be used to set the style of new group cells.
 * 
 * (code)
 * var graphCreateGroupCell = graph.createGroupCell;
 * graph.createGroupCell = function(cells)
 * {
 *   var group = graphCreateGroupCell.apply(this, arguments);
 *   group.setStyle('group');
 *   
 *   return group;
 * };
 */
mxGraph.prototype.createGroupCell = function(cells)
{
	var group = new mxCell('');
	group.setVertex(true);
	group.setConnectable(false);
	
	return group;
};

/**
 * Function: ungroupCells
 * 
 * Ungroups the given cells by moving the children the children to their
 * parents parent and removing the empty groups. Returns the children that
 * have been removed from the groups.
 * 
 * Parameters:
 * 
 * cells - Array of cells to be ungrouped. If null is specified then the
 * selection cells are used.
 */
mxGraph.prototype.ungroupCells = function(cells)
{
	var result = [];
	
	if (cells == null)
	{
		cells = this.getSelectionCells();

		// Finds the cells with children
		var tmp = [];
		
		for (var i = 0; i < cells.length; i++)
		{
			if (this.model.getChildCount(cells[i]) > 0)
			{
				tmp.push(cells[i]);
			}
		}

		cells = tmp;
	}
	
	if (cells != null && cells.length > 0)
	{
		this.model.beginUpdate();
		try
		{
			for (var i = 0; i < cells.length; i++)
			{
				var children = this.model.getChildren(cells[i]);
				
				if (children != null && children.length > 0)
				{
					children = children.slice();
					var parent = this.model.getParent(cells[i]);
					var index = this.model.getChildCount(parent);

					this.cellsAdded(children, parent, index, null, null, true);
					result = result.concat(children);
				}
			}

			this.removeCellsAfterUngroup(cells);
			this.fireEvent(new mxEventObject(mxEvent.UNGROUP_CELLS, 'cells', cells));
		}
		finally
		{
			this.model.endUpdate();
		}
	}
	
	return result;
};

/**
 * Function: removeCellsAfterUngroup
 * 
 * Hook to remove the groups after <ungroupCells>.
 * 
 * Parameters:
 * 
 * cells - Array of <mxCells> that were ungrouped.
 */
mxGraph.prototype.removeCellsAfterUngroup = function(cells)
{
	this.cellsRemoved(this.addAllEdges(cells));
};

/**
 * Function: removeCellsFromParent
 * 
 * Removes the specified cells from their parents and adds them to the
 * default parent. Returns the cells that were removed from their parents.
 * 
 * Parameters:
 * 
 * cells - Array of <mxCells> to be removed from their parents.
 */
mxGraph.prototype.removeCellsFromParent = function(cells)
{
	if (cells == null)
	{
		cells = this.getSelectionCells();
	}
	
	this.model.beginUpdate();
	try
	{
		var parent = this.getDefaultParent();
		var index = this.model.getChildCount(parent);

		this.cellsAdded(cells, parent, index, null, null, true);
		this.fireEvent(new mxEventObject(mxEvent.REMOVE_CELLS_FROM_PARENT, 'cells', cells));
	}
	finally
	{
		this.model.endUpdate();
	}

	return cells;
};

/**
 * Function: updateGroupBounds
 * 
 * Updates the bounds of the given groups to include all children and returns
 * the passed-in cells. Call this with the groups in parent to child order,
 * top-most group first, the cells are processed in reverse order and cells
 * with no children are ignored.
 * 
 * Parameters:
 * 
 * cells - The groups whose bounds should be updated. If this is null, then
 * the selection cells are used.
 * border - Optional border to be added in the group. Default is 0.
 * moveGroup - Optional boolean that allows the group to be moved. Default
 * is false.
 * topBorder - Optional top border to be added in the group. Default is 0.
 * rightBorder - Optional top border to be added in the group. Default is 0.
 * bottomBorder - Optional top border to be added in the group. Default is 0.
 * leftBorder - Optional top border to be added in the group. Default is 0.
 */
mxGraph.prototype.updateGroupBounds = function(cells, border, moveGroup, topBorder, rightBorder, bottomBorder, leftBorder)
{
	if (cells == null)
	{
		cells = this.getSelectionCells();
	}
	
	border = (border != null) ? border : 0;
	moveGroup = (moveGroup != null) ? moveGroup : false;
	topBorder = (topBorder != null) ? topBorder : 0;
	rightBorder = (rightBorder != null) ? rightBorder : 0;
	bottomBorder = (bottomBorder != null) ? bottomBorder : 0;
	leftBorder = (leftBorder != null) ? leftBorder : 0;

	this.model.beginUpdate();
	try
	{
		for (var i = cells.length - 1; i >= 0; i--)
		{
			var geo = this.getCellGeometry(cells[i]);
			
			if (geo != null)
			{
				var children = this.getChildCells(cells[i]);
				
				if (children != null && children.length > 0)
				{
					var bounds = this.getBoundingBoxFromGeometry(children, true);
					
					if (bounds != null && bounds.width > 0 && bounds.height > 0)
					{
						var left = 0;
						var top = 0;
						
						// Adds the size of the title area for swimlanes
						if (this.isSwimlane(cells[i]))
						{
							var size = this.getStartSize(cells[i]);
							left = size.width;
							top = size.height;
						}
						
						geo = geo.clone();
						
						if (moveGroup)
						{
							geo.x = Math.round(geo.x + bounds.x - border - left - leftBorder);
							geo.y = Math.round(geo.y + bounds.y - border - top - topBorder);
						}
						
						geo.width = Math.round(bounds.width + 2 * border + left + leftBorder + rightBorder);
						geo.height = Math.round(bounds.height + 2 * border + top + topBorder + bottomBorder);
						
						this.model.setGeometry(cells[i], geo);
						this.moveCells(children, border + left - bounds.x + leftBorder,
								border + top - bounds.y + topBorder);
					}
				}
			}
		}
	}
	finally
	{
		this.model.endUpdate();
	}

	return cells;
};

/**
 * Function: getBoundingBox
 * 
 * Returns the bounding box for the given array of <mxCells>. The bounding box for
 * each cell and its descendants is computed using <mxGraphView.getBoundingBox>.
 *
 * Parameters:
 *
 * cells - Array of <mxCells> whose bounding box should be returned.
 */
mxGraph.prototype.getBoundingBox = function(cells)
{
	var result = null;
	
	if (cells != null && cells.length > 0)
	{
		for (var i = 0; i < cells.length; i++)
		{
			if (this.model.isVertex(cells[i]) || this.model.isEdge(cells[i]))
			{
				var bbox = this.view.getBoundingBox(this.view.getState(cells[i]), true);
			
				if (bbox != null)
				{
					if (result == null)
					{
						result = mxRectangle.fromRectangle(bbox);
					}
					else
					{
						result.add(bbox);
					}
				}
			}
		}
	}
	
	return result;
};

/**
 * Group: Cell cloning, insertion and removal
 */

/**
 * Function: cloneCells
 * 
 * Returns the clones for the given cells. The clones are created recursively
 * using <mxGraphModel.cloneCells>. If the terminal of an edge is not in the
 * given array, then the respective end is assigned a terminal point and the
 * terminal is removed.
 * 
 * Parameters:
 * 
 * cells - Array of <mxCells> to be cloned.
 * allowInvalidEdges - Optional boolean that specifies if invalid edges
 * should be cloned. Default is true.
 * mapping - Optional mapping for existing clones.
 */
mxGraph.prototype.cloneCells = function(cells, allowInvalidEdges, mapping)
{
	allowInvalidEdges = (allowInvalidEdges != null) ? allowInvalidEdges : true;
	var clones = null;
	
	if (cells != null)
	{
		// Creates a dictionary for fast lookups
		var dict = new mxDictionary();
		var tmp = [];
		
		for (var i = 0; i < cells.length; i++)
		{
			dict.put(cells[i], true);
			tmp.push(cells[i]);
		}
		
		if (tmp.length > 0)
		{
			var scale = this.view.scale;
			var trans = this.view.translate;
			clones = this.model.cloneCells(cells, true, mapping);
		
			for (var i = 0; i < cells.length; i++)
			{
				if (!allowInvalidEdges && this.model.isEdge(clones[i]) &&
					this.getEdgeValidationError(clones[i],
						this.model.getTerminal(clones[i], true),
						this.model.getTerminal(clones[i], false)) != null)
				{
					clones[i] = null;
				}
				else
				{
					var g = this.model.getGeometry(clones[i]);
					
					if (g != null)
					{
						var state = this.view.getState(cells[i]);
						var pstate = this.view.getState(this.model.getParent(cells[i]));
						
						if (state != null && pstate != null)
						{
							var dx = pstate.origin.x;
							var dy = pstate.origin.y;
							
							if (this.model.isEdge(clones[i]))
							{
								var pts = state.absolutePoints;
								
								// Checks if the source is cloned or sets the terminal point
								var src = this.model.getTerminal(cells[i], true);
								
								while (src != null && !dict.get(src))
								{
									src = this.model.getParent(src);
								}
								
								if (src == null)
								{
									g.setTerminalPoint(
										new mxPoint(pts[0].x / scale - trans.x,
											pts[0].y / scale - trans.y), true);
								}
								
								// Checks if the target is cloned or sets the terminal point
								var trg = this.model.getTerminal(cells[i], false);
								
								while (trg != null && !dict.get(trg))
								{
									trg = this.model.getParent(trg);
								}
								
								if (trg == null)
								{
									var n = pts.length - 1;
									g.setTerminalPoint(
										new mxPoint(pts[n].x / scale - trans.x,
											pts[n].y / scale - trans.y), false);
								}
								
								// Translates the control points
								var points = g.points;
								
								if (points != null)
								{
									for (var j = 0; j < points.length; j++)
									{
										points[j].x += dx;
										points[j].y += dy;
									}
								}
							}
							else
							{
								g.translate(dx, dy);
							}
						}
					}
				}
			}
		}
		else
		{
			clones = [];
		}
	}
	
	return clones;
};

/**
 * Function: insertVertex
 * 
 * Adds a new vertex into the given parent <mxCell> using value as the user
 * object and the given coordinates as the <mxGeometry> of the new vertex.
 * The id and style are used for the respective properties of the new
 * <mxCell>, which is returned.
 *
 * When adding new vertices from a mouse event, one should take into
 * account the offset of the graph container and the scale and translation
 * of the view in order to find the correct unscaled, untranslated
 * coordinates using <mxGraph.getPointForEvent> as follows:
 * 
 * (code)
 * var pt = graph.getPointForEvent(evt);
 * var parent = graph.getDefaultParent();
 * graph.insertVertex(parent, null,
 * 			'Hello, World!', x, y, 220, 30);
 * (end)
 * 
 * For adding image cells, the style parameter can be assigned as
 * 
 * (code)
 * stylename;image=imageUrl
 * (end)
 * 
 * See <mxGraph> for more information on using images.
 *
 * Parameters:
 * 
 * parent - <mxCell> that specifies the parent of the new vertex.
 * id - Optional string that defines the Id of the new vertex.
 * value - Object to be used as the user object.
 * x - Integer that defines the x coordinate of the vertex.
 * y - Integer that defines the y coordinate of the vertex.
 * width - Integer that defines the width of the vertex.
 * height - Integer that defines the height of the vertex.
 * style - Optional string that defines the cell style.
 * relative - Optional boolean that specifies if the geometry is relative.
 * Default is false.
 */
mxGraph.prototype.insertVertex = function(parent, id, value,
	x, y, width, height, style, relative)
{
	var vertex = this.createVertex(parent, id, value, x, y, width, height, style, relative);

	return this.addCell(vertex, parent);
};

/**
 * Function: createVertex
 * 
 * Hook method that creates the new vertex for <insertVertex>.
 */
mxGraph.prototype.createVertex = function(parent, id, value,
		x, y, width, height, style, relative)
{
	// Creates the geometry for the vertex
	var geometry = new mxGeometry(x, y, width, height);
	geometry.relative = (relative != null) ? relative : false;
	
	// Creates the vertex
	var vertex = new mxCell(value, geometry, style);
	vertex.setId(id);
	vertex.setVertex(true);
	vertex.setConnectable(true);
	
	return vertex;
};
	
/**
 * Function: insertEdge
 * 
 * Adds a new edge into the given parent <mxCell> using value as the user
 * object and the given source and target as the terminals of the new edge.
 * The id and style are used for the respective properties of the new
 * <mxCell>, which is returned.
 *
 * Parameters:
 * 
 * parent - <mxCell> that specifies the parent of the new edge.
 * id - Optional string that defines the Id of the new edge.
 * value - JavaScript object to be used as the user object.
 * source - <mxCell> that defines the source of the edge.
 * target - <mxCell> that defines the target of the edge.
 * style - Optional string that defines the cell style.
 */
mxGraph.prototype.insertEdge = function(parent, id, value, source, target, style)
{
	var edge = this.createEdge(parent, id, value, source, target, style);
	
	return this.addEdge(edge, parent, source, target);
};

/**
 * Function: createEdge
 * 
 * Hook method that creates the new edge for <insertEdge>. This
 * implementation does not set the source and target of the edge, these
 * are set when the edge is added to the model.
 * 
 */
mxGraph.prototype.createEdge = function(parent, id, value, source, target, style)
{
	// Creates the edge
	var edge = new mxCell(value, new mxGeometry(), style);
	edge.setId(id);
	edge.setEdge(true);
	edge.geometry.relative = true;
	
	return edge;
};

/**
 * Function: addEdge
 * 
 * Adds the edge to the parent and connects it to the given source and
 * target terminals. This is a shortcut method. Returns the edge that was
 * added.
 * 
 * Parameters:
 * 
 * edge - <mxCell> to be inserted into the given parent.
 * parent - <mxCell> that represents the new parent. If no parent is
 * given then the default parent is used.
 * source - Optional <mxCell> that represents the source terminal.
 * target - Optional <mxCell> that represents the target terminal.
 * index - Optional index to insert the cells at. Default is to append.
 */
mxGraph.prototype.addEdge = function(edge, parent, source, target, index)
{
	return this.addCell(edge, parent, index, source, target);
};

/**
 * Function: addCell
 * 
 * Adds the cell to the parent and connects it to the given source and
 * target terminals. This is a shortcut method. Returns the cell that was
 * added.
 * 
 * Parameters:
 * 
 * cell - <mxCell> to be inserted into the given parent.
 * parent - <mxCell> that represents the new parent. If no parent is
 * given then the default parent is used.
 * index - Optional index to insert the cells at. Default is to append.
 * source - Optional <mxCell> that represents the source terminal.
 * target - Optional <mxCell> that represents the target terminal.
 */
mxGraph.prototype.addCell = function(cell, parent, index, source, target)
{
	return this.addCells([cell], parent, index, source, target)[0];
};

/**
 * Function: addCells
 * 
 * Adds the cells to the parent at the given index, connecting each cell to
 * the optional source and target terminal. The change is carried out using
 * <cellsAdded>. This method fires <mxEvent.ADD_CELLS> while the
 * transaction is in progress. Returns the cells that were added.
 * 
 * Parameters:
 * 
 * cells - Array of <mxCells> to be inserted.
 * parent - <mxCell> that represents the new parent. If no parent is
 * given then the default parent is used.
 * index - Optional index to insert the cells at. Default is to append.
 * source - Optional source <mxCell> for all inserted cells.
 * target - Optional target <mxCell> for all inserted cells.
 */
mxGraph.prototype.addCells = function(cells, parent, index, source, target)
{
	if (parent == null)
	{
		parent = this.getDefaultParent();
	}
	
	if (index == null)
	{
		index = this.model.getChildCount(parent);
	}
	
	this.model.beginUpdate();
	try
	{
		this.cellsAdded(cells, parent, index, source, target, false, true);
		this.fireEvent(new mxEventObject(mxEvent.ADD_CELLS, 'cells', cells,
				'parent', parent, 'index', index, 'source', source, 'target', target));
	}
	finally
	{
		this.model.endUpdate();
	}

	return cells;
};

/**
 * Function: cellsAdded
 * 
 * Adds the specified cells to the given parent. This method fires
 * <mxEvent.CELLS_ADDED> while the transaction is in progress.
 */
mxGraph.prototype.cellsAdded = function(cells, parent, index, source, target, absolute, constrain, extend)
{
	if (cells != null && parent != null && index != null)
	{
		this.model.beginUpdate();
		try
		{
			var parentState = (absolute) ? this.view.getState(parent) : null;
			var o1 = (parentState != null) ? parentState.origin : null;
			var zero = new mxPoint(0, 0);

			for (var i = 0; i < cells.length; i++)
			{
				if (cells[i] == null)
				{
					index--;
				}
				else
				{
					var previous = this.model.getParent(cells[i]);
	
					// Keeps the cell at its absolute location
					if (o1 != null && cells[i] != parent && parent != previous)
					{
						var oldState = this.view.getState(previous);
						var o2 = (oldState != null) ? oldState.origin : zero;
						var geo = this.model.getGeometry(cells[i]);
	
						if (geo != null)
						{
							var dx = o2.x - o1.x;
							var dy = o2.y - o1.y;
	
							// FIXME: Cells should always be inserted first before any other edit
							// to avoid forward references in sessions.
							geo = geo.clone();
							geo.translate(dx, dy);
							
							if (!geo.relative && this.model.isVertex(cells[i]) &&
								!this.isAllowNegativeCoordinates())
							{
								geo.x = Math.max(0, geo.x);
								geo.y = Math.max(0, geo.y);
							}
							
							this.model.setGeometry(cells[i], geo);
						}
					}
	
					// Decrements all following indices
					// if cell is already in parent
					if (parent == previous && index + i > this.model.getChildCount(parent))
					{
						index--;
					}

					this.model.add(parent, cells[i], index + i);
					
					if (this.autoSizeCellsOnAdd)
					{
						this.autoSizeCell(cells[i], true);
					}

					// Extends the parent or constrains the child
					if ((extend == null || extend) &&
						this.isExtendParentsOnAdd(cells[i]) && this.isExtendParent(cells[i]))
					{
						this.extendParent(cells[i]);
					}
					
					// Additionally constrains the child after extending the parent
					if (constrain == null || constrain)
					{
						this.constrainChild(cells[i]);
					}
					
					// Sets the source terminal
					if (source != null)
					{
						this.cellConnected(cells[i], source, true);
					}
					
					// Sets the target terminal
					if (target != null)
					{
						this.cellConnected(cells[i], target, false);
					}
				}
			}
			
			this.fireEvent(new mxEventObject(mxEvent.CELLS_ADDED, 'cells', cells,
				'parent', parent, 'index', index, 'source', source, 'target', target,
				'absolute', absolute));
		}
		finally
		{
			this.model.endUpdate();
		}
	}
};

/**
 * Function: autoSizeCell
 * 
 * Resizes the specified cell to just fit around the its label and/or children
 * 
 * Parameters:
 * 
 * cell - <mxCells> to be resized.
 * recurse - Optional boolean which specifies if all descendants should be
 * autosized. Default is true.
 */
mxGraph.prototype.autoSizeCell = function(cell, recurse)
{
	recurse = (recurse != null) ? recurse : true;
	
	if (recurse)
	{
		var childCount = this.model.getChildCount(cell);
		
		for (var i = 0; i < childCount; i++)
		{
			this.autoSizeCell(this.model.getChildAt(cell, i));
		}
	}

	if (this.getModel().isVertex(cell) && this.isAutoSizeCell(cell))
	{
		this.updateCellSize(cell);
	}
};

/**
 * Function: removeCells
 * 
 * Removes the given cells from the graph including all connected edges if
 * includeEdges is true. The change is carried out using <cellsRemoved>.
 * This method fires <mxEvent.REMOVE_CELLS> while the transaction is in
 * progress. The removed cells are returned as an array.
 * 
 * Parameters:
 * 
 * cells - Array of <mxCells> to remove. If null is specified then the
 * selection cells which are deletable are used.
 * includeEdges - Optional boolean which specifies if all connected edges
 * should be removed as well. Default is true.
 */
mxGraph.prototype.removeCells = function(cells, includeEdges)
{
	includeEdges = (includeEdges != null) ? includeEdges : true;
	
	if (cells == null)
	{
		cells = this.getDeletableCells(this.getSelectionCells());
	}

	// Adds all edges to the cells
	if (includeEdges)
	{
		// FIXME: Remove duplicate cells in result or do not add if
		// in cells or descendant of cells
		cells = this.getDeletableCells(this.addAllEdges(cells));
	}

	this.model.beginUpdate();
	try
	{
		this.cellsRemoved(cells);
		this.fireEvent(new mxEventObject(mxEvent.REMOVE_CELLS, 
				'cells', cells, 'includeEdges', includeEdges));
	}
	finally
	{
		this.model.endUpdate();
	}
	
	return cells;
};

/**
 * Function: cellsRemoved
 * 
 * Removes the given cells from the model. This method fires
 * <mxEvent.CELLS_REMOVED> while the transaction is in progress.
 * 
 * Parameters:
 * 
 * cells - Array of <mxCells> to remove.
 */
mxGraph.prototype.cellsRemoved = function(cells)
{
	if (cells != null && cells.length > 0)
	{
		var scale = this.view.scale;
		var tr = this.view.translate;
		
		this.model.beginUpdate();
		try
		{
			// Creates hashtable for faster lookup
			var dict = new mxDictionary();
			
			for (var i = 0; i < cells.length; i++)
			{
				dict.put(cells[i], true);
			}
			
			for (var i = 0; i < cells.length; i++)
			{
				// Disconnects edges which are not in cells
				var edges = this.getAllEdges([cells[i]]);
				
				var disconnectTerminal = mxUtils.bind(this, function(edge, source)
				{
					var geo = this.model.getGeometry(edge);

					if (geo != null)
					{
						var state = this.view.getState(edge);
								
						if (state != null)
						{
							// Checks which side of the edge is being disconnected
							var tmp = state.getVisibleTerminal(source);
							var connected = false;
							
							while (tmp != null)
							{
								if (cells[i] == tmp)
								{
									connected = true;
									break;
								}
								
								tmp = this.model.getParent(tmp);
							}
							
							if (connected)
							{
								var dx = tr.x;
								var dy = tr.y;
								var parentState = this.view.getState(this.model.getParent(edge));
								
								if (parentState != null && this.model.isVertex(parentState.cell))
								{
									dx = parentState.x / scale;
									dy = parentState.y / scale;
								}
								
								geo = geo.clone();
								var pts = state.absolutePoints;
								var n = (source) ? 0 : pts.length - 1;
								geo.setTerminalPoint(new mxPoint(pts[n].x / scale - dx, pts[n].y / scale - dy), source);
								this.model.setTerminal(edges[j], null, source);
								this.model.setGeometry(edges[j], geo);
							}
						}
					}
				});
				
				for (var j = 0; j < edges.length; j++)
				{
					if (!dict.get(edges[j]))
					{
						disconnectTerminal(edges[j], true);
						disconnectTerminal(edges[j], false);
					}
				}

				this.model.remove(cells[i]);
			}
			
			this.fireEvent(new mxEventObject(mxEvent.CELLS_REMOVED, 'cells', cells));
		}
		finally
		{
			this.model.endUpdate();
		}
	}
};

/**
 * Function: splitEdge
 * 
 * Splits the given edge by adding the newEdge between the previous source
 * and the given cell and reconnecting the source of the given edge to the
 * given cell. This method fires <mxEvent.SPLIT_EDGE> while the transaction
 * is in progress. Returns the new edge that was inserted.
 * 
 * Parameters:
 * 
 * edge - <mxCell> that represents the edge to be splitted.
 * cells - <mxCells> that represents the cells to insert into the edge.
 * newEdge - <mxCell> that represents the edge to be inserted.
 * dx - Optional integer that specifies the vector to move the cells.
 * dy - Optional integer that specifies the vector to move the cells.
 */
mxGraph.prototype.splitEdge = function(edge, cells, newEdge, dx, dy)
{
	dx = dx || 0;
	dy = dy || 0;

	var parent = this.model.getParent(edge);
	var source = this.model.getTerminal(edge, true);

	this.model.beginUpdate();
	try
	{
		if (newEdge == null)
		{
			newEdge = this.cloneCells([edge])[0];
			
			// Removes waypoints before/after new cell
			var state = this.view.getState(edge);
			var geo = this.getCellGeometry(newEdge);
			
			if (geo != null && geo.points != null && state != null)
			{
				var t = this.view.translate;
				var s = this.view.scale;
				var idx = mxUtils.findNearestSegment(state, (dx + t.x) * s, (dy + t.y) * s);
				geo.points = geo.points.slice(0, idx);
								
				geo = this.getCellGeometry(edge);
				
				if (geo != null && geo.points != null)
				{
					geo = geo.clone();
					geo.points = geo.points.slice(idx);
					this.model.setGeometry(edge, geo);
				}
			}
		}
		
		this.cellsMoved(cells, dx, dy, false, false);
		this.cellsAdded(cells, parent, this.model.getChildCount(parent), null, null,
				true);
		this.cellsAdded([newEdge], parent, this.model.getChildCount(parent),
				source, cells[0], false);
		this.cellConnected(edge, cells[0], true);
		this.fireEvent(new mxEventObject(mxEvent.SPLIT_EDGE, 'edge', edge,
				'cells', cells, 'newEdge', newEdge, 'dx', dx, 'dy', dy));
	}
	finally
	{
		this.model.endUpdate();
	}

	return newEdge;
};

/**
 * Group: Cell visibility
 */

/**
 * Function: toggleCells
 * 
 * Sets the visible state of the specified cells and all connected edges
 * if includeEdges is true. The change is carried out using <cellsToggled>.
 * This method fires <mxEvent.TOGGLE_CELLS> while the transaction is in
 * progress. Returns the cells whose visible state was changed.
 * 
 * Parameters:
 * 
 * show - Boolean that specifies the visible state to be assigned.
 * cells - Array of <mxCells> whose visible state should be changed. If
 * null is specified then the selection cells are used.
 * includeEdges - Optional boolean indicating if the visible state of all
 * connected edges should be changed as well. Default is true.
 */
mxGraph.prototype.toggleCells = function(show, cells, includeEdges)
{
	if (cells == null)
	{
		cells = this.getSelectionCells();
	}

	// Adds all connected edges recursively
	if (includeEdges)
	{
		cells = this.addAllEdges(cells);
	}

	this.model.beginUpdate();
	try
	{
		this.cellsToggled(cells, show);
		this.fireEvent(new mxEventObject(mxEvent.TOGGLE_CELLS,
			'show', show, 'cells', cells, 'includeEdges', includeEdges));
	}
	finally
	{
		this.model.endUpdate();
	}

	return cells;
};

/**
 * Function: cellsToggled
 * 
 * Sets the visible state of the specified cells.
 * 
 * Parameters:
 * 
 * cells - Array of <mxCells> whose visible state should be changed.
 * show - Boolean that specifies the visible state to be assigned.
 */
mxGraph.prototype.cellsToggled = function(cells, show)
{
	if (cells != null && cells.length > 0)
	{
		this.model.beginUpdate();
		try
		{
			for (var i = 0; i < cells.length; i++)
			{
				this.model.setVisible(cells[i], show);
			}
		}
		finally
		{
			this.model.endUpdate();
		}
	}
};

/**
 * Group: Folding
 */

/**
 * Function: foldCells
 * 
 * Sets the collapsed state of the specified cells and all descendants
 * if recurse is true. The change is carried out using <cellsFolded>.
 * This method fires <mxEvent.FOLD_CELLS> while the transaction is in
 * progress. Returns the cells whose collapsed state was changed.
 * 
 * Parameters:
 * 
 * collapsed - Boolean indicating the collapsed state to be assigned.
 * recurse - Optional boolean indicating if the collapsed state of all
 * descendants should be set. Default is false.
 * cells - Array of <mxCells> whose collapsed state should be set. If
 * null is specified then the foldable selection cells are used.
 * checkFoldable - Optional boolean indicating of isCellFoldable should be
 * checked. Default is false.
 * evt - Optional native event that triggered the invocation.
 */
mxGraph.prototype.foldCells = function(collapse, recurse, cells, checkFoldable, evt)
{
	recurse = (recurse != null) ? recurse : false;
	
	if (cells == null)
	{
		cells = this.getFoldableCells(this.getSelectionCells(), collapse);
	}

	this.stopEditing(false);

	this.model.beginUpdate();
	try
	{
		this.cellsFolded(cells, collapse, recurse, checkFoldable);
		this.fireEvent(new mxEventObject(mxEvent.FOLD_CELLS,
			'collapse', collapse, 'recurse', recurse, 'cells', cells));
	}
	finally
	{
		this.model.endUpdate();
	}

	return cells;
};

/**
 * Function: cellsFolded
 * 
 * Sets the collapsed state of the specified cells. This method fires
 * <mxEvent.CELLS_FOLDED> while the transaction is in progress. Returns the
 * cells whose collapsed state was changed.
 * 
 * Parameters:
 * 
 * cells - Array of <mxCells> whose collapsed state should be set.
 * collapsed - Boolean indicating the collapsed state to be assigned.
 * recurse - Boolean indicating if the collapsed state of all descendants
 * should be set.
 * checkFoldable - Optional boolean indicating of isCellFoldable should be
 * checked. Default is false.
 */
mxGraph.prototype.cellsFolded = function(cells, collapse, recurse, checkFoldable)
{
	if (cells != null && cells.length > 0)
	{
		this.model.beginUpdate();
		try
		{
			for (var i = 0; i < cells.length; i++)
			{
				if ((!checkFoldable || this.isCellFoldable(cells[i], collapse)) &&
					collapse != this.isCellCollapsed(cells[i]))
				{
					this.model.setCollapsed(cells[i], collapse);
					this.swapBounds(cells[i], collapse);

					if (this.isExtendParent(cells[i]))
					{
						this.extendParent(cells[i]);
					}

					if (recurse)
					{
						var children = this.model.getChildren(cells[i]);
						this.foldCells(children, collapse, recurse);
					}
					
					this.constrainChild(cells[i]);
				}
			}
			
			this.fireEvent(new mxEventObject(mxEvent.CELLS_FOLDED,
				'cells', cells, 'collapse', collapse, 'recurse', recurse));
		}
		finally
		{
			this.model.endUpdate();
		}
	}
};

/**
 * Function: swapBounds
 * 
 * Swaps the alternate and the actual bounds in the geometry of the given
 * cell invoking <updateAlternateBounds> before carrying out the swap.
 * 
 * Parameters:
 * 
 * cell - <mxCell> for which the bounds should be swapped.
 * willCollapse - Boolean indicating if the cell is going to be collapsed.
 */
mxGraph.prototype.swapBounds = function(cell, willCollapse)
{
	if (cell != null)
	{
		var geo = this.model.getGeometry(cell);
		
		if (geo != null)
		{
			geo = geo.clone();
			
			this.updateAlternateBounds(cell, geo, willCollapse);
			geo.swap();
			
			this.model.setGeometry(cell, geo);
		}
	}
};

/**
 * Function: updateAlternateBounds
 * 
 * Updates or sets the alternate bounds in the given geometry for the given
 * cell depending on whether the cell is going to be collapsed. If no
 * alternate bounds are defined in the geometry and
 * <collapseToPreferredSize> is true, then the preferred size is used for
 * the alternate bounds. The top, left corner is always kept at the same
 * location.
 * 
 * Parameters:
 * 
 * cell - <mxCell> for which the geometry is being udpated.
 * g - <mxGeometry> for which the alternate bounds should be updated.
 * willCollapse - Boolean indicating if the cell is going to be collapsed.
 */
mxGraph.prototype.updateAlternateBounds = function(cell, geo, willCollapse)
{
	if (cell != null && geo != null)
	{
		var state = this.view.getState(cell);
		var style = (state != null) ? state.style : this.getCellStyle(cell);

		if (geo.alternateBounds == null)
		{
			var bounds = geo;
			
			if (this.collapseToPreferredSize)
			{
				var tmp = this.getPreferredSizeForCell(cell);
				
				if (tmp != null)
				{
					bounds = tmp;

					var startSize = mxUtils.getValue(style, mxConstants.STYLE_STARTSIZE);

					if (startSize > 0)
					{
						bounds.height = Math.max(bounds.height, startSize);
					}
				}
			}
			
			geo.alternateBounds = new mxRectangle(0, 0, bounds.width, bounds.height);
		}
		
		if (geo.alternateBounds != null)
		{
			geo.alternateBounds.x = geo.x;
			geo.alternateBounds.y = geo.y;
			
			var alpha = mxUtils.toRadians(style[mxConstants.STYLE_ROTATION] || 0);
			
			if (alpha != 0)
			{
				var dx = geo.alternateBounds.getCenterX() - geo.getCenterX();
				var dy = geo.alternateBounds.getCenterY() - geo.getCenterY();
	
				var cos = Math.cos(alpha);
				var sin = Math.sin(alpha);
	
				var dx2 = cos * dx - sin * dy;
				var dy2 = sin * dx + cos * dy;
				
				geo.alternateBounds.x += dx2 - dx;
				geo.alternateBounds.y += dy2 - dy;
			}
		}
	}
};

/**
 * Function: addAllEdges
 * 
 * Returns an array with the given cells and all edges that are connected
 * to a cell or one of its descendants.
 */
mxGraph.prototype.addAllEdges = function(cells)
{
	var allCells = cells.slice();
	
	return mxUtils.removeDuplicates(allCells.concat(this.getAllEdges(cells)));
};

/**
 * Function: getAllEdges
 * 
 * Returns all edges connected to the given cells or its descendants.
 */
mxGraph.prototype.getAllEdges = function(cells)
{
	var edges = [];
	
	if (cells != null)
	{
		for (var i = 0; i < cells.length; i++)
		{
			var edgeCount = this.model.getEdgeCount(cells[i]);
			
			for (var j = 0; j < edgeCount; j++)
			{
				edges.push(this.model.getEdgeAt(cells[i], j));
			}

			// Recurses
			var children = this.model.getChildren(cells[i]);
			edges = edges.concat(this.getAllEdges(children));
		}
	}
	
	return edges;
};

/**
 * Group: Cell sizing
 */

/**
 * Function: updateCellSize
 * 
 * Updates the size of the given cell in the model using <cellSizeUpdated>.
 * This method fires <mxEvent.UPDATE_CELL_SIZE> while the transaction is in
 * progress. Returns the cell whose size was updated.
 * 
 * Parameters:
 * 
 * cell - <mxCell> whose size should be updated.
 */
mxGraph.prototype.updateCellSize = function(cell, ignoreChildren)
{
	ignoreChildren = (ignoreChildren != null) ? ignoreChildren : false;
	
	this.model.beginUpdate();				
	try
	{
		this.cellSizeUpdated(cell, ignoreChildren);
		this.fireEvent(new mxEventObject(mxEvent.UPDATE_CELL_SIZE,
				'cell', cell, 'ignoreChildren', ignoreChildren));
	}
	finally
	{
		this.model.endUpdate();
	}
	
	return cell;
};

/**
 * Function: cellSizeUpdated
 * 
 * Updates the size of the given cell in the model using
 * <getPreferredSizeForCell> to get the new size.
 * 
 * Parameters:
 * 
 * cell - <mxCell> for which the size should be changed.
 */
mxGraph.prototype.cellSizeUpdated = function(cell, ignoreChildren)
{
	if (cell != null)
	{
		this.model.beginUpdate();				
		try
		{
			var size = this.getPreferredSizeForCell(cell);
			var geo = this.model.getGeometry(cell);
			
			if (size != null && geo != null)
			{
				var collapsed = this.isCellCollapsed(cell);
				geo = geo.clone();

				if (this.isSwimlane(cell))
				{
					var state = this.view.getState(cell);
					var style = (state != null) ? state.style : this.getCellStyle(cell);
					var cellStyle = this.model.getStyle(cell);

					if (cellStyle == null)
					{
						cellStyle = '';
					}

					if (mxUtils.getValue(style, mxConstants.STYLE_HORIZONTAL, true))
					{
						cellStyle = mxUtils.setStyle(cellStyle,
								mxConstants.STYLE_STARTSIZE, size.height + 8);

						if (collapsed)
						{
							geo.height = size.height + 8;
						}

						geo.width = size.width;
					}
					else
					{
						cellStyle = mxUtils.setStyle(cellStyle,
								mxConstants.STYLE_STARTSIZE, size.width + 8);

						if (collapsed)
						{
							geo.width = size.width + 8;
						}

						geo.height = size.height;
					}

					this.model.setStyle(cell, cellStyle);
				}
				else
				{
					geo.width = size.width;
					geo.height = size.height;
				}

				if (!ignoreChildren && !collapsed)
				{
					var bounds = this.view.getBounds(this.model.getChildren(cell));

					if (bounds != null)
					{
						var tr = this.view.translate;
						var scale = this.view.scale;

						var width = (bounds.x + bounds.width) / scale - geo.x - tr.x;
						var height = (bounds.y + bounds.height) / scale - geo.y - tr.y;

						geo.width = Math.max(geo.width, width);
						geo.height = Math.max(geo.height, height);
					}
				}

				this.cellsResized([cell], [geo], false);
			}
		}
		finally
		{
			this.model.endUpdate();
		}
	}
};

/**
 * Function: getPreferredSizeForCell
 * 
 * Returns the preferred width and height of the given <mxCell> as an
 * <mxRectangle>. To implement a minimum width, add a new style eg.
 * minWidth in the vertex and override this method as follows.
 * 
 * (code)
 * var graphGetPreferredSizeForCell = graph.getPreferredSizeForCell;
 * graph.getPreferredSizeForCell = function(cell)
 * {
 *   var result = graphGetPreferredSizeForCell.apply(this, arguments);
 *   var style = this.getCellStyle(cell);
 *   
 *   if (style['minWidth'] > 0)
 *   {
 *     result.width = Math.max(style['minWidth'], result.width);
 *   }
 * 
 *   return result;
 * };
 * (end)
 * 
 * Parameters:
 * 
 * cell - <mxCell> for which the preferred size should be returned.
 */
mxGraph.prototype.getPreferredSizeForCell = function(cell)
{
	var result = null;
	
	if (cell != null)
	{
		var state = this.view.getState(cell) || this.view.createState(cell);
		var style = state.style;

		if (!this.model.isEdge(cell))
		{
			var fontSize = style[mxConstants.STYLE_FONTSIZE] || mxConstants.DEFAULT_FONTSIZE;
			var dx = 0;
			var dy = 0;
			
			// Adds dimension of image if shape is a label
			if (this.getImage(state) != null || style[mxConstants.STYLE_IMAGE] != null)
			{
				if (style[mxConstants.STYLE_SHAPE] == mxConstants.SHAPE_LABEL)
				{
					if (style[mxConstants.STYLE_VERTICAL_ALIGN] == mxConstants.ALIGN_MIDDLE)
					{
						dx += parseFloat(style[mxConstants.STYLE_IMAGE_WIDTH]) || mxLabel.prototype.imageSize;
					}
					
					if (style[mxConstants.STYLE_ALIGN] != mxConstants.ALIGN_CENTER)
					{
						dy += parseFloat(style[mxConstants.STYLE_IMAGE_HEIGHT]) || mxLabel.prototype.imageSize;
					}
				}
			}

			// Adds spacings
			dx += 2 * (style[mxConstants.STYLE_SPACING] || 0);
			dx += style[mxConstants.STYLE_SPACING_LEFT] || 0;
			dx += style[mxConstants.STYLE_SPACING_RIGHT] || 0;

			dy += 2 * (style[mxConstants.STYLE_SPACING] || 0);
			dy += style[mxConstants.STYLE_SPACING_TOP] || 0;
			dy += style[mxConstants.STYLE_SPACING_BOTTOM] || 0;
			
			// Add spacing for collapse/expand icon
			// LATER: Check alignment and use constants
			// for image spacing
			var image = this.getFoldingImage(state);
			
			if (image != null)
			{
				dx += image.width + 8;
			}

			// Adds space for label
			var value = this.cellRenderer.getLabelValue(state);

			if (value != null && value.length > 0)
			{
				if (!this.isHtmlLabel(state.cell))
				{
					value = mxUtils.htmlEntities(value);
				}
				
				value = value.replace(/\n/g, '<br>');
				
				var size = mxUtils.getSizeForString(value, fontSize, style[mxConstants.STYLE_FONTFAMILY]);
				var width = size.width + dx;
				var height = size.height + dy;
				
				if (!mxUtils.getValue(style, mxConstants.STYLE_HORIZONTAL, true))
				{
					var tmp = height;
					
					height = width;
					width = tmp;
				}
			
				if (this.gridEnabled)
				{
					width = this.snap(width + this.gridSize / 2);
					height = this.snap(height + this.gridSize / 2);
				}

				result = new mxRectangle(0, 0, width, height);
			}
			else
			{
				var gs2 = 4 * this.gridSize;
				result = new mxRectangle(0, 0, gs2, gs2);
			}
		}
	}
	
	return result;
};

/**
 * Function: resizeCell
 * 
 * Sets the bounds of the given cell using <resizeCells>. Returns the
 * cell which was passed to the function.
 * 
 * Parameters:
 * 
 * cell - <mxCell> whose bounds should be changed.
 * bounds - <mxRectangle> that represents the new bounds.
 */
mxGraph.prototype.resizeCell = function(cell, bounds, recurse)
{
	return this.resizeCells([cell], [bounds], recurse)[0];
};

/**
 * Function: resizeCells
 * 
 * Sets the bounds of the given cells and fires a <mxEvent.RESIZE_CELLS>
 * event while the transaction is in progress. Returns the cells which
 * have been passed to the function.
 * 
 * Parameters:
 * 
 * cells - Array of <mxCells> whose bounds should be changed.
 * bounds - Array of <mxRectangles> that represent the new bounds.
 */
mxGraph.prototype.resizeCells = function(cells, bounds, recurse)
{
	recurse = (recurse != null) ? recurse : this.isRecursiveResize();
	
	this.model.beginUpdate();
	try
	{
		this.cellsResized(cells, bounds, recurse);
		this.fireEvent(new mxEventObject(mxEvent.RESIZE_CELLS,
				'cells', cells, 'bounds', bounds));
	}
	finally
	{
		this.model.endUpdate();
	}

	return cells;
};

/**
 * Function: cellsResized
 * 
 * Sets the bounds of the given cells and fires a <mxEvent.CELLS_RESIZED>
 * event. If <extendParents> is true, then the parent is extended if a
 * child size is changed so that it overlaps with the parent.
 * 
 * The following example shows how to control group resizes to make sure
 * that all child cells stay within the group.
 * 
 * (code)
 * graph.addListener(mxEvent.CELLS_RESIZED, function(sender, evt)
 * {
 *   var cells = evt.getProperty('cells');
 *   
 *   if (cells != null)
 *   {
 *     for (var i = 0; i < cells.length; i++)
 *     {
 *       if (graph.getModel().getChildCount(cells[i]) > 0)
 *       {
 *         var geo = graph.getCellGeometry(cells[i]);
 *         
 *         if (geo != null)
 *         {
 *           var children = graph.getChildCells(cells[i], true, true);
 *           var bounds = graph.getBoundingBoxFromGeometry(children, true);
 *           
 *           geo = geo.clone();
 *           geo.width = Math.max(geo.width, bounds.width);
 *           geo.height = Math.max(geo.height, bounds.height);
 *           
 *           graph.getModel().setGeometry(cells[i], geo);
 *         }
 *       }
 *     }
 *   }
 * });
 * (end)
 * 
 * Parameters:
 * 
 * cells - Array of <mxCells> whose bounds should be changed.
 * bounds - Array of <mxRectangles> that represent the new bounds.
 * recurse - Optional boolean that specifies if the children should be resized.
 */
mxGraph.prototype.cellsResized = function(cells, bounds, recurse)
{
	recurse = (recurse != null) ? recurse : false;
	
	if (cells != null && bounds != null && cells.length == bounds.length)
	{
		this.model.beginUpdate();
		try
		{
			for (var i = 0; i < cells.length; i++)
			{
				this.cellResized(cells[i], bounds[i], false, recurse);

				if (this.isExtendParent(cells[i]))
				{
					this.extendParent(cells[i]);
				}
				
				this.constrainChild(cells[i]);
			}

			if (this.resetEdgesOnResize)
			{
				this.resetEdges(cells);
			}
			
			this.fireEvent(new mxEventObject(mxEvent.CELLS_RESIZED,
					'cells', cells, 'bounds', bounds));
		}
		finally
		{
			this.model.endUpdate();
		}
	}
};

/**
 * Function: cellResized
 * 
 * Resizes the parents recursively so that they contain the complete area
 * of the resized child cell.
 * 
 * Parameters:
 * 
 * cell - <mxCell> whose bounds should be changed.
 * bounds - <mxRectangles> that represent the new bounds.
 * ignoreRelative - Boolean that indicates if relative cells should be ignored.
 * recurse - Optional boolean that specifies if the children should be resized.
 */
mxGraph.prototype.cellResized = function(cell, bounds, ignoreRelative, recurse)
{
	var geo = this.model.getGeometry(cell);

	if (geo != null && (geo.x != bounds.x || geo.y != bounds.y ||
		geo.width != bounds.width || geo.height != bounds.height))
	{
		geo = geo.clone();

		if (!ignoreRelative && geo.relative)
		{
			var offset = geo.offset;

			if (offset != null)
			{
				offset.x += bounds.x - geo.x;
				offset.y += bounds.y - geo.y;
			}
		}
		else
		{
			geo.x = bounds.x;
			geo.y = bounds.y;
		}

		geo.width = bounds.width;
		geo.height = bounds.height;

		if (!geo.relative && this.model.isVertex(cell) && !this.isAllowNegativeCoordinates())
		{
			geo.x = Math.max(0, geo.x);
			geo.y = Math.max(0, geo.y);
		}

		this.model.beginUpdate();
		try
		{
			if (recurse)
			{
				this.resizeChildCells(cell, geo);
			}
						
			this.model.setGeometry(cell, geo);
			this.constrainChildCells(cell);
		}
		finally
		{
			this.model.endUpdate();
		}
	}
};

/**
 * Function: resizeChildCells
 * 
 * Resizes the child cells of the given cell for the given new geometry with
 * respect to the current geometry of the cell.
 * 
 * Parameters:
 * 
 * cell - <mxCell> that has been resized.
 * newGeo - <mxGeometry> that represents the new bounds.
 */
mxGraph.prototype.resizeChildCells = function(cell, newGeo)
{
	var geo = this.model.getGeometry(cell);
	var dx = newGeo.width / geo.width;
	var dy = newGeo.height / geo.height;
	var childCount = this.model.getChildCount(cell);
	
	for (var i = 0; i < childCount; i++)
	{
		this.scaleCell(this.model.getChildAt(cell, i), dx, dy, true);
	}
};

/**
 * Function: constrainChildCells
 * 
 * Constrains the children of the given cell using <constrainChild>.
 * 
 * Parameters:
 * 
 * cell - <mxCell> that has been resized.
 */
mxGraph.prototype.constrainChildCells = function(cell)
{
	var childCount = this.model.getChildCount(cell);
	
	for (var i = 0; i < childCount; i++)
	{
		this.constrainChild(this.model.getChildAt(cell, i));
	}
};

/**
 * Function: scaleCell
 * 
 * Scales the points, position and size of the given cell according to the
 * given vertical and horizontal scaling factors.
 * 
 * Parameters:
 * 
 * cell - <mxCell> whose geometry should be scaled.
 * dx - Horizontal scaling factor.
 * dy - Vertical scaling factor.
 * recurse - Boolean indicating if the child cells should be scaled.
 */
mxGraph.prototype.scaleCell = function(cell, dx, dy, recurse)
{
	var geo = this.model.getGeometry(cell);
	
	if (geo != null)
	{
		var state = this.view.getState(cell);
		var style = (state != null) ? state.style : this.getCellStyle(cell);
		
		geo = geo.clone();
		
		// Stores values for restoring based on style
		var x = geo.x;
		var y = geo.y
		var w = geo.width;
		var h = geo.height;
		
		geo.scale(dx, dy, style[mxConstants.STYLE_ASPECT] == 'fixed');
		
		if (style[mxConstants.STYLE_RESIZE_WIDTH] == '1')
		{
			geo.width = w * dx;
		}
		else if (style[mxConstants.STYLE_RESIZE_WIDTH] == '0')
		{
			geo.width = w;
		}
		
		if (style[mxConstants.STYLE_RESIZE_HEIGHT] == '1')
		{
			geo.height = h * dy;
		}
		else if (style[mxConstants.STYLE_RESIZE_HEIGHT] == '0')
		{
			geo.height = h;
		}
		
		if (!this.isCellMovable(cell))
		{
			geo.x = x;
			geo.y = y;
		}
		
		if (!this.isCellResizable(cell))
		{
			geo.width = w;
			geo.height = h;
		}

		if (this.model.isVertex(cell))
		{
			this.cellResized(cell, geo, true, recurse);
		}
		else
		{
			this.model.setGeometry(cell, geo);
		}
	}
};

/**
 * Function: extendParent
 * 
 * Resizes the parents recursively so that they contain the complete area
 * of the resized child cell.
 * 
 * Parameters:
 * 
 * cell - <mxCell> that has been resized.
 */
mxGraph.prototype.extendParent = function(cell)
{
	if (cell != null)
	{
		var parent = this.model.getParent(cell);
		var p = this.getCellGeometry(parent);
		
		if (parent != null && p != null && !this.isCellCollapsed(parent))
		{
			var geo = this.getCellGeometry(cell);
			
			if (geo != null && !geo.relative &&
				(p.width < geo.x + geo.width ||
				p.height < geo.y + geo.height))
			{
				p = p.clone();
				
				p.width = Math.max(p.width, geo.x + geo.width);
				p.height = Math.max(p.height, geo.y + geo.height);
				
				this.cellsResized([parent], [p], false);
			}
		}
	}
};

/**
 * Group: Cell moving
 */

/**
 * Function: importCells
 * 
 * Clones and inserts the given cells into the graph using the move
 * method and returns the inserted cells. This shortcut is used if
 * cells are inserted via datatransfer.
 * 
 * Parameters:
 * 
 * cells - Array of <mxCells> to be imported.
 * dx - Integer that specifies the x-coordinate of the vector. Default is 0.
 * dy - Integer that specifies the y-coordinate of the vector. Default is 0.
 * target - <mxCell> that represents the new parent of the cells.
 * evt - Mouseevent that triggered the invocation.
 * mapping - Optional mapping for existing clones.
 */
mxGraph.prototype.importCells = function(cells, dx, dy, target, evt, mapping)
{	
	return this.moveCells(cells, dx, dy, true, target, evt, mapping);
};

/**
 * Function: moveCells
 * 
 * Moves or clones the specified cells and moves the cells or clones by the
 * given amount, adding them to the optional target cell. The evt is the
 * mouse event as the mouse was released. The change is carried out using
 * <cellsMoved>. This method fires <mxEvent.MOVE_CELLS> while the
 * transaction is in progress. Returns the cells that were moved.
 * 
 * Use the following code to move all cells in the graph.
 * 
 * (code)
 * graph.moveCells(graph.getChildCells(null, true, true), 10, 10);
 * (end)
 * 
 * Parameters:
 * 
 * cells - Array of <mxCells> to be moved, cloned or added to the target.
 * dx - Integer that specifies the x-coordinate of the vector. Default is 0.
 * dy - Integer that specifies the y-coordinate of the vector. Default is 0.
 * clone - Boolean indicating if the cells should be cloned. Default is false.
 * target - <mxCell> that represents the new parent of the cells.
 * evt - Mouseevent that triggered the invocation.
 * mapping - Optional mapping for existing clones.
 */
mxGraph.prototype.moveCells = function(cells, dx, dy, clone, target, evt, mapping)
{
	dx = (dx != null) ? dx : 0;
	dy = (dy != null) ? dy : 0;
	clone = (clone != null) ? clone : false;
	
	if (cells != null && (dx != 0 || dy != 0 || clone || target != null))
	{
		// Removes descandants with ancestors in cells to avoid multiple moving
		cells = this.model.getTopmostCells(cells);

		this.model.beginUpdate();
		try
		{
			// Faster cell lookups to remove relative edge labels with selected
			// terminals to avoid explicit and implicit move at same time
			var dict = new mxDictionary();
			
			for (var i = 0; i < cells.length; i++)
			{
				dict.put(cells[i], true);
			}
			
			var isSelected = mxUtils.bind(this, function(cell)
			{
				while (cell != null)
				{
					if (dict.get(cell))
					{
						return true;
					}
					
					cell = this.model.getParent(cell);
				}
				
				return false;
			});
			
			// Removes relative edge labels with selected terminals
			var checked = [];
			
			for (var i = 0; i < cells.length; i++)
			{
				var geo = this.getCellGeometry(cells[i]);
				var parent = this.model.getParent(cells[i]);
		
				if ((geo == null || !geo.relative) || !this.model.isEdge(parent) ||
					(!isSelected(this.model.getTerminal(parent, true)) &&
					!isSelected(this.model.getTerminal(parent, false))))
				{
					checked.push(cells[i]);
				}
			}

			cells = checked;
			
			if (clone)
			{
				cells = this.cloneCells(cells, this.isCloneInvalidEdges(), mapping);

				if (target == null)
				{
					target = this.getDefaultParent();
				}
			}

			// FIXME: Cells should always be inserted first before any other edit
			// to avoid forward references in sessions.
			// Need to disable allowNegativeCoordinates if target not null to
			// allow for temporary negative numbers until cellsAdded is called.
			var previous = this.isAllowNegativeCoordinates();
			
			if (target != null)
			{
				this.setAllowNegativeCoordinates(true);
			}
			
			this.cellsMoved(cells, dx, dy, !clone && this.isDisconnectOnMove()
					&& this.isAllowDanglingEdges(), target == null,
					this.isExtendParentsOnMove() && target == null);
			
			this.setAllowNegativeCoordinates(previous);

			if (target != null)
			{
				var index = this.model.getChildCount(target);
				this.cellsAdded(cells, target, index, null, null, true);
			}

			// Dispatches a move event
			this.fireEvent(new mxEventObject(mxEvent.MOVE_CELLS, 'cells', cells,
				'dx', dx, 'dy', dy, 'clone', clone, 'target', target, 'event', evt));
		}
		finally
		{
			this.model.endUpdate();
		}
	}

	return cells;
};

/**
 * Function: cellsMoved
 * 
 * Moves the specified cells by the given vector, disconnecting the cells
 * using disconnectGraph is disconnect is true. This method fires
 * <mxEvent.CELLS_MOVED> while the transaction is in progress.
 */
mxGraph.prototype.cellsMoved = function(cells, dx, dy, disconnect, constrain, extend)
{
	if (cells != null && (dx != 0 || dy != 0))
	{
		extend = (extend != null) ? extend : false;

		this.model.beginUpdate();
		try
		{
			if (disconnect)
			{
				this.disconnectGraph(cells);
			}

			for (var i = 0; i < cells.length; i++)
			{
				this.translateCell(cells[i], dx, dy);
				
				if (extend && this.isExtendParent(cells[i]))
				{
					this.extendParent(cells[i]);
				}
				else if (constrain)
				{
					this.constrainChild(cells[i]);
				}
			}

			if (this.resetEdgesOnMove)
			{
				this.resetEdges(cells);
			}
			
			this.fireEvent(new mxEventObject(mxEvent.CELLS_MOVED,
				'cells', cells, 'dx', dx, 'dy', dy, 'disconnect', disconnect));
		}
		finally
		{
			this.model.endUpdate();
		}
	}
};

/**
 * Function: translateCell
 * 
 * Translates the geometry of the given cell and stores the new,
 * translated geometry in the model as an atomic change.
 */
mxGraph.prototype.translateCell = function(cell, dx, dy)
{
	var geo = this.model.getGeometry(cell);

	if (geo != null)
	{
		dx = parseFloat(dx);
		dy = parseFloat(dy);
		geo = geo.clone();
		geo.translate(dx, dy);

		if (!geo.relative && this.model.isVertex(cell) && !this.isAllowNegativeCoordinates())
		{
			geo.x = Math.max(0, parseFloat(geo.x));
			geo.y = Math.max(0, parseFloat(geo.y));
		}
		
		if (geo.relative && !this.model.isEdge(cell))
		{
			var parent = this.model.getParent(cell);
			var angle = 0;
			
			if (this.model.isVertex(parent))
			{
				var state = this.view.getState(parent);
				var style = (state != null) ? state.style : this.getCellStyle(parent);
				
				angle = mxUtils.getValue(style, mxConstants.STYLE_ROTATION, 0);
			}
			
			if (angle != 0)
			{
				var rad = mxUtils.toRadians(-angle);
				var cos = Math.cos(rad);
				var sin = Math.sin(rad);
				var pt = mxUtils.getRotatedPoint(new mxPoint(dx, dy), cos, sin, new mxPoint(0, 0));
				dx = pt.x;
				dy = pt.y;
			}
			
			if (geo.offset == null)
			{
				geo.offset = new mxPoint(dx, dy);
			}
			else
			{
				geo.offset.x = parseFloat(geo.offset.x) + dx;
				geo.offset.y = parseFloat(geo.offset.y) + dy;
			}
		}

		this.model.setGeometry(cell, geo);
	}
};

/**
 * Function: getCellContainmentArea
 * 
 * Returns the <mxRectangle> inside which a cell is to be kept.
 * 
 * Parameters:
 * 
 * cell - <mxCell> for which the area should be returned.
 */
mxGraph.prototype.getCellContainmentArea = function(cell)
{
	if (cell != null && !this.model.isEdge(cell))
	{
		var parent = this.model.getParent(cell);
		
		if (parent != null && parent != this.getDefaultParent())
		{
			var g = this.model.getGeometry(parent);
			
			if (g != null)
			{
				var x = 0;
				var y = 0;
				var w = g.width;
				var h = g.height;
				
				if (this.isSwimlane(parent))
				{
					var size = this.getStartSize(parent);
					
					var state = this.view.getState(parent);
					var style = (state != null) ? state.style : this.getCellStyle(parent);
					var dir = mxUtils.getValue(style, mxConstants.STYLE_DIRECTION, mxConstants.DIRECTION_EAST);
					var flipH = mxUtils.getValue(style, mxConstants.STYLE_FLIPH, 0) == 1;
					var flipV = mxUtils.getValue(style, mxConstants.STYLE_FLIPV, 0) == 1;
					
					if (dir == mxConstants.DIRECTION_SOUTH || dir == mxConstants.DIRECTION_NORTH)
					{
						var tmp = size.width;
						size.width = size.height;
						size.height = tmp;
					}
					
					if ((dir == mxConstants.DIRECTION_EAST && !flipV) || (dir == mxConstants.DIRECTION_NORTH && !flipH) ||
						(dir == mxConstants.DIRECTION_WEST && flipV) || (dir == mxConstants.DIRECTION_SOUTH && flipH))
					{
						x = size.width;
						y = size.height;
					}

					w -= size.width;
					h -= size.height;
				}
				
				return new mxRectangle(x, y, w, h);
			}
		}
	}
	
	return null;
};

/**
 * Function: getMaximumGraphBounds
 * 
 * Returns the bounds inside which the diagram should be kept as an
 * <mxRectangle>.
 */
mxGraph.prototype.getMaximumGraphBounds = function()
{
	return this.maximumGraphBounds;
};

/**
 * Function: constrainChild
 * 
 * Keeps the given cell inside the bounds returned by
 * <getCellContainmentArea> for its parent, according to the rules defined by
 * <getOverlap> and <isConstrainChild>. This modifies the cell's geometry
 * in-place and does not clone it.
 * 
 * Parameters:
 * 
 * cells - <mxCell> which should be constrained.
 * sizeFirst - Specifies if the size should be changed first. Default is true.
 */
mxGraph.prototype.constrainChild = function(cell, sizeFirst)
{
	sizeFirst = (sizeFirst != null) ? sizeFirst : true;
	
	if (cell != null)
	{
		var geo = this.getCellGeometry(cell);
		
		if (geo != null && (this.isConstrainRelativeChildren() || !geo.relative))
		{
			var parent = this.model.getParent(cell);
			var pgeo = this.getCellGeometry(parent);
			var max = this.getMaximumGraphBounds();
			
			// Finds parent offset
			if (max != null)
			{
				var off = this.getBoundingBoxFromGeometry([parent], false);
				
				if (off != null)
				{
					max = mxRectangle.fromRectangle(max);
					
					max.x -= off.x;
					max.y -= off.y;
				}
			}
			
			if (this.isConstrainChild(cell))
			{
				var tmp = this.getCellContainmentArea(cell);
				
				if (tmp != null)
				{
					var overlap = this.getOverlap(cell);
	
					if (overlap > 0)
					{
						tmp = mxRectangle.fromRectangle(tmp);
						
						tmp.x -= tmp.width * overlap;
						tmp.y -= tmp.height * overlap;
						tmp.width += 2 * tmp.width * overlap;
						tmp.height += 2 * tmp.height * overlap;
					}
					
					// Find the intersection between max and tmp
					if (max == null)
					{
						max = tmp;
					}
					else
					{
						max = mxRectangle.fromRectangle(max);
						max.intersect(tmp);
					}
				}
			}
			
			if (max != null)
			{
				var cells = [cell];
				
				if (!this.isCellCollapsed(cell))
				{
					var desc = this.model.getDescendants(cell);
					
					for (var i = 0; i < desc.length; i++)
					{
						if (this.isCellVisible(desc[i]))
						{
							cells.push(desc[i]);
						}
					}
				}
				
				var bbox = this.getBoundingBoxFromGeometry(cells, false);
				
				if (bbox != null)
				{
					geo = geo.clone();
					
					// Cumulative horizontal movement
					var dx = 0;
					
					if (geo.width > max.width)
					{
						dx = geo.width - max.width;
						geo.width -= dx;
					}
					
					if (bbox.x + bbox.width > max.x + max.width)
					{
						dx -= bbox.x + bbox.width - max.x - max.width - dx;
					}
					
					// Cumulative vertical movement
					var dy = 0;
					
					if (geo.height > max.height)
					{
						dy = geo.height - max.height;
						geo.height -= dy;
					}
					
					if (bbox.y + bbox.height > max.y + max.height)
					{
						dy -= bbox.y + bbox.height - max.y - max.height - dy;
					}
					
					if (bbox.x < max.x)
					{
						dx -= bbox.x - max.x;
					}
					
					if (bbox.y < max.y)
					{
						dy -= bbox.y - max.y;
					}
					
					if (dx != 0 || dy != 0)
					{
						if (geo.relative)
						{
							// Relative geometries are moved via absolute offset
							if (geo.offset == null)
							{
								geo.offset = new mxPoint();
							}
						
							geo.offset.x += dx;
							geo.offset.y += dy;
						}
						else
						{
							geo.x += dx;
							geo.y += dy;
						}
					}
					
					this.model.setGeometry(cell, geo);
				}
			}
		}
	}
};

/**
 * Function: resetEdges
 * 
 * Resets the control points of the edges that are connected to the given
 * cells if not both ends of the edge are in the given cells array.
 * 
 * Parameters:
 * 
 * cells - Array of <mxCells> for which the connected edges should be
 * reset.
 */
mxGraph.prototype.resetEdges = function(cells)
{
	if (cells != null)
	{
		// Prepares faster cells lookup
		var dict = new mxDictionary();
		
		for (var i = 0; i < cells.length; i++)
		{
			dict.put(cells[i], true);
		}
		
		this.model.beginUpdate();
		try
		{
			for (var i = 0; i < cells.length; i++)
			{
				var edges = this.model.getEdges(cells[i]);
				
				if (edges != null)
				{
					for (var j = 0; j < edges.length; j++)
					{
						var state = this.view.getState(edges[j]);
						
						var source = (state != null) ? state.getVisibleTerminal(true) : this.view.getVisibleTerminal(edges[j], true);
						var target = (state != null) ? state.getVisibleTerminal(false) : this.view.getVisibleTerminal(edges[j], false);
						
						// Checks if one of the terminals is not in the given array
						if (!dict.get(source) || !dict.get(target))
						{
							this.resetEdge(edges[j]);
						}
					}
				}
				
				this.resetEdges(this.model.getChildren(cells[i]));
			}
		}
		finally
		{
			this.model.endUpdate();
		}
	}
};

/**
 * Function: resetEdge
 * 
 * Resets the control points of the given edge.
 * 
 * Parameters:
 * 
 * edge - <mxCell> whose points should be reset.
 */
mxGraph.prototype.resetEdge = function(edge)
{
	var geo = this.model.getGeometry(edge);
	
	// Resets the control points
	if (geo != null && geo.points != null && geo.points.length > 0)
	{
		geo = geo.clone();
		geo.points = [];
		this.model.setGeometry(edge, geo);
	}
	
	return edge;
};

/**
 * Group: Cell connecting and connection constraints
 */

/**
 * Function: getOutlineConstraint
 * 
 * Returns the constraint used to connect to the outline of the given state.
 */
mxGraph.prototype.getOutlineConstraint = function(point, terminalState, me)
{
	if (terminalState.shape != null)
	{
		var bounds = this.view.getPerimeterBounds(terminalState);
		var direction = terminalState.style[mxConstants.STYLE_DIRECTION];
		
		if (direction == mxConstants.DIRECTION_NORTH || direction == mxConstants.DIRECTION_SOUTH)
		{
			bounds.x += bounds.width / 2 - bounds.height / 2;
			bounds.y += bounds.height / 2 - bounds.width / 2;
			var tmp = bounds.width;
			bounds.width = bounds.height;
			bounds.height = tmp;
		}
	
		var alpha = mxUtils.toRadians(terminalState.shape.getShapeRotation());
		
		if (alpha != 0)
		{
			var cos = Math.cos(-alpha);
			var sin = Math.sin(-alpha);
	
			var ct = new mxPoint(bounds.getCenterX(), bounds.getCenterY());
			point = mxUtils.getRotatedPoint(point, cos, sin, ct);
		}

		var sx = 1;
		var sy = 1;
		var dx = 0;
		var dy = 0;
		
		// LATER: Add flipping support for image shapes
		if (this.getModel().isVertex(terminalState.cell))
		{
			var flipH = terminalState.style[mxConstants.STYLE_FLIPH];
			var flipV = terminalState.style[mxConstants.STYLE_FLIPV];
			
			// Legacy support for stencilFlipH/V
			if (terminalState.shape != null && terminalState.shape.stencil != null)
			{
				flipH = mxUtils.getValue(terminalState.style, 'stencilFlipH', 0) == 1 || flipH;
				flipV = mxUtils.getValue(terminalState.style, 'stencilFlipV', 0) == 1 || flipV;
			}
			
			if (direction == mxConstants.DIRECTION_NORTH || direction == mxConstants.DIRECTION_SOUTH)
			{
				var tmp = flipH;
				flipH = flipV;
				flipV = tmp;
			}
			
			if (flipH)
			{
				sx = -1;
				dx = -bounds.width;
			}
			
			if (flipV)
			{
				sy = -1;
				dy = -bounds.height ;
			}
		}
		
		point = new mxPoint((point.x - bounds.x) * sx - dx + bounds.x, (point.y - bounds.y) * sy - dy + bounds.y);
		
		var x = Math.round((point.x - bounds.x) * 1000 / bounds.width) / 1000;
		var y = Math.round((point.y - bounds.y) * 1000 / bounds.height) / 1000;
		
		return new mxConnectionConstraint(new mxPoint(x, y), false);
	}
	
	return null;
};

/**
 * Function: getAllConnectionConstraints
 * 
 * Returns an array of all <mxConnectionConstraints> for the given terminal. If
 * the shape of the given terminal is a <mxStencilShape> then the constraints
 * of the corresponding <mxStencil> are returned.
 * 
 * Parameters:
 * 
 * terminal - <mxCellState> that represents the terminal.
 * source - Boolean that specifies if the terminal is the source or target.
 */
mxGraph.prototype.getAllConnectionConstraints = function(terminal, source)
{
	if (terminal != null && terminal.shape != null && terminal.shape.stencil != null)
	{
		return terminal.shape.stencil.constraints;
	}

	return null;
};

/**
 * Function: getConnectionConstraint
 * 
 * Returns an <mxConnectionConstraint> that describes the given connection
 * point. This result can then be passed to <getConnectionPoint>.
 * 
 * Parameters:
 * 
 * edge - <mxCellState> that represents the edge.
 * terminal - <mxCellState> that represents the terminal.
 * source - Boolean indicating if the terminal is the source or target.
 */
mxGraph.prototype.getConnectionConstraint = function(edge, terminal, source)
{
	var point = null;
	var x = edge.style[(source) ? mxConstants.STYLE_EXIT_X : mxConstants.STYLE_ENTRY_X];

	if (x != null)
	{
		var y = edge.style[(source) ? mxConstants.STYLE_EXIT_Y : mxConstants.STYLE_ENTRY_Y];
		
		if (y != null)
		{
			point = new mxPoint(parseFloat(x), parseFloat(y));
		}
	}
	
	var perimeter = false;
	
	if (point != null)
	{
		perimeter = mxUtils.getValue(edge.style, (source) ? mxConstants.STYLE_EXIT_PERIMETER :
			mxConstants.STYLE_ENTRY_PERIMETER, true);
	}
	
	return new mxConnectionConstraint(point, perimeter);
};

/**
 * Function: setConnectionConstraint
 * 
 * Sets the <mxConnectionConstraint> that describes the given connection point.
 * If no constraint is given then nothing is changed. To remove an existing
 * constraint from the given edge, use an empty constraint instead.
 * 
 * Parameters:
 * 
 * edge - <mxCell> that represents the edge.
 * terminal - <mxCell> that represents the terminal.
 * source - Boolean indicating if the terminal is the source or target.
 * constraint - Optional <mxConnectionConstraint> to be used for this
 * connection.
 */
mxGraph.prototype.setConnectionConstraint = function(edge, terminal, source, constraint)
{
	if (constraint != null)
	{
		this.model.beginUpdate();
		
		try
		{
			if (constraint == null || constraint.point == null)
			{
				this.setCellStyles((source) ? mxConstants.STYLE_EXIT_X :
					mxConstants.STYLE_ENTRY_X, null, [edge]);
				this.setCellStyles((source) ? mxConstants.STYLE_EXIT_Y :
					mxConstants.STYLE_ENTRY_Y, null, [edge]);
				this.setCellStyles((source) ? mxConstants.STYLE_EXIT_PERIMETER :
					mxConstants.STYLE_ENTRY_PERIMETER, null, [edge]);
			}
			else if (constraint.point != null)
			{
				this.setCellStyles((source) ? mxConstants.STYLE_EXIT_X :
					mxConstants.STYLE_ENTRY_X, constraint.point.x, [edge]);
				this.setCellStyles((source) ? mxConstants.STYLE_EXIT_Y :
					mxConstants.STYLE_ENTRY_Y, constraint.point.y, [edge]);
				
				// Only writes 0 since 1 is default
				if (!constraint.perimeter)
				{
					this.setCellStyles((source) ? mxConstants.STYLE_EXIT_PERIMETER :
						mxConstants.STYLE_ENTRY_PERIMETER, '0', [edge]);
				}
				else
				{
					this.setCellStyles((source) ? mxConstants.STYLE_EXIT_PERIMETER :
						mxConstants.STYLE_ENTRY_PERIMETER, null, [edge]);
				}
			}
		}
		finally
		{
			this.model.endUpdate();
		}
	}
};

/**
 * Function: getConnectionPoint
 *
 * Returns the nearest point in the list of absolute points or the center
 * of the opposite terminal.
 * 
 * Parameters:
 * 
 * vertex - <mxCellState> that represents the vertex.
 * constraint - <mxConnectionConstraint> that represents the connection point
 * constraint as returned by <getConnectionConstraint>.
 */
mxGraph.prototype.getConnectionPoint = function(vertex, constraint)
{
	var point = null;
	
	if (vertex != null && constraint.point != null)
	{
		var bounds = this.view.getPerimeterBounds(vertex);
        var cx = new mxPoint(bounds.getCenterX(), bounds.getCenterY());
		var direction = vertex.style[mxConstants.STYLE_DIRECTION];
		var r1 = 0;
		
		// Bounds need to be rotated by 90 degrees for further computation
		if (direction != null)
		{
			if (direction == mxConstants.DIRECTION_NORTH)
			{
				r1 += 270;
			}
			else if (direction == mxConstants.DIRECTION_WEST)
			{
				r1 += 180;
			}
			else if (direction == mxConstants.DIRECTION_SOUTH)
			{
				r1 += 90;
			}

			// Bounds need to be rotated by 90 degrees for further computation
			if (direction == mxConstants.DIRECTION_NORTH || direction == mxConstants.DIRECTION_SOUTH)
			{
				bounds.rotate90();
			}
		}

		point = new mxPoint(bounds.x + constraint.point.x * bounds.width,
				bounds.y + constraint.point.y * bounds.height);
		
		// Rotation for direction before projection on perimeter
		var r2 = vertex.style[mxConstants.STYLE_ROTATION] || 0;
		
		if (constraint.perimeter)
		{
			if (r1 != 0)
			{
				// Only 90 degrees steps possible here so no trig needed
				var cos = 0;
				var sin = 0;
				
				if (r1 == 90)
				{
					sin = 1;
				}
				else if (r1 == 180)
				{
					cos = -1;
				}
				else if (r1 == 270)
				{
					sin = -1;
				}
				
		        point = mxUtils.getRotatedPoint(point, cos, sin, cx);
			}
	
			point = this.view.getPerimeterPoint(vertex, point, false);
		}
		else
		{
			r2 += r1;
			
			if (this.getModel().isVertex(vertex.cell))
			{
				var flipH = vertex.style[mxConstants.STYLE_FLIPH] == 1;
				var flipV = vertex.style[mxConstants.STYLE_FLIPV] == 1;
				
				// Legacy support for stencilFlipH/V
				if (vertex.shape != null && vertex.shape.stencil != null)
				{
					flipH = (mxUtils.getValue(vertex.style, 'stencilFlipH', 0) == 1) || flipH;
					flipV = (mxUtils.getValue(vertex.style, 'stencilFlipV', 0) == 1) || flipV;
				}
				
				if (flipH)
				{
					point.x = 2 * bounds.getCenterX() - point.x;
				}
				
				if (flipV)
				{
					point.y = 2 * bounds.getCenterY() - point.y;
				}
			}
		}

		// Generic rotation after projection on perimeter
		if (r2 != 0 && point != null)
		{
	        var rad = mxUtils.toRadians(r2);
	        var cos = Math.cos(rad);
	        var sin = Math.sin(rad);
	        
	        point = mxUtils.getRotatedPoint(point, cos, sin, cx);
		}
	}
	
	if (point != null)
	{
		point.x = Math.round(point.x);
		point.y = Math.round(point.y);
	}

	return point;
};

/**
 * Function: connectCell
 * 
 * Connects the specified end of the given edge to the given terminal
 * using <cellConnected> and fires <mxEvent.CONNECT_CELL> while the
 * transaction is in progress. Returns the updated edge.
 * 
 * Parameters:
 * 
 * edge - <mxCell> whose terminal should be updated.
 * terminal - <mxCell> that represents the new terminal to be used.
 * source - Boolean indicating if the new terminal is the source or target.
 * constraint - Optional <mxConnectionConstraint> to be used for this
 * connection.
 */
mxGraph.prototype.connectCell = function(edge, terminal, source, constraint)
{
	this.model.beginUpdate();
	try
	{
		var previous = this.model.getTerminal(edge, source);
		this.cellConnected(edge, terminal, source, constraint);
		this.fireEvent(new mxEventObject(mxEvent.CONNECT_CELL,
			'edge', edge, 'terminal', terminal, 'source', source,
			'previous', previous));
	}
	finally
	{
		this.model.endUpdate();
	}

	return edge;
};

/**
 * Function: cellConnected
 * 
 * Sets the new terminal for the given edge and resets the edge points if
 * <resetEdgesOnConnect> is true. This method fires
 * <mxEvent.CELL_CONNECTED> while the transaction is in progress.
 * 
 * Parameters:
 * 
 * edge - <mxCell> whose terminal should be updated.
 * terminal - <mxCell> that represents the new terminal to be used.
 * source - Boolean indicating if the new terminal is the source or target.
 * constraint - <mxConnectionConstraint> to be used for this connection.
 */
mxGraph.prototype.cellConnected = function(edge, terminal, source, constraint)
{
	if (edge != null)
	{
		this.model.beginUpdate();
		try
		{
			var previous = this.model.getTerminal(edge, source);

			// Updates the constraint
			this.setConnectionConstraint(edge, terminal, source, constraint);
			
			// Checks if the new terminal is a port, uses the ID of the port in the
			// style and the parent of the port as the actual terminal of the edge.
			if (this.isPortsEnabled())
			{
				var id = null;
	
				if (this.isPort(terminal))
				{
					id = terminal.getId();
					terminal = this.getTerminalForPort(terminal, source);
				}
				
				// Sets or resets all previous information for connecting to a child port
				var key = (source) ? mxConstants.STYLE_SOURCE_PORT :
					mxConstants.STYLE_TARGET_PORT;
				this.setCellStyles(key, id, [edge]);
			}
			
			this.model.setTerminal(edge, terminal, source);
			
			if (this.resetEdgesOnConnect)
			{
				this.resetEdge(edge);
			}

			this.fireEvent(new mxEventObject(mxEvent.CELL_CONNECTED,
				'edge', edge, 'terminal', terminal, 'source', source,
				'previous', previous));
		}
		finally
		{
			this.model.endUpdate();
		}
	}
};

/**
 * Function: disconnectGraph
 * 
 * Disconnects the given edges from the terminals which are not in the
 * given array.
 * 
 * Parameters:
 * 
 * cells - Array of <mxCells> to be disconnected.
 */
mxGraph.prototype.disconnectGraph = function(cells)
{
	if (cells != null)
	{
		this.model.beginUpdate();
		try
		{							
			var scale = this.view.scale;
			var tr = this.view.translate;
			
			// Fast lookup for finding cells in array
			var dict = new mxDictionary();
			
			for (var i = 0; i < cells.length; i++)
			{
				dict.put(cells[i], true);
			}
			
			for (var i = 0; i < cells.length; i++)
			{
				if (this.model.isEdge(cells[i]))
				{
					var geo = this.model.getGeometry(cells[i]);
					
					if (geo != null)
					{
						var state = this.view.getState(cells[i]);
						var pstate = this.view.getState(
							this.model.getParent(cells[i]));
						
						if (state != null &&
							pstate != null)
						{
							geo = geo.clone();
							
							var dx = -pstate.origin.x;
							var dy = -pstate.origin.y;
							var pts = state.absolutePoints;

							var src = this.model.getTerminal(cells[i], true);
							
							if (src != null && this.isCellDisconnectable(cells[i], src, true))
							{
								while (src != null && !dict.get(src))
								{
									src = this.model.getParent(src);
								}
								
								if (src == null)
								{
									geo.setTerminalPoint(
										new mxPoint(pts[0].x / scale - tr.x + dx,
											pts[0].y / scale - tr.y + dy), true);
									this.model.setTerminal(cells[i], null, true);
								}
							}
							
							var trg = this.model.getTerminal(cells[i], false);
							
							if (trg != null && this.isCellDisconnectable(cells[i], trg, false))
							{
								while (trg != null && !dict.get(trg))
								{
									trg = this.model.getParent(trg);
								}
								
								if (trg == null)
								{
									var n = pts.length - 1;
									geo.setTerminalPoint(
										new mxPoint(pts[n].x / scale - tr.x + dx,
											pts[n].y / scale - tr.y + dy), false);
									this.model.setTerminal(cells[i], null, false);
								}
							}

							this.model.setGeometry(cells[i], geo);
						}
					}
				}
			}
		}
		finally
		{
			this.model.endUpdate();
		}
	}
};

/**
 * Group: Drilldown
 */

/**
 * Function: getCurrentRoot
 * 
 * Returns the current root of the displayed cell hierarchy. This is a
 * shortcut to <mxGraphView.currentRoot> in <view>.
 */
mxGraph.prototype.getCurrentRoot = function()
{
	return this.view.currentRoot;
};
 
/**
 * Function: getTranslateForRoot
 * 
 * Returns the translation to be used if the given cell is the root cell as
 * an <mxPoint>. This implementation returns null.
 * 
 * Example:
 * 
 * To keep the children at their absolute position while stepping into groups,
 * this function can be overridden as follows.
 * 
 * (code)
 * var offset = new mxPoint(0, 0);
 * 
 * while (cell != null)
 * {
 *   var geo = this.model.getGeometry(cell);
 * 
 *   if (geo != null)
 *   {
 *     offset.x -= geo.x;
 *     offset.y -= geo.y;
 *   }
 * 
 *   cell = this.model.getParent(cell);
 * }
 * 
 * return offset;
 * (end)
 * 
 * Parameters:
 * 
 * cell - <mxCell> that represents the root.
 */
mxGraph.prototype.getTranslateForRoot = function(cell)
{
	return null;
};

/**
 * Function: isPort
 * 
 * Returns true if the given cell is a "port", that is, when connecting to
 * it, the cell returned by getTerminalForPort should be used as the
 * terminal and the port should be referenced by the ID in either the
 * mxConstants.STYLE_SOURCE_PORT or the or the
 * mxConstants.STYLE_TARGET_PORT. Note that a port should not be movable.
 * This implementation always returns false.
 * 
 * A typical implementation is the following:
 * 
 * (code)
 * graph.isPort = function(cell)
 * {
 *   var geo = this.getCellGeometry(cell);
 *   
 *   return (geo != null) ? geo.relative : false;
 * };
 * (end)
 * 
 * Parameters:
 * 
 * cell - <mxCell> that represents the port.
 */
mxGraph.prototype.isPort = function(cell)
{
	return false;
};

/**
 * Function: getTerminalForPort
 * 
 * Returns the terminal to be used for a given port. This implementation
 * always returns the parent cell.
 * 
 * Parameters:
 * 
 * cell - <mxCell> that represents the port.
 * source - If the cell is the source or target port.
 */
mxGraph.prototype.getTerminalForPort = function(cell, source)
{
	return this.model.getParent(cell);
};

/**
 * Function: getChildOffsetForCell
 * 
 * Returns the offset to be used for the cells inside the given cell. The
 * root and layer cells may be identified using <mxGraphModel.isRoot> and
 * <mxGraphModel.isLayer>. For all other current roots, the
 * <mxGraphView.currentRoot> field points to the respective cell, so that
 * the following holds: cell == this.view.currentRoot. This implementation
 * returns null.
 * 
 * Parameters:
 * 
 * cell - <mxCell> whose offset should be returned.
 */
mxGraph.prototype.getChildOffsetForCell = function(cell)
{
	return null;
};

/**
 * Function: enterGroup
 * 
 * Uses the given cell as the root of the displayed cell hierarchy. If no
 * cell is specified then the selection cell is used. The cell is only used
 * if <isValidRoot> returns true.
 * 
 * Parameters:
 * 
 * cell - Optional <mxCell> to be used as the new root. Default is the
 * selection cell.
 */
mxGraph.prototype.enterGroup = function(cell)
{
	cell = cell || this.getSelectionCell();
	
	if (cell != null && this.isValidRoot(cell))
	{
		this.view.setCurrentRoot(cell);
		this.clearSelection();
	}
};

/**
 * Function: exitGroup
 * 
 * Changes the current root to the next valid root in the displayed cell
 * hierarchy.
 */
mxGraph.prototype.exitGroup = function()
{
	var root = this.model.getRoot();
	var current = this.getCurrentRoot();
	
	if (current != null)
	{
		var next = this.model.getParent(current);
		
		// Finds the next valid root in the hierarchy
		while (next != root && !this.isValidRoot(next) &&
				this.model.getParent(next) != root)
		{
			next = this.model.getParent(next);
		}
		
		// Clears the current root if the new root is
		// the model's root or one of the layers.
		if (next == root || this.model.getParent(next) == root)
		{
			this.view.setCurrentRoot(null);
		}
		else
		{
			this.view.setCurrentRoot(next);
		}
		
		var state = this.view.getState(current);
		
		// Selects the previous root in the graph
		if (state != null)
		{
			this.setSelectionCell(current);
		}
	}
};

/**
 * Function: home
 * 
 * Uses the root of the model as the root of the displayed cell hierarchy
 * and selects the previous root.
 */
mxGraph.prototype.home = function()
{
	var current = this.getCurrentRoot();
	
	if (current != null)
	{
		this.view.setCurrentRoot(null);
		var state = this.view.getState(current);
		
		if (state != null)
		{
			this.setSelectionCell(current);
		}
	}
};

/**
 * Function: isValidRoot
 * 
 * Returns true if the given cell is a valid root for the cell display
 * hierarchy. This implementation returns true for all non-null values.
 * 
 * Parameters:
 * 
 * cell - <mxCell> which should be checked as a possible root.
 */
mxGraph.prototype.isValidRoot = function(cell)
{
	return (cell != null);
};

/**
 * Group: Graph display
 */
 
/**
 * Function: getGraphBounds
 * 
 * Returns the bounds of the visible graph. Shortcut to
 * <mxGraphView.getGraphBounds>. See also: <getBoundingBoxFromGeometry>.
 */
 mxGraph.prototype.getGraphBounds = function()
 {
 	return this.view.getGraphBounds();
 };

/**
 * Function: getCellBounds
 * 
 * Returns the scaled, translated bounds for the given cell. See
 * <mxGraphView.getBounds> for arrays.
 * 
 * Parameters:
 * 
 * cell - <mxCell> whose bounds should be returned.
 * includeEdge - Optional boolean that specifies if the bounds of
 * the connected edges should be included. Default is false.
 * includeDescendants - Optional boolean that specifies if the bounds
 * of all descendants should be included. Default is false.
 */
mxGraph.prototype.getCellBounds = function(cell, includeEdges, includeDescendants)
{
	var cells = [cell];
	
	// Includes all connected edges
	if (includeEdges)
	{
		cells = cells.concat(this.model.getEdges(cell));
	}
	
	var result = this.view.getBounds(cells);
	
	// Recursively includes the bounds of the children
	if (includeDescendants)
	{
		var childCount = this.model.getChildCount(cell);
		
		for (var i = 0; i < childCount; i++)
		{
			var tmp = this.getCellBounds(this.model.getChildAt(cell, i),
				includeEdges, true);

			if (result != null)
			{
				result.add(tmp);
			}
			else
			{
				result = tmp;
			}
		}
	}
	
	return result;
};

/**
 * Function: getBoundingBoxFromGeometry
 * 
 * Returns the bounding box for the geometries of the vertices in the
 * given array of cells. This can be used to find the graph bounds during
 * a layout operation (ie. before the last endUpdate) as follows:
 * 
 * (code)
 * var cells = graph.getChildCells(graph.getDefaultParent(), true, true);
 * var bounds = graph.getBoundingBoxFromGeometry(cells, true);
 * (end)
 * 
 * This can then be used to move cells to the origin:
 * 
 * (code)
 * if (bounds.x < 0 || bounds.y < 0)
 * {
 *   graph.moveCells(cells, -Math.min(bounds.x, 0), -Math.min(bounds.y, 0))
 * }
 * (end)
 * 
 * Or to translate the graph view:
 * 
 * (code)
 * if (bounds.x < 0 || bounds.y < 0)
 * {
 *   graph.view.setTranslate(-Math.min(bounds.x, 0), -Math.min(bounds.y, 0));
 * }
 * (end)
 * 
 * Parameters:
 * 
 * cells - Array of <mxCells> whose bounds should be returned.
 * includeEdges - Specifies if edge bounds should be included by computing
 * the bounding box for all points in geometry. Default is false.
 */
mxGraph.prototype.getBoundingBoxFromGeometry = function(cells, includeEdges)
{
	includeEdges = (includeEdges != null) ? includeEdges : false;
	var result = null;
	
	if (cells != null)
	{
		for (var i = 0; i < cells.length; i++)
		{
			if (includeEdges || this.model.isVertex(cells[i]))
			{
				// Computes the bounding box for the points in the geometry
				var geo = this.getCellGeometry(cells[i]);
				
				if (geo != null)
				{
					var bbox = null;
					
					if (this.model.isEdge(cells[i]))
					{
						var addPoint = function(pt)
						{
							if (pt != null)
							{
								if (tmp == null)
								{
									tmp = new mxRectangle(pt.x, pt.y, 0, 0);
								}
								else
								{
									tmp.add(new mxRectangle(pt.x, pt.y, 0, 0));
								}
							}
						};
						
						if (this.model.getTerminal(cells[i], true) == null)
						{
							addPoint(geo.getTerminalPoint(true));
						}
						
						if (this.model.getTerminal(cells[i], false) == null)
						{
							addPoint(geo.getTerminalPoint(false));
						}
												
						var pts = geo.points;
						
						if (pts != null && pts.length > 0)
						{
							var tmp = new mxRectangle(pts[0].x, pts[0].y, 0, 0);

							for (var j = 1; j < pts.length; j++)
							{
								addPoint(pts[j]);
							}
						}
						
						bbox = tmp;
					}
					else
					{
						var parent = this.model.getParent(cells[i]);
						
						if (geo.relative)
						{
							if (this.model.isVertex(parent) && parent != this.view.currentRoot)
							{
								var tmp = this.getBoundingBoxFromGeometry([parent], false);
								
								if (tmp != null)
								{
									bbox = new mxRectangle(geo.x * tmp.width, geo.y * tmp.height, geo.width, geo.height);
									
									if (mxUtils.indexOf(cells, parent) >= 0)
									{
										bbox.x += tmp.x;
										bbox.y += tmp.y;
									}
								}
							}
						}
						else
						{
							bbox = mxRectangle.fromRectangle(geo);
							
							if (this.model.isVertex(parent) && mxUtils.indexOf(cells, parent) >= 0)
							{
								var tmp = this.getBoundingBoxFromGeometry([parent], false);

								if (tmp != null)
								{
									bbox.x += tmp.x;
									bbox.y += tmp.y;
								}
							}
						}
						
						if (bbox != null && geo.offset != null)
						{
							bbox.x += geo.offset.x;
							bbox.y += geo.offset.y;
						}
					}
					
					if (bbox != null)
					{
						if (result == null)
						{
							result = mxRectangle.fromRectangle(bbox);
						}
						else
						{
							result.add(bbox);
						}
					}
				}
			}
		}
	}
	
	return result;
};

/**
 * Function: refresh
 * 
 * Clears all cell states or the states for the hierarchy starting at the
 * given cell and validates the graph. This fires a refresh event as the
 * last step.
 * 
 * Parameters:
 * 
 * cell - Optional <mxCell> for which the cell states should be cleared.
 */
mxGraph.prototype.refresh = function(cell)
{
	this.view.clear(cell, cell == null);
	this.view.validate();
	this.sizeDidChange();
	this.fireEvent(new mxEventObject(mxEvent.REFRESH));
};

/**
 * Function: snap
 * 
 * Snaps the given numeric value to the grid if <gridEnabled> is true.
 * 
 * Parameters:
 * 
 * value - Numeric value to be snapped to the grid.
 */
mxGraph.prototype.snap = function(value)
{
	if (this.gridEnabled)
	{
		value = Math.round(value / this.gridSize ) * this.gridSize;
	}
	
	return value;
};

/**
 * Function: panGraph
 * 
 * Shifts the graph display by the given amount. This is used to preview
 * panning operations, use <mxGraphView.setTranslate> to set a persistent
 * translation of the view. Fires <mxEvent.PAN>.
 * 
 * Parameters:
 * 
 * dx - Amount to shift the graph along the x-axis.
 * dy - Amount to shift the graph along the y-axis.
 */
mxGraph.prototype.panGraph = function(dx, dy)
{
	if (this.useScrollbarsForPanning && mxUtils.hasScrollbars(this.container))
	{
		this.container.scrollLeft = -dx;
		this.container.scrollTop = -dy;
	}
	else
	{
		var canvas = this.view.getCanvas();
		
		if (this.dialect == mxConstants.DIALECT_SVG)
		{
			// Puts everything inside the container in a DIV so that it
			// can be moved without changing the state of the container
			if (dx == 0 && dy == 0)
			{
				// Workaround for ignored removeAttribute on SVG element in IE9 standards
				if (mxClient.IS_IE)
				{
					canvas.setAttribute('transform', 'translate(' + dx + ',' + dy + ')');
				}
				else
				{
					canvas.removeAttribute('transform');
				}
				
				if (this.shiftPreview1 != null)
				{
					var child = this.shiftPreview1.firstChild;
					
					while (child != null)
					{
						var next = child.nextSibling;
						this.container.appendChild(child);
						child = next;
					}

					if (this.shiftPreview1.parentNode != null)
					{
						this.shiftPreview1.parentNode.removeChild(this.shiftPreview1);
					}
					
					this.shiftPreview1 = null;
					
					this.container.appendChild(canvas.parentNode);
					
					child = this.shiftPreview2.firstChild;
					
					while (child != null)
					{
						var next = child.nextSibling;
						this.container.appendChild(child);
						child = next;
					}

					if (this.shiftPreview2.parentNode != null)
					{
						this.shiftPreview2.parentNode.removeChild(this.shiftPreview2);
					}
					
					this.shiftPreview2 = null;
				}
			}
			else
			{
				canvas.setAttribute('transform', 'translate(' + dx + ',' + dy + ')');
				
				if (this.shiftPreview1 == null)
				{
					// Needs two divs for stuff before and after the SVG element
					this.shiftPreview1 = document.createElement('div');
					this.shiftPreview1.style.position = 'absolute';
					this.shiftPreview1.style.overflow = 'visible';
					
					this.shiftPreview2 = document.createElement('div');
					this.shiftPreview2.style.position = 'absolute';
					this.shiftPreview2.style.overflow = 'visible';

					var current = this.shiftPreview1;
					var child = this.container.firstChild;
					
					while (child != null)
					{
						var next = child.nextSibling;
						
						// SVG element is moved via transform attribute
						if (child != canvas.parentNode)
						{
							current.appendChild(child);
						}
						else
						{
							current = this.shiftPreview2;
						}
						
						child = next;
					}
					
					// Inserts elements only if not empty
					if (this.shiftPreview1.firstChild != null)
					{
						this.container.insertBefore(this.shiftPreview1, canvas.parentNode);
					}
					
					if (this.shiftPreview2.firstChild != null)
					{
						this.container.appendChild(this.shiftPreview2);
					}
				}
				
				this.shiftPreview1.style.left = dx + 'px';
				this.shiftPreview1.style.top = dy + 'px';
				this.shiftPreview2.style.left = dx + 'px';
				this.shiftPreview2.style.top = dy + 'px';
			}
		}
		else
		{
			canvas.style.left = dx + 'px';
			canvas.style.top = dy + 'px';
		}
		
		this.panDx = dx;
		this.panDy = dy;

		this.fireEvent(new mxEventObject(mxEvent.PAN));
	}
};

/**
 * Function: zoomIn
 * 
 * Zooms into the graph by <zoomFactor>.
 */
mxGraph.prototype.zoomIn = function()
{
	this.zoom(this.zoomFactor);
};

/**
 * Function: zoomOut
 * 
 * Zooms out of the graph by <zoomFactor>.
 */
mxGraph.prototype.zoomOut = function()
{
	this.zoom(1 / this.zoomFactor);
};

/**
 * Function: zoomActual
 * 
 * Resets the zoom and panning in the view.
 */
mxGraph.prototype.zoomActual = function()
{
	if (this.view.scale == 1)
	{
		this.view.setTranslate(0, 0);
	}
	else
	{
		this.view.translate.x = 0;
		this.view.translate.y = 0;

		this.view.setScale(1);
	}
};

/**
 * Function: zoomTo
 * 
 * Zooms the graph to the given scale with an optional boolean center
 * argument, which is passd to <zoom>.
 */
mxGraph.prototype.zoomTo = function(scale, center)
{
	this.zoom(scale / this.view.scale, center);
};

/**
 * Function: center
 * 
 * Centers the graph in the container.
 * 
 * Parameters:
 * 
 * horizontal - Optional boolean that specifies if the graph should be centered
 * horizontally. Default is true.
 * vertical - Optional boolean that specifies if the graph should be centered
 * vertically. Default is true.
 * cx - Optional float that specifies the horizontal center. Default is 0.5.
 * cy - Optional float that specifies the vertical center. Default is 0.5.
 */
mxGraph.prototype.center = function(horizontal, vertical, cx, cy)
{
	horizontal = (horizontal != null) ? horizontal : true;
	vertical = (vertical != null) ? vertical : true;
	cx = (cx != null) ? cx : 0.5;
	cy = (cy != null) ? cy : 0.5;
	
	var hasScrollbars = mxUtils.hasScrollbars(this.container);
	var cw = this.container.clientWidth;
	var ch = this.container.clientHeight;
	var bounds = this.getGraphBounds();

	var t = this.view.translate;
	var s = this.view.scale;

	var dx = (horizontal) ? cw - bounds.width : 0;
	var dy = (vertical) ? ch - bounds.height : 0;
	
	if (!hasScrollbars)
	{
		this.view.setTranslate((horizontal) ? Math.floor(t.x - bounds.x * s + dx * cx / s) : t.x,
			(vertical) ? Math.floor(t.y - bounds.y * s + dy * cy / s) : t.y);
	}
	else
	{
		bounds.x -= t.x;
		bounds.y -= t.y;
	
		var sw = this.container.scrollWidth;
		var sh = this.container.scrollHeight;
		
		if (sw > cw)
		{
			dx = 0;
		}
		
		if (sh > ch)
		{
			dy = 0;
		}

		this.view.setTranslate(Math.floor(dx / 2 - bounds.x), Math.floor(dy / 2 - bounds.y));
		this.container.scrollLeft = (sw - cw) / 2;
		this.container.scrollTop = (sh - ch) / 2;
	}
};

/**
 * Function: zoom
 * 
 * Zooms the graph using the given factor. Center is an optional boolean
 * argument that keeps the graph scrolled to the center. If the center argument
 * is omitted, then <centerZoom> will be used as its value.
 */
mxGraph.prototype.zoom = function(factor, center)
{
	center = (center != null) ? center : this.centerZoom;
	var scale = Math.round(this.view.scale * factor * 100) / 100;
	var state = this.view.getState(this.getSelectionCell());
	factor = scale / this.view.scale;
	
	if (this.keepSelectionVisibleOnZoom && state != null)
	{
		var rect = new mxRectangle(state.x * factor, state.y * factor,
			state.width * factor, state.height * factor);
		
		// Refreshes the display only once if a scroll is carried out
		this.view.scale = scale;
		
		if (!this.scrollRectToVisible(rect))
		{
			this.view.revalidate();
			
			// Forces an event to be fired but does not revalidate again
			this.view.setScale(scale);
		}
	}
	else
	{
		var hasScrollbars = mxUtils.hasScrollbars(this.container);
		
		if (center && !hasScrollbars)
		{
			var dx = this.container.offsetWidth;
			var dy = this.container.offsetHeight;
			
			if (factor > 1)
			{
				var f = (factor - 1) / (scale * 2);
				dx *= -f;
				dy *= -f;
			}
			else
			{
				var f = (1 / factor - 1) / (this.view.scale * 2);
				dx *= f;
				dy *= f;
			}

			this.view.scaleAndTranslate(scale,
				this.view.translate.x + dx,
				this.view.translate.y + dy);
		}
		else
		{
			// Allows for changes of translate and scrollbars during setscale
			var tx = this.view.translate.x;
			var ty = this.view.translate.y;
			var sl = this.container.scrollLeft;
			var st = this.container.scrollTop;
			
			this.view.setScale(scale);
			
			if (hasScrollbars)
			{
				var dx = 0;
				var dy = 0;
				
				if (center)
				{
					dx = this.container.offsetWidth * (factor - 1) / 2;
					dy = this.container.offsetHeight * (factor - 1) / 2;
				}
				
				this.container.scrollLeft = (this.view.translate.x - tx) * this.view.scale + Math.round(sl * factor + dx);
				this.container.scrollTop = (this.view.translate.y - ty) * this.view.scale + Math.round(st * factor + dy);
			}
		}
	}
};

/**
 * Function: zoomToRect
 * 
 * Zooms the graph to the specified rectangle. If the rectangle does not have same aspect
 * ratio as the display container, it is increased in the smaller relative dimension only
 * until the aspect match. The original rectangle is centralised within this expanded one.
 * 
 * Note that the input rectangular must be un-scaled and un-translated.
 * 
 * Parameters:
 * 
 * rect - The un-scaled and un-translated rectangluar region that should be just visible 
 * after the operation
 */
mxGraph.prototype.zoomToRect = function(rect)
{
	var scaleX = this.container.clientWidth / rect.width;
	var scaleY = this.container.clientHeight / rect.height;
	var aspectFactor = scaleX / scaleY;

	// Remove any overlap of the rect outside the client area
	rect.x = Math.max(0, rect.x);
	rect.y = Math.max(0, rect.y);
	var rectRight = Math.min(this.container.scrollWidth, rect.x + rect.width);
	var rectBottom = Math.min(this.container.scrollHeight, rect.y + rect.height);
	rect.width = rectRight - rect.x;
	rect.height = rectBottom - rect.y;

	// The selection area has to be increased to the same aspect
	// ratio as the container, centred around the centre point of the 
	// original rect passed in.
	if (aspectFactor < 1.0)
	{
		// Height needs increasing
		var newHeight = rect.height / aspectFactor;
		var deltaHeightBuffer = (newHeight - rect.height) / 2.0;
		rect.height = newHeight;
		
		// Assign up to half the buffer to the upper part of the rect, not crossing 0
		// put the rest on the bottom
		var upperBuffer = Math.min(rect.y , deltaHeightBuffer);
		rect.y = rect.y - upperBuffer;
		
		// Check if the bottom has extended too far
		rectBottom = Math.min(this.container.scrollHeight, rect.y + rect.height);
		rect.height = rectBottom - rect.y;
	}
	else
	{
		// Width needs increasing
		var newWidth = rect.width * aspectFactor;
		var deltaWidthBuffer = (newWidth - rect.width) / 2.0;
		rect.width = newWidth;
		
		// Assign up to half the buffer to the upper part of the rect, not crossing 0
		// put the rest on the bottom
		var leftBuffer = Math.min(rect.x , deltaWidthBuffer);
		rect.x = rect.x - leftBuffer;
		
		// Check if the right hand side has extended too far
		rectRight = Math.min(this.container.scrollWidth, rect.x + rect.width);
		rect.width = rectRight - rect.x;
	}

	var scale = this.container.clientWidth / rect.width;
	var newScale = this.view.scale * scale;

	if (!mxUtils.hasScrollbars(this.container))
	{
		this.view.scaleAndTranslate(newScale, (this.view.translate.x - rect.x / this.view.scale), (this.view.translate.y - rect.y / this.view.scale));
	}
	else
	{
		this.view.setScale(newScale);
		this.container.scrollLeft = Math.round(rect.x * scale);
		this.container.scrollTop = Math.round(rect.y * scale);
	}
};

/**
 * Function: scrollCellToVisible
 * 
 * Pans the graph so that it shows the given cell. Optionally the cell may
 * be centered in the container.
 * 
 * To center a given graph if the <container> has no scrollbars, use the following code.
 * 
 * [code]
 * var bounds = graph.getGraphBounds();
 * graph.view.setTranslate(-bounds.x - (bounds.width - container.clientWidth) / 2,
 * 						   -bounds.y - (bounds.height - container.clientHeight) / 2);
 * [/code]
 * 
 * Parameters:
 * 
 * cell - <mxCell> to be made visible.
 * center - Optional boolean flag. Default is false.
 */
mxGraph.prototype.scrollCellToVisible = function(cell, center)
{
	var x = -this.view.translate.x;
	var y = -this.view.translate.y;

	var state = this.view.getState(cell);

	if (state != null)
	{
		var bounds = new mxRectangle(x + state.x, y + state.y, state.width,
			state.height);

		if (center && this.container != null)
		{
			var w = this.container.clientWidth;
			var h = this.container.clientHeight;

			bounds.x = bounds.getCenterX() - w / 2;
			bounds.width = w;
			bounds.y = bounds.getCenterY() - h / 2;
			bounds.height = h;
		}
		
		var tr = new mxPoint(this.view.translate.x, this.view.translate.y);

		if (this.scrollRectToVisible(bounds))
		{
			// Triggers an update via the view's event source
			var tr2 = new mxPoint(this.view.translate.x, this.view.translate.y);
			this.view.translate.x = tr.x;
			this.view.translate.y = tr.y;
			this.view.setTranslate(tr2.x, tr2.y);
		}
	}
};

/**
 * Function: scrollRectToVisible
 * 
 * Pans the graph so that it shows the given rectangle.
 * 
 * Parameters:
 * 
 * rect - <mxRectangle> to be made visible.
 */
mxGraph.prototype.scrollRectToVisible = function(rect)
{
	var isChanged = false;
	
	if (rect != null)
	{
		var w = this.container.offsetWidth;
		var h = this.container.offsetHeight;

        var widthLimit = Math.min(w, rect.width);
        var heightLimit = Math.min(h, rect.height);

		if (mxUtils.hasScrollbars(this.container))
		{
			var c = this.container;
			rect.x += this.view.translate.x;
			rect.y += this.view.translate.y;
			var dx = c.scrollLeft - rect.x;
			var ddx = Math.max(dx - c.scrollLeft, 0);

			if (dx > 0)
			{
				c.scrollLeft -= dx + 2;
			}
			else
			{
				dx = rect.x + widthLimit - c.scrollLeft - c.clientWidth;

				if (dx > 0)
				{
					c.scrollLeft += dx + 2;
				}
			}

			var dy = c.scrollTop - rect.y;
			var ddy = Math.max(0, dy - c.scrollTop);

			if (dy > 0)
			{
				c.scrollTop -= dy + 2;
			}
			else
			{
				dy = rect.y + heightLimit - c.scrollTop - c.clientHeight;

				if (dy > 0)
				{
					c.scrollTop += dy + 2;
				}
			}

			if (!this.useScrollbarsForPanning && (ddx != 0 || ddy != 0))
			{
				this.view.setTranslate(ddx, ddy);
			}
		}
		else
		{
			var x = -this.view.translate.x;
			var y = -this.view.translate.y;

			var s = this.view.scale;

			if (rect.x + widthLimit > x + w)
			{
				this.view.translate.x -= (rect.x + widthLimit - w - x) / s;
				isChanged = true;
			}

			if (rect.y + heightLimit > y + h)
			{
				this.view.translate.y -= (rect.y + heightLimit - h - y) / s;
				isChanged = true;
			}

			if (rect.x < x)
			{
				this.view.translate.x += (x - rect.x) / s;
				isChanged = true;
			}

			if (rect.y  < y)
			{
				this.view.translate.y += (y - rect.y) / s;
				isChanged = true;
			}

			if (isChanged)
			{
				this.view.refresh();
				
				// Repaints selection marker (ticket 18)
				if (this.selectionCellsHandler != null)
				{
					this.selectionCellsHandler.refresh();
				}
			}
		}
	}

	return isChanged;
};

/**
 * Function: getCellGeometry
 * 
 * Returns the <mxGeometry> for the given cell. This implementation uses
 * <mxGraphModel.getGeometry>. Subclasses can override this to implement
 * specific geometries for cells in only one graph, that is, it can return
 * geometries that depend on the current state of the view.
 * 
 * Parameters:
 * 
 * cell - <mxCell> whose geometry should be returned.
 */
mxGraph.prototype.getCellGeometry = function(cell)
{
	return this.model.getGeometry(cell);
};

/**
 * Function: isCellVisible
 * 
 * Returns true if the given cell is visible in this graph. This
 * implementation uses <mxGraphModel.isVisible>. Subclassers can override
 * this to implement specific visibility for cells in only one graph, that
 * is, without affecting the visible state of the cell.
 * 
 * When using dynamic filter expressions for cell visibility, then the
 * graph should be revalidated after the filter expression has changed.
 * 
 * Parameters:
 * 
 * cell - <mxCell> whose visible state should be returned.
 */
mxGraph.prototype.isCellVisible = function(cell)
{
	return this.model.isVisible(cell);
};

/**
 * Function: isCellCollapsed
 * 
 * Returns true if the given cell is collapsed in this graph. This
 * implementation uses <mxGraphModel.isCollapsed>. Subclassers can override
 * this to implement specific collapsed states for cells in only one graph,
 * that is, without affecting the collapsed state of the cell.
 * 
 * When using dynamic filter expressions for the collapsed state, then the
 * graph should be revalidated after the filter expression has changed.
 * 
 * Parameters:
 * 
 * cell - <mxCell> whose collapsed state should be returned.
 */
mxGraph.prototype.isCellCollapsed = function(cell)
{
	return this.model.isCollapsed(cell);
};

/**
 * Function: isCellConnectable
 * 
 * Returns true if the given cell is connectable in this graph. This
 * implementation uses <mxGraphModel.isConnectable>. Subclassers can override
 * this to implement specific connectable states for cells in only one graph,
 * that is, without affecting the connectable state of the cell in the model.
 * 
 * Parameters:
 * 
 * cell - <mxCell> whose connectable state should be returned.
 */
mxGraph.prototype.isCellConnectable = function(cell)
{
	return this.model.isConnectable(cell);
};

/**
 * Function: isOrthogonal
 * 
 * Returns true if perimeter points should be computed such that the
 * resulting edge has only horizontal or vertical segments.
 * 
 * Parameters:
 * 
 * edge - <mxCellState> that represents the edge.
 */
mxGraph.prototype.isOrthogonal = function(edge)
{
	var orthogonal = edge.style[mxConstants.STYLE_ORTHOGONAL];
	
	if (orthogonal != null)
	{
		return orthogonal;
	}
	
	var tmp = this.view.getEdgeStyle(edge);
	
	return tmp == mxEdgeStyle.SegmentConnector ||
		tmp == mxEdgeStyle.ElbowConnector ||
		tmp == mxEdgeStyle.SideToSide ||
		tmp == mxEdgeStyle.TopToBottom ||
		tmp == mxEdgeStyle.EntityRelation ||
		tmp == mxEdgeStyle.OrthConnector;
};

/**
 * Function: isLoop
 * 
 * Returns true if the given cell state is a loop.
 * 
 * Parameters:
 * 
 * state - <mxCellState> that represents a potential loop.
 */
mxGraph.prototype.isLoop = function(state)
{
	var src = state.getVisibleTerminalState(true);
	var trg = state.getVisibleTerminalState(false);
	
	return (src != null && src == trg);
};

/**
 * Function: isCloneEvent
 * 
 * Returns true if the given event is a clone event. This implementation
 * returns true if control is pressed.
 */
mxGraph.prototype.isCloneEvent = function(evt)
{
	return mxEvent.isControlDown(evt);
};

/**
 * Function: isTransparentClickEvent
 * 
 * Hook for implementing click-through behaviour on selected cells. If this
 * returns true the cell behind the selected cell will be selected. This
 * implementation returns false;
 */
mxGraph.prototype.isTransparentClickEvent = function(evt)
{
	return false;
};

/**
 * Function: isToggleEvent
 * 
 * Returns true if the given event is a toggle event. This implementation
 * returns true if the meta key (Cmd) is pressed on Macs or if control is
 * pressed on any other platform.
 */
mxGraph.prototype.isToggleEvent = function(evt)
{
	return (mxClient.IS_MAC) ? mxEvent.isMetaDown(evt) : mxEvent.isControlDown(evt);
};

/**
 * Function: isGridEnabledEvent
 * 
 * Returns true if the given mouse event should be aligned to the grid.
 */
mxGraph.prototype.isGridEnabledEvent = function(evt)
{
	return evt != null && !mxEvent.isAltDown(evt);
};

/**
 * Function: isConstrainedEvent
 * 
 * Returns true if the given mouse event should be aligned to the grid.
 */
mxGraph.prototype.isConstrainedEvent = function(evt)
{
	return mxEvent.isShiftDown(evt);
};

/**
 * Function: isIgnoreTerminalEvent
 * 
 * Returns true if the given mouse event should not allow any connections to be
 * made. This implementation returns false.
 */
mxGraph.prototype.isIgnoreTerminalEvent = function(evt)
{
	return false;
};

/**
 * Group: Validation
 */

/**
 * Function: validationAlert
 * 
 * Displays the given validation error in a dialog. This implementation uses
 * mxUtils.alert.
 */
mxGraph.prototype.validationAlert = function(message)
{
	mxUtils.alert(message);
};

/**
 * Function: isEdgeValid
 * 
 * Checks if the return value of <getEdgeValidationError> for the given
 * arguments is null.
 *  
 * Parameters:
 * 
 * edge - <mxCell> that represents the edge to validate.
 * source - <mxCell> that represents the source terminal.
 * target - <mxCell> that represents the target terminal.
 */
mxGraph.prototype.isEdgeValid = function(edge, source, target)
{
	return this.getEdgeValidationError(edge, source, target) == null;
};

/**
 * Function: getEdgeValidationError
 * 
 * Returns the validation error message to be displayed when inserting or
 * changing an edges' connectivity. A return value of null means the edge
 * is valid, a return value of '' means it's not valid, but do not display
 * an error message. Any other (non-empty) string returned from this method
 * is displayed as an error message when trying to connect an edge to a
 * source and target. This implementation uses the <multiplicities>, and
 * checks <multigraph>, <allowDanglingEdges> and <allowLoops> to generate
 * validation errors.
 * 
 * For extending this method with specific checks for source/target cells,
 * the method can be extended as follows. Returning an empty string means
 * the edge is invalid with no error message, a non-null string specifies
 * the error message, and null means the edge is valid.
 * 
 * (code)
 * graph.getEdgeValidationError = function(edge, source, target)
 * {
 *   if (source != null && target != null &&
 *     this.model.getValue(source) != null &&
 *     this.model.getValue(target) != null)
 *   {
 *     if (target is not valid for source)
 *     {
 *       return 'Invalid Target';
 *     }
 *   }
 *   
 *   // "Supercall"
 *   return mxGraph.prototype.getEdgeValidationError.apply(this, arguments);
 * }
 * (end)
 *  
 * Parameters:
 * 
 * edge - <mxCell> that represents the edge to validate.
 * source - <mxCell> that represents the source terminal.
 * target - <mxCell> that represents the target terminal.
 */
mxGraph.prototype.getEdgeValidationError = function(edge, source, target)
{
	if (edge != null && !this.isAllowDanglingEdges() && (source == null || target == null))
	{
		return '';
	}
	
	if (edge != null && this.model.getTerminal(edge, true) == null &&
		this.model.getTerminal(edge, false) == null)	
	{
		return null;
	}
	
	// Checks if we're dealing with a loop
	if (!this.allowLoops && source == target && source != null)
	{
		return '';
	}
	
	// Checks if the connection is generally allowed
	if (!this.isValidConnection(source, target))
	{
		return '';
	}

	if (source != null && target != null)
	{
		var error = '';

		// Checks if the cells are already connected
		// and adds an error message if required			
		if (!this.multigraph)
		{
			var tmp = this.model.getEdgesBetween(source, target, true);
			
			// Checks if the source and target are not connected by another edge
			if (tmp.length > 1 || (tmp.length == 1 && tmp[0] != edge))
			{
				error += (mxResources.get(this.alreadyConnectedResource) ||
					this.alreadyConnectedResource)+'\n';
			}
		}

		// Gets the number of outgoing edges from the source
		// and the number of incoming edges from the target
		// without counting the edge being currently changed.
		var sourceOut = this.model.getDirectedEdgeCount(source, true, edge);
		var targetIn = this.model.getDirectedEdgeCount(target, false, edge);

		// Checks the change against each multiplicity rule
		if (this.multiplicities != null)
		{
			for (var i = 0; i < this.multiplicities.length; i++)
			{
				var err = this.multiplicities[i].check(this, edge, source,
					target, sourceOut, targetIn);
				
				if (err != null)
				{
					error += err;
				}
			}
		}

		// Validates the source and target terminals independently
		var err = this.validateEdge(edge, source, target);
		
		if (err != null)
		{
			error += err;
		}
		
		return (error.length > 0) ? error : null;
	}
	
	return (this.allowDanglingEdges) ? null : '';
};

/**
 * Function: validateEdge
 * 
 * Hook method for subclassers to return an error message for the given
 * edge and terminals. This implementation returns null.
 * 
 * Parameters:
 * 
 * edge - <mxCell> that represents the edge to validate.
 * source - <mxCell> that represents the source terminal.
 * target - <mxCell> that represents the target terminal.
 */
mxGraph.prototype.validateEdge = function(edge, source, target)
{
	return null;
};

/**
 * Function: validateGraph
 * 
 * Validates the graph by validating each descendant of the given cell or
 * the root of the model. Context is an object that contains the validation
 * state for the complete validation run. The validation errors are
 * attached to their cells using <setCellWarning>. Returns null in the case of
 * successful validation or an array of strings (warnings) in the case of
 * failed validations.
 * 
 * Paramters:
 * 
 * cell - Optional <mxCell> to start the validation recursion. Default is
 * the graph root.
 * context - Object that represents the global validation state.
 */
mxGraph.prototype.validateGraph = function(cell, context)
{
	cell = (cell != null) ? cell : this.model.getRoot();
	context = (context != null) ? context : new Object();
	
	var isValid = true;
	var childCount = this.model.getChildCount(cell);
	
	for (var i = 0; i < childCount; i++)
	{
		var tmp = this.model.getChildAt(cell, i);
		var ctx = context;
		
		if (this.isValidRoot(tmp))
		{
			ctx = new Object();
		}
		
		var warn = this.validateGraph(tmp, ctx);
		
		if (warn != null)
		{
			this.setCellWarning(tmp, warn.replace(/\n/g, '<br>'));
		}
		else
		{
			this.setCellWarning(tmp, null);
		}
		
		isValid = isValid && warn == null;
	}
	
	var warning = '';
	
	// Adds error for invalid children if collapsed (children invisible)
	if (this.isCellCollapsed(cell) && !isValid)
	{
		warning += (mxResources.get(this.containsValidationErrorsResource) ||
			this.containsValidationErrorsResource) + '\n';
	}
	
	// Checks edges and cells using the defined multiplicities
	if (this.model.isEdge(cell))
	{
		warning += this.getEdgeValidationError(cell,
		this.model.getTerminal(cell, true),
		this.model.getTerminal(cell, false)) || '';
	}
	else
	{
		warning += this.getCellValidationError(cell) || '';
	}
	
	// Checks custom validation rules
	var err = this.validateCell(cell, context);
	
	if (err != null)
	{
		warning += err;
	}
	
	// Updates the display with the warning icons
	// before any potential alerts are displayed.
	// LATER: Move this into addCellOverlay. Redraw
	// should check if overlay was added or removed.
	if (this.model.getParent(cell) == null)
	{
		this.view.validate();
	}

	return (warning.length > 0 || !isValid) ? warning : null;
};

/**
 * Function: getCellValidationError
 * 
 * Checks all <multiplicities> that cannot be enforced while the graph is
 * being modified, namely, all multiplicities that require a minimum of
 * 1 edge.
 * 
 * Parameters:
 * 
 * cell - <mxCell> for which the multiplicities should be checked.
 */
mxGraph.prototype.getCellValidationError = function(cell)
{
	var outCount = this.model.getDirectedEdgeCount(cell, true);
	var inCount = this.model.getDirectedEdgeCount(cell, false);
	var value = this.model.getValue(cell);
	var error = '';

	if (this.multiplicities != null)
	{
		for (var i = 0; i < this.multiplicities.length; i++)
		{
			var rule = this.multiplicities[i];
			
			if (rule.source && mxUtils.isNode(value, rule.type,
				rule.attr, rule.value) && (outCount > rule.max ||
				outCount < rule.min))
			{
				error += rule.countError + '\n';
			}
			else if (!rule.source && mxUtils.isNode(value, rule.type,
					rule.attr, rule.value) && (inCount > rule.max ||
					inCount < rule.min))
			{
				error += rule.countError + '\n';
			}
		}
	}

	return (error.length > 0) ? error : null;
};

/**
 * Function: validateCell
 * 
 * Hook method for subclassers to return an error message for the given
 * cell and validation context. This implementation returns null. Any HTML
 * breaks will be converted to linefeeds in the calling method.
 * 
 * Parameters:
 * 
 * cell - <mxCell> that represents the cell to validate.
 * context - Object that represents the global validation state.
 */
mxGraph.prototype.validateCell = function(cell, context)
{
	return null;
};

/**
 * Group: Graph appearance
 */

/**
 * Function: getBackgroundImage
 * 
 * Returns the <backgroundImage> as an <mxImage>.
 */
mxGraph.prototype.getBackgroundImage = function()
{
	return this.backgroundImage;
};

/**
 * Function: setBackgroundImage
 * 
 * Sets the new <backgroundImage>.
 * 
 * Parameters:
 * 
 * image - New <mxImage> to be used for the background.
 */
mxGraph.prototype.setBackgroundImage = function(image)
{
	this.backgroundImage = image;
};

/**
 * Function: getFoldingImage
 * 
 * Returns the <mxImage> used to display the collapsed state of
 * the specified cell state. This returns null for all edges.
 */
mxGraph.prototype.getFoldingImage = function(state)
{
	if (state != null && this.foldingEnabled && !this.getModel().isEdge(state.cell))
	{
		var tmp = this.isCellCollapsed(state.cell);
		
		if (this.isCellFoldable(state.cell, !tmp))
		{
			return (tmp) ? this.collapsedImage : this.expandedImage;
		}
	}
	
	return null;
};

/**
 * Function: convertValueToString
 * 
 * Returns the textual representation for the given cell. This
 * implementation returns the nodename or string-representation of the user
 * object.
 *
 * Example:
 * 
 * The following returns the label attribute from the cells user
 * object if it is an XML node.
 * 
 * (code)
 * graph.convertValueToString = function(cell)
 * {
 * 	return cell.getAttribute('label');
 * }
 * (end)
 * 
 * See also: <cellLabelChanged>.
 * 
 * Parameters:
 * 
 * cell - <mxCell> whose textual representation should be returned.
 */
mxGraph.prototype.convertValueToString = function(cell)
{
	var value = this.model.getValue(cell);
	
	if (value != null)
	{
		if (mxUtils.isNode(value))
		{
			return value.nodeName;
		}
		else if (typeof(value.toString) == 'function')
		{
			return value.toString();
		}
	}
	
	return '';
};

/**
 * Function: getLabel
 * 
 * Returns a string or DOM node that represents the label for the given
 * cell. This implementation uses <convertValueToString> if <labelsVisible>
 * is true. Otherwise it returns an empty string.
 * 
 * To truncate a label to match the size of the cell, the following code
 * can be used.
 * 
 * (code)
 * graph.getLabel = function(cell)
 * {
 *   var label = mxGraph.prototype.getLabel.apply(this, arguments);
 * 
 *   if (label != null && this.model.isVertex(cell))
 *   {
 *     var geo = this.getCellGeometry(cell);
 * 
 *     if (geo != null)
 *     {
 *       var max = parseInt(geo.width / 8);
 * 
 *       if (label.length > max)
 *       {
 *         label = label.substring(0, max)+'...';
 *       }
 *     }
 *   } 
 *   return mxUtils.htmlEntities(label);
 * }
 * (end)
 * 
 * A resize listener is needed in the graph to force a repaint of the label
 * after a resize.
 * 
 * (code)
 * graph.addListener(mxEvent.RESIZE_CELLS, function(sender, evt)
 * {
 *   var cells = evt.getProperty('cells');
 * 
 *   for (var i = 0; i < cells.length; i++)
 *   {
 *     this.view.removeState(cells[i]);
 *   }
 * });
 * (end)
 * 
 * Parameters:
 * 
 * cell - <mxCell> whose label should be returned.
 */
mxGraph.prototype.getLabel = function(cell)
{
	var result = '';
	
	if (this.labelsVisible && cell != null)
	{
		var state = this.view.getState(cell);
		var style = (state != null) ? state.style : this.getCellStyle(cell);
		
		if (!mxUtils.getValue(style, mxConstants.STYLE_NOLABEL, false))
		{
			result = this.convertValueToString(cell);
		}
	}
	
	return result;
};

/**
 * Function: isHtmlLabel
 * 
 * Returns true if the label must be rendered as HTML markup. The default
 * implementation returns <htmlLabels>.
 * 
 * Parameters:
 * 
 * cell - <mxCell> whose label should be displayed as HTML markup.
 */
mxGraph.prototype.isHtmlLabel = function(cell)
{
	return this.isHtmlLabels();
};
 
/**
 * Function: isHtmlLabels
 * 
 * Returns <htmlLabels>.
 */
mxGraph.prototype.isHtmlLabels = function()
{
	return this.htmlLabels;
};
 
/**
 * Function: setHtmlLabels
 * 
 * Sets <htmlLabels>.
 */
mxGraph.prototype.setHtmlLabels = function(value)
{
	this.htmlLabels = value;
};

/**
 * Function: isWrapping
 * 
 * This enables wrapping for HTML labels.
 * 
 * Returns true if no white-space CSS style directive should be used for
 * displaying the given cells label. This implementation returns true if
 * <mxConstants.STYLE_WHITE_SPACE> in the style of the given cell is 'wrap'.
 * 
 * This is used as a workaround for IE ignoring the white-space directive
 * of child elements if the directive appears in a parent element. It
 * should be overridden to return true if a white-space directive is used
 * in the HTML markup that represents the given cells label. In order for
 * HTML markup to work in labels, <isHtmlLabel> must also return true
 * for the given cell.
 * 
 * Example:
 * 
 * (code)
 * graph.getLabel = function(cell)
 * {
 *   var tmp = mxGraph.prototype.getLabel.apply(this, arguments); // "supercall"
 *   
 *   if (this.model.isEdge(cell))
 *   {
 *     tmp = '<div style="width: 150px; white-space:normal;">'+tmp+'</div>';
 *   }
 *   
 *   return tmp;
 * }
 * 
 * graph.isWrapping = function(state)
 * {
 * 	 return this.model.isEdge(state.cell);
 * }
 * (end)
 * 
 * Makes sure no edge label is wider than 150 pixels, otherwise the content
 * is wrapped. Note: No width must be specified for wrapped vertex labels as
 * the vertex defines the width in its geometry.
 * 
 * Parameters:
 * 
 * state - <mxCell> whose label should be wrapped.
 */
mxGraph.prototype.isWrapping = function(cell)
{
	var state = this.view.getState(cell);
	var style = (state != null) ? state.style : this.getCellStyle(cell);

	return (style != null) ? style[mxConstants.STYLE_WHITE_SPACE] == 'wrap' : false;
};

/**
 * Function: isLabelClipped
 * 
 * Returns true if the overflow portion of labels should be hidden. If this
 * returns true then vertex labels will be clipped to the size of the vertices.
 * This implementation returns true if <mxConstants.STYLE_OVERFLOW> in the
 * style of the given cell is 'hidden'.
 * 
 * Parameters:
 * 
 * state - <mxCell> whose label should be clipped.
 */
mxGraph.prototype.isLabelClipped = function(cell)
{
	var state = this.view.getState(cell);
	var style = (state != null) ? state.style : this.getCellStyle(cell);

	return (style != null) ? style[mxConstants.STYLE_OVERFLOW] == 'hidden' : false;
};

/**
 * Function: getTooltip
 * 
 * Returns the string or DOM node that represents the tooltip for the given
 * state, node and coordinate pair. This implementation checks if the given
 * node is a folding icon or overlay and returns the respective tooltip. If
 * this does not result in a tooltip, the handler for the cell is retrieved
 * from <selectionCellsHandler> and the optional getTooltipForNode method is
 * called. If no special tooltip exists here then <getTooltipForCell> is used
 * with the cell in the given state as the argument to return a tooltip for the
 * given state.
 * 
 * Parameters:
 * 
 * state - <mxCellState> whose tooltip should be returned.
 * node - DOM node that is currently under the mouse.
 * x - X-coordinate of the mouse.
 * y - Y-coordinate of the mouse.
 */
mxGraph.prototype.getTooltip = function(state, node, x, y)
{
	var tip = null;
	
	if (state != null)
	{
		// Checks if the mouse is over the folding icon
		if (state.control != null && (node == state.control.node ||
			node.parentNode == state.control.node))
		{
			tip = this.collapseExpandResource;
			tip = mxUtils.htmlEntities(mxResources.get(tip) || tip).replace(/\\n/g, '<br>');
		}

		if (tip == null && state.overlays != null)
		{
			state.overlays.visit(function(id, shape)
			{
				// LATER: Exit loop if tip is not null
				if (tip == null && (node == shape.node || node.parentNode == shape.node))
				{
					tip = shape.overlay.toString();
				}
			});
		}
		
		if (tip == null)
		{
			var handler = this.selectionCellsHandler.getHandler(state.cell);
			
			if (handler != null && typeof(handler.getTooltipForNode) == 'function')
			{
				tip = handler.getTooltipForNode(node);
			}
		}
		
		if (tip == null)
		{
			tip = this.getTooltipForCell(state.cell);
		}
	}
	
	return tip;
};

/**
 * Function: getTooltipForCell
 * 
 * Returns the string or DOM node to be used as the tooltip for the given
 * cell. This implementation uses the cells getTooltip function if it
 * exists, or else it returns <convertValueToString> for the cell.
 * 
 * Example:
 * 
 * (code)
 * graph.getTooltipForCell = function(cell)
 * {
 *   return 'Hello, World!';
 * }
 * (end)
 * 
 * Replaces all tooltips with the string Hello, World!
 * 
 * Parameters:
 * 
 * cell - <mxCell> whose tooltip should be returned.
 */
mxGraph.prototype.getTooltipForCell = function(cell)
{
	var tip = null;
	
	if (cell != null && cell.getTooltip != null)
	{
		tip = cell.getTooltip();
	}
	else
	{
		tip = this.convertValueToString(cell);
	}
	
	return tip;
};

/**
 * Function: getCursorForMouseEvent
 * 
 * Returns the cursor value to be used for the CSS of the shape for the
 * given event. This implementation calls <getCursorForCell>.
 * 
 * Parameters:
 * 
 * me - <mxMouseEvent> whose cursor should be returned.
 */
mxGraph.prototype.getCursorForMouseEvent = function(me)
{
	return this.getCursorForCell(me.getCell());
};

/**
 * Function: getCursorForCell
 * 
 * Returns the cursor value to be used for the CSS of the shape for the
 * given cell. This implementation returns null.
 * 
 * Parameters:
 * 
 * cell - <mxCell> whose cursor should be returned.
 */
mxGraph.prototype.getCursorForCell = function(cell)
{
	return null;
};

/**
 * Function: getStartSize
 * 
 * Returns the start size of the given swimlane, that is, the width or
 * height of the part that contains the title, depending on the
 * horizontal style. The return value is an <mxRectangle> with either
 * width or height set as appropriate.
 * 
 * Parameters:
 * 
 * swimlane - <mxCell> whose start size should be returned.
 */
mxGraph.prototype.getStartSize = function(swimlane)
{
	var result = new mxRectangle();
	var state = this.view.getState(swimlane);
	var style = (state != null) ? state.style : this.getCellStyle(swimlane);
	
	if (style != null)
	{
		var size = parseInt(mxUtils.getValue(style,
			mxConstants.STYLE_STARTSIZE, mxConstants.DEFAULT_STARTSIZE));
		
		if (mxUtils.getValue(style, mxConstants.STYLE_HORIZONTAL, true))
		{
			result.height = size;
		}
		else
		{
			result.width = size;
		}
	}
	
	return result;
};

/**
 * Function: getImage
 * 
 * Returns the image URL for the given cell state. This implementation
 * returns the value stored under <mxConstants.STYLE_IMAGE> in the cell
 * style.
 * 
 * Parameters:
 * 
 * state - <mxCellState> whose image URL should be returned.
 */
mxGraph.prototype.getImage = function(state)
{
	return (state != null && state.style != null) ? state.style[mxConstants.STYLE_IMAGE] : null;
};

/**
 * Function: getVerticalAlign
 * 
 * Returns the vertical alignment for the given cell state. This
 * implementation returns the value stored under
 * <mxConstants.STYLE_VERTICAL_ALIGN> in the cell style.
 * 
 * Parameters:
 * 
 * state - <mxCellState> whose vertical alignment should be
 * returned.
 */
mxGraph.prototype.getVerticalAlign = function(state)
{
	return (state != null && state.style != null) ?
		(state.style[mxConstants.STYLE_VERTICAL_ALIGN] ||
		mxConstants.ALIGN_MIDDLE) : null;
};

/**
 * Function: getIndicatorColor
 * 
 * Returns the indicator color for the given cell state. This
 * implementation returns the value stored under
 * <mxConstants.STYLE_INDICATOR_COLOR> in the cell style.
 * 
 * Parameters:
 * 
 * state - <mxCellState> whose indicator color should be
 * returned.
 */
mxGraph.prototype.getIndicatorColor = function(state)
{
	return (state != null && state.style != null) ? state.style[mxConstants.STYLE_INDICATOR_COLOR] : null;
};

/**
 * Function: getIndicatorGradientColor
 * 
 * Returns the indicator gradient color for the given cell state. This
 * implementation returns the value stored under
 * <mxConstants.STYLE_INDICATOR_GRADIENTCOLOR> in the cell style.
 * 
 * Parameters:
 * 
 * state - <mxCellState> whose indicator gradient color should be
 * returned.
 */
mxGraph.prototype.getIndicatorGradientColor = function(state)
{
	return (state != null && state.style != null) ? state.style[mxConstants.STYLE_INDICATOR_GRADIENTCOLOR] : null;
};

/**
 * Function: getIndicatorShape
 * 
 * Returns the indicator shape for the given cell state. This
 * implementation returns the value stored under
 * <mxConstants.STYLE_INDICATOR_SHAPE> in the cell style.
 * 
 * Parameters:
 * 
 * state - <mxCellState> whose indicator shape should be returned.
 */
mxGraph.prototype.getIndicatorShape = function(state)
{
	return (state != null && state.style != null) ? state.style[mxConstants.STYLE_INDICATOR_SHAPE] : null;
};

/**
 * Function: getIndicatorImage
 * 
 * Returns the indicator image for the given cell state. This
 * implementation returns the value stored under
 * <mxConstants.STYLE_INDICATOR_IMAGE> in the cell style.
 * 
 * Parameters:
 * 
 * state - <mxCellState> whose indicator image should be returned.
 */
mxGraph.prototype.getIndicatorImage = function(state)
{
	return (state != null && state.style != null) ? state.style[mxConstants.STYLE_INDICATOR_IMAGE] : null;
};

/**
 * Function: getBorder
 * 
 * Returns the value of <border>.
 */
mxGraph.prototype.getBorder = function()
{
	return this.border;
};

/**
 * Function: setBorder
 * 
 * Sets the value of <border>.
 * 
 * Parameters:
 * 
 * value - Positive integer that represents the border to be used.
 */
mxGraph.prototype.setBorder = function(value)
{
	this.border = value;
};

/**
 * Function: isSwimlane
 * 
 * Returns true if the given cell is a swimlane in the graph. A swimlane is
 * a container cell with some specific behaviour. This implementation
 * checks if the shape associated with the given cell is a <mxSwimlane>.
 * 
 * Parameters:
 * 
 * cell - <mxCell> to be checked.
 */
mxGraph.prototype.isSwimlane = function (cell)
{
	if (cell != null)
	{
		if (this.model.getParent(cell) != this.model.getRoot())
		{
			var state = this.view.getState(cell);
			var style = (state != null) ? state.style : this.getCellStyle(cell);

			if (style != null && !this.model.isEdge(cell))
			{
				return style[mxConstants.STYLE_SHAPE] == mxConstants.SHAPE_SWIMLANE;
			}
		}
	}
	
	return false;
};

/**
 * Group: Graph behaviour
 */

/**
 * Function: isResizeContainer
 * 
 * Returns <resizeContainer>.
 */
mxGraph.prototype.isResizeContainer = function()
{
	return this.resizeContainer;
};

/**
 * Function: setResizeContainer
 * 
 * Sets <resizeContainer>.
 * 
 * Parameters:
 * 
 * value - Boolean indicating if the container should be resized.
 */
mxGraph.prototype.setResizeContainer = function(value)
{
	this.resizeContainer = value;
};

/**
 * Function: isEnabled
 * 
 * Returns true if the graph is <enabled>.
 */
mxGraph.prototype.isEnabled = function()
{
	return this.enabled;
};

/**
 * Function: setEnabled
 * 
 * Specifies if the graph should allow any interactions. This
 * implementation updates <enabled>.
 * 
 * Parameters:
 * 
 * value - Boolean indicating if the graph should be enabled.
 */
mxGraph.prototype.setEnabled = function(value)
{
	this.enabled = value;
};

/**
 * Function: isEscapeEnabled
 * 
 * Returns <escapeEnabled>.
 */
mxGraph.prototype.isEscapeEnabled = function()
{
	return this.escapeEnabled;
};

/**
 * Function: setEscapeEnabled
 * 
 * Sets <escapeEnabled>.
 * 
 * Parameters:
 * 
 * enabled - Boolean indicating if escape should be enabled.
 */
mxGraph.prototype.setEscapeEnabled = function(value)
{
	this.escapeEnabled = value;
};

/**
 * Function: isInvokesStopCellEditing
 * 
 * Returns <invokesStopCellEditing>.
 */
mxGraph.prototype.isInvokesStopCellEditing = function()
{
	return this.invokesStopCellEditing;
};

/**
 * Function: setInvokesStopCellEditing
 * 
 * Sets <invokesStopCellEditing>.
 */
mxGraph.prototype.setInvokesStopCellEditing = function(value)
{
	this.invokesStopCellEditing = value;
};

/**
 * Function: isEnterStopsCellEditing
 * 
 * Returns <enterStopsCellEditing>.
 */
mxGraph.prototype.isEnterStopsCellEditing = function()
{
	return this.enterStopsCellEditing;
};

/**
 * Function: setEnterStopsCellEditing
 * 
 * Sets <enterStopsCellEditing>.
 */
mxGraph.prototype.setEnterStopsCellEditing = function(value)
{
	this.enterStopsCellEditing = value;
};

/**
 * Function: isCellLocked
 * 
 * Returns true if the given cell may not be moved, sized, bended,
 * disconnected, edited or selected. This implementation returns true for
 * all vertices with a relative geometry if <locked> is false.
 * 
 * Parameters:
 * 
 * cell - <mxCell> whose locked state should be returned.
 */
mxGraph.prototype.isCellLocked = function(cell)
{
	var geometry = this.model.getGeometry(cell);
	
	return this.isCellsLocked() || (geometry != null && this.model.isVertex(cell) && geometry.relative);
};

/**
 * Function: isCellsLocked
 * 
 * Returns true if the given cell may not be moved, sized, bended,
 * disconnected, edited or selected. This implementation returns true for
 * all vertices with a relative geometry if <locked> is false.
 * 
 * Parameters:
 * 
 * cell - <mxCell> whose locked state should be returned.
 */
mxGraph.prototype.isCellsLocked = function()
{
	return this.cellsLocked;
};

/**
 * Function: setLocked
 * 
 * Sets if any cell may be moved, sized, bended, disconnected, edited or
 * selected.
 * 
 * Parameters:
 * 
 * value - Boolean that defines the new value for <cellsLocked>.
 */
mxGraph.prototype.setCellsLocked = function(value)
{
	this.cellsLocked = value;
};

/**
 * Function: getCloneableCells
 * 
 * Returns the cells which may be exported in the given array of cells.
 */
mxGraph.prototype.getCloneableCells = function(cells)
{
	return this.model.filterCells(cells, mxUtils.bind(this, function(cell)
	{
		return this.isCellCloneable(cell);
	}));
};

/**
 * Function: isCellCloneable
 * 
 * Returns true if the given cell is cloneable. This implementation returns
 * <isCellsCloneable> for all cells unless a cell style specifies
 * <mxConstants.STYLE_CLONEABLE> to be 0. 
 * 
 * Parameters:
 * 
 * cell - Optional <mxCell> whose cloneable state should be returned.
 */
mxGraph.prototype.isCellCloneable = function(cell)
{
	var state = this.view.getState(cell);
	var style = (state != null) ? state.style : this.getCellStyle(cell);

	return this.isCellsCloneable() && style[mxConstants.STYLE_CLONEABLE] != 0;
};

/**
 * Function: isCellsCloneable
 * 
 * Returns <cellsCloneable>, that is, if the graph allows cloning of cells
 * by using control-drag.
 */
mxGraph.prototype.isCellsCloneable = function()
{
	return this.cellsCloneable;
};

/**
 * Function: setCellsCloneable
 * 
 * Specifies if the graph should allow cloning of cells by holding down the
 * control key while cells are being moved. This implementation updates
 * <cellsCloneable>.
 * 
 * Parameters:
 * 
 * value - Boolean indicating if the graph should be cloneable.
 */
mxGraph.prototype.setCellsCloneable = function(value)
{
	this.cellsCloneable = value;
};

/**
 * Function: getExportableCells
 * 
 * Returns the cells which may be exported in the given array of cells.
 */
mxGraph.prototype.getExportableCells = function(cells)
{
	return this.model.filterCells(cells, mxUtils.bind(this, function(cell)
	{
		return this.canExportCell(cell);
	}));
};

/**
 * Function: canExportCell
 * 
 * Returns true if the given cell may be exported to the clipboard. This
 * implementation returns <exportEnabled> for all cells.
 * 
 * Parameters:
 * 
 * cell - <mxCell> that represents the cell to be exported.
 */
mxGraph.prototype.canExportCell = function(cell)
{
	return this.exportEnabled;
};

/**
 * Function: getImportableCells
 * 
 * Returns the cells which may be imported in the given array of cells.
 */
mxGraph.prototype.getImportableCells = function(cells)
{
	return this.model.filterCells(cells, mxUtils.bind(this, function(cell)
	{
		return this.canImportCell(cell);
	}));
};

/**
 * Function: canImportCell
 * 
 * Returns true if the given cell may be imported from the clipboard.
 * This implementation returns <importEnabled> for all cells.
 * 
 * Parameters:
 * 
 * cell - <mxCell> that represents the cell to be imported.
 */
mxGraph.prototype.canImportCell = function(cell)
{
	return this.importEnabled;
};

/**
 * Function: isCellSelectable
 *
 * Returns true if the given cell is selectable. This implementation
 * returns <cellsSelectable>.
 * 
 * To add a new style for making cells (un)selectable, use the following code.
 * 
 * (code)
 * mxGraph.prototype.isCellSelectable = function(cell)
 * {
 *   var state = this.view.getState(cell);
 *   var style = (state != null) ? state.style : this.getCellStyle(cell);
 *   
 *   return this.isCellsSelectable() && !this.isCellLocked(cell) && style['selectable'] != 0;
 * };
 * (end)
 * 
 * You can then use the new style as shown in this example.
 * 
 * (code)
 * graph.insertVertex(parent, null, 'Hello,', 20, 20, 80, 30, 'selectable=0');
 * (end)
 * 
 * Parameters:
 * 
 * cell - <mxCell> whose selectable state should be returned.
 */
mxGraph.prototype.isCellSelectable = function(cell)
{
	return this.isCellsSelectable();
};

/**
 * Function: isCellsSelectable
 *
 * Returns <cellsSelectable>.
 */
mxGraph.prototype.isCellsSelectable = function()
{
	return this.cellsSelectable;
};

/**
 * Function: setCellsSelectable
 *
 * Sets <cellsSelectable>.
 */
mxGraph.prototype.setCellsSelectable = function(value)
{
	this.cellsSelectable = value;
};

/**
 * Function: getDeletableCells
 * 
 * Returns the cells which may be exported in the given array of cells.
 */
mxGraph.prototype.getDeletableCells = function(cells)
{
	return this.model.filterCells(cells, mxUtils.bind(this, function(cell)
	{
		return this.isCellDeletable(cell);
	}));
};

/**
 * Function: isCellDeletable
 *
 * Returns true if the given cell is moveable. This returns
 * <cellsDeletable> for all given cells if a cells style does not specify
 * <mxConstants.STYLE_DELETABLE> to be 0.
 * 
 * Parameters:
 * 
 * cell - <mxCell> whose deletable state should be returned.
 */
mxGraph.prototype.isCellDeletable = function(cell)
{
	var state = this.view.getState(cell);
	var style = (state != null) ? state.style : this.getCellStyle(cell);
	
	return this.isCellsDeletable() && style[mxConstants.STYLE_DELETABLE] != 0;
};

/**
 * Function: isCellsDeletable
 *
 * Returns <cellsDeletable>.
 */
mxGraph.prototype.isCellsDeletable = function()
{
	return this.cellsDeletable;
};

/**
 * Function: setCellsDeletable
 * 
 * Sets <cellsDeletable>.
 * 
 * Parameters:
 * 
 * value - Boolean indicating if the graph should allow deletion of cells.
 */
mxGraph.prototype.setCellsDeletable = function(value)
{
	this.cellsDeletable = value;
};

/**
 * Function: isLabelMovable
 *
 * Returns true if the given edges's label is moveable. This returns
 * <movable> for all given cells if <isLocked> does not return true
 * for the given cell.
 * 
 * Parameters:
 * 
 * cell - <mxCell> whose label should be moved.
 */
mxGraph.prototype.isLabelMovable = function(cell)
{
	return !this.isCellLocked(cell) &&
		((this.model.isEdge(cell) && this.edgeLabelsMovable) ||
		(this.model.isVertex(cell) && this.vertexLabelsMovable));
};

/**
 * Function: isCellRotatable
 *
 * Returns true if the given cell is rotatable. This returns true for the given
 * cell if its style does not specify <mxConstants.STYLE_ROTATABLE> to be 0.
 * 
 * Parameters:
 * 
 * cell - <mxCell> whose rotatable state should be returned.
 */
mxGraph.prototype.isCellRotatable = function(cell)
{
	var state = this.view.getState(cell);
	var style = (state != null) ? state.style : this.getCellStyle(cell);
	
	return style[mxConstants.STYLE_ROTATABLE] != 0;
};

/**
 * Function: getMovableCells
 * 
 * Returns the cells which are movable in the given array of cells.
 */
mxGraph.prototype.getMovableCells = function(cells)
{
	return this.model.filterCells(cells, mxUtils.bind(this, function(cell)
	{
		return this.isCellMovable(cell);
	}));
};

/**
 * Function: isCellMovable
 *
 * Returns true if the given cell is moveable. This returns <cellsMovable>
 * for all given cells if <isCellLocked> does not return true for the given
 * cell and its style does not specify <mxConstants.STYLE_MOVABLE> to be 0.
 * 
 * Parameters:
 * 
 * cell - <mxCell> whose movable state should be returned.
 */
mxGraph.prototype.isCellMovable = function(cell)
{
	var state = this.view.getState(cell);
	var style = (state != null) ? state.style : this.getCellStyle(cell);
	
	return this.isCellsMovable() && !this.isCellLocked(cell) && style[mxConstants.STYLE_MOVABLE] != 0;
};

/**
 * Function: isCellsMovable
 *
 * Returns <cellsMovable>.
 */
mxGraph.prototype.isCellsMovable = function()
{
	return this.cellsMovable;
};

/**
 * Function: setCellsMovable
 * 
 * Specifies if the graph should allow moving of cells. This implementation
 * updates <cellsMsovable>.
 * 
 * Parameters:
 * 
 * value - Boolean indicating if the graph should allow moving of cells.
 */
mxGraph.prototype.setCellsMovable = function(value)
{
	this.cellsMovable = value;
};

/**
 * Function: isGridEnabled
 *
 * Returns <gridEnabled> as a boolean.
 */
mxGraph.prototype.isGridEnabled = function()
{
	return this.gridEnabled;
};

/**
 * Function: setGridEnabled
 * 
 * Specifies if the grid should be enabled.
 * 
 * Parameters:
 * 
 * value - Boolean indicating if the grid should be enabled.
 */
mxGraph.prototype.setGridEnabled = function(value)
{
	this.gridEnabled = value;
};

/**
 * Function: isPortsEnabled
 *
 * Returns <portsEnabled> as a boolean.
 */
mxGraph.prototype.isPortsEnabled = function()
{
	return this.portsEnabled;
};

/**
 * Function: setPortsEnabled
 * 
 * Specifies if the ports should be enabled.
 * 
 * Parameters:
 * 
 * value - Boolean indicating if the ports should be enabled.
 */
mxGraph.prototype.setPortsEnabled = function(value)
{
	this.portsEnabled = value;
};

/**
 * Function: getGridSize
 *
 * Returns <gridSize>.
 */
mxGraph.prototype.getGridSize = function()
{
	return this.gridSize;
};

/**
 * Function: setGridSize
 * 
 * Sets <gridSize>.
 */
mxGraph.prototype.setGridSize = function(value)
{
	this.gridSize = value;
};

/**
 * Function: getTolerance
 *
 * Returns <tolerance>.
 */
mxGraph.prototype.getTolerance = function()
{
	return this.tolerance;
};

/**
 * Function: setTolerance
 * 
 * Sets <tolerance>.
 */
mxGraph.prototype.setTolerance = function(value)
{
	this.tolerance = value;
};

/**
 * Function: isVertexLabelsMovable
 *
 * Returns <vertexLabelsMovable>.
 */
mxGraph.prototype.isVertexLabelsMovable = function()
{
	return this.vertexLabelsMovable;
};

/**
 * Function: setVertexLabelsMovable
 * 
 * Sets <vertexLabelsMovable>.
 */
mxGraph.prototype.setVertexLabelsMovable = function(value)
{
	this.vertexLabelsMovable = value;
};

/**
 * Function: isEdgeLabelsMovable
 *
 * Returns <edgeLabelsMovable>.
 */
mxGraph.prototype.isEdgeLabelsMovable = function()
{
	return this.edgeLabelsMovable;
};

/**
 * Function: isEdgeLabelsMovable
 * 
 * Sets <edgeLabelsMovable>.
 */
mxGraph.prototype.setEdgeLabelsMovable = function(value)
{
	this.edgeLabelsMovable = value;
};

/**
 * Function: isSwimlaneNesting
 *
 * Returns <swimlaneNesting> as a boolean.
 */
mxGraph.prototype.isSwimlaneNesting = function()
{
	return this.swimlaneNesting;
};

/**
 * Function: setSwimlaneNesting
 * 
 * Specifies if swimlanes can be nested by drag and drop. This is only
 * taken into account if dropEnabled is true.
 * 
 * Parameters:
 * 
 * value - Boolean indicating if swimlanes can be nested.
 */
mxGraph.prototype.setSwimlaneNesting = function(value)
{
	this.swimlaneNesting = value;
};

/**
 * Function: isSwimlaneSelectionEnabled
 *
 * Returns <swimlaneSelectionEnabled> as a boolean.
 */
mxGraph.prototype.isSwimlaneSelectionEnabled = function()
{
	return this.swimlaneSelectionEnabled;
};

/**
 * Function: setSwimlaneSelectionEnabled
 * 
 * Specifies if swimlanes should be selected if the mouse is released
 * over their content area.
 * 
 * Parameters:
 * 
 * value - Boolean indicating if swimlanes content areas
 * should be selected when the mouse is released over them.
 */
mxGraph.prototype.setSwimlaneSelectionEnabled = function(value)
{
	this.swimlaneSelectionEnabled = value;
};

/**
 * Function: isMultigraph
 *
 * Returns <multigraph> as a boolean.
 */
mxGraph.prototype.isMultigraph = function()
{
	return this.multigraph;
};

/**
 * Function: setMultigraph
 * 
 * Specifies if the graph should allow multiple connections between the
 * same pair of vertices.
 * 
 * Parameters:
 * 
 * value - Boolean indicating if the graph allows multiple connections
 * between the same pair of vertices.
 */
mxGraph.prototype.setMultigraph = function(value)
{
	this.multigraph = value;
};

/**
 * Function: isAllowLoops
 *
 * Returns <allowLoops> as a boolean.
 */
mxGraph.prototype.isAllowLoops = function()
{
	return this.allowLoops;
};

/**
 * Function: setAllowDanglingEdges
 * 
 * Specifies if dangling edges are allowed, that is, if edges are allowed
 * that do not have a source and/or target terminal defined.
 * 
 * Parameters:
 * 
 * value - Boolean indicating if dangling edges are allowed.
 */
mxGraph.prototype.setAllowDanglingEdges = function(value)
{
	this.allowDanglingEdges = value;
};

/**
 * Function: isAllowDanglingEdges
 *
 * Returns <allowDanglingEdges> as a boolean.
 */
mxGraph.prototype.isAllowDanglingEdges = function()
{
	return this.allowDanglingEdges;
};

/**
 * Function: setConnectableEdges
 * 
 * Specifies if edges should be connectable.
 * 
 * Parameters:
 * 
 * value - Boolean indicating if edges should be connectable.
 */
mxGraph.prototype.setConnectableEdges = function(value)
{
	this.connectableEdges = value;
};

/**
 * Function: isConnectableEdges
 *
 * Returns <connectableEdges> as a boolean.
 */
mxGraph.prototype.isConnectableEdges = function()
{
	return this.connectableEdges;
};

/**
 * Function: setCloneInvalidEdges
 * 
 * Specifies if edges should be inserted when cloned but not valid wrt.
 * <getEdgeValidationError>. If false such edges will be silently ignored.
 * 
 * Parameters:
 * 
 * value - Boolean indicating if cloned invalid edges should be
 * inserted into the graph or ignored.
 */
mxGraph.prototype.setCloneInvalidEdges = function(value)
{
	this.cloneInvalidEdges = value;
};

/**
 * Function: isCloneInvalidEdges
 *
 * Returns <cloneInvalidEdges> as a boolean.
 */
mxGraph.prototype.isCloneInvalidEdges = function()
{
	return this.cloneInvalidEdges;
};

/**
 * Function: setAllowLoops
 * 
 * Specifies if loops are allowed.
 * 
 * Parameters:
 * 
 * value - Boolean indicating if loops are allowed.
 */
mxGraph.prototype.setAllowLoops = function(value)
{
	this.allowLoops = value;
};

/**
 * Function: isDisconnectOnMove
 *
 * Returns <disconnectOnMove> as a boolean.
 */
mxGraph.prototype.isDisconnectOnMove = function()
{
	return this.disconnectOnMove;
};

/**
 * Function: setDisconnectOnMove
 * 
 * Specifies if edges should be disconnected when moved. (Note: Cloned
 * edges are always disconnected.)
 * 
 * Parameters:
 * 
 * value - Boolean indicating if edges should be disconnected
 * when moved.
 */
mxGraph.prototype.setDisconnectOnMove = function(value)
{
	this.disconnectOnMove = value;
};

/**
 * Function: isDropEnabled
 *
 * Returns <dropEnabled> as a boolean.
 */
mxGraph.prototype.isDropEnabled = function()
{
	return this.dropEnabled;
};

/**
 * Function: setDropEnabled
 * 
 * Specifies if the graph should allow dropping of cells onto or into other
 * cells.
 * 
 * Parameters:
 * 
 * dropEnabled - Boolean indicating if the graph should allow dropping
 * of cells into other cells.
 */
mxGraph.prototype.setDropEnabled = function(value)
{
	this.dropEnabled = value;
};

/**
 * Function: isSplitEnabled
 *
 * Returns <splitEnabled> as a boolean.
 */
mxGraph.prototype.isSplitEnabled = function()
{
	return this.splitEnabled;
};

/**
 * Function: setSplitEnabled
 * 
 * Specifies if the graph should allow dropping of cells onto or into other
 * cells.
 * 
 * Parameters:
 * 
 * dropEnabled - Boolean indicating if the graph should allow dropping
 * of cells into other cells.
 */
mxGraph.prototype.setSplitEnabled = function(value)
{
	this.splitEnabled = value;
};

/**
 * Function: isCellResizable
 *
 * Returns true if the given cell is resizable. This returns
 * <cellsResizable> for all given cells if <isCellLocked> does not return
 * true for the given cell and its style does not specify
 * <mxConstants.STYLE_RESIZABLE> to be 0.
 * 
 * Parameters:
 * 
 * cell - <mxCell> whose resizable state should be returned.
 */
mxGraph.prototype.isCellResizable = function(cell)
{
	var state = this.view.getState(cell);
	var style = (state != null) ? state.style : this.getCellStyle(cell);

	return this.isCellsResizable() && !this.isCellLocked(cell) &&
		mxUtils.getValue(style, mxConstants.STYLE_RESIZABLE, '1') != '0';
};

/**
 * Function: isCellsResizable
 *
 * Returns <cellsResizable>.
 */
mxGraph.prototype.isCellsResizable = function()
{
	return this.cellsResizable;
};

/**
 * Function: setCellsResizable
 * 
 * Specifies if the graph should allow resizing of cells. This
 * implementation updates <cellsResizable>.
 * 
 * Parameters:
 * 
 * value - Boolean indicating if the graph should allow resizing of
 * cells.
 */
mxGraph.prototype.setCellsResizable = function(value)
{
	this.cellsResizable = value;
};

/**
 * Function: isTerminalPointMovable
 *
 * Returns true if the given terminal point is movable. This is independent
 * from <isCellConnectable> and <isCellDisconnectable> and controls if terminal
 * points can be moved in the graph if the edge is not connected. Note that it
 * is required for this to return true to connect unconnected edges. This
 * implementation returns true.
 * 
 * Parameters:
 * 
 * cell - <mxCell> whose terminal point should be moved.
 * source - Boolean indicating if the source or target terminal should be moved.
 */
mxGraph.prototype.isTerminalPointMovable = function(cell, source)
{
	return true;
};

/**
 * Function: isCellBendable
 *
 * Returns true if the given cell is bendable. This returns <cellsBendable>
 * for all given cells if <isLocked> does not return true for the given
 * cell and its style does not specify <mxConstants.STYLE_BENDABLE> to be 0.
 * 
 * Parameters:
 * 
 * cell - <mxCell> whose bendable state should be returned.
 */
mxGraph.prototype.isCellBendable = function(cell)
{
	var state = this.view.getState(cell);
	var style = (state != null) ? state.style : this.getCellStyle(cell);
	
	return this.isCellsBendable() && !this.isCellLocked(cell) && style[mxConstants.STYLE_BENDABLE] != 0;
};

/**
 * Function: isCellsBendable
 *
 * Returns <cellsBenadable>.
 */
mxGraph.prototype.isCellsBendable = function()
{
	return this.cellsBendable;
};

/**
 * Function: setCellsBendable
 * 
 * Specifies if the graph should allow bending of edges. This
 * implementation updates <bendable>.
 * 
 * Parameters:
 * 
 * value - Boolean indicating if the graph should allow bending of
 * edges.
 */
mxGraph.prototype.setCellsBendable = function(value)
{
	this.cellsBendable = value;
};

/**
 * Function: isCellEditable
 *
 * Returns true if the given cell is editable. This returns <cellsEditable> for
 * all given cells if <isCellLocked> does not return true for the given cell
 * and its style does not specify <mxConstants.STYLE_EDITABLE> to be 0.
 * 
 * Parameters:
 * 
 * cell - <mxCell> whose editable state should be returned.
 */
mxGraph.prototype.isCellEditable = function(cell)
{
	var state = this.view.getState(cell);
	var style = (state != null) ? state.style : this.getCellStyle(cell);
	
	return this.isCellsEditable() && !this.isCellLocked(cell) && style[mxConstants.STYLE_EDITABLE] != 0;
};

/**
 * Function: isCellsEditable
 *
 * Returns <cellsEditable>.
 */
mxGraph.prototype.isCellsEditable = function()
{
	return this.cellsEditable;
};

/**
 * Function: setCellsEditable
 * 
 * Specifies if the graph should allow in-place editing for cell labels.
 * This implementation updates <cellsEditable>.
 * 
 * Parameters:
 * 
 * value - Boolean indicating if the graph should allow in-place
 * editing.
 */
mxGraph.prototype.setCellsEditable = function(value)
{
	this.cellsEditable = value;
};

/**
 * Function: isCellDisconnectable
 *
 * Returns true if the given cell is disconnectable from the source or
 * target terminal. This returns <isCellsDisconnectable> for all given
 * cells if <isCellLocked> does not return true for the given cell.
 * 
 * Parameters:
 * 
 * cell - <mxCell> whose disconnectable state should be returned.
 * terminal - <mxCell> that represents the source or target terminal.
 * source - Boolean indicating if the source or target terminal is to be
 * disconnected.
 */
mxGraph.prototype.isCellDisconnectable = function(cell, terminal, source)
{
	return this.isCellsDisconnectable() && !this.isCellLocked(cell);
};

/**
 * Function: isCellsDisconnectable
 *
 * Returns <cellsDisconnectable>.
 */
mxGraph.prototype.isCellsDisconnectable = function()
{
	return this.cellsDisconnectable;
};

/**
 * Function: setCellsDisconnectable
 *
 * Sets <cellsDisconnectable>.
 */
mxGraph.prototype.setCellsDisconnectable = function(value)
{
	this.cellsDisconnectable = value;
};

/**
 * Function: isValidSource
 * 
 * Returns true if the given cell is a valid source for new connections.
 * This implementation returns true for all non-null values and is
 * called by is called by <isValidConnection>.
 * 
 * Parameters:
 * 
 * cell - <mxCell> that represents a possible source or null.
 */
mxGraph.prototype.isValidSource = function(cell)
{
	return (cell == null && this.allowDanglingEdges) ||
		(cell != null && (!this.model.isEdge(cell) ||
		this.connectableEdges) && this.isCellConnectable(cell));
};
	
/**
 * Function: isValidTarget
 * 
 * Returns <isValidSource> for the given cell. This is called by
 * <isValidConnection>.
 * 
 * Parameters:
 * 
 * cell - <mxCell> that represents a possible target or null.
 */
mxGraph.prototype.isValidTarget = function(cell)
{
	return this.isValidSource(cell);
};

/**
 * Function: isValidConnection
 * 
 * Returns true if the given target cell is a valid target for source.
 * This is a boolean implementation for not allowing connections between
 * certain pairs of vertices and is called by <getEdgeValidationError>.
 * This implementation returns true if <isValidSource> returns true for
 * the source and <isValidTarget> returns true for the target.
 * 
 * Parameters:
 * 
 * source - <mxCell> that represents the source cell.
 * target - <mxCell> that represents the target cell.
 */
mxGraph.prototype.isValidConnection = function(source, target)
{
	return this.isValidSource(source) && this.isValidTarget(target);
};

/**
 * Function: setConnectable
 * 
 * Specifies if the graph should allow new connections. This implementation
 * updates <mxConnectionHandler.enabled> in <connectionHandler>.
 * 
 * Parameters:
 * 
 * connectable - Boolean indicating if new connections should be allowed.
 */
mxGraph.prototype.setConnectable = function(connectable)
{
	this.connectionHandler.setEnabled(connectable);
};
	
/**
 * Function: isConnectable
 * 
 * Returns true if the <connectionHandler> is enabled.
 */
mxGraph.prototype.isConnectable = function(connectable)
{
	return this.connectionHandler.isEnabled();
};

/**
 * Function: setTooltips
 * 
 * Specifies if tooltips should be enabled. This implementation updates
 * <mxTooltipHandler.enabled> in <tooltipHandler>.
 * 
 * Parameters:
 * 
 * enabled - Boolean indicating if tooltips should be enabled.
 */
mxGraph.prototype.setTooltips = function (enabled)
{
	this.tooltipHandler.setEnabled(enabled);
};

/**
 * Function: setPanning
 * 
 * Specifies if panning should be enabled. This implementation updates
 * <mxPanningHandler.panningEnabled> in <panningHandler>.
 * 
 * Parameters:
 * 
 * enabled - Boolean indicating if panning should be enabled.
 */
mxGraph.prototype.setPanning = function(enabled)
{
	this.panningHandler.panningEnabled = enabled;
};

/**
 * Function: isEditing
 * 
 * Returns true if the given cell is currently being edited.
 * If no cell is specified then this returns true if any
 * cell is currently being edited.
 *
 * Parameters:
 * 
 * cell - <mxCell> that should be checked.
 */
mxGraph.prototype.isEditing = function(cell)
{
	if (this.cellEditor != null)
	{
		var editingCell = this.cellEditor.getEditingCell();
		
		return (cell == null) ? editingCell != null : cell == editingCell;
	}
	
	return false;
};

/**
 * Function: isAutoSizeCell
 * 
 * Returns true if the size of the given cell should automatically be
 * updated after a change of the label. This implementation returns
 * <autoSizeCells> or checks if the cell style does specify
 * <mxConstants.STYLE_AUTOSIZE> to be 1.
 * 
 * Parameters:
 * 
 * cell - <mxCell> that should be resized.
 */
mxGraph.prototype.isAutoSizeCell = function(cell)
{
	var state = this.view.getState(cell);
	var style = (state != null) ? state.style : this.getCellStyle(cell);
	
	return this.isAutoSizeCells() || style[mxConstants.STYLE_AUTOSIZE] == 1;
};

/**
 * Function: isAutoSizeCells
 * 
 * Returns <autoSizeCells>.
 */
mxGraph.prototype.isAutoSizeCells = function()
{
	return this.autoSizeCells;
};

/**
 * Function: setAutoSizeCells
 * 
 * Specifies if cell sizes should be automatically updated after a label
 * change. This implementation sets <autoSizeCells> to the given parameter.
 * To update the size of cells when the cells are added, set
 * <autoSizeCellsOnAdd> to true.
 * 
 * Parameters:
 * 
 * value - Boolean indicating if cells should be resized
 * automatically.
 */
mxGraph.prototype.setAutoSizeCells = function(value)
{
	this.autoSizeCells = value;
};

/**
 * Function: isExtendParent
 * 
 * Returns true if the parent of the given cell should be extended if the
 * child has been resized so that it overlaps the parent. This
 * implementation returns <isExtendParents> if the cell is not an edge.
 * 
 * Parameters:
 * 
 * cell - <mxCell> that has been resized.
 */
mxGraph.prototype.isExtendParent = function(cell)
{
	return !this.getModel().isEdge(cell) && this.isExtendParents();
};

/**
 * Function: isExtendParents
 * 
 * Returns <extendParents>.
 */
mxGraph.prototype.isExtendParents = function()
{
	return this.extendParents;
};

/**
 * Function: setExtendParents
 * 
 * Sets <extendParents>.
 * 
 * Parameters:
 * 
 * value - New boolean value for <extendParents>.
 */
mxGraph.prototype.setExtendParents = function(value)
{
	this.extendParents = value;
};

/**
 * Function: isExtendParentsOnAdd
 * 
 * Returns <extendParentsOnAdd>.
 */
mxGraph.prototype.isExtendParentsOnAdd = function(cell)
{
	return this.extendParentsOnAdd;
};

/**
 * Function: setExtendParentsOnAdd
 * 
 * Sets <extendParentsOnAdd>.
 * 
 * Parameters:
 * 
 * value - New boolean value for <extendParentsOnAdd>.
 */
mxGraph.prototype.setExtendParentsOnAdd = function(value)
{
	this.extendParentsOnAdd = value;
};

/**
 * Function: isExtendParentsOnMove
 * 
 * Returns <extendParentsOnMove>.
 */
mxGraph.prototype.isExtendParentsOnMove = function()
{
	return this.extendParentsOnMove;
};

/**
 * Function: setExtendParentsOnMove
 * 
 * Sets <extendParentsOnMove>.
 * 
 * Parameters:
 * 
 * value - New boolean value for <extendParentsOnAdd>.
 */
mxGraph.prototype.setExtendParentsOnMove = function(value)
{
	this.extendParentsOnMove = value;
};

/**
 * Function: isRecursiveResize
 * 
 * Returns <recursiveResize>.
 * 
 * Parameters:
 * 
 * state - <mxCellState> that is being resized.
 */
mxGraph.prototype.isRecursiveResize = function(state)
{
	return this.recursiveResize;
};

/**
 * Function: setRecursiveResize
 * 
 * Sets <recursiveResize>.
 * 
 * Parameters:
 * 
 * value - New boolean value for <recursiveResize>.
 */
mxGraph.prototype.setRecursiveResize = function(value)
{
	this.recursiveResize = value;
};

/**
 * Function: isConstrainChild
 * 
 * Returns true if the given cell should be kept inside the bounds of its
 * parent according to the rules defined by <getOverlap> and
 * <isAllowOverlapParent>. This implementation returns false for all children
 * of edges and <isConstrainChildren> otherwise.
 * 
 * Parameters:
 * 
 * cell - <mxCell> that should be constrained.
 */
mxGraph.prototype.isConstrainChild = function(cell)
{
	return this.isConstrainChildren() && !this.getModel().isEdge(this.getModel().getParent(cell));
};

/**
 * Function: isConstrainChildren
 * 
 * Returns <constrainChildren>.
 */
mxGraph.prototype.isConstrainChildren = function()
{
	return this.constrainChildren;
};

/**
 * Function: setConstrainChildren
 * 
 * Sets <constrainChildren>.
 */
mxGraph.prototype.setConstrainChildren = function(value)
{
	this.constrainChildren = value;
};

/**
 * Function: isConstrainRelativeChildren
 * 
 * Returns <constrainRelativeChildren>.
 */
mxGraph.prototype.isConstrainRelativeChildren = function()
{
	return this.constrainRelativeChildren;
};

/**
 * Function: setConstrainRelativeChildren
 * 
 * Sets <constrainRelativeChildren>.
 */
mxGraph.prototype.setConstrainRelativeChildren = function(value)
{
	this.constrainRelativeChildren = value;
};

/**
 * Function: isConstrainChildren
 * 
 * Returns <allowNegativeCoordinates>.
 */
mxGraph.prototype.isAllowNegativeCoordinates = function()
{
	return this.allowNegativeCoordinates;
};

/**
 * Function: setConstrainChildren
 * 
 * Sets <allowNegativeCoordinates>.
 */
mxGraph.prototype.setAllowNegativeCoordinates = function(value)
{
	this.allowNegativeCoordinates = value;
};

/**
 * Function: getOverlap
 * 
 * Returns a decimal number representing the amount of the width and height
 * of the given cell that is allowed to overlap its parent. A value of 0
 * means all children must stay inside the parent, 1 means the child is
 * allowed to be placed outside of the parent such that it touches one of
 * the parents sides. If <isAllowOverlapParent> returns false for the given
 * cell, then this method returns 0.
 * 
 * Parameters:
 * 
 * cell - <mxCell> for which the overlap ratio should be returned.
 */
mxGraph.prototype.getOverlap = function(cell)
{
	return (this.isAllowOverlapParent(cell)) ? this.defaultOverlap : 0;
};
	
/**
 * Function: isAllowOverlapParent
 * 
 * Returns true if the given cell is allowed to be placed outside of the
 * parents area.
 * 
 * Parameters:
 * 
 * cell - <mxCell> that represents the child to be checked.
 */
mxGraph.prototype.isAllowOverlapParent = function(cell)
{
	return false;
};

/**
 * Function: getFoldableCells
 * 
 * Returns the cells which are movable in the given array of cells.
 */
mxGraph.prototype.getFoldableCells = function(cells, collapse)
{
	return this.model.filterCells(cells, mxUtils.bind(this, function(cell)
	{
		return this.isCellFoldable(cell, collapse);
	}));
};

/**
 * Function: isCellFoldable
 * 
 * Returns true if the given cell is foldable. This implementation
 * returns true if the cell has at least one child and its style
 * does not specify <mxConstants.STYLE_FOLDABLE> to be 0.
 * 
 * Parameters:
 * 
 * cell - <mxCell> whose foldable state should be returned.
 */
mxGraph.prototype.isCellFoldable = function(cell, collapse)
{
	var state = this.view.getState(cell);
	var style = (state != null) ? state.style : this.getCellStyle(cell);
	
	return this.model.getChildCount(cell) > 0 && style[mxConstants.STYLE_FOLDABLE] != 0;
};

/**
 * Function: isValidDropTarget
 *
 * Returns true if the given cell is a valid drop target for the specified
 * cells. If <splitEnabled> is true then this returns <isSplitTarget> for
 * the given arguments else it returns true if the cell is not collapsed
 * and its child count is greater than 0.
 * 
 * Parameters:
 * 
 * cell - <mxCell> that represents the possible drop target.
 * cells - <mxCells> that should be dropped into the target.
 * evt - Mouseevent that triggered the invocation.
 */
mxGraph.prototype.isValidDropTarget = function(cell, cells, evt)
{
	return cell != null && ((this.isSplitEnabled() &&
		this.isSplitTarget(cell, cells, evt)) || (!this.model.isEdge(cell) &&
		(this.isSwimlane(cell) || (this.model.getChildCount(cell) > 0 &&
		!this.isCellCollapsed(cell)))));
};

/**
 * Function: isSplitTarget
 *
 * Returns true if the given edge may be splitted into two edges with the
 * given cell as a new terminal between the two.
 * 
 * Parameters:
 * 
 * target - <mxCell> that represents the edge to be splitted.
 * cells - <mxCells> that should split the edge.
 * evt - Mouseevent that triggered the invocation.
 */
mxGraph.prototype.isSplitTarget = function(target, cells, evt)
{
	if (this.model.isEdge(target) && cells != null && cells.length == 1 &&
		this.isCellConnectable(cells[0]) && this.getEdgeValidationError(target,
			this.model.getTerminal(target, true), cells[0]) == null)
	{
		var src = this.model.getTerminal(target, true);
		var trg = this.model.getTerminal(target, false);

		return (!this.model.isAncestor(cells[0], src) &&
				!this.model.isAncestor(cells[0], trg));
	}

	return false;
};

/**
 * Function: getDropTarget
 * 
 * Returns the given cell if it is a drop target for the given cells or the
 * nearest ancestor that may be used as a drop target for the given cells.
 * If the given array contains a swimlane and <swimlaneNesting> is false
 * then this always returns null. If no cell is given, then the bottommost
 * swimlane at the location of the given event is returned.
 * 
 * This function should only be used if <isDropEnabled> returns true.
 * 
 * Parameters:
 * 
 * cells - Array of <mxCells> which are to be dropped onto the target.
 * evt - Mouseevent for the drag and drop.
 * cell - <mxCell> that is under the mousepointer.
 * clone - Optional boolean to indicate of cells will be cloned.
 */
mxGraph.prototype.getDropTarget = function(cells, evt, cell, clone)
{
	if (!this.isSwimlaneNesting())
	{
		for (var i = 0; i < cells.length; i++)
		{
			if (this.isSwimlane(cells[i]))
			{
				return null;
			}
		}
	}

	var pt = mxUtils.convertPoint(this.container,
		mxEvent.getClientX(evt), mxEvent.getClientY(evt));
	pt.x -= this.panDx;
	pt.y -= this.panDy;
	var swimlane = this.getSwimlaneAt(pt.x, pt.y);
	
	if (cell == null)
	{
		cell = swimlane;
	}
	else if (swimlane != null)
	{
		// Checks if the cell is an ancestor of the swimlane
		// under the mouse and uses the swimlane in that case
		var tmp = this.model.getParent(swimlane);
		
		while (tmp != null && this.isSwimlane(tmp) && tmp != cell)
		{
			tmp = this.model.getParent(tmp);
		}
		
		if (tmp == cell)
		{
			cell = swimlane;
		}
	}
	
	while (cell != null && !this.isValidDropTarget(cell, cells, evt) &&
		!this.model.isLayer(cell))
	{
		cell = this.model.getParent(cell);
	}
	
	// Checks if parent is dropped into child if not cloning
	if (clone == null || !clone)
	{
		var parent = cell;
		
		while (parent != null && mxUtils.indexOf(cells, parent) < 0)
		{
			parent = this.model.getParent(parent);
		}
	}

	return (!this.model.isLayer(cell) && parent == null) ? cell : null;
};

/**
 * Group: Cell retrieval
 */

/**
 * Function: getDefaultParent
 * 
 * Returns <defaultParent> or <mxGraphView.currentRoot> or the first child
 * child of <mxGraphModel.root> if both are null. The value returned by
 * this function should be used as the parent for new cells (aka default
 * layer).
 */
mxGraph.prototype.getDefaultParent = function()
{
	var parent = this.getCurrentRoot();
	
	if (parent == null)
	{
		parent = this.defaultParent;
		
		if (parent == null)
		{
			var root = this.model.getRoot();
			parent = this.model.getChildAt(root, 0);
		}
	}
	
	return parent;
};

/**
 * Function: setDefaultParent
 * 
 * Sets the <defaultParent> to the given cell. Set this to null to return
 * the first child of the root in getDefaultParent.
 */
mxGraph.prototype.setDefaultParent = function(cell)
{
	this.defaultParent = cell;
};

/**
 * Function: getSwimlane
 * 
 * Returns the nearest ancestor of the given cell which is a swimlane, or
 * the given cell, if it is itself a swimlane.
 * 
 * Parameters:
 * 
 * cell - <mxCell> for which the ancestor swimlane should be returned.
 */
mxGraph.prototype.getSwimlane = function(cell)
{
	while (cell != null && !this.isSwimlane(cell))
	{
		cell = this.model.getParent(cell);
	}
	
	return cell;
};

/**
 * Function: getSwimlaneAt
 * 
 * Returns the bottom-most swimlane that intersects the given point (x, y)
 * in the cell hierarchy that starts at the given parent.
 * 
 * Parameters:
 * 
 * x - X-coordinate of the location to be checked.
 * y - Y-coordinate of the location to be checked.
 * parent - <mxCell> that should be used as the root of the recursion.
 * Default is <defaultParent>.
 */
mxGraph.prototype.getSwimlaneAt = function (x, y, parent)
{
	parent = parent || this.getDefaultParent();
	
	if (parent != null)
	{
		var childCount = this.model.getChildCount(parent);
		
		for (var i = 0; i < childCount; i++)
		{
			var child = this.model.getChildAt(parent, i);
			var result = this.getSwimlaneAt(x, y, child);
			
			if (result != null)
			{
				return result;
			}
			else if (this.isSwimlane(child))
			{
				var state = this.view.getState(child);
				
				if (this.intersects(state, x, y))
				{
					return child;
				}
			}
		}
	}
	
	return null;
};

/**
 * Function: getCellAt
 * 
 * Returns the bottom-most cell that intersects the given point (x, y) in
 * the cell hierarchy starting at the given parent. This will also return
 * swimlanes if the given location intersects the content area of the
 * swimlane. If this is not desired, then the <hitsSwimlaneContent> may be
 * used if the returned cell is a swimlane to determine if the location
 * is inside the content area or on the actual title of the swimlane.
 * 
 * Parameters:
 * 
 * x - X-coordinate of the location to be checked.
 * y - Y-coordinate of the location to be checked.
 * parent - <mxCell> that should be used as the root of the recursion.
 * Default is current root of the view or the root of the model.
 * vertices - Optional boolean indicating if vertices should be returned.
 * Default is true.
 * edges - Optional boolean indicating if edges should be returned. Default
 * is true.
 * ignoreFn - Optional function that returns true if cell should be ignored.
 * The function is passed the cell state and the x and y parameter.
 */
mxGraph.prototype.getCellAt = function(x, y, parent, vertices, edges, ignoreFn)
{
	vertices = (vertices != null) ? vertices : true;
	edges = (edges != null) ? edges : true;

	if (parent == null)
	{
		parent = this.getCurrentRoot();
		
		if (parent == null)
		{
			parent = this.getModel().getRoot();
		}
	}

	if (parent != null)
	{
		var childCount = this.model.getChildCount(parent);
		
		for (var i = childCount - 1; i >= 0; i--)
		{
			var cell = this.model.getChildAt(parent, i);
			var result = this.getCellAt(x, y, cell, vertices, edges, ignoreFn);
			
			if (result != null)
			{
				return result;
			}
			else if (this.isCellVisible(cell) && (edges && this.model.isEdge(cell) ||
				vertices && this.model.isVertex(cell)))
			{
				var state = this.view.getState(cell);

				if (state != null && (ignoreFn == null || !ignoreFn(state, x, y)) &&
					this.intersects(state, x, y))
				{
					return cell;
				}
			}
		}
	}
	
	return null;
};

/**
 * Function: intersects
 * 
 * Returns the bottom-most cell that intersects the given point (x, y) in
 * the cell hierarchy that starts at the given parent.
 * 
 * Parameters:
 * 
 * state - <mxCellState> that represents the cell state.
 * x - X-coordinate of the location to be checked.
 * y - Y-coordinate of the location to be checked.
 */
mxGraph.prototype.intersects = function(state, x, y)
{
	if (state != null)
	{
		var pts = state.absolutePoints;

		if (pts != null)
		{
			var t2 = this.tolerance * this.tolerance;
			var pt = pts[0];
			
			for (var i = 1; i < pts.length; i++)
			{
				var next = pts[i];
				var dist = mxUtils.ptSegDistSq(pt.x, pt.y, next.x, next.y, x, y);
				
				if (dist <= t2)
				{
					return true;
				}
				
				pt = next;
			}
		}
		else
		{
			var alpha = mxUtils.toRadians(mxUtils.getValue(state.style, mxConstants.STYLE_ROTATION) || 0);
			
			if (alpha != 0)
			{
				var cos = Math.cos(-alpha);
				var sin = Math.sin(-alpha);
				var cx = new mxPoint(state.getCenterX(), state.getCenterY());
				var pt = mxUtils.getRotatedPoint(new mxPoint(x, y), cos, sin, cx);
				x = pt.x;
				y = pt.y;
			}
			
			if (mxUtils.contains(state, x, y))
			{
				return true;
			}
		}
	}
	
	return false;
};

/**
 * Function: hitsSwimlaneContent
 * 
 * Returns true if the given coordinate pair is inside the content
 * are of the given swimlane.
 * 
 * Parameters:
 * 
 * swimlane - <mxCell> that specifies the swimlane.
 * x - X-coordinate of the mouse event.
 * y - Y-coordinate of the mouse event.
 */
mxGraph.prototype.hitsSwimlaneContent = function(swimlane, x, y)
{
	var state = this.getView().getState(swimlane);
	var size = this.getStartSize(swimlane);
	
	if (state != null)
	{
		var scale = this.getView().getScale();
		x -= state.x;
		y -= state.y;
		
		if (size.width > 0 && x > 0 && x > size.width * scale)
		{
			return true;
		}
		else if (size.height > 0 && y > 0 && y > size.height * scale)
		{
			return true;
		}
	}
	
	return false;
};

/**
 * Function: getChildVertices
 * 
 * Returns the visible child vertices of the given parent.
 * 
 * Parameters:
 * 
 * parent - <mxCell> whose children should be returned.
 */
mxGraph.prototype.getChildVertices = function(parent)
{
	return this.getChildCells(parent, true, false);
};
	
/**
 * Function: getChildEdges
 * 
 * Returns the visible child edges of the given parent.
 * 
 * Parameters:
 * 
 * parent - <mxCell> whose child vertices should be returned.
 */
mxGraph.prototype.getChildEdges = function(parent)
{
	return this.getChildCells(parent, false, true);
};

/**
 * Function: getChildCells
 * 
 * Returns the visible child vertices or edges in the given parent. If
 * vertices and edges is false, then all children are returned.
 * 
 * Parameters:
 * 
 * parent - <mxCell> whose children should be returned.
 * vertices - Optional boolean that specifies if child vertices should
 * be returned. Default is false.
 * edges - Optional boolean that specifies if child edges should
 * be returned. Default is false.
 */
mxGraph.prototype.getChildCells = function(parent, vertices, edges)
{
	parent = (parent != null) ? parent : this.getDefaultParent();
	vertices = (vertices != null) ? vertices : false;
	edges = (edges != null) ? edges : false;

	var cells = this.model.getChildCells(parent, vertices, edges);
	var result = [];

	// Filters out the non-visible child cells
	for (var i = 0; i < cells.length; i++)
	{
		if (this.isCellVisible(cells[i]))
		{
			result.push(cells[i]);
		}
	}

	return result;
};
	
/**
 * Function: getConnections
 * 
 * Returns all visible edges connected to the given cell without loops.
 * 
 * Parameters:
 * 
 * cell - <mxCell> whose connections should be returned.
 * parent - Optional parent of the opposite end for a connection to be
 * returned.
 */
mxGraph.prototype.getConnections = function(cell, parent)
{
	return this.getEdges(cell, parent, true, true, false);
};
	
/**
 * Function: getIncomingEdges
 * 
 * Returns the visible incoming edges for the given cell. If the optional
 * parent argument is specified, then only child edges of the given parent
 * are returned.
 * 
 * Parameters:
 * 
 * cell - <mxCell> whose incoming edges should be returned.
 * parent - Optional parent of the opposite end for an edge to be
 * returned.
 */
mxGraph.prototype.getIncomingEdges = function(cell, parent)
{
	return this.getEdges(cell, parent, true, false, false);
};
	
/**
 * Function: getOutgoingEdges
 * 
 * Returns the visible outgoing edges for the given cell. If the optional
 * parent argument is specified, then only child edges of the given parent
 * are returned.
 * 
 * Parameters:
 * 
 * cell - <mxCell> whose outgoing edges should be returned.
 * parent - Optional parent of the opposite end for an edge to be
 * returned.
 */
mxGraph.prototype.getOutgoingEdges = function(cell, parent)
{
	return this.getEdges(cell, parent, false, true, false);
};
	
/**
 * Function: getEdges
 * 
 * Returns the incoming and/or outgoing edges for the given cell.
 * If the optional parent argument is specified, then only edges are returned
 * where the opposite is in the given parent cell. If at least one of incoming
 * or outgoing is true, then loops are ignored, if both are false, then all
 * edges connected to the given cell are returned including loops.
 * 
 * Parameters:
 * 
 * cell - <mxCell> whose edges should be returned.
 * parent - Optional parent of the opposite end for an edge to be
 * returned.
 * incoming - Optional boolean that specifies if incoming edges should
 * be included in the result. Default is true.
 * outgoing - Optional boolean that specifies if outgoing edges should
 * be included in the result. Default is true.
 * includeLoops - Optional boolean that specifies if loops should be
 * included in the result. Default is true.
 * recurse - Optional boolean the specifies if the parent specified only 
 * need be an ancestral parent, true, or the direct parent, false.
 * Default is false
 */
mxGraph.prototype.getEdges = function(cell, parent, incoming, outgoing, includeLoops, recurse)
{
	incoming = (incoming != null) ? incoming : true;
	outgoing = (outgoing != null) ? outgoing : true;
	includeLoops = (includeLoops != null) ? includeLoops : true;
	recurse = (recurse != null) ? recurse : false;
	
	var edges = [];
	var isCollapsed = this.isCellCollapsed(cell);
	var childCount = this.model.getChildCount(cell);

	for (var i = 0; i < childCount; i++)
	{
		var child = this.model.getChildAt(cell, i);

		if (isCollapsed || !this.isCellVisible(child))
		{
			edges = edges.concat(this.model.getEdges(child, incoming, outgoing));
		}
	}

	edges = edges.concat(this.model.getEdges(cell, incoming, outgoing));
	var result = [];
	
	for (var i = 0; i < edges.length; i++)
	{
		var state = this.view.getState(edges[i]);
		
		var source = (state != null) ? state.getVisibleTerminal(true) : this.view.getVisibleTerminal(edges[i], true);
		var target = (state != null) ? state.getVisibleTerminal(false) : this.view.getVisibleTerminal(edges[i], false);

		if ((includeLoops && source == target) || ((source != target) && ((incoming &&
			target == cell && (parent == null || this.isValidAncestor(source, parent, recurse))) ||
			(outgoing && source == cell && (parent == null ||
					this.isValidAncestor(target, parent, recurse))))))
		{
			result.push(edges[i]);
		}
	}

	return result;
};

/**
 * Function: isValidAncestor
 * 
 * Returns whether or not the specified parent is a valid
 * ancestor of the specified cell, either direct or indirectly
 * based on whether ancestor recursion is enabled.
 * 
 * Parameters:
 * 
 * cell - <mxCell> the possible child cell
 * parent - <mxCell> the possible parent cell
 * recurse - boolean whether or not to recurse the child ancestors
 */
mxGraph.prototype.isValidAncestor = function(cell, parent, recurse)
{
	return (recurse ? this.model.isAncestor(parent, cell) : this.model
			.getParent(cell) == parent);
};

/**
 * Function: getOpposites
 * 
 * Returns all distinct visible opposite cells for the specified terminal
 * on the given edges.
 * 
 * Parameters:
 * 
 * edges - Array of <mxCells> that contains the edges whose opposite
 * terminals should be returned.
 * terminal - Terminal that specifies the end whose opposite should be
 * returned.
 * source - Optional boolean that specifies if source terminals should be
 * included in the result. Default is true.
 * targets - Optional boolean that specifies if targer terminals should be
 * included in the result. Default is true.
 */
mxGraph.prototype.getOpposites = function(edges, terminal, sources, targets)
{
	sources = (sources != null) ? sources : true;
	targets = (targets != null) ? targets : true;
	
	var terminals = [];
	
	// Fast lookup to avoid duplicates in terminals array
	var dict = new mxDictionary();
	
	if (edges != null)
	{
		for (var i = 0; i < edges.length; i++)
		{
			var state = this.view.getState(edges[i]);
			
			var source = (state != null) ? state.getVisibleTerminal(true) : this.view.getVisibleTerminal(edges[i], true);
			var target = (state != null) ? state.getVisibleTerminal(false) : this.view.getVisibleTerminal(edges[i], false);
			
			// Checks if the terminal is the source of the edge and if the
			// target should be stored in the result
			if (source == terminal && target != null && target != terminal && targets)
			{
				if (!dict.get(target))
				{
					dict.put(target, true);
					terminals.push(target);
				}
			}
			
			// Checks if the terminal is the taget of the edge and if the
			// source should be stored in the result
			else if (target == terminal && source != null && source != terminal && sources)
			{
				if (!dict.get(source))
				{
					dict.put(source, true);
					terminals.push(source);
				}
			}
		}
	}
	
	return terminals;
};

/**
 * Function: getEdgesBetween
 * 
 * Returns the edges between the given source and target. This takes into
 * account collapsed and invisible cells and returns the connected edges
 * as displayed on the screen.
 * 
 * Parameters:
 * 
 * source -
 * target -
 * directed -
 */
mxGraph.prototype.getEdgesBetween = function(source, target, directed)
{
	directed = (directed != null) ? directed : false;
	var edges = this.getEdges(source);
	var result = [];

	// Checks if the edge is connected to the correct
	// cell and returns the first match
	for (var i = 0; i < edges.length; i++)
	{
		var state = this.view.getState(edges[i]);
		
		var src = (state != null) ? state.getVisibleTerminal(true) : this.view.getVisibleTerminal(edges[i], true);
		var trg = (state != null) ? state.getVisibleTerminal(false) : this.view.getVisibleTerminal(edges[i], false);

		if ((src == source && trg == target) || (!directed && src == target && trg == source))
		{
			result.push(edges[i]);
		}
	}

	return result;
};

/**
 * Function: getPointForEvent
 * 
 * Returns an <mxPoint> representing the given event in the unscaled,
 * non-translated coordinate space of <container> and applies the grid.
 * 
 * Parameters:
 * 
 * evt - Mousevent that contains the mouse pointer location.
 * addOffset - Optional boolean that specifies if the position should be
 * offset by half of the <gridSize>. Default is true.
 */
 mxGraph.prototype.getPointForEvent = function(evt, addOffset)
 {
	var p = mxUtils.convertPoint(this.container,
		mxEvent.getClientX(evt), mxEvent.getClientY(evt));
	
	var s = this.view.scale;
	var tr = this.view.translate;
	var off = (addOffset != false) ? this.gridSize / 2 : 0;
	
	p.x = this.snap(p.x / s - tr.x - off);
	p.y = this.snap(p.y / s - tr.y - off);
	
	return p;
 };

/**
 * Function: getCells
 * 
 * Returns the child vertices and edges of the given parent that are contained
 * in the given rectangle. The result is added to the optional result array,
 * which is returned. If no result array is specified then a new array is
 * created and returned.
 * 
 * Parameters:
 * 
 * x - X-coordinate of the rectangle.
 * y - Y-coordinate of the rectangle.
 * width - Width of the rectangle.
 * height - Height of the rectangle.
 * parent - <mxCell> that should be used as the root of the recursion.
 * Default is current root of the view or the root of the model.
 * result - Optional array to store the result in.
 */
mxGraph.prototype.getCells = function(x, y, width, height, parent, result)
{
	result = (result != null) ? result : [];
	
	if (width > 0 || height > 0)
	{
		var model = this.getModel();
		var right = x + width;
		var bottom = y + height;

		if (parent == null)
		{
			parent = this.getCurrentRoot();
			
			if (parent == null)
			{
				parent = model.getRoot();
			}
		}
		
		if (parent != null)
		{
			var childCount = model.getChildCount(parent);
			
			for (var i = 0; i < childCount; i++)
			{
				var cell = model.getChildAt(parent, i);
				var state = this.view.getState(cell);
				
				if (state != null && this.isCellVisible(cell))
				{
					var deg = mxUtils.getValue(state.style, mxConstants.STYLE_ROTATION) || 0;
					var box = state;
					
					if (deg != 0)
					{
						box = mxUtils.getBoundingBox(box, deg);
					}
					
					if ((model.isEdge(cell) || model.isVertex(cell)) &&
						box.x >= x && box.y + box.height <= bottom &&
						box.y >= y && box.x + box.width <= right)
					{
						result.push(cell);
					}
					else
					{
						this.getCells(x, y, width, height, cell, result);
					}
				}
			}
		}
	}
	
	return result;
};

/**
 * Function: getCellsBeyond
 * 
 * Returns the children of the given parent that are contained in the
 * halfpane from the given point (x0, y0) rightwards or downwards
 * depending on rightHalfpane and bottomHalfpane.
 * 
 * Parameters:
 * 
 * x0 - X-coordinate of the origin.
 * y0 - Y-coordinate of the origin.
 * parent - Optional <mxCell> whose children should be checked. Default is
 * <defaultParent>.
 * rightHalfpane - Boolean indicating if the cells in the right halfpane
 * from the origin should be returned.
 * bottomHalfpane - Boolean indicating if the cells in the bottom halfpane
 * from the origin should be returned.
 */
mxGraph.prototype.getCellsBeyond = function(x0, y0, parent, rightHalfpane, bottomHalfpane)
{
	var result = [];
	
	if (rightHalfpane || bottomHalfpane)
	{
		if (parent == null)
		{
			parent = this.getDefaultParent();
		}
		
		if (parent != null)
		{
			var childCount = this.model.getChildCount(parent);
			
			for (var i = 0; i < childCount; i++)
			{
				var child = this.model.getChildAt(parent, i);
				var state = this.view.getState(child);
				
				if (this.isCellVisible(child) && state != null)
				{
					if ((!rightHalfpane || state.x >= x0) &&
						(!bottomHalfpane || state.y >= y0))
					{
						result.push(child);
					}
				}
			}
		}
	}
	
	return result;
};

/**
 * Function: findTreeRoots
 * 
 * Returns all children in the given parent which do not have incoming
 * edges. If the result is empty then the with the greatest difference
 * between incoming and outgoing edges is returned.
 * 
 * Parameters:
 * 
 * parent - <mxCell> whose children should be checked.
 * isolate - Optional boolean that specifies if edges should be ignored if
 * the opposite end is not a child of the given parent cell. Default is
 * false.
 * invert - Optional boolean that specifies if outgoing or incoming edges
 * should be counted for a tree root. If false then outgoing edges will be
 * counted. Default is false.
 */
mxGraph.prototype.findTreeRoots = function(parent, isolate, invert)
{
	isolate = (isolate != null) ? isolate : false;
	invert = (invert != null) ? invert : false;
	var roots = [];
	
	if (parent != null)
	{
		var model = this.getModel();
		var childCount = model.getChildCount(parent);
		var best = null;
		var maxDiff = 0;
		
		for (var i=0; i<childCount; i++)
		{
			var cell = model.getChildAt(parent, i);
			
			if (this.model.isVertex(cell) && this.isCellVisible(cell))
			{
				var conns = this.getConnections(cell, (isolate) ? parent : null);
				var fanOut = 0;
				var fanIn = 0;
				
				for (var j = 0; j < conns.length; j++)
				{
					var src = this.view.getVisibleTerminal(conns[j], true);

                    if (src == cell)
                    {
                        fanOut++;
                    }
                    else
                    {
                        fanIn++;
                    }
				}
				
				if ((invert && fanOut == 0 && fanIn > 0) ||
					(!invert && fanIn == 0 && fanOut > 0))
				{
					roots.push(cell);
				}
				
				var diff = (invert) ? fanIn - fanOut : fanOut - fanIn;
				
				if (diff > maxDiff)
				{
					maxDiff = diff;
					best = cell;
				}
			}
		}
		
		if (roots.length == 0 && best != null)
		{
			roots.push(best);
		}
	}
	
	return roots;
};

/**
 * Function: traverse
 * 
 * Traverses the (directed) graph invoking the given function for each
 * visited vertex and edge. The function is invoked with the current vertex
 * and the incoming edge as a parameter. This implementation makes sure
 * each vertex is only visited once. The function may return false if the
 * traversal should stop at the given vertex.
 * 
 * Example:
 * 
 * (code)
 * mxLog.show();
 * var cell = graph.getSelectionCell();
 * graph.traverse(cell, false, function(vertex, edge)
 * {
 *   mxLog.debug(graph.getLabel(vertex));
 * });
 * (end)
 * 
 * Parameters:
 * 
 * vertex - <mxCell> that represents the vertex where the traversal starts.
 * directed - Optional boolean indicating if edges should only be traversed
 * from source to target. Default is true.
 * func - Visitor function that takes the current vertex and the incoming
 * edge as arguments. The traversal stops if the function returns false.
 * edge - Optional <mxCell> that represents the incoming edge. This is
 * null for the first step of the traversal.
 * visited - Optional <mxDictionary> from cells to true for the visited cells.
 * inverse - Optional boolean to traverse in inverse direction. Default is false.
 * This is ignored if directed is false.
 */
mxGraph.prototype.traverse = function(vertex, directed, func, edge, visited, inverse)
{
	if (func != null && vertex != null)
	{
		directed = (directed != null) ? directed : true;
		inverse = (inverse != null) ? inverse : false;
		visited = visited || new mxDictionary();
		
		if (!visited.get(vertex))
		{
			visited.put(vertex, true);
			var result = func(vertex, edge);
			
			if (result == null || result)
			{
				var edgeCount = this.model.getEdgeCount(vertex);
				
				if (edgeCount > 0)
				{
					for (var i = 0; i < edgeCount; i++)
					{
						var e = this.model.getEdgeAt(vertex, i);
						var isSource = this.model.getTerminal(e, true) == vertex;
						
						if (!directed || (!inverse == isSource))
						{
							var next = this.model.getTerminal(e, !isSource);
							this.traverse(next, directed, func, e, visited, inverse);
						}
					}
				}
			}
		}
	}
};

/**
 * Group: Selection
 */

/**
 * Function: isCellSelected
 * 
 * Returns true if the given cell is selected.
 * 
 * Parameters:
 * 
 * cell - <mxCell> for which the selection state should be returned.
 */
mxGraph.prototype.isCellSelected = function(cell)
{
	return this.getSelectionModel().isSelected(cell);
};

/**
 * Function: isSelectionEmpty
 * 
 * Returns true if the selection is empty.
 */
mxGraph.prototype.isSelectionEmpty = function()
{
	return this.getSelectionModel().isEmpty();
};

/**
 * Function: clearSelection
 * 
 * Clears the selection using <mxGraphSelectionModel.clear>.
 */
mxGraph.prototype.clearSelection = function()
{
	return this.getSelectionModel().clear();
};

/**
 * Function: getSelectionCount
 * 
 * Returns the number of selected cells.
 */
mxGraph.prototype.getSelectionCount = function()
{
	return this.getSelectionModel().cells.length;
};
	
/**
 * Function: getSelectionCell
 * 
 * Returns the first cell from the array of selected <mxCells>.
 */
mxGraph.prototype.getSelectionCell = function()
{
	return this.getSelectionModel().cells[0];
};

/**
 * Function: getSelectionCells
 * 
 * Returns the array of selected <mxCells>.
 */
mxGraph.prototype.getSelectionCells = function()
{
	return this.getSelectionModel().cells.slice();
};

/**
 * Function: setSelectionCell
 * 
 * Sets the selection cell.
 * 
 * Parameters:
 * 
 * cell - <mxCell> to be selected.
 */
mxGraph.prototype.setSelectionCell = function(cell)
{
	this.getSelectionModel().setCell(cell);
};

/**
 * Function: setSelectionCells
 * 
 * Sets the selection cell.
 * 
 * Parameters:
 * 
 * cells - Array of <mxCells> to be selected.
 */
mxGraph.prototype.setSelectionCells = function(cells)
{
	this.getSelectionModel().setCells(cells);
};

/**
 * Function: addSelectionCell
 * 
 * Adds the given cell to the selection.
 * 
 * Parameters:
 * 
 * cell - <mxCell> to be add to the selection.
 */
mxGraph.prototype.addSelectionCell = function(cell)
{
	this.getSelectionModel().addCell(cell);
};

/**
 * Function: addSelectionCells
 * 
 * Adds the given cells to the selection.
 * 
 * Parameters:
 * 
 * cells - Array of <mxCells> to be added to the selection.
 */
mxGraph.prototype.addSelectionCells = function(cells)
{
	this.getSelectionModel().addCells(cells);
};

/**
 * Function: removeSelectionCell
 * 
 * Removes the given cell from the selection.
 * 
 * Parameters:
 * 
 * cell - <mxCell> to be removed from the selection.
 */
mxGraph.prototype.removeSelectionCell = function(cell)
{
	this.getSelectionModel().removeCell(cell);
};

/**
 * Function: removeSelectionCells
 * 
 * Removes the given cells from the selection.
 * 
 * Parameters:
 * 
 * cells - Array of <mxCells> to be removed from the selection.
 */
mxGraph.prototype.removeSelectionCells = function(cells)
{
	this.getSelectionModel().removeCells(cells);
};

/**
 * Function: selectRegion
 * 
 * Selects and returns the cells inside the given rectangle for the
 * specified event.
 * 
 * Parameters:
 * 
 * rect - <mxRectangle> that represents the region to be selected.
 * evt - Mouseevent that triggered the selection.
 */
mxGraph.prototype.selectRegion = function(rect, evt)
{
	var cells = this.getCells(rect.x, rect.y, rect.width, rect.height);
	this.selectCellsForEvent(cells, evt);
	
	return cells;
};

/**
 * Function: selectNextCell
 * 
 * Selects the next cell.
 */
mxGraph.prototype.selectNextCell = function()
{
	this.selectCell(true);
};

/**
 * Function: selectPreviousCell
 * 
 * Selects the previous cell.
 */
mxGraph.prototype.selectPreviousCell = function()
{
	this.selectCell();
};

/**
 * Function: selectParentCell
 * 
 * Selects the parent cell.
 */
mxGraph.prototype.selectParentCell = function()
{
	this.selectCell(false, true);
};

/**
 * Function: selectChildCell
 * 
 * Selects the first child cell.
 */
mxGraph.prototype.selectChildCell = function()
{
	this.selectCell(false, false, true);
};

/**
 * Function: selectCell
 * 
 * Selects the next, parent, first child or previous cell, if all arguments
 * are false.
 * 
 * Parameters:
 * 
 * isNext - Boolean indicating if the next cell should be selected.
 * isParent - Boolean indicating if the parent cell should be selected.
 * isChild - Boolean indicating if the first child cell should be selected.
 */
mxGraph.prototype.selectCell = function(isNext, isParent, isChild)
{
	var sel = this.selectionModel;
	var cell = (sel.cells.length > 0) ? sel.cells[0] : null;
	
	if (sel.cells.length > 1)
	{
		sel.clear();
	}
	
	var parent = (cell != null) ?
		this.model.getParent(cell) :
		this.getDefaultParent();
	
	var childCount = this.model.getChildCount(parent);
	
	if (cell == null && childCount > 0)
	{
		var child = this.model.getChildAt(parent, 0);
		this.setSelectionCell(child);
	}
	else if ((cell == null || isParent) &&
		this.view.getState(parent) != null &&
		this.model.getGeometry(parent) != null)
	{
		if (this.getCurrentRoot() != parent)
		{
			this.setSelectionCell(parent);
		}
	}
	else if (cell != null && isChild)
	{
		var tmp = this.model.getChildCount(cell);
		
		if (tmp > 0)
		{
			var child = this.model.getChildAt(cell, 0);
			this.setSelectionCell(child);
		}
	}
	else if (childCount > 0)
	{
		var i = parent.getIndex(cell);
		
		if (isNext)
		{
			i++;
			var child = this.model.getChildAt(parent, i % childCount);
			this.setSelectionCell(child);
		}
		else
		{
			i--;
			var index =  (i < 0) ? childCount - 1 : i;
			var child = this.model.getChildAt(parent, index);
			this.setSelectionCell(child);
		}
	}
};

/**
 * Function: selectAll
 * 
 * Selects all children of the given parent cell or the children of the
 * default parent if no parent is specified. To select leaf vertices and/or
 * edges use <selectCells>.
 * 
 * Parameters:
 * 
 * parent - Optional <mxCell> whose children should be selected.
 * Default is <defaultParent>.
 * descendants - Optional boolean specifying whether all descendants should be
 * selected. Default is false.
 */
mxGraph.prototype.selectAll = function(parent, descendants)
{
	parent = parent || this.getDefaultParent();
	
	var cells = (descendants) ? this.model.filterDescendants(function(cell)
	{
		return cell != parent;
	}, parent) : this.model.getChildren(parent);
	
	if (cells != null)
	{
		this.setSelectionCells(cells);
	}
};

/**
 * Function: selectVertices
 * 
 * Select all vertices inside the given parent or the default parent.
 */
mxGraph.prototype.selectVertices = function(parent)
{
	this.selectCells(true, false, parent);
};

/**
 * Function: selectVertices
 * 
 * Select all vertices inside the given parent or the default parent.
 */
mxGraph.prototype.selectEdges = function(parent)
{
	this.selectCells(false, true, parent);
};

/**
 * Function: selectCells
 * 
 * Selects all vertices and/or edges depending on the given boolean
 * arguments recursively, starting at the given parent or the default
 * parent if no parent is specified. Use <selectAll> to select all cells.
 * For vertices, only cells with no children are selected.
 * 
 * Parameters:
 * 
 * vertices - Boolean indicating if vertices should be selected.
 * edges - Boolean indicating if edges should be selected.
 * parent - Optional <mxCell> that acts as the root of the recursion.
 * Default is <defaultParent>.
 */
mxGraph.prototype.selectCells = function(vertices, edges, parent)
{
	parent = parent || this.getDefaultParent();
	
	var filter = mxUtils.bind(this, function(cell)
	{
		return this.view.getState(cell) != null &&
			((this.model.getChildCount(cell) == 0 && this.model.isVertex(cell) && vertices
			&& !this.model.isEdge(this.model.getParent(cell))) ||
			(this.model.isEdge(cell) && edges));
	});
	
	var cells = this.model.filterDescendants(filter, parent);
	this.setSelectionCells(cells);
};

/**
 * Function: selectCellForEvent
 * 
 * Selects the given cell by either adding it to the selection or
 * replacing the selection depending on whether the given mouse event is a
 * toggle event.
 * 
 * Parameters:
 * 
 * cell - <mxCell> to be selected.
 * evt - Optional mouseevent that triggered the selection.
 */
mxGraph.prototype.selectCellForEvent = function(cell, evt)
{
	var isSelected = this.isCellSelected(cell);
	
	if (this.isToggleEvent(evt))
	{
		if (isSelected)
		{
			this.removeSelectionCell(cell);
		}
		else
		{
			this.addSelectionCell(cell);
		}
	}
	else if (!isSelected || this.getSelectionCount() != 1)
	{
		this.setSelectionCell(cell);
	}
};

/**
 * Function: selectCellsForEvent
 * 
 * Selects the given cells by either adding them to the selection or
 * replacing the selection depending on whether the given mouse event is a
 * toggle event.
 * 
 * Parameters:
 * 
 * cells - Array of <mxCells> to be selected.
 * evt - Optional mouseevent that triggered the selection.
 */
mxGraph.prototype.selectCellsForEvent = function(cells, evt)
{
	if (this.isToggleEvent(evt))
	{
		this.addSelectionCells(cells);
	}
	else
	{
		this.setSelectionCells(cells);
	}
};

/**
 * Group: Selection state
 */

/**
 * Function: createHandler
 * 
 * Creates a new handler for the given cell state. This implementation
 * returns a new <mxEdgeHandler> of the corresponding cell is an edge,
 * otherwise it returns an <mxVertexHandler>.
 * 
 * Parameters:
 * 
 * state - <mxCellState> whose handler should be created.
 */
mxGraph.prototype.createHandler = function(state)
{
	var result = null;
	
	if (state != null)
	{
		if (this.model.isEdge(state.cell))
		{
			var source = state.getVisibleTerminalState(true);
			var target = state.getVisibleTerminalState(false);
			var geo = this.getCellGeometry(state.cell);
			
			var edgeStyle = this.view.getEdgeStyle(state, (geo != null) ? geo.points : null, source, target);
			result = this.createEdgeHandler(state, edgeStyle);
		}
		else
		{
			result = this.createVertexHandler(state);
		}
	}
	
	return result;
};

/**
 * Function: createVertexHandler
 * 
 * Hooks to create a new <mxVertexHandler> for the given <mxCellState>.
 * 
 * Parameters:
 * 
 * state - <mxCellState> to create the handler for.
 */
mxGraph.prototype.createVertexHandler = function(state)
{
	return new mxVertexHandler(state);
};

/**
 * Function: createEdgeHandler
 * 
 * Hooks to create a new <mxEdgeHandler> for the given <mxCellState>.
 * 
 * Parameters:
 * 
 * state - <mxCellState> to create the handler for.
 */
mxGraph.prototype.createEdgeHandler = function(state, edgeStyle)
{
	var result = null;
	
	if (edgeStyle == mxEdgeStyle.Loop ||
		edgeStyle == mxEdgeStyle.ElbowConnector ||
		edgeStyle == mxEdgeStyle.SideToSide ||
		edgeStyle == mxEdgeStyle.TopToBottom)
	{
		result = this.createElbowEdgeHandler(state);
	}
	else if (edgeStyle == mxEdgeStyle.SegmentConnector || 
			edgeStyle == mxEdgeStyle.OrthConnector)
	{
		result = this.createEdgeSegmentHandler(state);
	}
	else
	{
		result = new mxEdgeHandler(state);
	}
	
	return result;
};

/**
 * Function: createEdgeSegmentHandler
 * 
 * Hooks to create a new <mxEdgeSegmentHandler> for the given <mxCellState>.
 * 
 * Parameters:
 * 
 * state - <mxCellState> to create the handler for.
 */
mxGraph.prototype.createEdgeSegmentHandler = function(state)
{
	return new mxEdgeSegmentHandler(state);
};

/**
 * Function: createElbowEdgeHandler
 * 
 * Hooks to create a new <mxElbowEdgeHandler> for the given <mxCellState>.
 * 
 * Parameters:
 * 
 * state - <mxCellState> to create the handler for.
 */
mxGraph.prototype.createElbowEdgeHandler = function(state)
{
	return new mxElbowEdgeHandler(state);
};

/**
 * Group: Graph events
 */

/**
 * Function: addMouseListener
 * 
 * Adds a listener to the graph event dispatch loop. The listener
 * must implement the mouseDown, mouseMove and mouseUp methods
 * as shown in the <mxMouseEvent> class.
 * 
 * Parameters:
 * 
 * listener - Listener to be added to the graph event listeners.
 */
mxGraph.prototype.addMouseListener = function(listener)
{
	if (this.mouseListeners == null)
	{
		this.mouseListeners = [];
	}
	
	this.mouseListeners.push(listener);
};

/**
 * Function: removeMouseListener
 * 
 * Removes the specified graph listener.
 * 
 * Parameters:
 * 
 * listener - Listener to be removed from the graph event listeners.
 */
mxGraph.prototype.removeMouseListener = function(listener)
{
	if (this.mouseListeners != null)
	{
		for (var i = 0; i < this.mouseListeners.length; i++)
		{
			if (this.mouseListeners[i] == listener)
			{
				this.mouseListeners.splice(i, 1);
				break;
			}
		}
	}
};

/**
 * Function: updateMouseEvent
 * 
 * Sets the graphX and graphY properties if the given <mxMouseEvent> if
 * required and returned the event.
 * 
 * Parameters:
 * 
 * me - <mxMouseEvent> to be updated.
 * evtName - Name of the mouse event.
 */
mxGraph.prototype.updateMouseEvent = function(me, evtName)
{
	if (me.graphX == null || me.graphY == null)
	{
		var pt = mxUtils.convertPoint(this.container, me.getX(), me.getY());
		
		me.graphX = pt.x - this.panDx;
		me.graphY = pt.y - this.panDy;
		
		// Searches for rectangles using method if native hit detection is disabled on shape
		if (me.getCell() == null && this.isMouseDown && evtName == mxEvent.MOUSE_MOVE)
		{
			me.state = this.view.getState(this.getCellAt(pt.x, pt.y, null, null, null, function(state)
			{
				return state.shape == null || state.shape.paintBackground != mxRectangleShape.prototype.paintBackground ||
					mxUtils.getValue(state.style, mxConstants.STYLE_POINTER_EVENTS, '1') == '1' ||
					(state.shape.fill != null && state.shape.fill != mxConstants.NONE);
			}));
		}
	}
	
	return me;
};

/**
 * Function: getStateForEvent
 * 
 * Returns the state for the given touch event.
 */
mxGraph.prototype.getStateForTouchEvent = function(evt)
{
	var x = mxEvent.getClientX(evt);
	var y = mxEvent.getClientY(evt);
	
	// Dispatches the drop event to the graph which
	// consumes and executes the source function
	var pt = mxUtils.convertPoint(this.container, x, y);

	return this.view.getState(this.getCellAt(pt.x, pt.y));
};

/**
 * Function: isEventIgnored
 * 
 * Returns true if the event should be ignored in <fireMouseEvent>.
 */
mxGraph.prototype.isEventIgnored = function(evtName, me, sender)
{
	var mouseEvent = mxEvent.isMouseEvent(me.getEvent());
	var result = false;

	// Drops events that are fired more than once
	if (me.getEvent() == this.lastEvent)
	{
		result = true;
	}
	else
	{
		this.lastEvent = me.getEvent();
	}

	// Installs event listeners to capture the complete gesture from the event source
	// for non-MS touch events as a workaround for all events for the same geture being
	// fired from the event source even if that was removed from the DOM.
	if (this.eventSource != null && evtName != mxEvent.MOUSE_MOVE)
	{
		mxEvent.removeGestureListeners(this.eventSource, null, this.mouseMoveRedirect, this.mouseUpRedirect);
		this.mouseMoveRedirect = null;
		this.mouseUpRedirect = null;
		this.eventSource = null;
	}
	else if (this.eventSource != null && me.getSource() != this.eventSource)
	{
		result = true;
	}
	else if (mxClient.IS_TOUCH && evtName == mxEvent.MOUSE_DOWN && !mouseEvent && !mxEvent.isPenEvent(me.getEvent()))
	{
		this.eventSource = me.getSource();

		this.mouseMoveRedirect = mxUtils.bind(this, function(evt)
		{
			this.fireMouseEvent(mxEvent.MOUSE_MOVE, new mxMouseEvent(evt, this.getStateForTouchEvent(evt)));
		});
		this.mouseUpRedirect = mxUtils.bind(this, function(evt)
		{
			this.fireMouseEvent(mxEvent.MOUSE_UP, new mxMouseEvent(evt, this.getStateForTouchEvent(evt)));
		});
		
		mxEvent.addGestureListeners(this.eventSource, null, this.mouseMoveRedirect, this.mouseUpRedirect);
	}

	// Factored out the workarounds for FF to make it easier to override/remove
	// Note this method has side-effects!
	if (this.isSyntheticEventIgnored(evtName, me, sender))
	{
		result = true;
	}

	// Never fires mouseUp/-Down for double clicks
	if (!mxEvent.isPopupTrigger(this.lastEvent) && evtName != mxEvent.MOUSE_MOVE && this.lastEvent.detail == 2)
	{
		return true;
	}
	
	// Filters out of sequence events or mixed event types during a gesture
	if (evtName == mxEvent.MOUSE_UP && this.isMouseDown)
	{
		this.isMouseDown = false;
	}
	else if (evtName == mxEvent.MOUSE_DOWN && !this.isMouseDown)
	{
		this.isMouseDown = true;
		this.isMouseTrigger = mouseEvent;
	}
	// Drops mouse events that are fired during touch gestures as a workaround for Webkit
	// and mouse events that are not in sync with the current internal button state
	else if (!result && (((!mxClient.IS_FF || evtName != mxEvent.MOUSE_MOVE) &&
		this.isMouseDown && this.isMouseTrigger != mouseEvent) ||
		(evtName == mxEvent.MOUSE_DOWN && this.isMouseDown) ||
		(evtName == mxEvent.MOUSE_UP && !this.isMouseDown)))
	{
		result = true;
	}
	
	if (!result && evtName == mxEvent.MOUSE_DOWN)
	{
		this.lastMouseX = me.getX();
		this.lastMouseY = me.getY();
	}

	return result;
};

/**
 * Function: isSyntheticEventIgnored
 * 
 * Hook for ignoring synthetic mouse events after touchend in Firefox.
 */
mxGraph.prototype.isSyntheticEventIgnored = function(evtName, me, sender)
{
	var result = false;
	var mouseEvent = mxEvent.isMouseEvent(me.getEvent());
	
	// LATER: This does not cover all possible cases that can go wrong in FF
	if (this.ignoreMouseEvents && mouseEvent && evtName != mxEvent.MOUSE_MOVE)
	{
		this.ignoreMouseEvents = evtName != mxEvent.MOUSE_UP;
		result = true;
	}
	else if (mxClient.IS_FF && !mouseEvent && evtName == mxEvent.MOUSE_UP)
	{
		this.ignoreMouseEvents = true;
	}
	
	return result;
};

/**
 * Function: isEventSourceIgnored
 * 
 * Returns true if the event should be ignored in <fireMouseEvent>. This
 * implementation returns true for select, option and input (if not of type
 * checkbox, radio, button, submit or file) event sources if the event is not
 * a mouse event or a left mouse button press event.
 * 
 * Parameters:
 * 
 * evtName - The name of the event.
 * me - <mxMouseEvent> that should be ignored.
 */
mxGraph.prototype.isEventSourceIgnored = function(evtName, me)
{
	var source = me.getSource();
	var name = (source.nodeName != null) ? source.nodeName.toLowerCase() : '';
	var candidate = !mxEvent.isMouseEvent(me.getEvent()) || mxEvent.isLeftMouseButton(me.getEvent());
	
	return evtName == mxEvent.MOUSE_DOWN && candidate && (name == 'select' || name == 'option' ||
		(name == 'input' && source.type != 'checkbox' && source.type != 'radio' &&
		source.type != 'button' && source.type != 'submit' && source.type != 'file'));
};

/**
 * Function: getEventState
 * 
 * Returns the <mxCellState> to be used when firing the mouse event for the
 * given state. This implementation returns the given state.
 * 
 * Parameters:
 * 
 * <mxCellState> - State whose event source should be returned.
 */
mxGraph.prototype.getEventState = function(state)
{
	return state;
};

/**
 * Function: fireMouseEvent
 * 
 * Dispatches the given event in the graph event dispatch loop. Possible
 * event names are <mxEvent.MOUSE_DOWN>, <mxEvent.MOUSE_MOVE> and
 * <mxEvent.MOUSE_UP>. All listeners are invoked for all events regardless
 * of the consumed state of the event.
 * 
 * Parameters:
 * 
 * evtName - String that specifies the type of event to be dispatched.
 * me - <mxMouseEvent> to be fired.
 * sender - Optional sender argument. Default is this.
 */
mxGraph.prototype.fireMouseEvent = function(evtName, me, sender)
{
	if (this.isEventSourceIgnored(evtName, me))
	{
		if (this.tooltipHandler != null)
		{
			this.tooltipHandler.hide();
		}
		
		return;
	}
	
	if (sender == null)
	{
		sender = this;
	}

	// Updates the graph coordinates in the event
	me = this.updateMouseEvent(me, evtName);

	// Detects and processes double taps for touch-based devices which do not have native double click events
	// or where detection of double click is not always possible (quirks, IE10+). Note that this can only handle
	// double clicks on cells because the sequence of events in IE prevents detection on the background, it fires
	// two mouse ups, one of which without a cell but no mousedown for the second click which means we cannot
	// detect which mouseup(s) are part of the first click, ie we do not know when the first click ends.
	if ((!this.nativeDblClickEnabled && !mxEvent.isPopupTrigger(me.getEvent())) || (this.doubleTapEnabled &&
		mxClient.IS_TOUCH && (mxEvent.isTouchEvent(me.getEvent()) || mxEvent.isPenEvent(me.getEvent()))))
	{
		var currentTime = new Date().getTime();
		
		// NOTE: Second mouseDown for double click missing in quirks mode
		if ((!mxClient.IS_QUIRKS && evtName == mxEvent.MOUSE_DOWN) || (mxClient.IS_QUIRKS && evtName == mxEvent.MOUSE_UP && !this.fireDoubleClick))
		{
			if (this.lastTouchEvent != null && this.lastTouchEvent != me.getEvent() &&
				currentTime - this.lastTouchTime < this.doubleTapTimeout &&
				Math.abs(this.lastTouchX - me.getX()) < this.doubleTapTolerance &&
				Math.abs(this.lastTouchY - me.getY()) < this.doubleTapTolerance &&
				this.doubleClickCounter < 2)
			{
				this.doubleClickCounter++;
				var doubleClickFired = false;
				
				if (evtName == mxEvent.MOUSE_UP)
				{
					if (me.getCell() == this.lastTouchCell && this.lastTouchCell != null)
					{
						this.lastTouchTime = 0;
						var cell = this.lastTouchCell;
						this.lastTouchCell = null;

						// Fires native dblclick event via event source
						// NOTE: This fires two double click events on edges in quirks mode. While
						// trying to fix this, we realized that nativeDoubleClick can be disabled for
						// quirks and IE10+ (or we didn't find the case mentioned above where it
						// would not work), ie. all double clicks seem to be working without this.
						if (mxClient.IS_QUIRKS)
						{
							me.getSource().fireEvent('ondblclick');
						}
						
						this.dblClick(me.getEvent(), cell);
						doubleClickFired = true;
					}
				}
				else
				{
					this.fireDoubleClick = true;
					this.lastTouchTime = 0;
				}

				// Do not ignore mouse up in quirks in this case
				if (!mxClient.IS_QUIRKS || doubleClickFired)
				{
					mxEvent.consume(me.getEvent());
					return;
				}
			}
			else if (this.lastTouchEvent == null || this.lastTouchEvent != me.getEvent())
			{
				this.lastTouchCell = me.getCell();
				this.lastTouchX = me.getX();
				this.lastTouchY = me.getY();
				this.lastTouchTime = currentTime;
				this.lastTouchEvent = me.getEvent();
				this.doubleClickCounter = 0;
			}
		}
		else if ((this.isMouseDown || evtName == mxEvent.MOUSE_UP) && this.fireDoubleClick)
		{
			this.fireDoubleClick = false;
			var cell = this.lastTouchCell;
			this.lastTouchCell = null;
			this.isMouseDown = false;
			
			// Workaround for Chrome/Safari not firing native double click events for double touch on background
			var valid = (cell != null) || ((mxEvent.isTouchEvent(me.getEvent()) || mxEvent.isPenEvent(me.getEvent())) &&
				(mxClient.IS_GC || mxClient.IS_SF));
			
			if (valid && Math.abs(this.lastTouchX - me.getX()) < this.doubleTapTolerance &&
				Math.abs(this.lastTouchY - me.getY()) < this.doubleTapTolerance)
			{
				this.dblClick(me.getEvent(), cell);
			}
			else
			{
				mxEvent.consume(me.getEvent());
			}
			
			return;
		}
	}

	if (!this.isEventIgnored(evtName, me, sender))
	{
		// Updates the event state via getEventState
		me.state = this.getEventState(me.getState());
		this.fireEvent(new mxEventObject(mxEvent.FIRE_MOUSE_EVENT, 'eventName', evtName, 'event', me));
		
		if ((mxClient.IS_OP || mxClient.IS_SF || mxClient.IS_GC || mxClient.IS_IE11 ||
			(mxClient.IS_IE && mxClient.IS_SVG) || me.getEvent().target != this.container))
		{
			if (evtName == mxEvent.MOUSE_MOVE && this.isMouseDown && this.autoScroll && !mxEvent.isMultiTouchEvent(me.getEvent))
			{
				this.scrollPointToVisible(me.getGraphX(), me.getGraphY(), this.autoExtend);
			}
			else if (evtName == mxEvent.MOUSE_UP && this.ignoreScrollbars && this.translateToScrollPosition &&
					(this.container.scrollLeft != 0 || this.container.scrollTop != 0))
			{
				var s = this.view.scale;
				var tr = this.view.translate;
				this.view.setTranslate(tr.x - this.container.scrollLeft / s, tr.y - this.container.scrollTop / s);
				this.container.scrollLeft = 0;
				this.container.scrollTop = 0;
			}
			
			if (this.mouseListeners != null)
			{
				var args = [sender, me];
	
				// Does not change returnValue in Opera
				if (!me.getEvent().preventDefault)
				{
					me.getEvent().returnValue = true;
				}
				
				for (var i = 0; i < this.mouseListeners.length; i++)
				{
					var l = this.mouseListeners[i];
					
					if (evtName == mxEvent.MOUSE_DOWN)
					{
						l.mouseDown.apply(l, args);
					}
					else if (evtName == mxEvent.MOUSE_MOVE)
					{
						l.mouseMove.apply(l, args);
					}
					else if (evtName == mxEvent.MOUSE_UP)
					{
						l.mouseUp.apply(l, args);
					}
				}
			}
			
			// Invokes the click handler
			if (evtName == mxEvent.MOUSE_UP)
			{
				this.click(me);
			}
		}
		
		// Detects tapAndHold events using a timer
		if ((mxEvent.isTouchEvent(me.getEvent()) || mxEvent.isPenEvent(me.getEvent())) &&
			evtName == mxEvent.MOUSE_DOWN && this.tapAndHoldEnabled && !this.tapAndHoldInProgress)
		{
			this.tapAndHoldInProgress = true;
			this.initialTouchX = me.getGraphX();
			this.initialTouchY = me.getGraphY();
			
			var handler = function()
			{
				if (this.tapAndHoldValid)
				{
					this.tapAndHold(me);
				}
				
				this.tapAndHoldInProgress = false;
				this.tapAndHoldValid = false;
			};
			
			if (this.tapAndHoldThread)
			{
				window.clearTimeout(this.tapAndHoldThread);
			}
	
			this.tapAndHoldThread = window.setTimeout(mxUtils.bind(this, handler), this.tapAndHoldDelay);
			this.tapAndHoldValid = true;
		}
		else if (evtName == mxEvent.MOUSE_UP)
		{
			this.tapAndHoldInProgress = false;
			this.tapAndHoldValid = false;
		}
		else if (this.tapAndHoldValid)
		{
			this.tapAndHoldValid =
				Math.abs(this.initialTouchX - me.getGraphX()) < this.tolerance &&
				Math.abs(this.initialTouchY - me.getGraphY()) < this.tolerance;
		}

		// Stops editing for all events other than from cellEditor
		if (evtName == mxEvent.MOUSE_DOWN && this.isEditing() && !this.cellEditor.isEventSource(me.getEvent()))
		{
			this.stopEditing(!this.isInvokesStopCellEditing());
		}

		this.consumeMouseEvent(evtName, me, sender);
	}
};

/**
 * Function: consumeMouseEvent
 * 
 * Consumes the given <mxMouseEvent> if it's a touchStart event.
 */
mxGraph.prototype.consumeMouseEvent = function(evtName, me, sender)
{
	// Workaround for duplicate click in Windows 8 with Chrome/FF/Opera with touch
	if (evtName == mxEvent.MOUSE_DOWN && mxEvent.isTouchEvent(me.getEvent()))
	{
		me.consume(false);
	}
};

/**
 * Function: fireGestureEvent
 * 
 * Dispatches a <mxEvent.GESTURE> event. The following example will resize the
 * cell under the mouse based on the scale property of the native touch event.
 * 
 * (code)
 * graph.addListener(mxEvent.GESTURE, function(sender, eo)
 * {
 *   var evt = eo.getProperty('event');
 *   var state = graph.view.getState(eo.getProperty('cell'));
 *   
 *   if (graph.isEnabled() && graph.isCellResizable(state.cell) && Math.abs(1 - evt.scale) > 0.2)
 *   {
 *     var scale = graph.view.scale;
 *     var tr = graph.view.translate;
 *     
 *     var w = state.width * evt.scale;
 *     var h = state.height * evt.scale;
 *     var x = state.x - (w - state.width) / 2;
 *     var y = state.y - (h - state.height) / 2;
 *     
 *     var bounds = new mxRectangle(graph.snap(x / scale) - tr.x,
 *     		graph.snap(y / scale) - tr.y, graph.snap(w / scale), graph.snap(h / scale));
 *     graph.resizeCell(state.cell, bounds);
 *     eo.consume();
 *   }
 * });
 * (end)
 * 
 * Parameters:
 * 
 * evt - Gestureend event that represents the gesture.
 * cell - Optional <mxCell> associated with the gesture.
 */
mxGraph.prototype.fireGestureEvent = function(evt, cell)
{
	// Resets double tap event handling when gestures take place
	this.lastTouchTime = 0;
	this.fireEvent(new mxEventObject(mxEvent.GESTURE, 'event', evt, 'cell', cell));
};

/**
 * Function: destroy
 * 
 * Destroys the graph and all its resources.
 */
mxGraph.prototype.destroy = function()
{
	if (!this.destroyed)
	{
		this.destroyed = true;
		
		if (this.tooltipHandler != null)
		{
			this.tooltipHandler.destroy();
		}
		
		if (this.selectionCellsHandler != null)
		{
			this.selectionCellsHandler.destroy();
		}

		if (this.panningHandler != null)
		{
			this.panningHandler.destroy();
		}

		if (this.popupMenuHandler != null)
		{
			this.popupMenuHandler.destroy();
		}
		
		if (this.connectionHandler != null)
		{
			this.connectionHandler.destroy();
		}
		
		if (this.graphHandler != null)
		{
			this.graphHandler.destroy();
		}
		
		if (this.cellEditor != null)
		{
			this.cellEditor.destroy();
		}
		
		if (this.view != null)
		{
			this.view.destroy();
		}

		if (this.model != null && this.graphModelChangeListener != null)
		{
			this.model.removeListener(this.graphModelChangeListener);
			this.graphModelChangeListener = null;
		}

		this.container = null;
	}
};
