+ free_noncritical_blocks();
+
+ Route *lead = 0;
+ if(r && !blocks.empty())
+ {
+ TrackIter first = blocks.front().track_iter();
+ TrackIter next = blocks.back().next().track_iter();
+ if(!r->has_track(*next))
+ {
+ lead = Route::find(next, *r);
+ if(!lead)
+ return false;
+ create_lead_route(lead, lead);
+ routes.push_front(lead);
+ }
+ else if(!r->has_track(*first))
+ lead = create_lead_route(0, r);
+ }
+
+ routes.clear();
+ if(lead)
+ routes.push_back(lead);
+ if(r)
+ routes.push_back(r);
+ end_of_route = false;
+
+ reserve_more();
+
+ signal_route_changed.emit(get_route());
+
+ return true;
+}
+
+bool Train::go_to(Track &to)
+{
+ for(BlockList::const_iterator i=blocks.begin(); i!=cur_blocks_end; ++i)
+ if((*i)->has_track(to))
+ {
+ signal_arrived.emit();
+ return set_route(0);
+ }
+
+ free_noncritical_blocks();
+
+ TrackIter next = blocks.back().next().track_iter();
+
+ Route *route = Route::find(next, to);
+ if(!route)
+ return false;
+ create_lead_route(route, route);
+ return set_route(route);
+}
+
+bool Train::divert(Track &from)
+{
+ if(!from.get_turnout_id())
+ throw InvalidParameterValue("Can't divert from a non-turnout");
+ if(routes.empty())
+ return false;
+
+ unsigned path = 0;
+ unsigned entry = 0;
+ list<RouteRef>::iterator route = routes.begin();
+
+ // Follow our routes to find out where we're entering the turnout
+ for(TrackLoopIter track = blocks.front().track_iter();;)