docs: function( karma, jasmineEnv ) {
  
        var currentSuite = new SuiteNode();
  
        /**
         * Jasmine 2.0 dispatches the following events:
         *
         *  - jasmineStarted
         *  - jasmineDone
         *  - suiteStarted
         *  - suiteDone
         *  - specStarted
         *  - specDone
         */
  
        this.jasmineStarted = function( data ) {
           // TODO(vojta): Do not send spec names when polling.
           karma.info( {
              total: data.totalSpecsDefined,
              specs: getAllSpecNames( jasmineEnv.topSuite() )
           } );
        };
  
        this.jasmineDone = function() {
           karma.complete( {
              coverage: window.__coverage__
           } );
        };
  
        this.suiteStarted = function( result ) {
           currentSuite = currentSuite.addChild( result.description );
        };
  
        this.suiteDone = function( result ) {
           // In the case of xdescribe, only "suiteDone" is fired.
           // We need to skip that.
           if( result.description !== currentSuite.name ) {
              return;
           }
  
           currentSuite = currentSuite.parent;
        };
  
        this.specStarted = function( specResult ) {
           specResult.startTime = new Date().getTime();
        };
  
        this.specDone = function( specResult ) {
           var skipped = specResult.status === 'disabled' || specResult.status === 'pending';
  
           var result = {
              description: specResult.description,
              id: specResult.id,
              log: [],
              skipped: skipped,
              success: specResult.failedExpectations.length === 0,
              suite: [],
              time: skipped ? 0 : new Date().getTime() - specResult.startTime
           };
  
           // generate ordered list of (nested) suite names
           var suitePointer = currentSuite;
           while( suitePointer.parent ) {
              result.suite.unshift( suitePointer.name );
              suitePointer = suitePointer.parent;
           }
  
           if( !result.success ) {
              var steps = specResult.failedExpectations;
              for( var i = 0, l = steps.length; i < l; i++ ) {
                 result.log.push( formatFailedStep( steps[i] ) );
              }
           }
  
           karma.result( result );
           delete specResult.startTime;
        };
     }