diff --git a/.gitignore b/.gitignore
index 9c2e31862409d54bf53a74b0b3009d907a363ab6..fd4538e0558cc07e929d1370f2f1ee36bb6921d9 100644
--- a/.gitignore
+++ b/.gitignore
@@ -8,3 +8,5 @@ C11-BackEnds/Clean_wrapper/output/document
 C11-BackEnds/Clean_wrapper/output/document.pdf
 C11-FrontEnd/generated/document
 C11-FrontEnd/generated/document.pdf
+*.thy~
+*.thy#
\ No newline at end of file
diff --git a/C11-BackEnds/Clean/examples/Quicksort.thy b/C11-BackEnds/Clean/examples/Quicksort.thy
index 4627cb43bda13eb52bea811531339bfc6c928203..4db779b644ec2fca63bf1eff03424244d8aa50de 100644
--- a/C11-BackEnds/Clean/examples/Quicksort.thy
+++ b/C11-BackEnds/Clean/examples/Quicksort.thy
@@ -88,6 +88,7 @@ section\<open>Clean Encoding of the Global State of Quicksort\<close>
 
 global_vars (state)
     A :: "int list"
+    B :: "int list list"
 
 function_spec swap (i::nat,j::nat) \<comment> \<open>TODO: the hovering on parameters produces a number of report equal to the number of \<^ML>\<open>Proof_Context.add_fixes\<close> called in \<^ML>\<open>Function_Specification_Parser.checkNsem_function_spec\<close>\<close>
 pre          "\<open>i < length A \<and> j < length A\<close>"    
@@ -97,6 +98,15 @@ defines      " \<open> tmp := A ! i\<close>  ;-
                \<open> A := list_update A i (A ! j)\<close> ;- 
                \<open> A := list_update A j tmp\<close> " 
 
+function_spec update_2d_array (i::nat,j::nat, val:: int) \<comment> \<open>TODO: the hovering on parameters produces a number of report equal to the number of \<^ML>\<open>Proof_Context.add_fixes\<close> called in \<^ML>\<open>Function_Specification_Parser.checkNsem_function_spec\<close>\<close>
+pre          "\<open>i < length A \<and> j < length A\<close>"    
+post         "\<open>\<lambda>res. length A = length(old A) \<and> res = ()\<close>" 
+local_vars   tmp :: int 
+defines      "
+               \<open> B :=  list_update B (i+1) (list_update (B!i) j val)\<close>" 
+
+find_theorems update_2d_array
+find_theorems update_2d_array_core
 
 function_spec partition (lo::nat, hi::nat) returns nat
 pre          "\<open>lo < length A \<and> hi < length A\<close>"    
@@ -116,6 +126,9 @@ defines      " \<open>pivot := A ! hi \<close>  ;- \<open>i := lo \<close> ;- \<
                 call\<^sub>C swap \<open>(i, j)\<close>  ;-
                 return\<^bsub>local_partition_state.result_value_update\<^esub> \<open>i\<close>" 
 
+find_theorems partition
+term partition
+
 thm partition_core_def
 
 
@@ -137,6 +150,10 @@ thm quicksort_def
 thm quicksort_pre_def
 thm quicksort_post_def
 
+find_theorems quicksort_core
+
+
+
 section\<open>Possible Application Sketch\<close>
 
 lemma quicksort_correct : 
diff --git a/C11-BackEnds/Clean/src/Clean.thy b/C11-BackEnds/Clean/src/Clean.thy
index 55dff1dfed6ddc621d9461269f94c2e086fe37cc..02d3c8ea2a0c6662a1603c584271e9f285941f9e 100644
--- a/C11-BackEnds/Clean/src/Clean.thy
+++ b/C11-BackEnds/Clean/src/Clean.thy
@@ -323,8 +323,8 @@ subsection\<open> The Assignment Operations (embedded in State-Exception Monad)
 text\<open>Based on the global variable states, we define   \<^term>\<open>break\<close>-aware and \<^term>\<open>return\<close>-aware 
 version of the assignment. The trick to do this in a generic \<^emph>\<open>and\<close> type-safe way is to provide
 the generated accessor and update functions (the ``lens'' representing this global variable,
-cf. \<^cite>\<open>"Foster2009BidirectionalPL" and "DBLP:journals/toplas/FosterGMPS07" and
-"DBLP:conf/ictac/FosterZW16"\<close>) to the generic assign operators. This pair of accessor and update
+cf. \cite{"Foster2009BidirectionalPL" and "DBLP:journals/toplas/FosterGMPS07" and
+"DBLP:conf/ictac/FosterZW16"} to the generic assign operators. This pair of accessor and update
 carries all relevant semantic and type information of this particular variable and \<^emph>\<open>characterizes\<close>
 this variable semantically. Specific syntactic support~\<^footnote>\<open>via the Isabelle concept of
 cartouche: \<^url>\<open>https://isabelle.in.tum.de/doc/isar-ref.pdf\<close>\<close> will hide away the syntactic overhead 
@@ -591,6 +591,9 @@ fun mk_Some t = let val some = \<^const_name>\<open>Option.option.Some\<close>
 
 fun dest_listTy (Type(\<^type_name>\<open>List.list\<close>, [T])) = T;
 
+fun is_listTy t = case t of (Type(\<^type_name>\<open>List.list\<close>, [T])) => true
+                        | _ => false
+
 fun mk_hdT t = let val ty = fastype_of t 
                in  Const(\<^const_name>\<open>List.hd\<close>, ty --> (dest_listTy ty)) $ t end
 
