diff --git a/automata/automaton_G_and_F.jl b/automata/automaton_G_and_F.jl
index b1e65c3df47bafab38f60d1ceef7dbddb6af1499..ba05cabdd66c062687176f6d69d57c1c12d32697 100644
--- a/automata/automaton_G_and_F.jl
+++ b/automata/automaton_G_and_F.jl
@@ -1,11 +1,7 @@
 
 # Creation of the automaton types
 #@everywhere @eval abstract type EdgeAutomatonGandF <: Edge end
-@everywhere struct EdgeAutomatonGandF <: Edge 
-    transitions::TransitionSet 
-    check_constraints::Function
-    update_state!::Function
-end
+@everywhere struct EdgeAutomatonGandF{T} <: Edge transitions::Union{Nothing,Vector{Symbol}} end
 @everywhere @eval $(MarkovProcesses.generate_code_lha_type_def(:AutomatonGandF, :EdgeAutomatonGandF))
 
 function create_automaton_G_and_F(m::ContinuousTimeModel, x1::Float64, x2::Float64, t1::Float64, t2::Float64, sym_obs_G::VariableModel,
@@ -63,26 +59,23 @@ function create_automaton_G_and_F(m::ContinuousTimeModel, x1::Float64, x2::Float
 
     id = MarkovProcesses.newid()
     #Symbol("Edge_$(lha_name)_$(basename_func)_$(from_loc)$(to_loc)_$(edge_number)")
-    function edge_name(from_loc::Location, to_loc::Location, edge_number::Int)
-        return Symbol("$(edge_type)_$(from_loc)$(to_loc)_$(edge_number)_$(model_name)_$(id)")
-    end
-    function check_constraints(from_loc::Location, to_loc::Location, edge_number::Int)
-        return Symbol("check_constraints_$(edge_type)_$(from_loc)$(to_loc)_$(edge_number)_$(model_name)_$(id)")
-    end
-    function update_state!(from_loc::Location, to_loc::Location, edge_number::Int)
-        return Symbol("update_state_$(edge_type)_$(from_loc)$(to_loc)_$(edge_number)_$(model_name)_$(id)!")
+    function generate_edge_type(from_loc::Location, to_loc::Location, edge_number::Int)
+        tag_type = Symbol("$(from_loc)$(to_loc)_$(edge_number)_$(model_name)_$(id)")
+        @eval type = EdgeAutomatonGandF{$(Meta.quot(tag_type))}
+        return @eval($type)
     end
 
     ## check_constraints & update_state!
     @everywhere @eval begin
+    #return quote
         istrue(val::Float64) = convert(Bool, val)
         ## Edges check constraint and update state functions
 
         # l0G loc
         # l0G => l1G
-        #struct $(edge_name(:l0G, :l1G, 1)) <: $(edge_type) transitions::TransitionSet end
-        $(check_constraints(:l0G, :l1G, 1))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = true
-        $(update_state!(:l0G, :l1G, 1))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = 
+        #struct $(generate_edge_type(:l0G, :l1G, 1)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end
+        $(check_constraints)(edge::$(generate_edge_type(:l0G, :l1G, 1)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = true
+        $(update_state!)(edge::$(generate_edge_type(:l0G, :l1G, 1)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = 
         (S_values[$(to_idx(:d))] = 0;
          S_values[$(to_idx(:n))] = x[$(idx_obs_var_G)];
          S_values[$(to_idx(:in))] = true;
@@ -91,125 +84,125 @@ function create_automaton_G_and_F(m::ContinuousTimeModel, x1::Float64, x2::Float
 
         # l1G loc
         # l1G => l3G
-        #struct $(edge_name(:l1G, :l3G, 1)) <: $(edge_type) transitions::TransitionSet end
-        $(check_constraints(:l1G, :l3G, 1))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = 
+        #struct $(generate_edge_type(:l1G, :l3G, 1)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end
+        $(check_constraints)(edge::$(generate_edge_type(:l1G, :l3G, 1)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = 
         S_time <= $t1 && 
         S_values[$(to_idx(:n))] < $x1 || S_values[$(to_idx(:n))] > $x2
-        $(update_state!(:l1G, :l3G, 1))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = 
+        $(update_state!)(edge::$(generate_edge_type(:l1G, :l3G, 1)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = 
         (S_values[$(to_idx(:d))] = min(abs($x1 - S_values[$(to_idx(:n))]), abs($x2 - S_values[$(to_idx(:n))]));
          S_values[$(to_idx(:in))] = false;
          :l3G)
 
-        #struct $(edge_name(:l1G, :l3G, 2)) <: $(edge_type) transitions::TransitionSet end
-        $(check_constraints(:l1G, :l3G, 2))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = 
+        #struct $(generate_edge_type(:l1G, :l3G, 2)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end
+        $(check_constraints)(edge::$(generate_edge_type(:l1G, :l3G, 2)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = 
         (S_time <= $t1) && 
         ($x1 <= S_values[$(to_idx(:n))] <= $x2)
-        $(update_state!(:l1G, :l3G, 2))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = 
+        $(update_state!)(edge::$(generate_edge_type(:l1G, :l3G, 2)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = 
         (S_values[$(to_idx(:d))] = 0;
          S_values[$(to_idx(:in))] = false;
          :l3G)
 
-        #struct $(edge_name(:l1G, :l3G, 3)) <: $(edge_type) transitions::TransitionSet end
-        $(check_constraints(:l1G, :l3G, 3))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = 
+        #struct $(generate_edge_type(:l1G, :l3G, 3)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end
+        $(check_constraints)(edge::$(generate_edge_type(:l1G, :l3G, 3)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = 
         !istrue(S_values[$(to_idx(:in))]) && 
         ($t1 <= S_time <= $t2) && 
         ($x1 <= S_values[$(to_idx(:n))] <= $x2)
-        $(update_state!(:l1G, :l3G, 3))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = 
+        $(update_state!)(edge::$(generate_edge_type(:l1G, :l3G, 3)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = 
         (S_values[$(to_idx(:d))] = S_values[$(to_idx(:d))] * (S_time - $t1);
          S_values[$(to_idx(:tprime))] = 0.0;
          :l3G)
 
-        #struct $(edge_name(:l1G, :l3G, 4)) <: $(edge_type) transitions::TransitionSet end
-        $(check_constraints(:l1G, :l3G, 4))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = 
+        #struct $(generate_edge_type(:l1G, :l3G, 4)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end
+        $(check_constraints)(edge::$(generate_edge_type(:l1G, :l3G, 4)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = 
         istrue(S_values[$(to_idx(:in))]) && 
         ($t1 <= S_time <= $t2) && 
         ($x1 <= S_values[$(to_idx(:n))] <= $x2)
-        $(update_state!(:l1G, :l3G, 4))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = 
+        $(update_state!)(edge::$(generate_edge_type(:l1G, :l3G, 4)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = 
         (S_values[$(to_idx(:tprime))] = 0.0;
          :l3G)
 
         # l1G => l4G
-        #struct $(edge_name(:l1G, :l4G, 1)) <: $(edge_type) transitions::TransitionSet end
-        $(check_constraints(:l1G, :l4G, 1))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = 
+        #struct $(generate_edge_type(:l1G, :l4G, 1)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end
+        $(check_constraints)(edge::$(generate_edge_type(:l1G, :l4G, 1)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = 
         !istrue(S_values[$(to_idx(:in))]) && 
         ($t1 <= S_time <= $t2) && 
         (S_values[$(to_idx(:n))] < $x1 || S_values[$(to_idx(:n))] > $x2)
-        $(update_state!(:l1G, :l4G, 1))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = 
+        $(update_state!)(edge::$(generate_edge_type(:l1G, :l4G, 1)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = 
         (S_values[$(to_idx(:d))] = S_values[$(to_idx(:d))] + S_values[$(to_idx(:d))] * (S_time - $t1);
          :l4G)
 
-        #struct $(edge_name(:l1G, :l4G, 2)) <: $(edge_type) transitions::TransitionSet end
-        $(check_constraints(:l1G, :l4G, 2))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = 
+        #struct $(generate_edge_type(:l1G, :l4G, 2)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end
+        $(check_constraints)(edge::$(generate_edge_type(:l1G, :l4G, 2)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = 
         istrue(S_values[$(to_idx(:in))]) && 
         ($t1 <= S_time <= $t2) && 
         (S_values[$(to_idx(:n))] < $x1 || S_values[$(to_idx(:n))] > $x2)
-        $(update_state!(:l1G, :l4G, 2))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = 
+        $(update_state!)(edge::$(generate_edge_type(:l1G, :l4G, 2)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = 
         (:l4G)
 
         # l1G => l2G
         #=
-        #struct $(edge_name(:l1G, :l2G, 3)) <: $(edge_type) transitions::TransitionSet end
-        $(check_constraints(:l1G, :l2G, 3))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = 
+        #struct $(generate_edge_type(:l1G, :l2G, 3)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end
+        $(check_constraints)(edge::$(generate_edge_type(:l1G, :l2G, 3)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = 
         istrue(S_values[$(to_idx(:isabs))]) && 
         S_time <= $t1
-        $(update_state!(:l1G, :l2G, 3))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = 
+        $(update_state!)(edge::$(generate_edge_type(:l1G, :l2G, 3)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = 
         (S_values[$(to_idx(:d))] = ($t2 - $t1) * min(abs($x1 - S_values[$(to_idx(:n))]), abs($x2 - S_values[$(to_idx(:n))]));
         :l2G)
 
-        #struct $(edge_name(:l1G, :l2G, 4)) <: $(edge_type) transitions::TransitionSet end
-        $(check_constraints(:l1G, :l2G, 4))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = 
+        #struct $(generate_edge_type(:l1G, :l2G, 4)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end
+        $(check_constraints)(edge::$(generate_edge_type(:l1G, :l2G, 4)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = 
         istrue(S_values[$(to_idx(:isabs))]) && 
         ($t1 <= S_time <= $t2)
-        $(update_state!(:l1G, :l2G, 4))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = 
+        $(update_state!)(edge::$(generate_edge_type(:l1G, :l2G, 4)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = 
         (S_values[$(to_idx(:d))] = S_values[$(to_idx(:d))] + ($t2 - S_time) * min(abs($x1 - S_values[$(to_idx(:n))]), abs($x2 - S_values[$(to_idx(:n))]));
         :l2G)
 
-        #struct $(edge_name(:l1G, :l2G, 1)) <: $(edge_type) transitions::TransitionSet end
-        $(check_constraints(:l1G, :l2G, 1))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = 
+        #struct $(generate_edge_type(:l1G, :l2G, 1)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end
+        $(check_constraints)(edge::$(generate_edge_type(:l1G, :l2G, 1)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = 
         istrue(S_values[$(to_idx(:in))]) && 
         S_time >= $t2
-        $(update_state!(:l1G, :l2G, 1))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = 
+        $(update_state!)(edge::$(generate_edge_type(:l1G, :l2G, 1)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = 
         (:l2G)
 
-        #struct $(edge_name(:l1G, :l2G, 2)) <: $(edge_type) transitions::TransitionSet end
-        $(check_constraints(:l1G, :l2G, 2))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = 
+        #struct $(generate_edge_type(:l1G, :l2G, 2)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end
+        $(check_constraints)(edge::$(generate_edge_type(:l1G, :l2G, 2)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = 
         !istrue(S_values[$(to_idx(:in))]) && 
         S_time >= $t2
-        $(update_state!(:l1G, :l2G, 2))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = 
+        $(update_state!)(edge::$(generate_edge_type(:l1G, :l2G, 2)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = 
         (S_values[$(to_idx(:d))] = S_values[$(to_idx(:d))] * ($t2 - $t1);
         :l2G)
         =#
 
         # l3G loc
         # l3G => l1G
-        #struct $(edge_name(:l3G, :l1G, 1)) <: $(edge_type) transitions::TransitionSet end
-        $(check_constraints(:l3G, :l1G, 1))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = true
-        $(update_state!(:l3G, :l1G, 1))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = 
+        #struct $(generate_edge_type(:l3G, :l1G, 1)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end
+        $(check_constraints)(edge::$(generate_edge_type(:l3G, :l1G, 1)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = true
+        $(update_state!)(edge::$(generate_edge_type(:l3G, :l1G, 1)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = 
         (S_values[$(to_idx(:n))] = x[$(idx_obs_var_G)];
          S_values[$(to_idx(:isabs))] = $(m.isabsorbing)(p, x);
          :l1G)
 
         # l3G => l2G
-        #struct $(edge_name(:l3G, :l2G, 2)) <: $(edge_type) transitions::TransitionSet end
-        $(check_constraints(:l3G, :l2G, 2))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = 
+        #struct $(generate_edge_type(:l3G, :l2G, 2)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end
+        $(check_constraints)(edge::$(generate_edge_type(:l3G, :l2G, 2)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = 
         istrue(S_values[$(to_idx(:in))]) && 
         (S_time >= $t2 || istrue(S_values[$(to_idx(:isabs))]))
-        $(update_state!(:l3G, :l2G, 2))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = 
+        $(update_state!)(edge::$(generate_edge_type(:l3G, :l2G, 2)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = 
         (S_values[$(to_idx(:d))] = S_values[$(to_idx(:d))] * ($t2 - $t1);
          :l2G)
 
-        #struct $(edge_name(:l3G, :l2G, 1)) <: $(edge_type) transitions::TransitionSet end
-        $(check_constraints(:l3G, :l2G, 1))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = 
+        #struct $(generate_edge_type(:l3G, :l2G, 1)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end
+        $(check_constraints)(edge::$(generate_edge_type(:l3G, :l2G, 1)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = 
         !istrue(S_values[$(to_idx(:in))]) && 
         (S_time >= $t2 || istrue(S_values[$(to_idx(:isabs))]))
-        $(update_state!(:l3G, :l2G, 1))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = 
+        $(update_state!)(edge::$(generate_edge_type(:l3G, :l2G, 1)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = 
         (:l2G)
 
         # l4G loc
         # l4G => l1G
-        #struct $(edge_name(:l4G, :l1G, 1)) <: $(edge_type) transitions::TransitionSet end
-        $(check_constraints(:l4G, :l1G, 1))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = true
-        $(update_state!(:l4G, :l1G, 1))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = 
+        #struct $(generate_edge_type(:l4G, :l1G, 1)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end
+        $(check_constraints)(edge::$(generate_edge_type(:l4G, :l1G, 1)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = true
+        $(update_state!)(edge::$(generate_edge_type(:l4G, :l1G, 1)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = 
         (S_values[$(to_idx(:d))] = S_values[$(to_idx(:d))] + S_values[$(to_idx(:tprime))] * min(abs($x1 - S_values[$(to_idx(:n))]), abs($x2 - S_values[$(to_idx(:n))]));
          S_values[$(to_idx(:tprime))] = 0.0;
          S_values[$(to_idx(:n))] = x[$(idx_obs_var_G)];
@@ -218,25 +211,25 @@ function create_automaton_G_and_F(m::ContinuousTimeModel, x1::Float64, x2::Float
          :l1G)
 
         # l4G => l2G
-        #struct $(edge_name(:l4G, :l2G, 1)) <: $(edge_type) transitions::TransitionSet end
-        $(check_constraints(:l4G, :l2G, 1))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = 
+        #struct $(generate_edge_type(:l4G, :l2G, 1)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end
+        $(check_constraints)(edge::$(generate_edge_type(:l4G, :l2G, 1)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = 
         (istrue(S_values[$(to_idx(:isabs))]))
-        $(update_state!(:l4G, :l2G, 1))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = 
+        $(update_state!)(edge::$(generate_edge_type(:l4G, :l2G, 1)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = 
         (S_values[$(to_idx(:d))] = S_values[$(to_idx(:d))] +  ($t2 - S_time) * min(abs($x1 - S_values[$(to_idx(:n))]), abs($x2 - S_values[$(to_idx(:n))]));
          :l2G)
 
-        #struct $(edge_name(:l4G, :l2G, 2)) <: $(edge_type) transitions::TransitionSet end
-        $(check_constraints(:l4G, :l2G, 2))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = 
+        #struct $(generate_edge_type(:l4G, :l2G, 2)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end
+        $(check_constraints)(edge::$(generate_edge_type(:l4G, :l2G, 2)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = 
         (S_time >= $t2)
-        $(update_state!(:l4G, :l2G, 2))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = 
+        $(update_state!)(edge::$(generate_edge_type(:l4G, :l2G, 2)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = 
         (S_values[$(to_idx(:d))] = S_values[$(to_idx(:d))] +  S_values[$(to_idx(:tprime))] * min(abs($x1 - S_values[$(to_idx(:n))]), abs($x2 - S_values[$(to_idx(:n))]));
          :l2G)
 
 
         # Connection between the two automata: l2G => l1F
-        #struct $(edge_name(:l2G, :l1F, 1)) <: $(edge_type) transitions::TransitionSet end
-        $(check_constraints(:l2G, :l1F, 1))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = true
-        $(update_state!(:l2G, :l1F, 1))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = 
+        #struct $(generate_edge_type(:l2G, :l1F, 1)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end
+        $(check_constraints)(edge::$(generate_edge_type(:l2G, :l1F, 1)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = true
+        $(update_state!)(edge::$(generate_edge_type(:l2G, :l1F, 1)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = 
         (S_values[$(to_idx(:n))] = x[$(idx_obs_var_F)];
          S_values[$(to_idx(:dprime))] = Inf;
          S_values[$(to_idx(:isabs))] = $(m.isabsorbing)(p, x);
@@ -244,77 +237,77 @@ function create_automaton_G_and_F(m::ContinuousTimeModel, x1::Float64, x2::Float
 
         # l1F loc : we con#struct  the edges of the form l1F => (..)
         # l1F => l2F
-        #struct $(edge_name(:l1F, :l2F, 1)) <: $(edge_type) transitions::TransitionSet end
-        $(check_constraints(:l1F, :l2F, 1))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = 
+        #struct $(generate_edge_type(:l1F, :l2F, 1)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end
+        $(check_constraints)(edge::$(generate_edge_type(:l1F, :l2F, 1)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = 
         S_time >= $t3 &&
         S_values[$(to_idx(:dprime))] == 0 
-        $(update_state!(:l1F, :l2F, 1))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = 
+        $(update_state!)(edge::$(generate_edge_type(:l1F, :l2F, 1)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = 
         (#S_values[$(to_idx(:dprime))] = 0;
          :l2F)
 
-        #struct $(edge_name(:l1F, :l2F, 2)) <: $(edge_type) transitions::TransitionSet end
-        $(check_constraints(:l1F, :l2F, 2))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = 
+        #struct $(generate_edge_type(:l1F, :l2F, 2)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end
+        $(check_constraints)(edge::$(generate_edge_type(:l1F, :l2F, 2)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = 
         (S_time >= $t4) && 
         (S_values[$(to_idx(:n))] < $x3 || S_values[$(to_idx(:n))] > $x4)
-        $(update_state!(:l1F, :l2F, 2))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = 
+        $(update_state!)(edge::$(generate_edge_type(:l1F, :l2F, 2)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = 
         (#S_values[$(to_idx(:dprime))] = min(abs(S_values[$(to_idx(:n))] - $x3), abs(S_values[$(to_idx(:n))] - $x4));
          S_values[$(to_idx(:d))] = S_values[$(to_idx(:d))] + S_values[$(to_idx(:dprime))];
          :l2F)
         #=
-        #struct $(edge_name(:l1F, :l2F, 3)) <: $(edge_type) transitions::TransitionSet end
-        $(check_constraints(:l1F, :l2F, 3))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = 
+        #struct $(generate_edge_type(:l1F, :l2F, 3)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end
+        $(check_constraints)(edge::$(generate_edge_type(:l1F, :l2F, 3)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = 
         istrue(S_values[$(to_idx(:isabs))]) && S_time <= $t4
-        $(update_state!(:l1F, :l2F, 3))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = 
+        $(update_state!)(edge::$(generate_edge_type(:l1F, :l2F, 3)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = 
         (S_values[$(to_idx(:d))] = S_values[$(to_idx(:d))] + S_values[$(to_idx(:dprime))];
         :l2F)
 
-        #struct $(edge_name(:l1F, :l2F, 4)) <: $(edge_type) transitions::TransitionSet end
-        $(check_constraints(:l1F, :l2F, 4))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = 
+        #struct $(generate_edge_type(:l1F, :l2F, 4)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end
+        $(check_constraints)(edge::$(generate_edge_type(:l1F, :l2F, 4)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = 
         S_time >= $t3 &&
         S_values[$(to_idx(:dprime))] == 0 
-        $(update_state!(:l1F, :l2F, 4))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = 
+        $(update_state!)(edge::$(generate_edge_type(:l1F, :l2F, 4)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = 
         (:l2F)
         =#
 
         # l1F => l3F
-        #struct $(edge_name(:l1F, :l3F, 1)) <: $(edge_type) transitions::TransitionSet end
-        $(check_constraints(:l1F, :l3F, 1))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = 
+        #struct $(generate_edge_type(:l1F, :l3F, 1)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end
+        $(check_constraints)(edge::$(generate_edge_type(:l1F, :l3F, 1)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = 
         (S_time <= $t3) &&
         (S_values[$(to_idx(:n))] < $x3 || S_values[$(to_idx(:n))] > $x4)
-        $(update_state!(:l1F, :l3F, 1))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = 
+        $(update_state!)(edge::$(generate_edge_type(:l1F, :l3F, 1)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = 
         (S_values[$(to_idx(:dprime))] = min(sqrt((S_time - $t3)^2 + (S_values[$(to_idx(:n))] - $x4)^2), 
                                             sqrt((S_time - $t3)^2 + (S_values[$(to_idx(:n))] - $x3)^2));
          :l3F)
 
-        #struct $(edge_name(:l1F, :l3F, 2)) <: $(edge_type) transitions::TransitionSet end
-        $(check_constraints(:l1F, :l3F, 2))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = 
+        #struct $(generate_edge_type(:l1F, :l3F, 2)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end
+        $(check_constraints)(edge::$(generate_edge_type(:l1F, :l3F, 2)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = 
         ($x3 <= S_values[$(to_idx(:n))] <= $x4)
-        $(update_state!(:l1F, :l3F, 2))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = 
+        $(update_state!)(edge::$(generate_edge_type(:l1F, :l3F, 2)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = 
         (S_values[$(to_idx(:dprime))] = 0;
          :l3F)
 
-        #struct $(edge_name(:l1F, :l3F, 3)) <: $(edge_type) transitions::TransitionSet end
-        $(check_constraints(:l1F, :l3F, 3))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = 
+        #struct $(generate_edge_type(:l1F, :l3F, 3)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end
+        $(check_constraints)(edge::$(generate_edge_type(:l1F, :l3F, 3)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = 
         (S_time >= $t3) &&
         (S_values[$(to_idx(:n))] < $x3 || S_values[$(to_idx(:n))] > $x4)
-        $(update_state!(:l1F, :l3F, 3))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = 
+        $(update_state!)(edge::$(generate_edge_type(:l1F, :l3F, 3)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = 
         (S_values[$(to_idx(:dprime))] = min(S_values[$(to_idx(:dprime))], min(abs(S_values[$(to_idx(:n))] - $x3), abs(S_values[$(to_idx(:n))] - $x4)));
          :l3F)
 
         # l3F loc
         # l3F => l1F
-        #struct $(edge_name(:l3F, :l1F, 1)) <: $(edge_type) transitions::TransitionSet end
-        $(check_constraints(:l3F, :l1F, 1))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = true
-        $(update_state!(:l3F, :l1F, 1))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = 
+        #struct $(generate_edge_type(:l3F, :l1F, 1)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end
+        $(check_constraints)(edge::$(generate_edge_type(:l3F, :l1F, 1)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = true
+        $(update_state!)(edge::$(generate_edge_type(:l3F, :l1F, 1)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = 
         (S_values[$(to_idx(:n))] = x[$(idx_obs_var_F)];
          S_values[$(to_idx(:isabs))] = $(m.isabsorbing)(p, x);
          :l1F)
 
         # l3F => l2F
-        #struct $(edge_name(:l3F, :l2F, 1)) <: $(edge_type) transitions::TransitionSet end
-        $(check_constraints(:l3F, :l2F, 1))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = 
+        #struct $(generate_edge_type(:l3F, :l2F, 1)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end
+        $(check_constraints)(edge::$(generate_edge_type(:l3F, :l2F, 1)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = 
         (S_time >= $t4 || istrue(S_values[$(to_idx(:isabs))]))
-        $(update_state!(:l3F, :l2F, 1))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = 
+        $(update_state!)(edge::$(generate_edge_type(:l3F, :l2F, 1)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = 
         (S_values[$(to_idx(:d))] = S_values[$(to_idx(:d))] + S_values[$(to_idx(:dprime))];
          :l2F)
     end
@@ -327,113 +320,91 @@ function create_automaton_G_and_F(m::ContinuousTimeModel, x1::Float64, x2::Float
 
         # l0G loc
         # l0G => l1G
-        edge1 = EdgeAutomatonGandF(nothing, $(check_constraints(:l0G, :l1G, 1)), $(update_state!(:l0G, :l1G, 1)))
+        edge1 = $(generate_edge_type(:l0G, :l1G, 1))(nothing)
         map_edges[:l0G][:l1G] = [edge1]
 
         # l1G => l3G
-        edge1 = EdgeAutomatonGandF(nothing, $(check_constraints(:l1G, :l3G, 1)), $(update_state!(:l1G, :l3G, 1)))
-        edge2 = EdgeAutomatonGandF(nothing, $(check_constraints(:l1G, :l3G, 2)), $(update_state!(:l1G, :l3G, 2)))
-        edge3 = EdgeAutomatonGandF(nothing, $(check_constraints(:l1G, :l3G, 3)), $(update_state!(:l1G, :l3G, 3)))
-        edge4 = EdgeAutomatonGandF(nothing, $(check_constraints(:l1G, :l3G, 4)), $(update_state!(:l1G, :l3G, 4)))
+        edge1 = $(generate_edge_type(:l1G, :l3G, 1))(nothing)
+        edge2 = $(generate_edge_type(:l1G, :l3G, 2))(nothing)
+        edge3 = $(generate_edge_type(:l1G, :l3G, 3))(nothing)
+        edge4 = $(generate_edge_type(:l1G, :l3G, 4))(nothing)
         map_edges[:l1G][:l3G] = [edge1, edge2, edge3, edge4]
 
         # l1G => l4G
-        edge1 = EdgeAutomatonGandF(nothing, $(check_constraints(:l1G, :l4G, 1)), $(update_state!(:l1G, :l4G, 1)))
-        edge2 = EdgeAutomatonGandF(nothing, $(check_constraints(:l1G, :l4G, 2)), $(update_state!(:l1G, :l4G, 2)))
+        edge1 = $(generate_edge_type(:l1G, :l4G, 1))(nothing)
+        edge2 = $(generate_edge_type(:l1G, :l4G, 2))(nothing)
         map_edges[:l1G][:l4G] = [edge1, edge2]
 
         # l1G => l2G
         #=
-        edge1 = EdgeAutomatonGandF(nothing, $(check_constraints(:l1G, :l2G, 1)), $(update_state!(:l1G, :l2G, 1)))
-        edge2 = EdgeAutomatonGandF(nothing, $(check_constraints(:l1G, :l2G, 2)), $(update_state!(:l1G, :l2G, 2)))
-        edge3 = EdgeAutomatonGandF(nothing, $(check_constraints(:l1G, :l2G, 3)), $(update_state!(:l1G, :l2G, 3)))
-        edge4 = EdgeAutomatonGandF(nothing, $(check_constraints(:l1G, :l2G, 4)), $(update_state!(:l1G, :l2G, 4)))
+        edge1 = $(generate_edge_type(:l1G, :l2G, 1))(nothing)
+        edge2 = $(generate_edge_type(:l1G, :l2G, 2))(nothing)
+        edge3 = $(generate_edge_type(:l1G, :l2G, 3))(nothing)
+        edge4 = $(generate_edge_type(:l1G, :l2G, 4))(nothing)
         map_edges[:l1G][:l2G] = [edge3, edge4, edge1, edge2]
         =#
 
         # l3G loc
         # l3G => l1G
-        edge1 = EdgeAutomatonGandF([:ALL], $(check_constraints(:l3G, :l1G, 1)), $(update_state!(:l3G, :l1G, 1)))
+        edge1 = $(generate_edge_type(:l3G, :l1G, 1))([:ALL])
         map_edges[:l3G][:l1G] = [edge1]
 
         # l3G => l2G
-        edge1 = EdgeAutomatonGandF(nothing, $(check_constraints(:l3G, :l2G, 1)), $(update_state!(:l3G, :l2G, 1)))
-        edge2 = EdgeAutomatonGandF(nothing, $(check_constraints(:l3G, :l2G, 2)), $(update_state!(:l3G, :l2G, 2)))
+        edge1 = $(generate_edge_type(:l3G, :l2G, 1))(nothing)
+        edge2 = $(generate_edge_type(:l3G, :l2G, 2))(nothing)
         map_edges[:l3G][:l2G] = [edge1, edge2]
 
         # l4 loc
         # l4G => l1G
-        edge1 = EdgeAutomatonGandF([:ALL], $(check_constraints(:l4G, :l1G, 1)), $(update_state!(:l4G, :l1G, 1)))
+        edge1 = $(generate_edge_type(:l4G, :l1G, 1))([:ALL])
         map_edges[:l4G][:l1G] = [edge1]
 
         # l4G => l2G
-        edge1 = EdgeAutomatonGandF(nothing, $(check_constraints(:l4G, :l2G, 1)), $(update_state!(:l4G, :l2G, 1)))
-        edge2 = EdgeAutomatonGandF(nothing, $(check_constraints(:l4G, :l2G, 2)), $(update_state!(:l4G, :l2G, 2)))
+        edge1 = $(generate_edge_type(:l4G, :l2G, 1))(nothing)
+        edge2 = $(generate_edge_type(:l4G, :l2G, 2))(nothing)
         map_edges[:l4G][:l2G] = [edge1,edge2]
 
         # l2G loc
         # l2G => l1F : Transition from autF to autG
-        edge1 = EdgeAutomatonGandF(nothing, $(check_constraints(:l2G, :l1F, 1)), $(update_state!(:l2G, :l1F, 1)))
+        edge1 = $(generate_edge_type(:l2G, :l1F, 1))(nothing)
         map_edges[:l2G][:l1F] = [edge1]
 
         # l1F loc
         # l1F => l3F
-        edge1 = EdgeAutomatonGandF(nothing, $(check_constraints(:l1F, :l2F, 1)), $(update_state!(:l1F, :l2F, 1)))
-        edge2 = EdgeAutomatonGandF(nothing, $(check_constraints(:l1F, :l2F, 2)), $(update_state!(:l1F, :l2F, 2)))
+        edge1 = $(generate_edge_type(:l1F, :l2F, 1))(nothing)
+        edge2 = $(generate_edge_type(:l1F, :l2F, 2))(nothing)
         map_edges[:l1F][:l2F] = [edge1, edge2]
-        #edge3 = EdgeAutomatonGandF(nothing, $(check_constraints(:l1F, :l2F, 3)), $(update_state!(:l1F, :l2F, 3)))
-        #edge4 = EdgeAutomatonGandF(nothing, $(check_constraints(:l1F, :l2F, 4)), $(update_state!(:l1F, :l2F, 4)))
+        #edge3 = $(generate_edge_type(:l1F, :l2F, 3))(nothing)
+        #edge4 = $(generate_edge_type(:l1F, :l2F, 4))(nothing)
         #map_edges[:l1F][:l2F] = [edge1, edge4, edge3, edge2]
 
         # l1F => l3F
-        edge1 = EdgeAutomatonGandF(nothing, $(check_constraints(:l1F, :l3F, 1)), $(update_state!(:l1F, :l3F, 1)))
-        edge2 = EdgeAutomatonGandF(nothing, $(check_constraints(:l1F, :l3F, 2)), $(update_state!(:l1F, :l3F, 2)))
-        edge3 = EdgeAutomatonGandF(nothing, $(check_constraints(:l1F, :l3F, 3)), $(update_state!(:l1F, :l3F, 3)))
+        edge1 = $(generate_edge_type(:l1F, :l3F, 1))(nothing)
+        edge2 = $(generate_edge_type(:l1F, :l3F, 2))(nothing)
+        edge3 = $(generate_edge_type(:l1F, :l3F, 3))(nothing)
         map_edges[:l1F][:l3F] = [edge1, edge2, edge3]
 
         # l3F loc
         # l3F => l1F
-        edge1 = EdgeAutomatonGandF([:ALL], $(check_constraints(:l3F, :l1F, 1)), $(update_state!(:l3F, :l1F, 1)))
+        edge1 = $(generate_edge_type(:l3F, :l1F, 1))([:ALL])
         map_edges[:l3F][:l1F] = [edge1]
 
         # l3F => l2F
-        edge1 = EdgeAutomatonGandF(nothing, $(check_constraints(:l3F, :l2F, 1)), $(update_state!(:l3F, :l2F, 1)))    
+        edge1 = $(generate_edge_type(:l3F, :l2F, 1))(nothing)    
         map_edges[:l3F][:l2F] = [edge1]
     end
 
-    ## Create data separately
-    map_edges_transitions = Dict{Symbol, Dict{Symbol,Vector{TransitionSet}}}()
-    map_edges_check_constraints = Dict{Symbol, Dict{Symbol,Vector{Function}}}()
-    map_edges_update_state = Dict{Symbol, Dict{Symbol,Vector{Function}}}()
-    for from_loc in keys(map_edges)
-        map_edges_transitions[from_loc] = Dict{Symbol,Vector{TransitionSet}}()
-        map_edges_check_constraints[from_loc] = Dict{Symbol,Vector{Function}}()
-        map_edges_update_state[from_loc] = Dict{Symbol,Vector{Function}}()
-        for to_loc in keys(map_edges[from_loc])
-            map_edges_transitions[from_loc][to_loc] = TransitionSet[]
-            map_edges_check_constraints[from_loc][to_loc] = Function[]
-            map_edges_update_state[from_loc][to_loc] = Function[]
-            for edge in map_edges[from_loc][to_loc]
-                push!(map_edges_transitions[from_loc][to_loc], edge.transitions)
-                push!(map_edges_check_constraints[from_loc][to_loc], edge.check_constraints)
-                push!(map_edges_update_state[from_loc][to_loc], edge.update_state!)
-            end
-        end
-    end
-
     ## Constants
     constants = Dict{Symbol,Float64}(:x1 => x1,  :x2 => x2, :t1 => t1, :t2 => t2,
                                      :x3 => x3,  :x4 => x4, :t3 => t3, :t4 => t4)
 
-    # Updating types and simulation method
+    # Updating types and simulation methods
     @everywhere @eval $(MarkovProcesses.generate_code_synchronized_model_type_def(model_name, lha_name))
-    @everywhere @eval $(MarkovProcesses.new_generate_code_next_state(lha_name, edge_type))
+    @everywhere @eval $(MarkovProcesses.generate_code_next_state(lha_name, edge_type, check_constraints, update_state!))
     @everywhere @eval $(MarkovProcesses.generate_code_synchronized_simulation(model_name, lha_name, edge_type, m.f!, m.isabsorbing))
 
     A = AutomatonGandF(m.transitions, locations, Λ_F, locations_init, locations_final, 
-                       map_var_automaton_idx, flow, map_edges, 
-                       map_edges_transitions, map_edges_check_constraints, map_edges_update_state,
-                       constants, m.map_var_idx)
+                       map_var_automaton_idx, flow, map_edges, constants, m.map_var_idx)
     return A
 end
 
diff --git a/core/common.jl b/core/common.jl
index c22a5837a5d29bee0bda72624af2abb8dd6a2f8b..4a501df49cbc18fc0bfc4bfc8eff803b0d11246e 100644
--- a/core/common.jl
+++ b/core/common.jl
@@ -11,7 +11,6 @@ abstract type Edge end
 const VariableModel = Symbol
 const ParameterModel = Symbol
 const Transition = Union{Symbol,Nothing}
-const TransitionSet = Union{Vector{Symbol},Nothing}
 const Location = Symbol
 const VariableAutomaton = Symbol
 
@@ -56,9 +55,6 @@ function generate_code_lha_type_def(lha_name::Symbol, edge_type::Symbol)
             map_var_automaton_idx::Dict{VariableAutomaton,Int} # nvar keys : str_var => idx in values
             flow::Dict{Location,Vector{Float64}} # output of length nvar
             map_edges::Dict{Location, Dict{Location,Vector{$(edge_type)}}}
-            map_edges_transitions::Dict{Location, Dict{Location,Vector{TransitionSet}}}
-            map_edges_check_constraints::Dict{Location, Dict{Location,Vector{Function}}}
-            map_edges_update_state::Dict{Location, Dict{Location,Vector{Function}}}
             constants::Dict{Symbol,Float64}
             map_var_model_idx::Dict{VariableModel,Int} # of dim d (of a model)
         end
diff --git a/core/lha.jl b/core/lha.jl
index 30fd1ec66047173409e082a96cc655aa51ec1a67..8f5fcc5f1d9514aae63417bee8a3c8e96071086c 100644
--- a/core/lha.jl
+++ b/core/lha.jl
@@ -90,234 +90,8 @@ function init_state(A::LHA, x0::Vector{Int}, t0::Float64)
     return S0
 end
 
-function generate_code_next_state_with_dicts_lha(lha_name::Symbol, edge_type::Symbol)
-    
-    return quote 
-        # A push! method implementend by myself because of preallocation of edge_candidates
-        function _push_edge!(edge_id_candidates::Vector{Int}, target_loc_candidates::Vector{Symbol}, 
-                             edge_id::Int, target_loc::Symbol, nbr_candidates::Int)
-            if nbr_candidates < length(edge_id_candidates)
-                 edge_id_candidates[nbr_candidates+1] = edge_id
-                 target_loc_candidates[nbr_candidates+1] = target_loc
-            else
-                push!(edge_id_candidates, edge_id)
-                push!(target_loc_candidates, target_loc)
-            end
-        end
-
-        function _find_edge_candidates!(edge_id_candidates::Vector{Int}, target_loc_candidates::Vector{Symbol},
-                                        dict_transitions_from_current_loc::Dict{Location,Vector{TransitionSet}},
-                                        dict_check_constraints_from_current_loc::Dict{Location,Vector{Function}},
-                                        Λ::Dict{Location,Function},
-                                        S_time::Float64, S_values::Vector{Float64},
-                                        x::Vector{Int}, p::Vector{Float64},
-                                        only_asynchronous::Bool)
-            nbr_candidates = 0
-            for target_loc in keys(dict_transitions_from_current_loc)
-                if !Λ[target_loc](x) continue end
-                for i = eachindex(dict_transitions_from_current_loc[target_loc])
-                    check_constraints_edge = dict_check_constraints_from_current_loc[target_loc][i]
-                    if check_constraints_edge(S_time, S_values, x, p)
-                        transitions = dict_transitions_from_current_loc[target_loc][i]
-                        if transitions == nothing
-                            _push_edge!(edge_id_candidates, target_loc_candidates, i, target_loc, nbr_candidates)
-                            nbr_candidates += 1
-                            return nbr_candidates
-                        else
-                            if !only_asynchronous
-                                _push_edge!(edge_id_candidates, target_loc_candidates, i, target_loc, nbr_candidates)
-                                nbr_candidates += 1
-                            end
-                        end
-                    end
-                end
-            end
-            return nbr_candidates
-        end
-
-        function _get_edge_index(edge_id_candidates::Vector{Int}, target_loc_candidates::Vector{Symbol}, nbr_candidates::Int,
-                                 dict_transitions_from_current_loc::Dict{Location,Vector{TransitionSet}},
-                                 detected_event::Bool, tr_nplus1::Transition)
-            ind_edge = 0
-            bool_event = detected_event
-            for i = 1:nbr_candidates
-                target_loc = target_loc_candidates[i]
-                edge_id = edge_id_candidates[i]
-                transitions = dict_transitions_from_current_loc[target_loc][edge_id]
-                # Asynchronous edge detection: we fire it
-                if transitions == nothing
-                    return (i, detected_event)
-                end
-                # Synchronous detection
-                if !detected_event && tr_nplus1 != nothing
-                    if (transitions[1] == :ALL) || (tr_nplus1 in transitions)
-                        ind_edge = i
-                        bool_event = true
-                    end
-                end
-            end
-            return (ind_edge, bool_event)
-        end
-
-        function next_state!(A::$(lha_name),
-                             ptr_loc_state::Vector{Symbol}, values_state::Vector{Float64}, ptr_time_state::Vector{Float64},
-                             xnplus1::Vector{Int}, tnplus1::Float64, tr_nplus1::Transition, 
-                             xn::Vector{Int}, p::Vector{Float64},
-                             edge_id_candidates::Vector{Int}, target_loc_candidates::Vector{Symbol}; verbose::Bool = false)
-            # En fait d'apres observation de Cosmos, après qu'on ait lu la transition on devrait stop.
-            detected_event::Bool = false
-            turns = 0
-            Λ = getfield(A, :Λ)
-            flow = getfield(A, :flow)
-            map_edges = A.map_edges
-            map_edges_transitions = A.map_edges_transitions
-            map_edges_check_constraints = A.map_edges_check_constraints
-            map_edges_update_state = A.map_edges_update_state
-            if verbose 
-                println("##### Begin next_state!")
-                @show xnplus1, tnplus1, tr_nplus1
-            end
-            # First, we check the asynchronous transitions
-            while true
-                turns += 1
-                if verbose @show turns end
-                #edge_candidates = empty!(edge_candidates) 
-                dict_transitions_from_current_loc = map_edges_transitions[ptr_loc_state[1]]
-                dict_check_constraints_from_current_loc = map_edges_check_constraints[ptr_loc_state[1]]
-                # Save all edges that satisfies transition predicate (asynchronous ones)
-                nbr_candidates = _find_edge_candidates!(edge_id_candidates, target_loc_candidates, 
-                                                        dict_transitions_from_current_loc, dict_check_constraints_from_current_loc,
-                                                        Λ, ptr_time_state[1], values_state, xn, p, true)
-                # Search the one we must chose, here the event is nothing because 
-                # we're not processing yet the next event
-                ind_edge, detected_event = _get_edge_index(edge_id_candidates, target_loc_candidates, nbr_candidates, 
-                                                           dict_transitions_from_current_loc,
-                                                           detected_event, nothing)
-                # Update the state with the chosen one (if it exists)
-                # Should be xn here
-                #first_round = false
-                if ind_edge > 0
-                    edge_target_loc = target_loc_candidates[ind_edge]
-                    edge_id = edge_id_candidates[ind_edge]
-                    firing_update_state! = map_edges_update_state[ptr_loc_state[1]][edge_target_loc][edge_id]
-                    ptr_loc_state[1] = firing_update_state!(ptr_time_state[1], values_state, xn, p)
-                else
-                    if verbose 
-                        println("No edge fired:")
-                        @show ind_edge, detected_event, nbr_candidates
-                    end
-                    break 
-                end
-                if verbose
-                    println("Edge fired:")
-                    @show edge_id_candidates, target_loc_candidates
-                    @show ind_edge, detected_event, nbr_candidates
-                    @show ptr_loc_state[1]
-                    @show ptr_time_state[1]
-                    @show values_state
-                    if turns == 500
-                        @warn "We've reached 500 turns"
-                    end
-                end
-                # For debug
-                #=
-                if turns > 100
-                println("Number of turns in next_state! is suspicious")
-                @show first_round, detected_event
-                @show length(edge_candidates)
-                @show tnplus1, tr_nplus1, xnplus1
-                @show edge_candidates
-                error("Unpredicted behavior automaton")
-                end
-                =#
-            end
-            if verbose 
-                println("Time flies with the flow...")
-            end
-            # Now time flies according to the flow
-            for i in eachindex(values_state)
-                 coeff_deriv = flow[ptr_loc_state[1]][i]
-                if coeff_deriv > 0
-                      values_state[i] += coeff_deriv*(tnplus1 - ptr_time_state[1])
-                end
-            end
-            ptr_time_state[1] = tnplus1
-            if verbose 
-                @show ptr_loc_state[1]
-                @show ptr_time_state[1]
-                @show values_state
-            end
-            # Now firing an edge according to the event 
-            while true
-                turns += 1
-                if verbose @show turns end
-                edges_from_current_loc = map_edges[ptr_loc_state[1]]
-                dict_transitions_from_current_loc = map_edges_transitions[ptr_loc_state[1]]
-                dict_check_constraints_from_current_loc = map_edges_check_constraints[ptr_loc_state[1]]
-                # Save all edges that satisfies transition predicate (synchronous ones)
-                nbr_candidates = _find_edge_candidates!(edge_id_candidates, target_loc_candidates,
-                                                        dict_transitions_from_current_loc, dict_check_constraints_from_current_loc,
-                                                        Λ, ptr_time_state[1], values_state, xnplus1, p, false)
-                # Search the one we must chose
-                ind_edge, detected_event = _get_edge_index(edge_id_candidates, target_loc_candidates, nbr_candidates, 
-                                                           dict_transitions_from_current_loc,
-                                                           detected_event, tr_nplus1)
-                # Update the state with the chosen one (if it exists)
-                if ind_edge > 0
-                    edge_target_loc = target_loc_candidates[ind_edge]
-                    edge_id = edge_id_candidates[ind_edge]
-                    firing_update_state! = map_edges_update_state[ptr_loc_state[1]][edge_target_loc][edge_id]
-                    ptr_loc_state[1] = firing_update_state!(ptr_time_state[1], values_state, xnplus1, p)
-                end
-                if ind_edge == 0 || detected_event
-                    if verbose 
-                        if detected_event    
-                            println("Synchronized with $(tr_nplus1)") 
-                            @show edge_id_candidates, target_loc_candidates
-                            @show ind_edge, detected_event, nbr_candidates
-                            @show detected_event
-                            @show ptr_loc_state[1]
-                            @show ptr_time_state[1]
-                            @show values_state
-                        else
-                            println("No edge fired")
-                        end
-                    end
-                    break 
-                end
-                if verbose
-                    @show edge_id_candidates, target_loc_candidates
-                    @show ind_edge, detected_event, nbr_candidates
-                    @show detected_event
-                    @show ptr_loc_state[1]
-                    @show ptr_time_state[1]
-                    @show values_state
-                    if turns == 500
-                        @warn "We've reached 500 turns"
-                    end
-                end
-                # For debug
-                #=
-                if turns > 100
-                println("Number of turns in next_state! is suspicious")
-                @show detected_event
-                @show length(edge_candidates)
-                @show tnplus1, tr_nplus1, xnplus1
-                @show edge_candidates
-                error("Unpredicted behavior automaton")
-                end
-                =#
-            end
-            if verbose 
-                println("##### End next_state!") 
-            end
-        end
-    end
-end
-
-############################################################################################################
-
-function generate_code_next_state(lha_name::Symbol, edge_type::Symbol)
+function generate_code_next_state(lha_name::Symbol, edge_type::Symbol, 
+                                  check_constraints::Symbol, update_state!::Symbol)
     
     return quote 
         # A push! method implementend by myself because of preallocation of edge_candidates
@@ -339,8 +113,8 @@ function generate_code_next_state(lha_name::Symbol, edge_type::Symbol)
             for target_loc in keys(edges_from_current_loc)
                 if !Λ[target_loc](x) continue end
                 for edge in edges_from_current_loc[target_loc]
-                    if edge.check_constraints(S_time, S_values, x, p)
-                        if edge.transitions == nothing
+                    if $(check_constraints)(edge, S_time, S_values, x, p)
+                        if getfield(edge, :transitions) == nothing
                             _push_edge!(edge_candidates, edge, nbr_candidates)
                             nbr_candidates += 1
                             return nbr_candidates
@@ -363,12 +137,13 @@ function generate_code_next_state(lha_name::Symbol, edge_type::Symbol)
             for i = 1:nbr_candidates
                 edge = edge_candidates[i]
                 # Asynchronous edge detection: we fire it
-                if edge.transitions == nothing
+                if getfield(edge, :transitions) == nothing
                     return (i, detected_event)
                 end
                 # Synchronous detection
                 if !detected_event && tr_nplus1 != nothing
-                    if (edge.transitions[1] == :ALL) || (tr_nplus1 in edge.transitions)
+                    if (getfield(edge, :transitions)[1] == :ALL) || 
+                        (tr_nplus1 in getfield(edge, :transitions))
                         ind_edge = i
                         bool_event = true
                     end
@@ -409,7 +184,7 @@ function generate_code_next_state(lha_name::Symbol, edge_type::Symbol)
                 #first_round = false
                 if ind_edge > 0
                     firing_edge = edge_candidates[ind_edge]
-                    ptr_loc_state[1] = firing_edge.update_state!(ptr_time_state[1], values_state, xn, p)
+                    ptr_loc_state[1] = $(update_state!)(firing_edge, ptr_time_state[1], values_state, xn, p)
                 else
                     if verbose println("No edge fired") end
                     break 
@@ -465,7 +240,7 @@ function generate_code_next_state(lha_name::Symbol, edge_type::Symbol)
                 # Update the state with the chosen one (if it exists)
                 if ind_edge > 0
                     firing_edge = edge_candidates[ind_edge]
-                    ptr_loc_state[1] = firing_edge.update_state!(ptr_time_state[1], values_state, xnplus1, p)
+                    ptr_loc_state[1] = $(update_state!)(firing_edge, ptr_time_state[1], values_state, xnplus1, p)
                 end
                 if ind_edge == 0 || detected_event
                     if verbose 
diff --git a/core/model.jl b/core/model.jl
index 9be33af0b5753618e4a1adb2b282781f6a979963..ef32b376a21b8addc241cab52d2ac0af2c7124f4 100644
--- a/core/model.jl
+++ b/core/model.jl
@@ -145,9 +145,7 @@ function generate_code_synchronized_simulation(model_name::Symbol, lha_name::Sym
             time_bound = getfield(m, :time_bound)
             buffer_size = getfield(m, :buffer_size)
             estim_min_states = getfield(m, :estim_min_states)
-            #edge_candidates = Vector{$(edge_type)}(undef, 2)
-            edge_id_candidates = zeros(Int, 2)
-            target_loc_candidates = Vector{Symbol}(undef, 2)
+            edge_candidates = Vector{$(edge_type)}(undef, 2)
             # First alloc
             full_values = Vector{Vector{Int}}(undef, getfield(m, :dim_state))
             for i = eachindex(full_values) full_values[i] = zeros(Int, estim_min_states) end
@@ -166,7 +164,7 @@ function generate_code_synchronized_simulation(model_name::Symbol, lha_name::Sym
             xn = copy(x0)
             tn = copy(t0) 
             next_state!(A, ptr_loc_state, values_state, ptr_time_state, 
-                        x0, t0, nothing, x0, p_sim, edge_id_candidates, target_loc_candidates; verbose = verbose)
+                        x0, t0, nothing, x0, p_sim, edge_candidates; verbose = verbose)
             isabsorbing::Bool = $(isabsorbing)(p_sim,xn)
             isacceptedLHA::Bool = isaccepted(ptr_loc_state[1], A)
             # Alloc of vectors where we stock n+1 values
@@ -182,7 +180,7 @@ function generate_code_synchronized_simulation(model_name::Symbol, lha_name::Sym
                 end
                 if isabsorbing && !isacceptedLHA
                     next_state!(A, ptr_loc_state, values_state, ptr_time_state, 
-                                xn, time_bound, nothing, xn, p_sim, edge_id_candidates, target_loc_candidates; verbose = verbose)
+                                xn, time_bound, nothing, xn, p_sim, edge_candidates; verbose = verbose)
                 end
                 setfield!(S, :loc, ptr_loc_state[1])
                 setfield!(S, :time, ptr_time_state[1])
@@ -197,7 +195,7 @@ function generate_code_synchronized_simulation(model_name::Symbol, lha_name::Sym
                     break
                 end
                 n += 1
-                next_state!(A, ptr_loc_state, values_state, ptr_time_state, vec_x, l_t[1], l_tr[1], xn, p_sim, edge_id_candidates, target_loc_candidates; verbose = verbose)
+                next_state!(A, ptr_loc_state, values_state, ptr_time_state, vec_x, l_t[1], l_tr[1], xn, p_sim, edge_candidates; verbose = verbose)
                 copyto!(xn, vec_x)
                 tn = l_t[1]
                 tr_n = l_tr[1]
@@ -216,7 +214,7 @@ function generate_code_synchronized_simulation(model_name::Symbol, lha_name::Sym
                 end
                 if isabsorbing && !isacceptedLHA
                     next_state!(A, ptr_loc_state, values_state, ptr_time_state, 
-                                xn, time_bound, nothing, xn, p_sim, edge_id_candidates, target_loc_candidates; verbose = verbose)
+                                xn, time_bound, nothing, xn, p_sim, edge_candidates; verbose = verbose)
                 end
                 setfield!(S, :loc, ptr_loc_state[1])
                 setfield!(S, :time, ptr_time_state[1])
@@ -241,7 +239,7 @@ function generate_code_synchronized_simulation(model_name::Symbol, lha_name::Sym
                         i -= 1
                         break
                     end
-                    next_state!(A, ptr_loc_state, values_state, ptr_time_state, vec_x, l_t[1], l_tr[1], xn, p_sim, edge_id_candidates, target_loc_candidates; verbose = verbose)
+                    next_state!(A, ptr_loc_state, values_state, ptr_time_state, vec_x, l_t[1], l_tr[1], xn, p_sim, edge_candidates; verbose = verbose)
                     copyto!(xn, vec_x)
                     tn = l_t[1]
                     tr_n = l_tr[1]
@@ -267,7 +265,7 @@ function generate_code_synchronized_simulation(model_name::Symbol, lha_name::Sym
             end
             if isabsorbing && !isacceptedLHA
                 next_state!(A, ptr_loc_state, values_state, ptr_time_state, 
-                            xn, time_bound, nothing, xn, p_sim, edge_id_candidates, target_loc_candidates; verbose = verbose)
+                            xn, time_bound, nothing, xn, p_sim, edge_candidates; verbose = verbose)
             end
             setfield!(S, :loc, ptr_loc_state[1])
             setfield!(S, :time, ptr_time_state[1])
@@ -282,15 +280,13 @@ function generate_code_synchronized_simulation(model_name::Symbol, lha_name::Sym
             ptr_loc_state = [S.loc]
             values_state = S.values
             ptr_time_state = [S.time]
-            #edge_candidates = Vector{$(edge_type)}(undef, 2)
-            edge_id_candidates = zeros(Int, 2)
-            target_loc_candidates = Vector{Symbol}(undef, 2)
+            edge_candidates = Vector{$(edge_type)}(undef, 2)
             # Values at time n
             n = 1
             xn = copy(x0)
             tn = copy(t0) 
             next_state!(A, ptr_loc_state, values_state, ptr_time_state, 
-                        x0, t0, nothing, x0, p_sim, edge_id_candidates, target_loc_candidates; verbose = verbose)
+                        x0, t0, nothing, x0, p_sim, edge_candidates; verbose = verbose)
             isabsorbing::Bool = $(isabsorbing)(p_sim,xn)
             isacceptedLHA::Bool = isaccepted(ptr_loc_state[1], A)
             # Alloc of vectors where we stock n+1 values
@@ -301,7 +297,7 @@ function generate_code_synchronized_simulation(model_name::Symbol, lha_name::Sym
             if isabsorbing || isacceptedLHA 
                 if !isacceptedLHA
                     next_state!(A, ptr_loc_state, values_state, ptr_time_state, 
-                                xn, time_bound, nothing, xn, p_sim, edge_id_candidates, target_loc_candidates; verbose = verbose)
+                                xn, time_bound, nothing, xn, p_sim, edge_candidates; verbose = verbose)
                 end
                 setfield!(S, :loc, ptr_loc_state[1])
                 setfield!(S, :time, ptr_time_state[1])
@@ -318,7 +314,7 @@ function generate_code_synchronized_simulation(model_name::Symbol, lha_name::Sym
                     break
                 end
                 next_state!(A, ptr_loc_state, values_state, ptr_time_state, 
-                            vec_x, l_t[1], l_tr[1], xn, p_sim, edge_id_candidates, target_loc_candidates; verbose = verbose)
+                            vec_x, l_t[1], l_tr[1], xn, p_sim, edge_candidates; verbose = verbose)
                 copyto!(xn, vec_x)
                 tn = l_t[1]
                 tr_n = l_tr[1]
@@ -327,7 +323,7 @@ function generate_code_synchronized_simulation(model_name::Symbol, lha_name::Sym
             end
             if isabsorbing && !isacceptedLHA
                 next_state!(A, ptr_loc_state, values_state, ptr_time_state, 
-                            xn, time_bound, nothing, xn, p_sim, edge_id_candidates, target_loc_candidates; verbose = verbose)
+                            xn, time_bound, nothing, xn, p_sim, edge_candidates; verbose = verbose)
             end
             setfield!(S, :loc, ptr_loc_state[1])
             setfield!(S, :time, ptr_time_state[1])