let decode_id s  =
  let sz = String.length s in
  let rec split p i acc =
    if i >= sz then
      [String.sub s p (i - p) :: acc]
    else
      if i + 1 >= sz then
        [String.sub s p (i - p + 1) :: acc]
      else
        if s.[i] = ':' then (
          if s.[i + 1] = ':' then (
            (String.sub s p (i - p) :: acc) :: split (i + 2) (i + 2) []
          ) else ( (* quote *)
            let rec quoted i =
              if i >= sz then i else
                if s.[i] = ':' then i else quoted (i + 1)
            in let i' = quoted (i + 1) in
              split (i' + 1) (i' + 1) (unquote_id_item (String.sub s (i + 1) (i' - i - 1)) :: String.sub s p (i - p) :: acc)
          )
        ) else
          split p (succ i) acc
  in List.map (List.fold_left (fun r s -> s ^ r) "") (split 0 0 [])