diff --git a/generator/transform/GeneratePML.py b/generator/transform/GeneratePML.py
index ecb5dfdad34fff12457025778567d3dd0964dd1f..1661d71ae968236af60da8609c245eb4102288a7 100644
--- a/generator/transform/GeneratePML.py
+++ b/generator/transform/GeneratePML.py
@@ -1,12 +1,14 @@
 from generator.analysis.Analysis import Analysis, PassInformation
 from generator.analysis import SavedStateTransition, Function
 from generator.analysis.AtomicBasicBlock import E, S
+from generator.analysis.common import *
 from collections import defaultdict
 import os
 import logging
 import yaml
+import networkx
 
-class GeneratePML(Analysis):
+class GeneratePML(Analysis, GraphObject):
     """ FIXME
 
     """
@@ -16,54 +18,92 @@ class GeneratePML(Analysis):
         used_cfg_edges = {E.function_level, E.timing_edge_0, E.timing_edge_1}
     )
 
-    def get_circuit_states(self, start, end):
-        start, end = set(start), set(end)
-        # 0. Find all CFG successors
-        stop = set()
-        for abb in end:
-            stop.update(abb.get_outgoing_nodes(E.function_level))
-        # 1. Find all states that will execute one ABB from the end set
+    def __init__(self):
+        Analysis.__init__(self)
+        GraphObject.__init__(self, "GeneratePML", root = True)
+
+    def graph_subobjects(self):
+        subobjects = []
+        for circuit in self.circuits:
+            if len(circuit['all_states']) > 500:
+                continue
+
+            mapping = {}
+            for state in circuit['all_states'].values():
+                color = 'green'
+                if id(state) in circuit['end_states']:
+                    color = 'red'
+                if id(state) in circuit['start_states']:
+                    color='blue'
+                label="N%d:%s/%s" %(circuit['state_to_idx'][id(state)],
+                                    state.current_subtask,
+                                    state.current_abb)
+                node = GraphObjectContainer(label, color=color)
+                mapping[id(state)] = node
+                subobjects.append(node)
+
+            for a in circuit['all_states'].values():
+                for b in a.get_outgoing_nodes(SavedStateTransition):
+                    if id(b) in circuit['all_states']:
+                        mapping[id(a)].edges.append(
+                            Edge(mapping[id(a)], mapping[id(b)]))
+
+        return subobjects
+
+
+    def get_circuit_states(self, start_abbs, end_abbs):
+        # 1. Find all starting states
         sse = self.system_graph.get_pass("sse")
-        start_states, end_states, stop_states = [], [], []
+        start_states, end_states = {}, {}
         for state in sse.states:
-            if state.current_abb in start:
-                start_states.append(state)
-            if state.current_abb in end:
-                end_states.append(state)
-        start_state_ids = {id(x) for x in start_states}
-        end_state_ids = {id(x) for x in end_states}
-        # stop_state_ids = {id(x) for x in stop_states}
+            if state.current_abb in start_abbs:
+                start_states[id(state)] = state
 
         # 2. DFS starting from the first element in the graph.
         # 2.1 All end states are definitly part of the graph
         good_states = { }
+        def add_to_good_states(path, curr):
+            for x in path + [curr]:
+                good_states[id(x)] = x
         def dfs(path, curr):
             # Uncomment for debugging purposes
             # print("V", [(x.current_subtask, x.current_abb) for x in path + [curr]])
 
-            if id(curr) in end_state_ids or id(curr) in good_states or\
-               id(curr) in [id(x) for x in path]:
+            state_loop = id(curr) in [id(x) for x in path]
+            hit_on_good_state = id(curr) in good_states
+            is_end_state = curr.current_abb in end_abbs
+
+            if state_loop or hit_on_good_state or is_end_state:
                 # print("A")
                 # Add the path to the good states
-                for x in path + [curr]:
-                    good_states[id(x)] = x
+                add_to_good_states(path, curr)
+
+            assert not is_end_state or (end_abbs[curr.current_abb] & 1) == 0, \
+                "TIMING_POINT_STOP_BEFORE should not be directly visited"
+
+            if is_end_state:
+                end_states[id(curr)] = curr
 
             # Stop DFS, if we were here already
             if id(curr) in visited:
                 return
 
