///|
/// Apply Cap'n Proto packing to a word-aligned byte sequence, including its
/// standard stream header when packing a complete message.
pub fn pack(input : Bytes) -> Bytes raise CapnpError {
  guard input.length() % 8 == 0 else {
    raise InvalidMessage("packed input must contain whole 8-byte words")
  }
  let out : Array[Byte] = []
  let mut pos = 0
  while pos < input.length() {
    let mut tag = 0
    for j in 0..<8 {
      if input[pos + j] != 0 {
        tag = tag | (1 << j)
      }
    }
    out.push(tag.to_byte())
    for j in 0..<8 {
      if (tag & (1 << j)) != 0 {
        out.push(input[pos + j])
      }
    }
    pos += 8
    if tag == 0 {
      let mut count = 0
      while count < 255 && pos < input.length() {
        let mut zero = true
        for j in 0..<8 {
          if input[pos + j] != 0 {
            zero = false
          }
        }
        if !zero {
          break
        }
        count += 1
        pos += 8
      }
      out.push(count.to_byte())
    } else if tag == 255 {
      // Copy dense spans verbatim. Allow one zero byte per word, matching the
      // reference algorithm's tradeoff between tags and raw runs.
      let start = pos
      let mut count = 0
      while count < 255 && pos < input.length() {
        let mut zeroes = 0
        for j in 0..<8 {
          if input[pos + j] == 0 {
            zeroes += 1
          }
        }
        if zeroes >= 2 {
          break
        }
        count += 1
        pos += 8
      }
      out.push(count.to_byte())
      for j in start.. Bytes raise CapnpError {
  guard max_output_bytes >= 0 else { raise Limit("negative unpack limit") }
  let out : Array[Byte] = []
  let mut pos = 0
  while pos < input.length() {
    guard out.length() <= max_output_bytes - 8 else {
      raise Limit("unpacked data exceeds the configured byte limit")
    }
    let tag = input[pos].to_int()
    pos += 1
    for j in 0..<8 {
      if (tag & (1 << j)) == 0 {
        out.push(0)
      } else {
        guard pos < input.length() else {
          raise InvalidMessage("truncated packed word")
        }
        out.push(input[pos])
        pos += 1
      }
    }
    if tag == 0 || tag == 255 {
      guard pos < input.length() else {
        raise InvalidMessage("missing packed run length")
      }
      let run_bytes = input[pos].to_int() * 8
      pos += 1
      guard run_bytes <= max_output_bytes - out.length() else {
        raise Limit("unpacked run exceeds the configured byte limit")
      }
      if tag == 0 {
        for _ in 0..