TODO: Implement delta refs to reduce stream size
function pack(hashes, opts, callback) {
  /*jshint validthis:true*/
  if (!callback) return pack.bind(this, hashes, opts);
  var repo = this;
  var i = 0, first = true, done = false;
  return callback(null, applyParser({ take: take }, encodePack));

  function take(callback) {
    if (done) return callback();
    if (first) return readFirst(callback);
    var hash = hashes[i++];
    if (hash === undefined) {
      return callback();
    }
    repo.loadRaw(hash, function (err, buffer) {
      if (err) return callback(err);
      if (!buffer) return callback(new Error("Missing hash: " + hash));
      // Reframe with pack format header
      callback(null, codec.deframe(buffer));
    });
  }

  function readFirst(callback) {
    first = false;
    callback(null, {num: hashes.length});
  }
}