-
             visited.add(id(curr))
             path = path + [curr]
             for succ in curr.get_outgoing_nodes(SavedStateTransition):
-                # Do not proceed locally on state graph within subtask
-                if id(curr) in end_state_ids:
-                    if succ.current_subtask == curr.current_subtask:
+                # Edges that origin from an end state to the same
+                # subtask are not taken.
+                if is_end_state and succ.current_subtask == curr.current_subtask:
                         continue
+                if succ.current_abb in end_abbs and (end_abbs[succ.current_abb] & 1) == 1:
+                    # TIMING_POINT_STOP_BEFORE
+                    end_states[id(curr)] = curr
+                    add_to_good_states(path, curr)
+                    continue
                 dfs(path, succ)
 
         visited = set()
-        for state in start_states:
+        for state in start_states.values():
             dfs([], state)
 
         # for state in good_states.values():
@@ -73,11 +113,11 @@ class GeneratePML(Analysis):
                 logging.warning("Idle state part of circuit... unanalyzable")
 
         # Every State can only occur only once in the result
-        return good_states.values()
+        return start_states, good_states, end_states
 
-    def find_irq_regions(self, circuit):
+    def find_irq_regions(self, all_states):
         """ Find all IRQ regions in a circuit. A IRQ region has one ISR kickoff, and N ISR exits"""
-        for state in circuit['states']:
+        for state in all_states.values():
             if state.current_subtask and state.current_subtask.conf.is_isr \
                and state.current_abb.isA(S.kickoff):
                 assert len(state.get_incoming_nodes(SavedStateTransition)) == 1,\
@@ -86,7 +126,7 @@ class GeneratePML(Analysis):
                 stack = [state]
                 visited = set()
                 entry = state
-                exits = set()
+                exits = {}
                 states = []
                 while stack:
                     p = stack.pop()
@@ -97,18 +137,22 @@ class GeneratePML(Analysis):
                     if p.current_abb.isA(S.iret):
                         assert len(p.get_outgoing_nodes(SavedStateTransition)) == 1,\
                             "Unexpected IRET state"
-                        exits.add(p)
+                        exits[id(p)] = p
                     else:
-                        stack.extend(p.get_outgoing_nodes(SavedStateTransition))
-                yield {'entry': entry, 'states': states, 'exits': exits}
-
-    def add_cfg_edges(self, circuit):
+                        for n in p.get_outgoing_nodes(SavedStateTransition):
+                            if id(n) in all_states:
+                                stack.append(n)
+                            else:
+                                exits[id(p)] = p
+                yield {'entry': entry, 'states': states, 'exits': exits.values()}
+
+    def add_cfg_edges(self, circuit_number, all_states):
         """Draw Edges (only for visualization) between the connected ABBs"""
         edges = set([])
-        edge_type = [E.timing_edge_0, E.timing_edge_1][circuit["circuit"] % 2]
-        for a in circuit["states"]:
+        edge_type = [E.timing_edge_0, E.timing_edge_1][circuit_number % 2]
+        for a in all_states.values():
             for b in a.get_outgoing_nodes(SavedStateTransition):
-                if id(b) not in circuit["state-ids"]:
+                if id(b) not in all_states:
                     continue
                 if (a.current_abb, b.current_abb) in edges:
                     continue
@@ -121,9 +165,11 @@ class GeneratePML(Analysis):
         self.flow_frequency_variable_counter += 1
         return "flow_var_" + hint + "_" + str(tmp)
 
-    def add_circuit_to_pml(self, pml, circuit):
+    def add_circuit_to_pml(self, pml, circuit_number,
+                           start_states, all_states, end_states,
+                           loops):
         """Adds the global-cfg field to the PML"""
