diff --git a/src/topupopt/problems/esipp/model.py b/src/topupopt/problems/esipp/model.py
index 1b37e1640920faa213eb7b1e178c9e492fc15d1e..412e5d959cbe1f17a66b5b1723cbe454c387388a 100644
--- a/src/topupopt/problems/esipp/model.py
+++ b/src/topupopt/problems/esipp/model.py
@@ -92,6 +92,10 @@ def create_model(
         model.set_G, within=model.set_L
     )  # should inherently exclude import nodes
 
+    model.set_L_max_out_g = pyo.Set(
+        model.set_G, within=model.set_L
+    )  # should inherently exclude export nodes
+
     # *************************************************************************
     # *************************************************************************
 
@@ -2677,33 +2681,25 @@ def create_model(
             return pyo.Constraint.Skip
 
         # max number of directed incoming arcs
-
         n_max_dir_in = sum(
             sum(
                 1
                 for j in m.set_J[(g, l_line, l)]
                 if j not in m.set_J_und[(g, l_line, l)]
             )  # directed
-            for l_line in m.set_L[g]
-            if l_line != l
-            if l_line not in m.set_L_imp[g]
+            for l_line in m.set_L[g] # for every node
+            if l_line != l # cannot be the same node
+            # if l_line not in m.set_L_imp[g] # why?
             if (g, l_line, l) in m.set_J
         )
         
         # check the maximum number of incoming arcs
-
         if n_max_dir_in <= 1:
             # there can only be one incoming arc at most: redundant constraint
-
             return pyo.Constraint.Skip
-
         else:  # more than one incoming arc is possible
-            # *****************************************************************
-
+        
             # number of (new) incoming directed arcs in a group
-
-            # *****************************************************************
-
             b_max_in_gl = 0
 
             # the big m
@@ -2765,6 +2761,7 @@ def create_model(
                         if j_dot not in m.set_J_und[(g, l_circ, l)]  # directed
                         if j_dot not in m.set_J_int[(g, l_circ, l)]  # not interfaced
                         if j_dot not in m.set_J_col[(g, l_circ, l)]  # individual
+                        if j_dot not in m.set_J_pre[(g, l_circ, l)]  # new
                         if j_dot not in m.set_J_mdt[(g, l_circ, l)]  # optional
                     )
                     if (g, l_circ, l) in m.set_J
@@ -2918,19 +2915,255 @@ def create_model(
                 return temp_constr
 
     model.constr_max_incoming_directed_arcs = pyo.Constraint(
-        model.set_GL_not_exp_imp, rule=rule_constr_max_incoming_directed_arcs
+        model.set_GL, rule=rule_constr_max_incoming_directed_arcs
     )
 
     # *************************************************************************
 
-    # def rule_constr_max_outgoing_directed_arcs(m, g, l):
+    def rule_constr_max_outgoing_directed_arcs(m, g, l):
+        # check if the node is not among those subject to a limited number of outgoing arcs
+        if l not in m.set_L_max_out_g[g]:
+            # it is not, skip this constraint
+            return pyo.Constraint.Skip
 
-    #     pass
+        # max number of directed outgoing arcs
+        n_max_dir_out = sum(
+            sum(
+                1
+                for j in m.set_J[(g, l, l_line)]
+                if j not in m.set_J_und[(g, l, l_line)]
+            )  # directed
+            for l_line in m.set_L[g]
+            if l_line != l
+            # if l_line not in m.set_L_exp[g] # cannot be an export: why?
+            if (g, l, l_line) in m.set_J
+        )
+        
+        # check the maximum number of incoming arcs
+        if n_max_dir_out <= 1:
+            # there can only be one outgoing arc at most: redundant constraint
+            # TODO: consider this condition when defining the set
+            return pyo.Constraint.Skip
+        else:  # more than one outgoing arc is possible
 
-    # model.constr_max_outgoing_directed_arcs = pyo.Constraint(
-    #     model.set_GL_not_exp_imp,
-    #     rule=rule_constr_max_outgoing_directed_arcs
-    #     )
+            # number of (new) incoming directed arcs in a group
+            b_max_out_gl = 0
+
+            # the big m
+            M_gl = n_max_dir_out - 1  # has to be positive since n_max_dir_out > 1
+            # TODO: put parenthesis to avoid funny results
+            temp_constr = (
+                sum(
+                    # *********************************************************
+                    # interfaced groups
+                    sum(
+                        sum(
+                            1
+                            for j in m.set_J_col[(g, l, l_circ)]  # part of group
+                            if j not in m.set_J_und[(g, l, l_circ)]  # directed
+                            if (g, l, l_circ, j) in m.set_GLLJ_col_t[t]
+                        )
+                        * m.var_xi_arc_inv_t[t]  # in t
+                        for t in m.set_T_int
+                    )
+                    +
+                    # *********************************************************
+                    # optional non-interfaced groups
+                    sum(
+                        sum(
+                            sum(
+                                1
+                                for j in m.set_J_col[(g, l, l_circ)]  # part of group
+                                if j not in m.set_J_und[(g, l, l_circ)]  # directed
+                                if (g, l, l_circ, j) in m.set_GLLJ_col_t[t]
+                            )
+                            * m.var_delta_arc_inv_th[(t, h)]
+                            for h in m.set_H_t[t]
+                        )
+                        for t in m.set_T
+                        if t not in m.set_T_mdt  # optional
+                        if t not in m.set_T_int  # not interfaced
+                    )
+                    +
+                    # *********************************************************
+                    # interfaced arcs
+                    (sum(
+                        m.var_xi_arc_inv_gllj[(g, l, l_circ, j_circ)]
+                        for j_circ in m.set_J[(g, l, l_circ)]
+                        if j_circ not in m.set_J_und[(g, l, l_circ)]  # directed
+                        if j_circ in m.set_J_int[(g, l, l_circ)]  # interfaced
+                        if j_circ not in m.set_J_col[(g, l, l_circ)]  # individual
+                    )
+                    if (g, l, l_circ) in m.set_J
+                    else 0) +
+                    # *********************************************************
+                    # optional non-interfaced arcs
+                    (sum(
+                        sum(
+                            m.var_delta_arc_inv_glljh[(g, l, l_circ, j_dot, h_dot)]
+                            for h_dot in m.set_H_gllj[(g, l, l_circ, j_dot)]
+                        )
+                        for j_dot in m.set_J[(g, l, l_circ)]
+                        if j_dot not in m.set_J_und[(g, l, l_circ)]  # directed
+                        if j_dot not in m.set_J_int[(g, l, l_circ)]  # not interfaced
+                        if j_dot not in m.set_J_col[(g, l, l_circ)]  # individual
+                        if j_dot not in m.set_J_pre[(g, l, l_circ)]  # new
+                        if j_dot not in m.set_J_mdt[(g, l, l_circ)]  # optional
+                    )
+                    if (g, l, l_circ) in m.set_J
+                    else 0) +
+                    # *********************************************************
+                    # preexisting directed arcs
+                    (sum(
+                        1
+                        for j_pre_dir in m.set_J_pre[(g, l, l_circ)]  # preexisting
+                        if j_pre_dir not in m.set_J_und[(g, l, l_circ)]  # directed
+                    )
+                    if (g, l, l_circ) in m.set_J_pre
+                    else 0) +
+                    # *********************************************************
+                    # mandatory directed arcs
+                    (sum(
+                        1
+                        for j_mdt_dir in m.set_J_mdt[(g, l, l_circ)]
+                        if j_mdt_dir not in m.set_J_und[(g, l, l_circ)]  # directed
+                    )
+                    if (g, l, l_circ) in m.set_J_mdt
+                    else 0)
+                    # *********************************************************
+                    for l_circ in m.set_L[g]
+                    if l_circ not in m.set_L_imp[g]
+                    if l_circ != l
+                )
+                <= 1  # + 
+                # TODO: what is below has copy&pasted, must be completely revised
+                # M_gl*sum(
+                #     # *********************************************************
+                #     # outgoing arcs in interfaced groups, nominal direction
+                #     sum(sum(1
+                #             for j in m.set_J_col[(g,l,l_diamond)]
+                #             #if j in m.set_J_int[(g,l,l_diamond)]
+                #             if (g,l,l_diamond,j) in m.set_GLLJ_col_t[t]
+                #             )*m.var_xi_arc_inv_t[t]
+                #         for t in m.set_T_int
+                #         ) if (g,l,l_diamond) in m.set_J_col else 0
+                #     +
+                #     # outgoing arcs in interfaced groups, reverse direction
+                #     sum(sum(1
+                #             for j in m.set_J_col[(g,l_diamond,l)]
+                #             #if j in m.set_J_int[(g,l_diamond,l)]
+                #             if j in m.set_J_und[(g,l_diamond,l)]
+                #             if (g,l_diamond,l,j) in m.set_GLLJ_col_t[t]
+                #             )*m.var_xi_arc_inv_t[t]
+                #         for t in m.set_T_int
+                #         ) if (g,l_diamond,l) in m.set_J_col else 0
+                #     +
+                #     # *********************************************************
+                #     # TODO: outgoing arcs in non-interfaced optional groups, nominal
+                #     sum(sum(1
+                #             for j in m.set_J_col[(g,l,l_diamond)]
+                #             #if j in m.set_J_int[(g,l,l_diamond)]
+                #             if (g,l,l_diamond,j) in m.set_GLLJ_col_t[t]
+                #             )*sum(
+                #                 m.var_delta_arc_inv_th[(t,h)]
+                #                 for h in m.set_H_t[t]
+                #                 )
+                #         for t in m.set_T
+                #         if t not in m.set_T_mdt
+                #         if t not in m.set_T_int
+                #         ) if (g,l,l_diamond) in m.set_J_col else 0
+                #     +
+                #     # TODO: outgoing arcs in non-interfaced optional groups, reverse
+                #     sum(sum(1
+                #             for j in m.set_J_col[(g,l_diamond,l)]
+                #             #if j in m.set_J_int[(g,l_diamond,l)]
+                #             if j in m.set_J_und[(g,l_diamond,l)]
+                #             if (g,l_diamond,l,j) in m.set_GLLJ_col_t[t]
+                #             )*sum(
+                #                 m.var_delta_arc_inv_th[(t,h)]
+                #                 for h in m.set_H_t[t]
+                #                 )
+                #         for t in m.set_T
+                #         if t not in m.set_T_mdt
+                #         if t not in m.set_T_int
+                #         ) if (g,l_diamond,l) in m.set_J_col else 0
+                #     +
+                #     # *********************************************************
+                #     # interfaced individual outgoing arcs, nominal direction
+                #     sum(m.var_xi_arc_inv_gllj[(g,l,l_diamond,j)]
+                #         for j in m.set_J_int[(g,l,l_diamond)] # interfaced
+                #         if j not in m.set_J_col[(g,l,l_diamond)] # individual
+                #         ) if (g,l,l_diamond) in m.set_J_int else 0
+                #     +
+                #     # *********************************************************
+                #     # interfaced individual undirected arcs, reverse direction
+                #     sum(m.var_xi_arc_inv_gllj[(g,l,l_diamond,j)]
+                #         for j in m.set_J_und[(g,l_diamond,l)] # undirected
+                #         if j in m.set_J_int[(g,l_diamond,l)] # interfaced
+                #         if j not in m.set_J_col[(g,l_diamond,l)] # individual
+                #         ) if (g,l_diamond,l) in m.set_J_und else 0
+                #     +
+                #     # *********************************************************
+                #     # outgoing non-interfaced individual optional arcs
+                #     sum(
+                #         sum(m.var_delta_arc_inv_glljh[(g,l,l_diamond,j,h)]
+                #             for h in m.set_H_gllj[(g,l,l_diamond,j)])
+                #         for j in m.set_J[(g,l,l_diamond)]
+                #         if j not in m.set_J_col[(g,l,l_diamond)] # individual
+                #         if j not in m.set_J_mdt[(g,l,l_diamond)] # optional
+                #         if j not in m.set_J_int[(g,l,l_diamond)] # interfaced
+                #         ) if (g,l,l_diamond) in m.set_J else 0
+                #     +
+                #     # *********************************************************
+                #     # individual non-interfaced undirected arcs, reverse dir.
+                #     sum(
+                #         sum(m.var_delta_arc_inv_glljh[(g,l_diamond,l,j,h)]
+                #             for h in m.set_H_gllj[(g,l_diamond,l,j)])
+                #         for j in m.set_J_und[(g,l_diamond,l)] # undirected
+                #         if j not in m.set_J_col[(g,l_diamond,l)] # individual
+                #         if j not in m.set_J_mdt[(g,l_diamond,l)] # optional
+                #         if j not in m.set_J_int[(g,l_diamond,l)] # interfaced
+                #         ) if (g,l_diamond,l) in m.set_J_und else 0
+                #     +
+                #     # *********************************************************
+                #     # preselected outgonig arcs, nominal direction
+                #     len(m.set_J_pre[(g,l,l_diamond)]
+                #         ) if (g,l,l_diamond) in m.set_J_pre else 0
+                #     +
+                #     # *********************************************************
+                #     # mandatory outgoing arcs, nominal direction
+                #     len(m.set_J_mdt[(g,l,l_diamond)]
+                #         ) if (g,l,l_diamond) in m.set_J_mdt else 0
+                #     +
+                #     # *********************************************************
+                #     # undirected preselected arcs, reverse direction
+                #     sum(1
+                #         for j in m.set_J_pre[(g,l_diamond,l)]
+                #         if j in m.set_J_und[(g,l_diamond,l)]
+                #         ) if (g,l_diamond,l) in m.set_J_pre else 0
+                #     +
+                #     # *********************************************************
+                #     # undirected mandatory arcs, reverse direction
+                #     sum(1
+                #         for j in m.set_J_mdt[(g,l_diamond,l)]
+                #         if j in m.set_J_und[(g,l_diamond,l)]
+                #         ) if (g,l_diamond,l) in m.set_J_mdt else 0
+                #     # *********************************************************
+                #     for l_diamond in m.set_L[g]
+                #     if l_diamond not in m.set_L_imp[g]
+                #     if l_diamond != l
+                #     )
+            )
+            if type(temp_constr) == bool:
+                # trivial outcome
+                return pyo.Constraint.Feasible if temp_constr else pyo.Constraint.Infeasible
+            else:
+                # constraint is relevant
+                return temp_constr
+
+    model.constr_max_outgoing_directed_arcs = pyo.Constraint(
+        model.set_GL, rule=rule_constr_max_outgoing_directed_arcs
+    )
 
     # # *************************************************************************
 
diff --git a/src/topupopt/problems/esipp/network.py b/src/topupopt/problems/esipp/network.py
index 1b129d72477d24dda1deb567d69039448ff64159..5e12053e74d96231b39831107d71a0f2dcfb43ea 100644
--- a/src/topupopt/problems/esipp/network.py
+++ b/src/topupopt/problems/esipp/network.py
@@ -612,21 +612,62 @@ class Network(nx.MultiDiGraph):
         KEY_ARC_TECH_CAPACITY_INSTANTANEOUS,
         KEY_ARC_TECH_STATIC_LOSS,
     )
+    
+    NET_TYPE_HYBRID = 0
+    NET_TYPE_TREE = 1
+    NET_TYPE_REV_TREE = 2
+    
+    NET_TYPES = (
+        NET_TYPE_HYBRID,
+        NET_TYPE_TREE,
+        NET_TYPE_REV_TREE
+        )
 
-    def __init__(self, incoming_graph_data=None, **attr):
+    def __init__(self, network_type = NET_TYPE_HYBRID, **kwargs):
         # run base class init routine
 
-        nx.MultiDiGraph.__init__(self, incoming_graph_data=incoming_graph_data, **attr)
+        nx.MultiDiGraph.__init__(self, **kwargs)
 
         # identify node types
 
         self.identify_node_types()
 
         # declare variables for the nodes without directed arc limitations
+        self.network_type = network_type
+
+        self.nodes_w_in_dir_arc_limitations = dict()
+    
+        self.nodes_w_out_dir_arc_limitations = dict()
+
+    # *************************************************************************
+    # *************************************************************************
+    
+    def _set_up_node(self, node_key, max_number_in_arcs: int = None, max_number_out_arcs: int = None):
+        
+        if self.should_be_tree_network():
+            # nodes have to be part of a tree: one incoming arc per node at most
+            self.nodes_w_in_dir_arc_limitations[node_key] = 1
+        elif self.should_be_reverse_tree_network():
+            # nodes have to be part of a reverse tree: one outgoing arc per node at most
+            self.nodes_w_out_dir_arc_limitations[node_key] = 1
+        else: 
+            # nodes have no peculiar restrictions or they are defined 1 by 1
+            if type(max_number_in_arcs) != type(None):
+                self.nodes_w_in_dir_arc_limitations[node_key] = max_number_in_arcs
+            if type(max_number_out_arcs) != type(None):
+                self.nodes_w_out_dir_arc_limitations[node_key] = max_number_out_arcs
 
-        self.nodes_wo_in_dir_arc_limitations = []
+    # *************************************************************************
+    # *************************************************************************
+    
+    def should_be_tree_network(self) -> bool:
+        return self.network_type == self.NET_TYPE_TREE
 
-        self.nodes_wo_out_dir_arc_limitations = []
+    # *************************************************************************
+    # *************************************************************************
+    
+    def should_be_reverse_tree_network(self) -> bool:
+        return self.network_type == self.NET_TYPE_REV_TREE
 
     # *************************************************************************
     # *************************************************************************
@@ -661,23 +702,25 @@ class Network(nx.MultiDiGraph):
 
     # add a new supply/demand node
 
-    def add_source_sink_node(self, node_key, base_flow: dict):
+    def add_source_sink_node(self, node_key, base_flow: dict, **kwargs):
         node_dict = {
             self.KEY_NODE_TYPE: self.KEY_NODE_TYPE_SOURCE_SINK,
             self.KEY_NODE_BASE_FLOW: base_flow,
         }
 
         self.add_node(node_key, **node_dict)
+        self._set_up_node(node_key, **kwargs)
 
     # *************************************************************************
     # *************************************************************************
 
     # add a new waypoint node
 
-    def add_waypoint_node(self, node_key):
+    def add_waypoint_node(self, node_key, **kwargs):
         node_dict = {self.KEY_NODE_TYPE: self.KEY_NODE_TYPE_WAY}
 
         self.add_node(node_key, **node_dict)
+        self._set_up_node(node_key, **kwargs)
 
     # *************************************************************************
     # *************************************************************************
diff --git a/src/topupopt/problems/esipp/problem.py b/src/topupopt/problems/esipp/problem.py
index 7d3c9e55c6c45f4ad585c793a9722dabf77f68bb..206a17c632d64d0cae265b6c929f54811312d389 100644
--- a/src/topupopt/problems/esipp/problem.py
+++ b/src/topupopt/problems/esipp/problem.py
@@ -1830,22 +1830,14 @@ class InfrastructurePlanningProblem(EnergySystem):
         }
 
         set_L_max_in_g = {
-            g: tuple(
-                l
-                for l in self.networks[g].nodes
-                if l not in self.networks[g].nodes_wo_in_dir_arc_limitations
-            )
+            g: tuple(self.networks[g].nodes_w_in_dir_arc_limitations.keys())
             for g in self.networks.keys()
-        }
+            }
 
