text: var fs = require('fs'),
      WritableStream = require('stream').Writable
                       || require('readable-stream').Writable,
      inherits = require('util').inherits;
  
  var parseParams = require('./utils').parseParams;
  
  function Busboy(opts) {
    if (!(this instanceof Busboy))
      return new Busboy(opts);
    if (opts.highWaterMark !== undefined)
      WritableStream.call(this, { highWaterMark: opts.highWaterMark });
    else
      WritableStream.call(this);
  
    this._done = false;
    this._parser = undefined;
  
    this.opts = opts;
    if (opts.headers && typeof opts.headers['content-type'] === 'string')
      this.parseHeaders(opts.headers);
  }
  inherits(Busboy, WritableStream);
  
  Busboy.prototype.emit = function(ev) {
    if (ev === 'finish' && !this._done)
      this._parser && this._parser.end();
    else
      WritableStream.prototype.emit.apply(this, arguments);
  };
  
  Busboy.prototype.parseHeaders = function(headers) {
    this._parser = undefined;
    if (headers['content-type']) {
      var parsed = parseParams(headers['content-type']),
          matched, type;
      for (var i = 0; i < TYPES_LEN; ++i) {
        type = TYPES[i];
        if (typeof type.detect === 'function')
          matched = type.detect(parsed);
        else
          matched = type.detect.test(parsed[0]);
        if (matched)
          break;
      }
      if (matched) {
        var cfg = {
          limits: this.opts.limits,
          headers: headers,
          parsedConType: parsed,
          highWaterMark: undefined,
          fileHwm: undefined,
          defCharset: undefined
        };
        if (this.opts.highWaterMark)
          cfg.highWaterMark = this.opts.highWaterMark;
        if (this.opts.fileHwm)
          cfg.fileHwm = this.opts.fileHwm;
        cfg.defCharset = this.opts.defCharset;
        this._parser = type(this, cfg);
        return;
      }
    }
    throw new Error('Unsupported content type: ' + headers['content-type']);
  };
  
  Busboy.prototype._write = function(chunk, encoding, cb) {
    if (!this._parser)
      return cb(new Error('Not ready to parse. Missing Content-Type?'));
    this._parser.write(chunk, cb);
  };
  
  var TYPES = [], TYPES_LEN = 0;
  fs.readdirSync(__dirname + '/types').forEach(function(type) {
    var typemod = require(__dirname + '/types/' + type);
    if (typemod.detect) {
      TYPES.push(typemod);
      ++TYPES_LEN;
    }
  });
  
  module.exports = Busboy;
  