function UIControl(geometry, style, type) {
    var that = this;

    /**
     * The map of combo attributes.
     * key is the attribute name. 
     * value is a array of possible values for the attribute.
     * @member {ComboAttributeMap} 
     */
    var comboAttrMap = new ComboAttributeMap();

    var xmlDoc = mxUtils.createXmlDocument();
    /**
     * Contains the data for the attributes of the ui element
     * A ui element always has a 'id'- and 'class'-attribute
     * @member {XMLDocument}
     */
    var uiObj = xmlDoc.createElement('uiObj');

    //uiObj.setAttribute('_id', '');
    uiObj.setAttribute('_class', '');
    uiObj.setAttribute('uiType', type || this.constructor.name.toLowerCase());


    /**
     * Contains the data of the tags assigned to the ui element.
     * The xml document is appended to the uiObj
     * @member {XMLDocument}
     */
    var tagRoot = xmlDoc.createElement('tagRoot');
    uiObj.append(tagRoot);

    /**
     * The number of tags assigned to the ui element
     * @member {Integer}
     */
    var tagCounter = 0;
    if (!geometry)
        geometry = new mxGeometry(0, 0, 78, 78);
    if (!style)
        style = style = mxConstants.STYLE_SHAPE + "=default;" +
            mxConstants.STYLE_FILLCOLOR + "=white;" +
            mxConstants.STYLE_STROKECOLOR + '=black;' +
            //mxConstants.STYLE_ASPECT + '=fixed;' +
            mxConstants.STYLE_EDITABLE + "=0;";
    mxCell.call(this, uiObj, geometry, style);

    this.setVertex(true);

    /**
     * The callback method for the makeTypeDraggable-function
     * TODO: Find a proper name for the function
     * @param  {Wireframe} wf The wireframe
     * @param  {object} evt a event which is not used
     * @param  {mxCell} dropTarget the target to add the new cell
     * @param  {Integer} x0 x-coordinate
     * @param  {Integer} y0 y-corrdinate
     * @return {String} the id of the created ui component
     */
    this.dropElementCallback = function (wf, evt, dropTarget, x0, y0) {
        wf.stopEditing(false);

        //encode UIControl
        var encoder = new mxCodec();

        //var pt = wf.getPointForEvent(evt);
        if(dropTarget && dropTarget.constructor.name !== 'DivContainer')
            dropTarget = null;
        var v = wf.getModel().cloneCell(that);
        v.geometry.x = dropTarget ? Math.abs(x0 - dropTarget.geometry.x) : x0;
        v.geometry.y = dropTarget ? Math.abs(y0 - dropTarget.geometry.y) : y0;
        var result = encoder.encode(v);

        var xml = mxUtils.getXml(result);
        var id = Util.GUID();
        y.share.action.set(mxEvent.ADD_VERTEX, {
            userId: y.db.userId,
            id: id,
            data: xml,
            parent: dropTarget ? dropTarget.getId() : null
        });
        return id;
    }

    /**
     * Make a type draggable to the canvas
     * @param {object} type the type
     * @param {Wireframe} wireframe the wireframe
     * @return{undefined}
     */
    this.makeTypeDraggable = function (type, wireframe) {
        var preview = document.createElement('div');
        preview.style.width = that.geometry.width + 'px';
        preview.style.height = that.geometry.height + 'px';
        preview.style.border = 'black 0.5px dashed';

        mxUtils.makeDraggable(type, wireframe, that.dropElementCallback, preview, 0, 0);
    }

    /**
     * Set attribute values from json file
     * @param {any} json a json
     * @return{undefined}
     */
    this.setValueFromJson = function (json) {
        for (var key in json) {
            if (this.value.hasAttribute(key)) {
                this.value.setAttribute(key, json[key]);
            }
        }
    }

    /**
     * Get the current number of tags for the ui element
     * @returns {Integer} the tag counter
     */
    this.getTagCounter = function () {
        return tagCounter;
    }

    /**
     * @param  {AbstractTag} tag the tag to add to the ui element
     * @return {undefined}
     */
    this.addTag = function (tag) {
        this.value.getElementsByTagName('tagRoot')[0].appendChild(tag.tagObj);
        tagCounter++;
    }

    /**
     * Remove a Tag by the id
     * @param  {String} tagId the id of the tag as string
     * @return {undefined}
     */
    this.removeTagById = function (tagId) {
        var r = this.value.getElementsByTagName('tagRoot')[0];
        var arr = Array.prototype.slice.call(r.childNodes);
        for (var i = 0; i < arr.length; i++) {
            if (tagId === arr[i].getAttribute('id')) {
                r.removeChild(arr[i]);
                tagCounter--;
                return true;
            }
        }

        return false;
    }

    /**
     * Creates the tags for the ui control
     * @return {undefined}
     */
    this.createTags = function () {
        var that = this;
        var tags = {};
        var _createTag = function (node, point) {
            var tag;
            var C = TagRegistry.getClass(node.getAttribute('tagType'));
            if (C)
                tag = new C(that, point, node.getAttribute('tagType'));
            return tag;
        }

        var children = this.value.childNodes[0].childNodes;
        var arr = Array.prototype.slice.call(children)

        for (var i = 0; i < arr.length; i++) {
            var point = new mxPoint(-CONST.TAG.SIZE * that.getTagCounter(), 0);
            var tag = _createTag(arr[i], point);
            tag.tagObj = arr[i];
            tags[tag.getId()] = tag;
            this.value.getElementsByTagName('tagRoot')[0].appendChild(tag.tagObj);
            tagCounter++;
            if (tag.tagObj.getAttribute('parent') !== '#') {
                var parentTag = tags[tag.tagObj.getAttribute('parent')];
                if (parentTag)
                    parentTag.addChildTag(tag);
            }
        }
        return tags;
    }

    /**
     * Get the combo attribute map for the ui element
     * @return {undefined}
     */
    this.getComboAttrMap = function () {
        return comboAttrMap;
    }

    /**
     * Set the uiType attribute
     * @param {String} type the type of the ui control
     * @return {undefined}
     */
    this.setType = function (type) {
        that.value.setAttribute('uiType', type);
    }
}
/**
 * Base class for all UI components of the editor
 * @classdesc Base abstract class for all UI components of the editor. 
 * @constructor 
 * @param {mxGeometry} geometry the width, height, x and y of the ui element
 * @param {String} style the style of the ui element
 * @param {String} type the type of the ui element
 * @extends mxCells
 * @requires TagRegistry
 * @requires CONST
 * @requires ComboAttributeMap
 */
