let partition_files_by_dir files =
  let rec part (acc : (string * (string list ref)) list) l =
    match l with
      [] -> List.map (fun (d,lref) -> (d,!lref)) acc
    | file :: q ->
        let d = Filename.dirname file in
        let f = Filename.basename file in
        try
          let lref = List.assoc d acc in
          lref := f :: !lref;
          part acc q
        with
          Not_found ->
            part ((d, ref [f])::acc) q
  in
  part [] files