let sources2packages ?(profiles=false) ?(noindep=false) ?(src="src") builddeparch l =
  let conflicts profile l = List.filter_map (select builddeparch profile) l in
  let depends profile ll =
    List.filter_map (fun l ->
      match List.filter_map (select builddeparch profile) l with
      |[] -> None 
      |-> Some l
    ) ll
  in
  (* In contrast to B-D and B-C, B-D-I and B-C-I requirements must be satisfied
   * by native packages. Despite that, both fields are each concatenated. B-D-I
   * and B-C-I can not contain :any or :native modifiers. Adding :native to
   * B-D-I and B-C-I makes sure they are satisfied by native packages *)

  let add_native_l =
    List.map (function
      |(((name, None), constr), al, pl) ->
          (((name, Some "native"), constr), al, pl)
      |(((name, Some a), constr), al, pl) ->
         warning "modifier %s for indep dependency %s used" a name;
         (((name, Some a), constr), al, pl)
    )
  in
  let add_native_ll = List.map add_native_l in

  (* the package name is encodes as src-<profile>:<package name> if
   * a profile is selected, src:<package-name> otherwise *)

  let src2pkg ?(profile=None) srcpkg =
    let prefix = match profile with None -> src | Some s -> src^"-"^s in
    let extras_profile  = match profile with None -> [] | Some s -> [("profile", s)] in
    let depends_indep   = if noindep then [] else add_native_ll srcpkg.build_depends_indep in
    let conflicts_indep = if noindep then [] else add_native_l srcpkg.build_conflicts_indep in
    let build_essential = [(("build-essential"Some "native"), None)] in
    { Packages.default_package with
      Packages.name = prefix ^ sep ^ srcpkg.name ;
      source = (srcpkg.name, Some srcpkg.version);
      version = srcpkg.version;
      depends = build_essential::(depends profile (depends_indep @ srcpkg.build_depends));
      conflicts = conflicts profile (conflicts_indep @ srcpkg.build_conflicts);
      architecture = String.concat "," srcpkg.architecture;
      extras = extras_profile @ [("Type",src)]
    }
  in

  (* search in Build-Depends and Build-Conflicts for buildprofiles
     searching in Build-Depends-Indep and Build-Conflicts-Indep doesnt make sense *)

  let getprofiles pkg =
    let deps = pkg.build_conflicts @ (List.flatten pkg.build_depends) in
    (* XXX certainly we could do better here ... *)
    List.unique (List.map snd (List.fold_left (fun l (_,_,pl) -> pl @ l) [] deps))
  in

  (* right fold to not inverse the order *)
  (* if a profile is selected we add an encoding of the package for each profile *)
  List.fold_right (fun srcpkg al ->
    (* let pkgarchs = srcpkg.architecture in
      if List.exists (fun a -> List.mem a archs) pkgarchs then *)

      let pkg = src2pkg srcpkg in
      if profiles then
        pkg :: (List.map (fun p -> src2pkg ~profile:(Some p) srcpkg) (getprofiles srcpkg)) @ al
      else
        pkg::al
    (* else al *)
  ) l []