-        # set_L_max_out_g = {
-        #     g: tuple(
-        #         l
-        #         for l in self.networks[g].nodes
-        #         if l not in self.networks[g].nodes_wo_out_dir_arc_limitations
-        #         )
-        #     for g in self.networks.keys()
-        #     }
+        set_L_max_out_g = {
+            g: tuple(self.networks[g].nodes_w_out_dir_arc_limitations.keys())
+            for g in self.networks.keys()
+            }
 
         set_GL = tuple((g, l) for g in set_G for l in set_L[g])
 
@@ -3317,7 +3309,7 @@ class InfrastructurePlanningProblem(EnergySystem):
                 "set_L_imp": set_L_imp,
                 "set_L_exp": set_L_exp,
                 "set_L_max_in_g": set_L_max_in_g,
-                #'set_L_max_out_g': set_L_max_out_g,
+                'set_L_max_out_g': set_L_max_out_g,
                 "set_GL": set_GL,
                 "set_GL_exp": set_GL_exp,
                 "set_GL_imp": set_GL_imp,
diff --git a/tests/test_esipp_problem.py b/tests/test_esipp_problem.py
index fdb57243d007521d7b57af69a7f415c10f6ed309..8e1b32a28e2b343ca2c3135bf9df304da416d0a3 100644
--- a/tests/test_esipp_problem.py
+++ b/tests/test_esipp_problem.py
@@ -226,7 +226,7 @@ class TestESIPPProblem:
         # ipp.instantiate(place_fixed_losses_upstream_if_possible=False)
 
         ipp.instantiate(initialise_ancillary_sets=init_aux_sets)
