def _tarjan(self, function, order, stack, data):
try:<EOL><INDENT>func_data = data[function.id]<EOL>return order<EOL><DEDENT>except KeyError:<EOL><INDENT>func_data = self._TarjanData(order)<EOL>data[function.id] = func_data<EOL><DEDENT>order += <NUM_LIT:1><EOL>pos = len(stack)<EOL>stack.append(function)<EOL>func_data.onstack = True<EOL>for call in compat_itervalues(function.calls):<EOL><INDENT>try:<EOL><INDENT>callee_data = data[call.callee_id]<EOL>if callee_data.onstack:<EOL><INDENT>func_data.lowlink = min(func_data.lowlink, callee_data.order)<EOL><DEDENT><DEDENT>except KeyError:<EOL><INDENT>callee = self.functions[call.callee_id]<EOL>order = self._tarjan(callee, order, stack, data)<EOL>callee_data = data[call.callee_id]<EOL>func_data.lowlink = min(func_data.lowlink, callee_data.lowlink)<EOL><DEDENT><DEDENT>if func_data.lowlink == func_data.order:<EOL><INDENT>members = stack[pos:]<EOL>del stack[pos:]<EOL>if len(members) > <NUM_LIT:1>:<EOL><INDENT>cycle = Cycle()<EOL>for member in members:<EOL><INDENT>cycle.add_function(member)<EOL>data[member.id].onstack = False<EOL><DEDENT><DEDENT>else:<EOL><INDENT>for member in members:<EOL><INDENT>data[member.id].onstack = False<EOL><DEDENT><DEDENT><DEDENT>return order<EOL>
Tarjan's strongly connected components algorithm.

        See also:
        - http://en.wikipedia.org/wiki/Tarjan's_strongly_connected_components_algorithm