let assigns_upper_bound spec =
  let bhvs = spec.spec_behavior in
  let upper a b =
    match a, b.b_assigns with
        | NoneWrites a when Cil.is_default_behavior b ->
          Some (b,a) (* default behavior always applies. *)
        | None, _ -> None (* WritesAny U X -> WritesAny *)
        | Some (b,_), _ when Cil.is_default_behavior b ->
          a (* default behavior prevails over other behaviors. *)
        | Some _, WritesAny ->
          None (* No default behavior and one behavior assigns everything. *)
        | Some(b,a1), Writes a2 -> Some (b,a1 @ a2)
          (* take the whole list of assigns. *)
  in
  match bhvs with
    | [] -> None
    | bhv::bhvs ->
      (* [VP 2011-02-04] Note that if there is no default and each
         behavior has a proper assigns clause we put dependencies only
         to the assigns of a more or less randomly selected behavior,
         but the datatypes above can't handle anything better.  *)

      let acc =
        match bhv.b_assigns with
            WritesAny -> None
          | Writes a -> Some(bhv,a)
      in
      List.fold_left upper acc bhvs