private function find_strongly_connected_components($first_task)
{
$first_marked_node =& $this->mark_node($first_task);
$this->current_index++;
$this->visited_nodes->push($first_task);
foreach ($first_task->get_dependencies() as $name => $second_task) {
$second_task_key = $this->task_key($second_task);
if (!$this->has_marked_node($second_task)) {
$this->find_strongly_connected_components($second_task);
$second_marked_node =& $this->get_marked_node($second_task);
$first_marked_node['lowlink'] = min($first_marked_node['lowlink'], $second_marked_node['lowlink']);
} else {
if ($this->marked_nodes[$second_task_key]['on_stack'] === true) {
$second_marked_node =& $this->get_marked_node($second_task);
$first_marked_node['lowlink'] = min($first_marked_node['lowlink'], $second_marked_node['index']);
}
}
}
if ($first_marked_node['lowlink'] == $first_marked_node['index']) {
$connected_component = array();
do {
$next_node = $this->visited_nodes->pop();
$next_marked_node =& $this->get_marked_node($next_node);
$connected_component[] = $next_node;
$next_marked_node['on_stack'] = false;
} while ($first_marked_node['task_node'] !== $next_node);
$this->connected_components[] = $connected_component;
}
}