docs: function( karma ) {
  
        var getAllSpecNames = function( topLevelSuites ) {
           var specNames = {};
  
           var processSuite = function( suite, pointer ) {
              var childSuite;
              var childPointer;
  
              for( var i = 0; i < suite.suites_.length; i++ ) {
                 childSuite = suite.suites_[i];
                 childPointer = pointer[childSuite.description] = {};
                 processSuite( childSuite, childPointer );
              }
  
              pointer._ = [];
              for( var j = 0; j < suite.specs_.length; j++ ) {
                 pointer._.push( suite.specs_[j].description );
              }
           };
  
           var suite;
           var pointer;
           for( var k = 0; k < topLevelSuites.length; k++ ) {
              suite = topLevelSuites[k];
              pointer = specNames[suite.description] = {};
              processSuite( suite, pointer );
           }
  
           return specNames;
        };
  
        this.reportRunnerStarting = function( runner ) {
           karma.info( {total: runner.specs().length, specs: getAllSpecNames( runner.topLevelSuites() )} );
        };
  
        this.reportRunnerResults = function( runner ) {
           karma.complete( {
              coverage: window.__coverage__
           } );
        };
  
        this.reportSuiteResults = function( suite ) {
           // memory clean up
           suite.after_ = null;
           suite.before_ = null;
           suite.queue = null;
        };
  
        this.reportSpecStarting = function( spec ) {
           spec.results_.time = new Date().getTime();
        };
  
        this.reportSpecResults = function( spec ) {
           var result = {
              id: spec.id,
              description: spec.description,
              suite: [],
              success: spec.results_.failedCount === 0,
              skipped: spec.results_.skipped,
              time: spec.results_.skipped ? 0 : new Date().getTime() - spec.results_.time,
              log: []
           };
  
           var suitePointer = spec.suite;
           while( suitePointer ) {
              result.suite.unshift( suitePointer.description );
              suitePointer = suitePointer.parentSuite;
           }
  
           if( !result.success ) {
              var steps = spec.results_.items_;
              for( var i = 0; i < steps.length; i++ ) {
                 if( !steps[i].passed_ ) {
                    result.log.push( formatFailedStep( steps[i] ) );
                 }
              }
           }
  
           karma.result( result );
  
           // memory clean up
           spec.results_ = null;
           spec.spies_ = null;
           spec.queue = null;
        };
  
        this.log = function() {};
     }