docs: function main(env, print, cb) {
      var dir = env.opts.directory || path.resolve(env.cwd, 'artifacts/jslint'),
          lines = [],
          count = 0,
          total = 0;
  
      function perOffense(o) {
          var evidence = o.evidence.trim();
  
          count += 1;
          total += 1;
  
          lines.push(fmt('  #%d %d,%d: %s', count, o.line, o.col, o.msg));
          if (evidence) {
              lines.push('     ' + evidence);
          }
      }
  
      /**
       * invoked by lintifier.doneYet()
       * @param {object|string|null} offenses
       * @param {string} msg "Done. no lint found..."
       */
      function reporter(offenses, msg) {
          var files,
              summary,
              writeErr;
  
          if (('string' === typeof offenses) || offenses instanceof Error) {
              cb(offenses);
              return;
          }
  
          function perFile(pathname) {
              count = 0;
              lines.push(pathname);
              offenses[pathname].forEach(perOffense);
              lines.push(''); // blank line
          }
  
          if (offenses) {
              // accumulate report in lines array
              files = Object.keys(offenses);
              files.forEach(perFile);
              summary = getSummary(total, files.length);
  
              if (env.opts.print) {
                  lines.unshift('JSLint Report', '');
                  print(lines.join(EOL));
  
              } else {
                  writeErr = writeHtmlFile(dir, getHtml(lines, summary));
              }
  
              // has errors
              cb(writeErr || summary);
  
          } else {
              // is lint free
              cb(null, msg);
          }
      }
  
      return reporter;
  }