docs: function createAction(config){
      // make a copy of config with defaults
      config = basis.object.extend({
        prepare: nothingToDo,
        request: nothingToDo
      }, config);
  
      // if body is function take in account special action context
      if (typeof config.body == 'function')
      {
        var bodyFn = config.body;
        config.body = function(){
          return bodyFn.apply(this.context, this.args);
        };
      }
  
      // splice properties
      var fn = basis.object.splice(config, ['prepare', 'request']);
      var callback = basis.object.merge(
        DEFAULT_CALLBACK,
        basis.object.splice(config, ['start', 'success', 'failure', 'abort', 'complete'])
      );
  
      // lazy transport
      var getTransport = basis.fn.lazyInit(function(){
        var transport = resolveTransport(config);
  
        transport.addHandler(CALLBACK_HANDLER, callback);
  
        return transport;
      });
  
      return function action(){
        // this - instance of AbstractData
        if (this.state != STATE_PROCESSING)
        {
          if (fn.prepare.apply(this, arguments))
          {
            /** @cut */ basis.dev.info('Prepare handler returns trulthy result. Operation aborted. Context: ', this);
            return Promise.reject('Prepare handler returns trulthy result. Operation aborted. Context: ', this);
          }
  
          var request;
          var requestData = basis.object.complete({
            origin: this,
            bodyContext: {
              context: this,
              args: basis.array(arguments)
            }
          }, fn.request.apply(this, arguments));
  
          // if body is function take in account special action context
          if (typeof requestData.body == 'function')
          {
            var bodyFn = requestData.body;
            requestData.body = function(){
              return bodyFn.apply(this.context, this.args);
            };
          }
  
          // do a request
          if (request = getTransport().request(requestData))
            return new Promise(function(fulfill, reject){
              request.addHandler(PROMISE_REQUEST_HANDLER, {
                request: request,
                fulfill: fulfill,
                reject: reject
              });
            });
  
          return Promise.reject('Request is not performed');
        }
        else
        {
          /** @cut */ basis.dev.warn('Context in processing state. Operation aborted. Context: ', this);
          return Promise.reject('Context in processing state, request is not performed');
        }
      };
    }