+int Route::get_turnout(unsigned id) const
+{
+ map<unsigned, int>::const_iterator i = turnouts.find(id);
+ if(i!=turnouts.end())
+ return i->second;
+ return -1;
+}
+
+unsigned Route::get_path(Track &trk) const
+{
+ if(unsigned tid = trk.get_turnout_id())
+ {
+ map<unsigned, int>::const_iterator i = turnouts.find(tid);
+ if(i!=turnouts.end())
+ return i->second;
+ }
+ return trk.get_active_path();
+}
+
+void Route::add_track(Track &trk)
+{
+ if(tracks.count(&trk))
+ return;
+
+ if(!tracks.empty())
+ {
+ unsigned valid = check_validity(trk);
+ if(!(valid&1))
+ throw Exception("Not linked to existing tracks");
+ else if(!(valid&2))
+ throw Exception("Branching routes not allowed");
+ else if(!(valid&4))
+ throw Exception("Route must be smooth");
+ }
+
+ tracks.insert(&trk);
+ update_turnouts();
+}
+
+void Route::add_tracks(const set<Track *> &trks)
+{
+ set<Track *> pending;
+ for(set<Track *>::const_iterator i=trks.begin(); i!=trks.end(); ++i)
+ if(!tracks.count(*i))
+ pending.insert(*i);
+
+ while(!pending.empty())
+ {
+ bool found = false;
+ for(set<Track *>::const_iterator i=pending.begin(); i!=pending.end(); ++i)
+ if(tracks.empty() || check_validity(**i)==7)
+ {
+ tracks.insert(*i);
+ pending.erase(*i);
+ found = true;
+ break;
+ }
+
+ if(!found)
+ throw Exception("Could not add all tracks to route");
+ }
+
+ update_turnouts();
+}
+
+void Route::add_track_chain(Track &start, unsigned ep, const TurnoutMap &trnts)
+{
+ TrackIter iter(&start, ep);
+ while(iter)
+ {
+ if(iter->get_type().is_dead_end())
+ break;
+
+ if(has_track(*iter))
+ break;
+
+ int path = 0;
+ if(iter->get_turnout_id())
+ {
+ TurnoutMap::const_iterator i = trnts.find(iter->get_turnout_id());
+ if(i==trnts.end())
+ break;
+
+ path = i->second;
+ }
+
+ add_track(*iter);
+
+ iter = iter.next(path);
+ }
+}
+
+bool Route::has_track(Track &t) const
+{
+ return tracks.count(&t);
+}
+
+void Route::save(list<DataFile::Statement> &st) const
+{
+ st.push_back((DataFile::Statement("name"), name));
+ for(map<unsigned, int>::const_iterator i=turnouts.begin(); i!=turnouts.end(); ++i)
+ st.push_back((DataFile::Statement("turnout"), i->first, i->second));
+}
+
+unsigned Route::check_validity(Track &trk) const