-        gcfg = {'name': 'timing-%d' % circuit['circuit'],
+        gcfg = {'name': 'timing-%d' % circuit_number,
                 'level': 'bitcode',
                 'entry-nodes': [],
                 'exit-nodes': [],
@@ -136,23 +182,34 @@ class GeneratePML(Analysis):
             gcfg['blocks'].append(data)
             return i, data
         def delete_block(idx):
+            assert False
             gcfg['blocks'][idx] = None
 
         # First we generate the artificial blocks
         isr_entry_abb_idx, _ = add_block({'function': 'irq_entry', 'name':"isr_entry_block"})
 
-        # Assign an idx to every state and abb
+        # Assign an idx to every state and abb. States are monotonly
+        # increasing numbers that refence objects in the PML
         abb_to_idx = {}
         state_to_idx = {}
-        def idx(state):
-            if id(state) in state_to_idx:
-                return state_to_idx[id(state)]
-            return abb_to_idx[state]
+        def idx(obj):
+            if id(obj) in state_to_idx:
+                return state_to_idx[id(obj)]
+            return abb_to_idx[obj]
 
         timer_function_name = '_ZN2os7Counter4tickEv'
 
-        for state in circuit['states']:
+        # Some states are part of a toplevel loop
+        state_to_loops = defaultdict(lambda: list())
+        for loop, states in loops.items():
+            for state in states:
+                state_to_loops[id(state)].append(loop)
+
+        for state in all_states.values():
+            # We first assign an id to the state
             state_to_idx[id(state)] = len(state_to_idx)
+
+            # We have to add an ABB object to the PML, for every ABB we newly ancounter
             abb = state.current_abb
             if abb not in abb_to_idx:
                 # ISR entry and Exit Nodes are filled separatly
@@ -184,25 +241,30 @@ class GeneratePML(Analysis):
                         record['exit-block'] = 'idle_loop_again'
 
 
-            # Some states are entry states, some states are know to be
-            # exit nodes
-            if abb in circuit['start']:
-                gcfg['entry-nodes'].append(idx(state))
-            if abb in circuit['end']:
-                gcfg['exit-nodes'].append(idx(state))
+
+        # After having an index for every state, we can mark states as
+        # entry or exit nodes.
+        for state in start_states.values():
+            gcfg['entry-nodes'].append(idx(state))
+        for state in end_states.values():
+            gcfg['exit-nodes'].append(idx(state))
 
 
         # Add all state records to the gcfg
-        for state in circuit['states']:
+        for state in all_states.values():
             successors = [x for x in state.get_outgoing_nodes(SavedStateTransition)
-                          if id(x) in circuit['state-ids']]
+                          if id(x) in all_states]
             local_successors = [idx(x) for x in successors if x.current_subtask == state.current_subtask]
             global_successors = [idx(x) for x in successors if x.current_subtask != state.current_subtask]
 
-            successors = [idx(x) for x in successors if id(x) in circuit['state-ids']]
+            successors = [idx(x) for x in successors if id(x) in all_states]
             data = {'index': idx(state),
                     'local-successors': local_successors,
                     'global-successors': global_successors}
+            # Annotate that states are part of a loop
+            if id(state) in state_to_loops:
+                data['loops'] = state_to_loops[id(state)]
+
             if state.current_abb in abb_to_idx:
                 data['abb'] = abb_to_idx[state.current_abb]
                 data['abb-name'] = str(state.current_abb)
@@ -215,17 +277,12 @@ class GeneratePML(Analysis):
             gcfg['nodes'].append(data)
 
         irq_entry_variables = defaultdict(list)
-        #print (circuit['states'])
 
         # Transform IRQ Regions
         ast_requests = set()
-        for region in self.find_irq_regions(circuit):
+        for region in self.find_irq_regions(all_states):
             isr_entry = region['entry']
             isr_entry_data = gcfg['nodes'][idx(isr_entry)]
-            # Sometimes an IRQ entry can be
-            if region['entry'].current_abb in circuit['start']:
-                gcfg['entry-nodes'].append(idx(isr_entry))
-
 
             # Give the isr_entry block a flow variable. This flow
             # variable, will capture how often an interrupt is
@@ -240,7 +297,6 @@ class GeneratePML(Analysis):
             isr_entry_data['abb'] = isr_entry_abb_idx
             isr_entry_data['abb-name'] = 'isr_entry'
 
-
             for isr_exit in region['exits']:
                 if id(isr_exit) not in state_to_idx:
                     continue
@@ -253,8 +309,7 @@ class GeneratePML(Analysis):
             # flow. This is necessary, since they are embedded into
             # the isr_entry state
             for state in region['states']:
-                if id(state) not in state_to_idx:
-                    continue
+                assert id(state) in state_to_idx
                 state_data = gcfg['nodes'][idx(state)]
                 state_data['abb-name'] = str(state.current_abb)
                 if state != isr_entry:
@@ -331,9 +386,28 @@ class GeneratePML(Analysis):
             'lhs': lhs
 ,        })
 
