let make_request tables universe native_arch request = 
  let to_cudf (p,v) = (p,Debian.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 -> 
      print_error "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) = Boilerplate.debvpkg ~native_arch to_cudf ((n,a),c) in
      if remove then
        (name,None)
      else
        match constr, request.Edsp.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. *)

    ) l 
  in
  if request.Edsp.upgrade || request.Edsp.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.Edsp.request;
    Cudf.upgrade = to_upgrade request.Edsp.install;
    Cudf.remove = select_packages ~remove:true request.Edsp.remove;
    }
  else
    {Cudf.default_request with
    Cudf.request_id = request.Edsp.request;
    Cudf.install = select_packages request.Edsp.install;
    Cudf.remove = select_packages ~remove:true request.Edsp.remove;
    }