text: /**
   * Abstract shape element. Shape element represents some visual vector or raster object.
   * @constructor
   * @param {String} name Tag name of the element.
   * @param {Object} config Set of parameters to initialize element with.
   * @param {Object} style Object with styles to set on element initialization.
   */
  jvm.AbstractShapeElement = function(name, config, style){
    this.style = style || {};
    this.style.current = {};
    this.isHovered = false;
    this.isSelected = false;
    this.updateStyle();
  };
  
  /**
   * Set hovered state to the element. Hovered state means mouse cursor is over element. Styles will be updates respectively.
   * @param {Boolean} isHovered <code>true</code> to make element hovered, <code>false</code> otherwise.
   */
  jvm.AbstractShapeElement.prototype.setHovered = function(isHovered){
    if (this.isHovered !== isHovered) {
      this.isHovered = isHovered;
      this.updateStyle();
    }
  };
  
  /**
   * Set selected state to the element. Styles will be updates respectively.
   * @param {Boolean} isSelected <code>true</code> to make element selected, <code>false</code> otherwise.
   */
  jvm.AbstractShapeElement.prototype.setSelected = function(isSelected){
    if (this.isSelected !== isSelected) {
      this.isSelected = isSelected;
      this.updateStyle();
      jvm.$(this.node).trigger('selected', [isSelected]);
    }
  };
  
  /**
   * Set element's style.
   * @param {Object|String} property Could be string to set only one property or object to set several style properties at once.
   * @param {String} value Value to set in case only one property should be set.
   */
  jvm.AbstractShapeElement.prototype.setStyle = function(property, value){
    var styles = {};
  
    if (typeof property === 'object') {
      styles = property;
    } else {
      styles[property] = value;
    }
    jvm.$.extend(this.style.current, styles);
    this.updateStyle();
  };
  
  
  jvm.AbstractShapeElement.prototype.updateStyle = function(){
    var attrs = {};
  
    jvm.AbstractShapeElement.mergeStyles(attrs, this.style.initial);
    jvm.AbstractShapeElement.mergeStyles(attrs, this.style.current);
    if (this.isHovered) {
      jvm.AbstractShapeElement.mergeStyles(attrs, this.style.hover);
    }
    if (this.isSelected) {
      jvm.AbstractShapeElement.mergeStyles(attrs, this.style.selected);
      if (this.isHovered) {
        jvm.AbstractShapeElement.mergeStyles(attrs, this.style.selectedHover);
      }
    }
    this.set(attrs);
  };
  
  jvm.AbstractShapeElement.mergeStyles = function(styles, newStyles){
    var key;
  
    newStyles = newStyles || {};
    for (key in newStyles) {
      if (newStyles[key] === null) {
        delete styles[key];
      } else {
        styles[key] = newStyles[key];
      }
    }
  }