Base class for all UI components of the editor
@classdesc Base abstract class for all UI components of the editor.
Base class for all UI components of the editor @classdesc Base abstract class for all UI components of the editor .
function UIControl(geometry, style, type) {
    var that = this;
    var comboAttrMap = new ComboAttributeMap();
    var xmlDoc = mxUtils.createXmlDocument();
    var uiObj = xmlDoc.createElement('uiObj');
    uiObj.setAttribute('_class', '');
    uiObj.setAttribute('uiType', type || this.constructor.name.toLowerCase());
    var tagRoot = xmlDoc.createElement('tagRoot');
    uiObj.append(tagRoot);
    var tagCounter = 0;
    if (!geometry)
        geometry = new mxGeometry(0, 0, 78, 78);
    if (!style)
        style = style = mxConstants.STYLE_SHAPE + "=default;" +
            mxConstants.STYLE_FILLCOLOR + "=white;" +
            mxConstants.STYLE_STROKECOLOR + '=black;' +
            mxConstants.STYLE_EDITABLE + "=0;";
    mxCell.call(this, uiObj, geometry, style);
    this.setVertex(true);
    this.dropElementCallback = function (wf, evt, dropTarget, x0, y0) {
        wf.stopEditing(false);
        var encoder = new mxCodec();
        if(dropTarget && dropTarget.constructor.name !== 'DivContainer')
            dropTarget = null;
        var v = wf.getModel().cloneCell(that);
        v.geometry.x = dropTarget ? Math.abs(x0 - dropTarget.geometry.x) : x0;
        v.geometry.y = dropTarget ? Math.abs(y0 - dropTarget.geometry.y) : y0;
        var result = encoder.encode(v);
        var xml = mxUtils.getXml(result);
        var id = Util.GUID();
        y.share.action.set(mxEvent.ADD_VERTEX, {
            userId: y.db.userId,
            id: id,
            data: xml,
            parent: dropTarget ? dropTarget.getId() : null
        });
        return id;
    }
    this.makeTypeDraggable = function (type, wireframe) {
        var preview = document.createElement('div');
        preview.style.width = that.geometry.width + 'px';
        preview.style.height = that.geometry.height + 'px';
        preview.style.border = 'black 0.5px dashed';
        mxUtils.makeDraggable(type, wireframe, that.dropElementCallback, preview, 0, 0);
    }
    this.setValueFromJson = function (json) {
        for (var key in json) {
            if (this.value.hasAttribute(key)) {
                this.value.setAttribute(key, json[key]);
            }
        }
    }
    this.getTagCounter = function () {
        return tagCounter;
    }
    this.addTag = function (tag) {
        this.value.getElementsByTagName('tagRoot')[0].appendChild(tag.tagObj);
        tagCounter++;
    }
    this.removeTagById = function (tagId) {
        var r = this.value.getElementsByTagName('tagRoot')[0];
        var arr = Array.prototype.slice.call(r.childNodes);
        for (var i = 0; i < arr.length; i++) {
            if (tagId === arr[i].getAttribute('id')) {
                r.removeChild(arr[i]);
                tagCounter--;
                return true;
            }
        }
        return false;
    }
    this.createTags = function () {
        var that = this;
        var tags = {};
        var _createTag = function (node, point) {
            var tag;
            var C = TagRegistry.getClass(node.getAttribute('tagType'));
            if (C)
                tag = new C(that, point, node.getAttribute('tagType'));
            return tag;
        }
        var children = this.value.childNodes[0].childNodes;
        var arr = Array.prototype.slice.call(children)
        for (var i = 0; i < arr.length; i++) {
            var point = new mxPoint(-CONST.TAG.SIZE * that.getTagCounter(), 0);
            var tag = _createTag(arr[i], point);
            tag.tagObj = arr[i];
            tags[tag.getId()] = tag;
            this.value.getElementsByTagName('tagRoot')[0].appendChild(tag.tagObj);
            tagCounter++;
            if (tag.tagObj.getAttribute('parent') !== '#') {
                var parentTag = tags[tag.tagObj.getAttribute('parent')];
                if (parentTag)
                    parentTag.addChildTag(tag);
            }
        }
        return tags;
    }
    this.getComboAttrMap = function () {
        return comboAttrMap;
    }
    this.setType = function (type) {
        that.value.setAttribute('uiType', type);
    }
}
function UIControl ( geometry , style , type ) { var that = this ; var comboAttrMap = new ComboAttributeMap ( ) ; var xmlDoc = mxUtils . createXmlDocument ( ) ; var uiObj = xmlDoc . createElement ( 'uiObj' ) ; uiObj . setAttribute ( '_class' , '' ) ; uiObj . setAttribute ( 'uiType' , type || this . constructor . name . toLowerCase ( ) ) ; var tagRoot = xmlDoc . createElement ( 'tagRoot' ) ; uiObj . append ( tagRoot ) ; var tagCounter = 0 ; if ( ! geometry ) geometry = new mxGeometry ( 0 , 0 , 78 , 78 ) ; if ( ! style ) style = style = mxConstants . STYLE_SHAPE + "=default;" + mxConstants . STYLE_FILLCOLOR + "=white;" + mxConstants . STYLE_STROKECOLOR + '=black;' + mxConstants . STYLE_EDITABLE + "=0;" ; mxCell . call ( this , uiObj , geometry , style ) ; this . setVertex ( true ) ; this . dropElementCallback = function ( wf , evt , dropTarget , x0 , y0 ) { wf . stopEditing ( false ) ; var encoder = new mxCodec ( ) ; if ( dropTarget && dropTarget . constructor . name !== 'DivContainer' ) dropTarget = null ; var v = wf . getModel ( ) . cloneCell ( that ) ; v . geometry . x = dropTarget ? Math . abs ( x0 - dropTarget . geometry . x ) : x0 ; v . geometry . y = dropTarget ? Math . abs ( y0 - dropTarget . geometry . y ) : y0 ; var result = encoder . encode ( v ) ; var xml = mxUtils . getXml ( result ) ; var id = Util . GUID ( ) ; y . share . action . set ( mxEvent . ADD_VERTEX , { userId : y . db . userId , id : id , data : xml , parent : dropTarget ? dropTarget . getId ( ) : null } ) ; return id ; } this . makeTypeDraggable = function ( type , wireframe ) { var preview = document . createElement ( 'div' ) ; preview . style . width = that . geometry . width + 'px' ; preview . style . height = that . geometry . height + 'px' ; preview . style . border = 'black 0.5px dashed' ; mxUtils . makeDraggable ( type , wireframe , that . dropElementCallback , preview , 0 , 0 ) ; } this . setValueFromJson = function ( json ) { for ( var key in json ) { if ( this . value . hasAttribute ( key ) ) { this . value . setAttribute ( key , json [ key ] ) ; } } } this . getTagCounter = function ( ) { return tagCounter ; } this . addTag = function ( tag ) { this . value . getElementsByTagName ( 'tagRoot' ) [ 0 ] . appendChild ( tag . tagObj ) ; tagCounter ++ ; } this . removeTagById = function ( tagId ) { var r = this . value . getElementsByTagName ( 'tagRoot' ) [ 0 ] ; var arr = Array . prototype . slice . call ( r . childNodes ) ; for ( var i = 0 ; i < arr . length ; i ++ ) { if ( tagId === arr [ i ] . getAttribute ( 'id' ) ) { r . removeChild ( arr [ i ] ) ; tagCounter -- ; return true ; } } return false ; } this . createTags = function ( ) { var that = this ; var tags = { } ; var _createTag = function ( node , point ) { var tag ; var C = TagRegistry . getClass ( node . getAttribute ( 'tagType' ) ) ; if ( C ) tag = new C ( that , point , node . getAttribute ( 'tagType' ) ) ; return tag ; } var children = this . value . childNodes [ 0 ] . childNodes ; var arr = Array . prototype . slice . call ( children ) for ( var i = 0 ; i < arr . length ; i ++ ) { var point = new mxPoint ( - CONST . TAG . SIZE * that . getTagCounter ( ) , 0 ) ; var tag = _createTag ( arr [ i ] , point ) ; tag . tagObj = arr [ i ] ; tags [ tag . getId ( ) ] = tag ; this . value . getElementsByTagName ( 'tagRoot' ) [ 0 ] . appendChild ( tag . tagObj ) ; tagCounter ++ ; if ( tag . tagObj . getAttribute ( 'parent' ) !== '#' ) { var parentTag = tags [ tag . tagObj . getAttribute ( 'parent' ) ] ; if ( parentTag ) parentTag . addChildTag ( tag ) ; } } return tags ; } this . getComboAttrMap = function ( ) { return comboAttrMap ; } this . setType = function ( type ) { that . value . setAttribute ( 'uiType' , type ) ; } }
Base class for all UI components of the editor
 @classdesc Base abstract class for all UI components of the editor.
