docs: function flush(options, callback) {
      if (!options) return callback(new Error('options is required'));
      if (!options.base) return callback(new Error('options.base is required'));
      if (!options.cache) return callback(new Error('options.cache is required'));
      if (!options.layer) return callback(new Error('options.layer is required'));
      if (!options.url) return callback(new Error('options.url is required'));
  
      var uri = url.parse(options.url);
      if (!uri.protocol) return callback(new Error('Invalid URL: ' + options.url));
  
      var extname = path.extname(path.basename(uri.pathname));
      var filepath;
      var layerpath;
  
      switch (extname.toLowerCase()) {
      case '.zip':
      case '.shp':
          layerpath = path.join(options.base, 'layers', options.layer);
          filepath = path.join(options.cache, path.dirname(cachepath(options.url)));
          break;
      default:
          layerpath = path.join(options.base, 'layers', options.layer + extname);
          filepath = path.join(options.cache, cachepath(options.url));
          break;
      }
  
      Step(function() {
          fs.lstat(layerpath, this);
      }, function removeSymlink(err, stat) {
          if (err && err.code !== 'ENOENT') throw err;
          if (!err && stat.isSymbolicLink()) {
              fs.unlink(layerpath, this);
          } else {
              this();
          }
      }, function removeCache(err) {
          if (err) throw err;
          existsAsync(filepath, function(exists) {
              if (!exists) return this();
              utils.rm(filepath, this);
          }.bind(this));
      }, function removeMetafile(err) {
          if (err) throw err;
          existsAsync(metapath(filepath), function(exists) {
              if (!exists) return this();
              utils.rm(metapath(filepath), this);
          }.bind(this));
      }, function finish(err) {
          callback(err);
      });
  }