/**
 * @class CM_StreamChannel_Definition
 * @extends CM_Frontend_JsonSerializable
 */
var CM_StreamChannel_Definition = CM_Frontend_JsonSerializable.extend({

  _class: 'CM_StreamChannel_Definition',

  /**
   * @returns {String}
   */
  getKey: function() {
    return this.get('key');
  },

  /**
   * @returns {Number}
   */
  getType: function() {
    return this.get('type');
  },

  /**
   * @param {String} eventName
   * @param {Function} callback fn(array data)
   * @param {Object} [context]
   * @param {Boolean} [allowClientMessage]
   */
  addStreamEventListener: function(eventName, callback, context, allowClientMessage) {
    cm.stream.bind(this.getKey(), this.getType(), eventName, callback, context, allowClientMessage);
  },

  /**
   * @param {String} [eventName]
   * @param {Function} [callback]
   * @param {Object} [context]
   */
  removeStreamEventListener: function(eventName, callback, context) {
    cm.stream.unbind(this.getKey(), this.getType(), eventName, callback, context);
  }
});

@@ -412,64 +412,919 @@
 ng%7D 
-eventName%0A   * @param %7BFunction%7D callback fn(array data)
+action%0A   * @param %7BCM_StreamChannel_Definition~actionCallback%7D callback%0A   * @param %7B*%7D %5Bcontext%5D%0A   */%0A  addActionEventListener: function(action, callback, context) %7B%0A    action = this._extractActionInfo(action);%0A    cm.action.bind(action.verb, action.type, this.getKey(), this.getType(), function(response) %7B%0A      /**%0A       * @callback CM_StreamChannel_Definition~actionCallback%0A       * @param %7BObject%7D action%0A       * @param %7BCM_Model_Abstract%7D model%0A       * @param %7BArray%7D data%0A       */%0A      callback.call(context, response.action, response.model, response.data);%0A    %7D);%0A  %7D,%0A%0A  /**%0A   * @param %7BString%7D action%0A   */%0A  removeActionEventListeners: function(action) %7B%0A    action = this._extractActionInfo(action);%0A    cm.action.unbind(action.verb, action.type, this.getKey(), this.getType());%0A  %7D,%0A%0A  /**%0A   * @param %7BString%7D eventName%0A   * @param %7BCM_StreamChannel_Definition~streamCallback%7D callback
 %0A   
@@ -1483,24 +1483,127 @@
 tMessage) %7B%0A
+    /**%0A     * @callback CM_StreamChannel_Definition~streamCallback%0A     * @param %7BArray%7D data%0A     */%0A
     cm.strea
@@ -1753,16 +1753,50 @@
 am %7B
-Function
+CM_StreamChannel_Definition~streamCallback
 %7D %5Bc
@@ -1860,32 +1860,33 @@
 eamEventListener
+s
 : function(event
@@ -1995,16 +1995,518 @@
 ntext);%0A
+  %7D,%0A%0A  /**%0A   * @param %7BString%7D action%0A   * @returns %7B%7Btype: Number, verb: String%7D%7D%0A   * @private%0A   */%0A  _extractActionInfo: function(action) %7B%0A    if (!/%5E(%5CS+)%5Cs+(.+)$/.test(action)) %7B%0A      throw new Error('StreamChannel action syntax error.');%0A    %7D%0A    var match = action.match(/%5E(%5CS+)%5Cs+(.+)$/);%0A    if (!_.isNumber(cm.action.types%5Bmatch%5B1%5D%5D)) %7B%0A      throw new Error('StreamChannel action type not found.');%0A    %7D%0A    return %7B%0A      type: cm.action.types%5Bmatch%5B1%5D%5D,%0A      verb: match%5B2%5D%0A    %7D;%0A
   %7D%0A%7D);%0A

Add action binding methods to CM_StreamChannel_Definition