/**@module api-requester*/
modules.define('api-requester', [
    'api-request', 'app-logger', 'objects'
], function (provide, ApiRequest, logger, objects, ApiRequester) {
    "use strict";

    var request = require('request'),
        Readable = require('stream').Readable;

    /**
     * @class ApiRequester
     * @extends BEM
     * @exports
     */
    provide(ApiRequester.decl(/**@lends ApiRequester.prototype*/{

        /**
         * @param {String} method
         * @param {String} [route]
         * @param {?Object} [routeParameters]
         * @param {String|Object|Readable} [body]
         * @returns {ApiRequest}
         */
        sendRequest: function (method, route, routeParameters, body) {
            var url = this.params.router.generate(route, routeParameters),
                apiRequest = new ApiRequest(),
                _this = this,
                jar = request.jar(this.params.cookieStorage);

            var requestCallback = function (err, res, body) {
                var parsedBody;

                try {
                    parsedBody = _this._processBody(res, body);
                } catch (e) {
                    logger.error('API response on ' + method.toUpperCase() + ' ' + url + ' can not be parsed');
                    logger.error('API response body:');
                    logger.error(body);
                    apiRequest.reject(e);
                    return;
                }

                var output = {
                    error: err ? err.message : '',
                    body: parsedBody
                };
                if (res) {
                    output.response = {
                        statusCode: res.statusCode,
                        statusText: res.statusText
                    };
                }
                var badStatus = res && (res.statusCode < 200 || res.statusCode > 299);
                if (badStatus) {
                    if (!output.error) {
                        output.error = output.body;
                    }
                }
                if (err) {
                    logger.error('API request ' + method.toUpperCase() + ' ' + url + ' error:');
                    logger.error(err);
                    apiRequest.reject(output);
                } else if (badStatus) {
                    logger.warn('API request ' + method.toUpperCase() + ' ' + url + ' has status ' + res.statusCode);
                    logger.warn(output.error);
                    apiRequest.reject(output);
                } else {
                    apiRequest.resolve(output);
                }
            };

            var req;
            if (body && body instanceof Readable) {
                req = body.pipe(request({
                    url: url,
                    method: method,
                    jar: jar
                }, requestCallback));
            } else {
                var preparedBody = typeof body === 'object' ? JSON.stringify(body) : body;
                req = request({
                    url: url,
                    method: method,
                    headers: this._getRequestHeaders(route),
                    body: preparedBody,
                    gzip: true,
                    jar: jar
                }, requestCallback);
            }
            apiRequest.setRequest(req);
            return apiRequest;
        },

        /**
         * @param {String} route
         * @returns {Object}
         * @protected
         */
        _getRequestHeaders: function (route) {
            return {
                'Accept': 'application/json',
                'Content-Type': 'application/json',
                'Connection': 'keep-alive'
            };
        },

        /**
         * @param {OutgoingMessage} res
         * @param {String} body
         * @returns {String|Object}
         * @throws {Error} if JSON is malformed
         * @private
         */
        _processBody: function (res, body) {
            if (res && /json/.test(res.headers['content-type'])) {
                return JSON.parse(body);
            }
            return body;
        }
    }));
});

@@ -415,16 +415,116 @@
 ype*/%7B%0A%0A
+        /**%0A         * @type function%0A         * @protected%0A         */%0A        _request: request,%0A%0A
         
@@ -958,16 +958,187 @@
 s = this
+;%0A%0A            apiRequest.setRequest(this._sendRequest(%7B%0A                route: route,%0A                url: url,%0A                method: method,%0A                body: body
 ,%0A      
@@ -1150,18 +1150,17 @@
      jar
- =
+:
  request
@@ -1190,18 +1190,16 @@
 Storage)
-;%0A
 %0A       
@@ -1207,29 +1207,10 @@
     
-var requestCallback =
+%7D,
  fun
@@ -2852,124 +2852,554 @@
    %7D
-;%0A%0A            var req;%0A            if (body && body instanceof Readable) %7B%0A                req = body.pipe(request(
+));%0A            return apiRequest;%0A        %7D,%0A%0A        /**%0A         * @param %7Bobject%7D options%0A         * @param %7Bstring%7D options.route%0A         * @param %7Bstring%7D options.url%0A         * @param %7Bstring%7D options.method%0A         * @param %7Bstring%7Cobject%7D options.body%0A         * @param %7BCookieJar%7D options.jar%0A         * @param %7Bfunction%7D requestCallback%0A         * @returns %7Bobject%7D%0A         * @protected%0A         */%0A        _sendRequest: function (options, requestCallback) %7B%0A            var body = options.body,%0A                requestParameters = 
 %7B%0A  
@@ -3413,32 +3413,40 @@
            url: 
+options.
 url,%0A           
@@ -3454,32 +3454,40 @@
         method: 
+options.
 method,%0A        
@@ -3495,32 +3495,40 @@
            jar: 
+options.
 jar%0A            
@@ -3524,32 +3524,150 @@
                %7D
+;%0A            if (body && body instanceof Readable) %7B%0A                return body.pipe(this._request(requestParameters
 , requestCallbac
@@ -3680,36 +3680,26 @@
            %7D
- else %7B%0A    
+%0A%0A
             
@@ -3789,98 +3789,65 @@
     
-    req = request(%7B%0A                    url: url,%0A                    method: method,%0A    
+return this._request(objects.extend(requestParameters, %7B%0A
     
@@ -3895,16 +3895,24 @@
 ers(
+options.
 route),%0A
     
@@ -3907,20 +3907,16 @@
 route),%0A
-    
         
@@ -3959,20 +3959,16 @@
         
-    
 gzip: tr
@@ -3973,43 +3973,9 @@
 true
-,%0A                    jar: jar%0A    
+%0A
     
@@ -3983,16 +3983,17 @@
        %7D
+)
 , reques
@@ -4008,93 +4008,8 @@
 k);%0A
-            %7D%0A            apiRequest.setRequest(req);%0A            return apiRequest;%0A
     

Add ability to redefine requests sending from node to api