diff --git a/src/topupopt/data/gis/calculate.py b/src/topupopt/data/gis/calculate.py
index 901ee9bed23b056c90353d6b96c3997284a9943a..8846eb9be5b7d824992f9b90dcf7d722b2d674dd 100644
--- a/src/topupopt/data/gis/calculate.py
+++ b/src/topupopt/data/gis/calculate.py
@@ -243,9 +243,9 @@ def node_path_length(network: MultiDiGraph,
         
         # get the arcs between these two nodes
         
-        arc_keys = ident.all_arcs_from_a_to_b(network, 
-                                              path[node_pair], 
-                                              path[node_pair+1])
+        arc_keys = ident.get_edges_from_a_to_b(network, 
+                                               path[node_pair], 
+                                               path[node_pair+1])
         
         number_arc_keys = len(arc_keys)
                     
@@ -440,4 +440,4 @@ def count_ocurrences(gdf: GeoDataFrame,
     return count_dict
 
 #******************************************************************************
-#******************************************************************************
\ No newline at end of file
+#******************************************************************************
diff --git a/src/topupopt/data/gis/identify.py b/src/topupopt/data/gis/identify.py
index c185296f6a92be135b69be25e089a5a2cb5a62e7..940a0081d708a64f590c9d0627df32e2f887d2e4 100644
--- a/src/topupopt/data/gis/identify.py
+++ b/src/topupopt/data/gis/identify.py
@@ -67,7 +67,7 @@ def find_edges_in_reverse(
     return {
         edge_key: [
             other_edge_key
-            for other_edge_key in all_arcs_from_a_to_b(
+            for other_edge_key in get_edges_from_a_to_b(
                         network, 
                         node_start=edge_key[1], 
                         node_end=edge_key[0]
@@ -182,7 +182,7 @@ def edges_are_in_reverse(
 
     """
     
-    # the arcs are the same but in reverse:
+    # the edges are the same but in reverse:
     # - all attributes have to be the same or lists with 
     # the same content, as in a set, except for 
     # the geometry and reversed attributes
@@ -208,7 +208,7 @@ def edges_are_in_reverse(
             # incoherent inputs
             return False
     
-    # for each key, value pair in the forward arc's dict
+    # for each key, value pair in the forward edge's dict
     for attr_key, attr_value in fw_dict.items():
         if (type(attr_value) == list and 
             ((type(rv_dict[attr_key]) == list and
@@ -231,7 +231,7 @@ def edges_are_in_reverse(
                type(rv_dict[attr_key]) != LineString)):
             # either the geometries are not reversed
             # or, there is no geometry attribute in the reverse dict
-            # or, the geometry in the reverse arc is not for a LineString
+            # or, the geometry in the reverse edge is not for a LineString
             # print('ping3:'+str(attr_key))
             return False
         elif (attr_key == osm.KEY_OSMNX_GEOMETRY and 
@@ -480,9 +480,9 @@ def find_roundabouts(network: nx.MultiDiGraph,
     
     for edge_key in new_network.edges(keys=True):
         
-        arc_data_dict = new_network.get_edge_data(*edge_key)
+        edge_data_dict = new_network.get_edge_data(*edge_key)
         
-        if osm.KEY_OSMNX_ONEWAY not in arc_data_dict:
+        if osm.KEY_OSMNX_ONEWAY not in edge_data_dict:
             
             # no information about being oneway or not: not a oneway edge
             
@@ -494,9 +494,9 @@ def find_roundabouts(network: nx.MultiDiGraph,
         
         else:
             
-            # there is information about the arc being oneway or not
+            # there is information about the edge being oneway or not
             
-            if not arc_data_dict[osm.KEY_OSMNX_ONEWAY]:
+            if not edge_data_dict[osm.KEY_OSMNX_ONEWAY]:
                 
                 # oneway attr is False: not a oneway edge
                 
@@ -651,45 +651,45 @@ def is_roundabout(network: nx.MultiDiGraph,
         
     # check if the last node connects to the first
     
-    arc_keys = all_arcs_from_a_to_b(network,
+    edge_keys = get_edges_from_a_to_b(network,
                                     path[-1],
                                     path[0])
     
-    if len(arc_keys) == 0:
+    if len(edge_keys) == 0:
         
         return False
     
     else:
         
-        # among the arcs between them, find at least one compatible
+        # among the edges between them, find at least one compatible
         
-        compatible_arc_exists = False
+        compatible_edge_exists = False
         
-        for arc_key in arc_keys: 
+        for edge_key in edge_keys: 
             
             # get its data
             
-            arc_data_dict = network.get_edge_data(u=arc_key[0],
-                                                  v=arc_key[1],
-                                                  key=arc_key[2])
+            edge_data_dict = network.get_edge_data(u=edge_key[0],
+                                                  v=edge_key[1],
+                                                  key=edge_key[2])
             
-            # ensure that this arc has the oneway attribute
+            # ensure that this edge has the oneway attribute
             
-            if osm.KEY_OSMNX_ONEWAY in arc_data_dict:
+            if osm.KEY_OSMNX_ONEWAY in edge_data_dict:
             
                 # ensure that it is true
                 
-                if arc_data_dict[osm.KEY_OSMNX_ONEWAY]:
+                if edge_data_dict[osm.KEY_OSMNX_ONEWAY]:
                     
-                    compatible_arc_exists = True
+                    compatible_edge_exists = True
                         
                     break
                 
-        # check for compatible arcs
+        # check for compatible edges
                 
-        if not compatible_arc_exists:
+        if not compatible_edge_exists:
             
-            # no compatible arcs exist between these two nodes
+            # no compatible edges exist between these two nodes
             
             return False
         
@@ -697,37 +697,37 @@ def is_roundabout(network: nx.MultiDiGraph,
 
     for node_pair in range(len(path)-1):
         
-        # for each arc between them, find at least one compatible arc
+        # for each edge between them, find at least one compatible edge
         
-        compatible_arc_exists = False
+        compatible_edge_exists = False
         
-        for arc_key in all_arcs_from_a_to_b(network,
+        for edge_key in get_edges_from_a_to_b(network,
                                             path[node_pair],
                                             path[node_pair+1]):
             
             # get its data
         
-            arc_data_dict = network.get_edge_data(u=arc_key[0],
-                                                  v=arc_key[1],
-                                                  key=arc_key[2])
+            edge_data_dict = network.get_edge_data(u=edge_key[0],
+                                                  v=edge_key[1],
+                                                  key=edge_key[2])
                                           
-            # ensure that this arc has the oneway attribute
+            # ensure that this edge has the oneway attribute
             
-            if osm.KEY_OSMNX_ONEWAY in arc_data_dict:
+            if osm.KEY_OSMNX_ONEWAY in edge_data_dict:
             
                 # ensure that it is true
                 
-                if arc_data_dict[osm.KEY_OSMNX_ONEWAY]:
+                if edge_data_dict[osm.KEY_OSMNX_ONEWAY]:
                     
-                    compatible_arc_exists = True
+                    compatible_edge_exists = True
                         
                     break
                 
-        # check for compatible arcs
+        # check for compatible edges
                 
-        if not compatible_arc_exists:
+        if not compatible_edge_exists:
             
-            # no compatible arcs exist between these two nodes
+            # no compatible edges exist between these two nodes
             
             return False
                                     
@@ -740,11 +740,11 @@ def is_roundabout(network: nx.MultiDiGraph,
 
 # TODO: change name to get_multi_edge_tuples
 
-def all_arcs_from_a_to_b(network: nx.MultiDiGraph, 
-                         node_start, 
-                         node_end) -> list:
+def get_edges_from_a_to_b(network: nx.MultiDiGraph, 
+                          node_start, 
+                          node_end) -> list:
     """
-    Retrieve the keys for arcs from one node to another.
+    Retrieve the keys for edges from one node to another.
 
     Parameters
     ----------
@@ -758,7 +758,7 @@ def all_arcs_from_a_to_b(network: nx.MultiDiGraph,
     Returns
     -------
     list
-        A list of arc keys from the start to the end node.
+        A list of edge keys from the start to the end node.
 
     """
     if network.has_edge(u=node_start, v=node_end):
@@ -770,12 +770,12 @@ def all_arcs_from_a_to_b(network: nx.MultiDiGraph,
 #******************************************************************************
 #******************************************************************************
 
-def all_arcs_between_two_nodes(network: nx.MultiDiGraph, u, v) -> list:
+def get_edges_between_two_nodes(network: nx.MultiDiGraph, u, v) -> list:
     """
-    Retrieve the keys for all arcs involving two specific nodes.
+    Retrieve the keys for all edges involving two specific nodes.
     
-    The keys concern arcs in both directions. For a single direction, consider
-    using the method all_arcs_from_a_to_b instead.
+    The keys concern edges in both directions. For a single direction, consider
+    using the method get_edges_from_a_to_b instead.
 
     Parameters
     ----------
@@ -789,41 +789,41 @@ def all_arcs_between_two_nodes(network: nx.MultiDiGraph, u, v) -> list:
     Returns
     -------
     list
-        A list of arc keys involving both nodes, in both directions.
+        A list of edge keys involving both nodes, in both directions.
 
     """
     
     if network.has_edge(u, v):
-        # arcs exist from u to v
+        # edges exist from u to v
         _out = [(u,v,k) for k in network._adj[u][v]]
         try:
-            # try finding out if arcs exist from v to u
+            # try finding out if edges exist from v to u
             _out.extend([(v,u,k) for k in network._adj[v][u]])
         except KeyError:
-            # arcs do not exist from v to u
+            # edges do not exist from v to u
             pass
         # return what was obtained
         return _out
     elif network.has_edge(v, u):
-        # arcs do not exist from u to v but exist from v to u
+        # edges do not exist from u to v but exist from v to u
         return [(v,u,k) for k in network._adj[v][u]]
     else:
-        # no arcs found
+        # no edges found
         return []
 
 #******************************************************************************
 #******************************************************************************
 
-def all_arcs_involving_node(network: nx.MultiDiGraph,
+def get_edges_involving_node(network: nx.MultiDiGraph,
                             node_key,
-                            include_outgoing_arcs: bool = True,
-                            include_incoming_arcs: bool = True,
+                            include_outgoing_edges: bool = True,
+                            include_incoming_edges: bool = True,
                             include_self_loops: bool = True) -> list:
     """
-    Retrieve the keys for all arcs involving a specific node.
+    Retrieve the keys for all edges involving a specific node.
     
-    The keys concern incoming and outgoing arcs. Optionally, the keys retrieved
-    can concern only incoming or outgoing arcs, self-loops included or not.
+    The keys concern incoming and outgoing edges. Optionally, the keys retrieved
+    can concern only incoming or outgoing edges, self-loops included or not.
 
     Parameters
     ----------
@@ -831,17 +831,17 @@ def all_arcs_involving_node(network: nx.MultiDiGraph,
         The object describing the network.
     node_key : hashable-type
         The key to the node under consideration.
-    include_outgoing_arcs : bool, optional
-        If True, outgoing arcs are considered. The default is True.
-    include_incoming_arcs : bool, optional
-        If True, incoming arcs are considered. The default is True.
+    include_outgoing_edges : bool, optional
+        If True, outgoing edges are considered. The default is True.
+    include_incoming_edges : bool, optional
+        If True, incoming edges are considered. The default is True.
     include_self_loops : bool, optional
         If True, self-loops are considered. The default is True.
 
     Returns
     -------
     list
-        A list of arc keys involving the specified node.
+        A list of edge keys involving the specified node.
 
     """
     
@@ -849,12 +849,12 @@ def all_arcs_involving_node(network: nx.MultiDiGraph,
         edge_key
         for edge_key in network.edges(keys=True)
         if node_key in edge_key[0:2]
-        # outgoing arcs
-        if ((node_key != edge_key[0] and not include_outgoing_arcs) or 
-            include_outgoing_arcs)
-        # incoming arcs
-        if ((node_key != edge_key[1] and not include_incoming_arcs) or 
-            include_incoming_arcs)
+        # outgoing edges
+        if ((node_key != edge_key[0] and not include_outgoing_edges) or 
+            include_outgoing_edges)
+        # incoming edges
+        if ((node_key != edge_key[1] and not include_incoming_edges) or 
+            include_incoming_edges)
         # self-loops
         if ((edge_key[0] != edge_key[1] and not include_self_loops) or 
             include_self_loops)
@@ -900,12 +900,19 @@ def neighbours(network: nx.MultiDiGraph or nx.MultiGraph,
         
         return nx.all_neighbors(network, node_key)
 
-#******************************************************************************
-#******************************************************************************
+# *****************************************************************************
+# *****************************************************************************
 
-def is_node_path(network: nx.MultiDiGraph, path: list) -> bool:
+def is_node_path(
+        network: nx.MultiDiGraph, 
+        path: list, 
+        consider_reversed_edges: bool = False) -> bool:
     """
     Indicates if a given path qualifies as a node path in a directed network.
+    
+    A node path consists of a sequence of nodes connected by directed edges.
+    
+    The sequence must include at least two nodes.
 
     Parameters
     ----------
@@ -913,6 +920,9 @@ def is_node_path(network: nx.MultiDiGraph, path: list) -> bool:
         The network object.
     path : list
         The tentative node path.
+    consider_reversed_edges : bool, optional
+        If True, reversed edges can be used to identify a path. If False, only
+        edges in the travel direction will be considered. The default is False.
 
     Returns
     -------
@@ -920,13 +930,25 @@ def is_node_path(network: nx.MultiDiGraph, path: list) -> bool:
         Returns True if path is a node path and False otherwise.
 
     """
-    if len(path) == 0:
+    if len(path) <= 1:
         return False
+    elif consider_reversed_edges:
+        # all nodes must exist in the network
+        for node in path:
+            if not network.has_node(node):
+                return False
+        # each pair of nodes must be connected, in one way or another
+        for n1, n2 in nx.utils.pairwise(path):
+            if network.has_edge(n1, n2) or network.has_edge(n2, n1):
+                continue
+            else:
+                return False
+        return True
     else:
-        return nx.is_path(network, path)
+        return nx.is_path(network, path)    
 
-#******************************************************************************
-#******************************************************************************
+# *****************************************************************************
+# *****************************************************************************
 
 def is_edge_path(network: nx.MultiDiGraph, 
                  path: list,
@@ -1060,7 +1082,7 @@ def convert_edge_path(network: nx.MultiDiGraph,
     path : list
         A list of sequential edge keys that form a path.
     allow_reversed_edges : bool, optional
-        If True, arcs in the opposite direction also count to form paths, as 
+        If True, edges in the opposite direction also count to form paths, as 
         long as the same nodes are involved. The default is False.
 
     Returns
@@ -1075,69 +1097,43 @@ def convert_edge_path(network: nx.MultiDiGraph,
                     ignore_edge_direction=allow_reversed_edges):
         
         # path is a sequence of edge keys: convert to node path
-        
         if allow_reversed_edges:
             
-            # reverse arcs are allowed
-        
+            # reverse edges are allowed
             # drop self-loops, if any
-            
             edge_path = [
                 edge_key
                 for edge_key in path
                 if edge_key[0] != edge_key[1] # exclude self loops
                 ]
                 
-            # if there is only one arc, the node path is straightforward
-            
+            # if there is only one edge, the node path is straightforward
             if len(edge_path) == 1:
-                
                 return [edge_path[0][0], edge_path[0][1]]
             
             node_path = []
-            
             for edge_index, edge_key in enumerate(edge_path):
                 
                 # if there are no nodes yet on the path
-                
                 if len(node_path) == 0:
-                    
                     # find out which node comes first
-                
                     if edge_key[0] in edge_path[1]:
-                        
                         # the start node is in the second edge too: reversed
-                                                                    
-                        node_path.append(edge_key[1])
-                                                                    
-                        node_path.append(edge_key[0])
-                    
-                    else: # the arc is not reversed
-                        
+                        node_path.append(edge_key[1])       
                         node_path.append(edge_key[0])
-                                                                    
+                    else: # the edge is not reversed
+                        node_path.append(edge_key[0])          
                         node_path.append(edge_key[1])
-                
                 else:
-                    
                     # find out which node comes after the previous node
-                    
                     if node_path[-1] == edge_key[0]:
-                        
                         # the start node is the same as the previous node
-                        
                         node_path.append(edge_key[1])
-                        
                     else:
-                        
                         # the end node is the same as the previous node
-                        
                         node_path.append(edge_key[0])
-                        
         else:
-            
-            # no reversed arcs
-            
+            # no reversed edges
             node_path = [
                 edge_key[0]
                 for edge_key in path
@@ -1145,682 +1141,115 @@ def convert_edge_path(network: nx.MultiDiGraph,
                 ]
                 
             # add the last edge's end node
-            
             node_path.append(path[-1][1])
     
         # return statement
-        
         return node_path
             
     else:
         
         # not an edge path
-        
         return []
 
-#******************************************************************************
-#******************************************************************************
-
-# TODO: split method into is_edge_path_simplifiable and is_node_path_simplifiable
+# *****************************************************************************
+# *****************************************************************************
 
-def is_path_simplifiable(network: nx.MultiDiGraph,
-                         path: list,
-                         path_as_node_keys: bool = True,
-                         ignore_self_loops: bool = True,
-                         ignore_arc_directions: bool = True) -> bool:
+def is_path_straight(network: nx.MultiDiGraph,
+                     path: list,
+                     consider_reversed_edges: bool = False,
+                     ignore_self_loops: bool = False) -> bool:
     """
-    Returns True if the path provided can be simplified and False otherwise.
+    Returns True if the path is straight and False otherwise.
+    
+    A path is defined to be straight if it presents no options along it.
 
     Parameters
     ----------
     network : nx.MultiDiGraph
         The objet describing the network.
     path : list
-        The list of nodes along the path. If path_as_node_keys is set to False,
-        the path is instead described using a list of edge keys.
-    path_as_node_keys : bool, optional
-        If True, the path is provided as a list of node keys. If False, the 
-        path is provided as a list of edge keys. The default is True.
+        The list of nodes along the path.
+    consider_reversed_edges : bool, optional
+        If True, reversed edges can also be used to form paths. If False, only
+        edges in the stated direction will be considered. The default is False.
     ignore_self_loops : bool, optional
-        If True, self-loops are ignored. If False, paths containing self-loops
-        cannot be simplified. The default is True.
-    ignore_arc_directions : bool, optional
-        If True, paths with arcs in different directions can still be 
-        simplified. If False, the paths with arcs in different directions 
-        cannot be simplified. The default is True.
+        If True, paths with self-loops can still be straight. If False, paths
+        containing self-loops cannot be straight. The default is False.
 
     Returns
     -------
     bool
-        A boolean indicating whether the path can be simplified or not.
+        A boolean indicating whether the path is straight or not.
 
     """
     
-    # path format
-    
-    if path_as_node_keys:
-        
-        # the path is provided as a list of node keys
-        
-        # a simplifiable path must contain at least three nodes
-        
-        path_length = len(path)
-        
-        if path_length < 3:
-            
-            return False
-        
-        # verify that the elements are node keys in the network
-        
-        for node_key in path:
-            
-            if not network.has_node(node_key):
-                
-                return False
-                            
-        # verify that there are arcs between each consecutive node pair
-        
-        for node_pair in range(path_length-1):
-            
-            if ignore_arc_directions:
-                
-                # check for arcs from A to B or vice-versa
-                
-                arc_keys = all_arcs_between_two_nodes(network, 
-                                                      path[node_pair], 
-                                                      path[node_pair+1])
-                
-                # if there are no arcs between the two nodes, no path exists
-                
-                if len(arc_keys) == 0:
-                    
-                    return False
-            
-            else:
-                
-                # check for arcs from A to B
-            
-                if not network.has_edge(u=path[node_pair],
-                                        v=path[node_pair+1]):
-                    
-                    return False
-            
-        # verify that each node in the list, except the first and last, only
-        # has two neighbours and that these are before and after it in the path
-                
-        for node_index, node_key in enumerate(path):
-            
-            if node_index == 0 or node_index == path_length-1:
-                
-                continue
-            
-            # get the respective neighbours
-            
-            _neighbours = list(
-                neighbours(
-                    network, node_key, ignore_self_loops=ignore_self_loops
-                    )
-                )
-            
-            # check the number of neighbours
-            
-            if len(_neighbours) != 2:
-                
-                # if not two, the path is not straight
-                
-                return False
-            
-            # for each neighbour
-            
-            for neighbour in _neighbours:
-                
-                # # verify that it is adjacent to node_key
-                
-                # if (neighbour != path[node_index-1] and
-                #     neighbour != path[node_index+1]):
-                    
-                #     return False
-                
-                assert (neighbour == path[node_index-1] or
-                        neighbour == path[node_index+1])
-        
-        #**********************************************************************
-        #**********************************************************************
-        
-    else:
-        
-        # the path is provided as a list of arc keys
-        
-        # there must be at least two arc keys: there must be a middle node
-        
-        path_length = len(path)
-        
-        if path_length < 2:
-            
-            return False # TODO: reach this statement
-        
-        # each arc key must have the (node_A, node_B, extra_arc_key) format
-        
-        node_path = []
-        
-        for arc_key in path:
-            
-            # check format
-            
-            if len(arc_key) != 3:
-                
-                return False # TODO: reach this statement
-            
-            # check that it exists in the network
-            
-            if ignore_arc_directions:
-                
-                # verify that it exists as provided
-                
-                if not network.has_edge(u=arc_key[0],
-                                        v=arc_key[1],
-                                        key=arc_key[2]):
-                    
-                    # if not, verify that it exists in the opposite direction
-                    
-                    if not network.has_edge(u=arc_key[1],
-                                            v=arc_key[0]):
-                        # TODO: reach this statement
-                        # if not either, then it does not exist
-                        
-                        return False
-                    
-            else:
-                
-                # verify that it exists as provided
-                
-                if not network.has_edge(u=arc_key[0],
-                                        v=arc_key[1],
-                                        key=arc_key[2]):
-                    
-                    # if not, then there is no link between the nodes
-                    
-                    return False # TODO: reach this statement
-    
-        #**********************************************************************
-        #**********************************************************************
+    # confirm that it is a path
+    if not is_node_path(network, path, consider_reversed_edges):
+        return False
     
-    # otherwise, return True
+    # a straight path requires at least two nodes
+    path_length = len(path)
+    if path_length == 2:
+        return True # path with two nodes is always straight
     
+    # check if the intermediate nodes have the right number of neighbours
+    for intermediate_node in path[1:-1]:
+        if len(tuple(neighbours(
+                network, 
+                intermediate_node, 
+                ignore_self_loops=ignore_self_loops))
+                ) != 2:
+            # the path is not straight if the intermediate nodes do not have 
+            # two distinct neighbours
+            return False 
+    
+    # if all intermediate nodes have two neighbours, return True
     return True
 
 #******************************************************************************
 #******************************************************************************
 
-def find_straight_paths(network: nx.MultiDiGraph,
-                        excluded_nodes: list,
-                        paths_must_be_oneway: bool = True,
-                        paths_must_be_unique: bool = True):
+def find_simplifiable_paths(network: nx.MultiDiGraph,
+                            excluded_nodes: list,
+                            ignore_self_loops: bool = False,
+                            consider_reversed_edges: bool = False,
+                            include_both_directions: bool = False) -> list:
+    """
+    Enumerates the simplifiable paths found in a given graph.
+    
+    A path is defined to be simplifiable if it presents no options along it
+    and involves at least three different nodes: two-node paths are straight
+    but are not simplifiable, with or without reversed edges.
+
+    Parameters
+    ----------
+    network : nx.MultiDiGraph
+        The object describing the graph.
+    excluded_nodes : list
+        A list of keys for nodes that cannot be in any straight path.
+    ignore_self_loops : bool, optional
+        If True, paths including self-loops can still be straight. If False,
+        paths including self-loops cannot be straight. The default is False.
+    consider_reversed_edges : bool, optional
+        If True, a straight path can include nodes connected in reverse. If
+        False, only edges in the stated direction will be considered. The 
+        default is False.
+    include_both_directions : bool, optional
+        If True, and if reverse edges are allowed, simplifiable paths will
+        appear once per direction, otherwise just once. The default is False.
+
+    Returns
+    -------
+    list
+        A list of the straight paths in the graph.
+
+    """
     
     # a straight path is a path where the intermediate nodes (all excluding the
     # first and the last) have to exist and have exactly 2 distinct neighbours
     
-    #**************************************************************************
-        
-    def find_path_case_a(
-            network: nx.MultiDiGraph,
-            list_valid_nodes: list,
-            path: list
-            ) -> list:
-        
-        #paths_must_be_oneway=True
-        #paths_must_be_unique=True
-        # cycles have to involve 3 nodes, e.g. [0, 1, 2, 0]
-        # [0, 1, 0] is ruled out, since it is not oneway (2 anti-parallel arcs)
-        
-        def find_path_forward(network: nx.MultiDiGraph,
-                             list_valid_nodes: list,
-                             path: list):
-            # identify the last node's neighbours
-            current_neighbours = set(
-                neighbours(network, path[-1], ignore_self_loops=True)
-                )
-            # check each neighbour
-            for a_neighbour in current_neighbours:
-                # determine which kinds of edges it has
-                n_forward = network.number_of_edges(path[-1], a_neighbour)
-                n_reverse = network.number_of_edges(a_neighbour, path[-1])
-                if a_neighbour in list_valid_nodes:
-                    # two neighbours, one of which must be the current node
-                    # this means there is at least another node to be added
-                    # which requires recursion, unless there is a loop
-                    if a_neighbour not in path:
-                        # the node is not on the path
-                        if n_forward == 1 and n_reverse == 0:
-                            # the node is connected to the path via a forward e
-                            path.append(a_neighbour)
-                            return find_path_forward(
-                                network, 
-                                list_valid_nodes, 
-                                path
-                                )
-                    elif (a_neighbour == path[0] and 
-                          n_forward == 1 and n_reverse == 0):
-                        # the neighbour matches the first node
-                        # and there is a forward edge
-                        # a cycle was found: finalise and return it
-                        path.append(a_neighbour)
-                        return path
-                elif n_forward == 1 and n_reverse == 0:
-                    # one neighbour only: end node
-                    path.append(a_neighbour)
-                    return path
-            # all neighbours have been visited: return the current path
-            return path
-        
-        def find_path_backward(network: nx.MultiDiGraph,
-                             list_valid_nodes: list,
-                             path: list):
-            # identify the last node's neighbours
-            current_neighbours = set(
-                neighbours(network, path[0], ignore_self_loops=True)
-                )
-            # check all neighbours (should be two at most)
-            for a_neighbour in current_neighbours:
-                # determine which kinds of edges it has
-                n_forward = network.number_of_edges(a_neighbour, path[0])
-                n_reverse = network.number_of_edges(path[0], a_neighbour)
-                if a_neighbour in list_valid_nodes:
-                    # two neighbours, one of which must be the current node
-                    # this means there is at least another node to be added
-                    # which requires recursion, unless there is a loop
-                    if a_neighbour not in path:
-                        # the node is not on the path
-                        if n_forward == 1 and n_reverse == 0:
-                            # the node is connected to the path via a forward e
-                            path.insert(0, a_neighbour)
-                            return find_path_backward(
-                                network, 
-                                list_valid_nodes, 
-                                path
-                                )
-                elif n_forward == 1 and n_reverse == 0:
-                    # one neighbour only: start node
-                    path.insert(0, a_neighbour)
-                    return path
-            # all neighbours have been visited: return the current path
-            return path
-        
-        # explore paths in the forward sense
-        path = find_path_forward(
-            network,
-            list_valid_nodes,
-            path
-            )
-        # check for cycles
-        if len(path) >= 3 and path[0] == path[-1]:  
-            # it is a cycle: no need to search backwards
-            return path
-        # explore paths in the backward sense and return the path
-        return find_path_backward(
-            network,
-            list_valid_nodes,
-            path
-            )
-            
-    #**************************************************************************
-        
-    def find_path_case_b(
-            network: nx.MultiDiGraph,
-            list_valid_nodes: list,
-            path: list
-            ) -> list:
-        
-        #paths_must_be_oneway=True
-        #paths_must_be_unique=False
-        # cycles have to involve 3 nodes, e.g. [0, 1, 2, 0]
-        # [0, 1, 0] is ruled out, since it is not oneway (2 anti-parallel arcs)
-        
-        def find_path_forward(network: nx.MultiDiGraph,
-                             list_valid_nodes: list,
-                             path: list):
-            # identify the last node's neighbours
-            current_neighbours = set(
-                neighbours(network, path[-1], ignore_self_loops=True)
-                )
-            # check each neighbour
-            for a_neighbour in current_neighbours:
-                # determine which kinds of edges it has
-                n_forward = network.number_of_edges(path[-1], a_neighbour)
-                n_reverse = network.number_of_edges(a_neighbour, path[-1])
-                if a_neighbour in list_valid_nodes:
-                    # two neighbours, one of which must be the current node
-                    # this means there is at least another node to be added
-                    # which requires recursion, unless there is a loop
-                    if a_neighbour not in path:
-                        # the node is not on the path
-                        if n_forward >= 1 and n_reverse == 0:
-                            # the node is connected to the path via a forward edge
-                            path.append(a_neighbour)
-                            return find_path_forward(
-                                network, 
-                                list_valid_nodes, 
-                                path
-                                )
-                    elif (a_neighbour == path[0] and 
-                          n_forward >= 1 and n_reverse == 0):
-                        # the neighbour matches the first node
-                        # and there is a forward edge
-                        # a cycle was found: finalise and return it
-                        path.append(a_neighbour)
-                        return path
-                elif n_forward >= 1 and n_reverse == 0:
-                    # one neighbour only: end node
-                    path.append(a_neighbour)
-                    return path
-            # all neighbours have been visited: return the current path
-            return path
-        
-        def find_path_backward(network: nx.MultiDiGraph,
-                             list_valid_nodes: list,
-                             path: list):
-            # identify the last node's neighbours
-            current_neighbours = set(
-                neighbours(network, path[0], ignore_self_loops=True)
-                )
-            # check all neighbours (should be two at most)
-            for a_neighbour in current_neighbours:
-                # determine which kinds of edges it has
-                n_forward = network.number_of_edges(a_neighbour, path[0])
-                n_reverse = network.number_of_edges(path[0], a_neighbour)
-                if a_neighbour in list_valid_nodes:
-                    # two neighbours, one of which must be the current node
-                    # this means there is at least another node to be added
-                    # which requires recursion, unless there is a loop
-                    if a_neighbour not in path:
-                        # the node is not on the path
-                        if n_forward >= 1 and n_reverse == 0:
-                            # the node is connected to the path via a forward edge
-                            path.insert(0, a_neighbour)
-                            return find_path_backward(
-                                network, 
-                                list_valid_nodes, 
-                                path
-                                )
-                elif n_forward >= 1 and n_reverse == 0:
-                    # one neighbour only: start node
-                    path.insert(0, a_neighbour)
-                    return path
-            # all neighbours have been visited: return the current path
-            return path
-        
-        # explore paths in the forward sense
-        path = find_path_forward(
-            network,
-            list_valid_nodes,
-            path
-            )
-        # check for cycles
-        if len(path) >= 3 and path[0] == path[-1]:  
-            # it is a cycle: no need to search backwards
-            return path
-        # explore paths in the backward sense and return the path
-        return find_path_backward(
-            network,
-            list_valid_nodes,
-            path
-            )
-    
-    #**************************************************************************
-        
-    def find_path_case_c(
-            network: nx.MultiDiGraph,
-            list_valid_nodes: list,
-            path: list
-            ) -> list:
-        
-        #paths_must_be_oneway=False 
-        #paths_must_be_unique=True
-        # [0,1,2,0]
-        # [0,1,0] is allowed since arcs anti-parallel arcs are allowed
-        # [1,0,1] is allowed since arcs anti-parallel arcs are allowed
-        # [0,1,0] and [1,0,1] should not be returned together
-        
-        #**********************************************************************
-        
-        def find_path_forward(network: nx.MultiDiGraph,
-                             list_valid_nodes: list,
-                             path: list):
-            # identify the last node's neighbours
-            current_neighbours = set(
-                neighbours(network, path[-1], ignore_self_loops=True)
-                )
-            # check each neighbour
-            for a_neighbour in current_neighbours:
-                # determine which kinds of edges it has
-                n_forward = network.number_of_edges(path[-1], a_neighbour)
-                n_reverse = network.number_of_edges(a_neighbour, path[-1])
-                if a_neighbour in list_valid_nodes:
-                    # two neighbours, one of which must be the current node
-                    # this means there is at least another node to be added
-                    # which requires recursion, unless there is a loop
-                    if a_neighbour not in path:
-                        # the node is not on the path
-                        if n_forward + n_reverse == 1:
-                            # either kind of edge will do
-                            path.append(a_neighbour)
-                            return find_path_forward(
-                                network, 
-                                list_valid_nodes, 
-                                path
-                                )
-                    elif (a_neighbour == path[0] and len(path) >= 3 and
-                          n_forward + n_reverse == 1):
-                        # the neighb. is in the path and matches the first node
-                        # and there is only one edge
-                        # a cycle was found: finalise and return it
-                        path.append(a_neighbour)
-                        return path
-                    # if the neighbour is on the path and not a cycle, continue
-                elif n_forward + n_reverse == 1 and a_neighbour not in path:
-                    # the neighbour is not on the list of valid nodes, id est,
-                    # it has one neighbour only: start/end node
-                    path.append(a_neighbour)
-                    return path
-                # else:
-                #     print('here4')
-                #     path.insert(0, a_neighbour)
-                #     return path
-            # all neighbours have been visited: return the current path
-            return path
-
-        #**********************************************************************
-        
-        def find_path_backward(network: nx.MultiDiGraph,
-                             list_valid_nodes: list,
-                             path: list):
-            # identify the last node's neighbours
-            current_neighbours = set(
-                neighbours(network, path[0], ignore_self_loops=True)
-                )
-            # check all neighbours (should be two at most)
-            for a_neighbour in current_neighbours:
-                # determine which kinds of edges it has
-                n_forward = network.number_of_edges(a_neighbour, path[0])
-                n_reverse = network.number_of_edges(path[0], a_neighbour)
-                if a_neighbour in list_valid_nodes:
-                    # two neighbours, one of which must be the current node
-                    # this means there is at least another node to be added
-                    # which requires recursion, unless there is a loop
-                    if a_neighbour not in path:
-                        # the node is not on the path
-                        if n_forward + n_reverse == 1:
-                            # the node is connected to the path via a forward e
-                            path.insert(0, a_neighbour)
-                            return find_path_backward(
-                                network, 
-                                list_valid_nodes, 
-                                path
-                                )
-                elif n_forward + n_reverse == 1 and a_neighbour not in path:
-                    # one neighbour only: start node
-                    path.insert(0, a_neighbour)
-                    return path
-            # all neighbours have been visited: return the current path
-            return path
-        
-        #**********************************************************************
-        
-        # explore paths in the forward sense
-        path = find_path_forward(
-            network,
-            list_valid_nodes,
-            path
-            )
-        # check for cycles
-        if len(path) >= 3 and path[0] == path[-1]:  
-            # it is a cycle: no need to search backwards
-            return path
-        # explore paths in the backward sense and return the path
-        return find_path_backward(
-            network,
-            list_valid_nodes,
-            path
-            )
-    
-    #**************************************************************************
-        
-    def find_path_case_d(
-            network: nx.MultiDiGraph,
-            list_valid_nodes: list,
-            path: list
-            ) -> list:
-        
-        # paths_must_be_oneway=False
-        # paths_must_be_unique=False
-        # cycles have to involve 3 nodes, e.g. [0, 1, 2, 0]
-        # [0, 1, 0] is ruled out, since it is not oneway (2 anti-parallel arcs)
-        
-        #**********************************************************************
-        
-        def find_path_forward(network: nx.MultiDiGraph,
-                             list_valid_nodes: list,
-                             path: list):
-            # identify the last node's neighbours
-            current_neighbours = set(
-                neighbours(network, path[-1], ignore_self_loops=True)
-                )
-            # print('current neighbours: '+str(current_neighbours))
-            # check each neighbour
-            for a_neighbour in current_neighbours:
-                # print('neighbour: '+str(a_neighbour))
-                # print('current path: '+str(path))
-                # determine which kinds of edges it has
-                n_forward = network.number_of_edges(path[-1], a_neighbour)
-                n_reverse = network.number_of_edges(a_neighbour, path[-1])
-                # print('n_forward: '+str(n_forward))
-                # print('n_reverse: '+str(n_reverse))
-                if a_neighbour in list_valid_nodes:
-                    # two neighbours, one of which must be the current node
-                    # this means there is at least another node to be added
-                    # which requires recursion, unless there is a loop
-                    
-                    if a_neighbour not in path:
-                        # the node is not on the path
-                        if n_forward + n_reverse >= 1:
-                            # either kind of edge will do
-                            # print('here')
-                            path.append(a_neighbour)
-                            return find_path_forward(
-                                network, 
-                                list_valid_nodes, 
-                                path
-                                )
-                    elif (a_neighbour == path[0] and len(path) >= 3 and
-                          n_forward + n_reverse >= 1):
-                        # the neighb. is in the path and matches the first node
-                        # and there is only one edge
-                        # a cycle was found: finalise and return it
-                        # print('here2')
-                        path.append(a_neighbour)
-                        return path
-                    # print('here23')
-                    # if the neighbour is on the path and not a cycle, continue
-                elif n_forward + n_reverse >= 1 and a_neighbour not in path:
-                    # the neighbour is not on the list of valid nodes, id est,
-                    # it has one neighbour only: start/end node
-                    # print('here3')
-                    path.append(a_neighbour)
-                    return path
-                # print('here34')
-                # else:
-                #     print('here4')
-                #     path.insert(0, a_neighbour)
-                #     return path
-            # all neighbours have been visited: return the current path
-            # print('here4')
-            return path
-
-        #**********************************************************************
-        
-        def find_path_backward(network: nx.MultiDiGraph,
-                             list_valid_nodes: list,
-                             path: list):
-            # identify the last node's neighbours
-            current_neighbours = set(
-                neighbours(network, path[0], ignore_self_loops=True)
-                )
-            # print('current neighbours: '+str(current_neighbours))
-            # check all neighbours (should be two at most)
-            for a_neighbour in current_neighbours:
-                # print('neighbour: '+str(a_neighbour))
-                # print('current path: '+str(path))
-                # determine which kinds of edges it has
-                n_forward = network.number_of_edges(a_neighbour, path[0])
-                n_reverse = network.number_of_edges(path[0], a_neighbour)
-                # print('n_forward: '+str(n_forward))
-                # print('n_reverse: '+str(n_reverse))
-                if a_neighbour in list_valid_nodes:
-                    # two neighbours, one of which must be the current node
-                    # this means there is at least another node to be added
-                    # which requires recursion, unless there is a loop
-                    if a_neighbour not in path:
-                        # the node is not on the path
-                        if n_forward + n_reverse >= 1:
-                            # print('here5')
-                            # the node is connected to the path via a forward e
-                            path.insert(0, a_neighbour)
-                            return find_path_backward(
-                                network, 
-                                list_valid_nodes, 
-                                path
-                                )
-                elif n_forward + n_reverse >= 1 and a_neighbour not in path:
-                    # print('here6')
-                    # one neighbour only: start node
-                    path.insert(0, a_neighbour)
-                    return path
-                # print('here67')
-            # all neighbours have been visited: return the current path
-            # print('here7')
-            return path
-        
-        #**********************************************************************
-        # print('path:'+str(path))
-        # explore paths in the forward sense
-        path = find_path_forward(
-            network,
-            list_valid_nodes,
-            path
-            )
-        # print('post-forward search path:'+str(path))
-        # check for cycles
-        if len(path) >= 3 and path[0] == path[-1]:  
-            # it is a cycle: no need to search backwards
-            return path
-        # explore paths in the backward sense and return the path
-        return find_path_backward(
-            network,
-            list_valid_nodes,
-            path
-            )
-    
-    #**************************************************************************
+    # *************************************************************************
+    # *************************************************************************
         
     # locate all the non-excluded nodes that can form straight paths
             
@@ -1829,7 +1258,7 @@ def find_straight_paths(network: nx.MultiDiGraph,
         for node_key in network.nodes()
         # the node cannot be among those excluded
         if node_key not in excluded_nodes
-        # the node can only be linked to two other nodes other than itself
+        # the node has to be linked to two other nodes other than itself
         if len(set(
             neighbours(
                 network, 
@@ -1837,12 +1266,15 @@ def find_straight_paths(network: nx.MultiDiGraph,
                 ignore_self_loops=True
                 )
             )) == 2
+        # exclude nodes with self-loops if desired:
+        # 1) self-loops are tolerated (no need to check)
+        # 2) self-loops are not tolerated and they do not exist
+        if (ignore_self_loops or 
+            (not ignore_self_loops and 
+             not network.has_edge(node_key, node_key)))
         ]
-    # print('******************************************************************')
-    # print('excluded_nodes:'+str(excluded_nodes))
-    # print('intermediate_candidate_nodes:'+str(intermediate_candidate_nodes))
-        
-    #**************************************************************************
+    
+    # *************************************************************************
         
     # find out paths around the nodes identified
     
@@ -1851,56 +1283,30 @@ def find_straight_paths(network: nx.MultiDiGraph,
     
     list_nodes_joined = []
     
-    for i, candidate_node in enumerate(intermediate_candidate_nodes):
-        # print('-------------------------------------------------------------')
-        # print('candidate_node: '+str(candidate_node))
-        # if node is already in previous paths, skip   
+    # try to form paths around the candidate nodes 
+    for candidate_node in intermediate_candidate_nodes:
+        
+        # skip if the node is already in a path
         if candidate_node in list_nodes_joined:
             continue
         
-        # a neighbour can extend the path under the following conditions:
-        # i) if it is among the valid nodes (has 2 neighbours only);
-        # ii) if it is not on the path already or it is its first node for a 
-        # path of at least 3 nodes (with the current neighbour included)
-        # iii) 
-        # a) with paths_must_be_oneway=True and paths_must_be_unique=True, if
-        # only one forward edge links the last node and the neighbour
-        # b) with paths_must_be_oneway=True and paths_must_be_unique=False, if
-        # no reverse edges link the last node and the neighbour
-        # c) with paths_must_be_oneway=False and paths_must_be_unique=True, if
-        # there is one forward or one reverse edge linking the nodes
-        # d) with paths_must_be_oneway=False and paths_must_be_unique=False, if
-        # there are any edges linking the last node and the neighbour
-        
-        if paths_must_be_oneway and paths_must_be_unique:
-            # case a
-            new_sequence = find_path_case_a(
+        # select method
+        if consider_reversed_edges:
+            # reversed edges are accepted
+            new_sequence = _find_path_direction_insensitive(
                 network,
-                intermediate_candidate_nodes, 
-                [candidate_node]
+                list_valid_nodes=intermediate_candidate_nodes, 
+                start_node=candidate_node
                 )   
-        elif paths_must_be_oneway and not paths_must_be_unique:
-            # case b
-            new_sequence = find_path_case_b(
-                network,
-                intermediate_candidate_nodes, 
-                [candidate_node]
-                )
-        elif not paths_must_be_oneway and paths_must_be_unique:
-            # case c
-            new_sequence = find_path_case_c(
-                network,
-                intermediate_candidate_nodes, 
-                [candidate_node]
-                )
         else:
-            # case d
-            new_sequence = find_path_case_d(
+            # reversed edges are not accepted
+            new_sequence = _find_path_direction_sensitive(
                 network,
-                intermediate_candidate_nodes, 
-                [candidate_node]
+                list_valid_nodes=intermediate_candidate_nodes, 
+                start_node=candidate_node
                 )
-        # print('new_sequence: '+str(new_sequence))
+            
+        # make sure the sequence is not redundant
         if (len(new_sequence) <= 2 or 
             new_sequence in list_paths or 
             set(new_sequence) in list_paths_nodes):
@@ -1910,262 +1316,286 @@ def find_straight_paths(network: nx.MultiDiGraph,
         # add the path 
         list_paths.append(new_sequence)
         list_paths_nodes.append(set(new_sequence))
-        
+        if consider_reversed_edges and include_both_directions:
+            # directions do not matter: 
+            list_paths.append(new_sequence[::-1])
+            
         # update the list of intermediate nodes already on paths 
         list_nodes_joined.extend(
             (element for element in new_sequence[1:-1]
              if element != candidate_node) # used to keep it shorter?
             )
     
-    #**************************************************************************
+    # *************************************************************************
+    # *************************************************************************
     
     return list_paths
 
-    #**************************************************************************
-
-#******************************************************************************
-#******************************************************************************
-
-def find_all_straight_paths(network: nx.MultiDiGraph,
-                            excluded_nodes: list,
-                            return_paths_as_arc_keys: bool = False,
-                            pick_shortest_parallel_edge: bool = True):
-    
-    # TODO: pick shortest parallel edge
-        
-    #**************************************************************************
-        
-    # locate all the non-excluded nodes that form straight paths, that is,
-    # nodes that only have arcs with two other nodes
-    
-    removable_nodes = []
-    
-    # for each node in the network
+    # *************************************************************************
+    # *************************************************************************
     
-    for node_key in network.nodes():
-        
-        # check if node_key is in the list of nodes not to be considered
-        
-        if node_key in excluded_nodes:
-            
-            continue
-        
-        # identify the node's neighbours (while ignoring self-loops)
-        
-        _node_neighbours = list(
-            neighbours(network, node_key, ignore_self_loops=True)
+# *****************************************************************************
+# *****************************************************************************
+       
+def _find_path_direction_sensitive(
+        network: nx.MultiDiGraph,
+        list_valid_nodes: list,
+        start_node
+        ) -> list:
+    
+    def find_path_forward(network: nx.MultiDiGraph,
+                          current_node,
+                          path: list):
+        # identify the last node's neighbours
+        current_neighbours = set(
+            neighbours(network, current_node, ignore_self_loops=True)
             )
-        
-        # if the node only has two neighbours
-        
-        if len(_node_neighbours) == 2:
-            
-            # store the node's key
-            
-            removable_nodes.append(node_key)
-    
-    #**************************************************************************
-    
-    # TODO: make the method work with ignore_arc_directions=False
-    
-    def get_path_valid_nodes(network: nx.MultiDiGraph,
-                             list_valid_nodes: list,
-                             path: list,
-                             ignore_arc_directions: bool = True) -> list:
-        
-        # forward direction
-        
-        path = get_path_valid_nodes_forward(network,
-                                            list_valid_nodes,
-                                            path,
-                                            ignore_arc_directions)
-        
-        # backward direction
-        
-        path = get_path_valid_nodes_backward(network,
-                                             list_valid_nodes,
-                                             path,
-                                             ignore_arc_directions)
-        
-        if len(path) == 1:
-            
-            _neighbours = list(neighbours(network, path[0]))
-            
-            path.insert(0, _neighbours[0])
-            path.append(_neighbours[1])
-        
-            return path
-        
-        # add the ends
-        
-        for neighbour in neighbours(network, path[0]):
-            
-            if neighbour not in path:
-                
-                path.insert(0, neighbour)
-                
-                break
-            
-        for neighbour in neighbours(network, path[-1]):
-
-            if neighbour not in path or neighbour == path[0]:
-                
-                path.append(neighbour)
-                
-                break
-            
+        # check each neighbour
+        for a_neighbour in current_neighbours:
+            # check the direction of edge towards the neighbour
+            if network.has_edge(current_node, a_neighbour):
+                # forward edge
+                # 1) node is not on the path
+                # 1.1) is a valid node >> path continues
+                # 1.2) is not a valid node >> end of path
+                # 2) node is on the path already
+                # 2.1) matches the start node = cycle
+                # 2.2) does not match the start node (reversed arc) = ignore
+                if a_neighbour not in path:
+                    # neighbour is not on the path
+                    if a_neighbour in list_valid_nodes:
+                        # is a valid node: path continues
+                        # add the neighbour to the end of the path
+                        path.append(a_neighbour)
+                        # recursive call with extended path
+                        return find_path_forward(
+                            network, 
+                            path[-1], 
+                            path
+                            )
+                    else: # is not a valid node: path ends
+                        # add the neighbour to the end of the path:
+                        path.append(a_neighbour)
+                        # return the path
+                        return path
+                elif a_neighbour == path[0]:
+                    # neighbour is already on the path and matches the start
+                    # add the neighbour to the end of the path:
+                    path.append(a_neighbour)
+                    # return the path
+                    return path
+        # all neighbours have been visited: return the current path
         return path
     
-    def get_path_valid_nodes_forward(
-            network: nx.MultiDiGraph,
-            list_valid_nodes: list,
-            path: list,
-            ignore_arc_directions: bool = True) -> list:
-        
-        _node_neighbours = list(
-            neighbours(network, path[-1], ignore_self_loops=True)
-            )
-        
-        for node_neighbour in _node_neighbours: 
-
-            # if it is a valid node
-            
-            if node_neighbour in list_valid_nodes:
-
-                # if it not in the path
-                    
-                if node_neighbour not in path:
-                    
-                    # neighbour is not on the path yet, and is valid
-                    
-                    # append it to the list
-                    
-                    path.append(node_neighbour)
-                    
-                    # call method again
-                    
-                    return get_path_valid_nodes_forward(network,
-                                                        list_valid_nodes,
-                                                        path)
-                            
-        return path
-            
-    def get_path_valid_nodes_backward(
-            network: nx.MultiDiGraph,
-            list_valid_nodes: list,
-            path: list,
-            ignore_arc_directions: bool = True) -> list:
-        
-        _node_neighbours = list(
-            neighbours(network, path[0], ignore_self_loops=True)
+    def find_path_backward(network: nx.MultiDiGraph,
+                           current_node,
+                           path: list):
+        # identify the last node's neighbours
+        current_neighbours = set(
+            neighbours(network, current_node, ignore_self_loops=True)
             )
-        
-        for node_neighbour in _node_neighbours:
-            
-            if node_neighbour in list_valid_nodes:
-                            
-                # node is already known
-                            
-                if node_neighbour not in path:
-                            
-                    # neighbour is not on the path yet, and is valid
-                                
-                    # append it to the list
-                                
-                    path.insert(0,node_neighbour)
-                                
-                    # call method again
-                                
-                    return get_path_valid_nodes_backward(network,
-                                                         list_valid_nodes,
-                                                         path)
-                           
+        # check each neighbour
+        # 1) if the neighbour is ahead and is a valid node: 
+        # >> recursion w/ neighbour and then return the final path
+        # 2) if the neighbour is ahead and is not a valid node: 
+        # >> add it to the path and then return it
+        # 3) if the neighbour is not ahead and is on the path: 
+        # >> continue, namely to check the other neighbour
+        # 4) if the neighbour is not ahead and is not on the path: 
+        # >> add it to the beginning of the path and continue
+        
+        # check each neighbour
+        for a_neighbour in current_neighbours:
+            # check the direction of edge towards the neighbour
+            if network.has_edge(a_neighbour, current_node):
+                # backward edge
+                # 1) node is not on the path
+                # 1.1) is a valid node >> path continues
+                # 1.2) is not a valid node >> end of path
+                # 2) node is on the path already
+                # 2.1) matches the start node = cycle
+                # 2.2) does not match the start node (reversed arc) = ignore
+                if a_neighbour not in path:
+                    # neighbour is not on the path
+                    if a_neighbour in list_valid_nodes:
+                        # is a valid node: path continues
+                        # add the neighbour to the start of the path
+                        path.insert(0, a_neighbour)
+                        # recursive call with extended path
+                        return find_path_backward(
+                            network, 
+                            path[0], 
+                            path
+                            )
+                    else: # is not a valid node: path ends
+                        # add the neighbour to the start of the path
+                        path.insert(0, a_neighbour)
+                        # return the path
+                        return path
+                elif a_neighbour == path[-1] and len(path) >= 3:
+                    # neighbour is already on the path, matches the end, and
+                    # the path length is greater than or equal to 3
+                    # add the neighbour to the start of the path
+                    path.insert(0, a_neighbour)
+                    # return the path
+                    return path
+        # all neighbours have been visited: return the current path
         return path
-        
-    #**************************************************************************
-        
-    # find out paths around the nodes identified
     
-    list_paths = []
+    # *************************************************************************
     
-    list_nodes_joined = []
+    # find the path forward, check for cycles and then find the path backwards
+    # find the forward path segment
+    path = find_path_forward(
+        network,
+        start_node,
+        [start_node]
+        )
+    # cycles have to be detected on the first try
+    if len(path) >= 3 and path[0] == path[-1]:  
+        # it is a cycle: no need to search backwards
+        return path
+    # find the backward path segment
+    return find_path_backward(
+        network,
+        path[0],
+        path
+        )
     
-    for i, node in enumerate(removable_nodes):
-        
-        # if node is already in previous paths, skip
-        
-        if node in list_nodes_joined:
-            
-            continue
-        
-        #**********************************************************************
-        
-        # get sequence of valid nodes
-        
-        new_sequence = get_path_valid_nodes(network,
-                                            removable_nodes, 
-                                            [node])
-        
-        # add the ends
-        
-        list_paths.append(new_sequence)
-        
-        list_nodes_joined.extend(
-            (element 
-             for element in new_sequence[1:-1]
-             if element != node)
-            )
-        
-        # print('new run:')
-        # print('iteration: '+str(i))
-        # print('node: '+str(node))
-        # print('paths: '+str(list_paths))
-        # print('nodes joined: '+str(list_nodes_joined))
+    # *************************************************************************
+
+# *****************************************************************************
+# *****************************************************************************
     
-    #**************************************************************************
+def _find_path_direction_insensitive(
+        network: nx.MultiDiGraph,
+        list_valid_nodes: list,
+        start_node
+        ) -> list:
     
-    if return_paths_as_arc_keys:
+    def find_path_forward(network: nx.MultiDiGraph,
+                          current_node,
+                          path: list):
         
-        # transform list of node lists into list of arc key lists
+        # identify the last node's neighbours
+        current_neighbours = set(
+            neighbours(network, current_node, ignore_self_loops=True)
+            )
+        # check each neighbour
+        for a_neighbour in current_neighbours:
+            # check the direction of edge towards the neighbour:
+            # 1) node is not on the path
+            # 1.1) is a valid node >> path continues
+            # 1.2) is not a valid node >> end of path
+            # 2) node is on the path already
+            # 2.1) matches the start node = cycle
+            # 2.2) does not match the start node (reversed arc) = ignore
+            if a_neighbour not in path:
+                # neighbour is not on the path
+                if a_neighbour in list_valid_nodes:
+                    # is a valid node: path continues
+                    # add the neighbour to the end of the path
+                    path.append(a_neighbour)
+                    # recursive call with extended path
+                    return find_path_forward(
+                        network, 
+                        path[-1], 
+                        path
+                        )
+                else: # is not a valid node: path ends
+                    # add the neighbour to the end of the path:
+                    path.append(a_neighbour)
+                    # return the path
+                    return path
+            elif a_neighbour == path[0] and len(path) >= 3:
+                # neighbour is already on the path and matches the start, and
+                # the path length is greater than or equal to 3
+                # add the neighbour to the end of the path:
+                path.append(a_neighbour)
+                # return the path
+                return path
+        # all neighbours have been visited: return the current path
+        return path
     
-        list_path_arcs = []
+    def find_path_backward(network: nx.MultiDiGraph,
+                           current_node,
+                           path: list):
         
-        for path in list_paths:
-            
-            temp_path_arcs = []
-            
-            for node_pair_index in range(len(path)-1):
-                
-                arcs = all_arcs_from_a_to_b(network, 
-                                            path[node_pair_index],
-                                            path[node_pair_index+1])
-                
-                if len(arcs) == 0:
-                    
-                    arcs = all_arcs_from_a_to_b(network, 
-                                                path[node_pair_index+1],
-                                                path[node_pair_index])
-                    
-                # if len(arcs) == 0:
-                #     print(list_paths)
-                #     print(path)
-                #     print((path[node_pair_index],path[node_pair_index+1]))
-                #     print((path[node_pair_index+1],path[node_pair_index]))
-                
-                temp_path_arcs.append(
-                    arcs[0]
-                    )
-                
-            list_path_arcs.append(temp_path_arcs)
-            
-        return list_path_arcs
-            
-    else:
-    
-        return list_paths
+        # identify the last node's neighbours
+        current_neighbours = set(
+            neighbours(network, current_node, ignore_self_loops=True)
+            )
+        # check each neighbour
+        # 1) if the neighbour is ahead and is a valid node: 
+        # >> recursion w/ neighbour and then return the final path
+        # 2) if the neighbour is ahead and is not a valid node: 
+        # >> add it to the path and then return it
+        # 3) if the neighbour is not ahead and is on the path: 
+        # >> continue, namely to check the other neighbour
+        # 4) if the neighbour is not ahead and is not on the path: 
+        # >> add it to the beginning of the path and continue
+        
+        # check each neighbour
+        for a_neighbour in current_neighbours:
+            # check the direction of edge towards the neighbour
+            # 1) node is not on the path
+            # 1.1) is a valid node >> path continues
+            # 1.2) is not a valid node >> end of path
+            # 2) node is on the path already
+            # 2.1) matches the start node = cycle
+            # 2.2) does not match the start node (reversed arc) = ignore
+            if a_neighbour not in path:
+                # neighbour is not on the path
+                if a_neighbour in list_valid_nodes:
+                    # is a valid node: path continues
+                    # add the neighbour to the start of the path
+                    path.insert(0, a_neighbour)
+                    # recursive call with extended path
+                    return find_path_backward(
+                        network, 
+                        path[0], 
+                        path
+                        )
+                else: # is not a valid node: path ends
+                    # add the neighbour to the start of the path
+                    path.insert(0, a_neighbour)
+                    # return the path
+                    return path
+            elif a_neighbour == path[-1] and len(path) >= 3:
+                # neighbour is already on the path, matches the end, and
+                # the path length is greater than or equal to 3
+                # add the neighbour to the start of the path
+                path.insert(0, a_neighbour)
+                # return the path
+                return path
+        # all neighbours have been visited: return the current path
+        return path # TODO: reach statement
+    
+    # *************************************************************************
+    
+    # find the path forward, check for cycles and then find the path backwards
+    # explore paths in the forward sense
+    path = find_path_forward(
+        network,
+        start_node,
+        [start_node]
+        )
+    # check for cycles
+    if len(path) >= 3 and path[0] == path[-1]:  
+        # it is a cycle: no need to search backwards
+        return path
+    # explore paths in the backward sense and return the path
+    return find_path_backward(
+        network,
+        path[0],
+        path
+        )
     
-#******************************************************************************
-#******************************************************************************
+    # *************************************************************************
+    # *************************************************************************
+
+# *****************************************************************************
+# *****************************************************************************
 
 def find_self_loops(network: nx.MultiDiGraph) -> list:
     """
@@ -2363,12 +1793,12 @@ def is_start_or_end_point(line: LineString,
 # *****************************************************************************
 # *****************************************************************************
 
-def identify_arc_closest_to_node(
+def identify_edge_closest_to_node(
         network: nx.MultiDiGraph,
         node_keys: list,
         crs: str = None) -> Tuple[list, nx.MultiDiGraph]:
     """
-    Identify the arcs that are closest to a given set of nodes.
+    Identify the edges that are closest to a given set of nodes.
     
     The network object should formatted according to OSMnx standards.
     
@@ -2387,8 +1817,8 @@ def identify_arc_closest_to_node(
 
     Returns
     -------
-    nearest_arc_keys : list
-        The list of keys for the arcs that are closest to the nodes (1:1).
+    nearest_edge_keys : list
+        The list of keys for the edges that are closest to the nodes (1:1).
     network : nx.MultiDiGraph
         The object for the projected network.
 
@@ -2397,7 +1827,7 @@ def identify_arc_closest_to_node(
     #**************************************************************************
     
     # 1) ensure that the network crs is correct and convert if not    
-    # 2) identify the arcs that are nearest to the nodes
+    # 2) identify the edges that are nearest to the nodes
     # 3) revert network crs back to the original, if necessary
 
     #**************************************************************************
@@ -2416,9 +1846,9 @@ def identify_arc_closest_to_node(
 
     #**************************************************************************
     
-    # 2) identify the arcs that are nearest to the nodes
+    # 2) identify the edges that are nearest to the nodes
     
-    nearest_arc_keys = nearest_edges(
+    nearest_edge_keys = nearest_edges(
         projected_network, 
         X=[projected_network.nodes[node_key][osm.KEY_OSMNX_X]
            for node_key in node_keys], 
@@ -2428,7 +1858,7 @@ def identify_arc_closest_to_node(
         
     # return statement
     
-    return nearest_arc_keys, projected_network
+    return nearest_edge_keys, projected_network
 
 # *****************************************************************************
-# *****************************************************************************
\ No newline at end of file
+# *****************************************************************************
diff --git a/src/topupopt/data/gis/modify.py b/src/topupopt/data/gis/modify.py
index d041e92f0c649ba15757f644421fc4ad58d12567..2ff69dbb18b38db0db9d9a6f9817ae17f7b37d0d 100644
--- a/src/topupopt/data/gis/modify.py
+++ b/src/topupopt/data/gis/modify.py
@@ -1,5 +1,3 @@
-# -*- coding: utf-8 -*-
-
 # standard library imports
 
 import math
@@ -170,7 +168,7 @@ def transform_roundabouts_into_crossroads(
             # if it is not in the roundabout itself
             if other_node_key not in roundabout 
             # for each arc between the two nodes
-            for edge_key in gis_iden.all_arcs_between_two_nodes(
+            for edge_key in gis_iden.get_edges_between_two_nodes(
                     network, 
                     node_key, 
                     other_node_key) 
@@ -581,13 +579,13 @@ def replace_path(
         
         if ignore_directions:
             # edge directions can be ignored
-            edge_key = list(gis_iden.all_arcs_between_two_nodes(
+            edge_key = list(gis_iden.get_edges_between_two_nodes(
                 network, 
                 path[node_pair_index], 
                 path[node_pair_index+1]
                 ))[0]
         else: # edge directions cannot be ignored
-            edge_key = list(gis_iden.all_arcs_from_a_to_b(
+            edge_key = list(gis_iden.get_edges_from_a_to_b(
                 network, 
                 path[node_pair_index], 
                 path[node_pair_index+1]
@@ -755,7 +753,7 @@ def remove_redundant_arcs(network: nx.MultiDiGraph,
             
             # get the arcs between the two nodes
                                              
-            # list_arcs = gis_iden.all_arcs_between_two_nodes(network, 
+            # list_arcs = gis_iden.get_edges_between_two_nodes(network, 
             #                                                 node_one, 
             #                                                 node_two)
         
@@ -779,7 +777,7 @@ def remove_redundant_arcs(network: nx.MultiDiGraph,
             
             # get the arcs between the two nodes
             
-            list_arcs = gis_iden.all_arcs_from_a_to_b(network, 
+            list_arcs = gis_iden.get_edges_from_a_to_b(network, 
                                                       node_one, 
                                                       node_two)
         
@@ -847,13 +845,13 @@ def remove_longer_parallel_arcs(network: nx.MultiDiGraph,
                 continue
             # get the arcs between the two nodes
             if ignore_arc_directions: # both directions
-                list_arcs = gis_iden.all_arcs_between_two_nodes(
+                list_arcs = gis_iden.get_edges_between_two_nodes(
                     network, 
                     node_one, 
                     node_two
                     )
             else: # one direction
-                list_arcs = gis_iden.all_arcs_from_a_to_b(
+                list_arcs = gis_iden.get_edges_from_a_to_b(
                     network, 
                     node_start=node_one, 
                     node_end=node_two
@@ -1731,4 +1729,4 @@ def create_reverse_edges(
     return edges_created
         
 # *****************************************************************************
-# *****************************************************************************
\ No newline at end of file
+# *****************************************************************************
diff --git a/src/topupopt/data/gis/utils.py b/src/topupopt/data/gis/utils.py
index 3ea3216831bfce713379e76e5e6ea4fbe74103a8..2e6e0826b0a0c2a33632def5deeac60545b3fc07 100644
--- a/src/topupopt/data/gis/utils.py
+++ b/src/topupopt/data/gis/utils.py
@@ -928,7 +928,7 @@ def identify_building_entrance_arcs(
         
     node_keys = list(node_key_to_gdf_index_dict.keys()) 
     
-    closest_arc_keys, network = gis_iden.identify_arc_closest_to_node(
+    closest_arc_keys, network = gis_iden.identify_edge_closest_to_node(
         network=network,
         node_keys=node_keys,
         crs=crs) # do not revert back to the original yet
@@ -1032,14 +1032,14 @@ def identify_building_entrance_arcs(
         
         # get adjacent/neighbouring arcs
         
-        other_arcs = gis_iden.all_arcs_involving_node(
+        other_arcs = gis_iden.get_edges_involving_node(
             network=network,
             node_key=closest_arc_key[0],
             include_self_loops=False
             )
         
         other_arcs.extend(
-            gis_iden.all_arcs_involving_node(
+            gis_iden.get_edges_involving_node(
                 network=network,
                 node_key=closest_arc_key[1],
                 include_self_loops=False
@@ -1215,4 +1215,4 @@ def convert_edge_path(edge_path: list) -> list:
         return out
     
 #******************************************************************************
-#******************************************************************************
\ No newline at end of file
+#******************************************************************************
diff --git a/tests/examples_gis.py b/tests/examples_gis.py
index c90190e2f5fb5891a9642a39e1a0b334b76b8241..9a8d30a3adc6d71e6ee59c1544f5930294d07bce 100644
--- a/tests/examples_gis.py
+++ b/tests/examples_gis.py
@@ -652,7 +652,7 @@ def example_roundabouts_protocol(network: nx.MultiDiGraph,
             # if it is not in the roundabout itself
             if other_node_key not in original_roundabout_nodes 
             # for each arc between the two nodes
-            for edge_key in gis_ident.all_arcs_between_two_nodes(
+            for edge_key in gis_ident.get_edges_between_two_nodes(
                     network, 
                     node_key, 
                     other_node_key) 
@@ -769,7 +769,7 @@ def example_roundabouts_protocol(network: nx.MultiDiGraph,
                     
                     for ra_i in roundabout_candidates:
                         
-                        for arc_key in gis_ident.all_arcs_from_a_to_b(
+                        for arc_key in gis_ident.get_edges_from_a_to_b(
                                 network, 
                                 edge_key[0], 
                                 new_roundabout_nodes[ra_i]):
@@ -804,7 +804,7 @@ def example_roundabouts_protocol(network: nx.MultiDiGraph,
                     
                     for ra_i in roundabout_candidates:
                         
-                        for arc_key in gis_ident.all_arcs_from_a_to_b(
+                        for arc_key in gis_ident.get_edges_from_a_to_b(
                                 network, 
                                 new_roundabout_nodes[ra_i],
                                 edge_key[1]):
@@ -856,7 +856,7 @@ def example_roundabouts_protocol(network: nx.MultiDiGraph,
                 
                 for ra_i in roundabout_candidates:
                     
-                    for arc_key in gis_ident.all_arcs_from_a_to_b(
+                    for arc_key in gis_ident.get_edges_from_a_to_b(
                             network, 
                             edge_key[0], 
                             new_roundabout_nodes[ra_i]):
@@ -893,7 +893,7 @@ def example_roundabouts_protocol(network: nx.MultiDiGraph,
                 
                 for ra_i in roundabout_candidates:
                     
-                    for arc_key in gis_ident.all_arcs_from_a_to_b(
+                    for arc_key in gis_ident.get_edges_from_a_to_b(
                             network, 
                             new_roundabout_nodes[ra_i],
                             edge_key[1]):
@@ -945,7 +945,7 @@ def example_roundabouts_protocol(network: nx.MultiDiGraph,
             
                 for ra_si_i in roundabout_candidates_sink:
                 
-                    for arc_key in gis_ident.all_arcs_from_a_to_b(
+                    for arc_key in gis_ident.get_edges_from_a_to_b(
                             network, 
                             new_roundabout_nodes[ra_so_i],
                             new_roundabout_nodes[ra_si_i]):
@@ -1011,7 +1011,7 @@ def example_intermediate_nodes_along_path(network: nx.MultiDiGraph,
         
         # replace the path
         
-        gis_mod.old_replace_path(network, 
+        gis_mod.replace_path(network, 
                              path, 
                              path_as_arc_keys=return_paths_as_arc_keys)
                 
@@ -1105,7 +1105,7 @@ def example_removal_redundant_arcs(seed_number: int = None):
     for arc in network.edges(keys=True):
         
         assert len(
-            gis_ident.all_arcs_from_a_to_b(network,arc[0],arc[1])
+            gis_ident.get_edges_from_a_to_b(network,arc[0],arc[1])
             ) == 1
     
     #**************************************************************************
diff --git a/tests/examples_gis_utils.py b/tests/examples_gis_utils.py
index c628dcd9da81f17dd23bab77387a3617efdfa6d9..d591726383f89e67fc6322a93c21ffac7b0a7c0b 100644
--- a/tests/examples_gis_utils.py
+++ b/tests/examples_gis_utils.py
@@ -933,7 +933,7 @@ def example_identify_entrances_simple_no_driveway_closest():
     
     # find out which is the closest arc
     
-    nearest_arc_keys, network = gis_iden.identify_arc_closest_to_node(
+    nearest_arc_keys, network = gis_iden.identify_edge_closest_to_node(
         network,
         node_keys=['P'])
     
@@ -2025,7 +2025,7 @@ def example_get_directed(network: nx.MultiDiGraph):
     
         edge_dict = directed_network.edges[edge_key]
         
-        for other_edge_key in gis_iden.all_arcs_from_a_to_b(
+        for other_edge_key in gis_iden.get_edges_from_a_to_b(
                 network, edge_key[0], edge_key[1]):
             
             # check all attributes
@@ -2060,4 +2060,4 @@ def example_get_directed(network: nx.MultiDiGraph):
         assert number_matching_attributes == len(edge_dict)
             
 #******************************************************************************
-#******************************************************************************
\ No newline at end of file
+#******************************************************************************
diff --git a/tests/test_gis_identify.py b/tests/test_gis_identify.py
index 7377f038a036cdcce9996bf8da9e509377faee67..90b5637dd82ee3d7cfba1f3a71b3768606b84c57 100644
--- a/tests/test_gis_identify.py
+++ b/tests/test_gis_identify.py
@@ -29,8 +29,7 @@ class TestGisIdentify:
             network: nx.MultiDiGraph, 
             path: list, 
             excluded_nodes: list,
-            paths_must_be_oneway: bool = True,
-            paths_must_be_unique: bool = True):    
+            consider_reversed_edges: bool):    
         # find out the unique nodes
         set_nodes = set(path)
         # at least three nodes
@@ -40,7 +39,7 @@ class TestGisIdentify:
             # count the nodes
             node_count = path.count(node)
             if node_count >= 3:
-                # the same node cannot appear three times
+                # the same node cannot appear three or more times
                 assert False
             elif node_count == 2:
                 # cycle: the first and last nodes must match
@@ -49,542 +48,1712 @@ class TestGisIdentify:
         # no excluded nodes in the intermediate positions
         for node in excluded_nodes:
             assert node not in path[1:-1]
-        # make sure it qualifies as a pth
-        if paths_must_be_oneway and paths_must_be_oneway:
-            assert gis_iden.is_node_path(network, path)
-    
+        # make sure it qualifies as a path
+        assert gis_iden.is_node_path(
+            network, 
+            path, 
+            consider_reversed_edges=consider_reversed_edges
+            )
+
     # *************************************************************************
     # *************************************************************************
     
-    def test_find_straight_paths_case_a(self):
+    def test_find_straight_path_empty_graph(self):
+        
+        # test variations:
+        # 1) excluded nodes
+        # 2) self loops
+        # 3) reversed edges
         
-        # case a:
-        paths_must_be_oneway = True     # reverse-parallel arcs prevent paths
-        paths_must_be_unique = True     # anti-/parallel arcs prevent paths
+        # *********************************************************************
+        # *********************************************************************
         
-        # network without straight paths
+        # network with a two edge path
         network = nx.MultiDiGraph()
+                
+        # no reversed edges, no self loops, no excluded nodes
+        consider_reversed_edges = False
+        ignore_self_loops = False
         excluded_nodes = []
-        straight_paths = gis_iden.find_straight_paths(
+        
+        # test path validator with non-path
+        error_raised = False
+        try:
+            assert not self.path_validator(
+                network, 
+                [1, 1, 1], 
+                excluded_nodes, 
+                False
+                )
+        except AssertionError:
+            error_raised = True
+        assert error_raised       
+        
+        straight_paths = gis_iden.find_simplifiable_paths(
             network, 
             excluded_nodes,
-            paths_must_be_oneway=paths_must_be_oneway,
-            paths_must_be_unique=paths_must_be_unique
+            consider_reversed_edges=consider_reversed_edges,
+            ignore_self_loops=ignore_self_loops
             )
         true_straight_paths = []
         assert len(straight_paths) == len(true_straight_paths)
         assert len(straight_paths) == 0
-    
+            
         # *********************************************************************
-    
-        # network with the simplest straight path
-        network = nx.MultiDiGraph()
-        network.add_edges_from([
-            (0, 1, 0),
-            (1, 2, 0),
-            # simple cycle
-            (3, 4, 0),
-            (4, 5, 0),
-            (5, 3, 0),
-            # two node loop >> not a straight path because it is not one-way
-            (6, 7, 0),
-            (7, 6, 0)
-            ])
+        # *********************************************************************
+                
+        # no reversed edges, no self loops, no excluded nodes
+        consider_reversed_edges = False
+        ignore_self_loops = True
         excluded_nodes = []
-        straight_paths = gis_iden.find_straight_paths(
+        
+        straight_paths = gis_iden.find_simplifiable_paths(
             network, 
             excluded_nodes,
-            paths_must_be_oneway=paths_must_be_oneway,
-            paths_must_be_unique=paths_must_be_unique
+            consider_reversed_edges=consider_reversed_edges,
+            ignore_self_loops=ignore_self_loops
             )
-        true_straight_paths = [[0, 1, 2], [3, 4, 5, 3]]
+        true_straight_paths = []
         assert len(straight_paths) == len(true_straight_paths)
-        for straight_path in straight_paths:
-            assert straight_path in true_straight_paths
-            self.path_validator(network, straight_path, excluded_nodes)
-            
-        # try a path in which a node appears three times
+        assert len(straight_paths) == 0
         
-        error_raised = False
-        try:
-            self.path_validator(network, [0, 1, 2, 1, 3, 1], excluded_nodes)
-        except AssertionError:
-            error_raised = True
-        assert error_raised
-    
         # *********************************************************************
-    
-        # network with longer path
+        # *********************************************************************
+        
+        # network with a two edge path
         network = nx.MultiDiGraph()
-        network.add_edges_from([
-            (0, 1, 0),
-            (1, 2, 0),
-            (2, 3, 0),
-            #
-            (4, 5, 0),
-            (5, 6, 0),
-            (6, 7, 0),
-            (7, 8, 0)
-            ])
+        
+        # no reversed edges, no self loops, no excluded nodes
+        consider_reversed_edges = True
+        ignore_self_loops = False
         excluded_nodes = []
-        straight_paths = gis_iden.find_straight_paths(
+        
+        straight_paths = gis_iden.find_simplifiable_paths(
             network, 
             excluded_nodes,
-            paths_must_be_oneway=paths_must_be_oneway,
-            paths_must_be_unique=paths_must_be_unique
+            consider_reversed_edges=consider_reversed_edges,
+            ignore_self_loops=ignore_self_loops
             )
-        true_straight_paths = [[0, 1, 2, 3], [4, 5, 6, 7, 8]]
+        true_straight_paths = []
         assert len(straight_paths) == len(true_straight_paths)
-        for straight_path in straight_paths:
-            assert straight_path in true_straight_paths
-            self.path_validator(network, straight_path, excluded_nodes)
+        assert len(straight_paths) == 0
         
-        #**************************************************************************
-    
-        # network with excluded nodes
-    
+        # *********************************************************************
+        # *********************************************************************
+        
+        # network with a two edge path
         network = nx.MultiDiGraph()
-        network.add_edges_from([
-            (0, 1, 0),
-            (1, 2, 0),
-            (2, 3, 0),
-            (3, 4, 0),
-            ])
-        excluded_nodes = [2]
-        straight_paths = gis_iden.find_straight_paths(
+        
+        # no reversed edges, no self loops, no excluded nodes
+        consider_reversed_edges = True
+        ignore_self_loops = True
+        excluded_nodes = []
+        
+        straight_paths = gis_iden.find_simplifiable_paths(
             network, 
             excluded_nodes,
-            paths_must_be_oneway=paths_must_be_oneway,
-            paths_must_be_unique=paths_must_be_unique
+            consider_reversed_edges=consider_reversed_edges,
+            ignore_self_loops=ignore_self_loops
             )
-        true_straight_paths = [[0, 1, 2], [2, 3, 4]]
+        true_straight_paths = []
         assert len(straight_paths) == len(true_straight_paths)
-        for straight_path in straight_paths:
-            assert straight_path in true_straight_paths
-            self.path_validator(network, straight_path, excluded_nodes)
-    
-        #**************************************************************************
+        assert len(straight_paths) == 0
+        
+        # *********************************************************************
+        # ********************************************************************* 
+        
+        # enhance test coverage
+        
+        # add single node
+        network.add_node(0)
+        
+        path = gis_iden._find_path_direction_insensitive(network, [], 0)
+        assert type(path) == list
+        assert len(path) == 1
+        assert repr(path) == repr([0])
+        
+    # *************************************************************************
+    # *************************************************************************
     
-        # network with self loops and excluded nodes
+    def test_find_one_edge_path(self):
     
+        # *********************************************************************
+        # *********************************************************************
+        
+        # network with a two edge path
         network = nx.MultiDiGraph()
         network.add_edges_from([
-            (0, 1, 0),
-            (2, 2, 0),
-            (1, 2, 0),
-            (2, 3, 0),
-            (3, 3, 0),
-            (3, 4, 0),
+            (0, 1, 0)
             ])
-        excluded_nodes = [2]
-        straight_paths = gis_iden.find_straight_paths(
+    
+        # *********************************************************************
+        # *********************************************************************
+        
+        # do not consider reversed edges
+        consider_reversed_edges = False
+        
+        # *********************************************************************
+        # *********************************************************************
+        
+        # no reversed edges, no self loops, no excluded nodes
+        ignore_self_loops = False
+        excluded_nodes = []
+        
+        straight_paths = gis_iden.find_simplifiable_paths(
             network, 
             excluded_nodes,
-            paths_must_be_oneway=paths_must_be_oneway,
-            paths_must_be_unique=paths_must_be_unique
+            consider_reversed_edges=consider_reversed_edges,
+            ignore_self_loops=ignore_self_loops
             )
-        true_straight_paths = [[0, 1, 2], [2, 3, 4]]
+        true_straight_paths = []
         assert len(straight_paths) == len(true_straight_paths)
-        for straight_path in straight_paths:
-            assert straight_path in true_straight_paths
-            self.path_validator(network, straight_path, excluded_nodes)
-    
-        #**************************************************************************
-    
-        # network with parallel arcs
+            
+        # *********************************************************************
+        # *********************************************************************
+            
+        # no reversed edges, allow self loops, no excluded nodes
+        ignore_self_loops = True
+        excluded_nodes = []
         
-        network = nx.MultiDiGraph()
-        network.add_edges_from([
-            (0, 1, 0),
-            (1, 2, 0),
-            (0, 1, 1),
-            (2, 3, 0),
-            (3, 4, 0),
-            ])
+        straight_paths = gis_iden.find_simplifiable_paths(
+            network, 
+            excluded_nodes,
+            consider_reversed_edges=consider_reversed_edges,
+            ignore_self_loops=ignore_self_loops
+            )
+        true_straight_paths = []
+        assert len(straight_paths) == len(true_straight_paths)
+            
+        # *********************************************************************
+        # *********************************************************************
+            
+        # do not allow reversed edges, no self loops, excluded the middle node
+        ignore_self_loops = False
+        excluded_nodes = [1]
+        
+        straight_paths = gis_iden.find_simplifiable_paths(
+            network, 
+            excluded_nodes,
+            consider_reversed_edges=consider_reversed_edges,
+            ignore_self_loops=ignore_self_loops
+            )
+        true_straight_paths = []
+        assert len(straight_paths) == len(true_straight_paths)
+            
+        # *********************************************************************
+        # *********************************************************************
+            
+        # do not allow reversed edges, no self loops, excluded the start node
+        ignore_self_loops = False
+        excluded_nodes = [0]
+        
+        straight_paths = gis_iden.find_simplifiable_paths(
+            network, 
+            excluded_nodes,
+            consider_reversed_edges=consider_reversed_edges,
+            ignore_self_loops=ignore_self_loops
+            )
+        true_straight_paths = []
+        assert len(straight_paths) == len(true_straight_paths)
+            
+        # *********************************************************************
+        # *********************************************************************
+            
+        # do not allow reversed edges, no self loops, excluded the end node
+        ignore_self_loops = False
         excluded_nodes = [2]
-        straight_paths = gis_iden.find_straight_paths(
+        
+        straight_paths = gis_iden.find_simplifiable_paths(
             network, 
             excluded_nodes,
-            paths_must_be_oneway=paths_must_be_oneway,
-            paths_must_be_unique=paths_must_be_unique
+            consider_reversed_edges=consider_reversed_edges,
+            ignore_self_loops=ignore_self_loops
             )
-        true_straight_paths = [[2,3,4]] # [0,1,2] involves parallel arcs
+        true_straight_paths = []
         assert len(straight_paths) == len(true_straight_paths)
-        for straight_path in straight_paths:
-            assert straight_path in true_straight_paths
-            self.path_validator(network, straight_path, excluded_nodes)
-    
-        #**************************************************************************
-    
-        # network with parallel and anti-parallel arcs
-    
-        network = nx.MultiDiGraph()
-        network.add_edges_from([
-            (0, 1, 0),
-            (1, 2, 0),
-            (0, 1, 1),
-            (1, 2, 1),
-            (2, 3, 0),
-            (3, 4, 0),
-            (3, 2, 0),
-            (4, 3, 0),
-            ])
+        
+        # *********************************************************************
+        # *********************************************************************
+        
+        # consider reversed edges
+        consider_reversed_edges = True
+        
+        # *********************************************************************
+        # *********************************************************************
+            
+        # allow reversed edges, allow self loops, no excluded nodes
+        ignore_self_loops = True
+        excluded_nodes = []
+        
+        straight_paths = gis_iden.find_simplifiable_paths(
+            network, 
+            excluded_nodes,
+            consider_reversed_edges=consider_reversed_edges,
+            ignore_self_loops=ignore_self_loops
+            )
+        true_straight_paths = []
+        assert len(straight_paths) == len(true_straight_paths)
+        
+        # *********************************************************************
+        # *********************************************************************
+            
+        # allow reversed edges, no self loops, no excluded nodes
+        ignore_self_loops = False
+        excluded_nodes = []
+        
+        straight_paths = gis_iden.find_simplifiable_paths(
+            network, 
+            excluded_nodes,
+            consider_reversed_edges=consider_reversed_edges,
+            ignore_self_loops=ignore_self_loops
+            )
+        true_straight_paths = []
+        assert len(straight_paths) == len(true_straight_paths)
+        
+        # *********************************************************************
+        # *********************************************************************
+            
+        # allow reversed edges, no self loops, excluded the middle node
+        ignore_self_loops = False
+        excluded_nodes = [1]
+        
+        straight_paths = gis_iden.find_simplifiable_paths(
+            network, 
+            excluded_nodes,
+            consider_reversed_edges=consider_reversed_edges,
+            ignore_self_loops=ignore_self_loops
+            )
+        true_straight_paths = []
+        assert len(straight_paths) == len(true_straight_paths)
+        
+        # *********************************************************************
+        # *********************************************************************
+            
+        # allow reversed edges, no self loops, excluded the start node
+        ignore_self_loops = False
+        excluded_nodes = [0]
+        
+        straight_paths = gis_iden.find_simplifiable_paths(
+            network, 
+            excluded_nodes,
+            consider_reversed_edges=consider_reversed_edges,
+            ignore_self_loops=ignore_self_loops
+            )
+        true_straight_paths = []
+        assert len(straight_paths) == len(true_straight_paths)
+        
+        # *********************************************************************
+        # *********************************************************************
+            
+        # allow reversed edges, no self loops, excluded the end node
+        ignore_self_loops = False
         excluded_nodes = [2]
-        straight_paths = gis_iden.find_straight_paths(
+        
+        straight_paths = gis_iden.find_simplifiable_paths(
             network, 
             excluded_nodes,
-            paths_must_be_oneway=paths_must_be_oneway,
-            paths_must_be_unique=paths_must_be_unique
+            consider_reversed_edges=consider_reversed_edges,
+            ignore_self_loops=ignore_self_loops
             )
-        true_straight_paths = [] # [0,1,2] has parallel arcs, [2,3,4] anti-parallel
+        true_straight_paths = []
         assert len(straight_paths) == len(true_straight_paths)
-        assert len(straight_paths) == 0
-          
-        #**************************************************************************
+        
+        # *********************************************************************
+        # *********************************************************************
+        
+    # *************************************************************************
+    # *************************************************************************
     
-        # network with cycles
+    def test_find_one_edge_path_w_reversed_edge(self):
     
+        # *********************************************************************
+        # *********************************************************************
+        
+        # network with a two edge path
         network = nx.MultiDiGraph()
         network.add_edges_from([
-            # simplest cycle (with reverse-parallel arcs)
-            (0, 1, 0),
-            (1, 0, 0),
-            # 3-node cycle (with/without reverse-/-parallel arcs)
-            (2, 3, 0),
-            (3, 4, 0),
-            (4, 2, 0),
-            # 2-node cycle (with parallel and reverse-parallel arcs)
-            (5, 6, 0),
-            (6, 5, 0),
-            (5, 6, 1),
-            (6, 5, 1),
-            # 3-node cycle (only without parallel arcs)
-            (7, 8, 0),
-            (8, 9, 0),
-            (9, 7, 0),
-            (9, 7, 1)
+            (0, 1, 0), (1, 0, 0)
             ])
+    
+        # *********************************************************************
+        # *********************************************************************
+        
+        # do not consider reversed edges
+        consider_reversed_edges = False
+        
+        # *********************************************************************
+        # *********************************************************************
+        
+        # no reversed edges, no self loops, no excluded nodes
+        ignore_self_loops = False
+        excluded_nodes = []
+        
+        straight_paths = gis_iden.find_simplifiable_paths(
+            network, 
+            excluded_nodes,
+            consider_reversed_edges=consider_reversed_edges,
+            ignore_self_loops=ignore_self_loops
+            )
+        true_straight_paths = []
+        assert len(straight_paths) == len(true_straight_paths)
+            
+        # *********************************************************************
+        # *********************************************************************
+            
+        # no reversed edges, allow self loops, no excluded nodes
+        ignore_self_loops = True
+        excluded_nodes = []
+        
+        straight_paths = gis_iden.find_simplifiable_paths(
+            network, 
+            excluded_nodes,
+            consider_reversed_edges=consider_reversed_edges,
+            ignore_self_loops=ignore_self_loops
+            )
+        true_straight_paths = []
+        assert len(straight_paths) == len(true_straight_paths)
+            
+        # *********************************************************************
+        # *********************************************************************
+            
+        # do not allow reversed edges, no self loops, excluded the middle node
+        ignore_self_loops = False
+        excluded_nodes = [1]
+        
+        straight_paths = gis_iden.find_simplifiable_paths(
+            network, 
+            excluded_nodes,
+            consider_reversed_edges=consider_reversed_edges,
+            ignore_self_loops=ignore_self_loops
+            )
+        true_straight_paths = []
+        assert len(straight_paths) == len(true_straight_paths)
+            
+        # *********************************************************************
+        # *********************************************************************
+            
+        # do not allow reversed edges, no self loops, excluded the start node
+        ignore_self_loops = False
+        excluded_nodes = [0]
+        
+        straight_paths = gis_iden.find_simplifiable_paths(
+            network, 
+            excluded_nodes,
+            consider_reversed_edges=consider_reversed_edges,
+            ignore_self_loops=ignore_self_loops
+            )
+        true_straight_paths = []
+        assert len(straight_paths) == len(true_straight_paths)
+            
+        # *********************************************************************
+        # *********************************************************************
+            
+        # do not allow reversed edges, no self loops, excluded the end node
+        ignore_self_loops = False
+        excluded_nodes = [2]
+        
+        straight_paths = gis_iden.find_simplifiable_paths(
+            network, 
+            excluded_nodes,
+            consider_reversed_edges=consider_reversed_edges,
+            ignore_self_loops=ignore_self_loops
+            )
+        true_straight_paths = []
+        assert len(straight_paths) == len(true_straight_paths)
+        
+        # *********************************************************************
+        # *********************************************************************
+        
+        # consider reversed edges
+        consider_reversed_edges = True
+        
+        # *********************************************************************
+        # *********************************************************************
+            
+        # allow reversed edges, allow self loops, no excluded nodes
+        ignore_self_loops = True
+        excluded_nodes = []
+        
+        straight_paths = gis_iden.find_simplifiable_paths(
+            network, 
+            excluded_nodes,
+            consider_reversed_edges=consider_reversed_edges,
+            ignore_self_loops=ignore_self_loops
+            )
+        true_straight_paths = []
+        assert len(straight_paths) == len(true_straight_paths)
+        
+        # *********************************************************************
+        # *********************************************************************
+            
+        # allow reversed edges, no self loops, no excluded nodes
+        ignore_self_loops = False
+        excluded_nodes = []
+        
+        straight_paths = gis_iden.find_simplifiable_paths(
+            network, 
+            excluded_nodes,
+            consider_reversed_edges=consider_reversed_edges,
+            ignore_self_loops=ignore_self_loops
+            )
+        true_straight_paths = []
+        assert len(straight_paths) == len(true_straight_paths)
+        
+        # *********************************************************************
+        # *********************************************************************
+            
+        # allow reversed edges, no self loops, excluded the middle node
+        ignore_self_loops = False
+        excluded_nodes = [1]
+        
+        straight_paths = gis_iden.find_simplifiable_paths(
+            network, 
+            excluded_nodes,
+            consider_reversed_edges=consider_reversed_edges,
+            ignore_self_loops=ignore_self_loops
+            )
+        true_straight_paths = []
+        assert len(straight_paths) == len(true_straight_paths)
+        
+        # *********************************************************************
+        # *********************************************************************
+            
+        # allow reversed edges, no self loops, excluded the start node
+        ignore_self_loops = False
+        excluded_nodes = [0]
+        
+        straight_paths = gis_iden.find_simplifiable_paths(
+            network, 
+            excluded_nodes,
+            consider_reversed_edges=consider_reversed_edges,
+            ignore_self_loops=ignore_self_loops
+            )
+        true_straight_paths = []
+        assert len(straight_paths) == len(true_straight_paths)
+        
+        # *********************************************************************
+        # *********************************************************************
+            
+        # allow reversed edges, no self loops, excluded the end node
+        ignore_self_loops = False
+        excluded_nodes = [2]
+        
+        straight_paths = gis_iden.find_simplifiable_paths(
+            network, 
+            excluded_nodes,
+            consider_reversed_edges=consider_reversed_edges,
+            ignore_self_loops=ignore_self_loops
+            )
+        true_straight_paths = []
+        assert len(straight_paths) == len(true_straight_paths)
+        
+        # *********************************************************************
+        # *********************************************************************
+
+    # *************************************************************************
+    # *************************************************************************
+    
+    def test_find_simple_straight_path(self):
+    
+        # *********************************************************************
+        # *********************************************************************
+        
+        # network with a two edge path
+        network = nx.MultiDiGraph()
+        network.add_edges_from([
+            (0, 1, 0), (1, 2, 0)
+            ])
+    
+        # *********************************************************************
+        # *********************************************************************
+        
+        # do not consider reversed edges
+        consider_reversed_edges = False
+        
+        # *********************************************************************
+        # *********************************************************************
+        
+        # no reversed edges, no self loops, no excluded nodes
+        ignore_self_loops = False
+        excluded_nodes = []
+        
+        straight_paths = gis_iden.find_simplifiable_paths(
+            network, 
+            excluded_nodes,
+            consider_reversed_edges=consider_reversed_edges,
+            ignore_self_loops=ignore_self_loops
+            )
+        true_straight_paths = [[0, 1, 2]]
+        assert len(straight_paths) == len(true_straight_paths)
+        for straight_path in straight_paths:
+            assert straight_path in true_straight_paths
+            self.path_validator(
+                network, 
+                straight_path, 
+                excluded_nodes,
+                consider_reversed_edges=consider_reversed_edges
+                )
+            
+        # *********************************************************************
+        # *********************************************************************
+            
+        # no reversed edges, allow self loops, no excluded nodes
+        ignore_self_loops = True
+        excluded_nodes = []
+        
+        straight_paths = gis_iden.find_simplifiable_paths(
+            network, 
+            excluded_nodes,
+            consider_reversed_edges=consider_reversed_edges,
+            ignore_self_loops=ignore_self_loops
+            )
+        true_straight_paths = [[0, 1, 2]]
+        assert len(straight_paths) == len(true_straight_paths)
+        for straight_path in straight_paths:
+            assert straight_path in true_straight_paths
+            self.path_validator(
+                network, 
+                straight_path, 
+                excluded_nodes,
+                consider_reversed_edges=consider_reversed_edges
+                )
+            
+        # *********************************************************************
+        # *********************************************************************
+            
+        # do not allow reversed edges, no self loops, excluded the middle node
+        ignore_self_loops = False
+        excluded_nodes = [1]
+        
+        straight_paths = gis_iden.find_simplifiable_paths(
+            network, 
+            excluded_nodes,
+            consider_reversed_edges=consider_reversed_edges,
+            ignore_self_loops=ignore_self_loops
+            )
+        true_straight_paths = []
+        assert len(straight_paths) == len(true_straight_paths)
+        
+        # *********************************************************************
+        # *********************************************************************
+            
+        # do not allow reversed edges, no self loops, excluded the start node
+        ignore_self_loops = False
+        excluded_nodes = [0]
+        
+        straight_paths = gis_iden.find_simplifiable_paths(
+            network, 
+            excluded_nodes,
+            consider_reversed_edges=consider_reversed_edges,
+            ignore_self_loops=ignore_self_loops
+            )
+        true_straight_paths = [[0, 1, 2]]
+        assert len(straight_paths) == len(true_straight_paths)
+        for straight_path in straight_paths:
+            assert straight_path in true_straight_paths
+            self.path_validator(
+                network, 
+                straight_path, 
+                excluded_nodes,
+                consider_reversed_edges=consider_reversed_edges
+                )
+            
+        # *********************************************************************
+        # *********************************************************************
+            
+        # do not allow reversed edges, no self loops, excluded the end node
+        ignore_self_loops = False
+        excluded_nodes = [2]
+        
+        straight_paths = gis_iden.find_simplifiable_paths(
+            network, 
+            excluded_nodes,
+            consider_reversed_edges=consider_reversed_edges,
+            ignore_self_loops=ignore_self_loops
+            )
+        true_straight_paths = [[0, 1, 2]]
+        assert len(straight_paths) == len(true_straight_paths)
+        for straight_path in straight_paths:
+            assert straight_path in true_straight_paths
+            self.path_validator(
+                network, 
+                straight_path, 
+                excluded_nodes,
+                consider_reversed_edges=consider_reversed_edges
+                )
+        
+        # *********************************************************************
+        # *********************************************************************
+        
+        # consider reversed edges
+        consider_reversed_edges = True
+        
+        # *********************************************************************
+        # *********************************************************************
+            
+        # allow reversed edges, allow self loops, no excluded nodes
+        ignore_self_loops = True
+        excluded_nodes = []
+        
+        straight_paths = gis_iden.find_simplifiable_paths(
+            network, 
+            excluded_nodes,
+            consider_reversed_edges=consider_reversed_edges,
+            ignore_self_loops=ignore_self_loops
+            )
+        true_straight_paths = [[0, 1, 2], [2, 1, 0]]
+        assert len(straight_paths) == len(true_straight_paths)-1
+        for straight_path in straight_paths:
+            assert straight_path in true_straight_paths
+            self.path_validator(
+                network, 
+                straight_path, 
+                excluded_nodes,
+                consider_reversed_edges=consider_reversed_edges
+                )
+        
+        # *********************************************************************
+        # *********************************************************************
+            
+        # allow reversed edges, no self loops, no excluded nodes
+        ignore_self_loops = False
+        excluded_nodes = []
+        
+        straight_paths = gis_iden.find_simplifiable_paths(
+            network, 
+            excluded_nodes,
+            consider_reversed_edges=consider_reversed_edges,
+            ignore_self_loops=ignore_self_loops
+            )
+        true_straight_paths = [[0, 1, 2], [2, 1, 0]]
+        assert len(straight_paths) == len(true_straight_paths)-1
+        for straight_path in straight_paths:
+            assert straight_path in true_straight_paths
+            self.path_validator(
+                network, 
+                straight_path, 
+                excluded_nodes,
+                consider_reversed_edges=consider_reversed_edges
+                )
+        
+        # *********************************************************************
+        # *********************************************************************
+            
+        # allow reversed edges, no self loops, excluded the middle node
+        ignore_self_loops = False
+        excluded_nodes = [1]
+        
+        straight_paths = gis_iden.find_simplifiable_paths(
+            network, 
+            excluded_nodes,
+            consider_reversed_edges=consider_reversed_edges,
+            ignore_self_loops=ignore_self_loops
+            )
+        true_straight_paths = []
+        assert len(straight_paths) == len(true_straight_paths)
+        
+        # *********************************************************************
+        # *********************************************************************
+            
+        # allow reversed edges, no self loops, excluded the start node
+        ignore_self_loops = False
+        excluded_nodes = [0]
+        
+        straight_paths = gis_iden.find_simplifiable_paths(
+            network, 
+            excluded_nodes,
+            consider_reversed_edges=consider_reversed_edges,
+            ignore_self_loops=ignore_self_loops
+            )
+        true_straight_paths = [[0, 1, 2], [2, 1, 0]]
+        assert len(straight_paths) == len(true_straight_paths)-1
+        for straight_path in straight_paths:
+            assert straight_path in true_straight_paths
+            self.path_validator(
+                network, 
+                straight_path, 
+                excluded_nodes,
+                consider_reversed_edges=consider_reversed_edges
+                )
+        
+        # *********************************************************************
+        # *********************************************************************
+            
+        # allow reversed edges, no self loops, excluded the end node
+        ignore_self_loops = False
+        excluded_nodes = [2]
+        
+        straight_paths = gis_iden.find_simplifiable_paths(
+            network, 
+            excluded_nodes,
+            consider_reversed_edges=consider_reversed_edges,
+            ignore_self_loops=ignore_self_loops
+            )
+        true_straight_paths = [[0, 1, 2], [2, 1, 0]]
+        assert len(straight_paths) == len(true_straight_paths)-1
+        for straight_path in straight_paths:
+            assert straight_path in true_straight_paths
+            self.path_validator(
+                network, 
+                straight_path, 
+                excluded_nodes,
+                consider_reversed_edges=consider_reversed_edges
+                )
+        
+        # *********************************************************************
+        # *********************************************************************
+        
+    # *************************************************************************
+    # *************************************************************************
+    
+    def test_find_simple_straight_path_with_antiparallel_edge(self):
+    
+        # *********************************************************************
+        # *********************************************************************
+        
+        # network with a two edge path
+        network = nx.MultiDiGraph()
+        network.add_edges_from([
+            (0, 1, 0), (1, 2, 0), (2, 1, 0)
+            ])
+    
+        # *********************************************************************
+        # *********************************************************************
+        
+        # do not consider reversed edges
+        consider_reversed_edges = False
+        
+        # *********************************************************************
+        # *********************************************************************
+        
+        # no reversed edges, no self loops, no excluded nodes
+        ignore_self_loops = False
+        excluded_nodes = []
+        
+        straight_paths = gis_iden.find_simplifiable_paths(
+            network, 
+            excluded_nodes,
+            consider_reversed_edges=consider_reversed_edges,
+            ignore_self_loops=ignore_self_loops
+            )
+        true_straight_paths = [[0, 1, 2]]
+        assert len(straight_paths) == len(true_straight_paths)
+        for straight_path in straight_paths:
+            assert straight_path in true_straight_paths
+            self.path_validator(
+                network, 
+                straight_path, 
+                excluded_nodes,
+                consider_reversed_edges=consider_reversed_edges
+                )
+            
+        # *********************************************************************
+        # *********************************************************************
+            
+        # no reversed edges, allow self loops, no excluded nodes
+        ignore_self_loops = True
+        excluded_nodes = []
+        
+        straight_paths = gis_iden.find_simplifiable_paths(
+            network, 
+            excluded_nodes,
+            consider_reversed_edges=consider_reversed_edges,
+            ignore_self_loops=ignore_self_loops
+            )
+        true_straight_paths = [[0, 1, 2]]
+        assert len(straight_paths) == len(true_straight_paths)
+        for straight_path in straight_paths:
+            assert straight_path in true_straight_paths
+            self.path_validator(
+                network, 
+                straight_path, 
+                excluded_nodes,
+                consider_reversed_edges=consider_reversed_edges
+                )
+            
+        # *********************************************************************
+        # *********************************************************************
+            
+        # do not allow reversed edges, no self loops, excluded the middle node
+        ignore_self_loops = False
+        excluded_nodes = [1]
+        
+        straight_paths = gis_iden.find_simplifiable_paths(
+            network, 
+            excluded_nodes,
+            consider_reversed_edges=consider_reversed_edges,
+            ignore_self_loops=ignore_self_loops
+            )
+        true_straight_paths = []
+        assert len(straight_paths) == len(true_straight_paths)
+            
+        # *********************************************************************
+        # *********************************************************************
+            
+        # do not allow reversed edges, no self loops, excluded the start node
+        ignore_self_loops = False
+        excluded_nodes = [0]
+        
+        straight_paths = gis_iden.find_simplifiable_paths(
+            network, 
+            excluded_nodes,
+            consider_reversed_edges=consider_reversed_edges,
+            ignore_self_loops=ignore_self_loops
+            )
+        true_straight_paths = [[0, 1, 2]]
+        assert len(straight_paths) == len(true_straight_paths)
+        for straight_path in straight_paths:
+            assert straight_path in true_straight_paths
+            self.path_validator(
+                network, 
+                straight_path, 
+                excluded_nodes,
+                consider_reversed_edges=consider_reversed_edges
+                )
+            
+        # *********************************************************************
+        # *********************************************************************
+            
+        # do not allow reversed edges, no self loops, excluded the end node
+        ignore_self_loops = False
+        excluded_nodes = [2]
+        
+        straight_paths = gis_iden.find_simplifiable_paths(
+            network, 
+            excluded_nodes,
+            consider_reversed_edges=consider_reversed_edges,
+            ignore_self_loops=ignore_self_loops
+            )
+        true_straight_paths = [[0, 1, 2]]
+        assert len(straight_paths) == len(true_straight_paths)
+        for straight_path in straight_paths:
+            assert straight_path in true_straight_paths
+            self.path_validator(
+                network, 
+                straight_path, 
+                excluded_nodes,
+                consider_reversed_edges=consider_reversed_edges
+                )
+        
+        # *********************************************************************
+        # *********************************************************************
+        
+        # consider reversed edges
+        consider_reversed_edges = True
+        
+        # *********************************************************************
+        # *********************************************************************
+            
+        # allow reversed edges, allow self loops, no excluded nodes
+        ignore_self_loops = True
+        excluded_nodes = []
+        
+        straight_paths = gis_iden.find_simplifiable_paths(
+            network, 
+            excluded_nodes,
+            consider_reversed_edges=consider_reversed_edges,
+            ignore_self_loops=ignore_self_loops
+            )
+        true_straight_paths = [[0, 1, 2], [2, 1, 0]]
+        assert len(straight_paths) == len(true_straight_paths)-1
+        for straight_path in straight_paths:
+            assert straight_path in true_straight_paths
+            self.path_validator(
+                network, 
+                straight_path, 
+                excluded_nodes,
+                consider_reversed_edges=consider_reversed_edges
+                )
+        
+        # *********************************************************************
+        # *********************************************************************
+            
+        # allow reversed edges, no self loops, no excluded nodes
+        ignore_self_loops = False
+        excluded_nodes = []
+        
+        straight_paths = gis_iden.find_simplifiable_paths(
+            network, 
+            excluded_nodes,
+            consider_reversed_edges=consider_reversed_edges,
+            ignore_self_loops=ignore_self_loops
+            )
+        true_straight_paths = [[0, 1, 2], [2, 1, 0]]
+        assert len(straight_paths) == len(true_straight_paths)-1
+        for straight_path in straight_paths:
+            assert straight_path in true_straight_paths
+            self.path_validator(
+                network, 
+                straight_path, 
+                excluded_nodes,
+                consider_reversed_edges=consider_reversed_edges
+                )
+        
+        # *********************************************************************
+        # *********************************************************************
+            
+        # allow reversed edges, no self loops, excluded the middle node
+        ignore_self_loops = False
+        excluded_nodes = [1]
+        
+        straight_paths = gis_iden.find_simplifiable_paths(
+            network, 
+            excluded_nodes,
+            consider_reversed_edges=consider_reversed_edges,
+            ignore_self_loops=ignore_self_loops
+            )
+        true_straight_paths = []
+        assert len(straight_paths) == len(true_straight_paths)
+        
+        # *********************************************************************
+        # *********************************************************************
+            
+        # allow reversed edges, no self loops, excluded the start node
+        ignore_self_loops = False
+        excluded_nodes = [0]
+        
+        straight_paths = gis_iden.find_simplifiable_paths(
+            network, 
+            excluded_nodes,
+            consider_reversed_edges=consider_reversed_edges,
+            ignore_self_loops=ignore_self_loops
+            )
+        true_straight_paths = [[0, 1, 2], [2, 1, 0]]
+        assert len(straight_paths) == len(true_straight_paths)-1
+        for straight_path in straight_paths:
+            assert straight_path in true_straight_paths
+            self.path_validator(
+                network, 
+                straight_path, 
+                excluded_nodes,
+                consider_reversed_edges=consider_reversed_edges
+                )
+        
+        # *********************************************************************
+        # *********************************************************************
+            
+        # allow reversed edges, no self loops, excluded the end node
+        ignore_self_loops = False
+        excluded_nodes = [2]
+        
+        straight_paths = gis_iden.find_simplifiable_paths(
+            network, 
+            excluded_nodes,
+            consider_reversed_edges=consider_reversed_edges,
+            ignore_self_loops=ignore_self_loops
+            )
+        true_straight_paths = [[0, 1, 2], [2, 1, 0]]
+        assert len(straight_paths) == len(true_straight_paths)-1
+        for straight_path in straight_paths:
+            assert straight_path in true_straight_paths
+            self.path_validator(
+                network, 
+                straight_path, 
+                excluded_nodes,
+                consider_reversed_edges=consider_reversed_edges
+                )
+        
+        # *********************************************************************
+        # *********************************************************************
+        
+    # *************************************************************************
+    # *************************************************************************
+    
+    def test_find_straight_path_cycle(self):
+        
+        # *********************************************************************
+        # *********************************************************************
+        
+        # network with a two edge path
+        network = nx.MultiDiGraph()
+        network.add_edges_from([
+            (0, 1, 0), (1, 2, 0), (2, 0, 0), (0, 2, 0), (1, 1, 0)
+            ])
+        
+        # *********************************************************************
+        # *********************************************************************
+        
+        # do not consider reversed edges
+        consider_reversed_edges = False
+            
+        # *********************************************************************
+        # *********************************************************************
+        
+        # no self loops, no excluded nodes
+        ignore_self_loops = False
+        excluded_nodes = []
+        
+        straight_paths = gis_iden.find_simplifiable_paths(
+            network, 
+            excluded_nodes,
+            consider_reversed_edges=consider_reversed_edges,
+            ignore_self_loops=ignore_self_loops
+            )
+        true_straight_paths = [[1, 2, 0, 1]]
+        assert len(straight_paths) == len(true_straight_paths)
+        for straight_path in straight_paths:
+            assert straight_path in true_straight_paths
+            self.path_validator(
+                network, 
+                straight_path, 
+                excluded_nodes,
+                consider_reversed_edges=consider_reversed_edges
+                )
+            
+        # *********************************************************************
+        # *********************************************************************
+            
+        # allow self loops, no excluded nodes
+        ignore_self_loops = True
+        excluded_nodes = []
+        
+        straight_paths = gis_iden.find_simplifiable_paths(
+            network, 
+            excluded_nodes,
+            consider_reversed_edges=consider_reversed_edges,
+            ignore_self_loops=ignore_self_loops
+            )
+        true_straight_paths = [[0, 1, 2, 0], [1, 2, 0, 1], [2, 1, 0, 2]]
+        assert len(straight_paths) == len(true_straight_paths)-2
+        for straight_path in straight_paths:
+            assert straight_path in true_straight_paths
+            self.path_validator(
+                network, 
+                straight_path, 
+                excluded_nodes,
+                consider_reversed_edges=consider_reversed_edges
+                )
+            
+        # *********************************************************************
+        # *********************************************************************
+            
+        # no self loops, excluded the "middle" node
+        ignore_self_loops = False
+        excluded_nodes = [1]
+        
+        straight_paths = gis_iden.find_simplifiable_paths(
+            network, 
+            excluded_nodes,
+            consider_reversed_edges=consider_reversed_edges,
+            ignore_self_loops=ignore_self_loops
+            )
+        true_straight_paths = [[1, 2, 0, 1]]
+        assert len(straight_paths) == len(true_straight_paths)
+        for straight_path in straight_paths:
+            assert straight_path in true_straight_paths
+            self.path_validator(
+                network, 
+                straight_path, 
+                excluded_nodes,
+                consider_reversed_edges=consider_reversed_edges
+                )
+            
+        # *********************************************************************
+        # *********************************************************************
+            
+        # no self loops, excluded the start node
+        ignore_self_loops = False
+        excluded_nodes = [0]
+        
+        straight_paths = gis_iden.find_simplifiable_paths(
+            network, 
+            excluded_nodes,
+            consider_reversed_edges=consider_reversed_edges,
+            ignore_self_loops=ignore_self_loops
+            )
+        true_straight_paths = [[1, 2, 0]]
+        assert len(straight_paths) == len(true_straight_paths)
+        for straight_path in straight_paths:
+            assert straight_path in true_straight_paths
+            self.path_validator(
+                network, 
+                straight_path, 
+                excluded_nodes,
+                consider_reversed_edges=consider_reversed_edges
+                )
+            
+        # *********************************************************************
+        # *********************************************************************
+            
+        # do not allow reversed edges, no self loops, excluded the end node
+        ignore_self_loops = False
+        excluded_nodes = [2]
+        
+        straight_paths = gis_iden.find_simplifiable_paths(
+            network, 
+            excluded_nodes,
+            consider_reversed_edges=consider_reversed_edges,
+            ignore_self_loops=ignore_self_loops
+            )
+        true_straight_paths = [[2, 0, 1]]
+        assert len(straight_paths) == len(true_straight_paths)
+        for straight_path in straight_paths:
+            assert straight_path in true_straight_paths
+            self.path_validator(
+                network, 
+                straight_path, 
+                excluded_nodes,
+                consider_reversed_edges=consider_reversed_edges
+                )
+            
+        # *********************************************************************
+        # *********************************************************************
+        
+        # consider reversed edges
+        consider_reversed_edges = True
+            
+        # *********************************************************************
+        # *********************************************************************
+            
+        # allow reversed edges, allow self loops, no excluded nodes
+        ignore_self_loops = True
+        excluded_nodes = []
+        
+        straight_paths = gis_iden.find_simplifiable_paths(
+            network, 
+            excluded_nodes,
+            consider_reversed_edges=consider_reversed_edges,
+            ignore_self_loops=ignore_self_loops
+            )
+        true_straight_paths = [[0, 1, 2, 0], [1, 2, 0, 1], [2, 1, 0, 2]]
+        assert len(straight_paths) == len(true_straight_paths)-2
+        for straight_path in straight_paths:
+            assert straight_path in true_straight_paths
+            self.path_validator(
+                network, 
+                straight_path, 
+                excluded_nodes,
+                consider_reversed_edges=consider_reversed_edges
+                )
+            
+        # *********************************************************************
+        # *********************************************************************
+            
+        # allow reversed edges, no self loops, no excluded nodes
+        ignore_self_loops = False
+        excluded_nodes = []
+        
+        straight_paths = gis_iden.find_simplifiable_paths(
+            network, 
+            excluded_nodes,
+            consider_reversed_edges=consider_reversed_edges,
+            ignore_self_loops=ignore_self_loops
+            )
+        true_straight_paths = [[1, 2, 0, 1], [1, 0, 2, 1]]
+        assert len(straight_paths) == len(true_straight_paths)-1 
+        for straight_path in straight_paths:
+            assert straight_path in true_straight_paths
+            self.path_validator(
+                network, 
+                straight_path, 
+                excluded_nodes,
+                consider_reversed_edges=consider_reversed_edges
+                )
+            
+        # *********************************************************************
+        # *********************************************************************
+            
+        # allow reversed edges, no self loops, excluded the middle node
+        ignore_self_loops = False
+        excluded_nodes = [1]
+        
+        straight_paths = gis_iden.find_simplifiable_paths(
+            network, 
+            excluded_nodes,
+            consider_reversed_edges=consider_reversed_edges,
+            ignore_self_loops=ignore_self_loops
+            )
+        true_straight_paths = [[1, 2, 0, 1], [1, 0, 2, 1]]
+        assert len(straight_paths) == len(true_straight_paths)-1
+        for straight_path in straight_paths:
+            assert straight_path in true_straight_paths
+            self.path_validator(
+                network, 
+                straight_path, 
+                excluded_nodes,
+                consider_reversed_edges=consider_reversed_edges
+                )
+            
+        # *********************************************************************
+        # *********************************************************************
+            
+        # allow reversed edges, no self loops, excluded the start node
+        ignore_self_loops = False
+        excluded_nodes = [0]
+        
+        straight_paths = gis_iden.find_simplifiable_paths(
+            network, 
+            excluded_nodes,
+            consider_reversed_edges=consider_reversed_edges,
+            ignore_self_loops=ignore_self_loops
+            )
+        true_straight_paths = [[1, 2, 0], [0, 2, 1]]
+        assert len(straight_paths) == len(true_straight_paths)-1
+        for straight_path in straight_paths:
+            assert straight_path in true_straight_paths
+            self.path_validator(
+                network, 
+                straight_path, 
+                excluded_nodes,
+                consider_reversed_edges=consider_reversed_edges
+                )
+            
+        # *********************************************************************
+        # *********************************************************************
+            
+        # allow reversed edges, no self loops, excluded the end node
+        ignore_self_loops = False
+        excluded_nodes = [2]
+        
+        straight_paths = gis_iden.find_simplifiable_paths(
+            network, 
+            excluded_nodes,
+            consider_reversed_edges=consider_reversed_edges,
+            ignore_self_loops=ignore_self_loops
+            )
+        true_straight_paths = [[1, 0, 2], [2, 0, 1]]
+        assert len(straight_paths) == len(true_straight_paths)-1
+        for straight_path in straight_paths:
+            assert straight_path in true_straight_paths
+            self.path_validator(
+                network, 
+                straight_path, 
+                excluded_nodes,
+                consider_reversed_edges=consider_reversed_edges
+                )
+            
+        # *********************************************************************
+        # *********************************************************************
+        
+    # *************************************************************************
+    # *************************************************************************
+    
+    def test_find_simple_straight_path_w_reversed_edge(self):
+    
+        # *********************************************************************
+        # *********************************************************************
+                
+        # network with a two edge path
+        network = nx.MultiDiGraph()
+        network.add_edges_from([
+            (0, 1, 0), (2, 1, 0)
+            ])
+            
+        # *********************************************************************
+        # *********************************************************************
+        
+        # consider reversed edges
+        consider_reversed_edges = False
+            
+        # *********************************************************************
+        # *********************************************************************
+        
+        # no reversed edges, no self loops, no excluded nodes
+        ignore_self_loops = False
+        excluded_nodes = []
+        
+        straight_paths = gis_iden.find_simplifiable_paths(
+            network, 
+            excluded_nodes,
+            consider_reversed_edges=consider_reversed_edges,
+            ignore_self_loops=ignore_self_loops
+            )
+        true_straight_paths = []
+        assert len(straight_paths) == len(true_straight_paths)
+            
+        # *********************************************************************
+        # *********************************************************************
+            
+        # no reversed edges, allow self loops, no excluded nodes
+        ignore_self_loops = True
+        excluded_nodes = []
+        
+        straight_paths = gis_iden.find_simplifiable_paths(
+            network, 
+            excluded_nodes,
+            consider_reversed_edges=consider_reversed_edges,
+            ignore_self_loops=ignore_self_loops
+            )
+        true_straight_paths = []
+        assert len(straight_paths) == len(true_straight_paths)
+            
+        # *********************************************************************
+        # *********************************************************************
+            
+        # do not allow reversed edges, no self loops, excluded the middle node
+        ignore_self_loops = False
+        excluded_nodes = [1]
+        
+        straight_paths = gis_iden.find_simplifiable_paths(
+            network, 
+            excluded_nodes,
+            consider_reversed_edges=consider_reversed_edges,
+            ignore_self_loops=ignore_self_loops
+            )
+        true_straight_paths = []
+        assert len(straight_paths) == len(true_straight_paths)
+            
+        # *********************************************************************
+        # *********************************************************************
+            
+        # do not allow reversed edges, no self loops, excluded the start node
+        ignore_self_loops = False
+        excluded_nodes = [0]
+        
+        straight_paths = gis_iden.find_simplifiable_paths(
+            network, 
+            excluded_nodes,
+            consider_reversed_edges=consider_reversed_edges,
+            ignore_self_loops=ignore_self_loops
+            )
+        true_straight_paths = []
+        assert len(straight_paths) == len(true_straight_paths)
+            
+        # *********************************************************************
+        # *********************************************************************
+            
+        # do not allow reversed edges, no self loops, excluded the end node
+        ignore_self_loops = False
+        excluded_nodes = [2]
+        
+        straight_paths = gis_iden.find_simplifiable_paths(
+            network, 
+            excluded_nodes,
+            consider_reversed_edges=consider_reversed_edges,
+            ignore_self_loops=ignore_self_loops
+            )
+        true_straight_paths = []
+        assert len(straight_paths) == len(true_straight_paths)
+            
+        # *********************************************************************
+        # *********************************************************************
+        
+        # consider reversed edges
+        consider_reversed_edges = True
+        
+        # *********************************************************************
+        # *********************************************************************
+        
+        # allow reversed edges, allow self loops, no excluded nodes
+        ignore_self_loops = True
+        excluded_nodes = []
+        
+        straight_paths = gis_iden.find_simplifiable_paths(
+            network, 
+            excluded_nodes,
+            consider_reversed_edges=consider_reversed_edges,
+            ignore_self_loops=ignore_self_loops
+            )
+        true_straight_paths = [[0, 1, 2], [2, 1, 0]]
+        assert len(straight_paths) == len(true_straight_paths)-1
+        for straight_path in straight_paths:
+            assert straight_path in true_straight_paths
+            self.path_validator(
+                network, 
+                straight_path, 
+                excluded_nodes,
+                consider_reversed_edges=consider_reversed_edges
+                )
+            
+        # *********************************************************************
+        # *********************************************************************
+            
+        # allow reversed edges, no self loops, no excluded nodes
+        ignore_self_loops = False
+        excluded_nodes = []
+        
+        straight_paths = gis_iden.find_simplifiable_paths(
+            network, 
+            excluded_nodes,
+            consider_reversed_edges=consider_reversed_edges,
+            ignore_self_loops=ignore_self_loops
+            )
+        true_straight_paths = [[0, 1, 2], [2, 1, 0]]
+        assert len(straight_paths) == len(true_straight_paths)-1
+        for straight_path in straight_paths:
+            assert straight_path in true_straight_paths
+            self.path_validator(
+                network, 
+                straight_path, 
+                excluded_nodes,
+                consider_reversed_edges=consider_reversed_edges
+                )
+        
+        # *********************************************************************
+        # *********************************************************************
+            
+        # allow reversed edges, no self loops, excluded the middle node
+        ignore_self_loops = False
+        excluded_nodes = [1]
+        
+        straight_paths = gis_iden.find_simplifiable_paths(
+            network, 
+            excluded_nodes,
+            consider_reversed_edges=consider_reversed_edges,
+            ignore_self_loops=ignore_self_loops
+            )
+        true_straight_paths = []
+        assert len(straight_paths) == len(true_straight_paths)
+            
+        # *********************************************************************
+        # *********************************************************************
+            
+        # allow reversed edges, no self loops, excluded the start node
+        ignore_self_loops = False
+        excluded_nodes = [0]
+        
+        straight_paths = gis_iden.find_simplifiable_paths(
+            network, 
+            excluded_nodes,
+            consider_reversed_edges=consider_reversed_edges,
+            ignore_self_loops=ignore_self_loops
+            )
+        true_straight_paths = [[0, 1, 2], [2, 1, 0]]
+        assert len(straight_paths) == len(true_straight_paths)-1
+        for straight_path in straight_paths:
+            assert straight_path in true_straight_paths
+            self.path_validator(
+                network, 
+                straight_path, 
+                excluded_nodes,
+                consider_reversed_edges=consider_reversed_edges
+                )
+            
+        # *********************************************************************
+        # *********************************************************************
+            
+        # allow reversed edges, no self loops, excluded the end node
+        ignore_self_loops = False
         excluded_nodes = [2]
-        straight_paths = gis_iden.find_straight_paths(
+        
+        straight_paths = gis_iden.find_simplifiable_paths(
             network, 
             excluded_nodes,
-            paths_must_be_oneway=paths_must_be_oneway,
-            paths_must_be_unique=paths_must_be_unique
+            consider_reversed_edges=consider_reversed_edges,
+            ignore_self_loops=ignore_self_loops
             )
-        # [0,1,0] or [1,0,1] are ruled out since they involve reverse-parallel arcs
-        # [5,6,5] or [6,5,6] are ruled out since they involve reverse/parallel arcs
-        # [7,8,9,7], etc are ruled out since they involve one parallel arc
-        true_straight_paths = [[2,3,4,2],[7,8,9]]
-        assert len(straight_paths) == len(true_straight_paths)
+        true_straight_paths = [[0, 1, 2], [2, 1, 0]]
+        assert len(straight_paths) == len(true_straight_paths)-1
         for straight_path in straight_paths:
             assert straight_path in true_straight_paths
-            self.path_validator(network, straight_path, excluded_nodes)
-    
+            self.path_validator(
+                network, 
+                straight_path, 
+                excluded_nodes,
+                consider_reversed_edges=consider_reversed_edges
+                )
+            
+        # *********************************************************************
+        # *********************************************************************
+        
     # *************************************************************************
     # *************************************************************************
     
-    def test_find_straight_paths_case_b(self):
-        
-        # case a:
-        paths_must_be_oneway = True     # anti-parallel arcs prevent paths
-        paths_must_be_unique = False    # parallel/anti-parallel arcs do not prevent paths
-        
-        # network without straight paths
-        network = nx.MultiDiGraph()
-        excluded_nodes = []
-        straight_paths = gis_iden.find_straight_paths(
-            network, 
-            excluded_nodes,
-            paths_must_be_oneway=paths_must_be_oneway,
-            paths_must_be_unique=paths_must_be_unique
-            )
-        true_straight_paths = []
-        assert len(straight_paths) == len(true_straight_paths)
-        assert len(straight_paths) == 0
-    
-        #**************************************************************************
+    def test_find_simple_straight_path_w_reversed_edge2(self):
     
-        # network with the simplest straight path
+        # *********************************************************************
+        # *********************************************************************
+                
+        # network with a two edge path
         network = nx.MultiDiGraph()
         network.add_edges_from([
-            (0, 1, 0),
-            (1, 2, 0),
-            # simple cycle
-            (3, 4, 0),
-            (4, 5, 0),
-            (5, 3, 0),
-            # invalid cycle
-            (6, 7, 0),
-            (7, 6, 0)
+            (1, 0, 0), (1, 2, 0)
             ])
+            
+        # *********************************************************************
+        # *********************************************************************
+        
+        # consider reversed edges
+        consider_reversed_edges = False
+            
+        # *********************************************************************
+        # *********************************************************************
+        
+        # no reversed edges, no self loops, no excluded nodes
+        ignore_self_loops = False
         excluded_nodes = []
-        straight_paths = gis_iden.find_straight_paths(
+        
+        straight_paths = gis_iden.find_simplifiable_paths(
             network, 
             excluded_nodes,
-            paths_must_be_oneway=paths_must_be_oneway,
-            paths_must_be_unique=paths_must_be_unique
+            consider_reversed_edges=consider_reversed_edges,
+            ignore_self_loops=ignore_self_loops
             )
-        true_straight_paths = [[0, 1, 2], [3, 4, 5, 3]]
+        true_straight_paths = []
         assert len(straight_paths) == len(true_straight_paths)
-        for straight_path in straight_paths:
-            assert straight_path in true_straight_paths
-            self.path_validator(network, straight_path, excluded_nodes)
-    
-        #**************************************************************************
-    
-        # network with longer path
-        network = nx.MultiDiGraph()
-        network.add_edges_from([
-            (0, 1, 0),
-            (1, 2, 0),
-            (2, 3, 0),
-            #
-            (4, 5, 0),
-            (5, 6, 0),
-            (6, 7, 0),
-            (7, 8, 0)
-            ])
+            
+        # *********************************************************************
+        # *********************************************************************
+            
+        # no reversed edges, allow self loops, no excluded nodes
+        ignore_self_loops = True
         excluded_nodes = []
-        straight_paths = gis_iden.find_straight_paths(
+        
+        straight_paths = gis_iden.find_simplifiable_paths(
             network, 
             excluded_nodes,
-            paths_must_be_oneway=paths_must_be_oneway,
-            paths_must_be_unique=paths_must_be_unique
+            consider_reversed_edges=consider_reversed_edges,
+            ignore_self_loops=ignore_self_loops
             )
-        true_straight_paths = [[0, 1, 2, 3], [4, 5, 6, 7, 8]]
+        true_straight_paths = []
         assert len(straight_paths) == len(true_straight_paths)
-        for straight_path in straight_paths:
-            assert straight_path in true_straight_paths
-            self.path_validator(network, straight_path, excluded_nodes)
+            
+        # *********************************************************************
+        # *********************************************************************
+            
+        # do not allow reversed edges, no self loops, excluded the middle node
+        ignore_self_loops = False
+        excluded_nodes = [1]
         
-        #**************************************************************************
-    
-        # network with excluded nodes
-        network = nx.MultiDiGraph()
-        network.add_edges_from([
-            (0, 1, 0),
-            (1, 2, 0),
-            (2, 3, 0),
-            (3, 4, 0),
-            # path involving reverse arcs
-            (6, 5, 0),
-            (6, 7, 0),
-            (8, 7, 0),
-            # another
-            (8, 9, 0),
-            (10, 9, 0),
-            (11, 10, 0),
-            # cycle
-            (12, 13, 0),
-            (14, 13, 0),
-            (15, 12, 0)
-            ])
-        excluded_nodes = [2]
-        straight_paths = gis_iden.find_straight_paths(
+        straight_paths = gis_iden.find_simplifiable_paths(
             network, 
             excluded_nodes,
-            paths_must_be_oneway=paths_must_be_oneway,
-            paths_must_be_unique=paths_must_be_unique
+            consider_reversed_edges=consider_reversed_edges,
+            ignore_self_loops=ignore_self_loops
             )
-        true_straight_paths = [[0, 1, 2], [2, 3, 4],[15, 12, 13],[11, 10, 9]]
+        true_straight_paths = []
         assert len(straight_paths) == len(true_straight_paths)
-        for straight_path in straight_paths:
-            assert straight_path in true_straight_paths
-            self.path_validator(network, straight_path, excluded_nodes)
-    
-        #**************************************************************************
-    
-        # network with self loops and excluded nodes
-        network = nx.MultiDiGraph()
-        network.add_edges_from([
-            (0, 1, 0),
-            (2, 2, 0),
-            (1, 2, 0),
-            (2, 3, 0),
-            (3, 3, 0),
-            (3, 4, 0),
-            ])
-        excluded_nodes = [2]
-        straight_paths = gis_iden.find_straight_paths(
+            
+        # *********************************************************************
+        # *********************************************************************
+            
+        # do not allow reversed edges, no self loops, excluded the start node
+        ignore_self_loops = False
+        excluded_nodes = [0]
+        
+        straight_paths = gis_iden.find_simplifiable_paths(
             network, 
             excluded_nodes,
-            paths_must_be_oneway=paths_must_be_oneway,
-            paths_must_be_unique=paths_must_be_unique
+            consider_reversed_edges=consider_reversed_edges,
+            ignore_self_loops=ignore_self_loops
             )
-        true_straight_paths = [[0, 1, 2], [2, 3, 4]]
+        true_straight_paths = []
         assert len(straight_paths) == len(true_straight_paths)
-        for straight_path in straight_paths:
-            assert straight_path in true_straight_paths
-            self.path_validator(network, straight_path, excluded_nodes)
-    
-        #**************************************************************************
-    
-        # network with parallel arcs
-        network = nx.MultiDiGraph()
-        network.add_edges_from([
-            (0, 1, 0),
-            (1, 2, 0),
-            (0, 1, 1),
-            (2, 3, 0),
-            (3, 4, 0),
-            # more parallel arcs
-            (5, 6, 0),
-            (6, 7, 0),
-            (5, 6, 1),
-            (6, 7, 1),
-            (7, 5, 0)
-            ])
+            
+        # *********************************************************************
+        # *********************************************************************
+            
+        # do not allow reversed edges, no self loops, excluded the end node
+        ignore_self_loops = False
         excluded_nodes = [2]
-        straight_paths = gis_iden.find_straight_paths(
+        
+        straight_paths = gis_iden.find_simplifiable_paths(
             network, 
             excluded_nodes,
-            paths_must_be_oneway=paths_must_be_oneway,
-            paths_must_be_unique=paths_must_be_unique
+            consider_reversed_edges=consider_reversed_edges,
+            ignore_self_loops=ignore_self_loops
             )
-        true_straight_paths = [[2,3,4],[0,1,2],[5,6,7,5]]
+        true_straight_paths = []
         assert len(straight_paths) == len(true_straight_paths)
-        for straight_path in straight_paths:
-            assert straight_path in true_straight_paths
-            self.path_validator(network, straight_path, excluded_nodes)
             
-        #**************************************************************************
-    
-        # network with parallel and anti-parallel arcs
-    
-        network = nx.MultiDiGraph()
-        network.add_edges_from([
-            (0, 1, 0),
-            (1, 2, 0),
-            (0, 1, 1),
-            (1, 2, 1),
-            (2, 3, 0),
-            (3, 4, 0),
-            (3, 2, 0),
-            (4, 3, 0),
-            ])
-        excluded_nodes = [2]
-        straight_paths = gis_iden.find_straight_paths(
+        # *********************************************************************
+        # *********************************************************************
+        
+        # consider reversed edges
+        consider_reversed_edges = True
+        
+        # *********************************************************************
+        # *********************************************************************
+        
+        # allow reversed edges, allow self loops, no excluded nodes
+        ignore_self_loops = True
+        excluded_nodes = []
+        
+        straight_paths = gis_iden.find_simplifiable_paths(
             network, 
             excluded_nodes,
-            paths_must_be_oneway=paths_must_be_oneway,
-            paths_must_be_unique=paths_must_be_unique
+            consider_reversed_edges=consider_reversed_edges,
+            ignore_self_loops=ignore_self_loops
             )
-        true_straight_paths = [[0,1,2]] # [2,3,4] has anti-parallel arcs
-        assert len(straight_paths) == len(true_straight_paths)
+        true_straight_paths = [[0, 1, 2], [2, 1, 0]]
+        assert len(straight_paths) == len(true_straight_paths)-1
         for straight_path in straight_paths:
             assert straight_path in true_straight_paths
-            self.path_validator(network, straight_path, excluded_nodes)
-          
-        #**************************************************************************
-    
-        # network with cycles
-        network = nx.MultiDiGraph()
-        network.add_edges_from([
-            # simplest cycle (with reverse-parallel arcs)
-            (0, 1, 0),
-            (1, 0, 0),
-            # 3-node cycle (with/without reverse-/-parallel arcs)
-            (2, 3, 0),
-            (3, 4, 0),
-            (4, 2, 0),
-            # 2-node cycle (with parallel and reverse-parallel arcs)
-            (5, 6, 0),
-            (6, 5, 0),
-            (5, 6, 1),
-            (6, 5, 1),
-            # 3-node cycle (only without parallel arcs)
-            (7, 8, 0),
-            (8, 9, 0),
-            (9, 7, 0),
-            (9, 7, 1),
-            (9, 7, 2)
-            ])
-        excluded_nodes = [2]
-        straight_paths = gis_iden.find_straight_paths(
+            self.path_validator(
+                network, 
+                straight_path, 
+                excluded_nodes,
+                consider_reversed_edges=consider_reversed_edges
+                )
+            
+        # *********************************************************************
+        # *********************************************************************
+            
+        # allow reversed edges, no self loops, no excluded nodes
+        ignore_self_loops = False
+        excluded_nodes = []
+        
+        straight_paths = gis_iden.find_simplifiable_paths(
             network, 
             excluded_nodes,
-            paths_must_be_oneway=paths_must_be_oneway,
-            paths_must_be_unique=paths_must_be_unique
+            consider_reversed_edges=consider_reversed_edges,
+            ignore_self_loops=ignore_self_loops
             )
-        # [0,1,0] or [1,0,1] are ruled out since they involve reverse-parallel arcs
-        # [5,6,5] or [6,5,6] are ruled out since they involve reverse/parallel arcs
-        true_straight_paths = [[2,3,4,2],[7,8,9,7]]
-        assert len(straight_paths) == len(true_straight_paths)
+        true_straight_paths = [[0, 1, 2], [2, 1, 0]]
+        assert len(straight_paths) == len(true_straight_paths)-1
         for straight_path in straight_paths:
             assert straight_path in true_straight_paths
-            self.path_validator(network, straight_path, excluded_nodes)
-    
-    # *************************************************************************
-    # *************************************************************************
-    
-    def test_find_straight_paths_case_c(self):
+            self.path_validator(
+                network, 
+                straight_path, 
+                excluded_nodes,
+                consider_reversed_edges=consider_reversed_edges
+                )
         
-        # case a:
-        paths_must_be_oneway=False  # arcs in the opposite direction do not prevent paths
-        paths_must_be_unique=True   # anti-/parallel arcs prevent paths
+        # *********************************************************************
+        # *********************************************************************
+            
+        # allow reversed edges, no self loops, excluded the middle node
+        ignore_self_loops = False
+        excluded_nodes = [1]
         
-        # network without straight paths
-        network = nx.MultiDiGraph()
-        excluded_nodes = []
-        straight_paths = gis_iden.find_straight_paths(
+        straight_paths = gis_iden.find_simplifiable_paths(
             network, 
             excluded_nodes,
-            paths_must_be_oneway=paths_must_be_oneway,
-            paths_must_be_unique=paths_must_be_unique
+            consider_reversed_edges=consider_reversed_edges,
+            ignore_self_loops=ignore_self_loops
             )
         true_straight_paths = []
         assert len(straight_paths) == len(true_straight_paths)
-        assert len(straight_paths) == 0
-    
-        # **************************************************************************
-    
-        # network with the simplest straight path
+            
+        # *********************************************************************
+        # *********************************************************************
+            
+        # allow reversed edges, no self loops, excluded the start node
+        ignore_self_loops = False
+        excluded_nodes = [0]
         
-        network = nx.MultiDiGraph()
-        network.add_edges_from([
-            (0, 1, 0),
-            (1, 2, 0),
-            # with reverse arcs
-            (3, 4, 0),
-            (5, 4, 0)
-            ])
-        excluded_nodes = []
-        straight_paths = gis_iden.find_straight_paths(
+        straight_paths = gis_iden.find_simplifiable_paths(
             network, 
             excluded_nodes,
-            paths_must_be_oneway=paths_must_be_oneway,
-            paths_must_be_unique=paths_must_be_unique
+            consider_reversed_edges=consider_reversed_edges,
+            ignore_self_loops=ignore_self_loops
             )
-        true_straight_paths = [[2, 1, 0], [0, 1, 2], [3, 4, 5], [5, 4, 3]]
-        assert len(straight_paths) == len(true_straight_paths)-2
+        true_straight_paths = [[0, 1, 2], [2, 1, 0]]
+        assert len(straight_paths) == len(true_straight_paths)-1
         for straight_path in straight_paths:
             assert straight_path in true_straight_paths
             self.path_validator(
                 network, 
                 straight_path, 
                 excluded_nodes,
-                paths_must_be_oneway=paths_must_be_oneway,
-                paths_must_be_unique=paths_must_be_unique
+                consider_reversed_edges=consider_reversed_edges
                 )
-    
-        # **************************************************************************
-    
-        # network with longer straight path
+            
+        # *********************************************************************
+        # *********************************************************************
+            
+        # allow reversed edges, no self loops, excluded the end node
+        ignore_self_loops = False
+        excluded_nodes = [2]
         
-        network = nx.MultiDiGraph()
-        network.add_edges_from([
-            (0, 1, 0),
-            (1, 2, 0),
-            (2, 3, 0),
-            ])
-        excluded_nodes = []
-        straight_paths = gis_iden.find_straight_paths(
+        straight_paths = gis_iden.find_simplifiable_paths(
             network, 
             excluded_nodes,
-            paths_must_be_oneway=paths_must_be_oneway,
-            paths_must_be_unique=paths_must_be_unique
+            consider_reversed_edges=consider_reversed_edges,
+            ignore_self_loops=ignore_self_loops
             )
-        true_straight_paths = [[0,1,2,3],[3,2,1,0]]
+        true_straight_paths = [[0, 1, 2], [2, 1, 0]]
         assert len(straight_paths) == len(true_straight_paths)-1
         for straight_path in straight_paths:
             assert straight_path in true_straight_paths
@@ -592,488 +1761,193 @@ class TestGisIdentify:
                 network, 
                 straight_path, 
                 excluded_nodes,
-                paths_must_be_oneway=paths_must_be_oneway,
-                paths_must_be_unique=paths_must_be_unique
+                consider_reversed_edges=consider_reversed_edges
                 )
+            
+        # *********************************************************************
+        # *********************************************************************
         
-        # **************************************************************************
+    # *************************************************************************
+    # *************************************************************************
+    
+    def test_find_simplifiable_path_four_nodes(self):
     
-        # network with excluded nodes
+        # *********************************************************************
+        # *********************************************************************
         
+        # network with a two edge path
         network = nx.MultiDiGraph()
         network.add_edges_from([
-            (0, 1, 0),
-            (1, 2, 0),
-            (2, 3, 0),
-            (3, 4, 0),
-            # path involving reverse arcs
-            (6, 5, 0),
-            (6, 7, 0),
-            (8, 7, 0),
-            # another
-            (8, 9, 0),
-            (10, 9, 0),
-            (11, 10, 0),
-            # cycle
-            (12, 13, 0),
-            (14, 13, 0),
-            (14, 15, 0),
-            (15, 12, 0)
+            (1, 0, 0), (1, 2, 0), (2, 3, 0)
             ])
-        excluded_nodes = [2, 8]
-        straight_paths = gis_iden.find_straight_paths(
+    
+        # *********************************************************************
+        # *********************************************************************
+        
+        # do not consider reversed edges
+        consider_reversed_edges = False
+        
+        # *********************************************************************
+        # *********************************************************************
+        
+        # no reversed edges, no self loops, no excluded nodes
+        ignore_self_loops = False
+        excluded_nodes = []
+        
+        straight_paths = gis_iden.find_simplifiable_paths(
             network, 
             excluded_nodes,
-            paths_must_be_oneway=paths_must_be_oneway,
-            paths_must_be_unique=paths_must_be_unique
+            consider_reversed_edges=consider_reversed_edges,
+            ignore_self_loops=ignore_self_loops
             )
-        true_straight_paths = [
-            [0,1,2],[2,1,0],
-            [2,3,4],[4,3,2],
-            [5,6,7,8],[8,7,6,5],
-            [8,9,10,11],[11,10,9,8],
-            [12,13,14,15,12],[14,13,12,15,14],[13,14,15,12,13],[15,12,13,14,15]
-            ]
-        assert len(straight_paths) == len(true_straight_paths)-4-3
+        true_straight_paths = [[1, 2, 3]]
+        assert len(straight_paths) == len(true_straight_paths)
         for straight_path in straight_paths:
             assert straight_path in true_straight_paths
             self.path_validator(
                 network, 
                 straight_path, 
                 excluded_nodes,
-                paths_must_be_oneway=paths_must_be_oneway,
-                paths_must_be_unique=paths_must_be_unique
+                consider_reversed_edges=consider_reversed_edges
                 )
-    
-        # **************************************************************************
-    
-        # network with self loops and excluded nodes
-    
-        network = nx.MultiDiGraph()
-        network.add_edges_from([
-            (0, 1, 0),
-            (2, 2, 0),
-            (1, 2, 0),
-            (2, 3, 0),
-            (3, 3, 0),
-            (3, 4, 0),
-            ])
-        excluded_nodes = [2]
-        straight_paths = gis_iden.find_straight_paths(network, excluded_nodes)
-        true_straight_paths = [[0, 1, 2], [2, 3, 4]]
-        assert len(straight_paths) == len(true_straight_paths)
+            
+        # *********************************************************************
+        # *********************************************************************
+        
+        # consider reversed edges
+        consider_reversed_edges = True
+        
+        # *********************************************************************
+        # *********************************************************************
+        
+        # no reversed edges, no self loops, no excluded nodes
+        ignore_self_loops = False
+        excluded_nodes = []
+        
+        straight_paths = gis_iden.find_simplifiable_paths(
+            network, 
+            excluded_nodes,
+            consider_reversed_edges=consider_reversed_edges,
+            ignore_self_loops=ignore_self_loops
+            )
+        true_straight_paths = [[0, 1, 2, 3], [3, 2, 1, 0]]
+        assert len(straight_paths) == len(true_straight_paths)-1
         for straight_path in straight_paths:
             assert straight_path in true_straight_paths
             self.path_validator(
                 network, 
                 straight_path, 
                 excluded_nodes,
-                paths_must_be_oneway=paths_must_be_oneway,
-                paths_must_be_unique=paths_must_be_unique
+                consider_reversed_edges=consider_reversed_edges
                 )
-    
-        # **************************************************************************
-    
-        # network with parallel arcs
+                
+        # *********************************************************************
+        # *********************************************************************
         
-        network = nx.MultiDiGraph()
-        network.add_edges_from([
-            (0, 1, 0),
-            (1, 2, 0),
-            (0, 1, 1),
-            (2, 3, 0),
-            (3, 4, 0),
-            # 3-node cycle (only without parallel arcs)
-            (7, 8, 0),
-            (7, 8, 1),
-            (8, 9, 0),
-            (9, 7, 0)
-            ])
-        excluded_nodes = [2]
-        straight_paths = gis_iden.find_straight_paths(
-            network,
+        # no reversed edges, no self loops, no excluded nodes
+        ignore_self_loops = False
+        excluded_nodes = []
+        
+        straight_paths = gis_iden.find_simplifiable_paths(
+            network, 
             excluded_nodes,
-            paths_must_be_oneway=paths_must_be_oneway,
-            paths_must_be_unique=paths_must_be_unique
-        )
-        true_straight_paths = [
-            [2,3,4],[4,3,2],
-            [8,9,7],[7,9,8]
-            ]
-        assert len(straight_paths) == len(true_straight_paths)-1-1
+            consider_reversed_edges=consider_reversed_edges,
+            ignore_self_loops=ignore_self_loops,
+            include_both_directions=True
+            )
+        true_straight_paths = [[0, 1, 2, 3], [3, 2, 1, 0]]
+        assert len(straight_paths) == len(true_straight_paths)
         for straight_path in straight_paths:
             assert straight_path in true_straight_paths
             self.path_validator(
                 network, 
                 straight_path, 
                 excluded_nodes,
-                paths_must_be_oneway=paths_must_be_oneway,
-                paths_must_be_unique=paths_must_be_unique
+                consider_reversed_edges=consider_reversed_edges
                 )
+            
+        # *********************************************************************
+        # *********************************************************************
+                
+    # *************************************************************************
+    # *************************************************************************
     
-        # **************************************************************************
-    
-        # network with parallel and anti-parallel arcs
+    def test_find_simplifiable_path_four_node_cycle(self):
     
+        # *********************************************************************
+        # *********************************************************************
+        
+        # network with a two edge path
         network = nx.MultiDiGraph()
         network.add_edges_from([
-            (0, 1, 0),
-            (1, 2, 0),
-            (0, 1, 1),
-            (1, 2, 1),
-            (2, 3, 0),
-            (3, 4, 0),
-            (4, 5, 0),
-            (5, 2, 0),
-            (5, 2, 1),
-            # cycle
-            (6, 7, 0),
-            (7, 8, 0),
-            (8, 9, 0),
-            (9, 6, 0)
+            (0, 1, 0), (1, 2, 0), (2, 3, 0), (0, 3, 0)
             ])
-        excluded_nodes = [2]
-        straight_paths = gis_iden.find_straight_paths(
-            network,
+    
+        # *********************************************************************
+        # *********************************************************************
+        
+        # do not consider reversed edges
+        consider_reversed_edges = False
+        
+        # *********************************************************************
+        # *********************************************************************
+        
+        # no reversed edges, no self loops, no excluded nodes
+        ignore_self_loops = False
+        excluded_nodes = []
+        
+        straight_paths = gis_iden.find_simplifiable_paths(
+            network, 
             excluded_nodes,
-            paths_must_be_oneway=paths_must_be_oneway,
-            paths_must_be_unique=paths_must_be_unique
-        )
-        true_straight_paths = [
-            [2,3,4,5],[5,4,3,2],
-            [6,7,8,9,6],[7,8,9,6,7],[8,9,6,7,8],[9,8,7,6,9],
-            [6,9,8,7,6],[7,6,9,8,7],[8,7,6,9,8],[9,6,7,8,9]
-            ]
-        assert len(straight_paths) == len(true_straight_paths)-1-3-4
+            consider_reversed_edges=consider_reversed_edges,
+            ignore_self_loops=ignore_self_loops
+            )
+        true_straight_paths = [[0, 1, 2, 3]]
+        assert len(straight_paths) == len(true_straight_paths)
         for straight_path in straight_paths:
             assert straight_path in true_straight_paths
             self.path_validator(
                 network, 
                 straight_path, 
                 excluded_nodes,
-                paths_must_be_oneway=paths_must_be_oneway,
-                paths_must_be_unique=paths_must_be_unique
+                consider_reversed_edges=consider_reversed_edges
                 )
-          
-        #**************************************************************************
-    
-        # network with cycles
-    
-        network = nx.MultiDiGraph()
-        network.add_edges_from([
-            # simplest cycle (with reverse-parallel arcs)
-            (0, 1, 0),
-            (1, 0, 0),
-            # 3-node cycle (with/without reverse-/-parallel arcs)
-            (2, 3, 0),
-            (3, 4, 0),
-            (4, 2, 0),
-            # 2-node cycle (with parallel and reverse-parallel arcs)
-            (5, 6, 0),
-            (6, 5, 0),
-            (5, 6, 1),
-            (6, 5, 1),
-            # 3-node cycle (only without parallel arcs)
-            (7, 8, 0),
-            (8, 9, 0),
-            (9, 7, 0),
-            (9, 7, 1)
-            ])
-        excluded_nodes = [2]
-        straight_paths = gis_iden.find_straight_paths(
-            network,
+            
+        # *********************************************************************
+        # *********************************************************************
+        
+        # consider reversed edges
+        consider_reversed_edges = True
+        
+        # *********************************************************************
+        # *********************************************************************
+        
+        # no reversed edges, no self loops, no excluded nodes
+        ignore_self_loops = False
+        excluded_nodes = []
+        
+        straight_paths = gis_iden.find_simplifiable_paths(
+            network, 
             excluded_nodes,
-            paths_must_be_oneway=True,      # reverse-parallel arcs prevent paths
-            paths_must_be_unique=True       # parallel arcs prevent paths
+            consider_reversed_edges=consider_reversed_edges,
+            ignore_self_loops=ignore_self_loops
             )
-        # [0,1,0] or [1,0,1] are ruled out since they involve reverse-parallel arcs
-        # [5,6,5] or [6,5,6] are ruled out since they involve reverse/parallel arcs
-        # [7,8,9,7], etc are ruled out since they involve one parallel arc
         true_straight_paths = [
-            [2,3,4,2],[3,4,2,3],[4,3,2,4],[2,4,3,2],[3,2,4,3],[4,2,3,4],
-            [7,8,9],[9,8,7]
+            [0, 1, 2, 3, 0], [1, 2, 3, 0, 1], [2, 3, 0, 1, 2], [3, 0, 1, 2, 3]
             ]
-        assert len(straight_paths) == len(true_straight_paths)-5-1
+        assert len(straight_paths) == len(true_straight_paths)-3
         for straight_path in straight_paths:
             assert straight_path in true_straight_paths
             self.path_validator(
                 network, 
                 straight_path, 
                 excluded_nodes,
-                paths_must_be_oneway=paths_must_be_oneway,
-                paths_must_be_unique=paths_must_be_unique
+                consider_reversed_edges=consider_reversed_edges
                 )
-    
-    # *************************************************************************
-    # *************************************************************************
-    
-    # def test_find_straight_paths_case_d(self):
-        
-    #     # case a:
-    #     paths_must_be_oneway=False   # reverse-parallel arcs prevent paths
-    #     paths_must_be_unique=False   # parallel arcs prevent paths
-        
-    #     # network without straight paths
-    #     network = nx.MultiDiGraph()
-    #     excluded_nodes = []
-    #     straight_paths = gis_iden.find_straight_paths(
-    #         network, 
-    #         excluded_nodes,
-    #         paths_must_be_oneway=paths_must_be_oneway,
-    #         paths_must_be_unique=paths_must_be_unique
-    #         )
-    #     true_straight_paths = []
-    #     assert len(straight_paths) == len(true_straight_paths)
-    #     assert len(straight_paths) == 0
-    
-    #     # **************************************************************************
-    
-    #     # network with the simplest straight path
-    #     network = nx.MultiDiGraph()
-    #     network.add_edges_from([
-    #         (0, 1, 0),
-    #         (1, 2, 0),
-    #         ])
-    #     excluded_nodes = []
-    #     straight_paths = gis_iden.find_straight_paths(
-    #         network, 
-    #         excluded_nodes,
-    #         paths_must_be_oneway=paths_must_be_oneway,
-    #         paths_must_be_unique=paths_must_be_unique
-    #         )
-    #     true_straight_paths = [[0,1,2],[2,1,0]]
-        
-    #     print('hello here')
-    #     print(network.edges(keys=True, data=True))
-    #     print('true :' + str(true_straight_paths))
-    #     print('actual :' + str(straight_paths))
-    #     assert len(straight_paths) == len(true_straight_paths)-1
-    #     for straight_path in straight_paths:
-    #         assert straight_path in true_straight_paths
-    #         self.path_validator(
-    #             network, 
-    #             straight_path, 
-    #             excluded_nodes,
-    #             paths_must_be_oneway=paths_must_be_oneway,
-    #             paths_must_be_unique=paths_must_be_unique
-    #             )
-    
-    #     # **************************************************************************
-    
-    #     # network with longer straight path
-    #     network = nx.MultiDiGraph()
-    #     network.add_edges_from([
-    #         (0, 1, 0),
-    #         (1, 2, 0),
-    #         (2, 3, 0),
-    #         ])
-    #     excluded_nodes = []
-    #     straight_paths = gis_iden.find_straight_paths(
-    #         network, 
-    #         excluded_nodes,
-    #         paths_must_be_oneway=paths_must_be_oneway,
-    #         paths_must_be_unique=paths_must_be_unique
-    #         )
-    #     true_straight_paths = [[0,1,2,3],[3,2,1,0]]
-    #     assert len(straight_paths) == len(true_straight_paths)-1
-    #     for straight_path in straight_paths:
-    #         assert straight_path in true_straight_paths
-    #         self.path_validator(
-    #             network, 
-    #             straight_path, 
-    #             excluded_nodes,
-    #             paths_must_be_oneway=paths_must_be_oneway,
-    #             paths_must_be_unique=paths_must_be_unique
-    #             )
-        
-    #     # **************************************************************************
-    
-    #     # network with excluded nodes
-    
-    #     network = nx.MultiDiGraph()
-    #     network.add_edges_from([
-    #         (0, 1, 0),
-    #         (1, 2, 0),
-    #         (2, 3, 0),
-    #         (3, 4, 0),
-    #         ])
-    
-    #     excluded_nodes = [2]
-    #     straight_paths = gis_iden.find_straight_paths(
-    #         network, 
-    #         excluded_nodes,
-    #         paths_must_be_oneway=paths_must_be_oneway,
-    #         paths_must_be_unique=paths_must_be_unique
-    #         )
-    #     true_straight_paths = [[0,1,2],[2,3,4],[2,1,0],[4,3,2]]
-    #     assert len(straight_paths) == len(true_straight_paths)-2
-    #     for straight_path in straight_paths:
-    #         assert straight_path in true_straight_paths
-    #         self.path_validator(
-    #             network, 
-    #             straight_path, 
-    #             excluded_nodes,
-    #             paths_must_be_oneway=paths_must_be_oneway,
-    #             paths_must_be_unique=paths_must_be_unique
-    #             )
-    
-    #     # **************************************************************************
-    
-    #     # network with self loops and excluded nodes
-    
-    #     network = nx.MultiDiGraph()
-    #     network.add_edges_from([
-    #         (0, 1, 0),
-    #         (2, 2, 0),
-    #         (1, 2, 0),
-    #         (2, 3, 0),
-    #         (3, 3, 0),
-    #         (3, 4, 0),
-    #         ])
-    #     excluded_nodes = [2]
-    #     straight_paths = gis_iden.find_straight_paths(
-    #         network,
-    #         excluded_nodes,
-    #         paths_must_be_oneway=paths_must_be_oneway,
-    #         paths_must_be_unique=paths_must_be_unique
-    #         )
-    #     true_straight_paths = [[0,1,2],[2,3,4],[4,3,2],[2,1,0]]
-    #     assert len(straight_paths) == len(true_straight_paths)-2
-    #     for straight_path in straight_paths:
-    #         assert straight_path in true_straight_paths
-    #         self.path_validator(
-    #             network, 
-    #             straight_path, 
-    #             excluded_nodes,
-    #             paths_must_be_oneway=paths_must_be_oneway,
-    #             paths_must_be_unique=paths_must_be_unique
-    #             )
-    
-    #     # **************************************************************************
-    
-    #     # network with parallel arcs
-        
-    #     network = nx.MultiDiGraph()
-    #     network.add_edges_from([
-    #         (0, 1, 0),
-    #         (1, 2, 0),
-    #         (0, 1, 1),
-    #         (2, 3, 0),
-    #         (3, 4, 0),
-    #         ])
-    #     excluded_nodes = [2,1]
-    #     straight_paths = gis_iden.find_straight_paths(
-    #         network,
-    #         excluded_nodes,
-    #         paths_must_be_oneway=paths_must_be_oneway,
-    #         paths_must_be_unique=paths_must_be_unique
-    #         )
-    #     true_straight_paths = [[2,3,4],[4,3,2]] # [0,1,2] involves parallel arcs
-    #     assert len(straight_paths) == len(true_straight_paths)-1
-    #     for straight_path in straight_paths:
-    #         assert straight_path in true_straight_paths
-    #         self.path_validator(
-    #             network, 
-    #             straight_path, 
-    #             excluded_nodes,
-    #             paths_must_be_oneway=paths_must_be_oneway,
-    #             paths_must_be_unique=paths_must_be_unique
-    #             )
-    
-    #     # **************************************************************************
-    
-    #     # network with parallel and anti-parallel arcs
-    
-    #     network = nx.MultiDiGraph()
-    #     network.add_edges_from([
-    #         (0, 1, 0),
-    #         (1, 2, 0),
-    #         (0, 1, 1),
-    #         (1, 2, 1),
-    #         (2, 3, 0),
-    #         (3, 4, 0),
-    #         (3, 2, 0),
-    #         (3, 3, 0),
-    #         (4, 3, 0),
-    #         ])
-    #     excluded_nodes = [2]
-    #     straight_paths = gis_iden.find_straight_paths(
-    #         network,
-    #         excluded_nodes,
-    #         paths_must_be_oneway=paths_must_be_oneway,
-    #         paths_must_be_unique=paths_must_be_unique
-    #         )
-    #     true_straight_paths = [
-    #         [0, 1, 2], [2, 1, 0],
-    #         [2, 3, 4], [4, 3, 2]
-    #         ] # all are good
-    #     print('hello here')
-    #     print(network.edges(keys=True, data=True))
-    #     print('true :' + str(true_straight_paths))
-    #     print('actual :' + str(straight_paths))
-    #     assert len(straight_paths) == len(true_straight_paths)-2
-    #     for straight_path in straight_paths:
-    #         assert straight_path in true_straight_paths
-    #         self.path_validator(
-    #             network, 
-    #             straight_path, 
-    #             excluded_nodes,
-    #             paths_must_be_oneway=paths_must_be_oneway,
-    #             paths_must_be_unique=paths_must_be_unique
-    #             )
-          
-    #     #**************************************************************************
-    
-    #     # network with cycles
-    
-    #     network = nx.MultiDiGraph()
-    #     network.add_edges_from([
-    #         # simplest cycle (with reverse-parallel arcs)
-    #         (0, 1, 0),
-    #         (1, 0, 0),
-    #         # 3-node cycle (with/without reverse-/-parallel arcs)
-    #         (2, 3, 0),
-    #         (3, 4, 0),
-    #         (4, 2, 0),
-    #         # 2-node cycle (with parallel and reverse-parallel arcs)
-    #         (5, 6, 0),
-    #         (6, 5, 0),
-    #         (5, 6, 1),
-    #         (6, 5, 1),
-    #         # 3-node cycle (only without parallel arcs)
-    #         (7, 8, 0),
-    #         (8, 9, 0),
-    #         (9, 7, 0),
-    #         (9, 7, 1)
-    #         ])
-    #     excluded_nodes = [2]
-    #     straight_paths = gis_iden.find_straight_paths(
-    #         network,
-    #         excluded_nodes,
-    #         paths_must_be_oneway=paths_must_be_oneway,
-    #         paths_must_be_unique=paths_must_be_unique
-    #         )
-    #     true_straight_paths = [
-    #         [2,3,4,2],[3,4,2,3],[4,3,2,4],[2,4,3,2],[3,2,4,3],[4,2,3,4],
-    #         [7,8,9,7],[8,9,7,8],[9,7,8,9],[7,9,8,7],[8,7,9,8],[9,7,8,9],
-    #         # [0,1,0],[1,0,1],
-    #         # [5,6,5],[6,5,6]
-    #         ]
-    #     print('hello here')
-    #     print(network.edges(keys=True, data=True))
-    #     print('true :' + str(true_straight_paths))
-    #     print('actual :' + str(straight_paths))
-    #     assert len(straight_paths) == len(true_straight_paths)-5-5
-    #     for straight_path in straight_paths:
-    #         assert straight_path in true_straight_paths
-    #         self.path_validator(
-    #             network, 
-    #             straight_path, 
-    #             excluded_nodes,
-    #             paths_must_be_oneway=paths_must_be_oneway,
-    #             paths_must_be_unique=paths_must_be_unique
-    #             )
-    
+            
+        # *********************************************************************
+        # *********************************************************************
+        
     # *************************************************************************
     # *************************************************************************
     
@@ -1213,9 +2087,9 @@ class TestGisIdentify:
     # *************************************************************************
     # *************************************************************************
     
-    def test_identify_all_from_a_to_b(self):
+    def test_identify_get_from_a_to_b(self):
     
-        # arc_keys = gis_iden.all_arcs_from_a_to_b(G, 0, 1)
+        # edge_keys = gis_iden.get_edges_from_a_to_b(G, 0, 1)
     
         G = nx.MultiDiGraph()
     
@@ -1230,80 +2104,80 @@ class TestGisIdentify:
     
         # from node 0 to node 1
     
-        arc_keys = gis_iden.all_arcs_from_a_to_b(G, 0, 1)
+        edge_keys = gis_iden.get_edges_from_a_to_b(G, 0, 1)
     
-        true_arc_keys = [(0, 1, 0)]
+        true_edge_keys = [(0, 1, 0)]
     
-        assert len(true_arc_keys) == len(arc_keys)
+        assert len(true_edge_keys) == len(edge_keys)
     
-        for arc_key in arc_keys:
+        for edge_key in edge_keys:
     
-            assert arc_key in true_arc_keys
+            assert edge_key in true_edge_keys
     
         # from node 1 to node 0
     
-        arc_keys = gis_iden.all_arcs_from_a_to_b(G, 1, 0)
+        edge_keys = gis_iden.get_edges_from_a_to_b(G, 1, 0)
     
-        true_arc_keys = [(1, 0, 0)]
+        true_edge_keys = [(1, 0, 0)]
     
-        assert len(true_arc_keys) == len(arc_keys)
+        assert len(true_edge_keys) == len(edge_keys)
     
-        for arc_key in arc_keys:
+        for edge_key in edge_keys:
     
-            assert arc_key in true_arc_keys
+            assert edge_key in true_edge_keys
     
         # from node 1 to node 2
     
-        arc_keys = gis_iden.all_arcs_from_a_to_b(G, 1, 2)
+        edge_keys = gis_iden.get_edges_from_a_to_b(G, 1, 2)
     
-        true_arc_keys = [(1, 2, 0)]
+        true_edge_keys = [(1, 2, 0)]
     
-        assert len(true_arc_keys) == len(arc_keys)
+        assert len(true_edge_keys) == len(edge_keys)
     
-        for arc_key in arc_keys:
+        for edge_key in edge_keys:
     
-            assert arc_key in true_arc_keys
+            assert edge_key in true_edge_keys
     
         # from node 2 to node 1
     
-        arc_keys = gis_iden.all_arcs_from_a_to_b(G, 2, 1)
+        edge_keys = gis_iden.get_edges_from_a_to_b(G, 2, 1)
     
-        true_arc_keys = []
+        true_edge_keys = []
     
-        assert len(true_arc_keys) == len(arc_keys)
+        assert len(true_edge_keys) == len(edge_keys)
     
         # from node 2 to node 3
     
-        arc_keys = gis_iden.all_arcs_from_a_to_b(G, 2, 3)
+        edge_keys = gis_iden.get_edges_from_a_to_b(G, 2, 3)
     
-        true_arc_keys = [(2, 3, 0), (2, 3, 1)]
+        true_edge_keys = [(2, 3, 0), (2, 3, 1)]
     
-        assert len(true_arc_keys) == len(arc_keys)
+        assert len(true_edge_keys) == len(edge_keys)
     
-        for arc_key in arc_keys:
+        for edge_key in edge_keys:
     
-            assert arc_key in true_arc_keys
+            assert edge_key in true_edge_keys
     
         # from node 3 to node 2
     
-        true_arc_keys = [(3, 2, 0)]
+        true_edge_keys = [(3, 2, 0)]
     
-        arc_keys = gis_iden.all_arcs_from_a_to_b(G, 3, 2)
+        edge_keys = gis_iden.get_edges_from_a_to_b(G, 3, 2)
     
-        assert len(true_arc_keys) == len(arc_keys)
+        assert len(true_edge_keys) == len(edge_keys)
     
-        for arc_key in arc_keys:
+        for edge_key in edge_keys:
     
-            assert arc_key in true_arc_keys
+            assert edge_key in true_edge_keys
     
     # *************************************************************************
     # *************************************************************************
     
-    def test_identify_all_arcs_involving_nodes(self):
+    def test_identify_get_edges_involving_nodes(self):
     
         G = nx.MultiDiGraph()
         
-        G.add_node('noarcs')
+        G.add_node('noedges')
     
         G.add_edges_from(
             [(0, 1, 0),
@@ -1311,31 +2185,31 @@ class TestGisIdentify:
              (1, 2, 1)]
         )
         
-        # no arcs
-        node_key = 'noarcs'
-        arcs = gis_iden.all_arcs_involving_node(G, node_key)
-        assert len(arcs) == 0
+        # no edges
+        node_key = 'noedges'
+        edges = gis_iden.get_edges_involving_node(G, node_key)
+        assert len(edges) == 0
         
-        # one arc
+        # one edge
         node_key = 0
-        true_arcs = [(0,1,0)]
-        arcs = gis_iden.all_arcs_involving_node(G, node_key)
-        assert len(arcs) == len(true_arcs)
-        for arc in arcs:
-            assert arc in true_arcs
+        true_edges = [(0,1,0)]
+        edges = gis_iden.get_edges_involving_node(G, node_key)
+        assert len(edges) == len(true_edges)
+        for edge in edges:
+            assert edge in true_edges
         
-        # multiple arcs
+        # multiple edges
         node_key = 1
-        true_arcs = [(0,1,0), (1,2,1), (1,2,0)]
-        arcs = gis_iden.all_arcs_involving_node(G, node_key)
-        assert len(arcs) == len(true_arcs)
-        for arc in arcs:
-            assert arc in true_arcs
+        true_edges = [(0,1,0), (1,2,1), (1,2,0)]
+        edges = gis_iden.get_edges_involving_node(G, node_key)
+        assert len(edges) == len(true_edges)
+        for edge in edges:
+            assert edge in true_edges
     
     # *************************************************************************
     # *************************************************************************
     
-    def test_identify_all_arcs_between_nodes(self):
+    def test_identify_get_edges_between_nodes(self):
     
         G = nx.MultiDiGraph()
     
@@ -1351,80 +2225,80 @@ class TestGisIdentify:
         
         # between two nodes that are not connected
     
-        arc_keys = gis_iden.all_arcs_between_two_nodes(G, 2, 4)
+        edge_keys = gis_iden.get_edges_between_two_nodes(G, 2, 4)
     
-        assert 0 == len(arc_keys)
+        assert 0 == len(edge_keys)
     
         # between nodes 0 and 1, nominal direction
     
-        arc_keys = gis_iden.all_arcs_between_two_nodes(G, 0, 1)
+        edge_keys = gis_iden.get_edges_between_two_nodes(G, 0, 1)
     
-        true_arc_keys = [(0, 1, 0), (1, 0, 0)]
+        true_edge_keys = [(0, 1, 0), (1, 0, 0)]
     
-        assert len(true_arc_keys) == len(arc_keys)
+        assert len(true_edge_keys) == len(edge_keys)
     
-        for arc_key in arc_keys:
+        for edge_key in edge_keys:
     
-            assert arc_key in true_arc_keys
+            assert edge_key in true_edge_keys
     
         # between nodes 0 and 1, reverse direction
     
-        arc_keys = gis_iden.all_arcs_between_two_nodes(G, 1, 0)
+        edge_keys = gis_iden.get_edges_between_two_nodes(G, 1, 0)
     
-        assert len(true_arc_keys) == len(arc_keys)
+        assert len(true_edge_keys) == len(edge_keys)
     
-        for arc_key in arc_keys:
+        for edge_key in edge_keys:
     
-            assert arc_key in true_arc_keys
+            assert edge_key in true_edge_keys
     
         # between nodes 1 and 2, nominal direction
     
-        arc_keys = gis_iden.all_arcs_between_two_nodes(G, 1, 2)
+        edge_keys = gis_iden.get_edges_between_two_nodes(G, 1, 2)
     
-        true_arc_keys = [(1, 2, 0)]
+        true_edge_keys = [(1, 2, 0)]
     
-        assert len(true_arc_keys) == len(arc_keys)
+        assert len(true_edge_keys) == len(edge_keys)
     
-        for arc_key in arc_keys:
+        for edge_key in edge_keys:
     
-            assert arc_key in true_arc_keys
+            assert edge_key in true_edge_keys
     
         # between nodes 1 and 2, reverse direction
     
-        arc_keys = gis_iden.all_arcs_between_two_nodes(G, 2, 1)
+        edge_keys = gis_iden.get_edges_between_two_nodes(G, 2, 1)
     
-        assert len(true_arc_keys) == len(arc_keys)
+        assert len(true_edge_keys) == len(edge_keys)
     
-        for arc_key in arc_keys:
+        for edge_key in edge_keys:
     
-            assert arc_key in true_arc_keys
+            assert edge_key in true_edge_keys
     
         # between nodes 2 and 3, nominal direction
     
-        arc_keys = gis_iden.all_arcs_between_two_nodes(G, 2, 3)
+        edge_keys = gis_iden.get_edges_between_two_nodes(G, 2, 3)
     
-        true_arc_keys = [(2, 3, 0), (2, 3, 1), (3, 2, 0)]
+        true_edge_keys = [(2, 3, 0), (2, 3, 1), (3, 2, 0)]
     
-        assert len(true_arc_keys) == len(arc_keys)
+        assert len(true_edge_keys) == len(edge_keys)
     
-        for arc_key in arc_keys:
+        for edge_key in edge_keys:
     
-            assert arc_key in true_arc_keys
+            assert edge_key in true_edge_keys
     
         # between nodes 2 and 3, reverse direction
     
-        arc_keys = gis_iden.all_arcs_between_two_nodes(G, 3, 2)
+        edge_keys = gis_iden.get_edges_between_two_nodes(G, 3, 2)
     
-        assert len(true_arc_keys) == len(arc_keys)
+        assert len(true_edge_keys) == len(edge_keys)
     
-        for arc_key in arc_keys:
+        for edge_key in edge_keys:
     
-            assert arc_key in true_arc_keys
+            assert edge_key in true_edge_keys
     
     # *************************************************************************
     # *************************************************************************
     
-    def test_identify_arcs_closest_to_nodes(self):
+    def test_identify_edges_closest_to_nodes(self):
     
         # network should be a OSM-nx formatted graph
     
@@ -1441,25 +2315,25 @@ class TestGisIdentify:
         while len(node_keys) > number_nodes:
             node_keys.pop(random.randint(0, len(node_keys)-1))
     
-        # find out which arcs are closest
-        arc_keys, projected_network = gis_iden.identify_arc_closest_to_node(
+        # find out which edges are closest
+        edge_keys, projected_network = gis_iden.identify_edge_closest_to_node(
             network=network,
             node_keys=node_keys
         )
         
-        # for each node, verify that there is no closer arc
-        # prepare the arc geometries 
-        arc_key_geos = [
-            (projected_network.edges[arc_key][gis_osm.KEY_OSMNX_GEOMETRY]
-             if gis_osm.KEY_OSMNX_GEOMETRY in projected_network.edges[arc_key] else
+        # for each node, verify that there is no closer edge
+        # prepare the edge geometries 
+        edge_key_geos = [
+            (projected_network.edges[edge_key][gis_osm.KEY_OSMNX_GEOMETRY]
+             if gis_osm.KEY_OSMNX_GEOMETRY in projected_network.edges[edge_key] else
              LineString([
-                 (projected_network.nodes[arc_key[0]][gis_osm.KEY_OSMNX_X],
-                  projected_network.nodes[arc_key[0]][gis_osm.KEY_OSMNX_Y]),
-                 (projected_network.nodes[arc_key[1]][gis_osm.KEY_OSMNX_X],
-                  projected_network.nodes[arc_key[1]][gis_osm.KEY_OSMNX_Y])
+                 (projected_network.nodes[edge_key[0]][gis_osm.KEY_OSMNX_X],
+                  projected_network.nodes[edge_key[0]][gis_osm.KEY_OSMNX_Y]),
+                 (projected_network.nodes[edge_key[1]][gis_osm.KEY_OSMNX_X],
+                  projected_network.nodes[edge_key[1]][gis_osm.KEY_OSMNX_Y])
                  ])
              )
-            for arc_key in arc_keys
+            for edge_key in edge_keys
             ]
         for node_index, node_key in enumerate(node_keys):  
             # prepare the node geometry
@@ -1467,22 +2341,22 @@ class TestGisIdentify:
                 projected_network.nodes[node_key][gis_osm.KEY_OSMNX_X],
                 projected_network.nodes[node_key][gis_osm.KEY_OSMNX_Y]
                 )
-            # calculate the distances to every arc
-            arc_point_distances = the_point.distance(arc_key_geos)
-            # find the distance to the arc identified as the closest one
-            shortest_distance = arc_point_distances[node_index]
-            # the arc identified must lead to the shortest distance
-            assert shortest_distance == min(arc_point_distances)
-    
-        # find out which arcs are closest using the projected network
-        arc_keys_proj, _ = gis_iden.identify_arc_closest_to_node(
+            # calculate the distances to every edge
+            edge_point_distances = the_point.distance(edge_key_geos)
+            # find the distance to the edge identified as the closest one
+            shortest_distance = edge_point_distances[node_index]
+            # the edge identified must lead to the shortest distance
+            assert shortest_distance == min(edge_point_distances)
+    
+        # find out which edges are closest using the projected network
+        edge_keys_proj, _ = gis_iden.identify_edge_closest_to_node(
             network=projected_network,
             node_keys=node_keys
         )
-        # assert that the same arcs have been returned (with the projected network)
-        assert len(arc_keys) == len(arc_keys_proj)
-        for arc_key1, arc_key2 in zip(arc_keys, arc_keys_proj):
-            assert arc_key1 == arc_key2
+        # assert that the same edges have been returned (with the projected network)
+        assert len(edge_keys) == len(edge_keys_proj)
+        for edge_key1, edge_key2 in zip(edge_keys, edge_keys_proj):
+            assert edge_key1 == edge_key2
     
     # *************************************************************************
     # *************************************************************************
@@ -1526,7 +2400,7 @@ class TestGisIdentify:
             # connect roundabouts 1 and 3 with a edge
             (1, 6, {'length': 9, 'oneway': False}),
             (6, 1, {'length': 24, 'oneway': False}),
-            # create an arc between node 7 and 5 that cannot be used,
+            # create an edge between node 7 and 5 that cannot be used,
             (7, 5, {'length': 6, 'oneway': False})
         ]
     
@@ -1570,7 +2444,7 @@ class TestGisIdentify:
             [16, 17, 18, 19],
             # true roundabout with one non-existent node added
             [2, 3, 'h', 4],
-            # path whose last node does not lead to the first through a valid arc
+            # path whose last node does not lead to the first through a valid edge
             [5, 6, 7],
             # true roundabout without the last node (8)
             [5, 6, 7, 19],
@@ -1674,17 +2548,7 @@ class TestGisIdentify:
         ]
     
         for edge_index, edge_path in enumerate(edge_paths):
-    
-            # try:
-            #     assert gis_mod.convert_edge_path(
-            #         network,
-            #         edge_path,
-            #         allow_reversed_edges=allow_reversed_edges) == expected_node_paths[
-            #             edge_index]
-            # except AssertionError:
-            #     print(edge_path)
-            #     print(expected_node_paths[edge_index])
-            #     assert False
+            
             assert gis_iden.convert_edge_path(
                 network,
                 edge_path,
@@ -2329,7 +3193,7 @@ class TestGisIdentify:
             truncate_by_edge=True
             )
         
-        # create arc to trigger the negative case with a different length
+        # create edge to trigger the negative case with a different length
         # (317812803, 317812802, 2)
         edge_k = network.add_edge(
             317812803, 
@@ -2343,7 +3207,7 @@ class TestGisIdentify:
                'length': 27.601+1}
             )
         assert edge_k == 2
-        # create arc tp trigger the negative case with a different geometry
+        # create edge tp trigger the negative case with a different geometry
         # (317812802, 317812803, 2)
         edge_k = network.add_edge(
             317812802,
@@ -2360,31 +3224,31 @@ class TestGisIdentify:
             )
         assert edge_k == 2
         
-        # find arcs that have matching arcs in the reverse direction
-        for arc_key in network.edges(keys=True):
-            arc_dict = network.get_edge_data(*arc_key)
+        # find edges that have matching edges in the reverse direction
+        for edge_key in network.edges(keys=True):
+            edge_dict = network.get_edge_data(*edge_key)
             for _attr in gis_osm.KEYS_OSMNX_EDGES_ESSENTIAL:
-                assert _attr in arc_dict.keys()
-            # for each arc, find if there is one in the opposite direction
-            if network.has_edge(u=arc_key[1], v=arc_key[0]):
-                # there is an arc in the opposite sense
-                for other_arc_key in gis_iden.all_arcs_from_a_to_b(
+                assert _attr in edge_dict.keys()
+            # for each edge, find if there is one in the opposite direction
+            if network.has_edge(u=edge_key[1], v=edge_key[0]):
+                # there is an edge in the opposite sense
+                for other_edge_key in gis_iden.get_edges_from_a_to_b(
                         network=network, 
-                        node_start=arc_key[1], 
-                        node_end=arc_key[0]
+                        node_start=edge_key[1], 
+                        node_end=edge_key[0]
                         ):
-                    # check if the arcs are the same but in reverse
+                    # check if the edges are the same but in reverse
                     if gis_iden.edges_are_in_reverse(
                             network, 
-                            edge_a=arc_key,
-                            edge_b=other_arc_key
+                            edge_a=edge_key,
+                            edge_b=other_edge_key
                             ):
-                        # the arcs are the same but in reverse:
+                        # the edges are the same but in reverse:
                         # - all attributes have to be the same or lists with 
                         # the same content, as in a set, except for 
                         # the geometry and reversed attributes
-                        fw_dict = network.get_edge_data(*arc_key)
-                        rv_dict = network.get_edge_data(*other_arc_key)
+                        fw_dict = network.get_edge_data(*edge_key)
+                        rv_dict = network.get_edge_data(*other_edge_key)
                         
                         # should have the same attributes
                         assert set(fw_dict.keys()) == set(rv_dict.keys())
@@ -2424,11 +3288,11 @@ class TestGisIdentify:
                                 # nor reversed attributes: they must match
                                 assert attr_value == rv_dict[attr_key]
                         
-                    else: # the arcs are not the same in reverse
+                    else: # the edges are not the same in reverse
                         # at least one of their attributes must be different or
                         # incompatible
-                        fw_dict = network.get_edge_data(*arc_key)
-                        rv_dict = network.get_edge_data(*other_arc_key)
+                        fw_dict = network.get_edge_data(*edge_key)
+                        rv_dict = network.get_edge_data(*other_edge_key)
                         error_raised = False
                         try:
                             # should have the same attributes
@@ -2563,13 +3427,11 @@ class TestGisIdentify:
         assert gis_iden.is_edge_consistent_with_geometry(network, edge_key)
         edge_key = (1104936963, 115831, 0)
         assert gis_iden.is_edge_consistent_with_geometry(network, edge_key)
-        
-        
-                                
+                           
     # *************************************************************************
     # *************************************************************************
     
-    def test_valid_paths(self):
+    def test_valid_node_paths(self):
         
         # *********************************************************************
         # *********************************************************************
@@ -2604,6 +3466,7 @@ class TestGisIdentify:
         
         invalid_node_paths = [
             [], # empty list
+            [1], # single node path
             [-1,0,1,2,3], # nodes do not belong to the network
             [3,2,1,0], # path 1 reversed
             [3,4,5,6], # path 2 reversed
@@ -2611,16 +3474,72 @@ class TestGisIdentify:
             [6,7,8,10] # node 10 is connected to node 8 but not the other way arou.
             ]
         
+        # make sure valid node paths are valid
         for path in valid_node_paths:
-            
             assert gis_iden.is_node_path(network, path)
-        
         # make sure invalid node paths are invalid
-        
         for path in invalid_node_paths:
-            
             assert not gis_iden.is_node_path(network, path)
-            
+        
+        # *********************************************************************
+        # *********************************************************************
+        
+        consider_reversed_edges = True
+        
+        valid_node_paths = [
+            [0,1,2,3],
+            [6,5,4,3],
+            [6,7,8,9],
+            [10,8,9],
+            [3,2,1,0], # path 1 reversed
+            [3,4,5,6], # path 2 reversed
+            [9,8,7,6], # path 3 reversed
+            [6,7,8,10] # node 10 is connected to node 8 but not the other way arou.
+            ]
+        
+        invalid_node_paths = [
+            [], # empty list
+            [1], # single node path
+            [-1,0,1,2,3], # nodes do not belong to the network
+            ]
+        
+        # make sure valid node paths are valid
+        for path in valid_node_paths:
+            assert gis_iden.is_node_path(network, path, consider_reversed_edges)
+        # make sure invalid node paths are invalid
+        for path in invalid_node_paths:
+            assert not gis_iden.is_node_path(
+                network, 
+                path, 
+                consider_reversed_edges
+                )
+                           
+    # *************************************************************************
+    # *************************************************************************
+    
+    def test_valid_edge_paths(self):
+        
+        # *********************************************************************
+        # *********************************************************************
+        
+        # create network
+        
+        network = nx.MultiDiGraph()
+        
+        # define and add edges
+        
+        list_edges = [
+            (0,1),(1,2),(2,3), # path 1
+            (4,3),(5,4),(6,5), # path 2
+            (6,7),(7,8),(8,9), # path 3
+            (2,2), # self loop on path 1
+            (4,4), # self loop on path 2
+            (9,9), # self loop on path 3
+            (10,8) # extra lone neighbour for node 8 on
+            ]
+        
+        network.add_edges_from(list_edges)
+        
         # *********************************************************************
         # *********************************************************************
         
@@ -2790,18 +3709,17 @@ class TestGisIdentify:
         
         # *********************************************************************
         # *********************************************************************
-
-    def test_simplifiable_paths(self):
+        
+    # *************************************************************************
+    # *************************************************************************
     
-        # *********************************************************************
-        # *********************************************************************
+    def test_straight_paths_reversed_edges_self_loops(self):
         
         # create network
         
         network = nx.MultiDiGraph()
         
         # define and add edges
-        
         list_edges = [
             (0,1),(1,2),(2,3), # path 1
             (4,3),(5,4),(6,5), # path 2
@@ -2811,75 +3729,78 @@ class TestGisIdentify:
             (9,9), # self loop on path 3
             (10,8) # extra lone neighbour for node 8 on
             ]
-        
         network.add_edges_from(list_edges)
         
-        # *********************************************************************
-        # *********************************************************************
-        
-        # node paths
-        
-        path_as_node_keys = True
-        
-        # arc directions matter
-        
-        ignore_arc_directions = False
+        # reversed edges are okay, self loops too
         
         ignore_self_loops = True
+        consider_reversed_edges = True
         
         # valid node paths
-        
         valid_straight_node_paths = [
             [0,1,2], 
             [1,2,3],
             [0,1,2,3],
             [5,4,3],
             [6,5,4],
-            [6,5,4,3]
+            [6,5,4,3],
+            [0,1],          # just two nodes
+            [0,1,2,3,4],    # node 4 is connected using an edge in the opposite dir.
+            [6,5,4,3,2],    # node 2 is connected using an edge in the opposite dir.
+            [3,4,5,6],      # the path is reversed
             ]
         
         # invalid node paths
-        
         invalid_straight_node_paths = [
-            [0,1],          # just two nodes
-            [0,1,2,3,4],    # node 4 is connected using an arc in the opposite dir.
-            [6,5,4,3,2],    # node 2 is connected using an arc in the opposite dir.
             [6,7,8,9],      # node 8 has three neighbours (7, 9 and 10)
-            [3,4,5,6],      # the path is reversed
             [0,4,1],        # node 4 is not a neighbour of nodes 0 and 1
             [11,3,4,5,6]    # there is no node 11
             ]
         
         # make sure valid node paths are valid
-        
         for path in valid_straight_node_paths:
-            
-            assert gis_iden.is_path_simplifiable(
+            assert gis_iden.is_path_straight(
                 network, 
                 path,
-                path_as_node_keys=path_as_node_keys,
-                ignore_arc_directions=ignore_arc_directions,
+                consider_reversed_edges=consider_reversed_edges,
                 ignore_self_loops=ignore_self_loops)
         
         # make sure invalid node paths are invalid
-        
         for path in invalid_straight_node_paths:
-            
-            assert not gis_iden.is_path_simplifiable(
+            assert not gis_iden.is_path_straight(
                 network, 
                 path,
-                path_as_node_keys=path_as_node_keys,
-                ignore_arc_directions=ignore_arc_directions,
+                consider_reversed_edges=consider_reversed_edges,
                 ignore_self_loops=ignore_self_loops)
                 
         # *********************************************************************
         # *********************************************************************
         
-        # ignore arc directions
+    # *************************************************************************
+    # *************************************************************************
+    
+    def test_straight_paths_no_reversed_edges_self_loops(self):
+        
+        # create network
+        
+        network = nx.MultiDiGraph()
+        
+        # define and add edges
+        list_edges = [
+            (0,1),(1,2),(2,3), # path 1
+            (4,3),(5,4),(6,5), # path 2
+            (6,7),(7,8),(8,9), # path 3
+            (2,2), # self loop on path 1
+            (4,4), # self loop on path 2
+            (9,9), # self loop on path 3
+            (10,8) # extra lone neighbour for node 8 on
+            ]
+        network.add_edges_from(list_edges)
         
-        ignore_arc_directions = True
+        # no reversed edges, self loops are okay
         
         ignore_self_loops = True
+        consider_reversed_edges = False
         
         # valid node paths
         
@@ -2887,25 +3808,25 @@ class TestGisIdentify:
             [0,1,2], 
             [1,2,3],
             [0,1,2,3],
-            [2,1,0],
-            [3,2,1],
-            [3,2,1,0],
             [5,4,3],
             [6,5,4],
             [6,5,4,3],
-            [3,4,5],
-            [4,5,6],
-            [3,4,5,6],
-            [0,1,2,3,4,5,6,7,8],
-            [8,7,6,5,4,3,2,1,0],
-            [0,1,2,3,4],
-            [6,5,4,3,2]
+            [0,1],          # just two nodes
             ]
         
         # invalid node paths
         
         invalid_straight_node_paths = [
-            [0,1],          # just two nodes
+            [2,1,0],        # reversed path
+            [3,2,1],        # reversed path
+            [3,2,1,0],      # reversed path
+            [3,4,5],        # reversed path
+            [4,5,6],        # reversed path
+            [3,4,5,6],      # reversed path
+            [0,1,2,3,4,5,6,7,8], # path with reversed elements
+            [8,7,6,5,4,3,2,1,0], # path with reversed element
+            [0,1,2,3,4],        # path with reversed elements
+            [6,5,4,3,2],        # the last edge is reversed
             [6,7,8,9],      # node 8 has three neighbours (7, 9 and 10)
             [0,4,1],        # node 4 is not a neighbour of nodes 0 and 1
             [11,3,4,5,6],   # there is no node 11
@@ -2913,34 +3834,50 @@ class TestGisIdentify:
             [9,8,7,6,5,4,3,2,1,0]  # node 8 has three neighbours (7, 9 and 10)
             ]
         
-        # make sure valid node paths are valid
-        
-        for path in valid_straight_node_paths:
-            
-            assert gis_iden.is_path_simplifiable(
+        # make sure valid node paths are valid     
+        for path in valid_straight_node_paths: 
+            assert gis_iden.is_path_straight(
                 network, 
                 path,
-                path_as_node_keys=path_as_node_keys,
-                ignore_arc_directions=ignore_arc_directions,
+                consider_reversed_edges=consider_reversed_edges,
                 ignore_self_loops=ignore_self_loops)
         
-        # make sure invalid node paths are invalid
-        
+        # make sure invalid node paths are invalid 
         for path in invalid_straight_node_paths:
-            
-            assert not gis_iden.is_path_simplifiable(
+            assert not gis_iden.is_path_straight(
                 network, 
                 path,
-                path_as_node_keys=path_as_node_keys,
-                ignore_arc_directions=ignore_arc_directions,
+                consider_reversed_edges=consider_reversed_edges,
                 ignore_self_loops=ignore_self_loops)
             
         # *********************************************************************
         # *********************************************************************
         
-        ignore_arc_directions = False
+    # *************************************************************************
+    # *************************************************************************
+    
+    def test_straight_paths_no_reversed_edges_no_self_loops(self):
+        
+        # create network
+        
+        network = nx.MultiDiGraph()
+        
+        # define and add edges
+        list_edges = [
+            (0,1),(1,2),(2,3), # path 1
+            (4,3),(5,4),(6,5), # path 2
+            (6,7),(7,8),(8,9), # path 3
+            (2,2), # self loop on path 1
+            (4,4), # self loop on path 2
+            (9,9), # self loop on path 3
+            (10,8) # extra lone neighbour for node 8 on
+            ]
+        network.add_edges_from(list_edges)
+        
+        # no reversed edges, self loops are not okay
         
         ignore_self_loops = False
+        consider_reversed_edges = False
         
         # (0,1),(1,2),(2,3), # path 1
         # (4,3),(5,4),(6,5), # path 2
@@ -2969,36 +3906,50 @@ class TestGisIdentify:
             [2,1,0]
             ]
         
-        # make sure valid node paths are valid
-        
-        for path in valid_straight_node_paths:
-            
-            assert gis_iden.is_path_simplifiable(
+        # make sure valid node paths are valid     
+        for path in valid_straight_node_paths: 
+            assert gis_iden.is_path_straight(
                 network, 
                 path,
-                path_as_node_keys=path_as_node_keys,
-                ignore_arc_directions=ignore_arc_directions,
+                consider_reversed_edges=consider_reversed_edges,
                 ignore_self_loops=ignore_self_loops)
         
-        # make sure invalid node paths are invalid
-        
+        # make sure invalid node paths are invalid 
         for path in invalid_straight_node_paths:
-            
-            assert not gis_iden.is_path_simplifiable(
+            assert not gis_iden.is_path_straight(
                 network, 
                 path,
-                path_as_node_keys=path_as_node_keys,
-                ignore_arc_directions=ignore_arc_directions,
+                consider_reversed_edges=consider_reversed_edges,
                 ignore_self_loops=ignore_self_loops)
             
         # *********************************************************************
         # *********************************************************************
         
-        # ignore arc directions
+    # *************************************************************************
+    # *************************************************************************
+    
+    def test_straight_paths_reversed_edges_no_self_loops(self):
+        
+        # create network
+        
+        network = nx.MultiDiGraph()
+        
+        # define and add edges
+        list_edges = [
+            (0,1),(1,2),(2,3), # path 1
+            (4,3),(5,4),(6,5), # path 2
+            (6,7),(7,8),(8,9), # path 3
+            (2,2), # self loop on path 1
+            (4,4), # self loop on path 2
+            (9,9), # self loop on path 3
+            (10,8) # extra lone neighbour for node 8 on
+            ]
+        network.add_edges_from(list_edges)
         
-        ignore_arc_directions = True
+        # reversed edges are okay, self loops are not
         
         ignore_self_loops = False
+        consider_reversed_edges = True
         
         # valid node paths
         
@@ -3020,33 +3971,27 @@ class TestGisIdentify:
             [6,5,4,3]
             ]
         
-        # make sure valid node paths are valid
-        
-        for path in valid_straight_node_paths:
-            
-            assert gis_iden.is_path_simplifiable(
+        # make sure valid node paths are valid     
+        for path in valid_straight_node_paths: 
+            assert gis_iden.is_path_straight(
                 network, 
                 path,
-                path_as_node_keys=path_as_node_keys,
-                ignore_arc_directions=ignore_arc_directions,
+                consider_reversed_edges=consider_reversed_edges,
                 ignore_self_loops=ignore_self_loops)
         
-        # make sure invalid node paths are invalid
-        
+        # make sure invalid node paths are invalid 
         for path in invalid_straight_node_paths:
-            
-            assert not gis_iden.is_path_simplifiable(
+            assert not gis_iden.is_path_straight(
                 network, 
                 path,
-                path_as_node_keys=path_as_node_keys,
-                ignore_arc_directions=ignore_arc_directions,
+                consider_reversed_edges=consider_reversed_edges,
                 ignore_self_loops=ignore_self_loops)
                 
         # *********************************************************************
         # *********************************************************************
         
-    #**************************************************************************
-    #**************************************************************************
+    # *************************************************************************
+    # *************************************************************************
     
     def test_nearest_node_keys(self):
         
@@ -3179,4 +4124,4 @@ class TestGisIdentify:
                 abs_tol=1)
     
 #******************************************************************************
-#******************************************************************************
\ No newline at end of file
+#******************************************************************************
diff --git a/tests/test_gis_modify.py b/tests/test_gis_modify.py
index 96c21ba8694fe4c60edf75c0b5de20a18a756bb8..90a7f5b94b0567c7ca1ff413f7697ecccd21a233 100644
--- a/tests/test_gis_modify.py
+++ b/tests/test_gis_modify.py
@@ -748,7 +748,7 @@ class TestGisModify:
         for edge_key in removed_edges:
             # confirm that there is at least one edge in reverse
             reverse_edge_found = False
-            for other_edge_key in gis_iden.all_arcs_from_a_to_b(
+            for other_edge_key in gis_iden.get_edges_from_a_to_b(
                     network, 
                     edge_key[1], 
                     edge_key[0]):
@@ -774,7 +774,7 @@ class TestGisModify:
         for edge_key in removed_edges:
             # confirm that there is at least one edge in reverse
             reverse_edge_found = False
-            for other_edge_key in gis_iden.all_arcs_from_a_to_b(
+            for other_edge_key in gis_iden.get_edges_from_a_to_b(
                     network, 
                     edge_key[1], 
                     edge_key[0]):
@@ -3201,4 +3201,4 @@ class TestGisModify:
         # *********************************************************************
     
 # *****************************************************************************
-# *****************************************************************************
\ No newline at end of file
+# *****************************************************************************
diff --git a/tests/test_gis_utils.py b/tests/test_gis_utils.py
index 05697d809d3800b87bba1fb5bfffba47fc6ef6fa..961100c3e134649b061a4413d100f30272111290 100644
--- a/tests/test_gis_utils.py
+++ b/tests/test_gis_utils.py
@@ -945,7 +945,7 @@ class TestGisUtils:
         
         # find out which is the closest arc
         
-        nearest_arc_keys, network = gis_iden.identify_arc_closest_to_node(
+        nearest_arc_keys, network = gis_iden.identify_edge_closest_to_node(
             network,
             node_keys=['P'])
         
@@ -2049,7 +2049,7 @@ class TestGisUtils:
         
             edge_dict = directed_network.edges[edge_key]
             
-            for other_edge_key in gis_iden.all_arcs_from_a_to_b(
+            for other_edge_key in gis_iden.get_edges_from_a_to_b(
                     network, edge_key[0], edge_key[1]):
                 
                 # check all attributes
@@ -2087,4 +2087,4 @@ class TestGisUtils:
     # *************************************************************************
         
 # *************************************************************************
-# *************************************************************************
\ No newline at end of file
+# *************************************************************************