docs: function createMiddleware(options) {
    // Check for required options
    if (!(options.root || options.match || options.transform)) {
      throw new Error('options.{root,match,transform} must be defined');
    }
  
    // Set encoding if not set and set to undefined if set to 'buffer'
    var e = options.encoding;
    options.encoding = e ? (e === 'buffer' ? undefined : e) : 'utf-8';
  
    // Create cache object
    var cache = {};
  
    // Return middleware function
    return function staticTransform(req, res, next) {
      // Check request method
      if (req.method !== 'GET' && req.method !== 'HEAD') {
        return next();
      }
      // Check request path
      var path = parse(req).pathname;
      if (!options.match.test(path)) {
        return next();
      }
      // Normalize path if necessary
      if (options.normalize) {
        if (typeof options.normalize === 'string') {
          path = path.replace(options.match, options.normalize);
        } else if (typeof options.normalize === 'function') {
          path = options.normalize(path);
        }
      }
      // Join path
      path = nPath.join(options.root, path);
      if (options.cache && cache[path]) {
        // Referenced cached value
        var cacheVal = cache[path];
        // Write cached value
        writeOut(req.headers['if-modified-since'] ? 304 : 200, res, cacheVal.out, cacheVal.headers, options);
      } else {
        // Stat the file
        fs.stat(path, function (err, stat) {
          if (err || !stat.isFile()) {
            return next();
          }
          // Pass path to transform if pathOnly is set
          if (options.pathOnly) {
            return options.transform(path, send);
          }
          // Read and transform file
          fs.readFile(path, options.encoding, function (err, data) {
            if (err) {
              throw err;
            }
            options.transform(path, data, send);
          });
          // Send function
          function send(out, headers) {
            // Check for headers
            if (!headers) {
              headers = {};
            }
            // Check out value
            if (!out) {
              return next();
            }
            // Do cache things if necessary
            if (options.cache) {
              var expire = new Date();
              expire.setYear(expire.getFullYear() + 1);
              headers['Expires'] = options.expires || expire.toUTCString();
              headers['Cache-Control'] = 'public, max-age=' + (options.maxage || 31536000/*One year in seconds*/);
              headers['Last-Modified'] = stat.mtime.toUTCString();
              cache[path] = {out: out, headers: headers};
            }
            // Write out transformed value
            writeOut(200, res, out, headers, options);
          }
        });
      }
    };
  }