text: 'use strict';
  
  var extend  = require('../util/extend'),
      Logging = require('../mixins/logging');
  
  var Extensible = {
    addExtension: function(extension) {
      this._extensions = this._extensions || [];
      this._extensions.push(extension);
      if (extension.added) extension.added(this);
    },
  
    removeExtension: function(extension) {
      if (!this._extensions) return;
      var i = this._extensions.length;
      while (i--) {
        if (this._extensions[i] !== extension) continue;
        this._extensions.splice(i,1);
        if (extension.removed) extension.removed(this);
      }
    },
  
    pipeThroughExtensions: function(stage, message, request, callback, context) {
      this.debug('Passing through ? extensions: ?', stage, message);
  
      if (!this._extensions) return callback.call(context, message);
      var extensions = this._extensions.slice();
  
      var pipe = function(message) {
        if (!message) return callback.call(context, message);
  
        var extension = extensions.shift();
        if (!extension) return callback.call(context, message);
  
        var fn = extension[stage];
        if (!fn) return pipe(message);
  
        if (fn.length >= 3) extension[stage](message, request, pipe);
        else                extension[stage](message, pipe);
      };
      pipe(message);
    }
  };
  
  extend(Extensible, Logging);
  
  module.exports = Extensible;
  