method read ?obsoletes ?(no_default=false)
      ?(on_type_error = fun groupable_cp raw_cp output filename in_channel ->
          close_in in_channel;
          Printf.eprintf
            "Type error while loading configuration parameter %s from file %s.\n%!"
            (String.concat "." groupable_cp#get_name) filename;
          output stderr;
          exit 1)
      filename =
    (* [filename] is created if it doesn't exist. In this case there is no need to read it. *)
    match Sys.file_exists filename with false -> self#write filename | true ->
    let in_channel = open_in filename in
    (* what to do when a cp is missing: *)
    let missing cp default = if no_default then raise (Missing_cp cp) else default in
    (* returns a cp contained in the nametree queue, which must be nonempty *)
    let choose queue =
      let rec iter q = Queue.iter (function
        | _, Immediate cp -> raise (Found_cp cp)
        | _, Subsection q -> iter q) q in
      try iter queue; failwith "choose" with Found_cp cp -> cp in
    (* [set_and_remove raw_cps nametree] sets the cp of [nametree] to their value
       defined in [raw_cps] and returns the remaining raw_cps. *)

    let set_cp cp value =
      try cp#set_raw value
      with Wrong_type output -> on_type_error cp value output filename in_channel in
    let rec set_and_remove raw_cps = function
      | name, Immediate cp ->
          (try list_assoc_remove name (fun value -> set_cp cp value; None) raw_cps
           with Not_found -> missing cp raw_cps)
      | name, Subsection queue ->
          (try list_assoc_remove name
             (function
                | Raw.Section l ->
                    (match remainings l queue with
                       | [] -> None
                       | l -> Some (Raw.Section l))
                | r -> missing (choose queue) (Some r))
             raw_cps
           with Not_found -> missing (choose queue) raw_cps)
    and remainings raw_cps queue = Queue.fold set_and_remove raw_cps queue in
    let remainings = remainings (Raw.of_channel in_channel) cps in
    (* Handling of options defined in filename but not belonging to self. *)
    if remainings <> [] then match obsoletes with
      | Some filename ->
          let out_channel =
            open_out filename in
(*             open_out_gen [Open_wronly; Open_creat; Open_append; Open_text] 0o666 filename in *)
          let formatter = Format.formatter_of_out_channel out_channel in
          Format.fprintf formatter "@[<v>";
          Raw.save formatter (Raw.Section remainings);
          Format.fprintf formatter "@]@.";
          close_out out_channel
      | None -> ()