docs: function () {
      var done = this.async();
      var options = this.options();
      var data = this.data;
  
      // default settings, overwritten with user defined settings
      settings = {
        pattern_port: Array.isArray(data.ports) && data.ports[0] ? data.ports[0] : Array.isArray(options.ports) && options.ports[0] ? options.ports[0] : 7020,
        snapshot_port: Array.isArray(data.ports) && data.ports[1] ? data.ports[1] : Array.isArray(options.ports) && options.ports[1] ? options.ports[1] : 7040,
        wwwroot: data.wwwroot || options.wwwroot || 'public',
        src: data.src || options.src || 'public/patterns',
        files: data.files || options.files || [],
        dest: data.dest || options.dest || 'docs',
        snapshot: (data.snapshot !== undefined ? data.snapshot : (options.snapshot !== undefined ? options.snapshot : false)),
        index: data.index || options.index || null,
        css: data.css || options.css || ['global.css']
      };
  
      var primer;
  
      // local pattern folder (there are the html snapshots)
      if (settings.files.length > 0) {
        var patterns = settings.files;
        var patternsFolder = settings.src;
  
        // our main function that starts the process
        primer = function (cb) {
          handleFiles(patternsFolder, patterns, cb);
        };
  
      } else {
       var patternFolder = './' + settings.src;
  
        // our main function that starts the process
        primer = function (cb) {
          readPatterns(patternFolder, cb);
        };
      }
  
     
  
      // middleware to spit out 404 (in case a non existing ressource is request)
      // or to process the `non static` requests
      var middleware = function (req, resp) {
        if (req.url !== '/') {
          resp.writeHead(404, {
            'Content-Length': 0,
            'Content-Type': 'text/plain'
          });
          resp.end();
          return;
        }
  
        // 200, success, always
        resp.writeHead(200, {'Content-Type': 'text/html'});
        // run the primer with cb
        primer(resp.end.bind(resp));
      };
  
      // initialize the server with static routes & dynamic template middleware
      var liveServer = connect.createServer(
        connect.static(process.cwd() + '/' + settings.wwwroot),
        middleware
      );
  
      // initialize the static server pointing to your snapshots
      var snapshotServer = connect.createServer(connect.static(process.cwd() + '/' + settings.dest));
  
      // starts the live server
      var startLiveServer = function () {
        liveServer.listen(settings.pattern_port, function () {
          grunt.log.ok('You can now visit http://localhost:' + settings.pattern_port + '/ to see your patterns.');
        });
      };
  
      // starts the snapshot server
      var startSnapshotServer = function () {
        snapshotServer.listen(settings.snapshot_port, function () {
          grunt.log.ok('You can now visit http://localhost:' + settings.snapshot_port + '/ to see your snaphsot patterns.');
        });
      };
  
      // writes the task output to a file 
      var writeSnapshot = function () {
        primer(function (content) {
          var promises = [];
          // write the index file
          grunt.file.write('./' + settings.dest + '/index.html', content);
          // copy css files
          settings.css.forEach(function (file) {
            var deferred = Q.defer();
            promises.push(deferred.promise);
            if (file.search('http://') !== -1) {
  
              var data = '';
              http.get(file, function (res) {
                res.on('data', function(chunk) {
                  data += chunk;
                });
                res.on('end', function () {
                  grunt.file.write('./' + settings.dest + '/style.css', data);
                  deferred.resolve();
                });
              })
              .on('err', deferred.reject);
            } else {
              grunt.file.copy('./' + settings.wwwroot + '/' + file, './' + settings.dest + '/' + file);
              deferred.resolve();
            }
          });
  
          grunt.log.ok('Stand-alone output can now be found in "' + settings.dest + '/"');
          grunt.event.emit('patternprimer:snapshot:written');
          if (promises.length === 0) {
            done();
          } else {
            Q.allSettled(promises).then(done);
          }
        });
      };
  
      // writes to file or starts a server,
      // depending on the given snapshot var
      if (!!settings.snapshot) {
        writeSnapshot();
      } else {
        startLiveServer();
        // only start snapshot server, if snapshots are available
        if (grunt.file.exists('./' + settings.dest + '/index.html')) {
          startSnapshotServer();
        }
      }
  
    }