function next(errSuite) {
      if (errSuite) {
        // current suite failed on a hook from errSuite
        if (errSuite === suite) {
          // if errSuite is current suite
          // continue to the next sibling suite
          return done();
        }
        // errSuite is among the parents of current suite
        // stop execution of errSuite and all sub-suites
        return done(errSuite);
      }

      if (self._abort) {
        return done();
      }

      var curr = suite.suites[i++];
      if (!curr) {
        return done();
      }

      // Avoid grep neglecting large number of tests causing a
      // huge recursive loop and thus a maximum call stack error.
      // See comment in `this.runTests()` for more information.
      if (self._grep !== self._defaultGrep) {
        Runner.immediately(function () {
          self.runSuite(curr, next);
        });
      } else {
        self.runSuite(curr, next);
      }
    }
Run the given `suite` and invoke the callback `fn()` when complete.

@private
@param {Suite} suite
@param {Function} fn