let requesttocudf tables universe request =
  let to_cudf (p,v) = (p,Debcudf.get_cudf_version tables (p,v)) in
  let get_candidate (name,constr) =
    try
      List.find
        (fun pkg ->
          try (Cudf.lookup_package_property pkg "apt-candidate") = "true"
          with Not_found -> false)
        (CudfAdd.who_provides universe (name,constr))
    with Not_found ->
      fatal "Package %s does not have a suitable candidate" name
  in
  let select_packages ?(remove=false) l =
    List.map (fun ((n,a),c) ->
      let (name,constr) = Debutil.debvpkg to_cudf ((n,a),c) in
      if remove then (name,None)
      else begin
        match constr, request.strict_pin with
        |Nonefalse -> (name, None)
        |_, _ -> (name,Some(`Eq,(get_candidate (name,constr)).Cudf.version))
        (* FIXME: when apt will accept version constraints different from `Eq,
           we will need to pass them through. *)

      end
    ) l
  in
  if request.upgrade || request.distupgrade then
    let to_upgrade = function
      |[] ->
        let filter pkg = pkg.Cudf.installed in
        let l = Cudf.get_packages ~filter universe in
        List.map (fun pkg -> (pkg.Cudf.package,None)) l
      |-> select_packages l
    in
    {Cudf.default_request with
    Cudf.request_id = request.request;
    Cudf.upgrade = to_upgrade request.install;
    Cudf.remove = select_packages ~remove:true request.remove;
    }
  else
    {Cudf.default_request with
    Cudf.request_id = request.request;
    Cudf.install = select_packages request.install;
    Cudf.remove = select_packages ~remove:true request.remove;
    }