let get_internal =
  Internals.memo
    (fun kf ->
       !Value.compute ();
       match kf.fundec with
       | Definition (f,_) ->
           (try
              Stack.iter
                (fun g -> if kf == g then begin
                   Cil.warn
                     "recursive call detected during out analysis of %a. Ignoring it is safe if the value analysis suceeded without problem."
                     Kernel_function.pretty_name kf;
                   raise Ignore
                 end
                )
                call_stack;

              (* No out to compute if the values were not computed for [kf] *)
              (* if not (Value.is_accessible kf) then raise Ignore; *)

              Stack.push kf call_stack;
              let computer = new do_it in
              ignore (visitCilFunction (computer:>cilVisitor) f);
              let _ = Stack.pop call_stack in
              computer#result
                (*
                  let initial_stmt = find_first_stmt kf in
                  let initial_state = Value.get_state initial_stmt in
                  let inputs = InOutContext.get_over_input_context
                  (!InOutContext.get_external kf)
                  in
                  let out_bases =
                  Zone.fold_bases
                  BaseUtils.BaseSet.add
                  res
                  BaseUtils.BaseSet.empty
                  in
                  let access_path = Access_path.compute initial_state out_bases in
                  let access_path = Access_path.filter access_path inputs in
                *)

                (*TODO*)
            with Ignore ->
              Zone.bottom)
       | Declaration (_,_,_,_) ->
           let behaviors =
             !Value.valid_behaviors kf (Value.get_initial_state kf)
           in
           let assigns = Ast_info.merge_assigns behaviors in
           (try
              let state = Value.get_initial_state kf in
              List.fold_left
                (fun acc (loc,_) ->
                   match loc with
                       Location loc ->
                         let c = loc.it_content in
                         if (Logic_utils.is_result c)
                         then acc
                         else
                           let loc = 
                             !Properties.Interp.loc_to_loc ~result:None 
                               state
                               c
                           in
                              Zone.join
                               acc
                               (Locations.valid_enumerate_bits loc)
                     | Nothing -> acc
                )
                Zone.bottom
                assigns
            with Invalid_argument "not an lvalue" ->
              Cil.warn "unsupported assigns clause for function %a; Ignoring it."
                Kernel_function.pretty_name kf;
              Zone.bottom)
    )