-        logging.info("     %s: %d states", gcfg['name'], len(gcfg['nodes']))
+        logging.info("     %s: %d states, %d loops", gcfg['name'],
+                     len(gcfg['nodes']),
+                     len(loops))
+        return state_to_idx
 
+    def find_loops(self, all_states):
+        # Create Directed Graph
+        G = networkx.DiGraph()
+
+        # Add a list of nodes:
+        G.add_nodes_from(all_states.keys())
+
+        for a in all_states.values():
+            for b in a.get_outgoing_nodes(SavedStateTransition):
+                if id(b) in all_states:
+                    G.add_edge(id(a), id(b))
 
+        loops = {}
+        for loop in networkx.simple_cycles(G):
+            loop_id = len(loops)
+            loops[loop_id] = [all_states[state_id] for state_id in loop]
+        return loops
 
     def do(self):
         self.flow_frequency_variable_counter = 0
@@ -348,37 +422,54 @@ class GeneratePML(Analysis):
 
         # We search for all circuits, the user has annotated with
         # function calls in his application
-        circuits = defaultdict(lambda : {'start': [], 'end': []})
+        circuits = defaultdict(lambda : {'start': {}, 'end': {}})
         for abb in self.system_graph.abbs:
-            for (bb, func, circuit) in abb.call_sites:
+            for (bb, func, args) in abb.call_sites:
+                if func in ('timing_start', 'timing_end'):
+                    circuit = args[0] & 0xff
+                    options = args[0] >> 8
                 if func == "timing_start":
                     if abb.subtask.conf.is_isr:
-                        logging.info("  timing-%d starts with IRQ activation", circuit[0])
+                        logging.info("  timing-%d starts with IRQ activation", circuit)
                         before = abb.definite_before(E.function_level)
                         assert before.isA(S.kickoff), "Can start analysis only at beginning of ISR"
-                        circuits[circuit[0]]["start"].append(before)
+                        circuits[circuit]["start"][before] = options
                     else:
-                        circuits[circuit[0]]["start"].append(abb)
+                        circuits[circuit]["start"][abb] = options
                 if func == "timing_end":
-                    circuits[circuit[0]]["end"].append(abb)
+                    circuits[circuit]["end"][abb] = options
         # Finds all states in between
-        for circuit, data in circuits.items():
-            states = self.get_circuit_states(data["start"], data["end"])
-
-            data['states'] = states
-            data['circuit'] = circuit # Copy ID into dict
-            data['state-ids'] = {id(x) for x in data['states']}
-            self.add_cfg_edges(data)
-
-
-        self.circuits = circuits.values()
-
         pml = {'format': 'pml-0.1',
                'triple': 'patmos-unknown-unknown-elf',
                'global-cfgs': []
         }
-        for circuit in self.circuits:
-            self.add_circuit_to_pml(pml, circuit)
+
+        self.circuits = []
+        for circuit_number, data in circuits.items():
+            start_states, all_states, end_states = self.get_circuit_states(data["start"], data["end"])
+
+            #print([x.current_abb for x in start_states.values()])
+            #print([x.current_abb for x in all_states.values()])
+            #print([x.current_abb for x in end_states.values()])
+            assert all([id_ in all_states for id_ in start_states]), \
+                "All start states must be part of the all_state set"
+            assert all([id_ in all_states for id_ in end_states]), \
+                "All end states must be part of the all_state set"
+
+            # Copy circuit into graph (combined ABB->ABB edges)
+            self.add_cfg_edges(circuit_number, all_states)
+
+            # Add Circuit to PML
+            loops = self.find_loops(all_states)
+            state_to_idx = self.add_circuit_to_pml(pml, circuit_number,
+                                                   start_states, all_states, end_states,
+                                                   loops)
+
+            self.circuits.append({"index": circuit_number,
+                                  'state_to_idx': state_to_idx,
+                                  'start_states': start_states,
+                                  'all_states': all_states,
+                                  'end_states': end_states})
 
 
         fn = os.path.join(os.path.dirname(self.system_graph.basefilename),