@@ -605,9 +608,13 @@ fun meta_eq_const T = Const (\<^const_name>\<open>Pure.eq\<close>, T --> T --> p
 
 fun mk_meta_eq (t, u) = meta_eq_const (fastype_of t) $ t $ u;
 
+
 fun   mk_pat_tupleabs [] t = t
     | mk_pat_tupleabs [(s,ty)] t = absfree(s,ty)(t)
-    | mk_pat_tupleabs ((s,ty)::R) t = HOLogic.mk_case_prod(absfree(s,ty)(mk_pat_tupleabs R t));
+    | mk_pat_tupleabs ((s,ty)::R) t = HOLogic.mk_case_prod(absfree(s,ty)(mk_pat_tupleabs R t))
+fun   mk_pat_tupleabs_wrapper [] t = absfree("unitparam",@{typ unit}) t
+    | mk_pat_tupleabs_wrapper R t = mk_pat_tupleabs R t 
+
 
 fun read_constname ctxt n = fst(dest_Const(Syntax.read_term ctxt n))
 
@@ -891,7 +898,7 @@ fun typ_2_string_raw (Type(s,[TFree _])) = if String.isSuffix "_scheme" s
 fun new_state_record0 add_record_cmd is_global_kind (aS, raw_fields) thy =
     let val state_index = (Int.toString o length o Symtab.dest)
                                 (StateMgt_core.get_state_field_tab_global thy)
-        val state_pos = (Binding.pos_of o #1 o hd) raw_fields
+        val state_pos = (Binding.pos_of o #1 o hd) raw_fields (*This hd is probably the reason why we cant have empty local vars*)
         val ((raw_params, binding), res_ty) = case aS of 
                                                 SOME d => d
                                               | NONE => (([], Binding.make(state_index,state_pos)), NONE)
@@ -899,8 +906,6 @@ fun new_state_record0 add_record_cmd is_global_kind (aS, raw_fields) thy =
                       then mk_global_state_name binding
                       else mk_local_state_name binding
         val raw_parent = SOME(typ_2_string_raw (StateMgt_core.get_state_type_global thy))
-        val _ = writeln("XXXXX " ^ @{make_string} raw_params ^ "CCC " ^  @{make_string} binding 
-                                 ^ @{make_string} raw_fields)
         val pos = Binding.pos_of binding
         fun upd_state_typ thy =  StateMgt_core.upd_state_type_global 
                                   (K (parse_typ_'a (Proof_Context.init_global thy) binding)) thy
@@ -917,8 +922,8 @@ fun new_state_record0 add_record_cmd is_global_kind (aS, raw_fields) thy =
 val add_record_cmd    = add_record_cmd0 read_fields;
 val add_record_cmd'   = add_record_cmd0 pair;
 
-val new_state_record  = new_state_record0 add_record_cmd
-val new_state_record' = new_state_record0 add_record_cmd';
+val new_state_record =  new_state_record0 add_record_cmd;
+val new_state_record'=new_state_record0 add_record_cmd';
 
 
 fun clean_ctxt_parser b = Parse.$$$ "(" 
@@ -1156,13 +1161,13 @@ structure Function_Specification_Parser  =
    fun define_cond binding f_sty transform_old check_absence_old cond_suffix params read_cond (ctxt:local_theory) = 
        let val params' = map (fn(b, ty) => (Binding.name_of b,ty)) params
            val src' = case transform_old (read_cond ctxt) of 
-                        Abs(nn, sty_pre, term) => mk_pat_tupleabs params' (Abs(nn,sty_pre,term))
-                      | _ => error ("define abstraction for result" ^ Position.here \<^here>)
+                        Abs(nn, sty_pre, term) => mk_pat_tupleabs_wrapper params' (Abs(nn,sty_pre,term))
+                      | a => error ("define abstraction for result" ^ (Position.here \<^here>)^(@{make_string}a))
            val bdg = Binding.suffix_name cond_suffix binding
            val _ = check_absence_old src'
            val bdg_ty = HOLogic.mk_tupleT(map (#2) params) --> f_sty HOLogic.boolT
            val eq =  mk_meta_eq(Free(Binding.name_of bdg, bdg_ty),src')
-           val args = (SOME(bdg,NONE,NoSyn), (Binding.empty_atts,eq),[],[]) 
+           val args = (SOME(bdg,NONE,NoSyn), (Binding.empty_atts,eq),[],[])
        in  StateMgt.cmd args ctxt end
 
    fun define_precond binding sty =
@@ -1177,10 +1182,8 @@ structure Function_Specification_Parser  =
            val bdg_core_name = Binding.name_of bdg_core
 
            val umty = args_ty --> StateMgt.MON_SE_T @{typ "unit"} sty
-
-           val eq = mk_meta_eq(Free (bdg_core_name, umty),mk_pat_tupleabs params' body)
+           val eq = mk_meta_eq(Free (bdg_core_name, umty),mk_pat_tupleabs_wrapper params' body)
            val args_core =(SOME (bdg_core, SOME umty, NoSyn), (Binding.empty_atts, eq), [], [])
-
        in StateMgt.cmd args_core
        end 
  
@@ -1199,7 +1202,7 @@ structure Function_Specification_Parser  =
            val params' = map (fn(b, ty) => (Binding.name_of b,ty)) params
            val measure_term = case read_variant_opt  of
                                  NONE => Free(bdg_ord_name,args_ty --> HOLogic.natT)
-                               | SOME f => ((f ctxt) |> mk_pat_tupleabs params')
+                               | SOME f => ((f ctxt) |> mk_pat_tupleabs_wrapper params')
            val measure =  Const(@{const_name "Wellfounded.measure"}, (args_ty --> HOLogic.natT)
                                                                      --> argsRelSet )
                           $ measure_term
@@ -1208,7 +1211,7 @@ structure Function_Specification_Parser  =
                                                                        --> args_ty --> rmty) $
                                          Free(bdg_ord_name, args_ty --> HOLogic.natT)
                           else Free(Binding.name_of binding, args_ty --> rmty)
-           val rhs_main = mk_pat_tupleabs params'
+           val rhs_main = mk_pat_tupleabs_wrapper params'
                           (Const(@{const_name "Clean.block\<^sub>C"}, umty --> umty  --> rmty --> rmty)
                           $ Const(read_constname ctxt (Binding.name_of push_name),umty)
                           $ (Const(read_constname ctxt bdg_core_name, args_ty --> umty)  
@@ -1275,17 +1278,19 @@ val _ = Named_Target.theory_map;
                                         #> define_postcond binding ret_ty sty_old params read_post)
                      in parse_contract
                      end
-                |> StateMgt.new_state_record false (SOME (([],binding), SOME ret_type),locals)
+                |>(let val v = StateMgt.new_state_record false (SOME (([],binding), SOME ret_type),locals)
+                    in v end)
                 |> theory_map
                          (fn params => fn ret_ty => fn ctxt => 
-                          let val sty = StateMgt_core.get_state_type ctxt
+                          let 
+                              val sty = StateMgt_core.get_state_type ctxt
                               val args_ty = HOLogic.mk_tupleT (map snd params)
                               val mon_se_ty = StateMgt_core.MON_SE_T ret_ty sty
                               val body = read_body ctxt mon_se_ty
                               val ctxt' =
                                 if #recursive isrec then
-                                  Proof_Context.add_fixes 
-                                    [(binding, SOME (args_ty --> mon_se_ty), NoSyn)] ctxt |> #2
+                                  (Proof_Context.add_fixes 
+                                    [(binding, SOME (args_ty --> mon_se_ty), NoSyn)] ctxt |> #2)
                                 else
                                   ctxt
                               val body = read_body  ctxt' mon_se_ty
@@ -1397,7 +1402,7 @@ definition while_C_A :: " (('\<sigma>_ext) control_state_scheme \<Rightarrow> bo
                         \<Rightarrow> (unit, ('\<sigma>_ext) control_state_ext)MON\<^sub>S\<^sub>E"
   where   "while_C_A Inv f c B \<equiv> while_C c B"
 
-
+                                 
 ML\<open>
 
 structure Clean_Term_interface = 
@@ -1407,40 +1412,37 @@ fun mk_seq_C C C' = let val t = fastype_of C
                      val t' =  fastype_of C'
                  in  Const(\<^const_name>\<open>bind_SE'\<close>, t --> t' --> t') $ C $ C' end;
 
+fun mk_seq_assign_C rhs lhs varname vartyp= let
+                    val t1 = fastype_of rhs
+                    val t2 = fastype_of lhs
+                in Const(\<^const_name>\<open>bind_SE\<close>, t1 --> (vartyp --> t2) --> t2 ) $ rhs $ absfree (varname, vartyp) lhs end;
+
 fun mk_skip_C sty = Const(\<^const_name>\<open>skip\<^sub>S\<^sub>E\<close>, StateMgt_core.MON_SE_T HOLogic.unitT sty)
 
 fun mk_break sty = 
     Const(\<^const_name>\<open>break\<close>, StateMgt_core.MON_SE_T HOLogic.unitT sty )
 
 fun mk_return_C upd rhs =
-    let val ty = fastype_of rhs 
-        val (sty,rty) = case ty of 
-                         Type("fun", [sty,rty]) => (sty,rty)
-                        | _  => error "mk_return_C: illegal type for body"
-        val upd_ty = (HOLogic.listT rty --> HOLogic.listT rty) --> sty --> sty
+    let val (rty, sty) = case fastype_of upd of Type("fun",[Type("fun", [Type(_(*list*),[r_ty]),_]),Type ("fun",[s_ty,_])]) => (r_ty, s_ty)
+                                                  | _=>error "mk_return_C: illegal type for update func"
+
         val rhs_ty = sty --> rty
         val mty = StateMgt_core.MON_SE_T HOLogic.unitT sty
-    in Const(\<^const_name>\<open>return\<^sub>C\<close>, upd_ty --> rhs_ty --> mty) $ upd $ rhs end
+    in Const(\<^const_name>\<open>return\<^sub>C\<close>, fastype_of upd --> rhs_ty --> mty) $ upd $ rhs end
 
 fun mk_assign_global_C upd rhs =
-    let val ty = fastype_of rhs 
-        val (sty,rty) = case ty of 
-                         Type("fun", [sty,rty]) => (sty,rty)
-                        | _  => error "mk_assign_global_C: illegal type for body"
-        val upd_ty = (rty --> rty) --> sty --> sty
+    let val (rty, sty) = case fastype_of upd of Type("fun",[Type("fun", [r_ty,_]),Type ("fun",[s_ty,_])]) => (r_ty, s_ty)
+                                                  | _=>error "mk_assign_global_C: illegal type for update func"
         val rhs_ty = sty --> rty
         val mty = StateMgt_core.MON_SE_T HOLogic.unitT sty
-    in Const(\<^const_name>\<open>assign_global\<close>, upd_ty --> rhs_ty --> mty) $ upd $ rhs end
+    in Const(\<^const_name>\<open>assign_global\<close>, fastype_of upd --> rhs_ty --> mty) $ upd $ rhs end
 
 fun mk_assign_local_C upd rhs =
-    let val ty = fastype_of rhs 
-        val (sty,rty) = case ty of 
-                         Type("fun", [sty,rty]) => (sty,rty)
-                        | _  => error "mk_assign_local_C: illegal type for body"
-        val upd_ty = (HOLogic.listT rty --> HOLogic.listT rty) --> sty --> sty
+    let val (rty, sty) = case fastype_of upd of Type("fun",[Type("fun", [Type(_(*list*),[r_ty]),_]),Type ("fun",[s_ty,_])]) => (r_ty, s_ty)
+                                                  | _=>error "mk_assign_local_C: illegal type for update func"
         val rhs_ty = sty --> rty
         val mty = StateMgt_core.MON_SE_T HOLogic.unitT sty
-    in Const(\<^const_name>\<open>assign_local\<close>, upd_ty --> rhs_ty --> mty) $ upd $ rhs end
+    in Const(\<^const_name>\<open>assign_local\<close>, fastype_of upd --> rhs_ty --> mty) $ upd $ rhs end
 
 fun mk_call_C opn args =
     let val ty = fastype_of opn 
@@ -1492,17 +1494,19 @@ end;\<close>
 
 section\<open>Function-calls in Expressions\<close>
 
-text\<open>The precise semantics of function-calls appearing inside expressions is underspecified in C,
+text\<open>The precise semantics of function-calls appearing inside expressions is under-specified in C,
 which is a notorious problem for compilers and analysis tools. In Clean, it is impossible by 
-construction --- and the type displine --- to have function-calls inside expressions.
+construction --- and the type discipline --- to have function-calls inside expressions.
 However, there is a somewhat \<^emph>\<open>recommended coding-scheme\<close> for this feature, which leaves this
 issue to decisions in the front-end:
-\begin{verbatim}
-  a = f() + g();
-\end{verbatim}
+
+@{verbatim [indent=10, indent=70] \<open>a = f() + g();\<close>}
+
 can be represented in Clean by:
-\<open>x \<leftarrow> f(); y \<leftarrow> g(); \<open>a := x + y\<close> \<close> or 
-\<open>x \<leftarrow> g(); y \<leftarrow> f(); \<open>a := y + x\<close> \<close>
+
+@{cartouche [indent=10, indent=70] \<open>x \<leftarrow> f(); y \<leftarrow> g(); \<open>a := x + y\<close> \<close>} or 
+@{cartouche [indent=10, indent=70] \<open>x \<leftarrow> g(); y \<leftarrow> f(); \<open>a := y + x\<close> \<close>}
+
 which makes the evaluation order explicit without introducing
 local variables or any form of explicit trace on the state-space of the Clean program. We assume, 
 however, even in this coding scheme, that \<^verbatim>\<open>f()\<close> and \<^verbatim>\<open>g()\<close> are atomic actions; note that this 
diff --git a/C11-BackEnds/Clean/src/MonadSE.thy b/C11-BackEnds/Clean/src/MonadSE.thy
index 70ea4d48fdd362c8e530b76cd25c57be1f950610..b6f9589b94931f87440ffad1b8fd4ace40d765df 100644
--- a/C11-BackEnds/Clean/src/MonadSE.thy
+++ b/C11-BackEnds/Clean/src/MonadSE.thy
@@ -69,7 +69,7 @@ syntax    (xsymbols)
           ("(2 _ \<leftarrow> _; _)" [5,8,8]8)
 translations 
           "x \<leftarrow> f; g" == "CONST bind_SE f (% x . g)"
-
+                                             
 definition unit_SE :: "'o \<Rightarrow> ('o, '\<sigma>)MON\<^sub>S\<^sub>E"   ("(result _)" 8) 
 where     "unit_SE e = (\<lambda>\<sigma>. Some(e,\<sigma>))"
 notation   unit_SE ("unit\<^sub>S\<^sub>E")
diff --git a/C11-BackEnds/Clean_wrapper/examples/Coder_Documentation.thy b/C11-BackEnds/Clean_wrapper/examples/Coder_Documentation.thy
new file mode 100644
index 0000000000000000000000000000000000000000..2280718b400d3b357f2c2d59bc2cfc75d7a07d2a
--- /dev/null
+++ b/C11-BackEnds/Clean_wrapper/examples/Coder_Documentation.thy
@@ -0,0 +1,140 @@
+(*In this file the current limitations of the translation from C to Clean are shown.*)
+theory "Coder_Documentation"
+  imports
+          "../src/compiler/Clean_Annotation"
+          "../src/CleanTranslationHook"
+begin
+
+
+section\<open>Architecture remarks\<close>
+text\<open>
+The function 
+   @{verbatim [indent=10, margin=70]
+     \<open>handle_declarations::nodeInfo cTranslationUnit -> Context.generic -> Context.generic\<close>}
+can be called with the AST of a translation unit to handle all the definitions. Within that, for every
+function the \<open>convertStmt\<close> (CleanCoder) is called to create a translation of the function body.
+
+The \<^verbatim>\<open>setup C_Module.C_Term.map_expression\<close> command handles the C-Term-Antiquotation, which is used for the annotations.
+The parsing of the annotation is delayed, for the reason that they need a contet within which sigma (and vars)
+are already defined. For that reason, they are stored in  \<^verbatim>\<open>Data_Clean_Annotations\<close> as functions with the
+signature  \<^verbatim>\<open>Context.generic \<rightarrow> term\<close>. This functions are then called when the new context is available.
+Additionally the position and function names are saved, which are needed for assigning pre- and postconditions to
+the functions and assigning invariants and measures to a loop (via positions).
+
+Importantly, the parsing of the expressions still needs the "old" env because it contains informations
+about local vars and parameters, therefore this is saved in the beginning of the  \<^verbatim>\<open>map_context_annotation_declaration\<close> function.
+The environment is then passed by writing it to the  \<^verbatim>\<open>Data_Surrounding_Env\<close> GenericData-store.
+
+To prevent Isabelle from coercing types of returned terms  \<^verbatim>\<open>Syntax.parse_term\<close> is used instead of  \<^verbatim>\<open>Syntax.read_term\<close>.
+Furthermore as parameters are represented as free variables, all constants that would be "selected" through
+a parameter name need to be hidden ( \<^verbatim>\<open>remove_params_from_proof\<close>).
+
+\<^bold>\<open>Environment\<close>:
+The scope of a parameter now is visible in the environment's var table. It is either "Global", "Local" or "Parameter".
+Furthermore each identifier has a field  \<^verbatim>\<open>functionArgs\<close> which is an optional list of function parameters.
+When an identifier has  \<^verbatim>\<open>functionArgs = NONE\<close>, then it is a variable.  \<^verbatim>\<open>functionArgs=SOME []\<close> corresponds to a parameterless function.
+
+\<^bold>\<open>Nice to know:\<close>
+- The environment of the last completely parsed C-context can be retrieved using \<^verbatim>\<open>C_Module.Data_In_Env\<close>.
+- Intermediate envs, containing parameters and local vars can be retrieved using \<^verbatim>\<open>C_Env.Data_Lang.get'\<close>.
+See C5.thy in the examples of C11-Frontend.
+\<close>
+
+section\<open>Limitations\<close>
+text\<open>
+\<^item> Only two types are currently mapped to isabelle types, 
+  namely \<^verbatim>\<open>int -> int\<close> and \<^verbatim>\<open>unsigned -> int\<close>.
+
+\<^item> Function calls can only occur as statements or on the right hand side of an assignment.
+  For example  \<^verbatim>\<open>a = b + foo();\<close> is not allowed. This must be rewritten as \<open>tmp = foo(); a=b+tmp;\<close>
+
+  Clean and is about to be fixed. The current translation should work for this case then.
+
+\<^item> Scoping: refrain from defining variables more than once. A read/write from a local variable
+  always affects the most recent definition. Scoping using curly braces does not work as in C!
+    Example:  
+    @{verbatim [indent=10, margin=70]
+     \<open>int foo(){
+        int x = 3;
+        {
+          int x = 5;
+        }
+        return x;  // wrongly returns 5
+      }\<close>}
+  Also defining global variables twice within one translation unit will result in only one definition, 
+  thus the second definition does not "reset" the value of the variable
+
+\<^item> Method overloading: Do not use function names multiple times, as this will break the whole
+  translation process in several ways.
+\<close>
+
+section\<open>Some examples\<close>
+
+text\<open>See \<open>Coder_Test_T_Units\<close> for more examples:\<close>
+
+C\<open>
+int sum_of_array(int arr[], int length){
+  int i;
+  int sum;
+  i = 0;
+  sum = 0;
+  while(i < length){
+    /*@ inv\<^sub>C\<^sub>l\<^sub>e\<^sub>a\<^sub>n  \<open>\<^C>\<^sub>e\<^sub>x\<^sub>p\<^sub>r\<open>i\<close> \<le> \<^C>\<^sub>e\<^sub>x\<^sub>p\<^sub>r\<open>length\<close>\<close> */
+    /*@ measure\<^sub>C\<^sub>l\<^sub>e\<^sub>a\<^sub>n  \<open>nat \<^C>\<^sub>e\<^sub>x\<^sub>p\<^sub>r\<open>length-i\<close>\<close> */
+    sum = sum + arr[i];
+    i = i+1;
+  }
+  return sum;
+}
+\<close>
+(*look at the annotated while loop - it has the inv as first and the measure as snd argument*)
+find_theorems sum_of_array_core
+
+text\<open>The following program would not work in C - Clean admits it however, but produces warnings\<close>
+C\<open>
+int A[5][4];
+int swap_rows(unsigned idx1, unsigned idx2){
+  int tmp[];
+  tmp = A[idx1];
+  A[idx1] = A[idx2];
+  A[idx2] = tmp;
+}
+\<close>
+find_theorems swap_rows_core
+
+text\<open>A fully annotated multiply\<close>
+C\<open>
+int multiply(int a, int b){
+  /*@ pre\<^sub>C\<^sub>l\<^sub>e\<^sub>a\<^sub>n  \<open>\<^C>\<^sub>e\<^sub>x\<^sub>p\<^sub>r\<open>a\<close> \<ge> 0\<close> */
+  /*@ post\<^sub>C\<^sub>l\<^sub>e\<^sub>a\<^sub>n  \<open>\<lambda>ret::int. ret = \<^C>\<^sub>e\<^sub>x\<^sub>p\<^sub>r\<open>a*b\<close>\<close> */
+  int sum;
+  int counter;
+  sum = 0;
+  counter = 0;
+
+  while(counter < a){
+    /*@ inv\<^sub>C\<^sub>l\<^sub>e\<^sub>a\<^sub>n  \<open>\<^C>\<^sub>e\<^sub>x\<^sub>p\<^sub>r\<open>counter*b\<close> = \<^C>\<^sub>e\<^sub>x\<^sub>p\<^sub>r\<open>sum\<close> \<and> \<^C>\<^sub>e\<^sub>x\<^sub>p\<^sub>r\<open>counter\<close> \<le> \<^C>\<^sub>e\<^sub>x\<^sub>p\<^sub>r\<open>a\<close>\<close> */
+    sum = sum + b;
+    counter = counter + 1;
+  }
+  return sum;
+}
+\<close>
+find_theorems multiply
+find_theorems multiply_pre
+find_theorems multiply_post
+
+text\<open>A recursive function calculating the factorial of \<open>n\<close>\<close>
+C\<open>
+int factorial_result;
+void factorial(int n){
+  if(n > 1){
+    factorial(n-1);
+    factorial_result = multiply(factorial_result, n);
+  }else{
+    factorial_result = 1;
+  }
+}\<close>
+find_theorems factorial_core
+
+end
diff --git a/C11-BackEnds/Clean_wrapper/examples/Coder_Test_Env_AEnv.thy b/C11-BackEnds/Clean_wrapper/examples/Coder_Test_Env_AEnv.thy
index db49ae7f09fdc431e0d362da60e00c5150b9de14..e9efd0875f685b018724748e2076abad4a6afa95 100644
--- a/C11-BackEnds/Clean_wrapper/examples/Coder_Test_Env_AEnv.thy
+++ b/C11-BackEnds/Clean_wrapper/examples/Coder_Test_Env_AEnv.thy
@@ -1,10 +1,12 @@
+section \<open>Accessing the \<open>C-Environment\<close> and Conversions to the \<open>Clean Environment\<close>\<close>
+
 theory "Coder_Test_Env_AEnv"
   imports "../src/CleanCoder"
 begin
 
 
 
-section \<open>Accessors to C-Env\<close>
+subsection \<open>Accessors to \<open>C_Env\<close>\<close>
 
 ML\<open>
 fun map_option f (SOME X) = SOME(f X)
@@ -12,7 +14,7 @@ fun map_option f (SOME X) = SOME(f X)
 
 fun lookup_Cid_info (C_env:C_Module.Data_In_Env.T) id = Symtab.lookup(#idents(#var_table C_env)) id
 
-fun is_global_Cid Cenv Cid     = map_option (#global o #3) (lookup_Cid_info Cenv Cid);
+fun is_global_Cid Cenv Cid     = map_option (#scope o #3) (lookup_Cid_info Cenv Cid);
 fun is_fun_Cid Cenv Cid        = map_option ((fn [C_Ast.CFunDeclr0 _] => true | _ => false) 
                                                o (#params o #3)) 
                                             (lookup_Cid_info Cenv Cid);
@@ -27,8 +29,9 @@ C11_Ast_Lib.toString_nodeinfo;
 C_Ast.SS_base
 \<close>
 
-section \<open>Global Variables, Local Variables, and Local Parameters\<close>
-subsection\<open>An Environment Spy\<close>
+subsection \<open>Global Variables, Local Variables, and Local Parameters\<close>
+
+subsubsection\<open>An Environment Spy\<close>
 
 ML\<open>
 val ENV = Unsynchronized.ref (@{C\<^sub>e\<^sub>n\<^sub>v})
@@ -38,7 +41,6 @@ fun print_env' s _ stack _ env thy =
   in thy end
 \<close>
 
-ML\<open>open Position\<close>
 setup \<open>ML_Antiquotation.inline @{binding print_env'}
                                (Scan.peek (fn _ => Scan.option Parse.embedded)
                                 >> (fn name => ("print_env' "
@@ -46,7 +48,7 @@ setup \<open>ML_Antiquotation.inline @{binding print_env'}
                                                               | SOME s => "(SOME \"" ^ s ^ "\")")
                                                 ^ " " ^ ML_Pretty.make_string_fn)))\<close>
 
-subsection\<open>Accessing the C_Env in an Example\<close>
+subsection\<open>Accessing the \<open>C_Env\<close> in an Example\<close>
 
 C \<comment> \<open>Nesting ML code in C comments\<close> \<open>
 int a(int b){int c; 
@@ -64,8 +66,6 @@ val b_res = lookup_Cid_info (!ENV) "b";
 val c_res = lookup_Cid_info (!ENV) "c"
 \<close>
 
-
-(* Problematic : *)
 C \<comment> \<open>Nesting ML code in C comments\<close> \<open>
 int a (int b){int b; 
               return b;
@@ -80,9 +80,7 @@ lookup_Cid_info (!ENV) "b"
 
 
 
-
-
-section \<open>Global Declarations via CEnv and via the Clean API\<close>
+subsection \<open>Global Declarations via \<open>C_Env\<close> and via the Clean API\<close>
 
 text \<open>
 First, we translate the expressions;
@@ -104,8 +102,9 @@ ML\<open>val sigma_i = StateMgt.get_state_type_global @{theory}\<close>
 declare [[C\<^sub>r\<^sub>u\<^sub>l\<^sub>e\<^sub>0 = "translation_unit"]]
 declare [[C\<^sub>e\<^sub>n\<^sub>v\<^sub>0 = last]]
 
-C\<open> int a[10+12][34][] = 1;
-   short int f(int x [][], long double y)
+C\<open>int a[10+12][34][] = 1;
+   \<close>
+C\<open> short int f(int x [][], long /* double */ y)
      {int y; x=x;
       /*@@ \<approx>setup \<open>@{print_env'}\<close> */
       /*@@ highlight */}
@@ -142,8 +141,6 @@ val [((Some (CDeclr0 (_,t,_,_,_)),_),_)] = B'
 end
 \<close>
 
-ML\<open>(#ret o #3 o the)(lookup_Cid_info env_expr "f" );\<close>
-
 ML\<open>
 C11_TypeSpec_2_CleanTyp.conv_CDerivedDecl_typ;C_Ast.CFunDeclr0;
 val S = hd ((#params o  #3 o the)(lookup_Cid_info env_expr "f" ));
@@ -152,7 +149,6 @@ val S' = C11_TypeSpec_2_CleanTyp.conv_CDerivedDecl_typ [S] sigma_i
 (* and the whole thing a bit more abstract with "a" and "f" *)
 ML\<open>
 map_option (C11_TypeSpec_2_CleanTyp.conv_GlobalIdDescr_typ o #3) (lookup_Cid_info env_expr "a" );
-(* map_option (conv_GlobalIdDescr_typ o #3) (lookup_Cid_info env_expr "f" ); *)
 map_option (C11_TypeSpec_2_CleanTyp.conv_GlobalIdDescr_typ o #3) (lookup_Cid_info env_expr "x" );
 map_option (C11_TypeSpec_2_CleanTyp.conv_GlobalIdDescr_typ o #3) (lookup_Cid_info env_expr "y" );
 \<close>
diff --git a/C11-BackEnds/Clean_wrapper/examples/Coder_Test_ExprStmt.thy b/C11-BackEnds/Clean_wrapper/examples/Coder_Test_ExprStmt.thy
index 8a14a2732e203df2e510984031a696d8d36c03cd..d86d0c17f813de0982de47500df438a988d2ef3f 100644
--- a/C11-BackEnds/Clean_wrapper/examples/Coder_Test_ExprStmt.thy
+++ b/C11-BackEnds/Clean_wrapper/examples/Coder_Test_ExprStmt.thy
@@ -23,9 +23,9 @@ ML\<open>
 open C11_Expr_2_Clean HOLogic;
 
 val S = (C11_Ast_Lib.fold_cExpression (K I) 
-                                      (convertExpr false sigma_i  mt_A_env  @{theory})
+                                      (convertExpr false sigma_i  mt_A_env  @{theory} "" (K NONE))
                                       ast_expr []);
-val S = conv_Cexpr_lifted_term  sigma_i mt_A_env @{theory} ast_expr
+val S = conv_Cexpr_lifted_term  sigma_i mt_A_env @{theory} "" (K NONE) ast_expr
 
 \<close>
 
@@ -48,9 +48,9 @@ ML\<open>val ast_expr = @{C11_CExpr}
 ML\<open>
 
 val S = (C11_Ast_Lib.fold_cExpression (K I) 
-                                      (convertExpr false sigma_i  mt_A_env @{theory}) 
+                                      (convertExpr false sigma_i  mt_A_env @{theory} "" (K NONE)) 
                                       ast_expr []);
-val S = conv_Cexpr_lifted_term  sigma_i mt_A_env @{theory} ast_expr
+val S = conv_Cexpr_lifted_term  sigma_i mt_A_env @{theory} "" (K NONE) ast_expr
 
 \<close>
 
@@ -72,11 +72,10 @@ ML\<open>val ast_expr = @{C11_CExpr}
 
 ML\<open>
 val S = (C11_Ast_Lib.fold_cExpression (K I) 
-                                      (convertExpr false sigma_i  mt_A_env @{theory}) 
+                                      (convertExpr false sigma_i  mt_A_env @{theory} "" (K NONE)) 
                                       ast_expr []);
-val S = conv_Cexpr_lifted_term  sigma_i mt_A_env @{theory} ast_expr
+val S = conv_Cexpr_lifted_term  sigma_i mt_A_env @{theory} "" (K NONE) ast_expr
 \<close>
-
 \<comment> \<open>pretty print of the latter\<close>
 ML\<open>writeln (Syntax.string_of_term_global @{theory} S);\<close>
 
@@ -96,9 +95,9 @@ ML\<open>val ast_expr = @{C11_CExpr}
 ML\<open>
 
 val S = (C11_Ast_Lib.fold_cExpression (K I) 
-                                      (convertExpr false sigma_i  mt_A_env @{theory}) 
+                                      (convertExpr false sigma_i  mt_A_env @{theory} "" (K NONE)) 
                                       ast_expr []);
-val S = conv_Cexpr_lifted_term  sigma_i mt_A_env @{theory} ast_expr
+val S = conv_Cexpr_lifted_term  sigma_i mt_A_env @{theory} "" (K NONE) ast_expr
 
 \<close>
 
@@ -121,9 +120,9 @@ ML\<open>val ast_expr = @{C11_CExpr}
 ML\<open>
 
 val S = (C11_Ast_Lib.fold_cExpression (K I) 
-                                      (convertExpr false sigma_i  mt_A_env @{theory}) 
+                                      (convertExpr false sigma_i  mt_A_env @{theory} "" (K NONE)) 
                                       ast_expr []);
-val S = conv_Cexpr_lifted_term  sigma_i mt_A_env @{theory} ast_expr
+val S = conv_Cexpr_lifted_term  sigma_i mt_A_env @{theory} "" (K NONE) ast_expr
 
 \<close>
 
@@ -147,8 +146,14 @@ C\<open>int a; int b[5];\<close>
 global_vars (test)  (*intern label *)
             a     :: "int"
             b     :: "int list"
-
-
+            c     :: "int list list"
+            n1    :: "nat"
+            n2    :: "nat"
+            var1  :: "int"
+            var2  :: "int"
+
+    find_theorems a
+                                                                 
 declare [[C\<^sub>r\<^sub>u\<^sub>l\<^sub>e\<^sub>0 = "expression"]]
 C\<open>1 * a\<close>
 
@@ -158,7 +163,12 @@ ML\<open>val ast_expr = @{C11_CExpr}
 local open C_AbsEnv HOLogic in
 (* we construct suitable environments by hand for testing: *)
    val A_env0 = [ Identifier("a", @{here}, intT, Global),
-                  Identifier("b", @{here}, listT intT, Global)];
+                  Identifier("b", @{here}, listT intT, Global),
+                  Identifier("c", @{here}, listT (listT intT), Global),
+                  Identifier("n1", @{here}, natT, Global),
+                  Identifier("n2", @{here}, natT, Global),
+                  Identifier("localArr", @{here}, listT intT, Local "to some function"),
+                  Identifier("localArrArr", @{here}, listT (listT intT), Local "to some function")];
    val A_env2 = [ Identifier("a", @{here}, intT, Parameter "of some function")];
 
    val sigma_i = StateMgt.get_state_type_global @{theory}
@@ -168,14 +178,14 @@ end
 ML\<open>
 
 val S = (C11_Ast_Lib.fold_cExpression (K I) 
-                                      (convertExpr false sigma_i  A_env0 @{theory}) 
+                                      (convertExpr false sigma_i  A_env0 @{theory} "" (K NONE)) 
                                       ast_expr []);
-val S = conv_Cexpr_lifted_term  sigma_i A_env0 @{theory} ast_expr
+val S = conv_Cexpr_lifted_term  sigma_i A_env0 @{theory} "" (K NONE) ast_expr
 
 val S'' = (C11_Ast_Lib.fold_cExpression (K I) 
-                                      (convertExpr false sigma_i  A_env2 @{theory}) 
+                                      (convertExpr false sigma_i  A_env2 @{theory} "" (K NONE)) 
                                       ast_expr []);
-val S'' = conv_Cexpr_lifted_term  sigma_i A_env2 @{theory} ast_expr
+val S'' = conv_Cexpr_lifted_term  sigma_i A_env2 @{theory} "" (K NONE) ast_expr
 
 \<close>
 
@@ -183,17 +193,21 @@ val S'' = conv_Cexpr_lifted_term  sigma_i A_env2 @{theory} ast_expr
 ML\<open>writeln (Syntax.string_of_term_global @{theory} S);\<close>
 
 \<comment> \<open>type-check of the latter\<close>
-ML\<open> Sign.certify_term @{theory} S \<close>
+ML\<open> Sign.certify_term @{theory} (Syntax.check_term @{context} S) \<close>
 
 (* This local variable space also creates the update function for the return_result. *)
 local_vars_test  (test_return "int")
     x  :: "int"
     y  :: "int list"
+    localArr :: "int list"
+    localArrArr :: "int list list"
 declare [[C\<^sub>r\<^sub>u\<^sub>l\<^sub>e\<^sub>0 = "translation_unit"]]
 declare [[C\<^sub>e\<^sub>n\<^sub>v\<^sub>0 = last]]
 C\<open>int x; int y[3];\<close>
 
 declare [[C\<^sub>r\<^sub>u\<^sub>l\<^sub>e\<^sub>0 = "expression"]]
+term\<open>result_value\<close>
+find_theorems result_value
 
 C\<open>1 * x\<close>
 ML\<open>val ast_expr = @{C11_CExpr}
@@ -210,9 +224,9 @@ end
 
 ML\<open>
 val S' = (C11_Ast_Lib.fold_cExpression (K I) 
-                                      (convertExpr false sigma_i  A_env1 @{theory}) 
+                                      (convertExpr false sigma_i  A_env1 @{theory} "" (K NONE)) 
                                       ast_expr []);
-val S' = conv_Cexpr_lifted_term  sigma_i A_env1 @{theory} ast_expr
+val S' = conv_Cexpr_lifted_term  sigma_i A_env1 @{theory} "" (K NONE) ast_expr
 \<close>
 
 
@@ -225,15 +239,15 @@ ML\<open>val ast_expr = @{C11_CExpr}
 ML\<open>
 
 val S = (C11_Ast_Lib.fold_cExpression (K I) 
-                                      (convertExpr false sigma_i  A_env1 @{theory}) 
+                                      (convertExpr false sigma_i  A_env1 @{theory} "" (K NONE)) 
                                       ast_expr []);
-val S = conv_Cexpr_lifted_term  sigma_i A_env1 @{theory} ast_expr
+val S = conv_Cexpr_lifted_term  sigma_i A_env1 @{theory} "" (K NONE) ast_expr
 \<close>
 \<comment> \<open>pretty print of the latter\<close>
 ML\<open>writeln (Syntax.string_of_term_global @{theory} S);\<close>
 
 \<comment> \<open>type-check of the latter\<close>
-ML\<open> Sign.certify_term @{theory} S \<close>
+ML\<open>Sign.certify_term @{theory} (Syntax.check_term @{context} S)\<close>
 
 
 (*7*****************************************************************************************************)
@@ -246,9 +260,9 @@ ML\<open>val ast_expr = @{C11_CExpr}
 ML\<open>
 
 val S = (C11_Ast_Lib.fold_cExpression (K I) 
-                                      (convertExpr false sigma_i  A_env0 @{theory}) 
+                                      (convertExpr true sigma_i  A_env0 @{theory} "" (K NONE)) 
                                       ast_expr []);
-val S = conv_Cexpr_lifted_term  sigma_i A_env0 @{theory} ast_expr
+val S = conv_Cexpr_lifted_term  sigma_i A_env0 @{theory} "" (K NONE) ast_expr
 
 \<close>
 
@@ -256,7 +270,7 @@ val S = conv_Cexpr_lifted_term  sigma_i A_env0 @{theory} ast_expr
 ML\<open>writeln (Syntax.string_of_term_global @{theory} S);\<close>
 
 \<comment> \<open>type-check of the latter\<close>
-ML\<open> Sign.certify_term @{theory} S \<close>
+ML\<open>Sign.certify_term @{theory} (Syntax.check_term @{context} S)\<close>
 
 section \<open>statements\<close>
 
@@ -282,7 +296,7 @@ ML\<open>val C_Ast.CCompound0(a, b, c) = ast_stmt;\<close> \<comment> \<open>gra
 ML\<open> 
 val [S] =  (C11_Ast_Lib.fold_cStatement 
                regroup    \<comment> \<open>real rearrangements of stack for statement compounds\<close>
-               (convertStmt true sigma_i A_env0 @{theory}) 
+               (convertStmt true sigma_i A_env0 @{theory} "" (K (NONE, NONE))) 
                           \<comment> \<open>combinator handlicng an individual statement\<close>
                 ast_stmt  \<comment> \<open>C11 ast\<close>
                 []        \<comment> \<open>mt stack\<close>); 
@@ -292,8 +306,115 @@ val [S] =  (C11_Ast_Lib.fold_cStatement
 ML\<open>writeln (Syntax.string_of_term_global @{theory} S);\<close>
 
 \<comment> \<open>type-check of the latter\<close>
+ML\<open>Sign.certify_term @{theory} (Syntax.check_term @{context} S)\<close>
+
+
+text\<open>Write to array\<close>
+
+text\<open>Global\<close>
+C\<open>c[1][a] = a;\<close>
+ML\<open>
+val ast_stmt = @{C11_CStat}
+val env_stmt = @{C\<^sub>e\<^sub>n\<^sub>v}
+\<close>
+
+ML\<open>
+val [S] =  (C11_Ast_Lib.fold_cStatement 
+               regroup    \<comment> \<open>real rearrangements of stack for statement compounds\<close>
+               (convertStmt false sigma_i A_env0 @{theory} "" (K (NONE, NONE))) 
+                          \<comment> \<open>combinator handlicng an individual statement\<close>
+                ast_stmt  \<comment> \<open>C11 ast\<close>
+                []        \<comment> \<open>mt stack\<close>); 
+\<close>
+
+ML\<open>writeln (Syntax.string_of_term_global @{theory} S);\<close>
+
+ML\<open> Sign.certify_term @{theory} S \<close>
+
+text\<open>local\<close>
+C\<open>localArrArr[1][a] = a;\<close>
+ML\<open>
+val ast_stmt = @{C11_CStat}
+val env_stmt = @{C\<^sub>e\<^sub>n\<^sub>v}
+\<close>
+
+ML\<open>
+val [S] =  (C11_Ast_Lib.fold_cStatement 
+               regroup    \<comment> \<open>real rearrangements of stack for statement compounds\<close>
+               (convertStmt false sigma_i A_env0 @{theory} "" (K (NONE, NONE))) 
+                          \<comment> \<open>combinator handlicng an individual statement\<close>
+                ast_stmt  \<comment> \<open>C11 ast\<close>
+                []        \<comment> \<open>mt stack\<close>); 
+\<close>
+
+ML\<open>writeln (Syntax.string_of_term_global @{theory} S);\<close>
+
 ML\<open> Sign.certify_term @{theory} S \<close>
 
+
+text\<open>Read global array\<close>
+C\<open>a = c[1][a];\<close>
+ML\<open>
+val ast_stmt = @{C11_CStat}
+val env_stmt = @{C\<^sub>e\<^sub>n\<^sub>v}
+\<close>
+
+ML\<open>
+val [S] =  (C11_Ast_Lib.fold_cStatement 
+               regroup    \<comment> \<open>real rearrangements of stack for statement compounds\<close>
+               (convertStmt false sigma_i A_env0 @{theory} "" (K (NONE, NONE))) 
+                          \<comment> \<open>combinator handlicng an individual statement\<close>
+                ast_stmt  \<comment> \<open>C11 ast\<close>
+                []        \<comment> \<open>mt stack\<close>); 
+\<close>
+
+ML\<open>writeln (Syntax.string_of_term_global @{theory} S);\<close>
+
+ML\<open> Sign.certify_term @{theory} S \<close>
+
+text\<open>Read local array\<close>
+C\<open>a = localArrArr[1][a];\<close>
+ML\<open>
+val ast_stmt = @{C11_CStat}
+val env_stmt = @{C\<^sub>e\<^sub>n\<^sub>v}
+\<close>
+
+ML\<open>
+val [S] =  (C11_Ast_Lib.fold_cStatement 
+               regroup    \<comment> \<open>real rearrangements of stack for statement compounds\<close>
+               (convertStmt false sigma_i A_env0 @{theory} "" (K (NONE, NONE))) 
+                          \<comment> \<open>combinator handlicng an individual statement\<close>
+                ast_stmt  \<comment> \<open>C11 ast\<close>
+                []        \<comment> \<open>mt stack\<close>); 
+\<close>
+
+ML\<open>writeln (Syntax.string_of_term_global @{theory} S);\<close>
+
+ML\<open> Sign.certify_term @{theory} S \<close>
+
+
+text\<open>mode complex array stuff\<close>
+C\<open>localArr[a] = localArrArr[1][b[c[1][2]]];\<close>
+ML\<open>
+val ast_stmt = @{C11_CStat}
+val env_stmt = @{C\<^sub>e\<^sub>n\<^sub>v}
+\<close>
+
+ML\<open>
+val [S] =  (C11_Ast_Lib.fold_cStatement 
+               regroup    \<comment> \<open>real rearrangements of stack for statement compounds\<close>
+               (convertStmt false sigma_i A_env0 @{theory} "" (K (NONE, NONE))) 
+                          \<comment> \<open>combinator handlicng an individual statement\<close>
+                ast_stmt  \<comment> \<open>C11 ast\<close>
+                []        \<comment> \<open>mt stack\<close>); 
+\<close>
+
+ML\<open>writeln (Syntax.string_of_term_global @{theory} S);\<close>
+
+ML\<open> Sign.certify_term @{theory} S \<close>
+
+
+
 (*2*****************************************************************************************************)
 
 (*if the body is empty, then we put a skip :*)
@@ -308,7 +429,7 @@ ML\<open>val ast_stmt = @{C11_CStat}
 ML\<open>
 val [S] =  (C11_Ast_Lib.fold_cStatement 
                regroup    \<comment> \<open>real rearrangements of stack for statement compounds\<close>
-               (convertStmt false sigma_i A_env0 @{theory}) 
+               (convertStmt false sigma_i A_env0 @{theory} "" (K (NONE, NONE))) 
                           \<comment> \<open>combinator handlicng an individual statement\<close>
                 ast_stmt  \<comment> \<open>C11 ast\<close>
                 []        \<comment> \<open>mt stack\<close>); 
@@ -317,7 +438,7 @@ val [S] =  (C11_Ast_Lib.fold_cStatement
 ML\<open>writeln (Syntax.string_of_term_global @{theory} S);\<close>
 
 \<comment> \<open>type-check of the latter\<close>
-ML\<open> Sign.certify_term @{theory} S \<close>
+ML\<open>Sign.certify_term @{theory} (Syntax.check_term @{context} S)\<close>
 
 (*3*****************************************************************************************************)
 
@@ -332,7 +453,7 @@ for(a = 0; a < 2; a = a + 1){
 ML\<open>
 val [S] =  (C11_Ast_Lib.fold_cStatement 
                regroup    \<comment> \<open>real rearrangements of stack for statement compounds\<close>
-               (convertStmt true sigma_i A_env0 @{theory}) 
+               (convertStmt true sigma_i A_env0 @{theory} "" (K (NONE, NONE))) 
                           \<comment> \<open>combinator handlicng an individual statement\<close>
                 ast_stmt  \<comment> \<open>C11 ast\<close>
                 []        \<comment> \<open>mt stack\<close>); 
@@ -341,7 +462,7 @@ val [S] =  (C11_Ast_Lib.fold_cStatement
 ML\<open>writeln (Syntax.string_of_term_global @{theory} S);\<close>
 
 \<comment> \<open>type-check of the latter\<close>
-ML\<open> Sign.certify_term @{theory} S \<close>
+ML\<open>Sign.certify_term @{theory} (Syntax.check_term @{context} S)\<close>
 
 (*4*****************************************************************************************************)
 
@@ -359,7 +480,7 @@ ML\<open>val ast_stmt = @{C11_CStat}
 ML\<open>
 val [S] =  (C11_Ast_Lib.fold_cStatement 
                regroup    \<comment> \<open>real rearrangements of stack for statement compounds\<close>
-               (convertStmt false sigma_i A_env0 @{theory}) 
+               (convertStmt false sigma_i A_env0 @{theory} "" (K (NONE, NONE))) 
                           \<comment> \<open>combinator handlicng an individual statement\<close>
                 ast_stmt  \<comment> \<open>C11 ast\<close>
                 []        \<comment> \<open>mt stack\<close>); 
@@ -368,7 +489,7 @@ val [S] =  (C11_Ast_Lib.fold_cStatement
 ML\<open>writeln (Syntax.string_of_term_global @{theory} S);\<close>
 
 \<comment> \<open>type-check of the latter\<close>
-ML\<open> Sign.certify_term @{theory} S \<close>
+ML\<open>Sign.certify_term @{theory} (Syntax.check_term @{context} S)\<close>
 
 
 (*5*****************************************************************************************************)
@@ -390,7 +511,7 @@ ML\<open>val sigma_i = StateMgt.get_state_type_global @{theory}\<close>
 ML\<open>
 val [S] =  (C11_Ast_Lib.fold_cStatement 
                regroup    \<comment> \<open>real rearrangements of stack for statement compounds\<close>
-               (convertStmt false sigma_i A_env0 @{theory}) 
+               (convertStmt false sigma_i A_env0 @{theory} "" (K (NONE, NONE))) 
                           \<comment> \<open>combinator handlicng an individual statement\<close>
                 ast_stmt  \<comment> \<open>C11 ast\<close>
                 []        \<comment> \<open>mt stack\<close>); 
@@ -406,7 +527,7 @@ ML\<open> read_N_coerce @{theory} "a" (sigma_i --> intT)\<close>
 ML\<open>writeln (Syntax.string_of_term_global @{theory} S);\<close>
 
 \<comment> \<open>type-check of the latter\<close>
-ML\<open> Sign.certify_term @{theory} S \<close>
+ML\<open>Sign.certify_term @{theory} (Syntax.check_term @{context} S)\<close>
 (* a very serious problem : the inheritance on state spaces is not appropriately mirrored. *)
 
 
@@ -418,7 +539,7 @@ text \<open>The next step is to study the declarations. There are globals or loc
 and functions or variables declarations.\<close>
 
 declare [[C\<^sub>r\<^sub>u\<^sub>l\<^sub>e\<^sub>0 = "external_declaration"]]
-C\<open> int b = a + a;\<close>
+C\<open> int b,a;\<close>
 ML\<open>val ast_ext_decl = @{C11_CExtDecl}
    val env_ext_decl =  @{C\<^sub>e\<^sub>n\<^sub>v}
 
@@ -427,10 +548,9 @@ ML\<open>val ast_ext_decl = @{C11_CExtDecl}
 (* initializers not yet supported; so this gives a local error *)
 ML \<open>
 val S =  (C11_Ast_Lib.fold_cExternalDeclaration regroup
-                  (convertExpr false sigma_i A_env1 @{theory}) (* DOES THIS MAKE SENSE ??? *)
+                  (convertExpr false sigma_i A_env1 @{theory} "" (K (NONE, NONE))) (* DOES THIS MAKE SENSE ??? *)
                   ast_ext_decl 
                   [])
-         handle ERROR _ => (writeln "CATCH ERROR"; []);
 \<close>
 
 (*4*****************************************************************************************************)
@@ -444,7 +564,7 @@ ML\<open>val ast_unit = @{C11_CTranslUnit}
    val env_unit = @{C\<^sub>e\<^sub>n\<^sub>v}
   \<close>
 
-C\<open>int  zzz ;\<close>
+C\<open>int  zzz = 13 ;\<close>
 
 ML\<open>val ast_unit' = @{C11_CTranslUnit}
    val env_unit' = @{C\<^sub>e\<^sub>n\<^sub>v}
@@ -477,16 +597,116 @@ declare [[C\<^sub>e\<^sub>n\<^sub>v\<^sub>0 = last]]
 declare [[C\<^sub>r\<^sub>u\<^sub>l\<^sub>e\<^sub>0 = "translation_unit"]]
 
 C\<open>
-void foo(int xy) { }
+int var1;
+int var2;
+int a;
+int b[];
+void foo(int xy) {
+  int z = xy+2;
+  return z+1;
+}
+
+void three_args_function(int x, int y, int z){
+  x = foo(x);
+}
+
+int fun_with_ret_value(int x){
+  return x;
+}
+\<close>
+
+ML\<open>
+val cenv = @{C\<^sub>e\<^sub>n\<^sub>v}
 \<close>
 
 ML\<open>
 local open C_AbsEnv in
-val (nEnv, callTable) = parseTranslUnitIdentifiers @{C11_CTranslUnit} [] Symtab.empty
+(* val translUnit = @{C11_CTranslUnit} *)
+val (nEnv, callTable) = parseTranslUnitIdentifiers @{C11_CTranslUnit} [] [] Symtab.empty
 val () = List.app printIdentifier nEnv
-val ast_stmt = extractStatement nEnv "foo";
+val ast_stmt = extractStatement nEnv "foo"
 end\<close>
 
+C\<open>
+void test1(int abc, int def) {
+  return abc;
+}
+
+void test2(){
+  return 12;
+}
+\<close>
+
+ML\<open>
+Theory.setup
+  (C_Inner_Syntax.command_no_range
+       (C_Inner_Toplevel.generic_theory oo C_Inner_Isar_Cmd.setup
+         \<open>fn ((v1, (v2, pos1, pos2)) :: _) =>
+              (fn v3 => fn v4 =>
+                tap (fn v5 =>
+                      Position.reports_text [((Position.range (pos1, pos2)
+                                               |> Position.range_position, Markup.intensify), "")]))
+           | _ => fn _ => fn _ => I\<close>)
+       ("store_env", \<^here>, \<^here>))
+\<close>
+
+ML \<open>
+
+
+Theory.setup
+  (C_Inner_Syntax.command_no_range
+       (C_Inner_Toplevel.generic_theory oo C_Inner_Isar_Cmd.setup
+         \<open>fn ((v1, (v2, pos1, pos2)) :: _) =>
+              (fn v3 => fn v4 =>
+                tap (fn v5 =>
+                      (SPY_ENV := SOME (C_Module.env v5);Position.reports_text [((Position.range (pos1, pos2)
+                                               |> Position.range_position, Markup.intensify), "")])))
+           | _ => fn _ => fn _ => I\<close>)
+       ("store_env1", \<^here>, \<^here>))
+\<close>
+
+ML\<open>
+ 
+
+\<close>
+
+
+C\<open>
+void test5(){
+}\<close>
+
+ML\<open>
+val SPY_ENV =  Unsynchronized.ref(NONE:C_Env.env_lang option);\<close>
+C\<open>
+
+
+void test3(char ab[][], int* *c, int *d){
+  int aasdfwqer;
+  
+  return 12;   /*@ \<approx>setup \<open>fn a => fn b => fn env =>
+               (writeln(@{make_string} env);(SPY_ENV := SOME env);I) \<close> */;
+
+}
+\<close>
+
+ML\<open>
+val a = let fun last (a::b::R) = last (b::R)
+               | last [a] = a
+
+in last (#scopes (the (!SPY_ENV))) end
+\<close>
+
+ML\<open>
+
+val tmp1 = (map (fn (a,(_,_,b)) => (a,#scope b,#functionArgs b)) (Symtab.dest (
+ #idents(#var_table(the (!SPY_ENV))))
+))
+\<close>
+
+ML\<open>
+val cenv = @{C\<^sub>e\<^sub>n\<^sub>v}
+\<close>
+
 term\<open>skip\<^sub>S\<^sub>E\<close>
 ML\<open>StateMgt.MON_SE_T HOLogic.unitT sigma_i\<close>
 consts foo :: "int \<Rightarrow> (unit,'a local_test_return_state_scheme)MON\<^sub>S\<^sub>E "
@@ -501,18 +721,83 @@ ML\<open>
 local open C_AbsEnv in
 val foo_stmt = @{C11_CStat};
 end
-
 \<close>
 
 ML\<open>
 val [S] =  (C11_Ast_Lib.fold_cStatement 
                regroup    \<comment> \<open>real rearrangements of stack for statement compounds\<close>
-               (convertStmt true sigma_i nEnv @{theory}) 
+               (convertStmt false sigma_i nEnv @{theory} "" (K (NONE, NONE))) 
                           \<comment> \<open>combinator handlicng an individual statement\<close>
                 foo_stmt  \<comment> \<open>C11 ast\<close>
                 []        \<comment> \<open>mt stack\<close>); 
 \<close>
 
+ML\<open>writeln (Syntax.string_of_term_global @{theory} S);\<close>
+
+ML\<open>Sign.certify_term @{theory} (Syntax.check_term @{context} S)\<close>
+
+subsection\<open>Call with no return type\<close>
+(*Methods call only with sideeffects*)
+consts three_args_function :: "(int * int * int) \<Rightarrow> (unit,'a local_test_return_state_scheme)MON\<^sub>S\<^sub>E "
+C\<open>three_args_function(3+3,4,8);\<close>
+ML\<open>
+val ast_stmt = @{C11_CStat}
+val env_stmt = @{C\<^sub>e\<^sub>n\<^sub>v}
+\<close>
+
+ML\<open>
+val [S] =  (C11_Ast_Lib.fold_cStatement 
+               regroup    \<comment> \<open>real rearrangements of stack for statement compounds\<close>
+               (convertStmt false sigma_i nEnv @{theory} "" (K (NONE, NONE))) 
+                          \<comment> \<open>combinator handlicng an individual statement\<close>
+                ast_stmt  \<comment> \<open>C11 ast\<close>
+                []        \<comment> \<open>mt stack\<close>); 
+
+
+\<close>
+term assign_to_a
+
+ML\<open>writeln (Syntax.string_of_term_global @{theory} S);\<close>
+
+ML\<open>Sign.certify_term @{theory} (Syntax.check_term @{context} S)\<close>
+
+subsection\<open>Call with return type\<close>
+consts fun_with_ret_value :: "(int) \<Rightarrow> (int,'a local_test_return_state_scheme)MON\<^sub>S\<^sub>E "
+
+C\<open>localArr[0]=fun_with_ret_value(3+3);\<close>
+ML\<open>
+val ast_stmt = @{C11_CStat}
+val env_stmt = @{C\<^sub>e\<^sub>n\<^sub>v}
+\<close>
+
+ML\<open>
+(* build the new env with local vars for test purposes *)
+local open C_AbsEnv HOLogic in
+val localVarEnv = [
+                  Identifier("x", @{here}, intT, Local "to some function"),
+                  Identifier("localArr", @{here}, listT intT, Local "to some function"),
+                  Identifier("localArrArr", @{here}, listT (listT intT), Local "to some function")
+]
+end
+val nEnv1 = nEnv@localVarEnv
+\<close>
+
+ML\<open>
+val [S] =  (C11_Ast_Lib.fold_cStatement 
+               regroup    \<comment> \<open>real rearrangements of stack for statement compounds\<close>
+               (convertStmt false sigma_i nEnv1 @{theory} "" (K (NONE, NONE))) 
+                          \<comment> \<open>combinator handlicng an individual statement\<close>
+                ast_stmt  \<comment> \<open>C11 ast\<close>
+                []        \<comment> \<open>mt stack\<close>); 
+
+
+\<close>
+term assign_to_a
+
+ML\<open>writeln (Syntax.string_of_term_global @{theory} S);\<close>
+
+ML\<open>Sign.certify_term @{theory} (Syntax.check_term @{context} S)\<close>
+
 section \<open>Experiments with Local Scopes\<close>
 
 ML\<open> local open C_Ast 
@@ -551,7 +836,8 @@ end
 ML    \<open>(Symtab.dest)(StateMgt_core.get_state_field_tab_global @{theory})\<close>
 setup \<open>conv_transl_unit ast_unit\<close>
 ML    \<open>(Symtab.dest)(StateMgt_core.get_state_field_tab_global @{theory})\<close>
+(* A Cadaver ... 
 setup \<open>conv_transl_unit ast_unit'\<close>
 ML    \<open>(Symtab.dest)(StateMgt_core.get_state_field_tab_global @{theory});\<close>
-
+ *)
 end
\ No newline at end of file
diff --git a/C11-BackEnds/Clean_wrapper/examples/Coder_Test_StmtTUnits.thy b/C11-BackEnds/Clean_wrapper/examples/Coder_Test_StmtTUnits.thy
index 147d53dd86b16698ffce7cff8a6bf13b30820485..015b7abc4dc9b48464976564e1352512a308692a 100644
--- a/C11-BackEnds/Clean_wrapper/examples/Coder_Test_StmtTUnits.thy
+++ b/C11-BackEnds/Clean_wrapper/examples/Coder_Test_StmtTUnits.thy
@@ -14,7 +14,7 @@ C\<open>int global1;\<close>
 
 ML\<open>
 local open C_AbsEnv in
-val (identifiers, callTable) = parseTranslUnitIdentifiers @{C11_CTranslUnit} [] Symtab.empty
+val (identifiers, callTable) = parseTranslUnitIdentifiers @{C11_CTranslUnit} [] [] Symtab.empty 
 val () = List.app printIdentifier identifiers
 end
 \<close>
@@ -24,7 +24,7 @@ C\<open>int global2[];
 
 ML\<open>
 local open C_AbsEnv in
-val (identifiers, callTable) = parseTranslUnitIdentifiers @{C11_CTranslUnit} [] Symtab.empty
+val (identifiers, callTable) = parseTranslUnitIdentifiers @{C11_CTranslUnit} [] [] Symtab.empty
 val () = List.app printIdentifier identifiers
 end
 \<close>
@@ -34,7 +34,7 @@ unsigned int global6, global7;\<close>
 
 ML\<open>
 local open C_AbsEnv in
-val (identifiers, callTable) = parseTranslUnitIdentifiers @{C11_CTranslUnit} [] Symtab.empty
+val (identifiers, callTable) = parseTranslUnitIdentifiers @{C11_CTranslUnit} [] [] Symtab.empty
 val () = List.app printIdentifier identifiers
 end
 \<close>
@@ -46,7 +46,7 @@ int c = foo(a), d;
 
 ML\<open>
 local open C_AbsEnv in
-val (identifiers, callTable) = parseTranslUnitIdentifiers @{C11_CTranslUnit} [] Symtab.empty
+val (identifiers, callTable) = parseTranslUnitIdentifiers @{C11_CTranslUnit} [] [] Symtab.empty
 val () = List.app printIdentifier identifiers
 end\<close>
 
@@ -60,7 +60,7 @@ void test() {
 
 ML\<open>
 local open C_AbsEnv in
-val (nEnv, callTable) = parseTranslUnitIdentifiers @{C11_CTranslUnit} [] Symtab.empty
+val (nEnv, callTable) = parseTranslUnitIdentifiers @{C11_CTranslUnit} [] [] Symtab.empty
 val () = List.app printIdentifier nEnv
 end\<close>
 
@@ -69,7 +69,10 @@ end\<close>
    function definition of `identity` *)
 local_vars_test  (identity "int")
     z  :: "int"
-ML\<open>val sigma_i = StateMgt.get_state_type_global @{theory}\<close>
+ML\<open>val sigma_i = StateMgt.get_state_type_global @{theory}
+
+val Type(ty_name, _) = sigma_i
+\<close>
 
 C\<open>int identity(int a) {
   return a;
@@ -77,7 +80,7 @@ C\<open>int identity(int a) {
 
 ML\<open>
 local open C_AbsEnv in
-val (nEnv, callTable) = parseTranslUnitIdentifiers @{C11_CTranslUnit} [] Symtab.empty
+val (nEnv, callTable) = parseTranslUnitIdentifiers @{C11_CTranslUnit} [] [] Symtab.empty
 val () = List.app printIdentifier nEnv
 val ast_stmt = extractStatement nEnv "identity"
 end
@@ -95,10 +98,12 @@ val lookup=Symtab.lookup state_field p *)
 
 val [S] =  (C11_Ast_Lib.fold_cStatement 
               regroup 
-              (convertStmt false sigma_i nEnv @{theory} )
+              (convertStmt false sigma_i nEnv @{theory} "" (K (NONE, NONE)))
               ast_stmt []);
 \<close>
 
+ML\<open>writeln (Syntax.string_of_term_global @{theory} S);\<close>
+
 ML\<open>
 (* We create an abstraction over the term: iterate backwards using the param list *)
 fun mk_final_term identifiers id t =
@@ -133,7 +138,7 @@ float add(int a, int b) {
 
 ML\<open>
 local open C_AbsEnv in
-val (nEnv, callTable) = parseTranslUnitIdentifiers @{C11_CTranslUnit} [] Symtab.empty
+val (nEnv, callTable) = parseTranslUnitIdentifiers @{C11_CTranslUnit} [] [] Symtab.empty
 val () = List.app printIdentifier nEnv
 val add_ast = @{C11_CTranslUnit}
 val ast_stmt = extractStatement nEnv "add"
@@ -145,12 +150,12 @@ ML\<open>
 
 val [S] =  (C11_Ast_Lib.fold_cStatement 
               regroup 
-              (convertStmt false sigma_i nEnv @{theory} )
+              (convertStmt false sigma_i nEnv @{theory} "" (K (NONE,NONE)) )
               ast_stmt []);
 \<close>
 
 ML\<open>
-val final_term = mk_final_term identifiers "add" S
+val final_term = mk_final_term nEnv "add" S
 \<close>
 
 ML\<open>
@@ -175,7 +180,7 @@ int increment(int a) {
 
 ML\<open>
 local open C_AbsEnv in
-val (nEnv, callTable) = parseTranslUnitIdentifiers @{C11_CTranslUnit} [] Symtab.empty
+val (nEnv, callTable) = parseTranslUnitIdentifiers @{C11_CTranslUnit} [] [] Symtab.empty
 val () = List.app printIdentifier nEnv
 val ast_stmt = extractStatement nEnv "increment";
 end
@@ -185,7 +190,7 @@ end
 ML\<open>
 val [S] =  (C11_Ast_Lib.fold_cStatement 
               regroup 
-              (convertStmt false sigma_i nEnv @{theory})
+              (convertStmt false sigma_i nEnv @{theory} "" (K(NONE,NONE))) 
               ast_stmt [])
            handle ERROR _ => [S];
 \<close>
@@ -207,7 +212,7 @@ void foo() {
 
 ML\<open>
 local open C_AbsEnv in
-val (nEnv, callTable) = parseTranslUnitIdentifiers @{C11_CTranslUnit} [] Symtab.empty
+val (nEnv, callTable) = parseTranslUnitIdentifiers @{C11_CTranslUnit} [] [] Symtab.empty
 val () = List.app printIdentifier nEnv
 val ast_stmt = extractStatement nEnv "foo";
 end
@@ -217,7 +222,7 @@ end
 ML\<open>
 val [S] =  (C11_Ast_Lib.fold_cStatement 
               regroup 
-              (convertStmt true sigma_i nEnv @{theory} )
+              (convertStmt true sigma_i nEnv @{theory} "" (K(NONE,NONE)))
               ast_stmt []);
 \<close>
 
@@ -226,7 +231,7 @@ val final_term = mk_final_term identifiers "foo" S
 \<close>
 
 ML\<open>
-Sign.certify_term @{theory} final_term
+Sign.certify_term @{theory} (Syntax.check_term @{context} final_term)
 \<close>
 
 ML\<open>
@@ -251,14 +256,16 @@ local_vars_test  (paws "unit")
 ML\<open>val sigma_i = StateMgt.get_state_type_global @{theory}\<close>
 ML\<open>val init_ident = [C_AbsEnv.Identifier("swap", Position.none, @{typ "unit"}, C_AbsEnv.FunctionCategory(C_AbsEnv.Final, NONE))]\<close>             
 
+
+(* TODO: should also be defined analogously to unsigned int, unsigned long, ... *)
 C\<open>
-void paws(unsigned int a, unsigned int b) {
+void paws(unsigned a, unsigned b) {
   swap(a, b);
 }\<close>
 
 ML\<open>
 local open C_AbsEnv in
-val (nEnv, callTable) = parseTranslUnitIdentifiers @{C11_CTranslUnit} init_ident Symtab.empty
+val (nEnv, callTable) = parseTranslUnitIdentifiers @{C11_CTranslUnit} init_ident [] Symtab.empty 
 val () = List.app printIdentifier nEnv
 val ast_stmt = extractStatement nEnv "paws";
 end
@@ -267,7 +274,7 @@ end
 ML\<open>
 val [S] =  (C11_Ast_Lib.fold_cStatement 
               regroup 
-              (convertStmt true sigma_i nEnv @{theory})
+              (convertStmt true sigma_i nEnv @{theory} "" (K(NONE,NONE)))
               ast_stmt []);
 \<close>
 
@@ -326,23 +333,28 @@ ML\<open>val init_idents = parse_state_field_tab @{theory}\<close>
 
 C\<open>
 int bar(int a, int b) {
+  int d;
   c = 0;
   return 0;
+  
 }
 \<close>
 
+
 ML\<open>
 local open C_AbsEnv in
-val (nEnv, callTable) = parseTranslUnitIdentifiers @{C11_CTranslUnit} init_idents Symtab.empty
+val (nEnv, callTable) = parseTranslUnitIdentifiers @{C11_CTranslUnit} init_idents [Identifier("c",@{here},HOLogic.intT, Global)] Symtab.empty
 val () = List.app printIdentifier nEnv
 val ast_stmt = extractStatement nEnv "bar";
+
+val env = @{C\<^sub>e\<^sub>n\<^sub>v}
 end
 \<close>
 
 ML\<open>
 val [S] =  (C11_Ast_Lib.fold_cStatement 
               regroup 
-              (convertStmt true sigma_i nEnv @{theory})
+              (convertStmt true sigma_i nEnv @{theory} "" (K(NONE,NONE)))
               ast_stmt []);
 \<close>
 
@@ -351,7 +363,7 @@ val final_term = mk_final_term identifiers "bar" S
 \<close>
 
 ML\<open>
-Sign.certify_term @{theory} final_term
+Sign.certify_term @{theory} (Syntax.check_term @{context} final_term)
 \<close>
 
 ML\<open>
@@ -373,7 +385,7 @@ int factorial(int n) {
 
 ML\<open>
 local open C_AbsEnv in
-val (nEnv, callTable) = parseTranslUnitIdentifiers @{C11_CTranslUnit} [] Symtab.empty
+val (nEnv, callTable) = parseTranslUnitIdentifiers @{C11_CTranslUnit} [] [] Symtab.empty
 val () = List.app printIdentifier nEnv
 val ast_stmt = extractStatement nEnv "factorial";
 end
@@ -384,7 +396,7 @@ end
 ML\<open>
 val [S] =  (C11_Ast_Lib.fold_cStatement 
               regroup 
-              (convertStmt false sigma_i nEnv @{theory} )
+              (convertStmt false sigma_i nEnv @{theory} "" (K(NONE,NONE)))
               ast_stmt [])
            handle ERROR _ => (writeln "correct crash: recursion not supported"; 
                               [@{term "undefined"}])
@@ -416,7 +428,7 @@ writeln (Syntax.string_of_term_global @{theory} final_term);
 
 ML\<open>
 local open C_AbsEnv in
-val (nEnv, callTable) = parseTranslUnitIdentifiers @{C11_CTranslUnit} [] Symtab.empty
+val (nEnv, callTable) = parseTranslUnitIdentifiers @{C11_CTranslUnit} [] [] Symtab.empty
 val () = List.app printIdentifier nEnv
 end\<close>
 
@@ -427,14 +439,14 @@ local_vars_test  (is_even "int")
 ML\<open>val sigma_i = StateMgt.get_state_type_global @{theory}\<close>
 
 C\<open>
-int is_even(unsigned int n) {
+int is_even(unsigned  n) {
     if (n == 0)
         return 0;
     else
         return is_odd(n - 1);
 }
 
-int is_odd(unsigned int n) {
+int is_odd(unsigned  n) {
     if (n == 0)
         return -1;
     else
@@ -444,7 +456,7 @@ int is_odd(unsigned int n) {
 
 ML\<open>
 local open C_AbsEnv in
-val (nEnv, callTable) = parseTranslUnitIdentifiers @{C11_CTranslUnit} [] Symtab.empty
+val (nEnv, callTable) = parseTranslUnitIdentifiers @{C11_CTranslUnit} [] [] Symtab.empty
 val () = List.app printIdentifier nEnv
 val ast_stmt = extractStatement nEnv "is_even";
 end
@@ -454,7 +466,7 @@ end
 ML\<open>
 val [S] =  (C11_Ast_Lib.fold_cStatement 
               regroup 
-              (convertStmt false sigma_i nEnv @{theory})
+              (convertStmt false sigma_i nEnv @{theory} "" (K(NONE,NONE)))
               ast_stmt []) 
             handle ERROR _ => (writeln "correct crash: recursion not supported"; 
                               [@{term "undefined"}]);
@@ -486,7 +498,7 @@ int sqrt(int a) {
 ML\<open>
 local open C_AbsEnv in
 val (nEnv, callTable) = parseTranslUnitIdentifiers @{C11_CTranslUnit} 
-                                  init_idents Symtab.empty
+                                  init_idents [] Symtab.empty
 val () = List.app printIdentifier nEnv
 val ast_stmt = extractStatement nEnv "sqrt";
 end
@@ -495,7 +507,7 @@ end
 ML\<open>
 val [S] =  (C11_Ast_Lib.fold_cStatement 
               regroup 
-              (convertStmt false sigma_i nEnv @{theory})
+              (convertStmt false sigma_i nEnv @{theory} "" (K(NONE,NONE)))
               ast_stmt []);
 \<close>
 
@@ -504,7 +516,7 @@ val final_term = mk_final_term identifiers "sqrt" S
 \<close>
 
 ML\<open>
-Sign.certify_term @{theory} final_term
+Sign.certify_term @{theory} (Syntax.check_term @{context} final_term)
 \<close>
 
 ML\<open>
@@ -533,16 +545,17 @@ int allzeros(int t[], int n) {
 ML\<open>
 local open C_AbsEnv in
 val (nEnv, callTable) = parseTranslUnitIdentifiers @{C11_CTranslUnit} 
-                                      nEnv_0 Symtab.empty
+                                      nEnv_0 [] Symtab.empty
 val () = List.app printIdentifier nEnv
 val ast_stmt = extractStatement nEnv "allzeros";
 end
 \<close>
 
+(* PROBLEM *)
 ML\<open>
 val [S] =  (C11_Ast_Lib.fold_cStatement 
               regroup 
-              (convertStmt false sigma_i nEnv @{theory})
+              (convertStmt false sigma_i nEnv @{theory} "" (K(NONE,NONE)))
               ast_stmt []);
 \<close>
 
@@ -566,7 +579,7 @@ int binarysearch(int t[], int n, int v) {
 
 ML\<open>
 local open C_AbsEnv in
-val (identifiers, callTable) = parseTranslUnitIdentifiers @{C11_CTranslUnit} [] Symtab.empty
+val (identifiers, callTable) = parseTranslUnitIdentifiers @{C11_CTranslUnit} [] [] Symtab.empty
 val () = List.app printIdentifier identifiers
 end\<close>
 
@@ -589,7 +602,7 @@ int linearsearch(int x, int t[], int n) {
 
 ML\<open>
 local open C_AbsEnv in
-val (nEnv, callTable) = parseTranslUnitIdentifiers @{C11_CTranslUnit} [] Symtab.empty
+val (nEnv, callTable) = parseTranslUnitIdentifiers @{C11_CTranslUnit} [] [] Symtab.empty
 val () = List.app printIdentifier nEnv
 end\<close>
 
@@ -635,7 +648,7 @@ printf("Sorted list in ascending order:\n");
 
 ML\<open>
 local open C_AbsEnv in
-val (nEnv, callTable) = parseTranslUnitIdentifiers @{C11_CTranslUnit} [] Symtab.empty
+val (nEnv, callTable) = parseTranslUnitIdentifiers @{C11_CTranslUnit} [] [] Symtab.empty
 val () = List.app printIdentifier nEnv
 end\<close>
 
@@ -690,7 +703,9 @@ fun convertEnv (name,(pos_list,serial,{ global = true , params = [] , ret = Pars
 end
 \<close>
 
-ML\<open>val (name,(pos_list,serial,{ global = true , params = P as (C_Ast.CFunDeclr0 G::R) , ret =  Z })) = nth menv 5;
+ML\<open>nth menv 5\<close>
+ML\<open>val (name,(pos_list,serial,{ scope = C_Env.Global , functionArgs=_,
+                                params = P as (C_Ast.CFunDeclr0 G::R) , ret =  Z })) = nth menv 5;
    val curried_w_dummyreturn = C11_TypeSpec_2_CleanTyp.conv_CDerivedDecl_typ P dummyT
    val (tyS,ty) = strip_type curried_w_dummyreturn
    val uncurried_w_dummyreturn = HOLogic.mk_tupleT tyS --> ty
@@ -698,18 +713,13 @@ ML\<open>val (name,(pos_list,serial,{ global = true , params = P as (C_Ast.CFunD
 ML\<open>nth menv 5;
    \<close>
 
-(* So ne scheisse. Der return-type ist zwar im AST sichtbar, aber nicht im globalen (Isabelle_C) 
-   Environment. Da findet sich lediglich : previous in stack. Das verkompliziert die Sache.
-
-   Immerhin:
-*)
-
-ML\<open>map_filter convertEnv menv\<close>
+(* dies ist ein Versuch, ein return in einem globalen Kontext auszufuehren. 
+   Dieser Test macht keinen Sinn.
 
 ML\<open> 
 val [body] =  (C11_Ast_Lib.fold_cStatement 
                regroup    \<comment> \<open>real rearrangements of stack for statement compounds\<close>
-               (convertStmt false (StateMgt_core.get_state_type @{context}) nEnv_0 @{theory}) 
+               (convertStmt false (StateMgt_core.get_state_type @{context}) nEnv_0 @{theory} "" (K(NONE,NONE))) 
                           \<comment> \<open>combinator handlicng an individual statement\<close>
                 ast_stmt  \<comment> \<open>C11 ast\<close>
                 []        \<comment> \<open>mt stack\<close>); 
@@ -730,4 +740,5 @@ val local_thy = Function_Specification_Parser.define_body_core add_bind ret_typ
                         param_list body;
 Function_Specification_Parser.define_body_core add_bind args_ty sty param_list body ctxt
 (*Function_Specification_Parser.define_body_main { recursive = false } add_bind ret_typ sty param_list NONE 0 ctxt*)
-\<close>
\ No newline at end of file
+\<close>
+*)
\ No newline at end of file
diff --git a/C11-BackEnds/Clean_wrapper/examples/Coder_Test_TUnits.thy b/C11-BackEnds/Clean_wrapper/examples/Coder_Test_TUnits.thy
new file mode 100644
index 0000000000000000000000000000000000000000..36ff8a10e8e6cb8144c72b7abccb7a516bc53592
--- /dev/null
+++ b/C11-BackEnds/Clean_wrapper/examples/Coder_Test_TUnits.thy
@@ -0,0 +1,435 @@
+theory "Coder_Test_TUnits"
+  imports
+          "../src/compiler/Clean_Annotation"
+          "../src/CleanTranslationHook"
+begin
+
+declare [[C\<^sub>e\<^sub>n\<^sub>v\<^sub>0 = last]]
+declare [[C\<^sub>r\<^sub>u\<^sub>l\<^sub>e\<^sub>0 = "translation_unit"]]
+
+
+C\<open>
+int foo10(){
+  int b = 0, d123=4, ex=13;
+}
+\<close>
+
+C\<open>
+int foo11(){
+  int var1,var2=3,var3, var4;
+}
+\<close>
+
+C\<open>
+int forloop(){
+  int b=3;
+  for(int i=0; i<10; i=i+1){
+    b=b+1;
+  }
+  return b;
+}
+\<close>
+
+find_theorems d123
+find_theorems foo10_core
+find_theorems forloop_core
+
+text\<open>Apparently currently it is decided based on the stack layout, whether an else branch exists.
+So a previous assignment destroys this code.\<close>
+C\<open>
+int g;
+int foo13(){
+  if(1){
+  }
+  if (g>0){
+     g=1;
+  }
+}
+\<close>
+C\<open>
+int g;
+int foo12(){
+  g = 0;
+  if (g>0){
+     g=1;
+  }
+}
+\<close>
+
+
+C\<open>
+int foo(int a, int b){
+}
+int bar(int b){
+  int a;
+  a = 2;
+}
+\<close>
+
+C\<open>
+int foo1(unsigned par){
+  unsigned tmp;
+  for (tmp = 0; tmp < tmp; tmp=tmp+1) { 
+  }
+}
+\<close>
+
+text\<open>Assigning numbers to a non-int variable causes issues\<close>
+C\<open>
+int bar1(){
+  unsigned tmp;
+  tmp = tmp+0;
+}
+\<close>
+
+C\<open>
+unsigned glob_nat;
+int bar2(){
+  glob_nat = 3;
+}
+\<close>
+
+
+C\<open>
+int multiply1(int a, int b){
+  /*@ pre\<^sub>C\<^sub>l\<^sub>e\<^sub>a\<^sub>n  \<open>(1::int) \<ge> 1\<close> */
+  return a;
+}\<close>
+
+
+term\<open>nat\<close>
+C\<open>
+int u;
+int arrr[];
+\<close>
+C\<open>
+int globvar;
+unsigned nat1;
+int u;
+int fun_with_pre_test(int u){
+  int localvar;
+
+  localvar = u;
+  /*@ pre\<^sub>C\<^sub>l\<^sub>e\<^sub>a\<^sub>n  \<open>\<^C>\<^sub>e\<^sub>x\<^sub>p\<^sub>r\<open>u\<close> > 1\<close> */
+  /*@ post\<^sub>C\<^sub>l\<^sub>e\<^sub>a\<^sub>n  \<open>\<lambda>ret::int.\<^C>\<^sub>e\<^sub>x\<^sub>p\<^sub>r\<open>u\<close> > 1 \<and> ret > 0\<close> */
+
+  while(localvar>0){
+  /*@ inv\<^sub>C\<^sub>l\<^sub>e\<^sub>a\<^sub>n  \<open>\<^C>\<^sub>e\<^sub>x\<^sub>p\<^sub>r\<open>u\<close> \<ge> \<^C>\<^sub>e\<^sub>x\<^sub>p\<^sub>r\<open>localvar\<close> \<close> */
+  /*@ measure\<^sub>C\<^sub>l\<^sub>e\<^sub>a\<^sub>n  \<open> \<^C>\<^sub>e\<^sub>x\<^sub>p\<^sub>r\<open>nat1\<close>\<close> */
+    localvar = localvar -1;
+  }
+
+  return 1;
+}\<close>
+find_theorems fun_with_pre_test_core
+
+
+section\<open>Demonstration\<close>
+
+subsection\<open>Global definitions\<close>
+C\<open>
+int global_integer;
+unsigned global_nat;
+\<close>
+(*variables are declared accordingly*)
+find_theorems global_integer
+find_theorems global_nat
+term\<open>global_integer\<close>
+term\<open>global_nat\<close>
+
+
+
+
+subsection\<open>Function definitions\<close>
+C\<open>int threefunc(){
+  return 1+2;
+}
+
+int sum5(int p1, int p2){
+  return p1+p2;
+}
+
+void addToGlobalInteger(int value){
+  global_integer = global_integer+value;
+}
+\<close>
+
+find_theorems threefunc_core
+term\<open>threefunc\<close>
+find_theorems sum_core
+term\<open>sum\<close>
+
+
+
+
+subsection\<open>And function calls\<close>
+C\<open>
+void addPlusThree(int val){
+  int three; /*Init expression currently unsupported*/
+  three = threefunc();
+  addToGlobalInteger(three+val);
+}
+\<close>
+
+
+text\<open>we compare this to an equivalent definition\<close>
+function_spec addPlusThree1(val :: int) returns unit
+pre          "\<open>True\<close>" 
+post         "\<open>\<lambda>res::unit. True \<close>"
+local_vars   three :: int
+defines "p\<^sub>t\<^sub>m\<^sub>p \<leftarrow> call\<^sub>C threefunc \<open>()\<close> ; assign_local three_update (\<lambda>\<sigma>. p\<^sub>t\<^sub>m\<^sub>p);-
+         call\<^sub>C addToGlobalInteger \<open>(three + val)\<close>"
+
+find_theorems addPlusThree_core
+find_theorems addPlusThree1_core
+term\<open>addPlusThree\<close>
+term\<open>addPlusThree1\<close>
+
+
+
+
+subsection \<open>Recursive functions\<close>
+find_theorems global_integer
+rec_function_spec recursive_add1(n::int) returns unit
+pre          "\<open>True\<close>" 
+post         "\<open>\<lambda>res::unit. True \<close>"
+local_vars   localvar1 :: int
+defines "if\<^sub>C \<open>n > 0\<close>  
+         then (\<open> global_integer :=  global_integer + 1\<close>);-
+               call\<^sub>C recursive_add1 \<open>(n-1)\<close>
+         else skip\<^sub>S\<^sub>E 
+         fi"
+
+C\<open>
+void recursive_add(int n){
+  if(n > 0){
+    global_integer = global_integer + 1;
+    recursive_add(n-1);
+  }
+}\<close>
+
+find_theorems recursive_add_core
+find_theorems recursive_add1_core
+term recursive_add
+term recursive_add1
+
+
+
+
+subsection\<open>(multidimensional) arrays are also supported\<close>
+C\<open>
+int globalArray[][];
+int something(){
+  int localvar;
+  localvar = globalArray[0][3];
+}
+\<close>
+
+
+
+
+subsection\<open>A fully annotated program\<close>
+text\<open>disclaimer: C_expr antiquotation does not yet work\<close>
+
+
+
+C\<open>
+int multiply(int a, int b){
+  /*@ pre\<^sub>C\<^sub>l\<^sub>e\<^sub>a\<^sub>n  \<open>(1::int) \<ge> 1\<close> */
+  /*@ post\<^sub>C\<^sub>l\<^sub>e\<^sub>a\<^sub>n  \<open>\<lambda>ret::int. ret = \<^C>\<^sub>e\<^sub>x\<^sub>p\<^sub>r\<open>a*b\<close>\<close> */
+  int s;
+  int counter;
+  int counter_b;
+  counter = 0;
+  s = 0;
+
+  while(counter < a){
+    /*@ inv\<^sub>C\<^sub>l\<^sub>e\<^sub>a\<^sub>n  \<open>\<^C>\<^sub>e\<^sub>x\<^sub>p\<^sub>r\<open>counter*b\<close> = \<^C>\<^sub>e\<^sub>x\<^sub>p\<^sub>r\<open>s\<close> \<and> \<^C>\<^sub>e\<^sub>x\<^sub>p\<^sub>r\<open>counter\<close> \<le> \<^C>\<^sub>e\<^sub>x\<^sub>p\<^sub>r\<open>a\<close>\<close> */
+    counter_b = 0;
+    while(counter_b < b){
+      /*@ inv\<^sub>C\<^sub>l\<^sub>e\<^sub>a\<^sub>n \<open>\<^C>\<^sub>e\<^sub>x\<^sub>p\<^sub>r\<open>counter_b\<close> \<le> \<^C>\<^sub>e\<^sub>x\<^sub>p\<^sub>r\<open>b\<close>\<close> */      
+      counter_b = counter_b +1;
+    }
+    
+    s = s + counter_b;
+    counter = counter + 1;
+  }
+  return s;
+}
+\<close>
+find_theorems multiply_pre
+
+
+
+
+
+
+section\<open>Some other tests\<close>
+
+C\<open>
+int intarr[][][];
+int x;
+\<close>
+term x
+find_theorems x
+C\<open>
+int sum1(int param1,int param2){
+  x = threefunc();
+  intarr[2][3][1] = x + param1 + param2;
+  return 1;
+}
+
+int sum3(int param1,int param2){
+  int x; // test to override
+  x = sum1(param1, param2);
+  return x;
+}\<close>
+find_theorems x
+find_theorems sum1_core
+C\<open>
+int test_scope(){
+  x = 1;
+  return x;
+}
+\<close>
+
+find_theorems sum3_core
+term\<open>intarr\<close>
+
+
+C\<open>
+int a;
+int testfunction(int v1, int v2){
+  global_integer = sum1(v1,v2);
+  return global_integer;
+}
+\<close>
+
+C\<open>
+int b;
+\<close>
+
+text\<open>Now the declaration of local variables\<close>
+C\<open>
+int funwithlocalvars(){
+  int localvar1;
+  localvar1 = threefunc();
+  return localvar1;
+}
+\<close>
+term localvar1
+find_theorems funwithlocalvars_core
+term funwithlocalvars_core
+
+ML\<open>
+val ast = @{C11_CTranslUnit}
+\<close>
+ML\<open>
+val env = @{C\<^sub>e\<^sub>n\<^sub>v}\<close>
+
+function_spec testfunction1(param1 :: int, param2::int) returns int
+pre          "\<open>True\<close>" 
+post         "\<open>\<lambda>res::int. True \<close>"
+local_vars   localvar1 :: int
+defines "p\<^sub>t\<^sub>m\<^sub>p \<leftarrow> call\<^sub>C sum1 \<open>(2::int, 3::int)\<close> ; assign_global global_integer_update (\<lambda>\<sigma>. p\<^sub>t\<^sub>m\<^sub>p);-
+         return\<^bsub>local_testfunction1_state.result_value_update\<^esub> \<open>global_integer\<close>"
+
+find_theorems testfunction1_core
+term\<open>testfunction1_core\<close>
+
+
+
+(*
+Recursions with return values are currently unsupported in CLEAN, but are about to be fixed by someone else
+
+rec_function_spec recursive_function2(n::int) returns int
+pre          "\<open>True\<close>" 
+post         "\<open>\<lambda>res::int. True \<close>"
+local_vars   localvar1 :: int
+defines "p\<^sub>t\<^sub>m\<^sub>p \<leftarrow> call\<^sub>C recursive_function2 \<open>2::int\<close> ; assign_local localvar1_update (\<lambda>\<sigma>. p\<^sub>t\<^sub>m\<^sub>p);-
+return\<^bsub>local_recursive_function2_state.result_value_update\<^esub> \<open>1::int\<close>"
+*)
+
+
+text\<open>Now the pre and post conditions\<close>
+
+
+
+C\<open>
+int xx;
+int fun_with_pre(int u){
+  int local1;
+  /*@ pre\<^sub>C\<^sub>l\<^sub>e\<^sub>a\<^sub>n  \<open>\<^C>\<^sub>e\<^sub>x\<^sub>p\<^sub>r\<open>xx\<close> > 0\<close> */
+  /*@ post\<^sub>C\<^sub>l\<^sub>e\<^sub>a\<^sub>n  \<open>\<lambda>ret::int.3 > \<^C>\<^sub>e\<^sub>x\<^sub>p\<^sub>r\<open>u\<close>\<close> */
+  return local1;
+}
+int fun_with_pre2(int u){
+  /*@ pre\<^sub>C\<^sub>l\<^sub>e\<^sub>a\<^sub>n  \<open>\<^C>\<^sub>e\<^sub>x\<^sub>p\<^sub>r\<open>u\<close>  > 0\<close> */
+
+  return 1;
+}
+\<close>
+
+ML\<open>
+
+val annotation_data = Clean_Annotation.Data_Clean_Annotations.get (Context.Theory @{theory})
+\<close>                                          
+
+
+text\<open>Invariants are more tricky, as there can be several within one function\<close>
+
+text\<open>Lets start with a simple example with two loops, 
+    which computes a*b, given a and b are positive!
+
+    The following program is fully annotated with pre-, and postcondition, aswell as 2 invariants\<close>
+C\<open>int a;\<close>
+C\<open>
+int multiply2(int a, int b){
+  /*@ pre\<^sub>C\<^sub>l\<^sub>e\<^sub>a\<^sub>n  \<open>\<^C>\<^sub>e\<^sub>x\<^sub>p\<^sub>r\<open>a\<close> > 0\<close> */
+  /*@ post\<^sub>C\<^sub>l\<^sub>e\<^sub>a\<^sub>n  \<open>\<lambda>ret::int. ret = \<^C>\<^sub>e\<^sub>x\<^sub>p\<^sub>r\<open>a*b\<close>\<close> */
+  int sum;
+  int counter;
+  int counter_b;
+
+  while(counter < a){
+    /* here we have a loop without an invariant */
+    counter = counter + 1;
+  }
+  counter = 0;
+  sum = 0;
+
+  while(counter < a){
+    /*@ inv\<^sub>C\<^sub>l\<^sub>e\<^sub>a\<^sub>n  \<open>\<^C>\<^sub>e\<^sub>x\<^sub>p\<^sub>r\<open>counter\<close> \<le> \<^C>\<^sub>e\<^sub>x\<^sub>p\<^sub>r\<open>a\<close>\<close> */
+    counter = counter + 1;
+  }
+
+  while(counter > 0){
+    /* inv\<^sub>C\<^sub>l\<^sub>e\<^sub>a\<^sub>n  \<open>\<^C>\<^sub>e\<^sub>x\<^sub>p\<^sub>r\<open>(a-counter)*b\<close> = \<^C>\<^sub>e\<^sub>x\<^sub>p\<^sub>r\<open>sum\<close> \<and> \<^C>\<^sub>e\<^sub>x\<^sub>p\<^sub>r\<open>counter\<close> \<ge> 0\<close> */
+    counter_b = 0;
+    while(counter_b < b){
+      /* inv\<^sub>C\<^sub>l\<^sub>e\<^sub>a\<^sub>n  \<open>C\<open>counter_b\<close> \<le> b\<close>*/      
+      counter_b = counter_b +1;
+    }
+    
+    sum = sum + counter_b;
+    counter = counter -1;
+
+  }
+  return sum;
+}
+\<close>
+
+C\<open>
+int globarr[];\<close>
+C\<open>
+void somefunction123(){
+int localArray[];
+
+}\<close>
+
+find_theorems multiply_core
+
+ML\<open>
+val annotation_data = Clean_Annotation.Data_Clean_Annotations.get (Context.Theory @{theory})
+\<close>   
+
diff --git a/C11-BackEnds/Clean_wrapper/src/.CleanCoder.thy.marks b/C11-BackEnds/Clean_wrapper/src/.CleanCoder.thy.marks
new file mode 100644
index 0000000000000000000000000000000000000000..1f89f043a1af642d6019bcd0e7f2b7778ba91719
--- /dev/null
+++ b/C11-BackEnds/Clean_wrapper/src/.CleanCoder.thy.marks
@@ -0,0 +1 @@
+!c;26152;26152
diff --git a/C11-BackEnds/Clean_wrapper/src/CleanCoder.thy b/C11-BackEnds/Clean_wrapper/src/CleanCoder.thy
index 6cbe4abcec38c4467ad1ee8ddd7023f3b5f128b2..2f6dc44119175cda3e2a63fdb763edcae99ddee1 100644
--- a/C11-BackEnds/Clean_wrapper/src/CleanCoder.thy
+++ b/C11-BackEnds/Clean_wrapper/src/CleanCoder.thy
@@ -67,28 +67,20 @@ exception WrongFormat of string
 exception UnknownTyp of string
 
 
-(*renvoie le type final d'une fonction, ou le type d'une constante*)
-fun lastype_of (Type(_, [x])) = x | lastype_of (Type(_, [_, y])) = y
 (*renvoie le type du premier attribut d'une fonction, ou le type d'une constante*)
-fun firstype_of (Type(_, [x])) = x | firstype_of (Type(_, x::_)) = x 
+fun firstype_of (Type(_, [x])) = x | firstype_of (Type(_, x::_)) = x
+   |firstype_of t = t
+
+fun lastype_of (Type(_, [x])) = x | lastype_of (Type(_, [_ , y])) = y 
 
 (* Creates a result_update_term for the local state *)
-fun mk_result_update thy =
-  let val sigma_i = StateMgt.get_state_type_global thy;
+fun mk_result_update thy sigma_i=
+  let
    val Type(ty_name,_) = sigma_i
    val s = ty_name |> String.tokens (fn x => x =  #".") |> tl |> hd
    val s' = String.substring(s, 0, size s - size "_scheme")^".result_value_update"
   in Syntax.read_term_global thy s' end;
 
-fun extract_ids long_id sigma_i =
-  let  val id = List.last(String.tokens (fn x => x = #".") long_id)
-       val Type(ty_name, _) = sigma_i;
-       val ty_name = ty_name |> String.tokens (fn x => x =  #".") |> tl |> hd
-       val local_state = String.substring (ty_name, 0, 
-                                           String.size ty_name 
-                                           - (String.size "_scheme"))
-                                                     (*dangerous. will work only for the local case *)
-  in  (id, local_state^"."^id) end
 
 fun read_N_coerce thy name ty = 
        (* a very dirty hack ... but reconstructs the true \<open>const_name\<close> 
@@ -96,6 +88,21 @@ fun read_N_coerce thy name ty =
        let val s = drop_dark_matter(Syntax.string_of_typ_global thy ty)
            val str = name ^ " :: " ^ s 
        in  Syntax.read_term_global thy str end
+
+fun read_N_coerce_global thy name =
+       (*this function is necessary, to ensure that a global variable is selected, in case
+         a local variable is defined later (as later vars would get selected by default)*)
+       let 
+           val consts = Sign.consts_of thy
+           fun filter_by_shortname (n, _) =
+             (case Long_Name.explode n of
+                [_, middle, base] => base = name andalso (String.substring (middle,0,6) = "global")
+              | _ => false) 
+           val longnames =  List.filter filter_by_shortname (#constants (Consts.dest consts))
+           val longname = (fst o hd) longnames
+       in  read_N_coerce thy longname end
+
+fun get_update_fun thy name = read_N_coerce thy (name^"_update")
 \<close>
 
 subsection\<open>C11 Expressions to Clean Terms\<close>
@@ -125,11 +132,22 @@ fun node_content_parser (x : C11_Ast_Lib.node_content) =
       val id = hd(tl(String.tokens (fn x => x = #"\"")(drop_dark_matter a_markup)))
     in id end  (* no type inference *);
 
-fun convertExpr verbose (sigma_i: typ) env thy 
+fun is_call a = case a of 
+              Const (@{const_name "Clean.call\<^sub>C"},_) $_ $_ => true
+              |_ => false
+
+fun convertExpr verbose (sigma_i: typ) env thy function_name _
            (a as { tag, sub_tag, args }:C11_Ast_Lib.node_content) 
            (b:  C_Ast.nodeInfo )   
            (c : term list) =
     ((if verbose then print_node_info a b c else ());
+    let fun get_most_general_type t1 t2 = 
+                              if t1 = natT andalso t2=natT then natT else 
+                              if (t1 = natT orelse t1 = intT) andalso (t2=natT orelse t2=intT) then intT else
+                              if t1 <> natT andalso t1<>intT then t1 else t2 (*this should be the fallback for rational numbers*)
+                         fun get_ring_op_type t1 t2 =
+                            if get_most_general_type t1 t2 = natT then intT else get_most_general_type t1 t2
+    in 
     case tag of
 (*variables*)
 (*here, we get the full name of the variable, then we return the term well named and typed.
@@ -141,31 +159,26 @@ Bound 0 is usefull for the statements, and can easily be deleted if necessary*)
                                                 SOME(identifier) => identifier
                                               | NONE => error("(convertExpr) identifier " 
                                                               ^ id ^ " not recognised")
-                        val Type(local_state_scheme, _) = sigma_i;
-                        val local_state = String.substring (local_state_scheme, 0, 
-                                                                String.size local_state_scheme 
-                                                                 - (String.size "_scheme"))
                                               (*dangerous. will work only for the local case *)
-                        val lid = local_state^"."^id
                     in case cat of
-                        C_AbsEnv.Global => read_N_coerce thy id (sigma_i --> ty) $ Free("\<sigma>",sigma_i) :: c
+                        C_AbsEnv.Global => read_N_coerce_global thy id (sigma_i --> ty) $ Free("\<sigma>",sigma_i)::c
                       | C_AbsEnv.Local(_) => Const(@{const_name "comp"}, 
                                                    (HOLogic.listT ty --> ty) 
                                                    --> (sigma_i --> HOLogic.listT ty) 
                                                    --> sigma_i --> ty) 
                                               $ Const(@{const_name "hd"}, HOLogic.listT ty --> ty) 
-                                              $ read_N_coerce thy lid (sigma_i --> HOLogic.listT ty) 
+                                              $ read_N_coerce thy id (sigma_i --> HOLogic.listT ty) 
                                               $ Free("\<sigma>",sigma_i) :: c
                       | C_AbsEnv.Parameter(_) => Free (id, ty) :: c
                       | C_AbsEnv.FunctionCategory(C_AbsEnv.MutuallyRecursive(_), _) =>
                                 error("Mutual recursion is not supported in Clean")
-                      | C_AbsEnv.FunctionCategory(C_AbsEnv.Final, _) => 
-                            let val Const(id, ty) = Syntax.read_term_global thy id
-                                val args = firstype_of ty
-                                val mty = StateMgt_core.MON_SE_T @{typ "unit"} sigma_i
-                            in Const(id, args --> mty) :: c end
-                              
-                      | c => error("(convertExpr) unrecognised category : " ^ @{make_string} c)
+                      | C_AbsEnv.FunctionCategory(_, _) =>
+                            let fun get_call_const id = Syntax.read_term_global thy id
+                                (* There is no term corresponding to the function. Hence skip the 
+                                   initialization of the type and infer it from the call args (see CCall0)*)
+                                fun get_rec_call_ident id= Free(id, 
+                                            (TVar (("'a", 0), [])) --> sigma_i --> (Type (@{type_name "option"}, [mk_tupleT [ty, sigma_i]])))
+                            in (if function_name = id then get_rec_call_ident id else get_call_const id) :: c end
                     end)
      |"Vars0" => c
      |"CVar0" => c
@@ -174,10 +187,10 @@ Bound 0 is usefull for the statements, and can easily be deleted if necessary*)
      (*binary operations*)
      |"CBinary0" => (case (drop_dark_matter sub_tag, c) of
                       (*arithmetic operations*) 
-                      ("CAddOp0",b::a::R) => (Const(@{const_name "plus"}, fastype_of a --> fastype_of b --> intT) $ a $ b :: R)
-                    | ("CMulOp0",b::a::R) => (Const(@{const_name "times"}, fastype_of a --> fastype_of b --> intT) $ a $ b :: R)
-                    | ("CDivOp0",b::a::R) => (Const(@{const_name "divide"}, fastype_of a --> fastype_of b --> intT) $ a $ b :: R)
-                    | ("CSubOp0",b::a::R) => (Const(@{const_name "minus"}, fastype_of a --> fastype_of b --> intT) $ a $ b :: R)
+                      ("CAddOp0",b::a::R) => let val ty = get_most_general_type (fastype_of a) (fastype_of b) in (Const(@{const_name "plus"}, ty --> ty --> ty) $ a $ b :: R) end
+                    | ("CMulOp0",b::a::R) => let val ty = get_most_general_type (fastype_of a) (fastype_of b) in (Const(@{const_name "times"}, ty --> ty --> ty) $ a $ b :: R) end
+                    | ("CDivOp0",b::a::R) => let val ty = get_ring_op_type (fastype_of a) (fastype_of b) in (Const(@{const_name "divide"}, ty --> ty --> ty) $ a $ b :: R) end
+                    | ("CSubOp0",b::a::R) => let val ty = get_ring_op_type (fastype_of a) (fastype_of b) in (Const(@{const_name "minus"}, ty --> ty --> ty) $ a $ b :: R) end
                       (*boolean operations*) 
 (*for boolean operations, because in C boolean are in fact integers, we need to
 translate integers in booleans. That's what term_to_bool t do.
@@ -193,18 +206,22 @@ translate integers in booleans. That's what term_to_bool t do.
                     | ("CEqOp0", b::a::R) => (mk_eq ( a, b) :: R)
                     | ("CNeqOp0", b::a::R) => (mk_not (mk_eq ( a, b))::R)
                       (*comp*)
-                    | ("CLeOp0", b::a::R) => (Const(@{const_name "less"}, 
-                                                    fastype_of a --> fastype_of b --> boolT) 
-                                             $ a $ b :: R) 
-                    | ("CGrOp0", b::a::R) => (Const(@{const_name "less"}, 
-                                                    fastype_of a --> fastype_of b --> boolT) 
-                                             $ b $ a :: R) 
-                    | ("CLeqOp0", b::a::R) => (Const(@{const_name "less_eq"}, 
-                                                     fastype_of a --> fastype_of b --> boolT) 
-                                              $ a $ b :: R) 
-                    | ("CGeqOp0", b::a::R) => (Const(@{const_name "less_eq"}, 
-                                                     fastype_of a --> fastype_of b --> boolT) 
-                                              $ b $ a :: R)
+                    | ("CLeOp0", b::a::R) => let val ty =get_most_general_type (fastype_of a) (fastype_of b)
+                                             in (Const(@{const_name "less"}, 
+                                                    ty --> ty --> boolT) 
+                                             $ a $ b :: R) end 
+                    | ("CGrOp0", b::a::R) => let val ty =get_most_general_type (fastype_of a) (fastype_of b)
+                                             in (Const(@{const_name "less"}, 
+                                                    ty --> ty --> boolT) 
+                                             $ b $ a :: R) end
+                    | ("CLeqOp0", b::a::R) => let val ty =get_most_general_type (fastype_of a) (fastype_of b)
+                                              in (Const(@{const_name "less_eq"}, 
+                                                     ty --> ty --> boolT) 
+                                              $ a $ b :: R) end
+                    | ("CGeqOp0", b::a::R) => let val ty =get_most_general_type (fastype_of a) (fastype_of b)
+                                              in (Const(@{const_name "less_eq"}, 
+                                                     ty -->  ty --> boolT) 
+                                              $ b $ a :: R)end
                     | _ => (writeln ("sub_tag all " ^sub_tag^" :>> "^ @{make_string} c);c ))
      (*unary operations*)
      |"CUnary0" =>  (case (drop_dark_matter sub_tag, c) of
@@ -215,7 +232,7 @@ translate integers in booleans. That's what term_to_bool t do.
 (*for the constants, we can use the makers*)
      |"CConst0"   => c (* skip this wrapper *)
      |"CInteger0" =>let val C11_Ast_Lib.data_int n = hd args
-                    in  (mk_number intT n)::c end
+                    in  (mk_number (if n>=0 then natT else intT) n)::c end
      |"CIntConst0"=> c (* skip this wrapper *)
      |"CString0"  => let val C11_Ast_Lib.data_string s = hd args
                      in  (mk_string s)::c end
@@ -240,7 +257,8 @@ translate integers in booleans. That's what term_to_bool t do.
                          ::c
                    end
      |"CIndex0" => (case c of 
-                     (idx::root::R) => let fun destListT (Type(@{type_name list},[t])) = t
+                     (idx::root::R) => let fun destListT arg =
+                                            case arg of (Type(@{type_name list},[t])) => t
                                            val idx_term = case fastype_of idx of
                                                             Type(@{type_name "nat"},[]) => idx
                                                           | Type(@{type_name "int"},[]) =>
@@ -258,28 +276,41 @@ translate integers in booleans. That's what term_to_bool t do.
      |"CFloatConst0"=> (c) (* skip this wrapper *)
      |"CChars0" => (warning "bizarre rule in context float: CChars0"; c)
      |"CExpr0"  => c (* skip this wrapper *)
-     |"CTypeSpec0" => c (* skip this wrapper *)
-     |"CDeclr0" => c (* skip this wrapper *)
-     |"CInitExpr0" => c (* skip this wrapper *)
-     |"CDecl0" =>  error("Local declarations inside a C context are not supported in Clean")
+      (*this is a very dirty trick: when declaring variables "int a,b=3,c,d=4;", the accesses to a and c lie
+        on the stack, polluting it. All non-assignments are thus removed, up until this item is met on the stack*)
+     |"CTypeSpec0" => ((Free ("--startofdeclarations--",@{typ unit}))::c)
+     |"CDeclr0" => c
+     |"CDecl0" =>  let  fun is_assignment ((Const (@{const_name "assign_local"},_))$_$_) = true
+                           |is_assignment ((Const (@{const_name "assign_global"},_))$_$_) = true
+                           |is_assignment  _ = false
+                        fun remove_dead_idents [] = []
+                           |remove_dead_idents (Free("--startofdeclarations--",_)::R) = R
+                           |remove_dead_idents (head::R) = if is_assignment head then (head::remove_dead_idents R) 
+                                      else remove_dead_idents R
+                   in
+                      remove_dead_idents c
+                   end
      |"CCall0" => c (* skip this wrapper *)
-     | str => error("unsupported expression with parse tag: "^str)) (* global catch all *)
+     |"CNoArrSize0" => c
+     |"CArrDeclr0" => c
+     | str => error("unsupported expression with parse tag: "^str^"and subtag: "^sub_tag)
+end) (* global catch all *)
 
 
 fun lifted_term sigma_i term = Abs("\<sigma>", sigma_i, abstract_over (Free("\<sigma>", sigma_i), term))
 
-fun conv_Cexpr_lifted_term  sigma_i A_env thy C_expr = 
+fun conv_Cexpr_lifted_term  sigma_i A_env thy function_name get_loop_annotations C_expr = 
     let val e::R = (C11_Ast_Lib.fold_cExpression (K I)
-                               (convertExpr false sigma_i A_env thy) C_expr [])
+                               (convertExpr false sigma_i A_env thy function_name get_loop_annotations) C_expr [])
     in  lifted_term sigma_i e end
 
 (*** -------------- ***)
 
-fun conv_cDerivedDeclarator_cSizeExpr_term (C_Ast.CArrDeclr0 (_,C_Ast.CArrSize0 (_,C_expr),_)) C_env thy = 
+fun conv_cDerivedDeclarator_cSizeExpr_term (C_Ast.CArrDeclr0 (_,C_Ast.CArrSize0 (_,C_expr),_)) C_env thy function_name get_loop_annotations= 
             SOME(hd((C11_Ast_Lib.fold_cExpression (K I)
-                                 (convertExpr false dummyT C_env thy) C_expr [])))
-   |conv_cDerivedDeclarator_cSizeExpr_term (C_Ast.CArrDeclr0 (_,C_Ast.CNoArrSize0 Z,_)) _ _ = NONE
-   |conv_cDerivedDeclarator_cSizeExpr_term (_)  _ _ =  
+                                 (convertExpr false dummyT C_env thy function_name get_loop_annotations) C_expr [])))
+   |conv_cDerivedDeclarator_cSizeExpr_term (C_Ast.CArrDeclr0 (_,C_Ast.CNoArrSize0 Z,_)) _ _ _ _= NONE
+   |conv_cDerivedDeclarator_cSizeExpr_term (_)  _ _ _ _=  
             error("DeclarationSpec format not defined. [Clean restriction]")
 
 
@@ -320,53 +351,96 @@ si on a k = 0 : renvoie la term skip
 fun block_to_term (Const("_END",_)::Const("_BEGIN",_)::R) 
               = mk_skip_C dummyT ::R
    |block_to_term R = 
-         let val _ = (writeln("block_to_term::"^ @{make_string } R))
-             val (topS, restS) = chop_prefix (fn Const("_BEGIN",_) => false | _ => true) R
+         let val (topS, restS) = chop_prefix (fn Const("_BEGIN",_) => false | _ => true) R
              val (Const("_END",_)::topS, Const("_BEGIN",_)::restS) = (topS, restS)
          in (foldl1 (uncurry mk_seq_C) (rev topS)) :: restS end
 
 
-fun convertStmt verbose sigma_i nEenv thy 
+fun convertStmt verbose sigma_i nEenv thy function_name get_loop_annotations
            (a as { tag, sub_tag, args }:C11_Ast_Lib.node_content) 
            (b:  C_Ast.nodeInfo ) 
            (stack : term list) =
-    ((if verbose then (writeln("tag:"^tag);print_node_info a b stack) else ());
-    case tag of
-
-     "CAssign0" => (case stack of
+    
+    let fun handle_assign stack = (case stack of
                       (rhs :: lhs ::  R) => 
-                          (let val long_id = (case lhs of
+                          ((let
+                               fun getLongId lhs  = (case lhs of
                                             Const(name, _) $ _ => name
                                           | _ $ _ $ Const(name, _) $ _ => name
                                           | Free (name, _) => name
+                                          | Const ("List.nth", _) $ lhs_candidat $ _ => (getLongId lhs_candidat)
                                           | _ => error("(convertStmt) CAssign0 does not recognise term: "
-                                                        ^(@{make_string} lhs)))
-                               val (id, lid) = extract_ids long_id sigma_i
-                               fun is_id (C_AbsEnv.Identifier(id_name, _, _, _)) = id_name = id
-                               val C_AbsEnv.Identifier(id, _, ty, cat) = 
+                                                        ^(@{make_string} lhs)^"With stacK"^(@{make_string} stack)))
+                               val ident_id = getLongId lhs
+
+                               val C_AbsEnv.Identifier(_, _, ty, cat) = let
+                                    fun is_id (C_AbsEnv.Identifier(id_name, _, _, _)) = id_name = Long_Name.base_name ident_id in
                                          case List.find is_id nEenv of SOME x  => x
-                                             | _ => error("id not found: "^ long_id)
-                               val (id, lid) = (id ^ "_update", lid ^ "_update")
-
-                           in case cat of
-                                C_AbsEnv.Global => (mk_assign_global_C 
-                                                       (read_N_coerce thy id 
-                                                           ((ty --> ty) --> sigma_i --> sigma_i))
-                                                       (lifted_term sigma_i rhs))::R
-                              | C_AbsEnv.Parameter(_) => error "assignment to parameter not allowed in Clean"
-                              | C_AbsEnv.Local(_) => (mk_assign_local_C 
-                                                       (read_N_coerce thy lid 
-                                                           ((listT ty --> listT ty) --> sigma_i --> sigma_i))
-                                                       (lifted_term sigma_i rhs) )::R
-                              | s => error("(convertStmt) CAssign0 with cat " 
-                                            ^ @{make_string} s ^ " is unrecognised")
-                           end)
+                                             | _ => error("id not found: "^ ident_id) end
+                               val (update_func_ty, mk_assign) = case cat of C_AbsEnv.Global => (((ty --> ty) --> sigma_i --> sigma_i), mk_assign_global_C)
+                                                               |C_AbsEnv.Local _ => (((listT ty --> listT ty) --> sigma_i --> sigma_i), mk_assign_local_C)
+                                                               | _ => error ("Assignment to "^ident_id^" not possible (is it a parameter?)")
+                               val update_func = get_update_fun thy ident_id update_func_ty
+                               fun get_base_type lhs ty = 
+                                  case lhs of Const ("List.nth", _) $ lhs_part1 $ _ => 
+                                                                       get_base_type lhs_part1 (dest_listTy ty)
+                                                     | _ => ((if (is_listTy ty) then warning "Assigning list of elements to variable. This is not possible in C, however supported by Clean" else ());ty)
+                               val tempvarn = "tmpvar"
+                               val tempvart = (get_base_type lhs ty)
+                               val is_fun_assignment = (case rhs of  Const (@{const_name "Clean.call\<^sub>C"},_) $_ $_ => true
+                                                                         | _ => false)
+                               (*Here comes the array part. Since only entire "rows" of arrays can be replaced,
+                                 for the expression A[1][2] = b, the right hand side of the CLEAN-statement has
+                                 to include parts of the LHS, which makes this transformation rather ugly, especially
+                                 in combination with function calls.
+                                 Based on the LHS, the function get_array_assignment provides, for the above example,
+                                 a function: 
+                                 \<lambda>rhs. A[1:= (A!1 [2:= rhs])
+                                  *)
+                               fun mk_list_update_t ty = Const(@{const_name "List.list_update"}, (* This is from "isa_termstypes.ML" *)
+                                                    listT ty --> natT --> ty --> listT ty)
+                               fun transform_rhs_list_assignment lhs_part ty value= 
+                                  case lhs_part of  Const ("List.nth", _) $ lhs_part1 $ idx_term => (
+                                      let 
+                                        val lst_update_t =  mk_list_update_t ty
+                                        val updated = lst_update_t $ lhs_part1 $ idx_term $ value
+                                      in
+                                        transform_rhs_list_assignment lhs_part1 (listT ty) updated 
+                                      end
+                                    )
+                                  | _ => value                                              
+
+                               val get_array_assignment = transform_rhs_list_assignment lhs (get_base_type lhs ty) 
+
+
+                               val assignment =if is_fun_assignment then ( mk_seq_assign_C 
+                                                            rhs 
+                                                            (((mk_assign update_func) 
+                                                              (lifted_term sigma_i (get_array_assignment (Free (tempvarn,tempvart)))))) 
+                                                            tempvarn 
+                                                            tempvart) 
+                                                     else (   
+                                                        ((mk_assign 
+                                                            update_func)
+                                                       (lifted_term sigma_i (get_array_assignment rhs))))
+                                val inferred_assignment = Syntax.check_term (Proof_Context.init_global thy) assignment
+                                in assignment::R
+                           end))
                       |_ => raise WrongFormat("assign"))
+
+     in ((if verbose then (writeln("tag:"^tag);print_node_info a b stack) else ());
+    if tag="CBinary0" andalso
+       case stack of (head::_) => is_call head |_=>false 
+          then error ("Function call only allowed on RHS of assignment. Tag: "^tag)  else ();
+    case tag of
+     "CAssign0" => handle_assign stack
+    |"CInitExpr0" => handle_assign stack
      (*statements*)
 (*for return, skip and break, we have makers except that they need types and terms that i didn't 
 understand so it's unfinished here*)
-     |"CReturn0" => let val rhs = hd stack
-                        val res_upd = mk_result_update thy 
+     |"CReturn0" => let
+                        val rhs = hd stack
+                        val res_upd = mk_result_update thy sigma_i
                     in (mk_return_C res_upd (lifted_term sigma_i rhs)) :: (tl stack) end
      |"CSkip0"  => (mk_skip_C sigma_i)::stack
      |"CBreak0" => (mk_break sigma_i)::stack
@@ -381,52 +455,92 @@ if ... then ... else skip*)
      | "CBlockStmt0" => stack
      | "CBlockDecl0" => stack
      | "CNestedFunDef0" =>  error"Nested Function Declarations not allowed in Clean"
-     | "CIf0" =>   (case stack of  
-                       (a::b::cond::R) => mk_if_C (lifted_term sigma_i cond) b a :: R
+     | "CIf0" =>   (case stack of (*checking based on how many elements are on the stack is wrong.
+                                    instead check the type of the condition. It must be a value (i.e. no function)*)
+                    (a::b::c::R) => (case fastype_of b of Type ("fun",_)=> mk_if_C (lifted_term sigma_i c) b a :: R (*b is not the condition*)
+                                                          | _ => (mk_if_C (lifted_term sigma_i b) (*b is the cond no else*)
+                                                                 (a)
+                                                                 (mk_skip_C sigma_i)::R))
                     |  (a::cond::R) => (mk_if_C (lifted_term sigma_i cond) 
                                                 (a)
                                                 (mk_skip_C sigma_i)::R)
                     |  _    => raise WrongFormat("if")
                    )
-     |"CWhile0" => (case stack of
-                       (a::b::R) => (mk_while_C  (lifted_term sigma_i b)  a) :: R
-                      |(a::R)    => (mk_while_C  (lifted_term sigma_i a)  
+     |"CWhile0" => let val pos = (case b of C_Ast.OnlyPos0 (pos,_) => pos
+                              |C_Ast.NodeInfo0 (pos,_,_) => pos)
+                       val (get_inv, get_measure) = get_loop_annotations pos
+                       val invariant_lifted =get_inv 
+                                  |> Option.map 
+                                      (fn get_inv=>(Syntax.check_term (Proof_Context.init_global thy) ((lifted_term sigma_i) (get_inv (Context.Theory thy)))))
+                       val measure_lifted =get_measure 
+                                  |> Option.map 
+                                      (fn get_measure => Syntax.check_term (Proof_Context.init_global thy) ((lifted_term sigma_i) ( get_measure (Context.Theory thy))))
+                       val mk_while_func = case (invariant_lifted,measure_lifted) 
+                            of (NONE,NONE) => mk_while_C
+                              |(SOME inv, SOME measure)=>mk_while_anno_C inv  measure (*Note the coercion to nat!*)
+                              |(SOME inv, NONE)=>mk_while_anno_C inv (lifted_term sigma_i @{term "1::nat"})
+                              |(NONE, SOME measure)=>mk_while_anno_C (lifted_term sigma_i @{term "True::bool"})  measure
+                                                                 
+                      in (case stack of
+                       (a::b::R) => (mk_while_func  (lifted_term sigma_i b)  a) :: R
+                      |(a::R)    => (mk_while_func  (lifted_term sigma_i a)  
                                                  (mk_skip_C dummyT)) :: R  (* really dummyT *)
                       |_ => raise WrongFormat("while")
-                   )
+                   ) end
 (*There is no For operator in Clean, so we have to translate it as a while :
 for(ini, cond, evol){body} is translated as ini; while(cond){body; evol;}*)
-     |"CFor0" =>   (case stack of
-                        (body::pace::cond::init::R) => (let val C' = mk_while_C
+     |"CFor0" =>   let val pos = (case b of C_Ast.OnlyPos0 (pos,_) => pos
+                              |C_Ast.NodeInfo0 (pos,_,_) => pos)
+                       (*duplicate code from while*)
+                       val (get_inv, get_measure) = get_loop_annotations pos
+                       val invariant_lifted =get_inv |> Option.map (fn get_inv=> (lifted_term sigma_i) (get_inv (Context.Theory thy)))
+                       val measure_lifted =get_measure |> Option.map (fn get_measure => (lifted_term sigma_i) ( get_measure (Context.Theory thy)))
+                       val mk_while_func = case (invariant_lifted,measure_lifted) 
+                            of (NONE,NONE) => mk_while_C
+                              |(SOME inv, SOME measure)=>mk_while_anno_C inv measure
+                              |(SOME inv, NONE)=>mk_while_anno_C inv (lifted_term sigma_i @{term "1::nat"})
+                              |(NONE, SOME measure)=>mk_while_anno_C (lifted_term sigma_i @{term "True::bool"}) measure
+                      in (case stack of
+                        (body::pace::cond::init::R) => (let val C' = mk_while_func
                                                                        (lifted_term sigma_i cond)
                                                                        (mk_seq_C body pace)
                                                         in   ((mk_seq_C init C'))::R end)
-                    |_ => raise WrongFormat("for"))
+                        |_ => raise WrongFormat("for")) end
      | "CCall0" => (let fun extract_fun_args (t :: R) args =
-                            case t of
+                            (case t of
                             (* very bad way of checking if term represents a function *)
                                Const(id, ty) => if not (firstype_of ty = sigma_i) 
                                                 then (args, Const(id, ty), R) 
                                                 else extract_fun_args R (Const(id, ty) :: args)
-                            | arg => extract_fun_args R (arg :: args)
-                        fun extract_type_list (arg :: args) =
-                            (case arg of
-                              (* should be expanded for the 3 term representations of variables... *)
-                              Free(_, ty) => ty :: extract_type_list args)
-                          | extract_type_list [] = []
-                        (* should be expanded for variable number of args... *)
-                        fun mk_cross_prod_args [a, b] = Const (@{const_name "Pair"}, 
-                                                               a --> b --> mk_prodT (a, b))
+                             |  Free(id, ty) => if id = function_name (*recursive call*)
+                                                then (args, Free(id, ty), R) 
+                                                else extract_fun_args R (Free(id, ty) :: args)
+                             | arg => extract_fun_args R (arg :: args))
+                            |extract_fun_args [] _ = error ("\"CCall0\": couldnt find function in stack: "^(@{make_string} stack))
                         val (args, f, R) = extract_fun_args stack []
-                        val cross_prod_args = mk_cross_prod_args (extract_type_list args)
-                        val fun_args_term = list_comb (cross_prod_args, args)
-                       in mk_call_C f (lifted_term sigma_i fun_args_term) :: R end)
-     | _ => convertExpr verbose sigma_i nEenv thy  a b stack )
+                        val ret_ty = case fastype_of f of Type (_, [_, (*args \<rightarrow>*)
+                                                          Type (_, [_, (*sigma \<rightarrow>*)
+                                                          Type (_, [ (*'a option*)
+                                                          Type(_, [ret_ty, _])])])]) => ret_ty (* (ret_type, sigma)*)
+                                                          | _ => error ("function type has wrong format: "^(@{make_string} (fastype_of f)))
+
+                        val new_args_ty = mk_tupleT (List.map fastype_of args)
+                        val new_ty = new_args_ty --> sigma_i --> (Type (@{type_name "option"},[Type (@{type_name "prod"}, [ret_ty,sigma_i])]))
+
+                        fun swap_ty (Const (name, _)) n_ty = Const (name, n_ty)
+                           |swap_ty (Free (name, _)) n_ty = Free (name, n_ty)
+                           |swap_ty _ _ = error "unexpected term at swap_ty"
+
+                        val f_new = swap_ty f new_ty
+                        val fun_args_term = mk_tuple args
+                       in mk_call_C f_new (lifted_term sigma_i fun_args_term) :: R end)
+     | _ => convertExpr verbose sigma_i nEenv thy function_name get_loop_annotations a b stack )
 
 end
 
 (*** -------------- ***)
 
+end
 end
 \<close>
 
@@ -465,6 +579,16 @@ fun convertCUnit verbose sigma_i env thy
      | s =>  (c)
 )
 
+fun get_loop_positions (a as { tag, sub_tag, args }:C11_Ast_Lib.node_content) 
+           (b:  C_Ast.nodeInfo )   
+           (c : C_Ast.positiona list) =
+      case tag of
+        "CWhile0" => (case b of C_Ast.OnlyPos0 (pos,_) => pos::c
+                              |C_Ast.NodeInfo0 (pos,_,_) => pos::c)
+        |"CFor0" => (case b of C_Ast.OnlyPos0 (pos,_) => pos::c
+                              |C_Ast.NodeInfo0 (pos,_,_) => pos::c)
+        | _ => c
+
 end
 end
 
diff --git a/C11-BackEnds/Clean_wrapper/src/CleanCoderTypAEnv.thy b/C11-BackEnds/Clean_wrapper/src/CleanCoderTypAEnv.thy
index a37a071e82b1793f616c70e44507ab73facc6b22..0773f0e28df698a70a4c6b41bdcbaf2cd33f4ace 100644
--- a/C11-BackEnds/Clean_wrapper/src/CleanCoderTypAEnv.thy
+++ b/C11-BackEnds/Clean_wrapper/src/CleanCoderTypAEnv.thy
@@ -139,7 +139,7 @@ fun conv_ParseStatus_CDeclSpecS (SOME(C_Env.Parsed S)) = SOME S
    |conv_ParseStatus_CDeclSpecS _ = NONE
 
 
-fun conv_cDeclarationSpecifier_typ (SOME([CTypeSpec0 (CUnsigType0 _)])) = SOME(HOLogic.intT)
+fun conv_cDeclarationSpecifier_typ (SOME([CTypeSpec0 (CUnsigType0 _)])) = SOME(HOLogic.natT)
    |conv_cDeclarationSpecifier_typ (SOME([CTypeSpec0 (CIntType0 _)]))   = SOME(HOLogic.intT)
    |conv_cDeclarationSpecifier_typ (SOME([CTypeSpec0 (CLongType0 _),
                                           CTypeSpec0 (CIntType0 _)]))   = SOME(HOLogic.intT)
@@ -244,6 +244,7 @@ signature C_ABS_ENVIRONMENT =
   datatype identifier = Identifier of string * Position.T * typ * identType
 
   val parseTranslUnitIdentifiers: C_Ast.nodeInfo C_Ast.cTranslationUnit 
+                                  -> identifier list 
                                   -> identifier list 
                                   -> string list Symtab.table 
                                   -> identifier list * string list Symtab.table
@@ -335,6 +336,11 @@ fun getMutuallyRecursiveCalls (Identifier(name, pos, ty, idType) :: s) functionN
   else getMutuallyRecursiveCalls s functionName
   | getMutuallyRecursiveCalls [] _ = []
 
+fun isCall0
+    ((nc, _) :: R) =
+    if #tag nc = "CCall0" then true
+    else isCall0 R
+  | isCall0 [] = false
 fun readCall0
     ((nc, _) :: R) =
     if #tag nc = "CCall0" then R
@@ -349,6 +355,7 @@ fun parseNodeContent
     (HOLType: Basic_Term.typ option)
     ((nc, ni) :: R)
     identList
+    oldIdents
     functionCallList
     (idType: identType) =
     let val Left(posL, posR) = C_Grammar_Rule_Lib.decode ni
@@ -356,47 +363,53 @@ fun parseNodeContent
        case #tag nc of
          "CTypeSpec0" (* this is the start variable declaration list (one or multiple) *)
          => let val HOLType = #sub_tag nc |> str2HOLogic
-            in parseNodeContent (SOME HOLType) (cutDownTypeSpec (R)) identList functionCallList idType
+            in parseNodeContent (SOME HOLType) (cutDownTypeSpec (R)) identList oldIdents functionCallList idType
             end
        | "Ident0"
          => let val name = node_content_parser nc
+                fun transform_list_type ((r,_)::R) ty = if #tag r = "CArrDeclr0" then HOLogic.listT (transform_list_type R ty) else ty
+                   | transform_list_type [] ty = ty 
+                fun skip_arr_decls ((r,b)::R) = if #tag r = "CArrDeclr0" then skip_arr_decls R else ((r,b)::R)
+                   | skip_arr_decls [] = []
             in (debug("(parseNodeContent) parsing: " ^ name);
                if (* if the identifier already exists, this is either a reference to a variable 
                      (which we ignore) or a declared function call *)
-                  identifierExists identList name 
-               then if functionIdentifierExists identList name 
-                    then parseNodeContent NONE R identList (name :: functionCallList) idType
-                    else parseNodeContent NONE R identList functionCallList idType
-               else (* otherwise, it is a variable declaration or an undeclared function call *) 
+                  (identifierExists (identList@oldIdents) name)
+               then (if functionIdentifierExists (identList@oldIdents) name (*potential error when function is redefined as variable*) 
+                    then parseNodeContent NONE R identList oldIdents (name :: functionCallList) idType
+                    else parseNodeContent NONE R identList oldIdents functionCallList idType)
+               else (* otherwise, it is a variable declaration or an undeclared function call or a reference to a variable defined elsewhere*) 
                     let val (nc2, ni2) :: R = R
                     in case #tag nc2 of
                      "CDeclr0" (* this is the end of one variable declaration *)
                       => (debug("(parseNodeContent) this is a DECLARATION: "^name);
                           parseNodeContent HOLType R (Identifier(node_content_parser nc, posL, 
-                             (fn (SOME(a)) => a) HOLType, idType) :: identList) functionCallList idType)
-                   | "CArrDeclr0" (* this is an array variable declaration, thus we INFER that
+                             (fn (SOME(a)) => a) HOLType, idType) :: identList) oldIdents functionCallList idType)
+                   | "CArrDeclr0" (* this is an array variable declaration, thus we count how many ArrDecls are here
                                       #tag (hd R) is "CDeclr0" so we skip it *)
-                     => parseNodeContent HOLType (tl R) (Identifier(node_content_parser nc, posL, 
-                             HOLogic.listT ((fn (SOME(a)) => a) HOLType), idType) :: identList) 
+                     => 
+                          parseNodeContent HOLType (skip_arr_decls R) (Identifier(node_content_parser nc, posL, 
+                             transform_list_type R (HOLogic.listT (the HOLType)), idType) :: identList) oldIdents 
                              functionCallList idType
                    | "CTypeSpec0"
                      => parseNodeContent HOLType (R) (Identifier(node_content_parser nc, posL,
-                             (fn (SOME(a)) => a) HOLType, idType) :: identList) functionCallList idType
-                   | s (* this is a function call, #tag nc2 is either another Ident0 which is a 
+                             (fn (SOME(a)) => a) HOLType, idType) :: identList) oldIdents functionCallList idType
+                   | s  =>(* this is a function call, #tag nc2 is either another Ident0 which is a 
                           parameter which we ignore or CCall0 in which the function calls ends *)
-                     => (debug("function call detected (tag = " ^ s ^ ") : " ^ @{make_string} (R));
-                         parseNodeContent HOLType (readCall0 ((nc2, ni2) :: R)) identList 
-                             (node_content_parser nc :: functionCallList) idType)
+                     if (isCall0 ((nc2, ni2) :: R)) then (debug("function call detected (tag = " ^ s ^ ") : " ^ @{make_string} (R));
+                         parseNodeContent HOLType (readCall0 ((nc2, ni2) :: R)) identList oldIdents
+                             (node_content_parser nc :: functionCallList) idType) else
+                          parseNodeContent HOLType R identList oldIdents functionCallList idType
                    end)
              end
         | "CDeclr0" (* artifact: list of params have a CDeclr0 at the end, so we ignore this *)
-          => parseNodeContent HOLType R identList functionCallList idType
+          => parseNodeContent HOLType R identList oldIdents functionCallList idType
         | "CCall0" (* artifact: list of params have a CDeclr0 at the end, so we ignore this *)
-          => parseNodeContent HOLType R identList functionCallList idType
+          => parseNodeContent HOLType R identList oldIdents functionCallList idType
         | _
           => error("node content parsing failure: " ^ @{make_string} ((nc, ni) :: R)))
     end
-  | parseNodeContent _ [] identList functionCallList _ = 
+  | parseNodeContent _ [] identList oldIdents functionCallList _ = 
     (debug("(parseNodeContent) finished: identList--" ^ @{make_string} identList 
                              ^ " functionCallList--" ^ @{make_string} functionCallList);
     (identList, functionCallList))
@@ -473,7 +486,7 @@ fun parseFunctionCalls
               (functionCategory, identList, functionCallTable) 
 
 fun parseParams L (functionName: string) =
-    let val (identList, _) = parseNodeContent NONE L [] [] (Parameter(functionName))
+    let val (identList, _) = parseNodeContent NONE L [] [] [] (Parameter(functionName))
     in identList end
  
 (* Parses identifiers in a function body.
@@ -488,9 +501,11 @@ fun parseLocals
     (* Table of previous function names with list of function calls *)
     (functionCallTable: string list Symtab.table)
     (* Previous identifiers *)
-    (identList: identifier list) =
+    (identList: identifier list)
+    (* Identifiers from a previous translation unit (synthesized from env)*)
+    (oldIdents: identifier list) =
     (debug("parsing locals: " ^ @{make_string} L);
-    let val (identList, functionCalls) = parseNodeContent NONE L identList [] (Local(functionName))
+    let val (identList, functionCalls) = parseNodeContent NONE L identList oldIdents [] (Local(functionName))
         val (functionCategory, identList, functionCallTable) = 
                      parseFunctionCalls functionName identList functionCallTable functionCalls Final
     in (identList, functionCategory, functionCallTable) end)
@@ -501,6 +516,7 @@ fun parseLocals
 fun parseExternalDeclaration 
     (CDeclExt0(declaration : nodeInfo cDeclaration))
     identList 
+    oldIdents
     functionCallTable =
   (* Select Ident0 constructors in a cDeclaration. Here we suppose that there is only 1 *)
   let val CDecl0(declarationSpecifierList, _, _) = declaration
@@ -511,7 +527,7 @@ fun parseExternalDeclaration
       val nodeContentList = rev (C11_Ast_Lib.fold_cDeclaration (K I) 
                  (selectFromNodeContent ["Ident0", "CTypeSpec0", "CArrDeclr0", "CDeclr0", "CCall0"]) 
                  declaration [])
-      val (newIdentList, _) = parseNodeContent NONE nodeContentList identList [] Global
+      val (newIdentList, _) = parseNodeContent NONE nodeContentList identList oldIdents [] Global
   in (debug("parsing global variable: " ^ @{make_string} nodeContentList); 
       (newIdentList, functionCallTable)) 
   end
@@ -525,6 +541,7 @@ fun parseExternalDeclaration
                                                  statement: nodeInfo cStatement,
                                                  ndInfo: nodeInfo)))
                               identList 
+                              oldIdents
                               (functionCallTable: string list Symtab.table) =
     let val functionReturnHOLType = conv_cDeclarationSpecifier_typ (SOME(declarationSpecifierList)) 
                                     |>  (fn (SOME(a)) => a)
@@ -538,27 +555,40 @@ fun parseExternalDeclaration
                                         (selectFromNodeContent ["Ident0", "CTypeSpec0", 
                                                                 "CArrDeclr0", "CDeclr0", "CCall0"]) 
                                         statement [])
-        val (newIdentList, functionCategory, newFunctionCallTable) = 
+        (*we need to sort out the local identifiers of previous functions, as they are no longer accessible*)
+        fun sortIdentifiers [] = ([],[])
+           |sortIdentifiers (ident::R) = let
+              val (prev_glob, prev_loc) = sortIdentifiers R
+              in case ident of Identifier (_,_,_,Global)=> (ident::prev_glob, prev_loc)
+                              |Identifier (_,_,_,FunctionCategory _) => (ident::prev_glob, prev_loc)
+                              |_ => (prev_glob, ident::prev_loc)
+              
+              end
+
+        val (previous_global_identifiers, previous_local_identifiers) = sortIdentifiers (identList)
+        val (newIdentList', functionCategory, newFunctionCallTable) =
                                     parseLocals statementContentList functionName functionCallTable 
-                                        (paramIdentifiers @ identList)
+                                        (paramIdentifiers@previous_global_identifiers) oldIdents
+        val newIdentList = newIdentList'@previous_local_identifiers
     in (Identifier(functionName, posL, functionReturnHOLType, 
                        FunctionCategory(functionCategory, SOME(statement))) :: newIdentList, 
                        newFunctionCallTable) 
     end
 
-  | parseExternalDeclaration s _ _ = error("Unsupported:  " ^ @{make_string} s)
+  | parseExternalDeclaration s _ _ _= error("Unsupported:  " ^ @{make_string} s)
 
 fun parseTranslUnitIdentifiers 
         (CTranslUnit0(externalDeclaration :: R, translUnitNodeInfo)) 
         identList
+        oldIdents
         (functionCallTable: string list Symtab.table) =
         let val (newIdentList, newFunctionCallTable) = 
-                    parseExternalDeclaration externalDeclaration identList functionCallTable
+                    parseExternalDeclaration externalDeclaration identList oldIdents functionCallTable
         in (debug("newIdentList (parseTranslUnitIdentifiers): " ^ @{make_string} newIdentList); 
             parseTranslUnitIdentifiers (CTranslUnit0(R, translUnitNodeInfo)) 
-                                       newIdentList newFunctionCallTable) 
+                                       newIdentList oldIdents newFunctionCallTable) 
         end
-  | parseTranslUnitIdentifiers _ identList functionCallTable = (identList, functionCallTable)
+  | parseTranslUnitIdentifiers _ identList oldIdents functionCallTable = (identList, functionCallTable)
 
 fun printIdentifier (Identifier(name, pos, typ, idType)) =
     writeln("Identifier: " ^ name ^ " " ^ Position.here pos ^
diff --git a/C11-BackEnds/Clean_wrapper/src/CleanTranslationHook.thy b/C11-BackEnds/Clean_wrapper/src/CleanTranslationHook.thy
new file mode 100644
index 0000000000000000000000000000000000000000..7dfae361f48c2aea08aac0e80938e3220f603ef3
--- /dev/null
+++ b/C11-BackEnds/Clean_wrapper/src/CleanTranslationHook.thy
@@ -0,0 +1,192 @@
+theory "CleanTranslationHook"
+  imports "../src/CleanCoder"  (* Coder_Test_Env_AEnv *)
+          "../src/compiler/Clean_Annotation"
+begin
+ML\<open>
+(*This is an override for the update_Root_Ast function that is registered in C_Command.*)
+
+fun transform_type typ = if typ = HOLogic.intT then "int" 
+                         else if typ = HOLogic.natT then "nat"
+                         else if is_listTy typ then (transform_type (dest_listTy typ))^" list" 
+                         else if typ = HOLogic.unitT then "unit"
+                         else error "Unknown variable type"
+
+local open C_AbsEnv HOLogic in
+fun get_hol_type (C_Env.Parsed ret) params = let
+      val base_type =the (C11_TypeSpec_2_CleanTyp.conv_cDeclarationSpecifier_typ (SOME ret))
+      fun transform_type ((C_Ast.CArrDeclr0 _)::R) base_type = listT (transform_type R base_type)
+         | transform_type [] base_type = base_type
+         | transform_type ps _ = error ("First type parameter unknown (maybe pointers): "^(@{make_string} ps))
+      in transform_type params base_type end
+    |get_hol_type a _ = error ("Can not get type of \""^(@{make_string} a)^"\"")
+fun map_env_ident_to_identifier (name,(positions,_,data)) =
+     let fun get_ident_scope C_Env.Global = Global 
+            |get_ident_scope C_Env.Local = Local ""
+            |get_ident_scope C_Env.Parameter = Parameter ""
+      in
+     case #functionArgs data of C_Ast.None => Identifier(name, if null positions then @{here} else hd positions,get_hol_type (#ret data) (#params data),get_ident_scope (#scope data))
+     |_=> Identifier(name, @{here},intT,FunctionCategory (Final, NONE))  (*this line is wrong because of different function types*)
+      end
+end
+
+fun declare_function idents name ast ret_ty recursive ctxt =
+   let  val param_idents = filter (fn i => case i of C_AbsEnv.Identifier(_,_,_, C_AbsEnv.Parameter f_name) => f_name = name |_=>false) idents
+        val local_idents = filter (fn i => case i of C_AbsEnv.Identifier(_,_,_, C_AbsEnv.Local f_name) => f_name = name |_=>false) idents
+        val global_idents = filter (fn i => case i of C_AbsEnv.Identifier(_,_,_, C_AbsEnv.Global) => true
+                                                      | C_AbsEnv.Identifier(_,_,_,C_AbsEnv.FunctionCategory _)=>true
+                                                      | _ => false) idents
+
+        (*Obtain the parameters and local variables*)
+        val params = map (fn C_AbsEnv.Identifier(name,pos,typ, _) => (Binding.make (name, pos), transform_type typ)) (param_idents)
+        val locals = map (fn C_AbsEnv.Identifier(name,pos,typ, _) => (Binding.make (name, pos), transform_type typ, NoSyn)) (local_idents)
+
+        (*This is necessary, as parameters are represented as free variables.
+          When the Invariants, post- and preconditions are read through the term antiquotations, 
+          Syntax.parse_term (Syntax.read_term does this too) would substitute them by another const,
+          which could be a local or global variable*)
+        fun remove_params_from_proof ctx = let
+             val param_names = List.map (fn C_AbsEnv.Identifier(n,_,_,_) => n) param_idents
+             fun filter_by_shortname param_names (n, _) =
+               List.exists (fn ele => ele = Long_Name.base_name n) param_names
+             val longnames =  List.filter (filter_by_shortname param_names) (#constants (Consts.dest (Sign.consts_of (Proof_Context.theory_of ctx))))
+             val thy0 = Proof_Context.theory_of ctx
+             val thy' = List.foldl (fn (longname, thy')=> thy' |> Sign.hide_const true longname)  thy0 (List.map fst longnames)
+             in Proof_Context.init_global thy' end
+
+        (*Invariants and measuress need to be matched to a loop. This is done by comparing the parse locations of all while loops.
+          The following are helper methods, to obtain the function get_invariant::positiona \<rightarrow> (context\<rightarrow>term) option*)
+        val invariants:((string*(Context.generic -> term)*Position.range) list) = List.filter (fn (f_name,_,_) => f_name = name) 
+                                                                (#invariants (Clean_Annotation.Data_Clean_Annotations.get ctxt)) 
+        val measures:((string*(Context.generic -> term)*Position.range) list) = List.filter (fn (f_name,_,_) => f_name = name) 
+                                                                (#measures (Clean_Annotation.Data_Clean_Annotations.get ctxt))                                                                                                       
+        val loop_pos =Library.distinct (op =) (C11_Ast_Lib.fold_cStatement (fn a => fn b => a@b) C11_Unit_2_Clean.get_loop_positions ast [])
+        fun compare_pos ((C_Ast.Position0 (pos1,_,_,_)),(C_Ast.Position0 (pos2,_,_,_))) = Int.compare (pos1,pos2)
+            |compare_pos a = error ("Unable to compare positions (for invariants and measures): "^(@{make_string} a))
+        val loop_pos_sorted = Library.sort compare_pos loop_pos 
+        fun range_less_than_pos (range:Position.range) (C_Ast.Position0 (pos,_,_,_)) = the (Position.offset_of (fst range)) < pos
+           |range_less_than_pos a b = error ("Unable to compare positions (for invariants and measures): "^(@{make_string} (a,b)))
+        fun get_for_position (((inv,inv_pos)::R_inv): ((Context.generic -> term)*Position.range)list)
+                                       (loop_positions: C_Ast.positiona list)
+                                       (pos3: C_Ast.positiona)
+                      (* search the first invariant, which is not declared before pos3 *)
+                      = (if range_less_than_pos inv_pos pos3 then get_for_position R_inv loop_positions pos3 
+                        else case loop_positions of (* we found the first invariant after pos3 *)
+                              (* Now check, if the next loop definition is after the invariant definition. 
+                                  Otherwise there is no invariant for the given loop *)
+                              (pos1::pos2::R) => if pos3 = pos1 andalso range_less_than_pos inv_pos pos2 then SOME inv
+                                                   else get_for_position ((inv,inv_pos)::R_inv) (pos2::R) pos3
+                              | (pos1::_) => if pos3 = pos1 then SOME inv else NONE
+                              | [] => NONE)
+           |get_for_position [] _ _ = NONE
+        fun get_invariant pos = (get_for_position (List.map (fn inv => (#2 inv, #3 inv)) invariants) loop_pos_sorted) pos
+        fun get_measure pos = (get_for_position (List.map (fn inv => (#2 inv, #3 inv)) measures) loop_pos_sorted) pos
+        fun get_loop_annotations pos = (get_invariant pos, get_measure pos)
+
+        (*generic function to get the first ele*)
+        val get_precond = Option.map (fn (_,e,_) => e) (List.find (fn (a,_,_) => a = name) (#preconditions (Clean_Annotation.Data_Clean_Annotations.get ctxt)))
+        val get_postcond = Option.map (fn (_,e,_) => e) (List.find (fn (a,_,_) => a = name) (#postconditions (Clean_Annotation.Data_Clean_Annotations.get ctxt)))    
+
+        (*the translation of the precondition*)
+        fun get_translation NONE default ctxt= C11_Expr_2_Clean.lifted_term (StateMgt.get_state_type (ctxt)) default
+          | get_translation (SOME get_term) _ ctxt= let
+                    val term = get_term (Context.Proof (remove_params_from_proof ctxt))
+                    val lifted = C11_Expr_2_Clean.lifted_term (StateMgt.get_state_type ctxt) term
+                    in
+                       Syntax.check_term ctxt lifted
+                    end
+        (*The actual translation of the loop body*)
+        fun get_translated_fun_bdy ctx _ = let
+              val ctx' = remove_params_from_proof ctx
+              val v = ((C11_Ast_Lib.fold_cStatement
+              C11_Stmt_2_Clean.regroup 
+              (C11_Stmt_2_Clean.convertStmt false 
+                                            (StateMgt.get_state_type ctx') 
+                                            (local_idents@param_idents@global_idents) 
+                                            (Proof_Context.theory_of ctx') 
+                                             name get_loop_annotations)
+              ast []))
+              in ( hd) v end
+
+        val test_function_sem = {binding = Binding.name name,
+                                 locals = locals@[(Binding.name "dummylocalvariable","int", NoSyn)], (*There needs to be at least one local variable*)
+                                 params = params,
+                                 ret_type = transform_type ret_ty,
+                                 read_pre = get_translation get_precond  (@{term True}),
+                                 read_post = get_translation get_postcond (Abs ("ret",ret_ty, @{term True})),
+                                 read_variant_opt = NONE,
+                                 read_body = get_translated_fun_bdy}
+        val decl = Function_Specification_Parser.checkNsem_function_spec_gen {recursive = recursive} test_function_sem
+    in decl end
+
+local open C_AbsEnv HOLogic in
+fun handle_declarations translUnit ctxt =
+     (let
+        (*get the OLD environment, which simplifies the parseTranslUnitIdentifiers by a lot.*)
+        val env = (C_Module.Data_Last_Env.get ctxt)
+        (*First we need to get all previously defined global vars and functions*)
+        val prev_idents =map map_env_ident_to_identifier (Symtab.dest (#idents(#var_table(env))))
+        (*the new identifiers are returned in reverse \<rightarrow> thus reverse *)
+        val (new_idents, call_table) = C_AbsEnv.parseTranslUnitIdentifiers translUnit [] prev_idents Symtab.empty
+        val identifiers = (rev new_idents)@prev_idents
+        val map_idents = List.map (fn C_AbsEnv.Identifier(name,_,typ,_) => (Binding.name name, transform_type typ, NoSyn))
+
+        fun get_declaration is_global idents = if null idents then I else StateMgt.new_state_record is_global (NONE,idents)
+        
+        val global_idents = (map_idents (List.filter (fn C_AbsEnv.Identifier(_,_,_,vis) => vis = C_AbsEnv.Global) new_idents))
+        val global_declaration =get_declaration true global_idents
+             
+        val fun_asts = 
+              List.map (fn C_AbsEnv.Identifier(name,_,ret_ty,C_AbsEnv.FunctionCategory ast) =>
+                     let  fun is_recursive NONE = false
+                            |is_recursive (SOME calls) = List.exists (fn x => x=name) calls
+                     in 
+                  (name,the (snd ast),ret_ty,  is_recursive (Symtab.lookup call_table name)) end
+                      | ident => error ("Expected function identifier. Instead: "^(@{make_string} ident)))
+                          
+              (List.filter (fn a => case a of C_AbsEnv.Identifier(_,_,_,C_AbsEnv.FunctionCategory _) => true | _ => false) (rev new_idents))
+        val function_declarations = List.map (fn (name,ast,ret_ty, recursive) => declare_function identifiers name ast ret_ty recursive ctxt) (fun_asts)
+        val function_decl = fold (fn f => fn acc => f acc) function_declarations
+    in
+     Context.map_theory (function_decl o global_declaration) ctxt
+    end);
+end
+\<close>
+ML\<open>
+fun handle_declarations_wrapper ast v2 ctxt =
+  let val ctx1 = update_Root_Ast SOME ast v2 ctxt (*Note the call to the original callback - this somehow gets overwritten*)
+  in
+    case ast of (C_Ast.Left translUnit) => handle_declarations translUnit ctx1
+                    | _ => ctx1
+  end
+\<close>
+setup \<open>C_Module.C_Term.map_expression 
+    (fn cexpr => fn _ => fn ctxt => let 
+    val sigma_i = (StateMgt.get_state_type o Context.proof_of )ctxt
+    val env = C_Module.Data_Surrounding_Env.get ctxt
+    val idents =  (Symtab.dest (#idents(#var_table(env))))
+    val A_env = List.map map_env_ident_to_identifier idents
+    val expr = (hd (C11_Ast_Lib.fold_cExpression (K I) 
+                                      (C11_Expr_2_Clean.convertExpr false sigma_i  A_env  (Context.theory_of ctxt) "" (K NONE))
+                                      cexpr [])) handle ERROR msg => (writeln("ERROR: "^(@{make_string}msg));@{term "1::int"})
+in
+  expr
+ end)\<close>
+setup \<open>Context.theory_map (C_Module.Data_Accept.put (handle_declarations_wrapper))\<close>
+
+(* Note: The hook "C_Module.C_Term.map_translation_unit" is not adequate, as it is 
+         meant for the term antiquotation (its callback returns a term, not a theory/context *)
+
+setup \<open>C_Module.C_Term.map_expression 
+    (fn cexpr => fn _ => fn ctxt => let 
+    val sigma_i = (StateMgt.get_state_type o Context.proof_of )ctxt
+    val env = C_Module.Data_Surrounding_Env.get ctxt
+    val idents =  (Symtab.dest (#idents(#var_table(env))))
+    val A_env = List.map map_env_ident_to_identifier idents
+    val expr = (hd (C11_Ast_Lib.fold_cExpression (K I) 
+                                      (C11_Expr_2_Clean.convertExpr false sigma_i  A_env  (Context.theory_of ctxt) "" (K NONE))
+                                      cexpr [])) handle ERROR msg => (writeln("ERROR: "^(@{make_string}msg));@{term "1::int"})
+in
+  expr
+ end)\<close>
+
+end
\ No newline at end of file
diff --git a/C11-BackEnds/Clean_wrapper/src/Clean_Wrapper.thy b/C11-BackEnds/Clean_wrapper/src/Clean_Wrapper.thy
index 5d7c7d02062e4394ea7be15c823e16daf927f540..e10d7daff84d600dd5965e662a2c1e8de454fe07 100644
--- a/C11-BackEnds/Clean_wrapper/src/Clean_Wrapper.thy
+++ b/C11-BackEnds/Clean_wrapper/src/Clean_Wrapper.thy
@@ -1,7 +1,7 @@
 (******************************************************************************
  * Isabelle/C/Clean
  *
- * Authors: Frederic Tuong, Burkhart Wolff
+ * Authors: Frederic Tuong, Lorenz Winkler, Burkhart Wolff
  *
  * Copyright (c) 2018-2019 Université Paris-Saclay, Univ. Paris-Sud, France
  *
diff --git a/C11-BackEnds/Clean_wrapper/src/compiler/Clean_Annotation.thy b/C11-BackEnds/Clean_wrapper/src/compiler/Clean_Annotation.thy
index 8d9d7adb581b4a38742e8b5bec123308ae6a691b..12df4f496390b528d0ce1bd54d94ccdf89c90cae 100644
--- a/C11-BackEnds/Clean_wrapper/src/compiler/Clean_Annotation.thy
+++ b/C11-BackEnds/Clean_wrapper/src/compiler/Clean_Annotation.thy
@@ -8,7 +8,7 @@
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are
  * met:
- *
+ 
  *     * Redistributions of source code must retain the above copyright
  *       notice, this list of conditions and the following disclaimer.
  *
@@ -63,20 +63,54 @@ datatype antiq_hol = Invariant of string (* term *)
                    | End_spec of string (* term *)
                    | Calls of text_range list
                    | Owned_by of text_range
+                   | Measure of string
+
+(*In the following data structure the annotations are saved*)
+type annotation_data = {
+  preconditions: (string*(Context.generic -> term)*Position.range) list,
+  postconditions: (string*(Context.generic -> term)*Position.range) list,
+  invariants: (string*(Context.generic -> term)*Position.range) list,
+  measures: (string*(Context.generic -> term)*Position.range) list
+}
+structure Data_Clean_Annotations = Generic_Data
+  (type T = annotation_data
+   val empty = {preconditions=[], postconditions=[], invariants=[], measures=[]}
+   val merge = K empty)
+
+fun map_context_annotation_declaration annotation_type src range context0 =
+let 
+  val current_env =snd (C_Stack.Data_Lang.get' context0) (*important: antiquotation needs current env*)
+  fun get_fun_name [(SOME (C_Ast.Ident0 (C_Ast.SS_base (C_Ast.ST name), _, _)),_)] = name
+      | get_fun_name (_::R) = get_fun_name R
+      | get_fun_name _ = (warning "unable to find name of surrounding function for CLEAN annotation";"")
+  val term =fn ctxt=> 
+                (*Important change: Syntax.read_term does coerce the types of the terms 
+                  constructed by C_Expr antiquotation. Syntax.parse_term does not do that*)
+                (*It does substitute free variables though, which is quite an issue*)
+                Syntax.parse_term 
+                        (Context.proof_of (C_Module.Data_Surrounding_Env.put current_env ctxt)) 
+                        (Token.inner_syntax_of src)
+  val function_name = (get_fun_name o #scopes o snd o C_Stack.Data_Lang.get') context0
+  val new_data = [(function_name, term, range)]
 
-fun toplevel _ = C_Inner_Toplevel.keep''
+  val new_context_map = Data_Clean_Annotations.map (fn {preconditions, postconditions, invariants, measures} => {
+      preconditions = case annotation_type of Spec _ => preconditions@new_data | _ => preconditions,
+      postconditions = case annotation_type of End_spec _ => postconditions@new_data | _ => postconditions,
+      invariants =case annotation_type of Invariant _ => invariants@new_data | _ => invariants,
+      measures =case annotation_type of Measure _ => measures@new_data | _ => measures
+  })
+in new_context_map context0 end
 
-fun bind scan _ ((stack1, (to_delay, stack2)), _) =
+fun bind scan context_map ((stack1, (to_delay, stack2)), _) =
   C_Parse.range scan
   >> (fn (src, range) =>
       C_Env.Parsing
         ( (stack1, stack2)
         , ( range
           , C_Inner_Syntax.bottom_up
-              (fn _ => fn context =>
-                ML_Context.exec
-                  (tap (fn _ => Syntax.read_term (Context.proof_of context) (Token.inner_syntax_of src)))
-                  context)
+              (fn v1 => fn context =>(
+                  context_map src range context)
+                  )
           , Symtab.empty
           , to_delay)))
 
@@ -92,17 +126,18 @@ user-defined annotations is very similar to the registration of ordinary command
 platform.\<close>
 
 ML \<open>local open Clean_Annotation
-    in fun command keyword f =
+    in fun command keyword annotation_type =
         C_Annotation.command' keyword ""
           (C_Token.syntax'
             (Parse.token Parse.cartouche)
-           >>> toplevel f)
-    end\<close>
+           >>> map_context_annotation_declaration annotation_type)
+    end\<close>    
 
 setup \<open>let open Clean_Annotation
-       in command ("pre\<^sub>C\<^sub>l\<^sub>e\<^sub>a\<^sub>n", \<^here>) Spec
-       #> command ("post\<^sub>C\<^sub>l\<^sub>e\<^sub>a\<^sub>n", \<^here>) End_spec
-       #> command ("inv\<^sub>C\<^sub>l\<^sub>e\<^sub>a\<^sub>n", \<^here>) Invariant
+       in command ("pre\<^sub>C\<^sub>l\<^sub>e\<^sub>a\<^sub>n", \<^here>) (Spec "")
+       #> command ("post\<^sub>C\<^sub>l\<^sub>e\<^sub>a\<^sub>n", \<^here>) (End_spec "")
+       #> command ("inv\<^sub>C\<^sub>l\<^sub>e\<^sub>a\<^sub>n", \<^here>) (Invariant "")
+       #> command ("measure\<^sub>C\<^sub>l\<^sub>e\<^sub>a\<^sub>n", \<^here>) (Measure "")
        end\<close>
 
 end
diff --git a/C11-FrontEnd/examples/C5.thy b/C11-FrontEnd/examples/C5.thy
new file mode 100644
index 0000000000000000000000000000000000000000..1bb1e23de6c80ddebe8de084c9f847edba87c69e
--- /dev/null
+++ b/C11-FrontEnd/examples/C5.thy
@@ -0,0 +1,100 @@
+theory C5
+  imports "Isabelle_C.C_Main"
+begin
+
+(*This file contains some ways to retrieve the C-environment*)
+
+ML\<open>
+val SPY_ENV =  Unsynchronized.ref(NONE:C_Env.env_lang option);\<close>
+declare [[C\<^sub>e\<^sub>n\<^sub>v\<^sub>0 = last]]
+declare [[C\<^sub>r\<^sub>u\<^sub>l\<^sub>e\<^sub>0 = "translation_unit"]]
+
+C\<open>
+int globalvar1;
+void test(int param1){
+  int localvariable1;
+  
+  return 12;   /*@ \<approx>setup \<open>fn _ => fn _ => fn env => 
+               (*The environment can be retrieved using the generic setup command*)
+               ((SPY_ENV := SOME env);I) \<close> */;
+  int localvariable2;
+}
+int globalvar2;
+\<close>
+
+ML\<open>
+(*We can see that the saved env in fact has all the current variables*)
+val saved_vars = (map (fn (a,(_,_,b)) => (a,#scope b)) (Symtab.dest (
+ #idents(#var_table(the (!SPY_ENV))))
+))
+val final_vars = (map (fn (a,(_,_,b)) => (a,#scope b)) (Symtab.dest (
+ #idents(#var_table(@{C\<^sub>e\<^sub>n\<^sub>v})))))
+\<close>
+
+(*There is a second way to achieve the same, using the context*)
+C\<open>
+int globalvar3;
+void test2(int param1){
+  int localvariable3;
+  
+  return 12;   /*@ \<approx>setup \<open>fn _ => fn _ => fn _ => fn ctx =>
+               (*The environment can be retrieved using the generic setup command*)
+               ((SPY_ENV := SOME (snd (C_Stack.Data_Lang.get' ctx)));ctx) \<close> */;
+  int localvariable4;
+}
+int globalvar4;
+\<close>
+
+ML\<open>
+(*We can see that the saved env in fact has all the current variables*)
+val saved_vars = (map (fn (a,(_,_,b)) => (a,#scope b)) (Symtab.dest (
+ #idents(#var_table(the (!SPY_ENV))))
+))
+\<close>
+
+
+(*Declaring a seperate antiquotation *)
+
+ML\<open>
+val env = @{C\<^sub>e\<^sub>n\<^sub>v}\<close>
+
+ML\<open>
+Theory.setup
+  (C_Inner_Syntax.command_no_range
+       (C_Inner_Toplevel.generic_theory oo C_Inner_Isar_Cmd.setup
+         \<open>fn ((_, (_, pos1, pos2)) :: _) =>
+              (fn _ => fn _ =>
+                tap (fn ctx =>
+                      (SPY_ENV := SOME (snd (C_Stack.Data_Lang.get' ctx));Position.reports_text [((Position.range (pos1, pos2)
+                                               |> Position.range_position, Markup.intensify), "")])))
+           | _ => fn _ => fn _ => I\<close>)
+       ("store_and_highlight", \<^here>, \<^here>))
+\<close>
+
+(*this is btw how all previous identifiers can get deleted*)
+setup\<open>Context.theory_map (C_Module.Data_In_Env.put C_Env.empty_env_lang)\<close>
+
+C\<open>
+int globalvar3;
+void test2(int param1){
+  int localvariable3;/*@ store_and_highlight */
+}
+\<close>
+
+ML\<open>
+val saved_vars = (map (fn (a,(_,_,b)) => (a,#scope b)) (Symtab.dest (
+ #idents(#var_table(the (!SPY_ENV)))) (*NOTE: localvariable3 is in the environment*)
+))\<close>
+
+setup\<open>Context.theory_map (C_Module.Data_In_Env.put C_Env.empty_env_lang)\<close>
+
+C\<open>
+int globalvar3;
+void test2(int param1){
+  int localvariable3;/*@@@@@ store_and_highlight */
+}
+\<close>
+ML\<open>
+val saved_vars = (map (fn (a,(_,_,b)) => (a,#scope b)) (Symtab.dest (
+ #idents(#var_table(the (!SPY_ENV)))) (*NOTE: localvariable3 is NOT in the environment*)
+))\<close>
\ No newline at end of file
diff --git a/C11-FrontEnd/main/C_Main.thy b/C11-FrontEnd/main/C_Main.thy
index 35899cbe078c1318a056fb968cbecb4baf1f8257..c82132bf5fbc216eb4d0302f910fbac300a902b5 100644
--- a/C11-FrontEnd/main/C_Main.thy
+++ b/C11-FrontEnd/main/C_Main.thy
@@ -40,5 +40,7 @@ theory C_Main
 begin
 text\<open> @{footnote \<open>sdf\<close>}, @{file "$ISABELLE_HOME/src/Pure/ROOT.ML"}\<close>
 
+
+
 end
 (*>*)
diff --git a/C11-FrontEnd/src/C_Ast.thy b/C11-FrontEnd/src/C_Ast.thy
index f5d9f2db8022386d9f5345887ba179133760eb39..09c55d92e67f848d915c1a22b6cf39fc94b83b8a 100644
--- a/C11-FrontEnd/src/C_Ast.thy
+++ b/C11-FrontEnd/src/C_Ast.thy
@@ -875,7 +875,7 @@ and fold_cExpression grp g ast st =
                    |> g (TT"CCast0") a
        | (CUnary0(unop:cUnaryOp, ex: 'a cExpression, a)) => 
                 st |> fold_cExpression grp g ex 
-                   |> g (TT("CUnary0 "^toString_cUnaryOp unop)) a
+                   |> g (TTT"CUnary0" (toString_cUnaryOp unop)) a
        | (CSizeofExpr0(ex:'a cExpression, a)) => 
                 st |> fold_cExpression grp g ex    |> g (TT"CSizeofExpr0") a
        | (CSizeofType0(decl:'a cDeclaration,a)) => 
diff --git a/C11-FrontEnd/src/C_Command.thy b/C11-FrontEnd/src/C_Command.thy
index 974aa23533b13402512d0d28daa90dbfe78caa7b..2548d5ed33d647820c46d1001e8170c93310a9d0 100644
--- a/C11-FrontEnd/src/C_Command.thy
+++ b/C11-FrontEnd/src/C_Command.thy
@@ -39,6 +39,7 @@ section \<open>Interface: Inner and Outer Commands\<close>
 
 theory C_Command
   imports C_Eval
+          "../../C11-BackEnds/Clean/src/Clean"
   keywords "C" :: thy_decl % "ML"
        and "C_file" :: thy_load % "ML"
        and "C_export_boot" :: thy_decl % "ML"
@@ -153,6 +154,8 @@ signature C_MODULE =
  sig
     structure Data_Accept    : GENERIC_DATA
     structure Data_In_Env    : GENERIC_DATA
+    structure Data_Last_Env  : GENERIC_DATA
+    structure Data_Surrounding_Env  : GENERIC_DATA
     structure Data_In_Source : GENERIC_DATA
     structure Data_Term      : GENERIC_DATA
 
@@ -168,13 +171,13 @@ signature C_MODULE =
         val key_external_declaration: Input.source
         val key_statement: Input.source
         val key_translation_unit: Input.source
-        val map_default: (C_Grammar_Rule.ast_generic -> C_Env.env_lang -> local_theory -> term) -> theory -> theory
-        val map_expression: (C_Grammar_Rule_Lib.CExpr -> C_Env.env_lang -> local_theory -> term) -> theory -> theory
+        val map_default: (C_Grammar_Rule.ast_generic -> C_Env.env_lang -> Context.generic -> term) -> theory -> theory
+        val map_expression: (C_Grammar_Rule_Lib.CExpr -> C_Env.env_lang -> Context.generic -> term) -> theory -> theory
         val map_external_declaration:
-           (C_Grammar_Rule_Lib.CExtDecl -> C_Env.env_lang -> local_theory -> term) -> theory -> theory
-        val map_statement: (C_Grammar_Rule_Lib.CStat -> C_Env.env_lang -> local_theory -> term) -> theory -> theory
+           (C_Grammar_Rule_Lib.CExtDecl -> C_Env.env_lang -> Context.generic -> term) -> theory -> theory
+        val map_statement: (C_Grammar_Rule_Lib.CStat -> C_Env.env_lang -> Context.generic -> term) -> theory -> theory
         val map_translation_unit:
-           (C_Grammar_Rule_Lib.CTranslUnit -> C_Env.env_lang -> local_theory -> term) -> theory -> theory
+           (C_Grammar_Rule_Lib.CTranslUnit -> C_Env.env_lang -> Context.generic -> term) -> theory -> theory
         val tok0_expression: string * ('a * 'a -> (C_Grammar.Tokens.svalue, 'a) LALR_Parser_Eval.Token.token)
         val tok0_external_declaration: string * ('a * 'a -> (C_Grammar.Tokens.svalue, 'a) LALR_Parser_Eval.Token.token)
         val tok0_statement: string * ('a * 'a -> (C_Grammar.Tokens.svalue, 'a) LALR_Parser_Eval.Token.token)
@@ -265,13 +268,23 @@ structure Data_In_Env = Generic_Data
    val empty = C_Env.empty_env_lang
    val merge = K empty)
 
+structure Data_Last_Env = Generic_Data
+  (type T = C_Env.env_lang
+   val empty = C_Env.empty_env_lang
+   val merge = K empty)
+
+structure Data_Surrounding_Env = Generic_Data
+  (type T = C_Env.env_lang
+   val empty = C_Env.empty_env_lang
+   val merge = K empty)
+
 structure Data_Accept = Generic_Data
   (type T = C_Grammar_Rule.ast_generic -> C_Env.env_lang -> Context.generic -> Context.generic
    fun empty _ _ = I
    val merge = #2)
 
 structure Data_Term = Generic_Data
-  (type T = (C_Grammar_Rule.ast_generic -> C_Env.env_lang -> local_theory -> term) Symtab.table
+  (type T = (C_Grammar_Rule.ast_generic -> C_Env.env_lang -> Context.generic -> term) Symtab.table
    val empty = Symtab.empty
    val merge = #2)
 
@@ -348,8 +361,9 @@ fun err0 _ _ pos =
 val err = pair () oooo err0
 
 fun accept0 f (env_lang:C_Env.env_lang) ast =
-  Data_In_Env.put env_lang
-  #> (fn context => f context ast env_lang (Data_Accept.get context ast env_lang context))
+  (fn ctx => Data_Last_Env.put (Data_In_Env.get ctx) ctx) 
+  #> Data_In_Env.put env_lang
+  #> (fn context => (f context ast env_lang (Data_Accept.get context ast env_lang context)))
 
 fun accept (env_lang:C_Env.env_lang) (_, (ast, _, _)) =
   pair () o C_Env.map_context (accept0 (K (K (K I))) env_lang ast)
@@ -373,18 +387,19 @@ fun accept ctxt start_rule =
     val (key, pos) = Input.source_content key
   in
     ( start
-    , fn env_lang => fn (_, (ast, _, _)) =>
+    , fn env_lang => fn (_, (ast, _, _)) =>((*This env_lang also contains the previous environment, 
+        but returning this would completely override the new env (which would be bad in case of parsing input with ned declarations)*)
         C_Env.map_context'
           (accept0
-            (fn context =>
+            (fn context =>(
               pair oo (case Symtab.lookup (Data_Term.get context) key of
                          NONE => tap (fn _ => warning ("Representation function associated to\
                                                        \ \"" ^ key ^ "\"" ^ Position.here pos
                                                        ^ " not found (returning a dummy term)"))
                                      (fn _ => fn _ => @{term "()"})
-                       | SOME f => fn ast => fn env_lang => f ast env_lang ctxt))
+                       | SOME f => fn ast => fn env_lang => f ast env_lang (Context.Proof ctxt))))
             env_lang
-            ast))
+            ast)))
   end
 
 fun eval_in text context env start_rule =
@@ -423,9 +438,9 @@ fun parse_translation l = l |>
                 src
                 (case Context.get_generic_context () of
                    NONE => Context.Proof ctxt
-                 | SOME context => Context.mapping I (K ctxt) context)
-                (C_Stack.Data_Lang.get #> (fn NONE => env0 ctxt
-                                            | SOME (_, env_lang) => env_lang))
+                 | SOME context => Context.Proof ctxt)
+                (fn _ => (C_Stack.Data_Lang.get #> (fn NONE => env0 ctxt (*HERE: This is a "fix" for starting with the current C_Env when parsing antiquotations.*)
+                                            | SOME (_, env_lang) => env_lang)) (Context.Proof ctxt))
                 start_rule
                 (c_enclose "" "" src)
               end
@@ -931,7 +946,7 @@ fun command_ml environment catch_all debug get_file gthy =
 val ML = command_ml "" false;
 val SML = command_ml ML_Env.SML true;
 end;
-\<close>
+\<close>                                         
 
 subsubsection \<open>Initialization\<close>
 
@@ -1309,6 +1324,7 @@ fun update_Root_Ast filter ast _ ctxt =
     end;
 
 
+
 fun get_Root_Ast filter thy =
   let val ctxt = Context.Theory thy
       val thid = Context.theory_long_name(Context.theory_of ctxt)
diff --git a/C11-FrontEnd/src/C_Environment.thy b/C11-FrontEnd/src/C_Environment.thy
index 985c19d760479c3af48bad136f7042324c8b563b..ece49874cd815bb5d4033ffc61a00d383d385cb1 100644
--- a/C11-FrontEnd/src/C_Environment.thy
+++ b/C11-FrontEnd/src/C_Environment.thy
@@ -59,11 +59,13 @@ signature C_ENV =
     type 'a stream = ('a, C_Lex.token) C_Scan.either list
     datatype 'a parse_status = Parsed of 'a | Previous_in_stack
 
+    datatype variable_scope = Global | Local | Parameter
     eqtype markup_global
-
-    type markup_ident = {global         : markup_global,
+                                              
+    type markup_ident = {scope         : markup_global,
                          params         : C_Ast.CDerivedDeclr list, 
-                         ret            : C_Ast.CDeclSpec list parse_status}
+                         ret            : C_Ast.CDeclSpec list parse_status,
+                         functionArgs   : ((string*(C_Ast.NodeInfo C_Ast.cDeclaration)) list) C_Ast.optiona}
     type 'a markup_store = Position.T list * serial * 'a
 
     type var_table =    {idents         : markup_ident markup_store Symtab.table,
@@ -200,11 +202,14 @@ type env_directives =
 
 datatype 'a parse_status = Parsed of 'a | Previous_in_stack
 
-type markup_global = bool (*true: global*)
+datatype variable_scope = Global | Local | Parameter
+
+type markup_global = variable_scope (*true: global*)
 
-type markup_ident = { global : markup_global
+type markup_ident = { scope : markup_global
                     , params : C_Ast.CDerivedDeclr list
-                    , ret : C_Ast.CDeclSpec list parse_status }
+                    , ret : C_Ast.CDeclSpec list parse_status 
+                    , functionArgs   : ((string*(C_Ast.NodeInfo C_Ast.cDeclaration)) list) C_Ast.optiona}
 
 type var_table = { tyidents : markup_global markup_store Symtab.table (*ident name*)
                                                                       Symtab.table (*internal
@@ -406,9 +411,9 @@ fun map_idents f {tyidents, idents} =
 (**)
 
 fun map_var_table f {var_table, scopes, namesupply, stream_ignored, env_directives} =
-                                  {var_table = f
+                                  ({var_table = f
                                                var_table, scopes = scopes, namesupply = namesupply, 
-                                   stream_ignored = stream_ignored, env_directives = env_directives}
+                                   stream_ignored = stream_ignored, env_directives = env_directives})
 
 fun map_scopes f {var_table, scopes, namesupply, stream_ignored, env_directives} =
                                   {var_table = var_table, scopes = f
@@ -503,7 +508,9 @@ fun string_of (env_lang : env_lang) =
   let fun dest0 x f = x |> Symtab.dest |> map f
       fun dest {tyidents, idents} =
             (dest0 tyidents #1, dest0 idents (fn (i, (_,_,v)) =>
-                                               (i, if #global v then "global" else "local")))
+                                               (i, case #scope v of Global => "global"
+                                                                  | Local => "local"
+                                                                  | Parameter => "parameter")))
   in \<^make_string> ( ("var_table", dest (#var_table env_lang))
                  , ("scopes", map (fn (id, i) =>
                                     ( Option.map (fn C_Ast.Ident0 (i, _, _) =>
diff --git a/C11-FrontEnd/src/C_Eval.thy b/C11-FrontEnd/src/C_Eval.thy
index beba4287778df3c5a4066efdccbe397f9eb37df7..54b51839b781c6d4e826fa268231ff75290aeade 100644
--- a/C11-FrontEnd/src/C_Eval.thy
+++ b/C11-FrontEnd/src/C_Eval.thy
@@ -219,7 +219,8 @@ fun makeLexer ((stack, stack_ml, stack_pos, stack_tree), arg) =
         |> C_Hook.advance stack
         |> f
         |> (fn (arg, stack_ml) => rpair ((stack, stack_ml, stack_pos, stack_tree), arg))
-      fun return0 x = \<comment> \<open>Warning: \<open>C_Hook.advance\<close> must not be early evaluated here, as it might
+      fun return0 x = \<comment> \<open>Warning: \<open>C_Hook.advance\<close> must not be early evae
+luated here, as it might
                                    generate undesirable markup reporting (in annotation commands).\<close>
                       \<comment> \<open>Todo: Arrange \<open>C_Hook.advance\<close> as a pure function, so that the overall could
                                 be eta-simplified.\<close>
@@ -760,26 +761,27 @@ fun eval env start err accept (ants, ants_err) {context, reports_text, error_lin
       val () = if Config.get ctxt C_Options.lexer_trace andalso Context_Position.is_visible ctxt
                then print (map_filter (fn Right x => SOME x | _ => NONE) ants_stack)
                else ()
-  in
-   C_Language.eval env
+      val v =   C_Language.eval env
                    start
                    err
                    accept
                    ants_stack
                    {context = context, reports_text = reports_text, error_lines = error_lines}
-  end
+  in 
+    v 
+ end
 
 
 (* derived versions *)
 
 fun eval' env start err accept ants =
   Context.>>> (fn context =>
-               C_Env_Ext.context_map'
+              let val v =C_Env_Ext.context_map'
                  (eval (env context) (start context) err accept ants
                   #> apsnd (Context_Position.reports_enabled_generic context ? tap (Position.reports_text o #reports_text)
                             #> tap (#error_lines #> (fn [] => () | l => error (cat_lines (rev l))))
                             #> (C_Env.empty_env_tree o #context)))
-                 context)
+                 context in v end)
 end;
 
 fun eval_source env start err accept source =
diff --git a/C11-FrontEnd/src/C_Parser_Language.thy b/C11-FrontEnd/src/C_Parser_Language.thy
index f6af7094b28c0abe2e2f0df9f78388401a40dfee..64c1528f5a1d78d8976143f1be483ee6c6c5e4da 100644
--- a/C11-FrontEnd/src/C_Parser_Language.thy
+++ b/C11-FrontEnd/src/C_Parser_Language.thy
@@ -207,7 +207,7 @@ sig
                            C_Env.env_tree ->
                            C_Env.env_lang * C_Env.env_tree
   val shadowTypedef0' : C_Ast.CDeclSpec list C_Env.parse_status ->
-                        bool ->
+                        C_Env.variable_scope ->
                         C_Ast.ident * C_Ast.CDerivedDeclr list ->
                         C_Env.env_lang ->
                         C_Env.env_tree ->
@@ -251,6 +251,7 @@ sig
   val ident_of_decl : (Ident list, CDecl list * bool) C_Ast.either ->
                       (Ident * CDerivedDeclr list * CDeclSpec list) list
   val doFuncParamDeclIdent : CDeclr -> unit monad
+  val extractFunctionArgs: 'a C_Ast.cDerivedDeclarator list -> ((string * 'a C_Ast.cDeclaration) list) C_Ast.optiona
 end
 
 structure C_Grammar_Rule_Lib : C_GRAMMAR_RULE_LIB =
@@ -322,14 +323,29 @@ struct
       #> (case typing of NONE => I | SOME x => cons x))
        (map (markup_init o Position.make_entity_markup {def = def} id varN o pair name) ps)
     end)
-
+  fun extractFunctionArgs ident =
+    let fun getVarName nameDecl = case nameDecl of Some (Ident0 (SS_base (ST name),_,_)) => name
+                                              | _ => "unknown"
+        fun getTypeSuffix potentialArrDeclaration = case potentialArrDeclaration of ((CArrDeclr0 (_,(CNoArrSize0 false),_)):: Rest) => "[]"^(getTypeSuffix ( Rest))
+                                                                                | ((CArrDeclr0 (_,(CArrSize0 _),_)):: Rest) => "[somesize]"^(getTypeSuffix ( Rest))
+                                                                                | ((CPtrDeclr0 _):: Rest) => "*"^(getTypeSuffix Rest)
+                                                                                | [] => ""
+                                                                                | _ => "unknown"
+        fun transformDeclaration decl =
+                  case decl of 
+                          (CDecl0 ([CTypeSpec0 (typespec)],[((Some (CDeclr0 (nameIdent,potentialArrDeclarations,_,_,_)),_),_)],_)) => (getVarName nameIdent,decl)  
+    in
+    case ident of [CFunDeclr0 (Right (declarations,_),_,_)] => Some (map transformDeclaration declarations)
+                                               | _ => None
+    end
   fun markup_make' typing get_global desc report =
     markup_make
       typing
       get_global
       (fn global =>
-        "C " ^ (case global of SOME true => "global "
-                             | SOME false => "local "
+        "C " ^ (case global of SOME C_Env.Global => "global "
+                             | SOME C_Env.Local => "local "
+                             | SOME C_Env.Parameter => "parameter "
                              | NONE => "")
              ^ desc)
       (fn cons' => fn def =>
@@ -344,8 +360,8 @@ struct
       I
       desc
       (fn cons' => fn def =>
-       fn true => cons' (if def then Markup.free else Markup.ML_keyword3)
-        | false => cons' Markup.skolem)
+       fn C_Env.Global => cons' (if def then Markup.free else Markup.ML_keyword3)
+        | _ => cons' Markup.skolem)
 
   val markup_tvar = markup_tvar0 "type variable"
   val markup_var_enum = markup_tvar0 "enum tag"
@@ -411,20 +427,20 @@ struct
   val markup_var =
     markup_make'
       typing
-      #global
+      #scope
       "variable"
       (fn cons' => fn def =>
-       fn true => if def then cons' Markup.free else cons' Markup.delimiter (*explicit black color,
+       fn C_Env.Global => if def then cons' Markup.free else cons' Markup.delimiter (*explicit black color,
                                                      otherwise the default color of constants might
                                                      be automatically chosen (especially in term
                                                      cartouches)*)
-        | false => cons' Markup.bound)
+        | _ => cons' Markup.bound)
 
   val markup_var_bound =
-    markup_make' typing #global "variable" (fn cons' => K (K (cons' Markup.bound)))
+    markup_make' typing #scope "variable" (fn cons' => K (K (cons' Markup.bound)))
 
   val markup_var_improper =
-    markup_make' typing #global "variable" (fn cons' => K (K (cons' Markup.improper)))
+    markup_make' typing #scope "variable" (fn cons' => K (K (cons' Markup.improper)))
 
   (**)
   val return = pair
@@ -528,7 +544,7 @@ struct
   fun addTypedef (Ident0 (_, i, node)) env =
     let val name = ident_decode i
         val pos1 = [decode_error' node |> #1]
-        val data = (pos1, serial (), null (C_Env_Ext.get_scopes env))
+        val data = (pos1, serial (), if null (C_Env_Ext.get_scopes env) then C_Env.Global else C_Env.Local)
     in ((), env |> C_Env_Ext.map_idents (Symtab.delete_safe name)
                 |> C_Env_Ext.map_tyidents_typedef (Symtab.update (name, data))
                 |> C_Env_Ext.map_reports_text
@@ -540,8 +556,8 @@ struct
   fun shadowTypedef0''' name pos data0 env_lang env_tree =
     let val data = (pos, serial (), data0)
         val update_id = Symtab.update (name, data)
-    in ( env_lang |> C_Env_Ext.map_tyidents'_typedef (Symtab.delete_safe name)
-                  |> C_Env_Ext.map_idents' update_id
+    in (env_lang |> C_Env_Ext.map_tyidents'_typedef (Symtab.delete_safe name)
+                  |> C_Env_Ext.map_idents' update_id (*In this line entries get added to the var table*)
        , update_id
        , env_tree
           |> C_Env.map_reports_text
@@ -553,25 +569,25 @@ struct
   fun shadowTypedef0'''' name pos data0 env_lang env_tree =
     let val (env_lang, _, env_tree) = shadowTypedef0''' name pos data0 env_lang env_tree
     in ( env_lang, env_tree) end
-  fun shadowTypedef0'' ret global (Ident0 (_, i, node), params) =
+  fun shadowTypedef0'' ret scope (Ident0 (a, i, node), params) =
     shadowTypedef0''' (ident_decode i)
                       [decode_error' node |> #1]
-                      {global = global, params = params, ret = ret}
+                      {scope = scope, params = params, ret = ret, functionArgs = extractFunctionArgs params }
   fun shadowTypedef0' ret global ident env_lang env_tree =
-    let val (env_lang, _, env_tree) = shadowTypedef0'' ret global ident env_lang env_tree 
+    let val (env_lang, _, env_tree) = shadowTypedef0'' ret global ident env_lang env_tree
     in (env_lang, env_tree) end
   fun shadowTypedef0 ret global f ident env =
     let val (update_id, env) =
           C_Env.map_env_lang_tree'
             (fn env_lang => fn env_tree => 
               let val (env_lang, update_id, env_tree) =
-                        shadowTypedef0'' ret global ident env_lang env_tree 
+                        shadowTypedef0'' ret global ident env_lang env_tree
               in (update_id, (env_lang, env_tree)) end)
             env
     in ((), f update_id env) end
   fun shadowTypedef_fun ident env =
-    shadowTypedef0 C_Env.Previous_in_stack
-                   (case C_Env_Ext.get_scopes env of _ :: [] => true | _ => false)
+                   shadowTypedef0 C_Env.Previous_in_stack
+                   (case C_Env_Ext.get_scopes env of _ :: [] => C_Env.Global | _ => C_Env.Local)
                    (fn update_id =>
                     C_Env_Ext.map_scopes
                      (fn (NONE, x) :: xs => (SOME (fst ident), C_Env.map_idents update_id x) :: xs
@@ -579,8 +595,10 @@ struct
                        | [] => error "Not expecting an empty scope"))
                    ident
                    env
+  fun shadowTypedef_function_param (i,params, ret) env =
+      shadowTypedef0 (C_Env.Parsed ret) C_Env.Parameter (K I) (i, params) env
   fun shadowTypedef (i, params, ret) env =
-    shadowTypedef0 (C_Env.Parsed ret) (List.null (C_Env_Ext.get_scopes env)) (K I) (i, params) env
+    shadowTypedef0 (C_Env.Parsed ret) (if List.null (C_Env_Ext.get_scopes env) then C_Env.Global else C_Env.Local) (K I) (i, params) env (*This line is relevant. From here the parameters call origins*)
   fun isTypeIdent s0 = Symtab.exists (fn (s1, _) => s0 = s1) o C_Env_Ext.get_tyidents_typedef
   fun enterScope env =
     ((), C_Env_Ext.map_scopes (cons (NONE, C_Env_Ext.get_var_table env)) env)
@@ -588,7 +606,7 @@ struct
     case C_Env_Ext.get_scopes env of
       [] => error "leaveScope: already in global scope"
     | (_, var_table) :: scopes => ((), env |> C_Env_Ext.map_scopes (K scopes)
-                                           |> C_Env_Ext.map_var_table (K var_table))
+                                           |> C_Env_Ext.map_var_table (K var_table)) (*This line is responsible for scoped vars from the var_table (replacing it with I keeps the vars)*)
   val getCurrentPosition = return NoPosition
 
   (* Language.C.Parser.Tokens *)
@@ -709,7 +727,7 @@ struct
     | _ => rappend declspecs (liftCAttrs new_attrs)
   val emptyDeclr = CDeclrR Nothing empty Nothing [] undefNode
   fun mkVarDeclr ident = CDeclrR (Some ident) empty Nothing []
-  fun doDeclIdent declspecs (decl as CDeclrR0 (mIdent, _, _, _, _)) =
+  fun doDeclIdent declspecs (decl as CDeclrR0 (mIdent, _,_,_,_)) =
     case mIdent of
       None => return ()
     | Some ident =>
@@ -750,7 +768,7 @@ struct
       (case mIdent0 of None => return ()
                      | Some mIdent0 => shadowTypedef_fun (mIdent0, param0))
       >>
-      sequence_ shadowTypedef
+      sequence_ shadowTypedef_function_param
                 (maps (fn CFunDeclr0 (params, _, _) => ident_of_decl params | _ => []) param_fun)
       >>
       sequence_
@@ -764,7 +782,7 @@ struct
                       val pos = [decode_error' node |> #1]
                       val data = ( pos
                                  , serial ()
-                                 , {global = false, params = params, ret = C_Env.Parsed ret})
+                                 , {scope = C_Env.Local, params = params, ret = C_Env.Parsed ret, functionArgs = extractFunctionArgs params})
                     in
                       ( env_lang |> Symtab.update (name, data)
                       , env_tree
@@ -947,7 +965,7 @@ val declarator1 : (CDeclrR) -> unit monad =
                       val pos = [decode_error' node |> #1]
                       val data = ( pos
                                  , serial ()
-                                 , {global = false, params = params, ret = C_Env.Parsed ret})
+                                 , {scope = C_Env.Local, params = params, ret = C_Env.Parsed ret, functionArgs = extractFunctionArgs params})
                     in
                       ( env_lang |> Symtab.update (name, data)
                       , env_tree
@@ -1019,7 +1037,7 @@ val declaration : (CDecl) -> unit monad =
                     fn (env_lang, env_tree) =>
                      let val name = ident_decode i
                          val pos1 = [decode_error' node |> #1]
-                         val data = (pos1, serial (), null (C_Env.get_scopes env_lang))
+                         val data = (pos1, serial (), if null (C_Env.get_scopes env_lang) then C_Env.Global else C_Env.Local)
                      in
                        ( C_Env_Ext.map_tyidents'_enum (Symtab.update (name, data)) env_lang
                        , C_Env.map_reports_text
@@ -1053,7 +1071,7 @@ val enumerator : ( ( Ident * CExpr Maybe ) ) -> unit monad =
         fn (ident as Ident0 (_, _, node), _) =>
           C_Grammar_Rule_Lib.shadowTypedef0'
             (C_Env.Parsed [CTypeSpec0 (CIntType0 node)])
-            (null (C_Env.get_scopes env_lang))
+            (if null (C_Env.get_scopes env_lang) then C_Env.Global else C_Env.Local)
             (ident, [])
             env_lang
       end
diff --git a/README_dev b/README_dev
index ac2d9407b3785a63d37e55eaebe514979308705a..f8dd26eec3f4ce3079a0bcd1782593d05ce2153d 100644
--- a/README_dev
+++ b/README_dev
@@ -9,3 +9,6 @@ START FOR EXAMPLE:
 cd Isabelle_C
 isabelle jedit -d . C11-BackEnds/Clean_wrapper/examples/Coder_Test_ExprStmt.thy
 
+Branch LorenzWinkler:
+cd Isabelle_C
+isabelle jedit -d C11-FrontEnd -d C11-BackEnds/Clean C11-BackEnds/Clean_wrapper/examples/Coder_Test_TUnits.thy