text: /**
   * Copyright (c) 2006-2015, JGraph Ltd
   * Copyright (c) 2006-2015, Gaudenz Alder
   */
  mxCodecRegistry.register(function()
  {
  	/**
  	 * Class: mxCellCodec
  	 *
  	 * Codec for <mxCell>s. This class is created and registered
  	 * dynamically at load time and used implicitely via <mxCodec>
  	 * and the <mxCodecRegistry>.
  	 *
  	 * Transient Fields:
  	 *
  	 * - children
  	 * - edges
  	 * - overlays
  	 * - mxTransient
  	 *
  	 * Reference Fields:
  	 *
  	 * - parent
  	 * - source
  	 * - target
  	 * 
  	 * Transient fields can be added using the following code:
  	 * 
  	 * mxCodecRegistry.getCodec(mxCell).exclude.push('name_of_field');
  	 * 
  	 * To subclass <mxCell>, replace the template and add an alias as
  	 * follows.
  	 * 
  	 * (code)
  	 * function CustomCell(value, geometry, style)
  	 * {
  	 *   mxCell.apply(this, arguments);
  	 * }
  	 * 
  	 * mxUtils.extend(CustomCell, mxCell);
  	 * 
  	 * mxCodecRegistry.getCodec(mxCell).template = new CustomCell();
  	 * mxCodecRegistry.addAlias('CustomCell', 'mxCell');
  	 * (end)
  	 */
  	var codec = new mxObjectCodec(new mxCell(),
  		['children', 'edges', 'overlays', 'mxTransient'],
  		['parent', 'source', 'target']);
  
  	/**
  	 * Function: isCellCodec
  	 *
  	 * Returns true since this is a cell codec.
  	 */
  	codec.isCellCodec = function()
  	{
  		return true;
  	};
  
  	/**
  	 * Overidden to disable conversion of value to number.
  	 */
  	codec.isNumericAttribute = function(dec, attr, obj)
  	{
  		return attr.nodeName !== 'value' && mxObjectCodec.prototype.isNumericAttribute.apply(this, arguments);
  	};
  	
  	/**
  	 * Function: isExcluded
  	 *
  	 * Excludes user objects that are XML nodes.
  	 */ 
  	codec.isExcluded = function(obj, attr, value, isWrite)
  	{
  		return mxObjectCodec.prototype.isExcluded.apply(this, arguments) ||
  			(isWrite && attr == 'value' &&
  			value.nodeType == mxConstants.NODETYPE_ELEMENT);
  	};
  	
  	/**
  	 * Function: afterEncode
  	 *
  	 * Encodes an <mxCell> and wraps the XML up inside the
  	 * XML of the user object (inversion).
  	 */
  	codec.afterEncode = function(enc, obj, node)
  	{
  		if (obj.value != null && obj.value.nodeType == mxConstants.NODETYPE_ELEMENT)
  		{
  			// Wraps the graphical annotation up in the user object (inversion)
  			// by putting the result of the default encoding into a clone of the
  			// user object (node type 1) and returning this cloned user object.
  			var tmp = node;
  			node = mxUtils.importNode(enc.document, obj.value, true);
  			node.appendChild(tmp);
  			
  			// Moves the id attribute to the outermost XML node, namely the
  			// node which denotes the object boundaries in the file.
  			var id = tmp.getAttribute('id');
  			node.setAttribute('id', id);
  			tmp.removeAttribute('id');
  		}
  
  		return node;
  	};
  
  	/**
  	 * Function: beforeDecode
  	 *
  	 * Decodes an <mxCell> and uses the enclosing XML node as
  	 * the user object for the cell (inversion).
  	 */
  	codec.beforeDecode = function(dec, node, obj)
  	{
  		var inner = node.cloneNode(true);
  		var classname = this.getName();
  		
  		if (node.nodeName != classname)
  		{
  			// Passes the inner graphical annotation node to the
  			// object codec for further processing of the cell.
  			var tmp = node.getElementsByTagName(classname)[0];
  			
  			if (tmp != null && tmp.parentNode == node)
  			{
  				mxUtils.removeWhitespace(tmp, true);
  				mxUtils.removeWhitespace(tmp, false);
  				tmp.parentNode.removeChild(tmp);
  				inner = tmp;
  			}
  			else
  			{
  				inner = null;
  			}
  			
  			// Creates the user object out of the XML node
  			obj.value = node.cloneNode(true);
  			var id = obj.value.getAttribute('id');
  			
  			if (id != null)
  			{
  				obj.setId(id);
  				obj.value.removeAttribute('id');
  			}
  		}
  		else
  		{
  			// Uses ID from XML file as ID for cell in model
  			obj.setId(node.getAttribute('id'));
  		}
  			
  		// Preprocesses and removes all Id-references in order to use the
  		// correct encoder (this) for the known references to cells (all).
  		if (inner != null)
  		{
  			for (var i = 0; i < this.idrefs.length; i++)
  			{
  				var attr = this.idrefs[i];
  				var ref = inner.getAttribute(attr);
  				
  				if (ref != null)
  				{
  					inner.removeAttribute(attr);
  					var object = dec.objects[ref] || dec.lookup(ref);
  					
  					if (object == null)
  					{
  						// Needs to decode forward reference
  						var element = dec.getElementById(ref);
  						
  						if (element != null)
  						{
  							var decoder = mxCodecRegistry.codecs[element.nodeName] || this;
  							object = decoder.decode(dec, element);
  						}
  					}
  					
  					obj[attr] = object;
  				}
  			}
  		}
  		
  		return inner;
  	};
  
  	// Returns the codec into the registry
  	return codec;
  
  }());
  