-        
+        ipp.instance.pprint()
         # optimise
         ipp.optimise(
             solver_name=solver,
@@ -1781,7 +1781,7 @@ class TestESIPPProblem:
         mynet = Network()
     
         # import node    
-        imp_node_key = generate_pseudo_unique_key(mynet.nodes())    
+        imp_node_key = 'thatimpnode'    
         mynet.add_import_node(
             node_key=imp_node_key,
             prices={
@@ -1791,7 +1791,7 @@ class TestESIPPProblem:
         )
     
         # export node    
-        exp_node_key = generate_pseudo_unique_key(mynet.nodes())    
+        exp_node_key = 'thatexpnode'    
         mynet.add_export_node(
             node_key=exp_node_key,
             prices={
@@ -1951,7 +1951,7 @@ class TestESIPPProblem:
         mynet = Network()
     
         # import node
-        imp_node_key = generate_pseudo_unique_key(mynet.nodes())
+        imp_node_key = 'thatimpnode'
         mynet.add_import_node(
             node_key=imp_node_key,
             prices={
@@ -1961,7 +1961,7 @@ class TestESIPPProblem:
         )
     
         # export node
-        exp_node_key = generate_pseudo_unique_key(mynet.nodes())
+        exp_node_key = 'thatexpnode'
         mynet.add_export_node(
             node_key=exp_node_key,
             prices={
@@ -2119,7 +2119,7 @@ class TestESIPPProblem:
         mynet = Network()
     
         # import node
-        imp_node_key = generate_pseudo_unique_key(mynet.nodes())
+        imp_node_key = 'thatimpnode'
         mynet.add_import_node(
             node_key=imp_node_key,
             prices={
@@ -2129,7 +2129,7 @@ class TestESIPPProblem:
         )
     
         # export node
-        exp_node_key = generate_pseudo_unique_key(mynet.nodes())
+        exp_node_key = 'thatexpnode'
         mynet.add_export_node(
             node_key=exp_node_key,
             prices={
@@ -2259,7 +2259,7 @@ class TestESIPPProblem:
         mynet = Network()
     
         # import node
-        imp_node_key = generate_pseudo_unique_key(mynet.nodes())
+        imp_node_key = 'thatimpnode'
         mynet.add_import_node(
             node_key=imp_node_key,
             prices={
@@ -2269,7 +2269,7 @@ class TestESIPPProblem:
         )
     
         # export node
-        exp_node_key = generate_pseudo_unique_key(mynet.nodes())
+        exp_node_key = 'thatexpnode'
         mynet.add_export_node(
             node_key=exp_node_key,
             prices={
@@ -2349,7 +2349,7 @@ class TestESIPPProblem:
     
         # no sos, regular time intervals
         ipp = self.build_solve_ipp(
-            solver_options={},
+            solver_options={},solver='scip',
             perform_analysis=False,
             plot_results=False,  # True,
             print_solver_output=False,
@@ -3059,7 +3059,7 @@ class TestESIPPProblem:
         mynet = Network()
 
         # import nodes
-        imp_node_key = generate_pseudo_unique_key(mynet.nodes())
+        imp_node_key = 'thatimpnode'
         mynet.add_import_node(
             node_key=imp_node_key,
             prices={
@@ -3375,7 +3375,7 @@ class TestESIPPProblem:
         mynet = Network()
         
         # import nodes
-        imp_node_key = generate_pseudo_unique_key(mynet.nodes())
+        imp_node_key = 'thatimpnode'
         mynet.add_import_node(
             node_key=imp_node_key,
             prices={
@@ -3638,7 +3638,7 @@ class TestESIPPProblem:
         mynet = Network()
     
         # import node
-        imp_node_key = generate_pseudo_unique_key(mynet.nodes())
+        imp_node_key = 'thatimpnode'
         imp_prices = {
             qpk: ResourcePrice(
                 prices=1.5,
@@ -3652,7 +3652,7 @@ class TestESIPPProblem:
         )
     
         # export node
-        exp_node_key = generate_pseudo_unique_key(mynet.nodes())
+        exp_node_key = 'thatexpnode'
         exp_prices = {
             qpk: ResourcePrice(
                 prices=0.5,
@@ -3765,7 +3765,7 @@ class TestESIPPProblem:
         mynet = Network()
     
         # import node
-        imp_node_key = generate_pseudo_unique_key(mynet.nodes())
+        imp_node_key = 'thatimpnode'
         imp_prices = {
             qpk: ResourcePrice(
                 prices=0.5,
@@ -3779,7 +3779,7 @@ class TestESIPPProblem:
         )
     
         # export node
-        exp_node_key = generate_pseudo_unique_key(mynet.nodes())
+        exp_node_key = 'thatexpnode'
         exp_prices = {
             qpk: ResourcePrice(
                 prices=1.5,
@@ -5938,7 +5938,7 @@ class TestESIPPProblem:
         mynet = Network()
     
         # import node
-        imp_node_key = generate_pseudo_unique_key(mynet.nodes())
+        imp_node_key = 'thatimpnode'
         mynet.add_import_node(
             node_key=imp_node_key,
             prices={
@@ -6087,7 +6087,7 @@ class TestESIPPProblem:
         mynet = Network()
     
         # import node
-        imp_node_key = generate_pseudo_unique_key(mynet.nodes())
+        imp_node_key = 'thatimpnode'
         mynet.add_import_node(
             node_key=imp_node_key,
             prices={
@@ -6240,7 +6240,7 @@ class TestESIPPProblem:
         mynet = Network()
     
         # import node
-        imp_node_key = generate_pseudo_unique_key(mynet.nodes())
+        imp_node_key = 'thatimpnode'
         mynet.add_import_node(
             node_key=imp_node_key,
             prices={
@@ -6523,7 +6523,7 @@ class TestESIPPProblem:
         mynet = Network()
     
         # import node
-        imp_node_key = generate_pseudo_unique_key(mynet.nodes())
+        imp_node_key = 'thatimpnode'
         mynet.add_import_node(
             node_key=imp_node_key,
             prices={
@@ -6800,7 +6800,7 @@ class TestESIPPProblem:
         mynet = Network()
     
         # import node
-        imp_node_key = generate_pseudo_unique_key(mynet.nodes())
+        imp_node_key = 'thatimpnode'
         mynet.add_import_node(
             node_key=imp_node_key,
             prices={
@@ -7084,7 +7084,7 @@ class TestESIPPProblem:
         mynet = Network()
     
         # import node
-        imp_node_key = generate_pseudo_unique_key(mynet.nodes())
+        imp_node_key = 'thatimpnode'
         mynet.add_import_node(
             node_key=imp_node_key,
             prices={
@@ -7705,11 +7705,10 @@ class TestESIPPProblem:
         number_periods = 2
     
         # 4 nodes: one import, one export, two supply/demand nodes
-    
         mynet = Network()
     
         # import node    
-        imp_node_key = generate_pseudo_unique_key(mynet.nodes())    
+        imp_node_key = 'thatimpnode'    
         mynet.add_import_node(
             node_key=imp_node_key,
             prices={
@@ -7720,7 +7719,7 @@ class TestESIPPProblem:
         )
     
         # other nodes    
-        node_A = generate_pseudo_unique_key(mynet.nodes())    
+        node_A = 'A'
         mynet.add_source_sink_node(node_key=node_A, base_flow={(q, 0): 1.0})
     
         # add arcs    
@@ -7840,11 +7839,10 @@ class TestESIPPProblem:
         number_periods = 2
     
         # 4 nodes: one import, one export, two supply/demand nodes
-    
         mynet = Network()
     
         # import node    
-        imp_node_key = generate_pseudo_unique_key(mynet.nodes())    
+        imp_node_key = 'thatimpnode'    
         mynet.add_import_node(
             node_key=imp_node_key,
             prices={
@@ -7855,7 +7853,7 @@ class TestESIPPProblem:
         )
     
         # other nodes    
-        node_A = generate_pseudo_unique_key(mynet.nodes())    
+        node_A = 'A'   
         mynet.add_source_sink_node(node_key=node_A, base_flow={(q, 0): 1.0})
     
         # add arcs    
@@ -8129,7 +8127,7 @@ class TestESIPPProblem:
         )
 
         # 2 nodes: one import, one regular
-        mynet = Network()
+        mynet = Network(network_type=Network.NET_TYPE_TREE)
 
         # import node
         node_IMP = "thatimpnode"
@@ -8223,11 +8221,8 @@ class TestESIPPProblem:
             max_number_parallel_arcs={},
             simplify_problem=True,
         )
-        
-        print('wowowowow')
-        ipp.instance.constr_max_incoming_directed_arcs.pprint()
         assert ipp.has_peak_total_assessments()
-        assert ipp.results["Problem"][0]["Number of constraints"] == 61 
+        assert ipp.results["Problem"][0]["Number of constraints"] == 61
         assert ipp.results["Problem"][0]["Number of variables"] == 53 
         assert ipp.results["Problem"][0]["Number of nonzeros"] == 143
         
@@ -8278,8 +8273,8 @@ class TestESIPPProblem:
         )
 
         # 2 nodes: one import, one regular
-        mynet = Network()
-
+        mynet = Network(network_type=Network.NET_TYPE_REV_TREE)
+        
         # export node
         node_EXP = "thatexpnode"
         mynet.add_export_node(
@@ -8309,12 +8304,12 @@ class TestESIPPProblem:
             base_flow={(q, 0): -1.25},
         )
         
-        list_imp_arcs = [
+        list_exp_arcs = [
             (node_A, node_EXP), # AE
             (node_B, node_EXP), # BE
             (node_C, node_EXP), # CE
             ]
-        for i, node_pair in enumerate(list_imp_arcs):
+        for i, node_pair in enumerate(list_exp_arcs):
         
             # import arcs: AE, BE, CE
             new_arc = Arcs(
@@ -8372,10 +8367,8 @@ class TestESIPPProblem:
             max_number_parallel_arcs={},
             simplify_problem=True,
         )
-        print('owowowowow')
-        ipp.instance.constr_max_incoming_directed_arcs.pprint()
         assert ipp.has_peak_total_assessments()
-        assert ipp.results["Problem"][0]["Number of constraints"] == 61 
+        assert ipp.results["Problem"][0]["Number of constraints"] == 61
         assert ipp.results["Problem"][0]["Number of variables"] == 53 
         assert ipp.results["Problem"][0]["Number of nonzeros"] == 143 # 
         
@@ -8384,9 +8377,9 @@ class TestESIPPProblem:
 
         # validation
 
-        # only the IA arc should be installed
-        true_imp_arcs_selected = [True, False, False]
-        for node_pair, true_arc_decision in zip(list_imp_arcs, true_imp_arcs_selected):
+        # only the AE arc should be installed
+        true_exp_arcs_selected = [True, False, False]
+        for node_pair, true_arc_decision in zip(list_exp_arcs, true_exp_arcs_selected):
             assert (
                 true_arc_decision
                 in ipp.networks["mynet"]