docs: function doUntil(fn, expectations, delay, timeout, negate) {
  
    // Montior time spent to compare against timeout
    var start = new Date().getTime();
  
    var next = function(err, result) {
      // One of the expectations failed.  Calculate remaining
      // time.
  
      // Out of time -- reject
      if (timeout === 0) {
        if (negate) {
          return result;
        } else {
          return Promise.reject(err);
        }
      }
  
      var elapsed = new Date().getTime() - start;
      var newTimeout = timeout - elapsed - delay;
  
      if (newTimeout < 0) {
        // Allow one more attempt at roughly the end of the timeout range
        // that doUntil was originally called with
        newTimeout = 0;
        delay = timeout;
      }
  
      //Not out of time, so let's delay and then try again, with
      //the updated timeout.
      return Promise.delay(delay).then(function() {
        return doUntil(fn, expectations, Math.min(delay*delay, 1000), newTimeout, negate);
      });
    };
  
    return fn()
    .then( function(result) {
      return Promise.all(_.map(expectations, function(exp) {
        return expector.expect(result, exp.expected, exp.stack)
        .then(function() {
          if (negate) {
            return Promise.reject(expector.fail(
              'One or more expectations succeeded which should not have',
              'Predicate Failure',
              exp.stack
            ));
          }
        }, function(err) {
          if (! negate) throw err;
        });
      }))
      .then(function() {
        return negate ? next(null, result) : result;
      }, function(err) {
        if (negate) throw err;
        return next(err);
      });
    });
  }