text: /*!
   * chai
   * http://chaijs.com
   * Copyright(c) 2011-2012 Jake Luer <jake@alogicalparadox.com>
   * MIT Licensed
   */
  
  module.exports = function (chai, _) {
    var Assertion = chai.Assertion
      , toString = Object.prototype.toString
      , flag = _.flag;
  
    /**
     * ### Language Chains
     *
     * The following are provide as chainable getters to
     * improve the readability of your assertions. They
     * do not provide an testing capability unless they
     * have been overwritten by a plugin.
     *
     * **Chains**
     *
     * - to
     * - be
     * - been
     * - is
     * - that
     * - and
     * - have
     * - with
     *
     * @name language chains
     * @api public
     */
  
    [ 'to', 'be', 'been'
    , 'is', 'and', 'have'
    , 'with', 'that' ].forEach(function (chain) {
      Assertion.addProperty(chain, function () {
        return this;
      });
    });
  
    /**
     * ### .not
     *
     * Negates any of assertions following in the chain.
     *
     *     expect(foo).to.not.equal('bar');
     *     expect(goodFn).to.not.throw(Error);
     *     expect({ foo: 'baz' }).to.have.property('foo')
     *       .and.not.equal('bar');
     *
     * @name not
     * @api public
     */
  
    Assertion.addProperty('not', function () {
      flag(this, 'negate', true);
    });
  
    /**
     * ### .deep
     *
     * Sets the `deep` flag, later used by the `equal` and
     * `property` assertions.
     *
     *     expect(foo).to.deep.equal({ bar: 'baz' });
     *     expect({ foo: { bar: { baz: 'quux' } } })
     *       .to.have.deep.property('foo.bar.baz', 'quux');
     *
     * @name deep
     * @api public
     */
  
    Assertion.addProperty('deep', function () {
      flag(this, 'deep', true);
    });
  
    /**
     * ### .a(type)
     *
     * The `a` and `an` assertions are aliases that can be
     * used either as language chains or to assert a value's
     * type (as revealed by `Object.prototype.toString`).
     *
     *     // typeof
     *     expect('test').to.be.a('string');
     *     expect({ foo: 'bar' }).to.be.an('object');
     *     expect(null).to.be.a('null');
     *     expect(undefined).to.be.an('undefined');
     *
     *     // language chain
     *     expect(foo).to.be.an.instanceof(Foo);
     *
     * @name a
     * @alias an
     * @param {String} type
     * @api public
     */
  
    function an(type) {
      var obj = flag(this, 'object')
        , klassStart = type.charAt(0).toUpperCase()
        , klass = klassStart + type.slice(1)
        , article = ~[ 'A', 'E', 'I', 'O', 'U' ].indexOf(klassStart) ? 'an ' : 'a ';
  
      this.assert(
          '[object ' + klass + ']' === toString.call(obj)
        , 'expected #{this} to be ' + article + type
        , 'expected #{this} not to be ' + article + type
      );
    }
  
    Assertion.addChainableMethod('an', an);
    Assertion.addChainableMethod('a', an);
  
    /**
     * ### .include(value)
     *
     * The `include` and `contain` assertions can be used as either property
     * based language chains or as methods to assert the inclusion of an object
     * in an array or a substring in a string. When used as language chains,
     * they toggle the `contain` flag for the `keys` assertion.
     *
     *     expect([1,2,3]).to.include(2);
     *     expect('foobar').to.contain('foo');
     *     expect({ foo: 'bar', hello: 'universe' }).to.include.keys('foo');
     *
     * @name include
     * @alias contain
     * @param {Object|String|Number} obj
     * @api public
     */
  
    function includeChainingBehavior () {
      flag(this, 'contains', true);
    }
  
    function include (val) {
      var obj = flag(this, 'object')
      this.assert(
          ~obj.indexOf(val)
        , 'expected #{this} to include ' + _.inspect(val)
        , 'expected #{this} to not include ' + _.inspect(val));
    }
  
    Assertion.addChainableMethod('include', include, includeChainingBehavior);
    Assertion.addChainableMethod('contain', include, includeChainingBehavior);
  
    /**
     * ### .ok
     *
     * Asserts that the target is truthy.
     *
     *     expect('everthing').to.be.ok;
     *     expect(1).to.be.ok;
     *     expect(false).to.not.be.ok;
     *     expect(undefined).to.not.be.ok;
     *     expect(null).to.not.be.ok;
     *
     * @name ok
     * @api public
     */
  
    Assertion.addProperty('ok', function () {
      this.assert(
          flag(this, 'object')
        , 'expected #{this} to be truthy'
        , 'expected #{this} to be falsy');
    });
  
    /**
     * ### .true
     *
     * Asserts that the target is `true`.
     *
     *     expect(true).to.be.true;
     *     expect(1).to.not.be.true;
     *
     * @name true
     * @api public
     */
  
    Assertion.addProperty('true', function () {
      this.assert(
          true === flag(this, 'object')
        , 'expected #{this} to be true'
        , 'expected #{this} to be false'
        , this.negate ? false : true
      );
    });
  
    /**
     * ### .false
     *
     * Asserts that the target is `false`.
     *
     *     expect(false).to.be.false;
     *     expect(0).to.not.be.false;
     *
     * @name false
     * @api public
     */
  
    Assertion.addProperty('false', function () {
      this.assert(
          false === flag(this, 'object')
        , 'expected #{this} to be false'
        , 'expected #{this} to be true'
        , this.negate ? true : false
      );
    });
  
    /**
     * ### .null
     *
     * Asserts that the target is `null`.
     *
     *     expect(null).to.be.null;
     *     expect(undefined).not.to.be.null;
     *
     * @name null
     * @api public
     */
  
    Assertion.addProperty('null', function () {
      this.assert(
          null === flag(this, 'object')
        , 'expected #{this} to be null'
        , 'expected #{this} not to be null'
      );
    });
  
    /**
     * ### .undefined
     *
     * Asserts that the target is `undefined`.
     *
     *      expect(undefined).to.be.undefined;
     *      expect(null).to.not.be.undefined;
     *
     * @name undefined
     * @api public
     */
  
    Assertion.addProperty('undefined', function () {
      this.assert(
          undefined === flag(this, 'object')
        , 'expected #{this} to be undefined'
        , 'expected #{this} not to be undefined'
      );
    });
  
    /**
     * ### .exist
     *
     * Asserts that the target is neither `null` nor `undefined`.
     *
     *     var foo = 'hi'
     *       , bar = null
     *       , baz;
     *
     *     expect(foo).to.exist;
     *     expect(bar).to.not.exist;
     *     expect(baz).to.not.exist;
     *
     * @name exist
     * @api public
     */
  
    Assertion.addProperty('exist', function () {
      this.assert(
          null != flag(this, 'object')
        , 'expected #{this} to exist'
        , 'expected #{this} to not exist'
      );
    });
  
  
    /**
     * ### .empty
     *
     * Asserts that the target's length is `0`. For arrays, it checks
     * the `length` property. For objects, it gets the count of
     * enumerable keys.
     *
     *     expect([]).to.be.empty;
     *     expect('').to.be.empty;
     *     expect({}).to.be.empty;
     *
     * @name empty
     * @api public
     */
  
    Assertion.addProperty('empty', function () {
      var obj = flag(this, 'object')
        , expected = obj;
  
      if (Array.isArray(obj) || 'string' === typeof object) {
        expected = obj.length;
      } else if (typeof obj === 'object') {
        expected = Object.keys(obj).length;
      }
  
      this.assert(
          !expected
        , 'expected #{this} to be empty'
        , 'expected #{this} not to be empty'
      );
    });
  
    /**
     * ### .arguments
     *
     * Asserts that the target is an arguments object.
     *
     *     function test () {
     *       expect(arguments).to.be.arguments;
     *     }
     *
     * @name arguments
     * @alias Arguments
     * @api public
     */
  
    function checkArguments () {
      var obj = flag(this, 'object')
        , type = Object.prototype.toString.call(obj);
      this.assert(
          '[object Arguments]' === type
        , 'expected #{this} to be arguments but got ' + type
        , 'expected #{this} to not be arguments'
      );
    }
  
    Assertion.addProperty('arguments', checkArguments);
    Assertion.addProperty('Arguments', checkArguments);
  
    /**
     * ### .equal(value)
     *
     * Asserts that the target is strictly equal (`===`) to `value`.
     * Alternately, if the `deep` flag is set, asserts that
     * the target is deeply equal to `value`.
     *
     *     expect('hello').to.equal('hello');
     *     expect(42).to.equal(42);
     *     expect(1).to.not.equal(true);
     *     expect({ foo: 'bar' }).to.not.equal({ foo: 'bar' });
     *     expect({ foo: 'bar' }).to.deep.equal({ foo: 'bar' });
     *
     * @name equal
     * @alias equals
     * @alias eq
     * @alias deep.equal
     * @param {Mixed} value
     * @api public
     */
  
    function assertEqual (val) {
      var obj = flag(this, 'object');
      if (flag(this, 'deep')) {
        return this.eql(val);
      } else {
        this.assert(
            val === obj
          , 'expected #{this} to equal #{exp}'
          , 'expected #{this} to not equal #{exp}'
          , val
        );
      }
    }
  
    Assertion.addMethod('equal', assertEqual);
    Assertion.addMethod('equals', assertEqual);
    Assertion.addMethod('eq', assertEqual);
  
    /**
     * ### .eql(value)
     *
     * Asserts that the target is deeply equal to `value`.
     *
     *     expect({ foo: 'bar' }).to.eql({ foo: 'bar' });
     *     expect([ 1, 2, 3 ]).to.eql([ 1, 2, 3 ]);
     *
     * @name eql
     * @param {Mixed} value
     * @api public
     */
  
    Assertion.addMethod('eql', function (obj) {
      this.assert(
          _.eql(obj, flag(this, 'object'))
        , 'expected #{this} to deeply equal #{exp}'
        , 'expected #{this} to not deeply equal #{exp}'
        , obj
      );
    });
  
    /**
     * ### .above(value)
     *
     * Asserts that the target is greater than `value`.
     *
     *     expect(10).to.be.above(5);
     *
     * Can also be used in conjunction with `length` to
     * assert a minimum length. The benefit being a
     * more informative error message than if the length
     * was supplied directly.
     *
     *     expect('foo').to.have.length.above(2);
     *     expect([ 1, 2, 3 ]).to.have.length.above(2);
     *
     * @name above
     * @alias gt
     * @alias greaterThan
     * @param {Number} value
     * @api public
     */
  
    function assertAbove (n) {
      var obj = flag(this, 'object');
      if (flag(this, 'doLength')) {
        new Assertion(obj).to.have.property('length');
        var len = obj.length;
        this.assert(
            len > n
          , 'expected #{this} to have a length above #{exp} but got #{act}'
          , 'expected #{this} to not have a length above #{exp}'
          , n
          , len
        );
      } else {
        this.assert(
            obj > n
          , 'expected #{this} to be above ' + n
          , 'expected #{this} to be below ' + n
        );
      }
    }
  
    Assertion.addMethod('above', assertAbove);
    Assertion.addMethod('gt', assertAbove);
    Assertion.addMethod('greaterThan', assertAbove);
  
    /**
     * ### .below(value)
     *
     * Asserts that the target is less than `value`.
     *
     *     expect(5).to.be.below(10);
     *
     * Can also be used in conjunction with `length` to
     * assert a maximum length. The benefit being a
     * more informative error message than if the length
     * was supplied directly.
     *
     *     expect('foo').to.have.length.below(4);
     *     expect([ 1, 2, 3 ]).to.have.length.below(4);
     *
     * @name below
     * @alias lt
     * @alias lessThan
     * @param {Number} value
     * @api public
     */
  
    function assertBelow (n) {
      var obj = flag(this, 'object');
      if (flag(this, 'doLength')) {
        new Assertion(obj).to.have.property('length');
        var len = obj.length;
        this.assert(
            len < n
          , 'expected #{this} to have a length below #{exp} but got #{act}'
          , 'expected #{this} to not have a length below #{exp}'
          , n
          , len
        );
      } else {
        this.assert(
            obj < n
          , 'expected #{this} to be below ' + n
          , 'expected #{this} to be above ' + n
        );
      }
    }
  
    Assertion.addMethod('below', assertBelow);
    Assertion.addMethod('lt', assertBelow);
    Assertion.addMethod('lessThan', assertBelow);
  
    /**
     * ### .within(start, finish)
     *
     * Asserts that the target is within a range.
     *
     *     expect(7).to.be.within(5,10);
     *
     * Can also be used in conjunction with `length` to
     * assert a length range. The benefit being a
     * more informative error message than if the length
     * was supplied directly.
     *
     *     expect('foo').to.have.length.within(2,4);
     *     expect([ 1, 2, 3 ]).to.have.length.within(2,4);
     *
     * @name within
     * @param {Number} start lowerbound inclusive
     * @param {Number} finish upperbound inclusive
     * @api public
     */
  
    Assertion.addMethod('within', function (start, finish) {
      var obj = flag(this, 'object')
        , range = start + '..' + finish;
      if (flag(this, 'doLength')) {
        new Assertion(obj).to.have.property('length');
        var len = obj.length;
        this.assert(
            len >= start && len <= finish
          , 'expected #{this} to have a length within ' + range
          , 'expected #{this} to not have a length within ' + range
        );
      } else {
        this.assert(
            obj >= start && obj <= finish
          , 'expected #{this} to be within ' + range
          , 'expected #{this} to not be within ' + range
        );
      }
    });
  
    /**
     * ### .instanceof(constructor)
     *
     * Asserts that the target is an instance of `constructor`.
     *
     *     var Tea = function (name) { this.name = name; }
     *       , Chai = new Tea('chai');
     *
     *     expect(Chai).to.be.an.instanceof(Tea);
     *     expect([ 1, 2, 3 ]).to.be.instanceof(Array);
     *
     * @name instanceof
     * @param {Constructor} constructor
     * @alias instanceOf
     * @api public
     */
  
    function assertInstanceOf (constructor) {
      var name = _.getName(constructor);
      this.assert(
          flag(this, 'object') instanceof constructor
        , 'expected #{this} to be an instance of ' + name
        , 'expected #{this} to not be an instance of ' + name
      );
    };
  
    Assertion.addMethod('instanceof', assertInstanceOf);
    Assertion.addMethod('instanceOf', assertInstanceOf);
  
    /**
     * ### .property(name, [value])
     *
     * Asserts that the target has a property `name`, optionally asserting that
     * the value of that property is strictly equal to  `value`.
     * If the `deep` flag is set, you can use dot- and bracket-notation for deep
     * references into objects and arrays.
     *
     *     // simple referencing
     *     var obj = { foo: 'bar' };
     *     expect(obj).to.have.property('foo');
     *     expect(obj).to.have.property('foo', 'bar');
     *
     *     // deep referencing
     *     var deepObj = {
     *         green: { tea: 'matcha' }
     *       , teas: [ 'chai', 'matcha', { tea: 'konacha' } ]
     *     };
  
     *     expect(deepObj).to.have.deep.property('green.tea', 'matcha');
     *     expect(deepObj).to.have.deep.property('teas[1]', 'matcha');
     *     expect(deepObj).to.have.deep.property('teas[2].tea', 'konacha');
     *
     * You can also use an array as the starting point of a `deep.property`
     * assertion, or traverse nested arrays.
     *
     *     var arr = [
     *         [ 'chai', 'matcha', 'konacha' ]
     *       , [ { tea: 'chai' }
     *         , { tea: 'matcha' }
     *         , { tea: 'konacha' } ]
     *     ];
     *
     *     expect(arr).to.have.deep.property('[0][1]', 'matcha');
     *     expect(arr).to.have.deep.property('[1][2].tea', 'konacha');
     *
     * Furthermore, `property` changes the subject of the assertion
     * to be the value of that property from the original object. This
     * permits for further chainable assertions on that property.
     *
     *     expect(obj).to.have.property('foo')
     *       .that.is.a('string');
     *     expect(deepObj).to.have.property('green')
     *       .that.is.an('object')
     *       .that.deep.equals({ tea: 'matcha' });
     *     expect(deepObj).to.have.property('teas')
     *       .that.is.an('array')
     *       .with.deep.property('[2]')
     *         .that.deep.equals({ tea: 'konacha' });
     *
     * @name property
     * @alias deep.property
     * @param {String} name
     * @param {Mixed} value (optional)
     * @returns value of property for chaining
     * @api public
     */
  
    Assertion.addMethod('property', function (name, val) {
      var descriptor = flag(this, 'deep') ? 'deep property ' : 'property '
        , negate = flag(this, 'negate')
        , obj = flag(this, 'object')
        , value = flag(this, 'deep')
          ? _.getPathValue(name, obj)
          : obj[name];
  
      if (negate && undefined !== val) {
        if (undefined === value) {
          throw new Error(_.inspect(obj) + ' has no ' + descriptor + _.inspect(name));
        }
      } else {
        this.assert(
            undefined !== value
          , 'expected #{this} to have a ' + descriptor + _.inspect(name)
          , 'expected #{this} to not have ' + descriptor + _.inspect(name));
      }
  
      if (undefined !== val) {
        this.assert(
            val === value
          , 'expected #{this} to have a ' + descriptor + _.inspect(name) + ' of #{exp}, but got #{act}'
          , 'expected #{this} to not have a ' + descriptor + _.inspect(name) + ' of #{act}'
          , val
          , value
        );
      }
  
      flag(this, 'object', value);
    });
  
  
    /**
     * ### .ownProperty(name)
     *
     * Asserts that the target has an own property `name`.
     *
     *     expect('test').to.have.ownProperty('length');
     *
     * @name ownProperty
     * @alias haveOwnProperty
     * @param {String} name
     * @api public
     */
  
    function assertOwnProperty (name) {
      var obj = flag(this, 'object');
      this.assert(
          obj.hasOwnProperty(name)
        , 'expected #{this} to have own property ' + _.inspect(name)
        , 'expected #{this} to not have own property ' + _.inspect(name)
      );
    }
  
    Assertion.addMethod('ownProperty', assertOwnProperty);
    Assertion.addMethod('haveOwnProperty', assertOwnProperty);
  
    /**
     * ### .length(value)
     *
     * Asserts that the target's `length` property has
     * the expected value.
     *
     *     expect([ 1, 2, 3]).to.have.length(3);
     *     expect('foobar').to.have.length(6);
     *
     * Can also be used as a chain precursor to a value
     * comparison for the length property.
     *
     *     expect('foo').to.have.length.above(2);
     *     expect([ 1, 2, 3 ]).to.have.length.above(2);
     *     expect('foo').to.have.length.below(4);
     *     expect([ 1, 2, 3 ]).to.have.length.below(4);
     *     expect('foo').to.have.length.within(2,4);
     *     expect([ 1, 2, 3 ]).to.have.length.within(2,4);
     *
     * @name length
     * @alias lengthOf
     * @param {Number} length
     * @api public
     */
  
    function assertLengthChain () {
      flag(this, 'doLength', true);
    }
  
    function assertLength (n) {
      var obj = flag(this, 'object');
      new Assertion(obj).to.have.property('length');
      var len = obj.length;
  
      this.assert(
          len == n
        , 'expected #{this} to have a length of #{exp} but got #{act}'
        , 'expected #{this} to not have a length of #{act}'
        , n
        , len
      );
    }
  
    Assertion.addChainableMethod('length', assertLength, assertLengthChain);
    Assertion.addMethod('lengthOf', assertLength, assertLengthChain);
  
    /**
     * ### .match(regexp)
     *
     * Asserts that the target matches a regular expression.
     *
     *     expect('foobar').to.match(/^foo/);
     *
     * @name match
     * @param {RegExp} RegularExpression
     * @api public
     */
  
    Assertion.addMethod('match', function (re) {
      var obj = flag(this, 'object');
      this.assert(
          re.exec(obj)
        , 'expected #{this} to match ' + re
        , 'expected #{this} not to match ' + re
      );
    });
  
    /**
     * ### .string(string)
     *
     * Asserts that the string target contains another string.
     *
     *     expect('foobar').to.have.string('bar');
     *
     * @name string
     * @param {String} string
     * @api public
     */
  
    Assertion.addMethod('string', function (str) {
      var obj = flag(this, 'object');
      new Assertion(obj).is.a('string');
  
      this.assert(
          ~obj.indexOf(str)
        , 'expected #{this} to contain ' + _.inspect(str)
        , 'expected #{this} to not contain ' + _.inspect(str)
      );
    });
  
  
    /**
     * ### .keys(key1, [key2], [...])
     *
     * Asserts that the target has exactly the given keys, or
     * asserts the inclusion of some keys when using the
     * `include` or `contain` modifiers.
     *
     *     expect({ foo: 1, bar: 2 }).to.have.keys(['foo', 'bar']);
     *     expect({ foo: 1, bar: 2, baz: 3 }).to.contain.keys('foo', 'bar');
     *
     * @name keys
     * @alias key
     * @param {String...|Array} keys
     * @api public
     */
  
    function assertKeys (keys) {
      var obj = flag(this, 'object')
        , str
        , ok = true;
  
      keys = keys instanceof Array
        ? keys
        : Array.prototype.slice.call(arguments);
  
      if (!keys.length) throw new Error('keys required');
  
      var actual = Object.keys(obj)
        , len = keys.length;
  
      // Inclusion
      ok = keys.every(function(key){
        return ~actual.indexOf(key);
      });
  
      // Strict
      if (!flag(this, 'negate') && !flag(this, 'contains')) {
        ok = ok && keys.length == actual.length;
      }
  
      // Key string
      if (len > 1) {
        keys = keys.map(function(key){
          return _.inspect(key);
        });
        var last = keys.pop();
        str = keys.join(', ') + ', and ' + last;
      } else {
        str = _.inspect(keys[0]);
      }
  
      // Form
      str = (len > 1 ? 'keys ' : 'key ') + str;
  
      // Have / include
      str = (flag(this, 'contains') ? 'contain ' : 'have ') + str;
  
      // Assertion
      this.assert(
          ok
        , 'expected #{this} to ' + str
        , 'expected #{this} to not ' + str
      );
    }
  
    Assertion.addMethod('keys', assertKeys);
    Assertion.addMethod('key', assertKeys);
  
    /**
     * ### .throw(constructor)
     *
     * Asserts that the function target will throw a specific error, or specific type of error
     * (as determined using `instanceof`), optionally with a RegExp or string inclusion test
     * for the error's message.
     *
     *     var err = new ReferenceError('This is a bad function.');
     *     var fn = function () { throw err; }
     *     expect(fn).to.throw(ReferenceError);
     *     expect(fn).to.throw(Error);
     *     expect(fn).to.throw(/bad function/);
     *     expect(fn).to.not.throw('good function');
     *     expect(fn).to.throw(ReferenceError, /bad function/);
     *     expect(fn).to.throw(err);
     *     expect(fn).to.not.throw(new RangeError('Out of range.'));
     *
     * Please note that when a throw expectation is negated, it will check each
     * parameter independently, starting with error constructor type. The appropriate way
     * to check for the existence of a type of error but for a message that does not match
     * is to use `and`.
     *
     *     expect(fn).to.throw(ReferenceError)
     *        .and.not.throw(/good function/);
     *
     * @name throw
     * @alias throws
     * @alias Throw
     * @param {ErrorConstructor} constructor
     * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types
     * @api public
     */
  
    function assertThrows (constructor, msg) {
      var obj = flag(this, 'object');
      new Assertion(obj).is.a('function');
  
      var thrown = false
        , desiredError = null
        , name = null;
  
      if (arguments.length === 0) {
        msg = null;
        constructor = null;
      } else if (constructor && (constructor instanceof RegExp || 'string' === typeof constructor)) {
        msg = constructor;
        constructor = null;
      } else if (constructor && constructor instanceof Error) {
        desiredError = constructor;
        constructor = null;
        msg = null;
      } else if (typeof constructor === 'function') {
        name = (new constructor()).name;
      } else {
        constructor = null;
      }
  
      try {
        obj();
      } catch (err) {
        // first, check desired error
        if (desiredError) {
          this.assert(
              err === desiredError
            , 'expected #{this} to throw ' + _.inspect(desiredError) + ' but ' + _.inspect(err) + ' was thrown'
            , 'expected #{this} to not throw ' + _.inspect(desiredError)
          );
          return this;
        }
        // next, check constructor
        if (constructor) {
          this.assert(
              err instanceof constructor
            , 'expected #{this} to throw ' + name + ' but a ' + err.name + ' was thrown'
            , 'expected #{this} to not throw ' + name );
          if (!msg) return this;
        }
        // next, check message
        if (err.message && msg && msg instanceof RegExp) {
          this.assert(
              msg.exec(err.message)
            , 'expected #{this} to throw error matching ' + msg + ' but got ' + _.inspect(err.message)
            , 'expected #{this} to throw error not matching ' + msg
          );
          return this;
        } else if (err.message && msg && 'string' === typeof msg) {
          this.assert(
              ~err.message.indexOf(msg)
            , 'expected #{this} to throw error including #{exp} but got #{act}'
            , 'expected #{this} to throw error not including #{act}'
            , msg
            , err.message
          );
          return this;
        } else {
          thrown = true;
        }
      }
  
      var expectedThrown = name ? name : desiredError ? _.inspect(desiredError) : 'an error';
  
      this.assert(
          thrown === true
        , 'expected #{this} to throw ' + expectedThrown
        , 'expected #{this} to not throw ' + expectedThrown
      );
    };
  
    Assertion.addMethod('throw', assertThrows);
    Assertion.addMethod('throws', assertThrows);
    Assertion.addMethod('Throw', assertThrows);
  
    /**
     * ### .respondTo(method)
     *
     * Asserts that the object or class target will respond to a method.
     *
     *     Klass.prototype.bar = function(){};
     *     expect(Klass).to.respondTo('bar');
     *     expect(obj).to.respondTo('bar');
     *
     * To check if a constructor will respond to a static function,
     * set the `itself` flag.
     *
     *    Klass.baz = function(){};
     *    expect(Klass).itself.to.respondTo('baz');
     *
     * @name respondTo
     * @param {String} method
     * @api public
     */
  
    Assertion.addMethod('respondTo', function (method) {
      var obj = flag(this, 'object')
        , itself = flag(this, 'itself')
        , context = ('function' === typeof obj && !itself)
          ? obj.prototype[method]
          : obj[method];
  
      this.assert(
          'function' === typeof context
        , 'expected #{this} to respond to ' + _.inspect(method)
        , 'expected #{this} to not respond to ' + _.inspect(method)
      );
    });
  
    /**
     * ### .itself
     *
     * Sets the `itself` flag, later used by the `respondTo` assertion.
     *
     *    function Foo() {}
     *    Foo.bar = function() {}
     *    Foo.prototype.baz = function() {}
     *
     *    expect(Foo).itself.to.respondTo('bar');
     *    expect(Foo).itself.not.to.respondTo('baz');
     *
     * @name itself
     * @api public
     */
  
    Assertion.addProperty('itself', function () {
      flag(this, 'itself', true);
    });
  
    /**
     * ### .satisfy(method)
     *
     * Asserts that the target passes a given truth test.
     *
     *     expect(1).to.satisfy(function(num) { return num > 0; });
     *
     * @name satisfy
     * @param {Function} matcher
     * @api public
     */
  
    Assertion.addMethod('satisfy', function (matcher) {
      var obj = flag(this, 'object');
      this.assert(
          matcher(obj)
        , 'expected #{this} to satisfy ' + _.inspect(matcher)
        , 'expected #{this} to not satisfy' + _.inspect(matcher)
        , this.negate ? false : true
        , matcher(obj)
      );
    });
  
    /**
     * ### .closeTo(expected, delta)
     *
     * Asserts that the target is equal `expected`, to within a +/- `delta` range.
     *
     *     expect(1.5).to.be.closeTo(1, 0.5);
     *
     * @name closeTo
     * @param {Number} expected
     * @param {Number} delta
     * @api public
     */
  
    Assertion.addMethod('closeTo', function (expected, delta) {
      var obj = flag(this, 'object');
      this.assert(
          Math.abs(obj - expected) <= delta
        , 'expected #{this} to be close to ' + expected + ' +/- ' + delta
        , 'expected #{this} not to be close to ' + expected + ' +/- ' + delta
      );
    });
  
  };
  