text: 'use strict';
  
  var NodeHTTPParser = require('http-parser-js').HTTPParser;
  
  var VERSION = process.version.match(/[0-9]+/g).map(function(n) { return parseInt(n, 10) });
  
  var TYPES = {
    request:  NodeHTTPParser.REQUEST  || 'request',
    response: NodeHTTPParser.RESPONSE || 'response'
  };
  
  var HttpParser = function(type) {
    this._type     = type;
    this._parser   = new NodeHTTPParser(TYPES[type]);
    this._complete = false;
    this.headers   = {};
  
    var current = null,
        self    = this;
  
    this._parser.onHeaderField = function(b, start, length) {
      current = b.toString('utf8', start, start + length).toLowerCase();
    };
  
    this._parser.onHeaderValue = function(b, start, length) {
      var value = b.toString('utf8', start, start + length);
  
      if (self.headers.hasOwnProperty(current))
        self.headers[current] += ', ' + value;
      else
        self.headers[current] = value;
    };
  
    this._parser.onHeadersComplete = this._parser[NodeHTTPParser.kOnHeadersComplete] =
    function(majorVersion, minorVersion, headers, method, pathname, statusCode) {
      var info = arguments[0];
  
      if (typeof info === 'object') {
        method     = info.method;
        pathname   = info.url;
        statusCode = info.statusCode;
        headers    = info.headers;
      }
  
      self.method     = (typeof method === 'number') ? HttpParser.METHODS[method] : method;
      self.statusCode = statusCode;
      self.url        = pathname;
  
      if (!headers) return;
  
      for (var i = 0, n = headers.length, key, value; i < n; i += 2) {
        key   = headers[i].toLowerCase();
        value = headers[i+1];
        if (self.headers.hasOwnProperty(key))
          self.headers[key] += ', ' + value;
        else
          self.headers[key] = value;
      }
  
      self._complete = true;
    };
  };
  
  HttpParser.METHODS = {
    0:  'DELETE',
    1:  'GET',
    2:  'HEAD',
    3:  'POST',
    4:  'PUT',
    5:  'CONNECT',
    6:  'OPTIONS',
    7:  'TRACE',
    8:  'COPY',
    9:  'LOCK',
    10: 'MKCOL',
    11: 'MOVE',
    12: 'PROPFIND',
    13: 'PROPPATCH',
    14: 'SEARCH',
    15: 'UNLOCK',
    16: 'BIND',
    17: 'REBIND',
    18: 'UNBIND',
    19: 'ACL',
    20: 'REPORT',
    21: 'MKACTIVITY',
    22: 'CHECKOUT',
    23: 'MERGE',
    24: 'M-SEARCH',
    25: 'NOTIFY',
    26: 'SUBSCRIBE',
    27: 'UNSUBSCRIBE',
    28: 'PATCH',
    29: 'PURGE',
    30: 'MKCALENDAR',
    31: 'LINK',
    32: 'UNLINK'
  };
  
  if (VERSION[0] === 0 && VERSION[1] === 12) {
    HttpParser.METHODS[16] = 'REPORT';
    HttpParser.METHODS[17] = 'MKACTIVITY';
    HttpParser.METHODS[18] = 'CHECKOUT';
    HttpParser.METHODS[19] = 'MERGE';
    HttpParser.METHODS[20] = 'M-SEARCH';
    HttpParser.METHODS[21] = 'NOTIFY';
    HttpParser.METHODS[22] = 'SUBSCRIBE';
    HttpParser.METHODS[23] = 'UNSUBSCRIBE';
    HttpParser.METHODS[24] = 'PATCH';
    HttpParser.METHODS[25] = 'PURGE';
  }
  
  HttpParser.prototype.isComplete = function() {
    return this._complete;
  };
  
  HttpParser.prototype.parse = function(chunk) {
    var consumed = this._parser.execute(chunk, 0, chunk.length);
  
    if (typeof consumed !== 'number') {
      this.error     = consumed;
      this._complete = true;
      return;
    }
  
    if (VERSION[0] === 0 && VERSION[1] < 6) consumed += 1;
  
    if (this._complete)
      this.body = (consumed < chunk.length)
                ? chunk.slice(consumed)
                : new Buffer(0);
  };
  
  module.exports = HttpParser;
  