Base class for all UI components of the editor @classdesc Base abstract class for all UI components of the editor .
/**
     * The map of combo attributes.
     * key is the attribute name. 
     * value is a array of possible values for the attribute.
     * @member {ComboAttributeMap} 
     */ /**
     * Contains the data for the attributes of the ui element
     * A ui element always has a 'id'- and 'class'-attribute
     * @member {XMLDocument}
     */ //uiObj.setAttribute('_id', ''); /**
     * Contains the data of the tags assigned to the ui element.
     * The xml document is appended to the uiObj
     * @member {XMLDocument}
     */ /**
     * The number of tags assigned to the ui element
     * @member {Integer}
     */ //mxConstants.STYLE_ASPECT + '=fixed;' + /**
     * The callback method for the makeTypeDraggable-function
     * TODO: Find a proper name for the function
     * @param  {Wireframe} wf The wireframe
     * @param  {object} evt a event which is not used
     * @param  {mxCell} dropTarget the target to add the new cell
     * @param  {Integer} x0 x-coordinate
     * @param  {Integer} y0 y-corrdinate
     * @return {String} the id of the created ui component
     */ //encode UIControl //var pt = wf.getPointForEvent(evt); /**
     * Make a type draggable to the canvas
     * @param {object} type the type
     * @param {Wireframe} wireframe the wireframe
     * @return{undefined}
     */ /**
     * Set attribute values from json file
     * @param {any} json a json
     * @return{undefined}
     */ /**
     * Get the current number of tags for the ui element
     * @returns {Integer} the tag counter
     */ /**
     * @param  {AbstractTag} tag the tag to add to the ui element
     * @return {undefined}
     */ /**
     * Remove a Tag by the id
     * @param  {String} tagId the id of the tag as string
     * @return {undefined}
     */ /**
     * Creates the tags for the ui control
     * @return {undefined}
     */ /**
     * Get the combo attribute map for the ui element
     * @return {undefined}
     */ /**
     * Set the uiType attribute
     * @param {String} type the type of the ui control
     * @return {undefined}
     */