let parse_header_line position line =
    match String.(split ~on:'\t' (chop_prefix_exn line ~prefix:"@")) with
    | [] -> assert false
    | "CO" :: rest -> return (`comment (String.concat ~sep:"\t" rest))
    | tag :: values ->
      if is_valid_tag tag then (
        let tag_values () =
          List.map values (fun v ->
            match String.split ~on:':' v with
            | tag :: value :: [] ->
              if is_valid_tag tag then (tag, value)
              else failwith "A"
            | other ->  failwith "A"in
        begin try return (tag_values ()) with
        | Failure _ -> fail (`invalid_tag_value_list (position, values))
        end
            >>= fun tv ->
        return (`header (tag, tv))
      ) else
        fail (`invalid_header_tag (position, tag))