[routino] 01/13: Imported Upstream version 3.0

Sebastiaan Couwenberg sebastic at moszumanska.debian.org
Sun Sep 13 22:33:06 UTC 2015


This is an automated email from the git hooks/post-receive script.

sebastic pushed a commit to branch master
in repository routino.

commit b43cac77b9e5fd31cac181fe40e9a6ea621e7b60
Author: Bas Couwenberg <sebastic at xs4all.nl>
Date:   Sun Sep 13 10:47:03 2015 +0200

    Imported Upstream version 3.0
---
 ChangeLog                                          | 2452 ++++++++++++++------
 Makefile                                           |    5 +-
 Makefile.conf                                      |   58 +-
 doc/INSTALL-MS-WIN.txt                             |  151 ++
 doc/INSTALL.txt                                    |    9 +-
 doc/LIBRARY.txt                                    |  683 ++++++
 doc/NEWS.txt                                       |   44 +-
 doc/OUTPUT.txt                                     |    7 +-
 doc/README.txt                                     |    5 +-
 doc/TAGGING.txt                                    |    4 +-
 doc/USAGE.txt                                      |   26 +-
 doc/html/algorithm.html                            |    5 +-
 doc/html/configuration.html                        |    5 +-
 doc/html/data.html                                 |    5 +-
 doc/html/index.html                                |   22 +-
 doc/html/installation-ms-windows.html              |  247 ++
 doc/html/installation.html                         |   13 +-
 doc/html/library.html                              |  967 ++++++++
 doc/html/limits.html                               |    5 +-
 doc/html/output.html                               |    5 +-
 doc/html/readme.html                               |  169 +-
 doc/html/style.css                                 |   46 +-
 doc/html/tagging.html                              |   24 +-
 doc/html/usage.html                                |   25 +-
 extras/find-fixme/Makefile                         |   50 +-
 extras/find-fixme/README.txt                       |   10 +-
 extras/find-fixme/fixme-dumper.c                   |   62 +-
 extras/find-fixme/fixme-finder.c                   |   85 +-
 extras/find-fixme/osmparser.c                      |   20 +-
 extras/find-fixme/web/www/index.html               |    5 +-
 extras/tagmodifier/Makefile                        |   18 +-
 extras/tagmodifier/README.txt                      |   11 +-
 extras/tagmodifier/tagmodifier.c                   |  105 +-
 src/Makefile                                       |  187 +-
 src/cache.h                                        |   15 +-
 src/errorlog.h                                     |   16 +-
 src/errorlogx.c                                    |   38 +-
 src/fakes.c                                        |   29 +-
 src/fakes.h                                        |    4 +-
 src/filedumper.c                                   |  138 +-
 src/filedumperx.c                                  |   55 +-
 src/files.c                                        |  326 ++-
 src/files.h                                        |   56 +-
 src/functions.h                                    |   23 +-
 src/logerror.c                                     |   12 +-
 src/logging.c                                      |   32 +-
 src/logging.h                                      |    3 +-
 src/mman-win32.c                                   |  206 ++
 src/mman-win32.h                                   |   77 +
 src/nodes.c                                        |   12 +-
 src/nodes.h                                        |   10 +-
 src/nodesx.c                                       |   42 +-
 src/nodesx.h                                       |    6 +-
 src/optimiser.c                                    |  836 +++----
 src/osmo5mparse.c                                  |   15 +-
 src/osmparser.c                                    |   28 +-
 src/osmpbfparse.c                                  |   19 +-
 src/osmxmlparse.c                                  |   88 +-
 src/output.c                                       |  593 +++--
 src/planetsplitter.c                               |  113 +-
 src/profiles.c                                     |  318 ++-
 src/profiles.h                                     |   27 +-
 src/relations.c                                    |    6 +-
 src/relations.h                                    |   10 +-
 src/relationsx.c                                   |   63 +-
 src/relationsx.h                                   |    6 +-
 src/results.c                                      |   14 +-
 src/router+lib.c                                   |  599 +++++
 src/router.c                                       |  507 ++--
 src/routino.c                                      |  728 ++++++
 src/routino.h                                      |  286 +++
 src/segments.c                                     |    6 +-
 src/segments.h                                     |   12 +-
 src/segmentsx.c                                    |   44 +-
 src/segmentsx.h                                    |    6 +-
 src/sorting.c                                      |   52 +-
 src/superx.c                                       |    6 +-
 src/tagging.c                                      |   76 +-
 src/test/Makefile                                  |   66 +-
 src/test/a-b-c-d.sh                                |   27 +-
 src/test/a-b-c.sh                                  |   27 +-
 src/test/a-b.sh                                    |   27 +-
 src/test/copyright.xml                             |    4 +-
 src/test/cycle-drive.sh                            |   35 +-
 src/test/only-split.sh                             |   15 +-
 src/test/run-tests.sh                              |  101 +
 src/test/start-1-finish.sh                         |   27 +-
 src/translations.c                                 |  796 +++++--
 src/translations.h                                 |   98 +-
 src/types.c                                        |    8 +-
 src/typesx.h                                       |    2 +-
 src/uncompress.c                                   |   31 +-
 src/version.h                                      |   30 +
 src/visualiser.c                                   |    9 +-
 src/ways.c                                         |    8 +-
 src/ways.h                                         |   12 +-
 src/waysx.c                                        |   52 +-
 src/waysx.h                                        |   18 +-
 src/xml/Makefile                                   |   34 +-
 src/xml/xsd-to-xmlparser.c                         |   40 +-
 src/xmlparse.c                                     |  178 +-
 src/xmlparse.h                                     |   27 +-
 web/Makefile                                       |  105 +-
 web/translations/router.html                       |   52 +-
 web/translations/translate.pl                      |   15 +-
 web/translations/translation.de.txt                |   57 +-
 web/translations/translation.en.txt                |   21 +-
 web/translations/translation.fr.txt                |   21 +-
 web/translations/translation.hu.txt                |  271 +++
 web/translations/translation.nl.txt                |   47 +-
 web/translations/translation.pl.txt                |  217 ++
 web/translations/translation.ru.txt                |   17 +-
 web/translations/translations-body.xml             |   15 +-
 web/translations/translations-head.xml             |    2 +-
 web/www/leaflet/install.sh                         |    2 +-
 web/www/routino/.htaccess                          |   10 +
 web/www/routino/icons/limit-2.6.png                |  Bin 747 -> 745 bytes
 web/www/routino/icons/limit-2.8.png                |  Bin 747 -> 744 bytes
 web/www/routino/icons/limit-20.6.png               |  Bin 860 -> 858 bytes
 web/www/routino/icons/limit-20.8.png               |  Bin 870 -> 867 bytes
 web/www/routino/icons/limit-21.6.png               |  Bin 833 -> 832 bytes
 web/www/routino/icons/limit-21.8.png               |  Bin 841 -> 840 bytes
 web/www/routino/icons/limit-22.6.png               |  Bin 860 -> 857 bytes
 web/www/routino/icons/limit-22.8.png               |  Bin 866 -> 864 bytes
 web/www/routino/icons/limit-23.6.png               |  Bin 859 -> 858 bytes
 web/www/routino/icons/limit-23.8.png               |  Bin 859 -> 857 bytes
 web/www/routino/icons/limit-24.6.png               |  Bin 814 -> 814 bytes
 web/www/routino/icons/limit-24.8.png               |  Bin 820 -> 820 bytes
 web/www/routino/icons/limit-25.5.png               |  Bin 848 -> 847 bytes
 web/www/routino/icons/limit-25.6.png               |  Bin 867 -> 865 bytes
 web/www/routino/icons/limit-25.8.png               |  Bin 864 -> 864 bytes
 web/www/routino/icons/limit-26.4.png               |  Bin 810 -> 810 bytes
 web/www/routino/icons/limit-26.6.png               |  Bin 852 -> 849 bytes
 web/www/routino/icons/limit-26.8.png               |  Bin 855 -> 851 bytes
 web/www/routino/icons/limit-26.png                 |  Bin 738 -> 737 bytes
 web/www/routino/icons/limit-27.6.png               |  Bin 851 -> 849 bytes
 web/www/routino/icons/limit-27.8.png               |  Bin 836 -> 835 bytes
 web/www/routino/icons/limit-28.4.png               |  Bin 822 -> 823 bytes
 web/www/routino/icons/limit-28.6.png               |  Bin 862 -> 859 bytes
 web/www/routino/icons/limit-28.8.png               |  Bin 845 -> 844 bytes
 web/www/routino/icons/limit-28.png                 |  Bin 728 -> 728 bytes
 web/www/routino/icons/limit-29.6.png               |  Bin 855 -> 853 bytes
 web/www/routino/icons/limit-29.8.png               |  Bin 859 -> 858 bytes
 web/www/routino/index.html                         |    5 +-
 web/www/routino/profiles.js                        |   76 +
 web/www/routino/profiles.pl                        |   78 +
 web/www/routino/router.css                         |   44 +-
 web/www/routino/router.html.de                     |   60 +-
 web/www/routino/router.html.en                     |   42 +-
 web/www/routino/router.html.fr                     |   42 +-
 web/www/routino/router.html.hu                     |  496 ++++
 web/www/routino/router.html.nl                     |   50 +-
 web/www/routino/{router.html.en => router.html.pl} |  202 +-
 web/www/routino/router.html.ru                     |   42 +-
 web/www/routino/router.leaflet.js                  |  256 +-
 web/www/routino/router.openlayers.js               |  257 +-
 web/www/routino/visualiser.html.de                 |   28 +-
 web/www/routino/visualiser.html.en                 |    6 +
 web/www/routino/visualiser.html.fr                 |    6 +
 .../{visualiser.html.nl => visualiser.html.hu}     |  210 +-
 web/www/routino/visualiser.html.nl                 |   24 +-
 .../{visualiser.html.en => visualiser.html.pl}     |  110 +-
 web/www/routino/visualiser.html.ru                 |    6 +
 xml/Makefile                                       |    4 +-
 xml/routino-tagging.xml                            |   10 +-
 xml/routino-translations.xml                       |  277 ++-
 xml/routino-translations.xsd                       |   14 +-
 167 files changed, 12129 insertions(+), 3833 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 3999129..8d78060 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,957 @@
+2015-09-12  Andrew M. Bishop <amb>
+
+	Version 3.0 released.
+
+2015-09-12 [r1798]  Andrew M. Bishop <amb>
+
+	* FILES, doc/NEWS.txt, doc/README.txt, doc/html/readme.html: Update
+	  files for release.
+
+2015-09-09 [r1797]  Andrew M. Bishop <amb>
+
+	* doc/USAGE.txt, doc/html/usage.html, extras/find-fixme/README.txt,
+	  extras/find-fixme/fixme-dumper.c,
+	  extras/find-fixme/fixme-finder.c, extras/tagmodifier/README.txt,
+	  extras/tagmodifier/tagmodifier.c, src/filedumper.c,
+	  src/filedumperx.c, src/planetsplitter.c, src/router+lib.c,
+	  src/router.c, src/version.h (added): Add a '--version' option to
+	  all executables to print the current version (defined in
+	  version.h).
+
+2015-09-07 [r1796]  Andrew M. Bishop <amb>
+
+	* src/output.c, src/translations.c,
+	  web/translations/translation.de.txt,
+	  web/translations/translation.en.txt,
+	  web/translations/translation.fr.txt,
+	  web/translations/translation.hu.txt,
+	  web/translations/translation.nl.txt,
+	  web/translations/translation.pl.txt,
+	  web/translations/translation.ru.txt,
+	  web/translations/translations-body.xml,
+	  web/translations/translations-head.xml,
+	  web/www/routino/router.leaflet.js,
+	  web/www/routino/router.openlayers.js,
+	  xml/routino-translations.xml, xml/routino-translations.xsd: Merge
+	  some of the translation phrases together to simplify them. Change
+	  the HTML output and web pages to work with this.
+
+2015-09-03 [r1795]  Andrew M. Bishop <amb>
+
+	* doc/LIBRARY.txt, doc/html/library.html, src/output.c,
+	  src/router+lib.c, src/routino.c, src/routino.h: Add in an
+	  HTML-all linked list formats that includes the full set of points
+	  and the HTML directions for the important ones.
+
+2015-09-03 [r1794]  Andrew M. Bishop <amb>
+
+	* src/router.c: Bug fix in usage information.
+
+2015-08-17 [r1793]  Andrew M. Bishop <amb>
+
+	* web/www/routino/router.leaflet.js,
+	  web/www/routino/router.openlayers.js: Fix a bug with dragging a
+	  marker from the left panel onto the map when the left panel has
+	  scrolled the page.
+
+2015-08-17 [r1792]  Andrew M. Bishop <amb>
+
+	* doc/LIBRARY.txt, doc/html/library.html, src/router+lib.c,
+	  src/routino.c, src/routino.h, src/translations.c,
+	  src/translations.h: Add a new API function to return the full
+	  names of the languages available in the translations XML file.
+	  Increase API version to 6.
+
+2015-08-17 [r1791]  Andrew M. Bishop <amb>
+
+	* src/test/copyright.xml, src/translations.c, src/translations.h,
+	  web/translations/translate.pl,
+	  web/translations/translations-body.xml,
+	  xml/routino-translations.xml, xml/routino-translations.xsd: Add
+	  the long version of the language name to the XML translations
+	  file.
+
+2015-08-17 [r1790]  Andrew M. Bishop <amb>
+
+	* web/translations/translation.de.txt: Replace one German word
+	  (via http://www.routino.org/translations/).
+
+2015-08-16 [r1789]  Andrew M. Bishop <amb>
+
+	* web/translations/translate.pl,
+	  web/translations/translation.pl.txt,
+	  xml/routino-translations.xml: Delete some Polish documentation
+	  strings that were incorrectly formed (not enough '%s').
+
+2015-08-15 [r1788]  Andrew M. Bishop <amb>
+
+	* doc/html/index.html, doc/html/installation-ms-windows.html,
+	  doc/html/installation.html: Some small documentation tidying up.
+
+2015-08-15 [r1787]  Andrew M. Bishop <amb>
+
+	* extras/find-fixme/Makefile, extras/tagmodifier/Makefile,
+	  src/Makefile, src/xml/Makefile: Use $^ instead of $< in Makefiles
+	  where it is simpler and where there are multiple dependencies
+	  that all need to be used together.
+
+2015-08-15 [r1786]  Andrew M. Bishop <amb>
+
+	* src/test/Makefile: Compile the executables all in one go rather
+	  than running make for each one.
+
+2015-08-15 [r1785]  Andrew M. Bishop <amb>
+
+	* Makefile, src/Makefile: Don't automatically choose the order in
+	  which to enter the sub-directories but hard-code it to make it
+	  more sensible.
+
+2015-08-15 [r1784]  Andrew M. Bishop <amb>
+
+	* Makefile.conf, doc/INSTALL-MS-WIN.txt, doc/LIBRARY.txt (added),
+	  doc/html/index.html, doc/html/installation-ms-windows.html,
+	  doc/html/library.html (added), extras/find-fixme/Makefile,
+	  extras/find-fixme/fixme-dumper.c,
+	  extras/find-fixme/fixme-finder.c, extras/find-fixme/osmparser.c,
+	  extras/tagmodifier/Makefile, extras/tagmodifier/tagmodifier.c,
+	  src, src/Makefile, src/errorlogx.c, src/fakes.c, src/fakes.h,
+	  src/filedumper.c, src/filedumperx.c, src/files.c, src/files.h,
+	  src/functions.h, src/logerror.c, src/nodes.c, src/nodesx.c,
+	  src/optimiser.c, src/osmo5mparse.c, src/osmparser.c,
+	  src/osmpbfparse.c, src/osmxmlparse.c, src/output.c,
+	  src/planetsplitter.c, src/profiles.c, src/profiles.h,
+	  src/relations.c, src/relationsx.c, src/relationsx.h,
+	  src/results.c, src/router+lib.c (added), src/router.c,
+	  src/routino.c (added), src/routino.h (added), src/segments.c,
+	  src/segmentsx.c, src/superx.c, src/tagging.c, src/test,
+	  src/test/Makefile, src/test/a-b-c-d.sh, src/test/a-b-c.sh,
+	  src/test/a-b.sh, src/test/cycle-drive.sh, src/test/only-split.sh,
+	  src/test/run-tests.sh (added), src/test/start-1-finish.sh,
+	  src/translations.c, src/translations.h, src/types.c,
+	  src/visualiser.c, src/ways.c, src/waysx.c, src/xml/Makefile,
+	  src/xml/xsd-to-xmlparser.c, src/xmlparse.c, src/xmlparse.h,
+	  web/Makefile, web/www/routino/documentation: Merge libroutino
+	  branch back into the trunk.
+
+2015-08-15 [r1783]  Andrew M. Bishop <amb> (from 'branches/libroutino')
+
+	* Makefile.conf, extras/find-fixme/Makefile,
+	  extras/tagmodifier/Makefile, src/Makefile, src/test/Makefile,
+	  src/xml/Makefile, web/Makefile: Add '.exe' to the EXE targets to
+	  stop MinGW recompiling the executables each time.
+
+2015-08-14 [r1782]  Andrew M. Bishop <amb> (from 'branches/libroutino')
+
+	* Makefile.conf, doc/INSTALL-MS-WIN.txt,
+	  doc/html/installation-ms-windows.html,
+	  extras/find-fixme/Makefile, extras/tagmodifier/Makefile,
+	  src/Makefile, web/Makefile: Fully automatic host detection (for
+	  Cygwin, MinGW and generic UNIX).
+
+2015-08-14 [r1781]  Andrew M. Bishop <amb> (from 'branches/libroutino')
+
+	* Makefile.conf, src/Makefile: Using 'make install' now installs
+	  the libraries. On Windows installation uses 'Program
+	  Files/Routino' as the base directory.
+
+2015-08-14 [r1780]  Andrew M. Bishop <amb>
+
+	* web/translations/translation.de.txt,
+	  web/translations/translation.nl.txt,
+	  web/translations/translation.ru.txt,
+	  xml/routino-translations.xml: Remove duplicated words and
+	  whitespace in translations.
+
+2015-08-11 [r1779]  Andrew M. Bishop <amb> (from 'branches/libroutino')
+
+	* Makefile.conf: Don't include '-fPIC' for MinGW compilation (stops
+	  some warnings).
+
+2015-08-11 [r1776-1778]  Andrew M. Bishop <amb> (from 'branches/libroutino')
+
+	* doc/INSTALL-MS-WIN.txt, doc/html/installation-ms-windows.html:
+	  Updated documentation for compiling with MinGW64 and compiling
+	  library files.
+
+	* src/Makefile: An attempt at creating routino.def and routino.lib
+	  using dlltool instead of gendef.
+
+	* src/files.c, src/files.h: Undefine some #defines that MinGW64
+	  uses to remove lots of compiler warnings.
+
+2015-08-10 [r1773-1775]  Andrew M. Bishop <amb> (from 'branches/libroutino')
+
+	* src/Makefile: Create routino.dll and routino.def when compiling
+	  with MinGW (based on suggestion from Oliver Eichler).
+
+	* src/router+lib.c: Use 'use_stdout' instead of 'stdout' as a
+	  variable name (patch from Oliver Eichler).
+
+	* src/routino.h: Use DLL_PUBLIC for the extern definitions of the
+	  global variables (patch from Oliver Eichler).
+
+2015-08-08 [r1772]  Andrew M. Bishop <amb> (from 'branches/libroutino')
+
+	* src/translations.c: Put the missing space back in the HTML
+	  string.
+
+2015-08-08 [r1771]  Andrew M. Bishop <amb> (from 'branches/libroutino')
+
+	* doc/LIBRARY.txt, doc/html/library.html, src/output.c,
+	  src/router+lib.c, src/routino.c, src/routino.h,
+	  src/translations.c, src/translations.h: Simplify the HTML
+	  generation by making more complex format strings when parsing the
+	  translations. Add another field to the API HTML format output
+	  (cumulative distance). Increase API version to 5.
+
+2015-08-08 [r1770]  Andrew M. Bishop <amb> (from 'branches/libroutino')
+
+	* doc/LIBRARY.txt, doc/html/library.html: Add some missing API
+	  changes.
+
+2015-08-08 [r1769]  Andrew M. Bishop <amb>
+
+	* doc/OUTPUT.txt: Fix some text formatting problems.
+
+2015-08-08 [r1768]  Andrew M. Bishop <amb> (from 'branches/libroutino')
+
+	* doc/LIBRARY.txt, doc/html/library.html, src/output.c,
+	  src/router+lib.c, src/routino.c, src/routino.h,
+	  src/translations.c, src/translations.h: Add a new output list
+	  format that contains a text version of the normal HTML output.
+	  Increase API version to 4.
+
+2015-08-04 [r1767]  Andrew M. Bishop <amb> (from 'branches/libroutino')
+
+	* doc/LIBRARY.txt, doc/html/library.html, src/optimiser.c,
+	  src/router+lib.c, src/routino.c, src/routino.h: Add a progress
+	  callback that reports routing progress and can abort the routing
+	  algorithm if required. Increase API version to 3.
+
+2015-08-04 [r1766]  Andrew M. Bishop <amb> (from 'branches/libroutino')
+
+	* doc/LIBRARY.txt, doc/html/library.html, src/output.c,
+	  src/routino.c, src/routino.h: Add speed for each route segment
+	  (text-all version) and rename the 'string' parameter to 'name'.
+	  Increase API version to 2.
+
+2015-08-03 [r1765]  Andrew M. Bishop <amb> (from 'branches/libroutino')
+
+	* doc/LIBRARY.txt, doc/html/library.html, src/router+lib.c,
+	  src/routino.c, src/routino.h: Add a library API version number
+	  #define and variable and a function to compare the two.
+
+2015-08-03 [r1764]  Andrew M. Bishop <amb> (from 'branches/libroutino')
+
+	* web/www/routino/documentation: Ignore the library documentation
+	  when copied to the web directory.
+
+2015-08-03 [r1763]  Andrew M. Bishop <amb>
+
+	* web/www/routino/router.leaflet.js,
+	  web/www/routino/router.openlayers.js: Format the web links to
+	  only use 5 decimal places.
+
+2015-08-02 [r1761-1762]  Andrew M. Bishop <amb> (from 'branches/libroutino')
+
+	* src/output.c: Another fix for a mistake in output generation.
+
+	* src/output.c: Patch from Oliver Eichler for some mistakes in
+	  output generation.
+
+2015-07-31 [r1760]  Andrew M. Bishop <amb> (from 'branches/libroutino')
+
+	* doc/LIBRARY.txt (added), doc/html/index.html,
+	  doc/html/library.html (added), src/routino.c, src/routino.h:
+	  Documentation for the libroutino library.
+
+2015-07-31 [r1759]  Andrew M. Bishop <amb>
+
+	* web/translations/translation.pl.txt: More Polish translations
+	  (via http://www.routino.org/translations/).
+
+2015-07-30 [r1758]  Andrew M. Bishop <amb> (from 'branches/libroutino')
+
+	* src/functions.h, src/output.c, src/router+lib.c, src/router.c,
+	  src/routino.c, src/routino.h: Add the ability to request a linked
+	  list output representing the route when using the routino
+	  library.
+
+2015-07-21 [r1757]  Andrew M. Bishop <amb> (from 'branches/libroutino')
+
+	* src/routino.c, src/routino.h: Add a user profile type and
+	  functions to convert it to and from the Routino profile.
+
+2015-07-20 [r1756]  Andrew M. Bishop <amb> (from 'branches/libroutino')
+
+	* src/router+lib.c, src/router.c, src/routino.c, src/routino.h: Add
+	  options to the routing function to allow selection of the type of
+	  output files generated.
+
+2015-07-20 [r1755]  Andrew M. Bishop <amb> (from 'branches/libroutino')
+
+	* src/profiles.c, src/profiles.h, src/router+lib.c, src/routino.c,
+	  src/routino.h, src/translations.c, src/translations.h: Add
+	  functions to the library to return the list of loaded translation
+	  languages and profile names.
+
+2015-07-20 [r1754]  Andrew M. Bishop <amb> (from 'branches/libroutino')
+
+	* Makefile.conf, src/Makefile: Compile the version of the router
+	  using libroutino to search for the shared library in the same
+	  directory.
+
+2015-07-20 [r1753]  Andrew M. Bishop <amb> (from 'branches/libroutino')
+
+	* src/routino.c, src/routino.h: Check for validated profiles before
+	  using them.
+
+2015-07-18 [r1752]  Andrew M. Bishop <amb> (from 'branches/libroutino')
+
+	* src/test/Makefile, src/test/run-tests.sh (added): Put the test
+	  script execution into a script.
+
+2015-07-18 [r1751]  Andrew M. Bishop <amb> (from 'branches/libroutino')
+
+	* src/test, src/test/Makefile, src/test/a-b-c-d.sh,
+	  src/test/a-b-c.sh, src/test/a-b.sh, src/test/cycle-drive.sh,
+	  src/test/only-split.sh, src/test/start-1-finish.sh: Add tests of
+	  the router built with libroutino.
+
+2015-07-16 [r1750]  Andrew M. Bishop <amb> (from 'branches/libroutino')
+
+	* src/router+lib.c: Fix bug in last check-in.
+
+2015-07-16 [r1749]  Andrew M. Bishop <amb> (from 'branches/libroutino')
+
+	* src/router+lib.c, src/router.c, src/routino.c,
+	  src/translations.c: Allow choosing a named translation, the first
+	  in the file or the built-in English one. Make the routers use the
+	  first in the file if no language is specified rather than the
+	  built-in one.
+
+2015-07-16 [r1748]  Andrew M. Bishop <amb> (from 'branches/libroutino')
+
+	* src/profiles.c, src/profiles.h, src/router+lib.c, src/router.c,
+	  src/routino.c, src/routino.h: Validate profile parameters better
+	  when reading XML or router command line. Change the Profile data
+	  structure so that UpdateProfile() does not change the parts that
+	  are loaded from file so that it can be used multiple times on the
+	  same profile. Change the highway and props data to be between 0
+	  and 1 rather than a percentage. Add a new function to the library
+	  to validate a profile and also update it.
+
+2015-07-15 [r1746-1747]  Andrew M. Bishop <amb> (from 'branches/libroutino')
+
+	* src/profiles.c, src/routino.c, src/routino.h, src/translations.c:
+	  Add a Routino_errno variable that indicates the error status of
+	  the most recent library function called.
+
+	* src/Makefile: Fix bug with Makefile dependencies for
+	  libroutino.so and libroutino-slim.so.
+
+2015-07-14 [r1745]  Andrew M. Bishop <amb>
+
+	* src/files.c, src/files.h: Merge changes from MS-Windows branch
+	  (changes for stati64/fstati64/lseeki64).
+
+2015-07-14 [r1743]  Andrew M. Bishop <amb> (from 'branches/MS-Windows')
+
+	* src/files.c, src/files.h: Fix changes for
+	  stati64/fstati64/lseeki64.
+
+2015-07-11 [r1741]  Andrew M. Bishop <amb>
+
+	* src/cache.h, src/errorlog.h, src/errorlogx.c, src/files.c,
+	  src/files.h, src/logerror.c, src/nodes.c, src/nodes.h,
+	  src/nodesx.c, src/relations.h, src/relationsx.c,
+	  src/relationsx.h, src/ways.h, src/waysx.c, src/waysx.h: Merge
+	  change from MS-Windows branch (offset_t).
+
+2015-07-11 [r1740]  Andrew M. Bishop <amb> (from 'branches/MS-Windows')
+
+	* src/cache.h, src/errorlog.h, src/errorlogx.c, src/files.c,
+	  src/files.h, src/logerror.c, src/nodes.c, src/nodes.h,
+	  src/nodesx.c, src/relations.h, src/relationsx.c,
+	  src/relationsx.h, src/ways.h, src/waysx.c, src/waysx.h: Define a
+	  custom type for the offset within a file (because MS Windows can
+	  create a 4GB file but only seek +/-2GB within it).
+
+2015-07-10 [r1739]  Andrew M. Bishop <amb>
+
+	* src/nodes.h, src/nodesx.h, src/relations.h, src/segments.h,
+	  src/segmentsx.h, src/ways.h, src/waysx.h: Clarify the comments
+	  surrounding the definition of the slim mode cache data
+	  structures.
+
+2015-07-09 [r1738]  Andrew M. Bishop <amb> (from 'branches/libroutino')
+
+	* src, src/Makefile, src/router+lib.c (added), src/routino.c,
+	  src/routino.h: Update the library and include a version of the
+	  router program that uses the libroutino shared library for
+	  calculating routes. Currently generates output files of all types
+	  and accepts but ignores all options to change this.
+
+2015-07-08 [r1737]  Andrew M. Bishop <amb> (from 'branches/libroutino')
+
+	* src/translations.c: Bug fix when freeing the loaded translations.
+
+2015-07-08 [r1736]  Andrew M. Bishop <amb> (from 'branches/libroutino')
+
+	* src/translations.c: Bug fix for change introduced into xmlparse.c
+	  by r1701.
+
+2015-07-08 [1735]  Andrew M. Bishop <amb>
+
+	* src/files.c: Merge change from MS-Windows branch.
+
+2015-07-08 [r1734]  Andrew M. Bishop <amb>
+
+	* src/xmlparse.c: Remove a commented out line left over from a
+	  previous change.
+
+2015-07-08 [r1733]  Andrew M. Bishop <amb> (from 'branches/MS-Windows')
+
+	* src/files.c: Use the same definition of ssize_t in files.c as
+	  other files (for MS Windows).
+
+2015-07-07 [r1732]  Andrew M. Bishop <amb>
+
+	* web/translations/translation.pl.txt: More Polish translations
+	  (via http://www.routino.org/translations/).
+
+2015-07-06 [r1731]  Andrew M. Bishop <amb>
+
+	* web/translations/translation.pl.txt (added), web/www/routino,
+	  web/www/routino/.htaccess, xml/routino-translations.xml: Added
+	  Polish version of translations (submitted through
+	  http://www.routino.org/translations/).
+
+2015-07-04 [r1730]  Andrew M. Bishop <amb> (from 'branches/libroutino')
+
+	* src/functions.h, src/optimiser.c, src/router.c: Move the
+	  CalculateRoute function from router.c into optimiser.c.
+
+2015-07-02 [r1729]  Andrew M. Bishop <amb> (from 'branches/libroutino')
+
+	* src/functions.h, src/output.c, src/profiles.c, src/profiles.h,
+	  src/router.c, src/translations.c, src/translations.h: Identify
+	  the best bits from the profiles XML reader and translations XML
+	  reader functions and implement them in both.
+
+2015-07-02 [r1728]  Andrew M. Bishop <amb>
+
+	* src/profiles.c: Fix error with --help-profile-xml option.
+
+2015-07-01 [r1726]  Andrew M. Bishop <amb>
+
+	* src/files.c, src/files.h, src/osmo5mparse.c, src/osmpbfparse.c,
+	  src/xmlparse.c: Merge changes from MS-Windows branch.
+
+2015-07-01 [r1724-1725]  Andrew M. Bishop <amb> (from 'branches/MS-Windows')
+
+	* src/files.c: More fixes for MSVC, set permission for creating
+	  files and combine code with MinGW.
+
+	* src/files.h, src/osmo5mparse.c, src/osmpbfparse.c,
+	  src/xmlparse.c: More fixes for MSVC from Oliver Eichler (include
+	  basestd.h and define ssize_t).
+
+2015-06-22 [r1723]  Andrew M. Bishop <amb> (from 'branches/libroutino')
+
+	* src/optimiser.c: Bug fix for latest change (logassert and
+	  LIBROUTINO).
+
+2015-06-22 [r1722]  Andrew M. Bishop <amb> (from 'branches/libroutino')
+
+	* src/files.c, src/nodes.c, src/optimiser.c, src/relations.c,
+	  src/results.c, src/segments.c, src/ways.c: Remove all references
+	  to log_memory(), log_free(), log_mmap(), log_munmap() and
+	  logassert() from code compiled into the library.
+
+2015-06-20 [r1720]  Andrew M. Bishop <amb> (from 'branches/libroutino')
+
+	* src/routino.h: Avoid defining DLL_PUBLIC twice on Cygwin.
+
+2015-06-20 [r1719]  Andrew M. Bishop <amb>
+
+	* extras/tagmodifier/tagmodifier.c, src/osmxmlparse.c,
+	  src/profiles.c, src/tagging.c, src/translations.c,
+	  src/xml/xsd-to-xmlparser.c, src/xmlparse.c, src/xmlparse.h: Make
+	  the xmltags definitions of XML files be constants.
+
+2015-06-20 [r1717-1718]  Andrew M. Bishop <amb> (from 'branches/libroutino')
+
+	* src/xmlparse.c, src/xmlparse.h: Don't print an error when XML
+	  parsing fails but store a string for later use (for use within
+	  library version).
+
+	* src/optimiser.c: Check for defined(LIBROUTINO) instead of
+	  LIBROUTINO.
+
+2015-06-19 [r1716]  Andrew M. Bishop <amb> (from 'branches/libroutino')
+
+	* src/files.c, src/optimiser.c, src/output.c, src/profiles.c,
+	  src/translations.c: Do not print error or debug messages when
+	  compiled into library. Return an appropriate error value from
+	  functions instead of exiting.
+
+2015-06-18 [r1715]  Andrew M. Bishop <amb> (from 'branches/libroutino')
+
+	* Makefile.conf, src/Makefile, src/routino.c (added), src/routino.h
+	  (added): Add stub files for Routino library exported functions
+	  and Makefile support.
+
+2015-06-17 [r1713]  Andrew M. Bishop <amb>
+
+	* extras/tagmodifier/README.txt, extras/tagmodifier/tagmodifier.c:
+	  Add the '--logmemory' option that the other programs have.
+
+2015-06-17 [r1712]  Andrew M. Bishop <amb> (from 'branches/libroutino')
+
+	* extras/find-fixme/fixme-finder.c: Fix error with command line
+	  tagging filename selection. Change code to make it clearer that
+	  the error log file is not optional.
+
+2015-06-16 [r1711]  Andrew M. Bishop <amb> (from 'branches/libroutino')
+
+	* extras/find-fixme/osmparser.c, extras/tagmodifier/tagmodifier.c,
+	  src/errorlogx.c, src/fakes.c, src/fakes.h, src/logerror.c,
+	  src/nodesx.c, src/osmo5mparse.c, src/osmparser.c,
+	  src/osmpbfparse.c, src/osmxmlparse.c, src/profiles.c,
+	  src/relationsx.c, src/segmentsx.c, src/tagging.c,
+	  src/translations.c, src/visualiser.c, src/waysx.c,
+	  src/xmlparse.c: Audit the use of file static variables to make
+	  sure that there are no implicit assumptions about initialisation
+	  conditions that would be wrong for library usage. Fix problems
+	  and add comments for clarity.
+
+2015-06-14 [r1710]  Andrew M. Bishop <amb> (from 'branches/libroutino')
+
+	* extras/find-fixme/fixme-dumper.c,
+	  extras/tagmodifier/tagmodifier.c, src/filedumper.c, src/nodesx.c,
+	  src/osmxmlparse.c, src/planetsplitter.c, src/relationsx.c,
+	  src/relationsx.h, src/segmentsx.c, src/superx.c, src/tagging.c,
+	  src/translations.c, src/types.c, src/waysx.c,
+	  src/xml/xsd-to-xmlparser.c, src/xmlparse.c: Audit the use of
+	  function static variables to make sure that there are no implicit
+	  assumptions about initialisation conditions that would be wrong
+	  for library usage. Fix problems and add comments for clarity.
+
+2015-06-12 [r1709]  Andrew M. Bishop <amb> (from 'branches/libroutino')
+
+	* src/filedumperx.c: Correct an error in a comment.
+
+2015-06-12 [r1708]  Andrew M. Bishop <amb> (from 'branches/libroutino')
+
+	* extras/find-fixme/fixme-finder.c, src/planetsplitter.c,
+	  src/router.c: Minimise the number of times that FileName() is
+	  called since each one will allocate memory and take time.
+
+2015-06-12 [r1706-1707]  Andrew M. Bishop <amb> (from 'branches/libroutino')
+
+	* src/profiles.c, src/profiles.h, src/router.c: Add a function to
+	  free the memory in the Profile structures loaded from file.
+
+	* src/output.c, src/router.c, src/translations.c,
+	  src/translations.h: Create a Translation structure to hold the
+	  translated strings and have one global variable instead of 30.
+	  Add a function to free the memory in the Translation structure.
+
+2015-06-10 [r1705]  Andrew M. Bishop <amb>
+
+	* doc/html/index.html, web/www/routino/documentation: Merge the
+	  MS-Windows branch back into the trunk. More documentation
+	  changes.
+
+2015-06-10 [r1704]  Andrew M. Bishop <amb> (from 'branches/MS-Windows')
+
+	* doc/html/index.html: Update the index to point to the new MS
+	  Windows installation documentation.
+
+2015-06-10 [r1703]  Andrew M. Bishop <amb> (from 'branches/MS-Windows')
+
+	* web/www/routino/documentation: Ignore the new MS Windows
+	  installation documentation file.
+
+2015-06-10 [r1701-1702]  Andrew M. Bishop <amb> (from 'branches/libroutino')
+
+	* src/router.c: The translations are required to be loaded for the
+	  text output formats.
+
+	* src/output.c, src/xmlparse.c: The ParseXML_Encode_Safe_XML()
+	  function now returns a pointer to the same re-allocated string
+	  each time rather than allocating a new string each time that it
+	  is called.
+
+2015-06-09 [r1699]  Andrew M. Bishop <amb>
+
+	* Makefile.conf, doc/INSTALL-MS-WIN.txt (added), doc/INSTALL.txt,
+	  doc/html/installation-ms-windows.html (added),
+	  doc/html/installation.html, extras/find-fixme/Makefile,
+	  extras/tagmodifier/Makefile, src/Makefile, src/errorlogx.c,
+	  src/files.c, src/files.h, src/logerror.c, src/nodesx.c,
+	  src/output.c, src/relationsx.c, src/segmentsx.c,
+	  src/test/Makefile, src/uncompress.c, src/waysx.c,
+	  src/xml/Makefile, src/xmlparse.c, web/Makefile: Merge the
+	  MS-Windows branch back into the trunk. Code changes and
+	  documentation for Cygwin and MinGW compilers.
+
+2015-05-31 [r1697]  Andrew M. Bishop <amb> (from 'branches/MS-Windows')
+
+	* src/errorlogx.c, src/files.c, src/files.h, src/nodesx.c,
+	  src/relationsx.c, src/segmentsx.c, src/waysx.c: Microsoft Windows
+	  does not allow deleting an open file and continuing to use it
+	  like UNIX does. For MS Windows rename the file instead of
+	  deleting and replacing it and do not delete open files
+	  immediately but wait until they are closed.
+
+2015-05-30 [r1696]  Andrew M. Bishop <amb> (from 'branches/MS-Windows')
+
+	* src/files.c, src/logerror.c, src/output.c: Open files in binary
+	  mode for MSVC and MinGW.
+
+2015-05-29 [r1695]  Andrew M. Bishop <amb>
+
+	* src/nodesx.c, src/relationsx.c, src/segmentsx.c, src/waysx.c:
+	  Ensure that allocated strings are long enough even if the %p
+	  format is extravagant in the number of characters it uses.
+
+2015-05-29 [r1694]  Andrew M. Bishop <amb>
+
+	* web/Makefile: Change the order so that the translations are
+	  created before the icons (because the icons are more difficult to
+	  make and more likely to fail).
+
+2015-05-29 [r1693]  Andrew M. Bishop <amb>
+
+	* Makefile.conf: Remove the -Wfloat-conversion gcc option since it
+	  was only included in gcc version 4.9 so is not available
+	  everywhere.
+
+2015-05-29 [r1692]  Andrew M. Bishop <amb> (from 'branches/MS-Windows')
+
+	* doc/INSTALL-MS-WIN.txt, doc/html/installation-ms-windows.html:
+	  Add instructions for compiling with Cygwin (no source code
+	  changes needed).
+
+2015-05-28 [r1690]  Andrew M. Bishop <amb>
+
+	* extras/find-fixme/Makefile, extras/tagmodifier/Makefile,
+	  src/Makefile, src/test/Makefile, src/xml/Makefile, web/Makefile,
+	  web/www/routino, web/www/routino/router.html (removed),
+	  web/www/routino/visualiser.html (removed), xml/Makefile: Update
+	  Makefiles so that 'make clean' goes back to the source code in
+	  the release tar files and 'make distclean' goes back to the
+	  source code in subversion (the difference mainly being web page
+	  icons and web page translations).
+
+2015-05-28 [r1687-1689]  Andrew M. Bishop <amb> (from 'branches/MS-Windows')
+
+	* doc/INSTALL-MS-WIN.txt (added), doc/INSTALL.txt,
+	  doc/html/installation-ms-windows.html (added),
+	  doc/html/installation.html: Update documentation to describe
+	  compilation on Microsoft Windows.
+
+	* src/uncompress.c: Do not try to compile the built-in file
+	  decompression on MINGW or MSVC due to the lack of fork()
+	  function.
+
+	* Makefile.conf, extras/find-fixme/Makefile,
+	  extras/tagmodifier/Makefile, src/Makefile, src/xml/Makefile,
+	  web/Makefile: Update Makefiles for compiling with MINGW to
+	  include mman-win32.o and handle executables with .exe file
+	  extension.
+
+2015-05-26 [r1683-1686]  Andrew M. Bishop <amb> (from 'branches/MS-Windows')
+
+	* src/xmlparse.c: When compiling with MINGW there is no
+	  strcasecmp() function so _stricmp() must be used (the same as
+	  with MSVC).
+
+	* src/files.c: When compiling with MINGW the same mman-win32
+	  functions are required as with MSVC. The open() function can not
+	  set the 'group' and 'other' permissions although it can set the
+	  'user' permissions.
+
+	* src/files.h: When compiling with MINGW the pread() and pwrite()
+	  functions are not available. Fix a signed/unsigned assignment
+	  warning in the inline functions.
+
+	* src/uncompress.c: Only compile the pipe_and_fork() function if
+	  any of the compression methods are enabled.
+
+2015-05-26 [r1680]  Andrew M. Bishop <amb>
+
+	* Makefile.conf, extras/find-fixme/fixme-dumper.c,
+	  extras/find-fixme/fixme-finder.c,
+	  extras/tagmodifier/tagmodifier.c, src/Makefile, src/cache.h,
+	  src/fakes.c, src/filedumper.c, src/files.c, src/files.h,
+	  src/logging.c, src/logging.h, src/mman-win32.c (added),
+	  src/mman-win32.h (added), src/nodes.c, src/optimiser.c,
+	  src/osmo5mparse.c, src/osmpbfparse.c, src/output.c,
+	  src/planetsplitter.c, src/profiles.c, src/router.c,
+	  src/segments.h, src/uncompress.c, src/ways.c, src/ways.h,
+	  src/xml/xsd-to-xmlparser.c, src/xmlparse.c: Merge branch 'MSVC'
+	  back into the trunk.
+
+2015-05-26 [r1679]  Andrew M. Bishop <amb>
+
+	* web/www/leaflet/install.sh: Update to Leaflet version 0.7.3.
+
+2015-05-21 [r1678]  Andrew M. Bishop <amb>
+
+	* src/sorting.c: Fix bug with 64-bit version failing 'make test'.
+
+2015-05-20 [r1677]  Andrew M. Bishop <amb>
+
+	* src/output.c: Change a static variable to a const to clarify it
+	  usage.
+
+2015-05-20 [r1676]  Andrew M. Bishop <amb> (from 'branches/MSVC')
+
+	* Makefile.conf: Add the -Wfloat-conversion gcc option to catch any
+	  future score_t related conversions required.
+
+2015-05-20 [r1675]  Andrew M. Bishop <amb> (from 'branches/MSVC')
+
+	* src/optimiser.c, src/profiles.c, src/router.c: Typecasts for
+	  score_t and explicit float (not double) literals for MSVC
+	  compilation [based on patch from Oliver Eichler].
+
+2015-05-20 [r1674]  Andrew M. Bishop <amb> (from 'branches/MSVC')
+
+	* src/logging.c, src/xmlparse.c: Updated MSVC code changes after
+	  testing [patch from Oliver Eichler].
+
+2015-05-20 [r1673]  Andrew M. Bishop <amb> (from 'branches/MSVC')
+
+	* src/files.c, src/files.h, src/mman-win32.c (added),
+	  src/mman-win32.h (added): Added a Win32 implementation of the
+	  mmap/munmap functions [files from
+	  https://code.google.com/p/mman-win32 suggested by Oliver
+	  Eichler].
+
+2015-05-19 [r1666-1671]  Andrew M. Bishop <amb> (from 'branches/MSVC')
+
+	* src/ways.c: Fix uninitialised memory [found by Oliver Eichler
+	  when compiling with Microsoft C compiler].
+
+	* src/fakes.c, src/segments.h, src/ways.h: Add some explicit casts
+	  for some assignments resulting from pointer arithmetic [patch
+	  from Oliver Eichler for compiling with Microsoft C].
+
+	* src/files.c, src/nodes.c, src/xmlparse.c: Add some explicit casts
+	  for some assignments between different integer types [patch from
+	  Oliver Eichler for compiling with Microsoft C].
+
+	* src/Makefile, src/planetsplitter.c, src/router.c: Rename DATADIR
+	  to ROUTINO_DATADIR to avoid problems when compiling with
+	  Microsoft C compiler [inspired by patches from Oliver Eichler].
+
+	* src/files.c, src/files.h: Remove memory mapping functions when
+	  compiling with Microsoft C compiler [inspired by patches from
+	  Oliver Eichler]. This will only allow slim more to be compiled.
+
+	* src/xmlparse.c: Remove <strings.h> when compiling with Microsoft
+	  C compiler (in which use a macro to replace strcasecmp) [inspired
+	  by patches from Oliver Eichler].
+
+2015-05-19 [r1664-1665]  Andrew M. Bishop <amb> (from 'branches/MSVC')
+
+	* src/files.c, src/files.h: Remove <unistd.h> where not needed at
+	  all or when compiling with Microsoft C compiler (in which case
+	  add <io.h> and some macros to replace read/write/open/close/lseek
+	  etc.) [inspired by patches from Oliver Eichler].
+
+	* extras/find-fixme/fixme-finder.c,
+	  extras/tagmodifier/tagmodifier.c, src/cache.h, src/osmo5mparse.c,
+	  src/osmpbfparse.c, src/output.c, src/planetsplitter.c,
+	  src/uncompress.c, src/xml/xsd-to-xmlparser.c, src/xmlparse.c:
+	  Remove <unistd.h> where not needed at all or when compiling with
+	  Microsoft C compiler (in which case add <io.h> and some macros to
+	  replace read/write/open/close/lseek etc.) [inspired by patches
+	  from Oliver Eichler].
+
+2015-05-19 [r1663]  Andrew M. Bishop <amb> (from 'branches/MSVC')
+
+	* extras/find-fixme/fixme-dumper.c, src/filedumper.c,
+	  src/logging.c, src/logging.h: Remove <sys/time.h> where not
+	  needed at all or when compiling with Microsoft C compiler (in
+	  which case add a replacement gettimeofday function) [inspired by
+	  patches from Oliver Eichler].
+
+2015-05-18 [r1661]  Andrew M. Bishop <amb>
+
+	* src/optimiser.c: Fix use-after-free error found by valgrind.
+
+2015-05-16 [r1657]  Andrew M. Bishop <amb>
+
+	* web/www/routino/router.leaflet.js,
+	  web/www/routino/router.openlayers.js: Fix bug with moving markers
+	  on the map (OpenLayers version) and enable markers when they are
+	  dragged onto the map (both versions).
+
+2015-05-16 [r1656]  Andrew M. Bishop <amb>
+
+	* web/translations/router.html,
+	  web/translations/translation.de.txt,
+	  web/translations/translation.en.txt,
+	  web/translations/translation.fr.txt,
+	  web/translations/translation.nl.txt, web/www/routino/router.css,
+	  web/www/routino/router.leaflet.js,
+	  web/www/routino/router.openlayers.js: Allow dragging the waypoint
+	  icon up-and-down in the list and onto the map.
+
+2015-05-15 [r1655]  Andrew M. Bishop <amb>
+
+	* web/translations/translation.hu.txt: Add updated Hungarian
+	  translations submitted via http://www.routino.org/translations/
+	  on 2015-05-14.
+
+2015-05-14 [r1652-1653]  Andrew M. Bishop <amb>
+
+	* Makefile.conf: Add the -pedantic compilation flag to allow
+	  detection of more potential errors and portability issues.
+
+	* src/errorlog.h, src/files.c, src/nodes.h, src/relations.h,
+	  src/segments.h, src/sorting.c, src/ways.h: Replace all arithmetic
+	  involving 'void*' pointers with 'char*' since it isn't strictly
+	  valid although it is accepted by gcc.
+
+2015-05-13 [r1651]  Andrew M. Bishop <amb>
+
+	* src/xmlparse.c: Remove a gcc warning about overflow in implicit
+	  constant conversion (by making it an explicit type cast).
+
+2015-05-13 [r1650]  Andrew M. Bishop <amb>
+
+	* extras/find-fixme/fixme-dumper.c, src/filedumper.c,
+	  src/logging.c: Use "%zu" to print 'size_t' type values and use
+	  Pindex_t to print 'index_t' type values.
+
+2015-05-13 [r1649]  Andrew M. Bishop <amb>
+
+	* src/sorting.c: Remove some pthread related code that was being
+	  used even if compiled without pthreads.
+
+2015-05-05 [r1648]  Andrew M. Bishop <amb>
+
+	* web/translations/translation.de.txt: Add updated German
+	  translations submitted via http://www.routino.org/translations/
+	  on 2015-05-04.
+
+2015-05-01 [r1646]  Andrew M. Bishop <amb>
+
+	* doc/html/algorithm.html, doc/html/configuration.html,
+	  doc/html/data.html, doc/html/index.html,
+	  doc/html/installation.html, doc/html/limits.html,
+	  doc/html/output.html, doc/html/readme.html, doc/html/style.css,
+	  doc/html/tagging.html, doc/html/usage.html,
+	  extras/find-fixme/web/www/index.html, web/www/routino/index.html:
+	  Add "meta" header to HTML to help mobile devices and tidy up some
+	  CSS.
+
+2015-05-01 [r1644-1645]  Andrew M. Bishop <amb>
+
+	* doc/html/readme.html: Fixed some header links.
+
+	* doc/TAGGING.txt, doc/html/tagging.html: Fixed some text
+	  formatting.
+
+2015-04-26 [r1643]  Andrew M. Bishop <amb>
+
+	* web/translations/translation.hu.txt (added), web/www/routino,
+	  xml/routino-translations.xml: Added a Hungarian translation of
+	  the Routino routes and router web pages (from unknown person
+	  using http://routino.org/translations/).
+
+2015-04-11 [r1642]  Andrew M. Bishop <amb>
+
+	* web/Makefile: Run make in the xml directory after updating the
+	  xml/translations.xml file.
+
+2015-04-10 [r1641]  Andrew M. Bishop <amb>
+
+	* src/translations.c: Change built-in default HTML translation
+	  strings so that they work with the web page if they have to be
+	  used.
+
+2015-03-30 [r1638]  Andrew M. Bishop <amb>
+
+	* src/optimiser.c: Fix bug with indenting of debug output in
+	  FindMiddleRoute() function.
+
+2015-03-28 [r1636]  Andrew M. Bishop <amb>
+
+	* src/optimiser.c: More verbose, consistent, complete and
+	  descriptive debugging of routes found.
+
+2015-03-28 [r1634]  Andrew M. Bishop <amb>
+
+	* src/optimiser.c: The new FindStartRoutes() function does not need
+	  to be so complicated.
+
+2015-03-28 [r1632]  Andrew M. Bishop <amb>
+
+	* src/functions.h, src/optimiser.c, src/router.c: Remove the
+	  ExtendStartRoutes() function by merging its functionality with
+	  the FindStartRoutes() function since they were almost identical
+	  anyway.
+
+2015-03-21 [r1626-1627]  Andrew M. Bishop <amb>
+
+	* src/optimiser.c, src/router.c: Make sure that all complete routes
+	  have finish_node and last_segment filled in.
+
+	* src/optimiser.c: Bug fix and clarification for previous change.
+
+2015-03-21 [r1625]  Andrew M. Bishop <amb>
+
+	* src/functions.h, src/optimiser.c, src/router.c: Don't merge the
+	  end of the route with the middle part of the route before
+	  combining with the beginning of the route - combine beginning,
+	  middle and end all in one function.
+
+2015-02-02 [r1624]  Andrew M. Bishop <amb>
+
+	* web/translations/translation.de.txt,
+	  xml/routino-translations.xml: Add updated German translations
+	  submitted via http://www.routino.org/translations/ on 2014-01-31.
+
+2015-01-17 [r1623]  Andrew M. Bishop <amb>
+
+	* web/translations/translation.de.txt,
+	  xml/routino-translations.xml: Add updated German translations
+	  submitted via http://www.routino.org/translations/ on 2014-01-16.
+
+2015-01-13 [r1622]  Andrew M. Bishop <amb>
+
+	* web/translations/translation.de.txt: Add updated German
+	  translations submitted via http://www.routino.org/translations/
+	  on 2014-01-13.
+
+2015-01-09 [r1621]  Andrew M. Bishop <amb>
+
+	* web/translations/translation.nl.txt: Add updated Dutch
+	  translations submitted via http://www.routino.org/translations/
+	  on 2014-01-08.
+
+2015-01-07 [r1620]  Andrew M. Bishop <amb>
+
+	* xml/routino-tagging.xml: Remove cycle_barrier and bicycle_barrier
+	  since these don't always block bicycles.
+
+2014-12-04 [r1619]  Andrew M. Bishop <amb>
+
+	* src/typesx.h: Increase MAX_SEG_PER_NODE to avoid further
+	  problems.
+
+2014-11-29 [r1618]  Andrew M. Bishop <amb>
+
+	* src/visualiser.c: Include typesx.h to get the definition of
+	  MAX_SEG_PER_NODE rather than having another one.
+
 2014-11-08  Andrew M. Bishop <amb>
 
 	Version 2.7.3 released.
@@ -2135,46 +3089,46 @@
 	* xml/routino-tagging.xml: Stop two contradictory errors messages
 	  about 'access = foot' etc.
 
-2013-02-09  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2013-02-09  Andrew M. Bishop <amb>
 
 	Version 2.5 released
 
-2013-02-09 [r1255]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2013-02-09 [r1255]  Andrew M. Bishop <amb>
 
 	* doc/html/usage.html, doc/USAGE.txt: Fix HTML validation error.
 
-2013-02-09 [r1254]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2013-02-09 [r1254]  Andrew M. Bishop <amb>
 
 	* doc/html/readme.html, doc/NEWS.txt, doc/README.txt, FILES: Update
 	  documentation for version 2.5.
 
-2013-02-09 [r1253]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2013-02-09 [r1253]  Andrew M. Bishop <amb>
 
 	* doc/html/tagging.html, doc/TAGGING.txt: Update documentation for
 	  the new tagging transformations.
 
-2013-02-09 [r1252]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2013-02-09 [r1252]  Andrew M. Bishop <amb>
 
 	* xml/routino-tagging.xml: Add some more highway tagging
 	  transformations (motorroad, sidewalk, footway, cycleway), remove
 	  some rare bicycle specific ones and add some access tag values.
 
-2013-02-09 [r1251]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2013-02-09 [r1251]  Andrew M. Bishop <amb>
 
 	* src/osmo5mparse.c: Rename the local functions that perform the
 	  integer conversions (from pbf_* to o5m_*).
 
-2013-02-08 [r1250]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2013-02-08 [r1250]  Andrew M. Bishop <amb>
 
 	* web/www/routino/documentation, doc/html/limits.html (added),
 	  doc/html/index.html, doc/LIMITS.txt (added): Add documentation
 	  about the numerical limits (OSM identifiers and database size).
 
-2013-02-03 [r1249]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2013-02-03 [r1249]  Andrew M. Bishop <amb>
 
 	* src/prunex.c: Some trivial changes, same functionality.
 
-2013-01-24 [r1248]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2013-01-24 [r1248]  Andrew M. Bishop <amb>
 
 	* web/www/routino/visualiser.js, src/visualiser.h,
 	  src/filedumper.c, doc/USAGE.txt, web/www/routino/visualiser.cgi,
@@ -2182,7 +3136,7 @@
 	  doc/html/usage.html: Add the ability for the visualiser to
 	  display highways that have a particular property.
 
-2013-01-24 [r1247]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2013-01-24 [r1247]  Andrew M. Bishop <amb>
 
 	* doc/html/tagging.html, xml/routino-tagging.xml, doc/TAGGING.txt,
 	  src/osmparser.c: Change the "lanes=..." tag processing because it
@@ -2191,24 +3145,24 @@
 	  property is intended to allow prioritisation of roads where
 	  traffic can use multiple lanes in each direction.
 
-2013-01-21 [r1246]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2013-01-21 [r1246]  Andrew M. Bishop <amb>
 
 	* src/tagging.c, src/osmparser.c: Remove unnecessary word from
 	  logerror messages.
 
-2013-01-21 [r1245]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2013-01-21 [r1245]  Andrew M. Bishop <amb>
 
 	* xml/routino-translations.xml: Updated German translations from
 	  Alex Treiber.
 
-2013-01-20 [r1244]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2013-01-20 [r1244]  Andrew M. Bishop <amb>
 
 	* xml/routino-tagging.xml: Change the comments to clarify what the
 	  way access tag rules are for. Change slightly the logged message.
 	  Add new tagging rules to transform (for example) access=foot to
 	  foot=yes, access=no.
 
-2013-01-20 [r1243]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2013-01-20 [r1243]  Andrew M. Bishop <amb>
 
 	* xml/routino-tagging.xml, src/types.c, xml/routino-profiles.xml,
 	  doc/README.txt, doc/html/usage.html, src/types.h,
@@ -2221,7 +3175,7 @@
 	  web/www/routino/router.html.de: Replace 'motorbike' with
 	  'motorcycle' everywhere.
 
-2013-01-20 [r1242]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2013-01-20 [r1242]  Andrew M. Bishop <amb>
 
 	* doc/CONFIGURATION.txt, xml/routino-tagging.xsd,
 	  xml/routino-tagging.xml, src/tagging.h,
@@ -2230,17 +3184,17 @@
 	  specified and add a custom error message. Rework the access tag
 	  checking to use the new logcheck.
 
-2013-01-19 [r1241]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2013-01-19 [r1241]  Andrew M. Bishop <amb>
 
 	* xml/routino-tagging.xml: Ignore some more highway types ('no' and
 	  'disused').
 
-2013-01-19 [r1240]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2013-01-19 [r1240]  Andrew M. Bishop <amb>
 
 	* web/www/routino/visualiser.html.en: Fix link to documentation
 	  directory.
 
-2013-01-19 [r1239]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2013-01-19 [r1239]  Andrew M. Bishop <amb>
 
 	* web/www/routino/router.html.de,
 	  web/www/routino/visualiser.html.en,
@@ -2249,28 +3203,28 @@
 	  web/www/routino/router.html.en: Added MapQuest as an optional map
 	  layer, added layer specific attributions to mapprops.js.
 
-2013-01-15 [r1238]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2013-01-15 [r1238]  Andrew M. Bishop <amb>
 
 	* web/bin/summarise-log.pl: Fix stupid typo.
 
-2013-01-12 [r1237]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2013-01-12 [r1237]  Andrew M. Bishop <amb>
 
 	* web/bin/summarise-log.pl: Sort the listed nodes, ways or
 	  relations by ID.
 
-2013-01-09 [r1236]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2013-01-09 [r1236]  Andrew M. Bishop <amb>
 
 	* src/osmparser.c: Reset the to/via/from indexes before parsing
 	  each relation.
 
-2012-12-29 [r1235]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-12-29 [r1235]  Andrew M. Bishop <amb>
 
 	* src/xmlparse.h, src/osmpbfparse.c, src/osmo5mparse.c,
 	  src/osmxmlparse.c, src/xmlparse.c, src/filedumper.c: Replace the
 	  remaining 'long long' and 'unsigned long long' types with
 	  uint64_t.
 
-2012-12-29 [r1234]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-12-29 [r1234]  Andrew M. Bishop <amb>
 
 	* src/osmo5mparse.c, src/osmxmlparse.c, src/tagmodifier.c,
 	  src/osmparser.c, src/osmparser.h, src/tagging.c,
@@ -2284,66 +3238,66 @@
 	  relation counters be 'int64_t' instead of 'long long' in the XML
 	  parsers for consistency with the non-XML parsers.
 
-2012-12-28 [r1233]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-12-28 [r1233]  Andrew M. Bishop <amb>
 
 	* src/osmparser.c: Log errors for areas that are oneway.
 
-2012-12-28 [r1232]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-12-28 [r1232]  Andrew M. Bishop <amb>
 
 	* src/osmparser.c: Log errors for areas that are not closed.
 
-2012-12-27 [r1231]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-12-27 [r1231]  Andrew M. Bishop <amb>
 
 	* src/segmentsx.c, src/osmparser.c, web/bin/summarise-log.pl: Don't
 	  append segments if they are duplicates within a way or have
 	  duplicated nodes. Log errors for middle nodes that repeat within
 	  a way (can be non-trivial unintentional loops).
 
-2012-12-26 [r1230]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-12-26 [r1230]  Andrew M. Bishop <amb>
 
 	* src/osmpbfparse.c: Some small changes for similarity with the
 	  O5M/O5C parser.
 
-2012-12-26 [r1229]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-12-26 [r1229]  Andrew M. Bishop <amb>
 
 	* doc/ALGORITHM.txt, doc/html/algorithm.html: Remove the
 	  "practicalities" section because it is out of date and not very
 	  relevant.
 
-2012-12-26 [r1228]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-12-26 [r1228]  Andrew M. Bishop <amb>
 
 	* src/relationsx.c, src/segmentsx.c: Make the log error messages
 	  more useful when there are missing nodes or ways.
 
-2012-12-24 [r1227]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-12-24 [r1227]  Andrew M. Bishop <amb>
 
 	* src/osmparser.h, doc/html/usage.html, src/osmo5mparse.c (added),
 	  src/planetsplitter.c, src/osmparser.c, src/Makefile,
 	  doc/USAGE.txt: Added parsing of O5M/O5C format (a binary format
 	  but otherwise very close to OSM/OSC).
 
-2012-12-24 [r1226]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-12-24 [r1226]  Andrew M. Bishop <amb>
 
 	* src/planetsplitter.c, src/osmparser.c, src/osmparser.h,
 	  src/osmpbfparse.c: The PBF format does not support change files
 	  (the 'visible' part of the info message is only for historical
 	  data and not for changes).
 
-2012-12-24 [r1225]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-12-24 [r1225]  Andrew M. Bishop <amb>
 
 	* src/osmpbfparse.c: Fix memory allocation error.
 
-2012-12-22 [r1224]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-12-22 [r1224]  Andrew M. Bishop <amb>
 
 	* doc/html/usage.html, src/planetsplitter.c, src/tagmodifier.c,
 	  doc/USAGE.txt: Data can no longer be read from stdin for
 	  planetsplitter or tagmodifier.
 
-2012-12-21 [r1223]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-12-21 [r1223]  Andrew M. Bishop <amb>
 
 	* web/data/create.sh: Correct the URLs to use to download data.
 
-2012-12-21 [r1221]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-12-21 [r1221]  Andrew M. Bishop <amb>
 
 	* doc/html/usage.html, src/osmxmlparse.c, src/planetsplitter.c,
 	  src/osmparser.c, src/Makefile, doc/USAGE.txt, src/osmparser.h,
@@ -2351,7 +3305,7 @@
 	  Separate the XML parser from the data processing in osmparser.c.
 	  Update planetsplitter and documentation to use new format.
 
-2012-12-19 [r1219-1220]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-12-19 [r1219-1220]  Andrew M. Bishop <amb>
 
 	* src/xmlparse.c: Use 'unsigned char' instead of 'char' for buffer.
 	  Renumber the LEX states to remove hole.
@@ -2359,28 +3313,28 @@
 	* src/uncompress.c: Trivial change to not set a state variable
 	  where not needed.
 
-2012-12-19 [r1218]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-12-19 [r1218]  Andrew M. Bishop <amb>
 
 	* src/osmxmlparse.c (added): Copying osmparser.c to create
 	  osmxmlparse.c for the XML callback functions and shared
 	  variables.
 
-2012-12-17 [r1217]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-12-17 [r1217]  Andrew M. Bishop <amb>
 
 	* src/optimiser.c: Refactor to remove duplicated code in each
 	  branch of if statement (in each optimiser loop).
 
-2012-12-17 [r1216]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-12-17 [r1216]  Andrew M. Bishop <amb>
 
 	* doc/NEWS.txt, doc/README.txt, FILES, doc/html/readme.html:
 	  Reintegrate the changes from 2.4.1 branch back into trunk.
 
-2012-12-15 [r1209]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-12-15 [r1209]  Andrew M. Bishop <amb>
 
 	* xml/routino-tagging.xml: Fix some errors that appeared in the
 	  tagging file after adding nesting.
 
-2012-12-15 [r1206-1207]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-12-15 [r1206-1207]  Andrew M. Bishop <amb>
 
 	* xml/routino-tagging.xml: Change the tagging rules to use the
 	  nested <if> rules.
@@ -2390,14 +3344,14 @@
 	  tagging rules to have an <ifnot ...> rule which can also be
 	  nested.
 
-2012-12-15 [r1205]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-12-15 [r1205]  Andrew M. Bishop <amb>
 
 	* src/translations.c, xml/routino-translations.xsd: Change one
 	  entry in the translations XSD file that used a different case
 	  from the other defined types (not consistent with other XSD files
 	  but self-consistent).
 
-2012-12-15 [r1204]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-12-15 [r1204]  Andrew M. Bishop <amb>
 
 	* src/xml/xsd-to-xmlparser.c, src/osmparser.c, src/tagging.c,
 	  src/translations.c, src/profiles.c: Change the xsd-to-xmlparser
@@ -2405,13 +3359,13 @@
 	  file and do not attempt to sort them into reverse order of
 	  reference.
 
-2012-12-15 [r1203]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-12-15 [r1203]  Andrew M. Bishop <amb>
 
 	* doc/html/configuration.html, src/tagging.c,
 	  doc/CONFIGURATION.txt, xml/routino-tagging.xml: Change the
 	  tagging rules to use the nested <if> rules.
 
-2012-12-15 [r1200-1202]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-12-15 [r1200-1202]  Andrew M. Bishop <amb>
 
 	* src/planetsplitter.c: Change the order of the command line option
 	  parsing to match the program usage output.
@@ -2422,25 +3376,25 @@
 	* doc/html/usage.html, src/tagmodifier.c: Add the --logtime and
 	  --errorlog options to tagmodifier.
 
-2012-12-15 [r1199]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-12-15 [r1199]  Andrew M. Bishop <amb>
 
 	* xml/routino-tagging.xsd, src/tagging.h, src/tagmodifier.c,
 	  src/osmparser.c, src/tagging.c: Allow the tagging rule syntax to
 	  contain nested <if ...> statements.
 
-2012-12-14 [r1197]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-12-14 [r1197]  Andrew M. Bishop <amb>
 
 	* doc/USAGE.txt, doc/html/usage.html, src/planetsplitter.c,
 	  src/tagmodifier.c: Update the usage messages and documentation
 	  for bzip2/gzip uncompression.
 
-2012-12-14 [r1196]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-12-14 [r1196]  Andrew M. Bishop <amb>
 
 	* src/Makefile, src/uncompress.c, src/uncompress.h,
 	  src/planetsplitter.c, src/tagmodifier.c: Add the ability to read
 	  gzip compressed files when specified by name.
 
-2012-12-13 [r1194-1195]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-12-13 [r1194-1195]  Andrew M. Bishop <amb>
 
 	* src/xmlparse.c: Handle the output of the uncompressor where
 	  reading may return only a partial buffer. Makes it more robust
@@ -2450,27 +3404,27 @@
 	  src/planetsplitter.c, src/tagmodifier.c: Add the ability to read
 	  bzip2 compressed files when specified by name.
 
-2012-12-12 [r1192]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-12-12 [r1192]  Andrew M. Bishop <amb>
 
 	* src/xml/xsd-to-xmlparser.c, src/planetsplitter.c: Use
 	  STDIN_FILENO instead of 0 for the stdin file descriptor.
 
-2012-12-11 [r1190]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-12-11 [r1190]  Andrew M. Bishop <amb>
 
 	* src/xmlparse.c: Reorder if/then/else statements so that most
 	  common ones come first (using profiling when parsing GB OSM
 	  file).
 
-2012-12-11 [r1189]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-12-11 [r1189]  Andrew M. Bishop <amb>
 
 	* src/xmlparse.c: Most xml attribute values are ASCII so optimise
 	  for that case.
 
-2012-12-10 [r1188]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-12-10 [r1188]  Andrew M. Bishop <amb>
 
 	* src/Makefile: Re-enable the optimisation option.
 
-2012-12-10 [r1185-1187]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-12-10 [r1185-1187]  Andrew M. Bishop <amb>
 
 	* src: Change svn ignored files (don't ignore xmlparse.c now).
 
@@ -2486,53 +3440,53 @@
 	  tag attributes do not need memory allocated or copying from file
 	  buffer and there are no yylex() function calls/returns.
 
-2012-12-17  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-12-17  Andrew M. Bishop <amb>
 
 	Version 2.4.1 released
 
-2012-12-17 [r1214]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-12-17 [r1214]  Andrew M. Bishop <amb>
 
 	* doc/html/readme.html, doc/NEWS.txt, doc/README.txt, FILES: Update
 	  for version 2.4.1.
 
-2012-12-17 [r1213]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-12-17 [r1213]  Andrew M. Bishop <amb>
 
 	* src/optimiser.c, src/waysx.c, src/segmentsx.c, src/nodesx.c,
 	  src/router.c, src/prunex.c, src/logging.c, src/relationsx.c:
 	  Merge revisions 1191, 1193, 1198, 1208 and 1210 from trunk into
 	  2.4.1 branch.
 
-2012-12-17 [r1210]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-12-17 [r1210]  Andrew M. Bishop <amb>
 
 	* src/optimiser.c: Fix the incorrect finish_score variable that was
 	  set to infinite distance and not infinite score (infinte distance
 	  << infinite score so search was terminating early).
 
-2012-12-15 [r1208]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-12-15 [r1208]  Andrew M. Bishop <amb>
 
 	* src/nodesx.c, src/prunex.c, src/relationsx.c, src/waysx.c,
 	  src/segmentsx.c: Stop planetsplitter crashing out in unusual ways
 	  if there is no data.
 
-2012-12-14 [r1198]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-12-14 [r1198]  Andrew M. Bishop <amb>
 
 	* src/waysx.c, src/nodesx.c: Don't crash in binary search if no
 	  nodes/ways.
 
-2012-12-13 [r1193]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-12-13 [r1193]  Andrew M. Bishop <amb>
 
 	* src/logging.c: Fix bug with printing messages if not to stdout.
 
-2012-12-12 [r1191]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-12-12 [r1191]  Andrew M. Bishop <amb>
 
 	* src/router.c: Fix error when searching for default profiles.xml
 	  file.
 
-2012-12-08  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-12-08  Andrew M. Bishop <amb>
 
 	Version 2.4 released
 
-2012-12-08 [r1182-1183]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-12-08 [r1182-1183]  Andrew M. Bishop <amb>
 
 	* doc/NEWS.txt, doc/README.txt, FILES, doc/html/readme.html: Update
 	  for version 2.4.
@@ -2540,7 +3494,7 @@
 	* doc/TAGGING.txt: Update with the tagging rule changes in this
 	  version.
 
-2012-12-08 [r1181]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-12-08 [r1181]  Andrew M. Bishop <amb>
 
 	* src/xmlparse.l, src/xml/test/good.xml,
 	  src/xml/test/bad-cdata-start.xml (removed),
@@ -2549,22 +3503,22 @@
 	  raise an explicit error for text outside of tags. Modify test
 	  cases for these changes.
 
-2012-12-06 [r1180]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-12-06 [r1180]  Andrew M. Bishop <amb>
 
 	* src/xmlparse.l: Some further small changes to pull out bigger
 	  groups of characters (only marginally faster though).
 
-2012-12-05 [r1179]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-12-05 [r1179]  Andrew M. Bishop <amb>
 
 	* src/prunex.c: Minor theoretical improvements to pruning (slim
 	  mode is still very slow).
 
-2012-12-05 [r1178]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-12-05 [r1178]  Andrew M. Bishop <amb>
 
 	* src/xmlparse.l: Change rules to remove all states that require
 	  backing up (only marginally faster though).
 
-2012-12-05 [r1176-1177]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-12-05 [r1176-1177]  Andrew M. Bishop <amb>
 
 	* doc/html/tagging.html: Update with the tagging rule changes in
 	  this version.
@@ -2572,12 +3526,12 @@
 	* xml/routino-tagging.xml: Small change to the tag processing for
 	  nodes for easier future expansion.
 
-2012-12-01 [r1175]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-12-01 [r1175]  Andrew M. Bishop <amb>
 
 	* src/tagging.c: Fix memory leak from making incorrect assumption
 	  when freeing tagging rule.
 
-2012-12-01 [r1174]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-12-01 [r1174]  Andrew M. Bishop <amb>
 
 	* src/superx.c, src/translations.h, src/visualiser.c,
 	  src/profiles.h, src/types.h, src/osmparser.c, src/filedumper.c,
@@ -2587,19 +3541,19 @@
 	  return Highway_None instead of Highway_Count if no match found -
 	  all changes for consistency with similar types and functions.
 
-2012-11-27 [r1173]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-11-27 [r1173]  Andrew M. Bishop <amb>
 
 	* src/osmparser.c, web/bin/summarise-log.pl, src/segmentsx.c: Log
 	  an error about duplicated segments within a way while parsing the
 	  OSM instead of later (will have been removed by de-duplication
 	  code before tested later in most cases).
 
-2012-11-27 [r1172]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-11-27 [r1172]  Andrew M. Bishop <amb>
 
 	* web/bin/summarise-log.pl: Make the script still work when no
 	  command line argument is used.
 
-2012-11-27 [r1171]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-11-27 [r1171]  Andrew M. Bishop <amb>
 
 	* src/relationsx.c, src/planetsplitter.c, src/waysx.c,
 	  src/segmentsx.c, src/nodesx.c: Don't log an error for duplicated
@@ -2607,12 +3561,12 @@
 	  changes or if using multiple geographically overlapping files and
 	  neither is a data error.
 
-2012-11-21 [r1170]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-11-21 [r1170]  Andrew M. Bishop <amb>
 
 	* xml/routino-tagging.xml: Add some more tag checking, accept more
 	  tags.
 
-2012-11-21 [r1169]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-11-21 [r1169]  Andrew M. Bishop <amb>
 
 	* src/types.h, src/segmentsx.c: Finally fix the segment area
 	  handling - segments that are areas are discarded in preference to
@@ -2626,7 +3580,7 @@
 	  when no longer needed but didn't fix the rest. Revision r1168
 	  reverted r1164 so needed to be re-applied.
 
-2012-11-21 [r1168]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-11-21 [r1168]  Andrew M. Bishop <amb>
 
 	* src/prunex.c, src/segmentsx.h, src/filedumperx.c, src/segments.c,
 	  src/superx.c, src/fakes.c, src/types.h, src/segments.h,
@@ -2635,14 +3589,14 @@
 	  super-segments are longer than 65535 metres even if no individual
 	  segment is.
 
-2012-11-20 [r1167]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-11-20 [r1167]  Andrew M. Bishop <amb>
 
 	* doc/html/usage.html, src/relationsx.c, src/planetsplitter.c,
 	  src/waysx.c, src/relationsx.h, src/segmentsx.c, doc/USAGE.txt,
 	  src/nodesx.c, src/waysx.h, src/segmentsx.h, src/nodesx.h: Rename
 	  the '--preserve' command line option to '--keep' for simplicity.
 
-2012-11-20 [r1166]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-11-20 [r1166]  Andrew M. Bishop <amb>
 
 	* src/segmentsx.c, src/nodesx.c, src/prunex.c, src/results.c,
 	  src/sorting.c, src/logging.c, src/superx.c, src/files.h,
@@ -2651,13 +3605,13 @@
 	  Replace all assert statements with a custom error message that
 	  explains the cause and suggests a solution.
 
-2012-11-20 [r1165]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-11-20 [r1165]  Andrew M. Bishop <amb>
 
 	* src/types.h, src/osmparser.c, src/nodes.h, src/nodesx.c,
 	  src/nodesx.h: Use a specific type for the node flags instead of a
 	  generic uint16_t.
 
-2012-11-20 [r1164]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-11-20 [r1164]  Andrew M. Bishop <amb>
 
 	* src/filedumperx.c, src/segments.c, src/superx.c, src/fakes.c,
 	  src/types.h, src/segments.h, src/optimiser.c, src/osmparser.c,
@@ -2665,18 +3619,18 @@
 	  src/prunex.c, src/segmentsx.h: Replace the 32-bit combined
 	  distance and flags in the segment with 16 bits for each.
 
-2012-11-20 [r1163]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-11-20 [r1163]  Andrew M. Bishop <amb>
 
 	* src/relationsx.c, src/relationsx.h, src/typesx.h,
 	  src/filedumperx.c: Tidy up all of the recent code changes -
 	  Rename TurnRestrictRelX structure to TurnRelX.
 
-2012-11-20 [r1162]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-11-20 [r1162]  Andrew M. Bishop <amb>
 
 	* src/files.c: Tidy up all of the recent code changes - Fix
 	  comment.
 
-2012-11-20 [r1161]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-11-20 [r1161]  Andrew M. Bishop <amb>
 
 	* src/nodesx.c, src/waysx.h, src/segmentsx.h, doc/DATALIFE.txt,
 	  src/nodesx.h, src/superx.c, src/relationsx.c, src/osmparser.c,
@@ -2684,27 +3638,27 @@
 	  the recent code changes - change the name of a few of the
 	  functions.
 
-2012-11-20 [r1160]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-11-20 [r1160]  Andrew M. Bishop <amb>
 
 	* src/waysx.c, src/relationsx.h, src/segmentsx.c, src/nodesx.c,
 	  src/waysx.h, src/segmentsx.h, src/nodesx.h: Tidy up all of the
 	  recent code changes - change the order of the functions within
 	  the files to a more sensible and consitent order.
 
-2012-11-19 [r1159]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-11-19 [r1159]  Andrew M. Bishop <amb>
 
 	* src/osmparser.c: Unconditionally mark ways as deleted if they
 	  have been modified to handle the case when applying more than one
 	  change file if a way is created by the first of the change files
 	  and modified by the second it will not be in the index.
 
-2012-11-19 [r1158]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-11-19 [r1158]  Andrew M. Bishop <amb>
 
 	* src/waysx.c, src/waysx.h, src/planetsplitter.c: Do not create the
 	  way indexes when loading the parsed ways to apply changes
 	  (reverses r1145).
 
-2012-11-19 [r1157]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-11-19 [r1157]  Andrew M. Bishop <amb>
 
 	* doc/html/usage.html, src/planetsplitter.c, doc/USAGE.txt: Do not
 	  require that --preserve must be used with --parse-only before
@@ -2712,23 +3666,23 @@
 	  functionality but preserves the changes to the functions that
 	  enable it).
 
-2012-11-19 [r1156]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-11-19 [r1156]  Andrew M. Bishop <amb>
 
 	* src/filedumperx.c: Fix bug with dumping ways.
 
-2012-11-19 [r1155]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-11-19 [r1155]  Andrew M. Bishop <amb>
 
 	* src/segmentsx.c: De-duplicate segments when sorting only if they
 	  have the same nodes, way and distance - i.e. the same data
 	  imported twice.
 
-2012-11-18 [r1154]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-11-18 [r1154]  Andrew M. Bishop <amb>
 
 	* src/osmparser.c: When marking modified nodes as deleted don't
 	  accidentally re-include them as new ways with the deleted flag
 	  set.
 
-2012-11-18 [r1152-1153]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-11-18 [r1152-1153]  Andrew M. Bishop <amb>
 
 	* src/segmentsx.c: When sorting segments use the distance flags as
 	  the tie-breaker so that duplicated segments with different flags
@@ -2740,7 +3694,7 @@
 	  modification causes it to be invalid and not stored therefore
 	  leaving the old version.
 
-2012-11-18 [r1151]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-11-18 [r1151]  Andrew M. Bishop <amb>
 
 	* src/segmentsx.h, src/nodesx.h, src/superx.c, doc/html/usage.html,
 	  src/relationsx.c, src/planetsplitter.c, src/waysx.c,
@@ -2748,7 +3702,7 @@
 	  src/waysx.h: Using --parse-only and --preserve must sort the data
 	  so that it is ready to apply the changes.
 
-2012-11-17 [r1149-1150]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-11-17 [r1149-1150]  Andrew M. Bishop <amb>
 
 	* src/filedumper.c: Some small changes to match the new filedumperx
 	  program.
@@ -2758,7 +3712,7 @@
 	  dump the contents of the intermediate files that are generated by
 	  using --preserve or --changes.
 
-2012-11-17 [r1147-1148]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-11-17 [r1147-1148]  Andrew M. Bishop <amb>
 
 	* src/waysx.c: Replace a hard-coded constant with the #defined
 	  value it should have been.
@@ -2768,14 +3722,14 @@
 	  written to disk (avoid byte-level differences when applying
 	  changes).
 
-2012-11-17 [r1146]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-11-17 [r1146]  Andrew M. Bishop <amb>
 
 	* src/nodesx.c, src/relationsx.c, src/planetsplitter.c,
 	  src/waysx.c, src/segmentsx.c: Suppress some error log messages
 	  when applying changes (false positive duplicate detection due to
 	  modification of existing items).
 
-2012-11-17 [r1144-1145]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-11-17 [r1144-1145]  Andrew M. Bishop <amb>
 
 	* src/planetsplitter.c, src/osmparser.c, src/waysx.c, src/waysx.h:
 	  Fix applying changes for ways (highways that have been modified
@@ -2785,7 +3739,7 @@
 	* src/typesx.h, src/types.h: Change the type-casting of some
 	  constants.
 
-2012-11-16 [r1140-1143]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-11-16 [r1140-1143]  Andrew M. Bishop <amb>
 
 	* src/xml: Ignore the automatically generated executables from the
 	  new XML Schema.
@@ -2803,25 +3757,25 @@
 	  change files (.osc files) to an existing set of parsed (and
 	  preserved) data.
 
-2012-11-15 [r1139]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-11-15 [r1139]  Andrew M. Bishop <amb>
 
 	* src/nodesx.h, src/superx.c, src/relationsx.c,
 	  src/planetsplitter.c, src/waysx.c, src/relationsx.h,
 	  src/segmentsx.c, src/nodesx.c, src/waysx.h, src/segmentsx.h:
 	  Fixed the --preserve option.
 
-2012-11-12 [r1138]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-11-12 [r1138]  Andrew M. Bishop <amb>
 
 	* src/relationsx.c: Fix mis-use of NO_WAY/NO_WAY_ID and
 	  NO_RELATION/NO_RELATION_ID constants in route relation handling.
 
-2012-11-11 [r1137]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-11-11 [r1137]  Andrew M. Bishop <amb>
 
 	* src/types.h, src/osmparser.c, src/segmentsx.c: Mark those
 	  segments that come from ways which are areas with an explicit
 	  flag rather than an implicit one (also fixes a bug).
 
-2012-11-10 [r1136]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-11-10 [r1136]  Andrew M. Bishop <amb>
 
 	* src/nodesx.c, src/waysx.h, src/segmentsx.h, src/nodesx.h,
 	  doc/html/usage.html, src/relationsx.c, src/planetsplitter.c,
@@ -2829,34 +3783,34 @@
 	  Added a --preserve option which keeps the raw data files after
 	  parsing, sorting and de-duplication.
 
-2012-11-10 [r1134-1135]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-11-10 [r1134-1135]  Andrew M. Bishop <amb>
 
 	* doc/DATALIFE.txt, src/waysx.c: Don't index the ways in the first
 	  sorting, but wait until after de-duplicating.
 
 	* src/relationsx.c: Sort the route relations and remove duplicates.
 
-2012-11-10 [r1133]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-11-10 [r1133]  Andrew M. Bishop <amb>
 
 	* src/planetsplitter.c, src/segmentsx.c, src/segmentsx.h,
 	  doc/DATALIFE.txt: The MergeSuperSegments function creates the
 	  output file in the sorted order already, there is no need to
 	  re-sort it.
 
-2012-11-10 [r1132]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-11-10 [r1132]  Andrew M. Bishop <amb>
 
 	* src/segmentsx.c, src/segmentsx.h, doc/DATALIFE.txt,
 	  src/planetsplitter.c: De-duplicate the super-segments as a
 	  post-processing function after the sort so both operations are
 	  combined in a single function.
 
-2012-11-10 [r1131]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-11-10 [r1131]  Andrew M. Bishop <amb>
 
 	* src/segmentsx.h, src/planetsplitter.c, src/segmentsx.c:
 	  De-duplicate the raw segments before any other processing (to
 	  match the node, way and turn relation processing).
 
-2012-11-10 [r1129-1130]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-11-10 [r1129-1130]  Andrew M. Bishop <amb>
 
 	* src/planetsplitter.c: Separate the de-duplication of the ways
 	  from the extracting of the names. Use the modified functions for
@@ -2865,51 +3819,51 @@
 	* src/waysx.c, src/waysx.h, doc/DATALIFE.txt: Separate the
 	  de-duplication of the ways from the extracting of the names.
 
-2012-11-08 [r1128]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-11-08 [r1128]  Andrew M. Bishop <amb>
 
 	* web/bin/summarise-log.pl: Allow generation of an HTML version of
 	  the log file summary.
 
-2012-11-08 [r1127]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-11-08 [r1127]  Andrew M. Bishop <amb>
 
 	* src/osmparser.c: Add two extra parsing rules for feet and inches.
 
-2012-11-04 [r1126]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-11-04 [r1126]  Andrew M. Bishop <amb>
 
 	* src/tagging.c: Clarify that errors logged when examining tags
 	  mean that tag will be ignored.
 
-2012-11-04 [r1125]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-11-04 [r1125]  Andrew M. Bishop <amb>
 
 	* src/osmparser.c: Log an error for ways with only 1 node and for
 	  relations with no nodes, ways or relations.
 
-2012-11-03 [r1124]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-11-03 [r1124]  Andrew M. Bishop <amb>
 
 	* src/prunex.c: Append the new ways directly to the end of the
 	  existing ways rather than using a new file.
 
-2012-11-03 [r1123]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-11-03 [r1123]  Andrew M. Bishop <amb>
 
 	* src/nodesx.h, src/superx.c, src/relationsx.c, src/waysx.c,
 	  src/relationsx.h, src/segmentsx.c, src/nodesx.c, src/waysx.h,
 	  src/segmentsx.h: Don't open the input file for appending if there
 	  is no intention to write anything to it.
 
-2012-11-03 [r1122]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-11-03 [r1122]  Andrew M. Bishop <amb>
 
 	* src/superx.c, src/files.h, src/relationsx.c, src/segmentsx.c,
 	  src/prunex.c, src/files.c: Change the UnmapFile() function to
 	  take a pointer to the data instead of the filename (like the
 	  CloseFile() function takes the file descriptor).
 
-2012-11-02 [r1121]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-11-02 [r1121]  Andrew M. Bishop <amb>
 
 	* src/prunex.c, src/segmentsx.h: Fix a bug which gave different
 	  results for slim mode and normal mode when pruning short
 	  segments.
 
-2012-11-01 [r1120]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-11-01 [r1120]  Andrew M. Bishop <amb>
 
 	* src/planetsplitter.c, src/waysx.c, src/relationsx.h,
 	  src/segmentsx.c, doc/USAGE.txt, src/nodesx.c, src/waysx.h,
@@ -2921,11 +3875,11 @@
 	  which closes the file and renames it to a temporary filename
 	  which is used for the remaining processing.
 
-2012-11-01 [r1119]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-11-01 [r1119]  Andrew M. Bishop <amb>
 
 	* src/files.c, src/files.h: Add a function to rename a file.
 
-2012-10-31 [r1118]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-10-31 [r1118]  Andrew M. Bishop <amb>
 
 	* src/relationsx.c, src/sorting.h, src/waysx.c, src/segmentsx.c,
 	  src/nodesx.c: Add the option for the sorting function to preserve
@@ -2933,7 +3887,7 @@
 	  feature in sorting so that slim mode and normal mode give the
 	  same results.
 
-2012-10-24 [r1116-1117]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-10-24 [r1116-1117]  Andrew M. Bishop <amb>
 
 	* doc/html/usage.html, doc/html/algorithm.html,
 	  src/planetsplitter.c, doc/USAGE.txt, doc/ALGORITHM.txt,
@@ -2943,14 +3897,14 @@
 	* doc/DATALIFE.txt: Use the index provided by the pre-sort function
 	  rather than the way's internal id when pruning/compacting.
 
-2012-10-24 [r1114-1115]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-10-24 [r1114-1115]  Andrew M. Bishop <amb>
 
 	* src/segmentsx.c: Remove a debugging print statement.
 
 	* src/waysx.c: Use the index provided by the pre-sort function
 	  rather than the way's internal id when pruning/compacting.
 
-2012-10-22 [r1112-1113]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-10-22 [r1112-1113]  Andrew M. Bishop <amb>
 
 	* src/waysx.c: Use the new pre-sort function to allow CompactWays()
 	  to delete the unused segments before sorting them.
@@ -2959,7 +3913,7 @@
 	  index parameter in new pre-sort function and change comments to
 	  clarify.
 
-2012-10-22 [r1110-1111]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-10-22 [r1110-1111]  Andrew M. Bishop <amb>
 
 	* src/segmentsx.c: Use the new pre-sort function to allow
 	  RemovePrunedSegments() to delete the pruned segments before
@@ -2968,14 +3922,14 @@
 	* src/segmentsx.c, src/relationsx.c: Change the message after
 	  sorting geographically to be consistent with others.
 
-2012-10-21 [r1109]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-10-21 [r1109]  Andrew M. Bishop <amb>
 
 	* src/planetsplitter.c, src/nodesx.c, doc/DATALIFE.txt,
 	  src/nodesx.h: Move the UpdateNodes() work into the callback for
 	  SortNodeListGeographically() and use firstnode when saving the
 	  nodes.
 
-2012-10-21 [r1108]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-10-21 [r1108]  Andrew M. Bishop <amb>
 
 	* src/planetsplitter.c, src/relationsx.h, doc/DATALIFE.txt,
 	  src/relationsx.c: Use the new pre-sort function to allow
@@ -2983,7 +3937,7 @@
 	  into a single SortTurnRelationListGeographically() function that
 	  only reads and writes the data once instead of twice.
 
-2012-10-21 [r1107]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-10-21 [r1107]  Andrew M. Bishop <amb>
 
 	* src/segmentsx.h, doc/DATALIFE.txt, src/planetsplitter.c,
 	  src/segmentsx.c: Use the new pre-sort function to allow
@@ -2991,7 +3945,7 @@
 	  single SortSegmentListGeographically() function that only reads
 	  and writes the data once instead of twice.
 
-2012-10-21 [r1106]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-10-21 [r1106]  Andrew M. Bishop <amb>
 
 	* src/nodesx.c, src/sorting.c, src/relationsx.c, src/sorting.h,
 	  src/waysx.c, src/segmentsx.c: Change the sorting functions to
@@ -2999,7 +3953,7 @@
 	  a post-selection one (this will allow deletion of some items
 	  before sorting instead of after sorting in some cases).
 
-2012-10-21 [r1103-1105]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-10-21 [r1103-1105]  Andrew M. Bishop <amb>
 
 	* doc/DATALIFE.txt: Added new columns showing when the data files
 	  are mapped into memory.
@@ -3011,17 +3965,17 @@
 	* src/ways.h, src/filedumper.c: Delete the onumber parameter from
 	  the Ways file header.
 
-2012-10-21 [r1102]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-10-21 [r1102]  Andrew M. Bishop <amb>
 
 	* src/segmentsx.c: Reallocate the firstnode array when indexing
 	  segments because there may be fewer nodes now.
 
-2012-10-21 [r1101]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-10-21 [r1101]  Andrew M. Bishop <amb>
 
 	* src/nodesx.c: Remove some unused parts of the
 	  SortNodeListGeographically() function.
 
-2012-10-20 [r1100]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-10-20 [r1100]  Andrew M. Bishop <amb>
 
 	* doc/DATALIFE.txt, src/relationsx.c, src/planetsplitter.c,
 	  src/waysx.c, src/segmentsx.c, src/waysx.h, src/segmentsx.h: Move
@@ -3029,63 +3983,63 @@
 	  ways at this point and also call the function again after pruning
 	  segments.
 
-2012-10-20 [r1099]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-10-20 [r1099]  Andrew M. Bishop <amb>
 
 	* src/nodesx.c: Mark pruned nodes in the node index.
 
-2012-10-20 [r1098]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-10-20 [r1098]  Andrew M. Bishop <amb>
 
 	* src/relationsx.c, src/planetsplitter.c, src/relationsx.h,
 	  src/segmentsx.c, src/nodesx.c, src/prunex.c, doc/DATALIFE.txt,
 	  src/nodesx.h, src/superx.c: Delete the pruned nodes before
 	  searching for super-nodes etc.
 
-2012-10-20 [r1097]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-10-20 [r1097]  Andrew M. Bishop <amb>
 
 	* src/nodesx.c: Move the calculation of lat/long extents to the
 	  UpdateNodes() function.
 
-2012-10-20 [r1096]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-10-20 [r1096]  Andrew M. Bishop <amb>
 
 	* doc/DATALIFE.txt: Add missing data (nodesx->super).
 
-2012-10-20 [r1095]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-10-20 [r1095]  Andrew M. Bishop <amb>
 
 	* doc/DATALIFE.txt (added): A description of the data lifetime in
 	  the planetsplitter program (as an aid to understanding it better
 	  and not messing it up when editing it).
 
-2012-10-19 [r1094]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-10-19 [r1094]  Andrew M. Bishop <amb>
 
 	* src/waysx.c: Remove one filesort and one read through the ways
 	  file when compacting.
 
-2012-10-19 [r1093]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-10-19 [r1093]  Andrew M. Bishop <amb>
 
 	* src/waysx.c, src/segmentsx.c, src/waysx.h: Change to an external
 	  index for the compacted ways.
 
-2012-10-18 [r1092]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-10-18 [r1092]  Andrew M. Bishop <amb>
 
 	* src/planetsplitter.c, src/waysx.c, src/waysx.h: When compacting
 	  ways exclude the ones that are not used by any segments.
 
-2012-10-17 [r1091]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-10-17 [r1091]  Andrew M. Bishop <amb>
 
 	* src/planetsplitter.c: Perform the Way compacting at the end
 	  (after pruning segments).
 
-2012-10-17 [r1090]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-10-17 [r1090]  Andrew M. Bishop <amb>
 
 	* src/waysx.h, src/waysx.c, src/segmentsx.c: Rename the WayX->prop
 	  entry to WayX->cid to disambiguate it.
 
-2012-10-17 [r1089]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-10-17 [r1089]  Andrew M. Bishop <amb>
 
 	* src/typesx.h, src/superx.c: Rename the BitMask functions to set
 	  or clear all bits.
 
-2012-09-28 [r1078]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-09-28 [r1078]  Andrew M. Bishop <amb>
 
 	* src/ways.c, src/segments.c, src/visualiser.c, src/nodes.c,
 	  src/ways.h, src/fakes.c, src/segments.h, src/optimiser.c,
@@ -3094,7 +4048,7 @@
 	  use the Hungarian notation "p" suffix (only applies to the
 	  router, not planetsplitter).
 
-2012-07-22 [r1027-1028]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-07-22 [r1027-1028]  Andrew M. Bishop <amb>
 
 	* web/www/routino/noscript.cgi (removed),
 	  web/www/routino/noscript.html (removed),
@@ -3105,21 +4059,21 @@
 	  web/www/routino/customrouter.cgi (removed): Delete obsolete
 	  custom* CGIs.
 
-2012-10-06  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-10-06  Andrew M. Bishop <amb>
 
 	Version 2.3.2 released
 
-2012-10-06 [r1083]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-10-06 [r1083]  Andrew M. Bishop <amb>
 
 	* doc/NEWS.txt, doc/README.txt, FILES, doc/html/readme.html: Update
 	  for 2.3.2 release.
 
-2012-10-02 [r1079]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-10-02 [r1079]  Andrew M. Bishop <amb>
 
 	* xml/routino-tagging.xml: Make the access tag normalisation
 	  consistent between nodes an ways.
 
-2012-09-26 [r1077]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-09-26 [r1077]  Andrew M. Bishop <amb>
 
 	* src/visualiser.c, web/www/routino/visualiser.js,
 	  src/visualiser.h, src/filedumper.c,
@@ -3128,14 +4082,14 @@
 	  visualiser to display nodes that disallow selected transport
 	  type.
 
-2012-09-25 [r1076]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-09-25 [r1076]  Andrew M. Bishop <amb>
 
 	* doc/OUTPUT.txt, doc/html/output.html: Change the example output
 	  now that the copyright notice has changed, the final turn is no
 	  longer missed and minor junctions are formatted differently in
 	  the all text format.
 
-2012-09-23 [r1075]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-09-23 [r1075]  Andrew M. Bishop <amb>
 
 	* src/test/expected/turns-WP08.txt,
 	  src/test/expected/turns-WP09.txt,
@@ -3179,7 +4133,7 @@
 	  output for the HTML) are labelled differently. This also required
 	  the expected results for the tests cases to be changed.
 
-2012-09-22 [r1074]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-09-22 [r1074]  Andrew M. Bishop <amb>
 
 	* src/test/expected/super-or-not-WP02.txt,
 	  src/test/expected/turns-WP10.txt,
@@ -3234,13 +4188,13 @@
 	  test case expected results since the last turn was not being
 	  described properly.
 
-2012-09-20 [r1073]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-09-20 [r1073]  Andrew M. Bishop <amb>
 
 	* src/test/start-1-finish.sh, src/test/a-b-c.sh, src/test/a-b.sh:
 	  Change the scripts for the test cases to use 'diff' instead of
 	  'cmp' so that it is possible to see the changes.
 
-2012-09-19 [r1071-1072]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-09-19 [r1071-1072]  Andrew M. Bishop <amb>
 
 	* src/router.c: Change the error message printed if a super-route
 	  cannot be converted into a normal route.
@@ -3249,20 +4203,20 @@
 	  super-nodes don't route through them when calculating
 	  super-segments.
 
-2012-09-18 [r1070]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-09-18 [r1070]  Andrew M. Bishop <amb>
 
 	* xml/routino-translations.xml: Change the URL for the
 	  license/copyright file (not CC specific and points to
 	  openstreetmap site).
 
-2012-09-17 [r1069]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-09-17 [r1069]  Andrew M. Bishop <amb>
 
 	* src/superx.c, src/test/node-restrictions.osm, src/types.h,
 	  src/test/expected/node-restrictions-WP04.txt: Do not mark
 	  barriers that cannot be passed by any type of transport as
 	  super-nodes.
 
-2012-09-16 [r1068]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-09-16 [r1068]  Andrew M. Bishop <amb>
 
 	* src/test/expected/node-restrictions-WP06.txt (added),
 	  src/test/node-restrictions.sh (added),
@@ -3277,33 +4231,33 @@
 	  to route if a selected waypoint is a node that does not permit
 	  chosen traffic type. Add test cases for this change.
 
-2012-09-13 [r1067]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-09-13 [r1067]  Andrew M. Bishop <amb>
 
 	* src/test/oneway-loop.osm, src/test/invalid-turn-relations.osm,
 	  src/test/turns.osm: Make every test case loadable in JOSM.
 
-2012-09-13 [r1066]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-09-13 [r1066]  Andrew M. Bishop <amb>
 
 	* src/superx.c, src/optimiser.c: Update some comments and make a
 	  few very small optimisations.
 
-2012-09-10 [r1065]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-09-10 [r1065]  Andrew M. Bishop <amb>
 
 	* src/relationsx.c, src/waysx.c: Tidy up relation expression.
 
-2012-09-10 [r1064]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-09-10 [r1064]  Andrew M. Bishop <amb>
 
 	* src/relationsx.c: Log an error if a foot/bicycle way doesn't
 	  allow foot/bicycle transport (it already overrides the way
 	  tagging but didn't warn).
 
-2012-09-09 [r1062-1063]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-09-09 [r1062-1063]  Andrew M. Bishop <amb>
 
 	* src/optimiser.c: Refactor the code for the previous change.
 
 	* src/superx.c: Tiny optimisation to super-segment calculation.
 
-2012-09-08 [r1058-1061]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-09-08 [r1058-1061]  Andrew M. Bishop <amb>
 
 	* src/optimiser.c: Fix the FindSuperSegment() function for routing
 	  problem.
@@ -3319,32 +4273,32 @@
 	  real-life pathological routing problem involving oneway streets
 	  and loops.
 
-2012-08-12 [r1057]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-08-12 [r1057]  Andrew M. Bishop <amb>
 
 	* src/visualiser.c: Fix for highway type visualiser (was missing
 	  one-way segments).
 
-2012-08-11  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-08-11  Andrew M. Bishop <amb>
 
 	Version 2.3.1 released
 
-2012-08-11 [r1050]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-08-11 [r1050]  Andrew M. Bishop <amb>
 
 	* web/www/routino/router.html.en, web/www/routino/router.html.de,
 	  web/www/routino/router.html.nl: Revert the change to waypoint
 	  table widths.
 
-2012-08-11 [r1049]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-08-11 [r1049]  Andrew M. Bishop <amb>
 
 	* web/www/routino/router.pl: Fix for older versions of Perl that
 	  don't accept certain anonymous list syntax.
 
-2012-08-11 [r1048]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-08-11 [r1048]  Andrew M. Bishop <amb>
 
 	* doc/README.txt, FILES, doc/html/readme.html, doc/NEWS.txt:
 	  Updated for version 2.3.1.
 
-2012-08-11 [r1047]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-08-11 [r1047]  Andrew M. Bishop <amb>
 
 	* web/www/routino/router.pl, web/www/routino/router.js,
 	  web/www/routino/router.html.nl, web/www/routino,
@@ -3357,7 +4311,7 @@
 	  web/www/routino/router.html.en, src: Merge the changes from trunk
 	  version into version 2.3.1 branch.
 
-2012-08-06 [r1044-1045]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-08-06 [r1044-1045]  Andrew M. Bishop <amb>
 
 	* src/test/Makefile, src/Makefile, src/xml/Makefile: Be more
 	  consistent about what files to clean up.
@@ -3365,14 +4319,14 @@
 	* src/xmlparse.l: Allow an unlimited number of attributes per tag
 	  without crashing.
 
-2012-08-04 [r1043]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-08-04 [r1043]  Andrew M. Bishop <amb>
 
 	* web/www/routino/router.pl, web/www/routino/router.js,
 	  web/www/routino/router.cgi: Don't send back the unused lines from
 	  the router CGI, add the complete command line and execution time
 	  to the log file.
 
-2012-08-03 [r1040]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-08-03 [r1040]  Andrew M. Bishop <amb>
 
 	* web/www/routino/router.html.de, web/www/routino/router.html.nl,
 	  web/www/routino/maplayout.css, web/www/routino/router.html.en,
@@ -3380,52 +4334,52 @@
 	  adjust the table width so that user browser preferences don't
 	  destroy layout (using small or large font).
 
-2012-08-03 [r1039]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-08-03 [r1039]  Andrew M. Bishop <amb>
 
 	* web/www/routino/router.js: Fix some bugs in the latest check-ins.
 
-2012-08-03 [r1038]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-08-03 [r1038]  Andrew M. Bishop <amb>
 
 	* web/www/routino/router.html.de, web/www/routino/router.html.nl,
 	  web/www/routino/router.js, web/www/routino/router.html.en: Add a
 	  button to close the loop (duplicate the first waypoint at the
 	  end).
 
-2012-08-03 [r1037]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-08-03 [r1037]  Andrew M. Bishop <amb>
 
 	* web/www/routino/router.js: Don't add the waypoint items at the
 	  start and hide them if not needed but make them invisible to
 	  start with and display them if required.
 
-2012-08-03 [r1036]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-08-03 [r1036]  Andrew M. Bishop <amb>
 
 	* web/www/routino/router.js: Improve the way that the home marker
 	  is handled (dragging etc).
 
-2012-08-03 [r1035]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-08-03 [r1035]  Andrew M. Bishop <amb>
 
 	* web/www/routino/visualiser.js, web/www/routino/router.js: Add
 	  comments to the functions that are called from the HTML file (to
 	  simplify debugging and make easier to maintain).
 
-2012-08-02 [r1034]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-08-02 [r1034]  Andrew M. Bishop <amb>
 
 	* web/www/routino/router.js: Never-used markers now show as blank,
 	  not 0,0. Clicking an unused marker centres it on the map and
 	  updates the coordinates.
 
-2012-08-02 [r1033]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-08-02 [r1033]  Andrew M. Bishop <amb>
 
 	* web/www/routino/router.js: Refactor the code that inserts,
 	  removes and moves markers around so that all properties are moved
 	  including search/coords selection, search values etc.
 
-2012-08-02 [r1032]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-08-02 [r1032]  Andrew M. Bishop <amb>
 
 	* web/www/routino/router.js: Change the formSetCoords() function so
 	  that it doesn't change the active state.
 
-2012-07-31 [r1030-1031]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-07-31 [r1030-1031]  Andrew M. Bishop <amb>
 
 	* web/www/routino/icons: Generate the full set of icons and ignore
 	  them from SVN.
@@ -3433,27 +4387,27 @@
 	* web/www/routino/icons/create-icons.pl: Create more limit markers
 	  for the visualiser.
 
-2012-07-22 [r1029]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-07-22 [r1029]  Andrew M. Bishop <amb>
 
 	* web/www/routino/icons/create-icons.pl: Create
 	  marker-XXX-(red|grey).png icons which can get requested before
 	  the Javascript removes them.
 
-2012-07-21  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-07-21  Andrew M. Bishop <amb>
 
 	Version 2.3 released
 
-2012-07-21 [r1026]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-07-21 [r1026]  Andrew M. Bishop <amb>
 
 	* doc/NEWS.txt, doc/README.txt, FILES, doc/html/readme.html: Update
 	  to version 2.3.
 
-2012-07-21 [r1025]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-07-21 [r1025]  Andrew M. Bishop <amb>
 
 	* src/osmparser.c: Fix problem with not logging all invalid tags.
 	  Minor optimisation to speed up tag recognition.
 
-2012-07-17 [r1023-1024]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-07-17 [r1023-1024]  Andrew M. Bishop <amb>
 
 	* doc/html/output.html: Change the comment describing the
 	  parameters for the example route.
@@ -3462,44 +4416,44 @@
 	  threads and not enough memory will slow down planetsplitter
 	  operation.
 
-2012-07-17 [r1022]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-07-17 [r1022]  Andrew M. Bishop <amb>
 
 	* src/xmlparse.l: Some small lex changes and an optimisation to
 	  remove repeated memory allocation.
 
-2012-07-16 [r1021]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-07-16 [r1021]  Andrew M. Bishop <amb>
 
 	* src/sorting.c: Restore the shortcut that doesn't write the data
 	  to a temporary file if it all can be sorted in one go. This
 	  removes the slowdown with the multi-threaded code even when
 	  running with no threads.
 
-2012-07-15 [r1020]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-07-15 [r1020]  Andrew M. Bishop <amb>
 
 	* src/sorting.c: Don't call any of the pthread functions unless
 	  running with multiple threads.
 
-2012-07-14 [r1019]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-07-14 [r1019]  Andrew M. Bishop <amb>
 
 	* src/logging.c: Default not to use the --logtime option.
 
-2012-07-12 [r1018]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-07-12 [r1018]  Andrew M. Bishop <amb>
 
 	* web/www/routino/router.js: Another change related to OpenLayers
 	  2.12.
 
-2012-07-11 [r1017]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-07-11 [r1017]  Andrew M. Bishop <amb>
 
 	* src/prunex.c: Fix bug with pruning straight highways
 	  (uninitialised data).
 
-2012-07-10 [r1016]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-07-10 [r1016]  Andrew M. Bishop <amb>
 
 	* web/www/routino/router.html.en, web/www/routino/router.html.de,
 	  web/www/routino/router.html.nl, web/www/routino/router.js:
 	  Trigger the search form only when pressing the return key.
 
-2012-07-10 [r1014-1015]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-07-10 [r1014-1015]  Andrew M. Bishop <amb>
 
 	* web/www/routino/page-elements.js: Remove some temporary variables
 	  by combining statements.
@@ -3507,50 +4461,50 @@
 	* web/www/routino/visualiser.js: A change that should have been in
 	  r985.
 
-2012-07-09 [r1013]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-07-09 [r1013]  Andrew M. Bishop <amb>
 
 	* web/www/openlayers/routino.cfg, web/www/routino/visualiser.js,
 	  web/www/routino/router.js: Make compatible with OpenLayers
 	  version 2.12 (but don't default to using it).
 
-2012-07-09 [r1012]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-07-09 [r1012]  Andrew M. Bishop <amb>
 
 	* doc/INSTALL.txt, web/www/routino/router.js,
 	  web/www/routino/mapprops.js: Move the maxmarkers variable from
 	  router.js to mapprops.js.
 
-2012-06-30 [r1011]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-06-30 [r1011]  Andrew M. Bishop <amb>
 
 	* web/www/routino/router.js, web/www/routino/visualiser.js: Remove
 	  some temporary variables by combining statements.
 
-2012-06-29 [r1010]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-06-29 [r1010]  Andrew M. Bishop <amb>
 
 	* web/www/routino/router.html.de,
 	  web/www/routino/visualiser.html.en,
 	  web/www/routino/router.html.nl, web/www/routino/router.js,
 	  web/www/routino/router.html.en: Fix HTML so that it validates.
 
-2012-06-29 [r1009]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-06-29 [r1009]  Andrew M. Bishop <amb>
 
 	* web/www/routino/router.js, web/www/routino/visualiser.js: Be more
 	  consistent with the .transform() operation.
 
-2012-06-29 [r1008]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-06-29 [r1008]  Andrew M. Bishop <amb>
 
 	* web/www/routino/router.js, web/www/routino/search.pl,
 	  web/www/routino/search.cgi: Pass bounding box to search to help
 	  find local places. Properly URI encode search strings. Properly
 	  check CGI parameters.
 
-2012-06-29 [r1007]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-06-29 [r1007]  Andrew M. Bishop <amb>
 
 	* web/www/routino/router.html.en, web/www/routino/router.css,
 	  web/www/routino/router.html.de, web/www/routino/router.html.nl:
 	  Remove all style definitions from HTML files except for
 	  "display:none".
 
-2012-06-29 [r1005-1006]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-06-29 [r1005-1006]  Andrew M. Bishop <amb>
 
 	* web/www/routino/icons/waypoint-coords.png,
 	  web/www/routino/icons/waypoint-search.png: Fix icons to have
@@ -3562,7 +4516,7 @@
 	  web/www/routino/router.css, doc/INSTALL.txt: Display all of the
 	  search results and allow the user to select one.
 
-2012-06-05 [r1004]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-06-05 [r1004]  Andrew M. Bishop <amb>
 
 	* web/www/routino/search.pl, web/www/routino/router.cgi,
 	  web/www/routino/results.cgi, web/www/routino/search.cgi,
@@ -3570,7 +4524,7 @@
 	  web/www/routino/statistics.cgi: Made some of the perl variables
 	  scope-local and checked other perl functions.
 
-2012-06-05 [r1003]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-06-05 [r1003]  Andrew M. Bishop <amb>
 
 	* src/visualiser.c, doc/html/usage.html,
 	  web/www/routino/visualiser.js, src/visualiser.h,
@@ -3578,7 +4532,7 @@
 	  web/www/routino/visualiser.html.en: Add an option to the
 	  visualiser to display segments of each of the highway types.
 
-2012-06-05 [r1002]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-06-05 [r1002]  Andrew M. Bishop <amb>
 
 	* src/visualiser.h, src/filedumper.c, doc/USAGE.txt,
 	  web/www/routino/visualiser.cgi,
@@ -3588,7 +4542,7 @@
 	  to the visualiser to display segments accessible to each of the
 	  transport types.
 
-2012-06-05 [r1001]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-06-05 [r1001]  Andrew M. Bishop <amb>
 
 	* web/www/routino/router.html.en, web/www/routino/search.cgi
 	  (added), web/www/routino/router.css, web/www/routino/paths.pl,
@@ -3600,74 +4554,74 @@
 	  lat/long text entry with a location search entry. Use Nominatim
 	  service via CGI to get first search result and fill in coords.
 
-2012-06-04 [r999-1000]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-06-04 [r999-1000]  Andrew M. Bishop <amb>
 
 	* web/www/routino/results.cgi: No need to include paths.pl.
 
 	* doc/html/installation.html: Move the filename prefix parameter to
 	  the paths.pl script with the other user-editable parameters.
 
-2012-06-04 [r998]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-06-04 [r998]  Andrew M. Bishop <amb>
 
 	* doc/INSTALL.txt, web/www/routino/paths.pl,
 	  web/www/routino/router.pl: Move the filename prefix parameter to
 	  the paths.pl script with the other user-editable parameters.
 
-2012-06-04 [r997]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-06-04 [r997]  Andrew M. Bishop <amb>
 
 	* web/www/routino/router.pl: On OSX the md5 program is called "md5"
 	  and not "md5sum".
 
-2012-05-10 [r996]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-05-10 [r996]  Andrew M. Bishop <amb>
 
 	* src/sorting.c: Added some mutexes and condition variables to
 	  communicate between threads.
 
-2012-05-09 [r995]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-05-09 [r995]  Andrew M. Bishop <amb>
 
 	* src/relationsx.c: Force bicycle routes to be bicycle accessible
 	  and foot routes to be foot accessible.
 
-2012-05-08 [r994]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-05-08 [r994]  Andrew M. Bishop <amb>
 
 	* web/www/routino/router.html.de: Merge in the changes to the HTML
 	  template.
 
-2012-05-08 [r993]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-05-08 [r993]  Andrew M. Bishop <amb>
 
 	* web/www/routino/router.html.de: Make link to documentation a
 	  relative one rather than to the Routino website.
 
-2012-05-08 [r992]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-05-08 [r992]  Andrew M. Bishop <amb>
 
 	* web/www/routino/router.html.en, web/www/routino/router.html.de
 	  (added), web/www/routino/router.html.nl: Add a German language
 	  router webpage, and links to it from the other ones (patch from
 	  Andreas Matthus).
 
-2012-05-02 [r991]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-05-02 [r991]  Andrew M. Bishop <amb>
 
 	* src/planetsplitter.c, src/Makefile, doc/USAGE.txt, src/sorting.c,
 	  doc/html/usage.html: Convert sorting algorithms to optionally use
 	  multiple threads.
 
-2012-05-01 [r990]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-05-01 [r990]  Andrew M. Bishop <amb>
 
 	* xml/routino-osm.xsd, xml/osm.xsd, src/osmparser.c: Handle OSM
 	  files that contain changesets.
 
-2012-04-29 [r989]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-04-29 [r989]  Andrew M. Bishop <amb>
 
 	* src/planetsplitter.c: Handle the --process-only and --parse-only
 	  options better.
 
-2012-04-01 [r988]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-04-01 [r988]  Andrew M. Bishop <amb>
 
 	* web/www/routino/customvisualiser.cgi,
 	  web/www/routino/customrouter.cgi: Don't even bother checking the
 	  legality of the parameters since the JavaScript does that.
 
-2012-04-01 [r987]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-04-01 [r987]  Andrew M. Bishop <amb>
 
 	* web/www/routino/icons, web/www/routino/router.html.nl,
 	  web/www/routino/router.js, web/www/routino/icons/create-icons.pl,
@@ -3675,7 +4629,7 @@
 	  controlled by the JavaScript and they are automatically inserted
 	  so there is no need to insert multiple lines in the HTML.
 
-2012-03-31 [r986]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-03-31 [r986]  Andrew M. Bishop <amb>
 
 	* web/www/routino/router.html.en,
 	  web/www/routino/visualiser.html.en,
@@ -3683,7 +4637,7 @@
 	  web/www/routino/visualiser.js: Update the link URLs just-in-time
 	  rather than every time the map moves or parameters are changed.
 
-2012-03-24 [r985]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-03-24 [r985]  Andrew M. Bishop <amb>
 
 	* web/www/routino/visualiser.js,
 	  web/www/routino/customvisualiser.cgi,
@@ -3696,7 +4650,7 @@
 	  redirect to the HTML page (will be removed in later versions -
 	  for existing link compatibility only).
 
-2012-03-23 [r984]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-03-23 [r984]  Andrew M. Bishop <amb>
 
 	* web/www/routino/router.html.en, web/www/routino/router.html.nl,
 	  web/www/routino/router.js: Added new buttons to centre map on
@@ -3705,7 +4659,7 @@
 	  Allow "up" on first marker and "down" on last marker to wrap
 	  around.
 
-2012-03-23 [r983]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-03-23 [r983]  Andrew M. Bishop <amb>
 
 	* web/www/routino/icons/waypoint-locate.png (added),
 	  web/www/routino/icons/waypoint-recentre.png (added),
@@ -3717,17 +4671,17 @@
 	  web/www/routino/icons/waypoint-up.png: Enlarged the button icons,
 	  changed some and added two new ones.
 
-2012-03-17 [r982]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-03-17 [r982]  Andrew M. Bishop <amb>
 
 	* src/logging.c, doc/html/usage.html, src/planetsplitter.c,
 	  src/logging.h, doc/USAGE.txt: Add a new '--logtime' option that
 	  prints the elapsed time for planetsplitter.
 
-2012-03-03  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-03-03  Andrew M. Bishop <amb>
 
 	Version 2.2 released
 
-2012-03-03 [r978-981]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-03-03 [r978-981]  Andrew M. Bishop <amb>
 
 	* doc/html/output.html: Updated to version 2.2.
 
@@ -3737,16 +4691,16 @@
 
 	* doc/NEWS.txt: Updated to version 2.2.
 
-2012-02-21 [r977]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-02-21 [r977]  Andrew M. Bishop <amb>
 
 	* src/prunex.c: Refactor code slightly for isolated regions.
 
-2012-02-21 [r976]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-02-21 [r976]  Andrew M. Bishop <amb>
 
 	* src/prunex.c: Re-arrange small sections of code based on results
 	  of profiling.
 
-2012-02-21 [r975]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-02-21 [r975]  Andrew M. Bishop <amb>
 
 	* src/test/a-b-c.sh, src/test/a-b.sh, doc/html/usage.html,
 	  src/planetsplitter.c, src/test/Makefile, src/test, doc/USAGE.txt,
@@ -3755,98 +4709,98 @@
 	  pruning but only compare against the expected results when not
 	  pruned.
 
-2012-02-20 [r974]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-02-20 [r974]  Andrew M. Bishop <amb>
 
 	* src/planetsplitter.c: Prune straight highways then isolated
 	  regions and then short segments.
 
-2012-02-20 [r973]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-02-20 [r973]  Andrew M. Bishop <amb>
 
 	* src/prunex.c: Remove compiler warnings (when compiled with
 	  optimisation).
 
-2012-02-20 [r972]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-02-20 [r972]  Andrew M. Bishop <amb>
 
 	* src/prunex.c: Allow pruning isolated regions to be run second or
 	  later.
 
-2012-02-20 [r971]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-02-20 [r971]  Andrew M. Bishop <amb>
 
 	* src/prunex.c: Don't remove nodes/segments when straightening ways
 	  if it would cause the loss of a way name.
 
-2012-02-19 [r970]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-02-19 [r970]  Andrew M. Bishop <amb>
 
 	* src/prunex.c: Some fixes to be able to process the whole of the
 	  UK.
 
-2012-02-18 [r969]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-02-18 [r969]  Andrew M. Bishop <amb>
 
 	* doc/html/algorithm.html, doc/ALGORITHM.txt: Add a general
 	  description of data pruning.
 
-2012-02-18 [r968]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-02-18 [r968]  Andrew M. Bishop <amb>
 
 	* src/prunex.c: Fix bug with pruning that caused super-node search
 	  to fail.
 
-2012-02-18 [r967]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-02-18 [r967]  Andrew M. Bishop <amb>
 
 	* src/prunex.c: Refactored the code for straight highways and made
 	  improvements.
 
-2012-02-18 [r966]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-02-18 [r966]  Andrew M. Bishop <amb>
 
 	* src/prunex.h, doc/html/usage.html, src/planetsplitter.c,
 	  doc/USAGE.txt, src/prunex.c: Prune nodes in the middle of
 	  straight highways.
 
-2012-02-12 [r965]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-02-12 [r965]  Andrew M. Bishop <amb>
 
 	* src/nodesx.h: Need 3 cached nodes for slim mode.
 
-2012-02-11 [r964]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-02-11 [r964]  Andrew M. Bishop <amb>
 
 	* doc/html/usage.html, src/planetsplitter.c, src/segments.h,
 	  doc/USAGE.txt, src/waysx.h, src/prunex.c, src/segmentsx.h: Prune
 	  short segments.
 
-2012-02-09 [r963]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-02-09 [r963]  Andrew M. Bishop <amb>
 
 	* src/prunex.h, src/planetsplitter.c, src/prunex.c: Prune isolated
 	  segments if they cannot be routed to anywhere else, not just if
 	  they are not connected.
 
-2012-02-09 [r962]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-02-09 [r962]  Andrew M. Bishop <amb>
 
 	* src/types.h: The latlong_t type is signed so must use an
 	  appropriate constant.
 
-2012-02-08 [r961]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-02-08 [r961]  Andrew M. Bishop <amb>
 
 	* src/nodesx.h, src/types.h, src/prunex.c: Change the way that
 	  pruned nodes are recorded.
 
-2012-02-08 [r960]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-02-08 [r960]  Andrew M. Bishop <amb>
 
 	* src/prunex.c: Don't mark pruned nodes as they are found but mark
 	  them all at the end.
 
-2012-02-07 [r959]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-02-07 [r959]  Andrew M. Bishop <amb>
 
 	* src/Makefile: Revert the CFLAGS value.
 
-2012-01-28 [r958]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-01-28 [r958]  Andrew M. Bishop <amb>
 
 	* src/typesx.h: Fix the recent change with the bitmask type.
 
-2012-01-28 [r956-957]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-01-28 [r956-957]  Andrew M. Bishop <amb>
 
 	* src/files.h, src/prunex.c: Fix function comments.
 
 	* src/sorting.h: Replace a missing header.
 
-2012-01-28 [r955]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-01-28 [r955]  Andrew M. Bishop <amb>
 
 	* src/segments.c, src/prunex.h, src/superx.c, src/visualiser.c,
 	  src/relationsx.c, src/profiles.h, src/sorting.h, src/fakes.h,
@@ -3856,30 +4810,30 @@
 	  src/tagging.c, src/prunex.c, src/segmentsx.h, src/profiles.c,
 	  src/queue.c: Simplify and standardise the included headers.
 
-2012-01-14 [r954]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-01-14 [r954]  Andrew M. Bishop <amb>
 
 	* src/typesx.h: Change the bitmask type from uint8_t to uint32_t.
 
-2012-01-14 [r953]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-01-14 [r953]  Andrew M. Bishop <amb>
 
 	* src/prunex.h, doc/html/usage.html, src/planetsplitter.c,
 	  doc/USAGE.txt, src/prunex.c: Add the option to prune small
 	  isolated regions out of the database to avoid routes starting of
 	  finishing on them.
 
-2012-01-14 [r951-952]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-01-14 [r951-952]  Andrew M. Bishop <amb>
 
 	* src/segmentsx.c: Bug fix for latest change.
 
 	* src/relationsx.c: Zero the structure before filling it in so that
 	  no junk is written to disk.
 
-2012-01-13 [r950]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-01-13 [r950]  Andrew M. Bishop <amb>
 
 	* src/nodesx.h, src/superx.c, src/segmentsx.c, src/typesx.h,
 	  src/segmentsx.h: Add new macros to abstract the bit mask types.
 
-2012-01-13 [r949]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-01-13 [r949]  Andrew M. Bishop <amb>
 
 	* src/nodesx.h, src/prunex.h (added), src/superx.c,
 	  src/relationsx.c, src/types.h, src/planetsplitter.c,
@@ -3887,44 +4841,44 @@
 	  (added), src/segmentsx.h: Add an infrastructure to allow adding
 	  new functions to prune nodes and segments.
 
-2012-01-11 [r948]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-01-11 [r948]  Andrew M. Bishop <amb>
 
 	* src/sorting.c, src/relationsx.c, src/sorting.h, src/waysx.c,
 	  src/nodesx.c: The filesort_*() functions now return a count of
 	  the number of items kept after sorting.
 
-2012-01-10 [r947]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2012-01-10 [r947]  Andrew M. Bishop <amb>
 
 	* src/superx.c, src/nodesx.c: Move the allocation of the nodexs
 	  super flags memory until just before it is needed and free it as
 	  soon as no longer needed.
 
-2011-12-11 [r946]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-12-11 [r946]  Andrew M. Bishop <amb>
 
 	* src/segmentsx.c: Remove unnecessary test.
 
-2011-12-11 [r945]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-12-11 [r945]  Andrew M. Bishop <amb>
 
 	* src/output.c: Remove warning about uninitialised variable.
 
-2011-12-11 [r944]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-12-11 [r944]  Andrew M. Bishop <amb>
 
 	* src/relationsx.c, src/segmentsx.c, src/nodesx.c: Fill the
 	  structures with zero before inserting data and writing to file
 	  (removes junk from unused spaces in database files).
 
-2011-12-11 [r943]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-12-11 [r943]  Andrew M. Bishop <amb>
 
 	* src/superx.c, src/relationsx.c, src/segmentsx.c, src/segmentsx.h:
 	  Remove the "position" parameter from the NextSegmentX() function.
 
-2011-12-11 [r942]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-12-11 [r942]  Andrew M. Bishop <amb>
 
 	* src/nodesx.h, src/relationsx.c, src/segmentsx.c, src/waysx.h,
 	  src/segmentsx.h: Remove the "position" parameter from the
 	  PutBack*X() functions (only used in slim mode).
 
-2011-12-10 [r940-941]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-12-10 [r940-941]  Andrew M. Bishop <amb>
 
 	* src/osmparser.h: Update file now that the name has changed.
 
@@ -3932,14 +4886,14 @@
 	  src/osmparser.c, src/osmparser.h (added): Rename functionsx.h to
 	  osmparser.h.
 
-2011-12-09 [r939]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-12-09 [r939]  Andrew M. Bishop <amb>
 
 	* web/www/routino/customvisualiser.cgi,
 	  web/www/routino/customrouter.cgi: The custom router uses the
 	  translated router.html or visualiser.html depending on the
 	  browser's Accept-Language header.
 
-2011-12-08 [r936-938]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-12-08 [r936-938]  Andrew M. Bishop <amb>
 
 	* web/www/routino/visualiser.html (added): Create a link from
 	  visualiser.html.en to visualiser.html.
@@ -3952,18 +4906,18 @@
 	  web/www/routino/router.js: Move semi-constant strings from the
 	  JavaScript to the HTML so that they can be translated.
 
-2011-12-08 [r935]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-12-08 [r935]  Andrew M. Bishop <amb>
 
 	* web/www/routino/router.html.en, web/www/routino/router.html.nl,
 	  web/www/routino/router.js: Use the translated total distance from
 	  the summary and not the untranslated one from the CGI.
 
-2011-12-08 [r934]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-12-08 [r934]  Andrew M. Bishop <amb>
 
 	* src/visualiser.c: Make limit checking work with one-way streets
 	  and in slim mode.
 
-2011-12-07 [r933]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-12-07 [r933]  Andrew M. Bishop <amb>
 
 	* doc/html/installation.html, web/www/routino/visualiser.js,
 	  web/www/routino/router.html.en, doc/INSTALL.txt,
@@ -3972,28 +4926,28 @@
 	  Move the map preferences (N/S/E/W range, zoom range and URLs) to
 	  a separate file.
 
-2011-12-07 [r932]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-12-07 [r932]  Andrew M. Bishop <amb>
 
 	* web/www/routino/page-elements.css,
 	  web/www/routino/router.html.en, web/www/routino/visualiser.html,
 	  web/www/routino/router.html.nl: Replace the "show"/"hide" button
 	  with "+"/"-" buttons.
 
-2011-12-07 [r931]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-12-07 [r931]  Andrew M. Bishop <amb>
 
 	* web/data/create.sh: Generate an error log.
 
-2011-12-06 [r930]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-12-06 [r930]  Andrew M. Bishop <amb>
 
 	* doc/TAGGING.txt, doc/html/tagging.html: Describe what the
 	  roundabout and mini-roundabout tags are used for.
 
-2011-12-06 [r929]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-12-06 [r929]  Andrew M. Bishop <amb>
 
 	* src/output.c: Mini-roundabouts are now described as roundabouts
 	  instead of junctions.
 
-2011-12-06 [r927-928]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-12-06 [r927-928]  Andrew M. Bishop <amb>
 
 	* src/test/expected/turns-WP09.txt,
 	  src/test/expected/turns-WP10.txt,
@@ -4009,7 +4963,7 @@
 	* src/output.c: Use constants for the values of the "important"
 	  variable. Fix the missing junctions on roundabouts.
 
-2011-12-06 [r925-926]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-12-06 [r925-926]  Andrew M. Bishop <amb>
 
 	* src/output.c: Output HTML directions for roundabouts.
 
@@ -4017,18 +4971,18 @@
 	  src/translations.c, xml/routino-translations.xsd: Add new
 	  translate-able strings for roundabouts.
 
-2011-12-06 [r924]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-12-06 [r924]  Andrew M. Bishop <amb>
 
 	* src/ways.h: Cache three ways not two.
 
-2011-11-26 [r923]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-11-26 [r923]  Andrew M. Bishop <amb>
 
 	* src/types.h, doc/TAGGING.txt, src/osmparser.c, src/filedumper.c,
 	  doc/html/tagging.html, src/types.c, xml/routino-tagging.xml:
 	  Parse and store information about roundabouts (to improve routing
 	  instructions).
 
-2011-11-26 [r921-922]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-11-26 [r921-922]  Andrew M. Bishop <amb>
 
 	* doc/OUTPUT.txt, src/output.c, doc/html/output.html: Refactor a
 	  lot of the code, simplify it and fix some bugs: Names of highways
@@ -4038,31 +4992,31 @@
 	* src/ways.h, src/ways.c: Allow space to cache one name for each
 	  cached way (in slim mode).
 
-2011-11-23 [r920]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-11-23 [r920]  Andrew M. Bishop <amb>
 
 	* xml/routino-tagging-nomodify.xml: Fix the invalid XML.
 
-2011-11-22 [r919]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-11-22 [r919]  Andrew M. Bishop <amb>
 
 	* src/osmparser.c, xml/routino-osm.xsd: Check that XML file
 	  contains version='0.6' in 'osm' tag.
 
-2011-11-22 [r918]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-11-22 [r918]  Andrew M. Bishop <amb>
 
 	* src/filedumper.c: Refactor the code by moving the dumping of an
 	  OSM region into a separate function.
 
-2011-11-22 [r917]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-11-22 [r917]  Andrew M. Bishop <amb>
 
 	* src/filedumper.c: Include a bounding box in the --dump-osm XML
 	  output.
 
-2011-11-21 [r916]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-11-21 [r916]  Andrew M. Bishop <amb>
 
 	* src/filedumper.c: Ensure that only segments completely within the
 	  specified region are dumped when using --dump-osm.
 
-2011-11-21 [r914-915]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-11-21 [r914-915]  Andrew M. Bishop <amb>
 
 	* doc/TAGGING.txt, doc/html/tagging.html: Document the use of the
 	  area tag.
@@ -4070,24 +5024,24 @@
 	* src/osmparser.c, src/segmentsx.c, xml/routino-tagging.xml: When
 	  an area and a way overlap keep the way and discard the area.
 
-2011-11-20 [r913]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-11-20 [r913]  Andrew M. Bishop <amb>
 
 	* src/test/Makefile, src/xml/Makefile: Fix some more Makefile
 	  oddities.
 
-2011-11-20 [r912]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-11-20 [r912]  Andrew M. Bishop <amb>
 
 	* web/www/openlayers/install.sh: Change script to default to
 	  downloading OpenLayers v2.11.
 
-2011-11-19 [r910-911]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-11-19 [r910-911]  Andrew M. Bishop <amb>
 
 	* Makefile: Fix some Makefile oddities.
 
 	* src/test/Makefile, src/Makefile, src/xml/Makefile: Fix some
 	  Makefile oddities.
 
-2011-11-19 [r907-909]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-11-19 [r907-909]  Andrew M. Bishop <amb>
 
 	* doc/html/tagging.html: Fix heading anchor names.
 
@@ -4099,27 +5053,27 @@
 	  with the change that should have happened in r883 rather than
 	  being based on r868.
 
-2011-11-12  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-11-12  Andrew M. Bishop <amb>
 
 	Version 2.1.2 released
 
-2011-11-12 [r903]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-11-12 [r903]  Andrew M. Bishop <amb>
 
 	* doc/NEWS.txt, doc/README.txt, FILES, doc/html/readme.html:
 	  Updated for version 2.1.2.
 
-2011-11-12 [r902]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-11-12 [r902]  Andrew M. Bishop <amb>
 
 	* xml/routino-translations.xml, web/www/routino/router.html.en,
 	  web/www/routino/router.html.nl: Added Russian language
 	  translations.
 
-2011-11-12 [r901]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-11-12 [r901]  Andrew M. Bishop <amb>
 
 	* doc/OUTPUT.txt, doc/TAGGING.txt, doc/ALGORITHM.txt,
 	  doc/INSTALL.txt: Small formatting changes.
 
-2011-11-11 [r900]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-11-11 [r900]  Andrew M. Bishop <amb>
 
 	* doc/OUTPUT.txt, src/output.c, doc/html/output.html: Change the
 	  names of the variables for the XML and raw versions of the
@@ -4127,33 +5081,33 @@
 	  names. Update the documentation to say that only the header is
 	  untranslated in the text files.
 
-2011-11-11 [r899]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-11-11 [r899]  Andrew M. Bishop <amb>
 
 	* xml/routino-tagging.xml: Fix invalid XML file.
 
-2011-11-11 [r898]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-11-11 [r898]  Andrew M. Bishop <amb>
 
 	* doc/TAGGING.txt, doc/html/tagging.html, xml/routino-tagging.xml:
 	  Improve the documentation for the tagging rule configuration
 	  file.
 
-2011-11-11 [r896-897]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-11-11 [r896-897]  Andrew M. Bishop <amb>
 
 	* xml/routino-tagging.xml: Add some more tagging rules from the UK
 	  error.log file.
 
 	* web/bin/summarise-log.pl: Summarise segments that are loops.
 
-2011-11-11 [r895]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-11-11 [r895]  Andrew M. Bishop <amb>
 
 	* src/relationsx.c: Make the progress messages more consistent.
 
-2011-11-10 [r894]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-11-10 [r894]  Andrew M. Bishop <amb>
 
 	* web/www/routino/router.pl: Use the same convention to indicate
 	  the user-editable part of the file as used elsewhere.
 
-2011-11-10 [r893]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-11-10 [r893]  Andrew M. Bishop <amb>
 
 	* src/translations.h, doc/OUTPUT.txt, src/output.c,
 	  src/translations.c, doc/html/output.html: Change the names of the
@@ -4163,33 +5117,33 @@
 	  to say that only the copyright information is translated in the
 	  text files.
 
-2011-11-10 [r892]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-11-10 [r892]  Andrew M. Bishop <amb>
 
 	* src/translations.c: Don't convert the highway types to XML
 	  numeric entities here (it is already done in the output
 	  functions).
 
-2011-11-09 [r891]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-11-09 [r891]  Andrew M. Bishop <amb>
 
 	* src/optimiser.c: Change the condition used to terminate the
 	  search for the best route.
 
-2011-11-08 [r890]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-11-08 [r890]  Andrew M. Bishop <amb>
 
 	* src/superx.c: Improve comment.
 
-2011-11-08 [r889]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-11-08 [r889]  Andrew M. Bishop <amb>
 
 	* xml/Makefile: Delete the auto-generated profile.js and profile.pl
 	  files with distclean target.
 
-2011-10-31 [r888]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-10-31 [r888]  Andrew M. Bishop <amb>
 
 	* src/files.h: Add a #define to disable the use of pread()/pwrite()
 	  but this must be manually configured, there is no configure
 	  script.
 
-2011-10-31 [r887]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-10-31 [r887]  Andrew M. Bishop <amb>
 
 	* src/nodesx.h, src/relations.h, src/files.h, src/relationsx.c,
 	  src/ways.h, src/segments.h, src/waysx.c, src/Makefile,
@@ -4197,52 +5151,52 @@
 	  pread() and pwrite() functions instead of seek() followed by
 	  read() or write().
 
-2011-10-30 [r886]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-10-30 [r886]  Andrew M. Bishop <amb>
 
 	* src/nodes.c, src/nodes.h: Copy the node offsets into RAM for the
 	  slim mode since looking them up in the file is the largest single
 	  contributor to the time.
 
-2011-10-29 [r885]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-10-29 [r885]  Andrew M. Bishop <amb>
 
 	* src/segments.c, src/visualiser.c, src/nodes.c, src/optimiser.c,
 	  src/filedumper.c, src/nodes.h, src/output.c: Rationalise and
 	  reduce the usage of LookUpNode() function.
 
-2011-10-24 [r884]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-10-24 [r884]  Andrew M. Bishop <amb>
 
 	* src/Makefile, src/xml/Makefile: Fix long-standing annoying bug
 	  with dependencies for slim versions.
 
-2011-10-24 [r883]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-10-24 [r883]  Andrew M. Bishop <amb>
 
 	* src/queue.c: No need to use uint32_t (just use int).
 
-2011-10-23  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-10-23  Andrew M. Bishop <amb>
 
 	Version 2.1.1 released
 
-2011-10-23 [r881-882]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-10-23 [r881-882]  Andrew M. Bishop <amb>
 
 	* doc/NEWS.txt, FILES, doc/html/readme.html: Update for version
 	  2.1.1.
 
 	* doc/html/configuration.html: Update copyright year.
 
-2011-10-22 [r880]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-10-22 [r880]  Andrew M. Bishop <amb>
 
 	* Makefile: Fix running 'make test' from the top level.
 
-2011-10-22 [r879]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-10-22 [r879]  Andrew M. Bishop <amb>
 
 	* src/filedumper.c: Add some more typecasts before printing the
 	  values.
 
-2011-10-22 [r878]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-10-22 [r878]  Andrew M. Bishop <amb>
 
 	* xml/Makefile: Fix the installation of the XML files.
 
-2011-10-22 [r876-877]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-10-22 [r876-877]  Andrew M. Bishop <amb>
 
 	* src/test/expected/turns-WP09.txt, src/test/turns.osm,
 	  src/test/expected/turns-WP10.txt,
@@ -4262,36 +5216,36 @@
 	* src/osmparser.c, xml/routino-tagging.xml: Fix handling of
 	  'except' tags for turn restrictions.
 
-2011-10-22 [r875]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-10-22 [r875]  Andrew M. Bishop <amb>
 
 	* src/sorting.c: Revert back to something very close to r869
 	  because it is fastest by a tiny fraction.
 
-2011-10-22 [r874]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-10-22 [r874]  Andrew M. Bishop <amb>
 
 	* src/results.h, src/queue.c: Revert back to r867 because it is
 	  faster (although only by 1%) than any of the other combinations.
 
-2011-10-22 [r873]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-10-22 [r873]  Andrew M. Bishop <amb>
 
 	* src/sorting.c, src/queue.c: Revert back to r864 zero-based binary
 	  heap but with r868/r869 refactored code.
 
-2011-10-15 [r872]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-10-15 [r872]  Andrew M. Bishop <amb>
 
 	* src/sorting.c, src/queue.c: Change the binary heap to a 3-ary
 	  heap.
 
-2011-10-15 [r871]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-10-15 [r871]  Andrew M. Bishop <amb>
 
 	* src/sorting.c: Bug fixes for the previous change.
 
-2011-10-15 [r870]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-10-15 [r870]  Andrew M. Bishop <amb>
 
 	* src/sorting.c, src/results.h, src/queue.c: Change the binary heap
 	  to a 4-ary heap.
 
-2011-10-15 [r868-869]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-10-15 [r868-869]  Andrew M. Bishop <amb>
 
 	* src/sorting.c: Refactor the binary heap to reduce the number of
 	  comparisons.
@@ -4299,69 +5253,69 @@
 	* src/queue.c: Refactor the binary heap to reduce the number of
 	  comparisons.
 
-2011-10-09 [r867]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-10-09 [r867]  Andrew M. Bishop <amb>
 
 	* src/sorting.c: Change to a unity based binary heap rather than
 	  zero based one to save some additions.
 
-2011-10-09 [r866]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-10-09 [r866]  Andrew M. Bishop <amb>
 
 	* src/queue.c: Bug fix with previous change.
 
-2011-10-06 [r865]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-10-06 [r865]  Andrew M. Bishop <amb>
 
 	* src/results.h, src/queue.c: Change to a unity based binary heap
 	  rather than zero based one to save some additions.
 
-2011-10-06 [r864]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-10-06 [r864]  Andrew M. Bishop <amb>
 
 	* src/results.c: Swap the order of two parts of an && statement.
 
-2011-10-06 [r863]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-10-06 [r863]  Andrew M. Bishop <amb>
 
 	* src/results.h, src/results.c: Change bin counters to 8-bit
 	  (reduces memory) and pre-allocate first dimension of pointer
 	  array (saves time).
 
-2011-10-06 [r862]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-10-06 [r862]  Andrew M. Bishop <amb>
 
 	* Makefile, xml/Makefile, doc/Makefile, src/Makefile,
 	  src/xml/Makefile: Makefiles are more consistent with each other
 	  and 'make test' can be run from the top level.
 
-2011-10-06 [r861]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-10-06 [r861]  Andrew M. Bishop <amb>
 
 	* doc/html/usage.html, src/planetsplitter.c, doc/USAGE.txt: Change
 	  the default number of iterations to 5 since testing shows that
 	  there is negligible improvement beyond here.
 
-2011-10-05 [r860]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-10-05 [r860]  Andrew M. Bishop <amb>
 
 	* src/optimiser.c: Optimise the number of hash function bins by
 	  trial and error.
 
-2011-10-05 [r859]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-10-05 [r859]  Andrew M. Bishop <amb>
 
 	* src/Makefile, src/xml/Makefile: Add the gcc options for profiling
 	  (coverage) and delete the files generated by it.
 
-2011-10-05 [r858]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-10-05 [r858]  Andrew M. Bishop <amb>
 
 	* src/results.c: If there are too many results in one bin then
 	  double the number of bins.
 
-2011-10-05 [r857]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-10-05 [r857]  Andrew M. Bishop <amb>
 
 	* src/results.h, src/results.c: Remove the two RESULTS_*_INCREMENT
 	  constants by swapping the dimensions on the 'point' array so that
 	  both have unity value and are pointless.
 
-2011-10-05 [r856]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-10-05 [r856]  Andrew M. Bishop <amb>
 
 	* src/superx.c: Optimise the number of hash function bins by trial
 	  and error.
 
-2011-10-04 [r854-855]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-10-04 [r854-855]  Andrew M. Bishop <amb>
 
 	* src/superx.c, src/optimiser.c: Increase the size of the hash
 	  array used to store the results.
@@ -4369,30 +5323,30 @@
 	* src/results.h, src/results.c: Change the way that allocated
 	  memory is tracked.
 
-2011-10-04 [r853]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-10-04 [r853]  Andrew M. Bishop <amb>
 
 	* src/results.c: Split the data increment constant into two for the
 	  different parts of the data structure.
 
-2011-10-03 [r852]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-10-03 [r852]  Andrew M. Bishop <amb>
 
 	* web/www/routino/router.cgi: Ensure that the shortest or quickest
 	  option is passed to the router.
 
-2011-10-03  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-10-03  Andrew M. Bishop <amb>
 
 	Version 2.1 released
 
-2011-10-03 [r851]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-10-03 [r851]  Andrew M. Bishop <amb>
 
 	* FILES: Remove another .svn directory.
 
-2011-10-03 [r850]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-10-03 [r850]  Andrew M. Bishop <amb>
 
 	* doc/NEWS.txt, FILES, doc/html/readme.html: Update for version
 	  2.1.
 
-2011-09-07 [r849]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-09-07 [r849]  Andrew M. Bishop <amb>
 
 	* src/test/super-or-not.osm, src/optimiser.c,
 	  src/test/expected/super-or-not-WP03.txt (added): Handle the
@@ -4400,29 +5354,29 @@
 	  point is somewhere within one of the super-segments from that
 	  node.
 
-2011-09-07 [r848]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-09-07 [r848]  Andrew M. Bishop <amb>
 
 	* src/nodes.c: Fix for previous binary search change.
 
-2011-09-07 [r847]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-09-07 [r847]  Andrew M. Bishop <amb>
 
 	* src/filedumper.c: Fix bug with earlier change to OSM file
 	  creator.
 
-2011-09-07 [r846]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-09-07 [r846]  Andrew M. Bishop <amb>
 
 	* src/router.c: Fix confusing, duplicated, output message.
 
-2011-09-07 [r845]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-09-07 [r845]  Andrew M. Bishop <amb>
 
 	* src/nodes.c: Make stricter checks for closest nodes just like in
 	  v2.0.3 for segments.
 
-2011-09-07 [r844]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-09-07 [r844]  Andrew M. Bishop <amb>
 
 	* src/filedumper.c: Fix formatting problem with dumped OSM file.
 
-2011-09-07 [r842-843]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-09-07 [r842-843]  Andrew M. Bishop <amb>
 
 	* src/nodes.c, src/waysx.c, src/nodesx.c, src/relations.c: Check
 	  binary search functions and improve comments, fix pathological
@@ -4431,7 +5385,7 @@
 	* src/filedumper.c: Use macro test function rather than direct
 	  check.
 
-2011-09-06 [r841]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-09-06 [r841]  Andrew M. Bishop <amb>
 
 	* src/test/super-or-not.osm (added), src/test/a-b.sh (added),
 	  src/test/expected/super-or-not-WP01.txt (added),
@@ -4440,7 +5394,7 @@
 	  routing bug-fix in version 2.0.3 (route via super-nodes may not
 	  be shortest).
 
-2011-09-06 [r840]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-09-06 [r840]  Andrew M. Bishop <amb>
 
 	* src/test/expected/dead-ends-WP01.txt,
 	  src/test/expected/dead-ends-WP02.txt,
@@ -4486,7 +5440,7 @@
 	  correct copyright notice (Routino, AGPL3) in generated data and
 	  not the default one (OSM, CC-SA).
 
-2011-09-06 [r838-839]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-09-06 [r838-839]  Andrew M. Bishop <amb>
 
 	* src/test/expected/dead-ends-WP01.txt (added),
 	  src/test/expected/dead-ends-WP02.txt (added),
@@ -4535,19 +5489,19 @@
 	  src/test/start-1-finish.sh: Store the expected results to check
 	  for future regressions.
 
-2011-09-05 [r837]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-09-05 [r837]  Andrew M. Bishop <amb>
 
 	* src/relationsx.c: Ignore relations based on all vehicle types
 	  (including bicycles) not just motor vehicles.
 
-2011-09-05 [r836]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-09-05 [r836]  Andrew M. Bishop <amb>
 
 	* xml/Makefile, xml/scripts/walk.pl (added), xml,
 	  xml/scripts/ride.pl (added), web/data, xml/scripts (added),
 	  xml/scripts/drive.pl (added): Generate special-use sets of
 	  tagging rules for walking, riding and driving
 
-2011-08-27 [r834-835]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-08-27 [r834-835]  Andrew M. Bishop <amb>
 
 	* web/bin/summarise-log.pl (added): A script to process the error
 	  log file and summarise it.
@@ -4555,51 +5509,51 @@
 	* xml/routino-tagging.xml: Add lots more tagging rules based on
 	  errors logged from parsing UK, add some more error logging.
 
-2011-08-27 [r832-833]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-08-27 [r832-833]  Andrew M. Bishop <amb>
 
 	* src/osmparser.c: Only log errors for highways.
 
 	* src/relationsx.c: Improve the error messages for bad relations.
 
-2011-08-27 [r830-831]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-08-27 [r830-831]  Andrew M. Bishop <amb>
 
 	* src/filedumper.c: Change the 'generator' tag in the dumped XML
 	  file.
 
 	* xml/routino-tagging.xsd: Whitespace change.
 
-2011-08-21 [r828]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-08-21 [r828]  Andrew M. Bishop <amb>
 
 	* doc/NEWS.txt, doc/README.txt, src/nodes.c, FILES,
 	  src/optimiser.c, src/router.c, doc/html/readme.html: Merge
 	  version 2.0.3 into working version.
 
-2011-08-14 [r827]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-08-14 [r827]  Andrew M. Bishop <amb>
 
 	* src/tagging.h, src/tagging.c, xml/routino-tagging.xsd: Add an
 	  unset rule in the tagging processing XML file.
 
-2011-08-13 [r826]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-08-13 [r826]  Andrew M. Bishop <amb>
 
 	* src/tagging.h, src/tagmodifier.c, src/osmparser.c, src/tagging.c,
 	  xml/routino-tagging.xsd: Add a logerror rule in the tagging
 	  processing XML file.
 
-2011-08-04 [r825]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-08-04 [r825]  Andrew M. Bishop <amb>
 
 	* src/osmparser.c: Add more acceptable number suffixes.
 
-2011-07-23 [r813]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-07-23 [r813]  Andrew M. Bishop <amb>
 
 	* src/osmparser.c: Better parsing of width/height/length and weight
 	  and more information about value actually used.
 
-2011-07-21 [r812]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-07-21 [r812]  Andrew M. Bishop <amb>
 
 	* src/relationsx.c, src/osmparser.c, src/waysx.c, src/segmentsx.c,
 	  src/nodesx.c: Add logging of parsing and processing errors.
 
-2011-07-21 [r810-811]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-07-21 [r810-811]  Andrew M. Bishop <amb>
 
 	* src/test/a-b-c.sh, src/test/start-1-finish.sh,
 	  src/test/only-split.sh: Use the --errorlog option.
@@ -4607,12 +5561,12 @@
 	* doc/html/usage.html, src/planetsplitter.c, doc/USAGE.txt: The
 	  filename is now optional in the --errorlog option.
 
-2011-07-21 [r809]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-07-21 [r809]  Andrew M. Bishop <amb>
 
 	* src/planetsplitter.c: Only open/close the error log file if one
 	  was requested.
 
-2011-07-10 [r806-808]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-07-10 [r806-808]  Andrew M. Bishop <amb>
 
 	* src/test: Ignore the auto-generated files from the new test case.
 
@@ -4624,37 +5578,37 @@
 	* src/relationsx.c: Check turn relations more carefully and discard
 	  them if they are invalid.
 
-2011-07-04 [r805]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-07-04 [r805]  Andrew M. Bishop <amb>
 
 	* src/relationsx.c: Change the termination of route relation
 	  way/relation lists.
 
-2011-07-03 [r804]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-07-03 [r804]  Andrew M. Bishop <amb>
 
 	* src/logging.c, doc/html/usage.html, src/planetsplitter.c,
 	  src/logging.h, doc/USAGE.txt: Add framework for logging error
 	  during OSM parsing and subsequent processing.
 
-2011-07-02 [r803]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-07-02 [r803]  Andrew M. Bishop <amb>
 
 	* src/nodes.h: Replace over-sized file entry with one of
 	  appropriate size.
 
-2011-08-04  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-08-04  Andrew M. Bishop <amb>
 
 	Version 2.0.3 released
 
-2011-08-04 [r823]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-08-04 [r823]  Andrew M. Bishop <amb>
 
 	* doc/NEWS.txt, doc/README.txt, FILES, doc/html/readme.html:
 	  Updated for version 2.0.3.
 
-2011-08-04 [r822]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-08-04 [r822]  Andrew M. Bishop <amb>
 
 	* src/router.c: If there is a route that passes super-nodes and one
 	  that doesn't then choose the better one.
 
-2011-08-04 [r820-821]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-08-04 [r820-821]  Andrew M. Bishop <amb>
 
 	* src/router.c: If there is a direct route without passing any
 	  super-nodes then keep it as a backup in case the potential route
@@ -4662,52 +5616,52 @@
 
 	* src/optimiser.c: Allow calling FixForwardRoute() more than once.
 
-2011-08-04 [r819]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-08-04 [r819]  Andrew M. Bishop <amb>
 
 	* src/optimiser.c: Revert previous change because it breaks the
 	  dead-end handling.
 
-2011-08-03 [r818]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-08-03 [r818]  Andrew M. Bishop <amb>
 
 	* src/router.c: Find a valid route if the start and end point are
 	  the same location (it doesn't require a U-turn).
 
-2011-08-03 [r817]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-08-03 [r817]  Andrew M. Bishop <amb>
 
 	* src/optimiser.c, src/router.c: Add a new (less confusing) error
 	  message for when the start of the route has no super-nodes and
 	  doesn't include the end node and make clearer the error message
 	  when the combining of routes fails.
 
-2011-08-03 [r816]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-08-03 [r816]  Andrew M. Bishop <amb>
 
 	* src/nodes.c: Make more checks on the closest segment to avoid
 	  choosing one that our profile does not allow us to use.
 
-2011-08-02 [r815]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-08-02 [r815]  Andrew M. Bishop <amb>
 
 	* src/optimiser.c: Handle the case where the start node is a
 	  super-node and there is no previous segment.
 
-2011-06-26  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-06-26  Andrew M. Bishop <amb>
 
 	Version 2.0.2 released
 
-2011-06-26 [r800-r801]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-06-26 [r800-r801]  Andrew M. Bishop <amb>
 
 	* doc/README.txt, doc/html/readme.html: Update for version 2.0.2.
 
 	* doc/NEWS.txt, FILES, doc/html/readme.html: Update for version
 	  2.0.2.
 
-2011-06-25 [r798-799]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-06-25 [r798-799]  Andrew M. Bishop <amb>
 
 	* src/results.c: Fix comment associated with results list memory
 	  handling.
 
 	* src/optimiser.c: Free temporary results that are calculated.
 
-2011-06-25 [r795-797]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-06-25 [r795-797]  Andrew M. Bishop <amb>
 
 	* src/tagging.h, src/planetsplitter.c, src/tagging.c: Add some
 	  functions to free the tagging rules when they have been used.
@@ -4717,12 +5671,12 @@
 
 	* src/nodesx.c: Free some memory allocated when writing the file.
 
-2011-06-19 [r794]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-06-19 [r794]  Andrew M. Bishop <amb>
 
 	* src/tagmodifier.c: Change to unsigned long and ensure that printf
 	  format specifiers are correct.
 
-2011-06-19 [r792-793]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-06-19 [r792-793]  Andrew M. Bishop <amb>
 
 	* src/segmentsx.c: If a node has no segments return a NULL pointer
 	  rather than random junk.
@@ -4730,14 +5684,14 @@
 	* xml/routino-tagging.xml: Reinstate the line that makes
 	  roundabouts one-way.
 
-2011-06-18 [r791]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-06-18 [r791]  Andrew M. Bishop <amb>
 
 	* src/osmparser.c, src/xmlparse.h, src/xmlparse.l: Don't use the
 	  flex yylineno but keep track with an unsigned long long line
 	  counter instead (if there are more than 2^31 nodes then there are
 	  more than 2^31 lines as well).
 
-2011-06-18 [r790]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-06-18 [r790]  Andrew M. Bishop <amb>
 
 	* src/superx.c, src/relationsx.c, src/types.h, src/osmparser.c,
 	  src/waysx.c, src/filedumper.c, src/segmentsx.c, src/nodesx.c,
@@ -4745,7 +5699,7 @@
 	  the index_t type that an appropriate printf format specifier is
 	  used (ready for if it is redefined as 64-bit).
 
-2011-06-18 [r788-789]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-06-18 [r788-789]  Andrew M. Bishop <amb>
 
 	* src/Makefile: Use the -std=c99 option by default.
 
@@ -4753,38 +5707,38 @@
 	  src/segmentsx.h: Fix some more warnings from -Wextra and/or
 	  -pedantic options.
 
-2011-06-18 [r787]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-06-18 [r787]  Andrew M. Bishop <amb>
 
 	* src/xmlparse.l: Use flex %options instead of #defines, force
 	  clean compilation with C99.
 
-2011-06-18 [r786]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-06-18 [r786]  Andrew M. Bishop <amb>
 
 	* src/relationsx.c, src/relationsx.h: Rename structure element
 	  "restrict" to "restriction" to avoid C99 error (reserved word).
 
-2011-06-18 [r785]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-06-18 [r785]  Andrew M. Bishop <amb>
 
 	* src/superx.c: Removed warning from gcc-4.6.
 
-2011-06-14 [r784]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-06-14 [r784]  Andrew M. Bishop <amb>
 
 	* xml/routino-tagging.xml: Fix error with handling ferry routes
 	  (patch from Michael Günnewig).
 
-2011-06-07  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-06-07  Andrew M. Bishop <amb>
 
 	Version 2.0.1 released
 
-2011-06-07 [r782]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-06-07 [r782]  Andrew M. Bishop <amb>
 
 	* doc/html/readme.html: Update for version 2.0.1.
 
-2011-06-07 [r781]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-06-07 [r781]  Andrew M. Bishop <amb>
 
 	* doc/NEWS.txt, doc/README.txt, FILES: Update for version 2.0.1.
 
-2011-06-05 [r779-780]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-06-05 [r779-780]  Andrew M. Bishop <amb>
 
 	* src/superx.c, src/visualiser.c, src/nodes.c, src/relationsx.c,
 	  src/waysx.c, src/filedumper.c, src/segmentsx.c, src/nodesx.c,
@@ -4795,7 +5749,7 @@
 	  bin types and a new type for latitude/longitude bins (two
 	  dimensions).
 
-2011-06-05 [r777-778]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-06-05 [r777-778]  Andrew M. Bishop <amb>
 
 	* src/profiles.c: Change unsigned int to int for consistency with
 	  the rest of the code.
@@ -4803,11 +5757,11 @@
 	* src/optimiser.c: Remove unused variable (hangover from previous
 	  U-turn searching).
 
-2011-06-04 [r776]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-06-04 [r776]  Andrew M. Bishop <amb>
 
 	* src/superx.c, src/osmparser.c: Add missing header file.
 
-2011-06-04 [r773-775]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-06-04 [r773-775]  Andrew M. Bishop <amb>
 
 	* src/osmparser.c: Convert integer and floating point values
 	  inline. Check that node, way and relation IDs don't need to be
@@ -4820,7 +5774,7 @@
 	  XMLPARSE_ASSERT_(INTEGER|FLOATING) functions now don't return the
 	  converted type.
 
-2011-06-04 [r770-772]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-06-04 [r770-772]  Andrew M. Bishop <amb>
 
 	* src/segments.h: Add a type cast to a macro.
 
@@ -4830,12 +5784,12 @@
 	* src/relationsx.c, src/segmentsx.c: Fix some more potential
 	  problems with a transition to 64-bit node_t.
 
-2011-06-03 [r761]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-06-03 [r761]  Andrew M. Bishop <amb>
 
 	* src/superx.c, src/relationsx.c, src/segmentsx.c: Shorten the
 	  messages when running to avoid going beyond 80 characters.
 
-2011-06-03 [r759-760]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-06-03 [r759-760]  Andrew M. Bishop <amb>
 
 	* src/visualiser.c: Remove hard-coded numeric value and replace
 	  with a #define value.
@@ -4844,75 +5798,75 @@
 	  Remove hard-coded numeric values and replace with a common
 	  #define value. Handle overflows consistently.
 
-2011-06-03 [r758]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-06-03 [r758]  Andrew M. Bishop <amb>
 
 	* src/nodesx.h, src/typesx.h: Move some macros from nodesx.h to
 	  typesx.h.
 
-2011-06-03 [r757]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-06-03 [r757]  Andrew M. Bishop <amb>
 
 	* src/relationsx.c, src/tagmodifier.c, src/optimiser.c,
 	  src/osmparser.c, src/waysx.c: Rationalise the increment of the
 	  numbers used for the output when not --loggable.
 
-2011-06-01 [r756]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-06-01 [r756]  Andrew M. Bishop <amb>
 
 	* src/relationsx.c: Delete turn relations that refer to nodes or
 	  ways that don't exist as soon as possible.
 
-2011-05-31 [r755]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-05-31 [r755]  Andrew M. Bishop <amb>
 
 	* src/nodesx.h, src/osmparser.c, src/segmentsx.c, src/waysx.h,
 	  src/typesx.h: Fix some obvious problems with a transition to
 	  64-bit node_t.
 
-2011-05-31 [r754]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-05-31 [r754]  Andrew M. Bishop <amb>
 
 	* src/tagging.c, src/translations.c, src/profiles.c: Fix
 	  inconsistent C language version usage.
 
-2011-05-30 Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-05-30 Andrew M. Bishop <amb>
 
 	Version 2.0 released
 
-2011-05-30 [r742]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-05-30 [r742]  Andrew M. Bishop <amb>
 
 	* src/relationsx.c: Don't crash on malformed relations, give better
 	  reporting of number when processing them.
 
-2011-05-30 [r741]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-05-30 [r741]  Andrew M. Bishop <amb>
 
 	* FILES: Update for release.
 
-2011-05-30 [r740]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-05-30 [r740]  Andrew M. Bishop <amb>
 
 	* src/segmentsx.c: Fix spelling mistake in function parameter
 	  comment.
 
-2011-05-30 [r738-739]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-05-30 [r738-739]  Andrew M. Bishop <amb>
 
 	* src/test/Makefile: Make sure that clean really means it.
 
 	* doc/NEWS.txt, doc/README.txt, doc/html/readme.html: Update for
 	  version 2.0 release.
 
-2011-05-30 [r737]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-05-30 [r737]  Andrew M. Bishop <amb>
 
 	* doc/html/usage.html, doc/html/algorithm.html, doc/TAGGING.txt,
 	  doc/html/index.html, doc/html/data.html, doc/USAGE.txt,
 	  doc/ALGORITHM.txt, doc/DATA.txt, doc/html/tagging.html: Run a
 	  spelling check on the documentation.
 
-2011-05-30 [r736]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-05-30 [r736]  Andrew M. Bishop <amb>
 
 	* doc/html/algorithm.html: Describe new philosophy of alloing
 	  U-turn at waypoints to avoid dead-ends.
 
-2011-05-30 [r735]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-05-30 [r735]  Andrew M. Bishop <amb>
 
 	* src/optimiser.c: Fix problem with test case loops WP11.
 
-2011-05-30 [r734]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-05-30 [r734]  Andrew M. Bishop <amb>
 
 	* src/optimiser.c, src/functions.h, src/router.c: Change the
 	  philosophy on dead ends so that now a U-turn is made at the
@@ -4920,7 +5874,7 @@
 	  a dead-end. This simplifies the algorithm and removes a lot of
 	  special case handling.
 
-2011-05-30 [r731-733]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-05-30 [r731-733]  Andrew M. Bishop <amb>
 
 	* src/test/loops.osm: Give the loops unique names.
 
@@ -4930,16 +5884,16 @@
 	* src/fakes.c: Fix error with calculating length of fake segment
 	  and optimise the ExtraFakeSegment function.
 
-2011-05-29 [r730]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-05-29 [r730]  Andrew M. Bishop <amb>
 
 	* src/test/a-b-c.sh: Exit on error.
 
-2011-05-21 [r729]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-05-21 [r729]  Andrew M. Bishop <amb>
 
 	* src/optimiser.c, src/functions.h, src/router.c: Find all routes
 	  in the no-super.osm test case.
 
-2011-05-20 [r727-728]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-05-20 [r727-728]  Andrew M. Bishop <amb>
 
 	* src/test/no-super.osm: Add new test cases for fake
 	  nodes/segments.
@@ -4948,7 +5902,7 @@
 	  to handle the detection of U-turns between two fake segments that
 	  sit on the same real segment.
 
-2011-05-18 [r725-726]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-05-18 [r725-726]  Andrew M. Bishop <amb>
 
 	* src/test/a-b-c.sh (added), src/test, src/test/no-super.sh
 	  (added), src/test/no-super.osm (added): Add new test cases for
@@ -4957,12 +5911,12 @@
 	* src/fakes.c: Fix routing between two fake nodes on the same
 	  segment (again).
 
-2011-05-18 [r724]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-05-18 [r724]  Andrew M. Bishop <amb>
 
 	* src/test/dead-ends.osm: Add a new waypoint at the very end of a
 	  dead-end (not super-node).
 
-2011-05-18 [r722-723]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-05-18 [r722-723]  Andrew M. Bishop <amb>
 
 	* src/optimiser.c, src/functions.h: Remove the override flag from
 	  FindNormalRoute().
@@ -4971,40 +5925,40 @@
 	  of the route as the start of the combined route (since it may
 	  have special override segments in it).
 
-2011-05-17 [r721]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-05-17 [r721]  Andrew M. Bishop <amb>
 
 	* src/optimiser.c, src/functions.h, src/router.c: Change the order
 	  of the arguments to the routing functions (move profile earlier).
 
-2011-05-17 [r720]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-05-17 [r720]  Andrew M. Bishop <amb>
 
 	* doc/Makefile: Install the license file in the doc directory.
 
-2011-05-15 [r719]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-05-15 [r719]  Andrew M. Bishop <amb>
 
 	* src/optimiser.c, src/router.c: Finally find a way out of
 	  dead-ends, might have some nasty side-effects though.
 
-2011-05-14 [r717-718]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-05-14 [r717-718]  Andrew M. Bishop <amb>
 
 	* src/optimiser.c: Fix slim/non-slim variation.
 
 	* src/test/dead-ends.osm: Add another waypoint at the terminal
 	  super-node.
 
-2011-05-13 [r716]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-05-13 [r716]  Andrew M. Bishop <amb>
 
 	* src/test/turns.osm: Force waypoint 13 to go round the roundabout
 	  twice.
 
-2011-05-12 [r714-715]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-05-12 [r714-715]  Andrew M. Bishop <amb>
 
 	* src/test/turns.osm (added), src/test, src/test/turns.sh (added):
 	  Added turn restriction test cases.
 
 	* src/test/start-1-finish.sh: Bug fix for logging.
 
-2011-05-11 [r712-713]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-05-11 [r712-713]  Andrew M. Bishop <amb>
 
 	* src/superx.c, src/segmentsx.c: Add comments to assert statements
 	  that don't already have them.
@@ -5012,7 +5966,7 @@
 	* src/optimiser.c: Crash out if infinite loop (usually caused by a
 	  bug elsewhere).
 
-2011-05-08 [r708-711]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-05-08 [r708-711]  Andrew M. Bishop <amb>
 
 	* src/test/start-1-finish.sh: Run filedumper, allow running under a
 	  run-time debugger.
@@ -5025,34 +5979,34 @@
 	* src/segments.c, src/segments.h: Make the NextSegment function
 	  inline (move from segments.c to segments.h).
 
-2011-05-08 [r707]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-05-08 [r707]  Andrew M. Bishop <amb>
 
 	* src/segments.c, src/visualiser.c, src/nodes.c, src/optimiser.c,
 	  src/filedumper.c, src/nodes.h, src/output.c: The FirstSegment
 	  function now takes a cache position argument.
 
-2011-05-08 [r706]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-05-08 [r706]  Andrew M. Bishop <amb>
 
 	* src/segments.c, src/nodes.c, src/relations.c, src/ways.c: Ensure
 	  that the correct number of cached nodes, segments, ways or
 	  relations are initialised.
 
-2011-05-08 [r705]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-05-08 [r705]  Andrew M. Bishop <amb>
 
 	* src/ways.h, src/filedumper.c, src/ways.c: Remove the unused name
 	  caching for the ways (in slim mode).
 
-2011-05-08 [r704]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-05-08 [r704]  Andrew M. Bishop <amb>
 
 	* src/segments.h, src/segmentsx.h: Simplify the lookup of the
 	  segment index in slim mode.
 
-2011-05-07 [r703]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-05-07 [r703]  Andrew M. Bishop <amb>
 
 	* src/optimiser.c: Allow the start of a route to double-back to the
 	  initial node even if a super-node.
 
-2011-05-07 [r700-702]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-05-07 [r700-702]  Andrew M. Bishop <amb>
 
 	* src/test/loops.osm: Rename the waypoints.
 
@@ -5061,7 +6015,7 @@
 	* src/optimiser.c, src/nodes.h, src/segmentsx.c: Fix bugs found by
 	  valgrind.
 
-2011-05-07 [r697-699]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-05-07 [r697-699]  Andrew M. Bishop <amb>
 
 	* src/optimiser.c: Handle things correctly if the
 	  FindSuperSegment() function is called with a fake segment.
@@ -5071,7 +6025,7 @@
 
 	* src/Makefile: Require slim and non-slim versions of fakes.o.
 
-2011-05-07 [r695-696]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-05-07 [r695-696]  Andrew M. Bishop <amb>
 
 	* src/router.c: Calculate an override version of the start of the
 	  route to get out of dead-ends.
@@ -5079,7 +6033,7 @@
 	* src/output.c: Use real segments when making comparisons (not
 	  pointers or non-real segments).
 
-2011-05-06 [r690-694]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-05-06 [r690-694]  Andrew M. Bishop <amb>
 
 	* src/test: Ignore files and directories generated by running 'make
 	  test'.
@@ -5095,18 +6049,18 @@
 
 	* src/test (added): A directory for routing test cases.
 
-2011-05-06 [r689]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-05-06 [r689]  Andrew M. Bishop <amb>
 
 	* src/xml/test/bad-attr-character-ref.xml (removed): Remove
 	  false-positive test case (a bug in xmlparse.l previously flagged
 	  this as an error).
 
-2011-04-27 [r688]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-04-27 [r688]  Andrew M. Bishop <amb>
 
 	* src/optimiser.c: Force going straight on if a waypoint is a
 	  super-node.
 
-2011-04-27 [r686-687]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-04-27 [r686-687]  Andrew M. Bishop <amb>
 
 	* src/optimiser.c: Improve the FindSuperSegment() function when the
 	  existing segment is the right answer.
@@ -5114,24 +6068,24 @@
 	* src/optimiser.c, src/router.c: Rename the variables in and around
 	  the CombineRoutes() function for clarity.
 
-2011-04-26 [r685]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-04-26 [r685]  Andrew M. Bishop <amb>
 
 	* src/optimiser.c: When starting a super-route ensure that all
 	  starting segments are super-segments to avoid u-turns at the
 	  starting super-node.
 
-2011-04-25 [r683-684]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-04-25 [r683-684]  Andrew M. Bishop <amb>
 
 	* src/output.c: Fix error with turn description.
 
 	* src/output.c: Include a point number (hidden) in the HTML file.
 
-2011-04-24 [r682]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-04-24 [r682]  Andrew M. Bishop <amb>
 
 	* src/waysx.c, src/waysx.h: Fix error is last semi-automated
 	  update.
 
-2011-04-24 [r681]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-04-24 [r681]  Andrew M. Bishop <amb>
 
 	* src/segments.c, src/superx.c, src/visualiser.c, src/relationsx.c,
 	  src/segments.h, src/superx.h, src/filedumper.c, src/nodesx.c,
@@ -5139,7 +6093,7 @@
 	  src/waysx.c, src/nodes.h, src/segmentsx.c, src/waysx.h,
 	  src/segmentsx.h, src/ways.c: Make the comments more consistent.
 
-2011-04-24 [r680]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-04-24 [r680]  Andrew M. Bishop <amb>
 
 	* src/translations.h, src/fakes.c, src/filedumper.c, src/fakes.h,
 	  src/nodesx.c, src/output.c, src/results.c, src/files.c,
@@ -5154,59 +6108,59 @@
 	  src/segmentsx.c, src/functions.h, src/waysx.h, src/router.c,
 	  src/segmentsx.h: Update comments throughout the source code.
 
-2011-04-23 [r679]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-04-23 [r679]  Andrew M. Bishop <amb>
 
 	* doc/html/algorithm.html, doc/ALGORITHM.txt: Add description of
 	  U-turns at dead-ends.
 
-2011-04-23 [r678]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-04-23 [r678]  Andrew M. Bishop <amb>
 
 	* src/optimiser.c, src/functions.h, src/output.c, src/router.c:
 	  Allow U-turns at dead-ends to avoid getting stuck.
 
-2011-04-22 [r677]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-04-22 [r677]  Andrew M. Bishop <amb>
 
 	* src/optimiser.c, src/router.c: Handle failure to find route
 	  gracefully.
 
-2011-04-22 [r676]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-04-22 [r676]  Andrew M. Bishop <amb>
 
 	* web/www/routino/visualiser.cgi: Another change related to turn
 	  restrictions (missed in last checkin).
 
-2011-04-22 [r675]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-04-22 [r675]  Andrew M. Bishop <amb>
 
 	* src/segments.c, doc/html/usage.html, web/www/routino/router.cgi,
 	  src/segments.h, doc/USAGE.txt, src/router.c: Add in the option to
 	  specify an initial heading.
 
-2011-04-22 [r674]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-04-22 [r674]  Andrew M. Bishop <amb>
 
 	* src/segmentsx.c, src/nodesx.c: Finish off the geographic sorting
 	  of segments.
 
-2011-04-22 [r673]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-04-22 [r673]  Andrew M. Bishop <amb>
 
 	* src/filedumper.c: Use the common TurnAngle() function from
 	  segments.c instead of a local one.
 
-2011-04-22 [r672]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-04-22 [r672]  Andrew M. Bishop <amb>
 
 	* src/segments.c, src/segments.h, src/output.c: Move the
 	  turn_angle() and bearing_angle() functions from output.c into
 	  segments.c.
 
-2011-04-22 [r671]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-04-22 [r671]  Andrew M. Bishop <amb>
 
 	* doc/html/algorithm.html, doc/ALGORITHM.txt: Simplify the language
 	  used describing the highway properties.
 
-2011-03-21 [r670]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-03-21 [r670]  Andrew M. Bishop <amb>
 
 	* src/relationsx.c: Ignore turn restrictions that ban going the
 	  wrong way down a one-way road.
 
-2011-03-21 [r668-669]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-03-21 [r668-669]  Andrew M. Bishop <amb>
 
 	* src/segments.c, src/filedumper.c, src/profiles.c: Include math.h
 	  for files that use math functions.
@@ -5214,26 +6168,26 @@
 	* src/types.h: Round the node latitude/longitude rather than
 	  truncating.
 
-2011-03-21 [r667]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-03-21 [r667]  Andrew M. Bishop <amb>
 
 	* src/filedumper.c: Include some of the Routino internal
 	  information when dumping an OSM format output.
 
-2011-03-21 [r666]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-03-21 [r666]  Andrew M. Bishop <amb>
 
 	* src/segmentsx.c: Fix bug with segment deduplication.
 
-2011-03-21 [r665]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-03-21 [r665]  Andrew M. Bishop <amb>
 
 	* src/relationsx.c, src/planetsplitter.c, src/relationsx.h,
 	  src/nodesx.c: Sort the segments geographically.
 
-2011-03-20 [r664]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-03-20 [r664]  Andrew M. Bishop <amb>
 
 	* src/nodesx.c: Sort nodes strictly by latitude/longitude within
 	  the bins (helps with regresssion testing).
 
-2011-03-20 [r661-663]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-03-20 [r661-663]  Andrew M. Bishop <amb>
 
 	* web/www/routino/documentation: Ignore extra image files.
 
@@ -5242,79 +6196,79 @@
 
 	* src/router.c: Fix bug found by gcc-4.5.
 
-2011-03-20 [r660]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-03-20 [r660]  Andrew M. Bishop <amb>
 
 	* src/segmentsx.c: Return early from the IndexSegments function if
 	  there are no segments.
 
-2011-03-19 [r659]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-03-19 [r659]  Andrew M. Bishop <amb>
 
 	* doc/html/algorithm.html, doc/html/example0.png,
 	  doc/html/example1.png, doc/ALGORITHM.txt, doc/html/example2.png,
 	  doc/html/example3.png (added), doc/html/example4.png (added):
 	  Update the algorithm documents for turn restrictions.
 
-2011-03-19 [r658]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-03-19 [r658]  Andrew M. Bishop <amb>
 
 	* src/segmentsx.c: Deduplicate in pairs only (i.e. if a segment
 	  occurs 4 times then keep 2 of them).
 
-2011-03-19 [r657]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-03-19 [r657]  Andrew M. Bishop <amb>
 
 	* src/segmentsx.c: Cache the recently used ways when de-duplicating
 	  segments.
 
-2011-03-19 [r656]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-03-19 [r656]  Andrew M. Bishop <amb>
 
 	* src/superx.c: Use previous segment in router rather than looking
 	  at previous node.
 
-2011-03-12 [r655]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-03-12 [r655]  Andrew M. Bishop <amb>
 
 	* src/segmentsx.c, src/nodesx.c: Make the used nodes marker
 	  bit-wide rather than byte-wide.
 
-2011-03-12 [r654]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-03-12 [r654]  Andrew M. Bishop <amb>
 
 	* src/nodesx.h, src/superx.c, src/nodesx.c: Make the nodes super
 	  marker bit-wide rather than byte-wide.
 
-2011-03-12 [r653]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-03-12 [r653]  Andrew M. Bishop <amb>
 
 	* src/nodesx.h, src/superx.c, src/planetsplitter.c, src/superx.h,
 	  src/nodesx.c: Make the nodes super marker a boolean.
 
-2011-03-12 [r652]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-03-12 [r652]  Andrew M. Bishop <amb>
 
 	* src/superx.c, src/planetsplitter.c, src/superx.h: Optimise the
 	  search for supernodes, consider traffic when counting segments
 	  that meet at a node.
 
-2011-02-27 [r651]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-02-27 [r651]  Andrew M. Bishop <amb>
 
 	* src/nodesx.h, src/superx.c, src/relationsx.c, src/waysx.c,
 	  src/segmentsx.c, src/waysx.h, src/segmentsx.h: Rename the xdata
 	  and xcached members of the nodesx, segmentsx and waysx
 	  structures.
 
-2011-02-27 [r650]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-02-27 [r650]  Andrew M. Bishop <amb>
 
 	* src/nodesx.h, src/relationsx.c, src/planetsplitter.c,
 	  src/waysx.c, src/relationsx.h, src/segmentsx.c, src/nodesx.c,
 	  src/waysx.h, src/segmentsx.h: Don't have both xnumber and number
 	  in the nodesx, segmentsx, waysx and relationsx structures.
 
-2011-02-27 [r649]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-02-27 [r649]  Andrew M. Bishop <amb>
 
 	* src/segmentsx.c, src/segmentsx.h: Remove a now unused array of
 	  segment indexes.
 
-2011-02-27 [r648]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-02-27 [r648]  Andrew M. Bishop <amb>
 
 	* src/logging.c: Handle the case where the middle string is shorter
 	  than the previous one.
 
-2011-02-26 [r646-647]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-02-26 [r646-647]  Andrew M. Bishop <amb>
 
 	* src/superx.c: Use the OtherNode and IsOneWay* macros when
 	  routing.
@@ -5323,17 +6277,17 @@
 	  Remove a pair of functions that are no longer used and rename the
 	  other pair.
 
-2011-02-26 [r645]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-02-26 [r645]  Andrew M. Bishop <amb>
 
 	* src/relationsx.c, src/planetsplitter.c, src/relationsx.h: Fixed
 	  the turn relations with a few more functions.
 
-2011-02-26 [r644]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-02-26 [r644]  Andrew M. Bishop <amb>
 
 	* src/planetsplitter.c, src/segmentsx.c, src/segmentsx.h: Renamed a
 	  couple of functions for clarity.
 
-2011-02-26 [r643]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-02-26 [r643]  Andrew M. Bishop <amb>
 
 	* src/nodesx.h, src/superx.c, src/relationsx.c,
 	  src/planetsplitter.c, src/osmparser.c, src/segmentsx.c,
@@ -5346,43 +6300,43 @@
 	  super-node/segment optimisation doesn't remove mutual loops. This
 	  change doesn't handle turn restrictions yet.
 
-2011-02-24 [r642]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-02-24 [r642]  Andrew M. Bishop <amb>
 
 	* src/superx.c: Change a variable name to match the one used in
 	  optimiser.c.
 
-2011-02-24 [r641]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-02-24 [r641]  Andrew M. Bishop <amb>
 
 	* src/superx.c, src/segmentsx.c: Create super-segments that go in
 	  loops and preserve all such loops.
 
-2011-02-23 [r640]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-02-23 [r640]  Andrew M. Bishop <amb>
 
 	* src/segmentsx.c: Fix latent bug that can occur when
 	  de-duplicating segments.
 
-2011-02-23 [r639]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-02-23 [r639]  Andrew M. Bishop <amb>
 
 	* xml/Makefile: Fix error in creating web files containing
 	  profiles.
 
-2011-02-20 [r638]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-02-20 [r638]  Andrew M. Bishop <amb>
 
 	* src/optimiser.c: Allow U-turns at via points for transport types
 	  that ignore turn restrictions.
 
-2011-02-20 [r637]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-02-20 [r637]  Andrew M. Bishop <amb>
 
 	* src/optimiser.c, src/functions.h, src/fakes.h: Don't allow
 	  U-turns at via points (but doesn't necessarily include turning
 	  round in the score when searching for optimum).
 
-2011-02-18 [r636]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-02-18 [r636]  Andrew M. Bishop <amb>
 
 	* src/optimiser.c: Fix the code that stops routes doubling-back on
 	  themselves.
 
-2011-02-11 [r635]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-02-11 [r635]  Andrew M. Bishop <amb>
 
 	* web/www/routino/update-profiles.pl (added), xml/Makefile,
 	  web/www/routino, web/www/routino/router.html.en,
@@ -5390,23 +6344,23 @@
 	  web/www/routino/router.js: Move the Javascript and Perl profiles
 	  into separate files.
 
-2011-02-11 [r634]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-02-11 [r634]  Andrew M. Bishop <amb>
 
 	* doc/html/installation.html, web/www/openlayers/install.sh,
 	  doc/INSTALL.txt: Change to OpenLayers 2.10.
 
-2011-02-11 [r632-633]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-02-11 [r632-633]  Andrew M. Bishop <amb>
 
 	* src/output.c: Don't confuse fake segments with junctions.
 
 	* src/optimiser.c: Fix problem with only one super-node in the
 	  route.
 
-2011-02-11 [r631]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-02-11 [r631]  Andrew M. Bishop <amb>
 
 	* src/fakes.c: Fix bug with generating fake segments.
 
-2011-02-11 [r629-630]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-02-11 [r629-630]  Andrew M. Bishop <amb>
 
 	* xml/routino-profiles.xml: Wheelchairs do not obey turn
 	  restrictions.
@@ -5417,23 +6371,23 @@
 	  a message if routed OK, allow web users to see router output (now
 	  logged to file).
 
-2011-02-05 [r628]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-02-05 [r628]  Andrew M. Bishop <amb>
 
 	* src/filedumper.c: Fix statistics for ways (broken by change for
 	  relations).
 
-2011-02-05 [r626-627]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-02-05 [r626-627]  Andrew M. Bishop <amb>
 
 	* src/superx.c, src/optimiser.c, src/segmentsx.c, src/nodesx.c:
 	  Change some output printed while running.
 
 	* src/filedumper.c: Fix problem with dumping turn relations.
 
-2011-02-05 [r625]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-02-05 [r625]  Andrew M. Bishop <amb>
 
 	* src/filedumper.c: Print out the size of the relations.mem file.
 
-2011-02-05 [r623-624]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-02-05 [r623-624]  Andrew M. Bishop <amb>
 
 	* web/www/routino/visualiser.cgi: Updated the visualiser to include
 	  turn restrictions.
@@ -5443,7 +6397,7 @@
 	  src/filedumper.c, doc/USAGE.txt, web/www/routino/visualiser.html:
 	  Updated the visualiser to include turn restrictions.
 
-2011-02-05 [r622]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-02-05 [r622]  Andrew M. Bishop <amb>
 
 	* src/profiles.h, web/www/routino/noscript.cgi,
 	  web/www/routino/customrouter.cgi, xml/routino-profiles.xsd,
@@ -5455,7 +6409,7 @@
 	  Include the option to obey turn restrictions in the profile for
 	  each transport type.
 
-2011-01-30 [r620-621]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-01-30 [r620-621]  Andrew M. Bishop <amb>
 
 	* doc/html/algorithm.html, doc/ALGORITHM.txt: Update algorithm
 	  description to include turn restrictions and a note about how the
@@ -5464,71 +6418,71 @@
 	* doc/TAGGING.txt, doc/USAGE.txt: Update text versions of documents
 	  to match HTML.
 
-2011-01-30 [r618-619]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-01-30 [r618-619]  Andrew M. Bishop <amb>
 
 	* src/output.c: Correct comments.
 
 	* src/filedumper.c: Put a "restriction" tag into the turn
 	  restrictions when dumped.
 
-2011-01-30 [r617]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-01-30 [r617]  Andrew M. Bishop <amb>
 
 	* src/optimiser.c, src/functions.h, src/router.c: Ensure that the
 	  first/last node and first/last segment of the Results structure
 	  are filled in properly.
 
-2011-01-30 [r616]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-01-30 [r616]  Andrew M. Bishop <amb>
 
 	* src/optimiser.c: Fix routing where the final node is a
 	  super-node.
 
-2011-01-29 [r615]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-01-29 [r615]  Andrew M. Bishop <amb>
 
 	* src/relationsx.c: All nodes adjacent to a turn restriction must
 	  also be turn restrictions.
 
-2011-01-29 [r613-614]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-01-29 [r613-614]  Andrew M. Bishop <amb>
 
 	* src/files.h: Fix assert problem.
 
 	* src/Makefile, src/xml/Makefile: Make dependency filename based on
 	  object file name (fixes overwriting problem with slim versions).
 
-2011-01-29 [r612]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-01-29 [r612]  Andrew M. Bishop <amb>
 
 	* src/superx.c, src/files.h, src/relationsx.c, src/waysx.c,
 	  src/segmentsx.c, src/nodesx.c, src/files.c: Ensure that record of
 	  closed file descriptors are erased.
 
-2011-01-29 [r610-611]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-01-29 [r610-611]  Andrew M. Bishop <amb>
 
 	* src/optimiser.c: Don't check for turn relations in
 	  FindStartRoutes().
 
 	* src/optimiser.c: Add some comments, shuffle a few lines of code.
 
-2011-01-29 [r609]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-01-29 [r609]  Andrew M. Bishop <amb>
 
 	* src/optimiser.c: Fix the code that allows overshooting by one
 	  node when finding finish nodes.
 
-2011-01-29 [r608]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-01-29 [r608]  Andrew M. Bishop <amb>
 
 	* src/fakes.c, src/optimiser.c, src/Makefile, src/fakes.h,
 	  src/relations.c, src/router.c: When finding a normal route check
 	  for turn relations (considering previous segment). When finding
 	  turn relations convert fake segments into real ones.
 
-2011-01-29 [r607]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-01-29 [r607]  Andrew M. Bishop <amb>
 
 	* src/nodes.c: Fix pathological case of rounding error for points
 	  almost exactly on a segment.
 
-2011-01-29 [r606]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-01-29 [r606]  Andrew M. Bishop <amb>
 
 	* src/superx.c: Fix for route finding in planetsplitter.
 
-2011-01-24 [r605]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-01-24 [r605]  Andrew M. Bishop <amb>
 
 	* src/results.h, src/superx.c, src/optimiser.c, src/functions.h,
 	  src/output.c, src/router.c, src/results.c: Finds routes and obeys
@@ -5536,23 +6490,23 @@
 	  restrictions, more turn restriction testing and regression
 	  testing required).
 
-2011-01-16 [r604]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-01-16 [r604]  Andrew M. Bishop <amb>
 
 	* src/relations.h, src/relations.c: Fix logic error with searching
 	  for via nodes.
 
-2011-01-15 [r603]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-01-15 [r603]  Andrew M. Bishop <amb>
 
 	* src/results.h, src/superx.c, src/optimiser.c, src/output.c,
 	  src/results.c: Change the results structure to contain next
 	  segment and rename elements to clarify prev/next node and
 	  prev/next segment.
 
-2011-01-15 [r602]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-01-15 [r602]  Andrew M. Bishop <amb>
 
 	* src/segmentsx.c: Change to comment for clarification.
 
-2011-01-15 [r599-601]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-01-15 [r599-601]  Andrew M. Bishop <amb>
 
 	* doc/html/usage.html: Correction and clarification to filedumper
 	  usage.
@@ -5564,53 +6518,53 @@
 	  'from' and 'to' segments and not nodes (to handle fake nodes
 	  inserted in segments).
 
-2011-01-15 [r598]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-01-15 [r598]  Andrew M. Bishop <amb>
 
 	* src/visualiser.c, src/output.c: Change the IsSuperNode() macro to
 	  take a single pointer argument.
 
-2011-01-09 [r597]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-01-09 [r597]  Andrew M. Bishop <amb>
 
 	* src/superx.c, src/relationsx.c, src/types.h: Make the 'from' and
 	  'to' nodes of turn restrictions super-nodes.
 
-2011-01-09 [r596]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-01-09 [r596]  Andrew M. Bishop <amb>
 
 	* src/relations.h, src/optimiser.c, src/nodes.h, src/relations.c:
 	  Check turn relations when finding a route.
 
-2011-01-08 [r595]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-01-08 [r595]  Andrew M. Bishop <amb>
 
 	* src/optimiser.c, src/filedumper.c, src/nodes.h: Change the
 	  IsSuperNode() macro to take a single pointer argument.
 
-2011-01-08 [r594]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-01-08 [r594]  Andrew M. Bishop <amb>
 
 	* src/optimiser.c: Move the local variables closer to where they
 	  are used.
 
-2011-01-08 [r593]  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2011-01-08 [r593]  Andrew M. Bishop <amb>
 
 	* doc/html/tagging.html: Add information about the tags used for
 	  turn relations.
 
-2010-12-29  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2010-12-29  Andrew M. Bishop <amb>
 
 	Changed version control environment from RCS to CVS to SVN.
 
-2010-12-29  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2010-12-29  Andrew M. Bishop <amb>
 
 	* doc/NEWS.txt: Temporary checkin to allow transition from RCS to
 	  CVS to SVN.
 
 	* xml/routino-tagging.xml: Pass through turn relation information.
 
-2010-12-21  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2010-12-21  Andrew M. Bishop <amb>
 
 	* src/filedumper.c: Add turn relations to the statistics and dump
 	  outputs.
 
-2010-12-21  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2010-12-21  Andrew M. Bishop <amb>
 
 	* src/ways.h, src/segments.h, src/nodes.h, src/ways.c: Optimise the
 	  node, segment, way lookup in slim mode by checking if the
@@ -5619,12 +6573,12 @@
 	* src/relations.h, src/relations.c: Optimise the turn relation
 	  lookup.
 
-2010-12-21  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2010-12-21  Andrew M. Bishop <amb>
 
 	* src/relations.h, src/relations.c: Add functions to search for
 	  turn relations that match a particular node.
 
-2010-12-21  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2010-12-21  Andrew M. Bishop <amb>
 
 	* src/relations.h (added), src/relations.c (added): Initial
 	  revision
@@ -5632,13 +6586,13 @@
 	* src/superx.c, src/relationsx.c, src/types.h: Update the nodes to
 	  force a super-node where there is a turn restriction.
 
-2010-12-21  Andrew M. Bishop <amb at gedanken.demon.co.uk>
+2010-12-21  Andrew M. Bishop <amb>
 
 	* src/relationsx.c, src/planetsplitter.c, src/relationsx.h: Finish
 	  the processing of the turn relations now that the extra node
 	  lookup table is in place.
 
-2010-12-20  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2010-12-20  Andrew M. Bishop  <amb>
 
 	* src/nodesx.c, src/segmentsx.c, src/segmentsx.h:
 	Handle the SegmentX Segment in the same way as the other data structures (map
@@ -5668,7 +6622,7 @@
 	generate the Node from the NodeX when written to disk.  Create a lookup table
 	between the original index and the geographically sorted index.
 
-2010-12-19  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2010-12-19  Andrew M. Bishop  <amb>
 
 	* src/planetsplitter.c, src/relationsx.c:
 	Process the turn relations (apart from updating the indexes to the
@@ -5686,7 +6640,7 @@
 
 	* src/sorting.c: Bug fix for last change.
 
-2010-12-18  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2010-12-18  Andrew M. Bishop  <amb>
 
 	* src/segmentsx.c:
 	Remove the test for sorting zero segments (now that the sort function doesn't
@@ -5704,12 +6658,12 @@
 	in.  Still doesn't perform the required processing after reading the data or use
 	the information for routing.
 
-2010-12-12  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2010-12-12  Andrew M. Bishop  <amb>
 
 	* src/osmparser.c, src/typesx.h:
 	Change the names of the enumerated types for turn restrictions.
 
-2010-12-05  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2010-12-05  Andrew M. Bishop  <amb>
 
 	* src/osmparser.c, src/relationsx.c, src/relationsx.h, src/typesx.h:
 	Parse turn restriction relations and store ones with a single via node.
@@ -5718,12 +6672,12 @@
 	* src/nodesx.h, src/segmentsx.h, src/waysx.h:
 	Updated the comments for clarity.
 
-2010-12-04  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2010-12-04  Andrew M. Bishop  <amb>
 
 	* src/filedumper.c, src/nodesx.c, src/nodesx.h, src/osmparser.c, src/types.h:
 	Improved version of previous change.
 
-2010-11-28  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2010-11-28  Andrew M. Bishop  <amb>
 
 	* src/filedumper.c, src/nodesx.c, src/nodesx.h, src/osmparser.c, src/types.h:
 	Add parsing of mini-roundabouts.
@@ -5738,7 +6692,7 @@
 	* src/nodes.c:
 	Return the two nodes of a segment in the same order each time.
 
-2010-11-27  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2010-11-27  Andrew M. Bishop  <amb>
 
 	* src/fakes.h, src/sorting.h: New file.
 
@@ -5759,7 +6713,7 @@
 
 	* src/types.h, src/ways.h: Change the waytype_t type into highway_t.
 
-2010-11-14  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2010-11-14  Andrew M. Bishop  <amb>
 
 	* xml/routino-tagging.xml:
 	Fix mis-spelling with surface=asphalt tag (patch from Michael Günnewig).
@@ -5767,11 +6721,11 @@
 	* src/filedumper.c, src/types.c, src/types.h, src/ways.h, src/waysx.c:
 	Print out statistics about what highways are included in the database.
 
-2010-11-13  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2010-11-13  Andrew M. Bishop  <amb>
 
 	Version 1.5.1 released
 
-2010-11-13  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2010-11-13  Andrew M. Bishop  <amb>
 
 	* doc/NEWS.txt, doc/README.txt: Updated for version 1.5.1.
 
@@ -5791,20 +6745,20 @@
 	src/waysx.c:
 	Add an option to make the output more suitable for a log file.
 
-2010-10-31  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2010-10-31  Andrew M. Bishop  <amb>
 
 	* src/files.c:
 	Ensure that enough memory gets allocated in FileName() function.
 
-2010-10-30  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2010-10-30  Andrew M. Bishop  <amb>
 
 	Version 1.5 released
 
-2010-10-30  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2010-10-30  Andrew M. Bishop  <amb>
 
 	* doc/README.txt, doc/NEWS.txt: Updated for version 1.5.
 
-2010-10-18  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2010-10-18  Andrew M. Bishop  <amb>
 
 	* src/profiles.c:
 	Use sqrt() function to reduce the effect of property preferences close to 50%.
@@ -5817,11 +6771,11 @@
 	Add in the footroute and bicycleroute configuration options and route relation
 	tag processing.
 
-2010-10-16  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2010-10-16  Andrew M. Bishop  <amb>
 
 	* src/files.c: Fixed some comments for recent changes.
 
-2010-10-09  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2010-10-09  Andrew M. Bishop  <amb>
 
 	* xml/routino-profiles.xml:
 	Add footroute and bicycleroute to the profiles.
@@ -5835,7 +6789,7 @@
 
 	* src/xmlparse.l: Ensure that comparisons are made with unsigned chars.
 
-2010-10-03  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2010-10-03  Andrew M. Bishop  <amb>
 
 	* src/nodesx.c, src/relationsx.c, src/segmentsx.c, src/superx.c:
 	Don't try mapping a file if it is zero length (e.g. no super-segments).
@@ -5848,7 +6802,7 @@
 	Avoid self-recursion and adding route information to relations that already have
 	it.
 
-2010-09-25  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2010-09-25  Andrew M. Bishop  <amb>
 
 	* src/osmparser.c, src/relationsx.c, src/relationsx.h, src/waysx.h:
 	Apply the route=bicycle or route=foot tags from the relation to all ways
@@ -5861,7 +6815,7 @@
 	* src/nodesx.c, src/functions.h, src/sorting.c:
 	Rename the heapsort() function to filesort_heapsort().
 
-2010-09-19  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2010-09-19  Andrew M. Bishop  <amb>
 
 	* src/files.c, src/files.h, src/nodesx.c, src/segmentsx.c, src/sorting.c, src/waysx.c:
 	Change the names of the functions used to open files, change the ReOpen function
@@ -5869,7 +6823,7 @@
 
 	* src/relationsx.c: Remove the sorting of the route relations.
 
-2010-09-17  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2010-09-17  Andrew M. Bishop  <amb>
 
 	* src/nodesx.c, src/segmentsx.c:
 	Zero the NodesFile and SegmentsFile data structures before writing them (zeros
@@ -5893,12 +6847,12 @@
 	* xml/routino-tagging-nomodify.xml, xml/routino-tagging.xsd, src/tagging.c:
 	Process tags for relations.
 
-2010-09-16  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2010-09-16  Andrew M. Bishop  <amb>
 
 	* src/waysx.c, src/segmentsx.c, src/nodesx.c:
 	Fix the comment for the Append...() function.
 
-2010-09-15  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2010-09-15  Andrew M. Bishop  <amb>
 
 	* xml/routino-profiles.xml, xml/routino-tagging.xml, xml/routino-translations.xml,
 	src/output.c, src/translations.c, src/types.c, src/types.h:
@@ -5928,11 +6882,11 @@
 	* xml/routino-translations.xml:
 	Revert to UTF-8 multi-byte representations instead of character references.
 
-2010-09-14  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2010-09-14  Andrew M. Bishop  <amb>
 
 	* src/xmlparse.l: Stricter checking on XML data (Unicode).
 
-2010-09-05  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2010-09-05  Andrew M. Bishop  <amb>
 
 	* xml/Makefile, src/Makefile, doc/Makefile, Makefile:
 	Move all of the installation pathnames to the top level Makefile and include it
@@ -5942,7 +6896,7 @@
 	Use the installed tagging.xml, profiles.xml or translations.xml files as the
 	fallback option if no other given.
 
-2010-09-04  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2010-09-04  Andrew M. Bishop  <amb>
 
 	* xml/routino-translations.xml:
 	Change German translations from named HTML character encodings to numeric ones
@@ -5951,7 +6905,7 @@
 	* xml/routino-translations.xml:
 	Added Dutch translations (from Jan Jansen).
 
-2010-08-30  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2010-08-30  Andrew M. Bishop  <amb>
 
 	* xml/routino-translations.xml:
 	Change German translation to UTF-8, add comments indicating the origin of the
@@ -5972,7 +6926,7 @@
 
 	* src/profiles.c: Fix bug with writing out JSON profile information.
 
-2010-08-30  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2010-08-30  Andrew M. Bishop  <amb>
 
 	* src/ways.h, src/output.c:
 	Change the names of the functions used to get the highway names.
@@ -5983,26 +6937,26 @@
 
 	* src/profiles.c: Fix bug with writing out JSON profile information.
 
-2010-08-04  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2010-08-04  Andrew M. Bishop  <amb>
 
 	* src/output.c, src/segmentsx.c, src/types.h, src/fakes.c, src/functions.h, src/nodesx.c,
 	src/optimiser.c:
 	Change the way that fake nodes and segments are recognised (allows nearly 4G
 	nodes to be stored instead of 2G nodes).
 
-2010-08-03  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2010-08-03  Andrew M. Bishop  <amb>
 
 	* src/filedumper.c, src/nodes.h, src/nodesx.c, src/optimiser.c, src/types.h:
 	Rename the variables that hold the node allowed transports and flags.
 
-2010-08-02  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2010-08-02  Andrew M. Bishop  <amb>
 
 	* xml/routino-tagging-nomodify.xml, xml/routino-tagging.xml, xml/routino-tagging.xsd,
 	src/filedumper.c, src/nodesx.c, src/nodesx.h, src/optimiser.c, src/osmparser.c,
 	src/superx.c, src/tagging.c, src/types.h:
 	Understand node traffic type restrictions.
 
-2010-07-31  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2010-07-31  Andrew M. Bishop  <amb>
 
 	* src/profiles.h, src/types.c, src/types.h, src/ways.h, src/waysx.c:
 	Rename the wayallow_t type to allow_t (since it applies to nodes as well now).
@@ -6025,12 +6979,12 @@
 	* src/nodesx.c, src/segmentsx.c, src/superx.c, src/waysx.c:
 	Remove the assert statements that check the order of calling the functions.
 
-2010-07-26  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2010-07-26  Andrew M. Bishop  <amb>
 
 	* src/filedumper.c, src/nodes.c, src/nodes.h, src/visualiser.c:
 	Final part of slim mode for the router (node offsets).
 
-2010-07-24  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2010-07-24  Andrew M. Bishop  <amb>
 
 	* src/nodesx.c, src/segmentsx.c, src/waysx.c:
 	Some tidying up of the writing of the file headers.
@@ -6039,7 +6993,7 @@
 	src/output.c, src/profiles.c, src/visualiser.c:
 	Finished slim mode for the router by adding ways.
 
-2010-07-23  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2010-07-23  Andrew M. Bishop  <amb>
 
 	* src/filedumper.c, src/nodes.c, src/nodes.h, src/output.c, src/segments.c, src/segments.h,
 	src/segmentsx.c:
@@ -6056,30 +7010,30 @@
 
 	* src/fakes.c: New file.
 
-2010-07-19  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2010-07-19  Andrew M. Bishop  <amb>
 
 	* xml/routino-profiles.xml:
 	Reduce the "multilane" preference for motor vehicles.  Gives too much bias with
 	previous setting.
 
-2010-07-15  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2010-07-15  Andrew M. Bishop  <amb>
 
 	* src/Makefile, src/filedumper.c, src/nodes.c, src/nodes.h, src/nodesx.c, src/visualiser.c:
 	Added a slim mode to the router (just for nodes to start with).
 
-2010-07-14  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2010-07-14  Andrew M. Bishop  <amb>
 
 	* src/segmentsx.h, src/superx.c, src/waysx.c, src/waysx.h, src/Makefile, src/nodesx.c,
 	src/nodesx.h, src/planetsplitter.c, src/segmentsx.c:
 	Replaced the runtime selection of slim mode / non-slim mode with compile time
 	selection that gives no runtime overhead but gives two executables.
 
-2010-07-13  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2010-07-13  Andrew M. Bishop  <amb>
 
 	* src/nodesx.c, src/nodesx.h, src/segmentsx.c, src/segmentsx.h, src/waysx.c, src/waysx.h:
 	Move the functions for slim mode out into the header file and make it inline.
 
-2010-07-12  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2010-07-12  Andrew M. Bishop  <amb>
 
 	* src/files.h: New file.
 
@@ -6090,7 +7044,7 @@
 	Create a files.h header and put some of the most heavily used files.c functions
 	into it and make them inline.
 
-2010-07-11  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2010-07-11  Andrew M. Bishop  <amb>
 
 	* src/segmentsx.c, src/segmentsx.h, src/files.c, src/nodesx.c, src/nodesx.h:
 	Made the planetsplitter slim mode handle the output node and segment data in a
@@ -6099,11 +7053,11 @@
 	* src/nodesx.c, src/segmentsx.c, src/waysx.c:
 	Change the names of the temporary files.
 
-2010-07-10  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2010-07-10  Andrew M. Bishop  <amb>
 
 	Version 1.4.1 released
 
-2010-07-10  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2010-07-10  Andrew M. Bishop  <amb>
 
 	* doc/NEWS.txt: Update NEWS for release.
 
@@ -6111,12 +7065,12 @@
 	Update documentation for slight modification to algorithm, also add more
 	information about how preferences etc are handled.
 
-2010-07-09  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2010-07-09  Andrew M. Bishop  <amb>
 
 	* src/Makefile:
 	Default compilation flags include optimisation and not debugging symbols.
 
-2010-07-08  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2010-07-08  Andrew M. Bishop  <amb>
 
 	* src/nodes.c:
 	Fix error with finding closest segment to the specified point.
@@ -6124,7 +7078,7 @@
 	* src/optimiser.c:
 	Bug fix for not crashing when finding the middle part of the route.
 
-2010-07-07  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2010-07-07  Andrew M. Bishop  <amb>
 
 	* src/results.c, src/optimiser.c:
 	Changed the amount of memory allocated for intermediate results => routes much
@@ -6143,16 +7097,16 @@
 	* xml/Makefile:
 	Fix error from last checkin and clean up web directory on distclean.
 
-2010-07-06  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2010-07-06  Andrew M. Bishop  <amb>
 
 	* src/optimiser.c:
 	Don't crash if the middle part of the route can't be found but exit cleanly.
 
-2010-07-05  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2010-07-05  Andrew M. Bishop  <amb>
 
 	* src/superx.c: Change the algorithm used to determine supernodes.
 
-2010-07-03  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2010-07-03  Andrew M. Bishop  <amb>
 
 	* xml/routino-translations.xml:
 	Added German translation [patch from Christoph Eckert].
@@ -6161,11 +7115,11 @@
 	Don't crash if more than one language is in translations.xml but --language
 	option is not used.
 
-2010-06-28  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2010-06-28  Andrew M. Bishop  <amb>
 
 	* src/router.c: Don't crash if start and finish are the same point.
 
-2010-06-27  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2010-06-27  Andrew M. Bishop  <amb>
 
 	* doc/DATA.txt: New file.
 
@@ -6177,7 +7131,7 @@
 
 	* xml/Makefile: Add some new variables.
 
-2010-06-26  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2010-06-26  Andrew M. Bishop  <amb>
 
 	* xml/routino-profiles.xml, xml/routino-tagging-nomodify.xml, xml/routino-tagging.xml,
 	xml/routino-translations.xml, src/translations.c:
@@ -6187,11 +7141,11 @@
 
 	* doc/OUTPUT.txt: Changed URLs to http://www.routino.org/
 
-2010-05-31  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2010-05-31  Andrew M. Bishop  <amb>
 
 	Version 1.4 released
 
-2010-05-31  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2010-05-31  Andrew M. Bishop  <amb>
 
 	* doc/INSTALL.txt, doc/NEWS.txt, doc/README.txt:
 	Update for version 1.4.
@@ -6203,7 +7157,7 @@
 	* src/router.c:
 	Fix the code that should stop routing if no segment is found.
 
-2010-05-30  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2010-05-30  Andrew M. Bishop  <amb>
 
 	* doc/USAGE.txt:
 	Add the planetsplitter tagging rules option (and remove the unnecessary options
@@ -6229,7 +7183,7 @@
 
 	* src/optimiser.c: Fix printing the number of super-segments tried.
 
-2010-05-29  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2010-05-29  Andrew M. Bishop  <amb>
 
 	* xml/routino-translations.xml, xml/routino-translations.xsd, src/ways.h, src/filedumper.c,
 	src/osmparser.c, src/output.c, src/translations.c, src/translations.h:
@@ -6244,11 +7198,11 @@
 	When finding a closest segment one of the nodes must be within the search
 	distance.
 
-2010-05-28  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2010-05-28  Andrew M. Bishop  <amb>
 
 	* src/router.c: Make sure that some profiles are loaded.
 
-2010-05-27  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2010-05-27  Andrew M. Bishop  <amb>
 
 	* src/optimiser.c, src/profiles.c:
 	Fix bug with profile preferences (used incorrectly in route optimisation).
@@ -6256,11 +7210,11 @@
 	* src/Makefile, src/filedumper.c, src/types.c, src/types.h:
 	Add an option to filedumper to dump an OSM format file.
 
-2010-05-25  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2010-05-25  Andrew M. Bishop  <amb>
 
 	* src/xmlparse.l: Fix bug with encoding XML strings.
 
-2010-05-23  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2010-05-23  Andrew M. Bishop  <amb>
 
 	* xml/Makefile:
 	Make sure that modified files are copied to web directory.
@@ -6274,7 +7228,7 @@
 	* src/tagmodifier.c, xml/osm.xsd, xml/routino-osm.xsd, src/osmparser.c:
 	Add the 'bound' element to the XML parser.
 
-2010-05-22  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2010-05-22  Andrew M. Bishop  <amb>
 
 	* src/functionsx.h, src/osmparser.c, src/planetsplitter.c, src/ways.h, src/waysx.c,
 	src/waysx.h:
@@ -6282,7 +7236,7 @@
 	--not-property=<property> options from planetsplitter because they can be done
 	by the tagging.xml file now.
 
-2010-05-18  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2010-05-18  Andrew M. Bishop  <amb>
 
 	* src/Makefile: Add tagmodifier program.
 
@@ -6303,20 +7257,20 @@
 
 	* xml/osm.xsd: Small fix for OSM schema.
 
-2010-05-14  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2010-05-14  Andrew M. Bishop  <amb>
 
 	* src/types.c: Remove highway type aliases from HighwayType() function.
 
 	* src/xmlparse.h, src/xmlparse.l: Allow empty strings to be returned.
 
-2010-05-10  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2010-05-10  Andrew M. Bishop  <amb>
 
 	* src/xmlparse.h, src/xmlparse.l:
 	The line number is now a long integer.
 
 	* src/xml/Makefile: Running 'make test' now compiles everything first.
 
-2010-04-28  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2010-04-28  Andrew M. Bishop  <amb>
 
 	* src/xml/Makefile: Delete zero length file if xsd-to-xmlparser fails.
 
@@ -6326,7 +7280,7 @@
 	* src/Makefile, src/filedumper.c, src/xml/Makefile:
 	Compile with _FILE_OFFSET_BITS=64 to get 64-bit fopen() and stat().
 
-2010-04-27  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2010-04-27  Andrew M. Bishop  <amb>
 
 	* src/output.c: Fix mistake of writing GPX information to wrong file.
 
@@ -6336,7 +7290,7 @@
 	doc/README.txt:
 	Interim checkin of updated documentation.
 
-2010-04-24  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2010-04-24  Andrew M. Bishop  <amb>
 
 	* src/router.c:
 	Merged the three functions to output the head/body/tail of the results back into
@@ -6365,13 +7319,13 @@
 	Add an option to not convert the XML strings into decoded representations (saves
 	converting them back later for the translated strings).
 
-2010-04-23  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2010-04-23  Andrew M. Bishop  <amb>
 
 	* src/xml/xsd-to-xmlparser.c, src/translations.c, src/xmlparse.h, src/xmlparse.l,
 	src/profiles.c:
 	Pass the tag name to the tag function.
 
-2010-04-22  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2010-04-22  Andrew M. Bishop  <amb>
 
 	* Makefile: Fix bug in makefile.
 
@@ -6384,13 +7338,13 @@
 	* src/xmlparse.l:
 	Restart properly so that a different file can be read.
 
-2010-04-13  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2010-04-13  Andrew M. Bishop  <amb>
 
 	* src/xml/xsd-to-xmlparser.c, src/profiles.c, src/translations.c:
 	Name the tag variables and functions after the XSD data type and not the tag
 	name that uses it.
 
-2010-04-12  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2010-04-12  Andrew M. Bishop  <amb>
 
 	* src/profiles.c, src/translations.c, src/xmlparse.h, src/xmlparse.l,
 	src/xml/xsd-to-xmlparser.c, src/xml/Makefile:
@@ -6401,7 +7355,7 @@
 
 	* src/types.c: New file.
 
-2010-04-11  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2010-04-11  Andrew M. Bishop  <amb>
 
 	* src/xml/xsd-to-xmlparser.c, src/profiles.c, src/translations.c, src/xmlparse.h,
 	src/xmlparse.l:
@@ -6409,7 +7363,7 @@
 	Added macros to perform common error checking.
 	Change XML parser callback functions to return an error status.
 
-2010-04-10  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2010-04-10  Andrew M. Bishop  <amb>
 
 	* src/router.c: Fix usage information.
 
@@ -6420,13 +7374,13 @@
 	* src/Makefile, src/router.c:
 	Added file of translations and language selection.
 
-2010-04-09  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2010-04-09  Andrew M. Bishop  <amb>
 
 	* src/functions.h, src/planetsplitter.c, src/sorting.c:
 	Add an option '--sort-ram-size' to specify the RAM to use for sorting - defaults
 	to 256MB if not using slim mode.
 
-2010-04-08  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2010-04-08  Andrew M. Bishop  <amb>
 
 	* src/xml/Makefile: Fix test program generation and running.
 
@@ -6437,11 +7391,11 @@
 	* src/profiles.c, src/xml/xsd-to-xmlparser.c:
 	Make the strings const and add the number of attributes to the xmltag structure.
 
-2010-04-07  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2010-04-07  Andrew M. Bishop  <amb>
 
 	* xml/Makefile: New file.
 
-2010-04-06  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2010-04-06  Andrew M. Bishop  <amb>
 
 	* src/Makefile:
 	Remove special lex/flex flags.  Remove profiles.o from planetsplitter.
@@ -6454,7 +7408,7 @@
 	Make sure attribute values are cleared before calling tag function (for
 	end-tags).
 
-2010-04-04  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2010-04-04  Andrew M. Bishop  <amb>
 
 	* src/xml/Makefile: Add some XML parsing test cases.
 
@@ -6462,23 +7416,23 @@
 
 	* src/xmlparse.h, src/xmlparse.l, src/profiles.c: Added error checking.
 
-2010-04-03  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2010-04-03  Andrew M. Bishop  <amb>
 
 	* src/functionsx.h, src/osmparser.c, src/planetsplitter.c:
 	Rename the old ParseXML() function as ParseOSM().
 
-2010-04-01  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2010-04-01  Andrew M. Bishop  <amb>
 
 	* src/output.c: Wrap GPX descriptions in CDATA.
 
-2010-03-31  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2010-03-31  Andrew M. Bishop  <amb>
 
 	* xml/routino-profiles.xml: New file.
 
 	* src/xml/xsd-to-xmlparser.c, src/profiles.c, src/xmlparse.h, src/xmlparse.l:
 	Call the XML tag functions for the end tags as well as the start tags.
 
-2010-03-30  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2010-03-30  Andrew M. Bishop  <amb>
 
 	* src/profiles.c, src/profiles.h:
 	Change the name of the --profile-json and --profile-perl options.
@@ -6486,7 +7440,7 @@
 	* src/filedumper.c, src/planetsplitter.c, src/router.c:
 	Improve the program help messages.
 
-2010-03-29  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2010-03-29  Andrew M. Bishop  <amb>
 
 	* src/files.c, src/functions.h, src/profiles.c, src/profiles.h, src/router.c:
 	Added command line option to specify a file containing profiles.
@@ -6504,7 +7458,7 @@
 	* src/xmlparse.h, src/xmlparse.l:
 	Add the option to ignore unknown attributes.
 
-2010-03-28  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2010-03-28  Andrew M. Bishop  <amb>
 
 	* src/profiles.h, src/router.c, src/profiles.c:
 	Add an option to print out the profiles as XML format.
@@ -6516,7 +7470,7 @@
 
 	* src/xmlparse.l, src/xml/Makefile: New file.
 
-2010-03-20  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2010-03-20  Andrew M. Bishop  <amb>
 
 	* src/output.c: Add descriptions to each point in the GPX route file.
 
@@ -6537,77 +7491,77 @@
 	* src/planetsplitter.c:
 	Allow filenames on the planetsplitter command line.
 
-2010-03-19  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2010-03-19  Andrew M. Bishop  <amb>
 
 	* src/waysx.h, src/filedumper.c, src/files.c, src/functions.h, src/nodesx.c, src/nodesx.h,
 	src/planetsplitter.c, src/segmentsx.c, src/segmentsx.h, src/superx.c, src/waysx.c:
 	Allow planetsplitter to be run with a --parse-only or --process-only option and
 	append to existing file or read from existing file.
 
-2010-03-18  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2010-03-18  Andrew M. Bishop  <amb>
 
 	* src/router.c: Fix usage message error and shuffle order.
 
 	* src/output.c, src/router.c:
 	Allow selection of which outputs are to be created.
 
-2010-03-17  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2010-03-17  Andrew M. Bishop  <amb>
 
 	* src/output.c: Re-order the code for HTML.
 
-2010-03-15  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2010-03-15  Andrew M. Bishop  <amb>
 
 	* src/output.c: Create a simple HTML output.
 
-2010-03-06  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2010-03-06  Andrew M. Bishop  <amb>
 
 	* src/router.c, src/nodes.c:
 	Speed up start/via/stop point search algorithm.
 
-2010-03-05  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2010-03-05  Andrew M. Bishop  <amb>
 
 	* src/profiles.c:
 	Change the format of the output for the --help-profile-{pl|js} options.
 
-2010-01-21  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2010-01-21  Andrew M. Bishop  <amb>
 
 	Version 1.3 released
 
-2010-01-21  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2010-01-21  Andrew M. Bishop  <amb>
 
 	* doc/NEWS.txt: Update to latest news.
 
-2010-01-18  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2010-01-18  Andrew M. Bishop  <amb>
 
 	* doc/USAGE.txt, doc/TAGGING.txt, doc/INSTALL.txt:
 	Updated documentation.
 
-2010-01-15  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2010-01-15  Andrew M. Bishop  <amb>
 
 	* src/router.c, src/functions.h:
 	Change the test output formats to add turn, node type and bearing information.
 
-2010-01-13  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2010-01-13  Andrew M. Bishop  <amb>
 
 	* src/output.c:
 	Change the test output formats to add turn, node type and bearing information.
 
-2009-12-16  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2009-12-16  Andrew M. Bishop  <amb>
 
 	* src/router.c:
 	Added an option to use only nodes and not interpolate a point into a segment.
 
-2009-12-15  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2009-12-15  Andrew M. Bishop  <amb>
 
 	* src/osmparser.c, src/profiles.c, src/types.h, src/ways.c:
 	Added wheelchair as type of transport.
 
-2009-12-13  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2009-12-13  Andrew M. Bishop  <amb>
 
 	* src/osmparser.c, src/profiles.c, src/types.h, src/ways.c:
 	Add bridge and tunnel to highway properties.
 
-2009-12-12  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2009-12-12  Andrew M. Bishop  <amb>
 
 	* src/Makefile:
 	Ignore the error if executables cannot be copied after compiling.
@@ -6615,68 +7569,68 @@
 	* src/functions.h, src/nodesx.c, src/segmentsx.c, src/sorting.c, src/waysx.c:
 	Add some FILESORT_* #defines and use them.
 
-2009-12-11  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2009-12-11  Andrew M. Bishop  <amb>
 
 	* src/functions.h, src/nodesx.c, src/planetsplitter.c, src/segmentsx.c, src/sorting.c,
 	src/waysx.c, src/waysx.h:
 	Added a new function to sort variable length data - simplifies the compacting of
 	ways, reduces memory usage potentially required for it and simplifies the code.
 
-2009-12-10  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2009-12-10  Andrew M. Bishop  <amb>
 
 	* src/waysx.c:
 	Write out the list of ways without memory mapping anything.
 
-2009-11-27  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2009-11-27  Andrew M. Bishop  <amb>
 
 	* src/osmparser.c, src/profiles.c, src/types.h, src/ways.c:
 	Add in "multilane" as a new highway property.
 
-2009-11-25  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2009-11-25  Andrew M. Bishop  <amb>
 
 	* src/filedumper.c, src/optimiser.c, src/osmparser.c, src/planetsplitter.c, src/profiles.h,
 	src/router.c, src/ways.h, src/waysx.c, src/waysx.h:
 	Store the selected options when parsing (planetsplitter) and display them in the
 	statistics (filedumper) and check them when routing (router).
 
-2009-11-23  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2009-11-23  Andrew M. Bishop  <amb>
 
 	* src/osmparser.c, src/output.c, src/profiles.c, src/types.h, src/ways.c:
 	Add in "steps" as a new highway type.
 
-2009-11-19  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2009-11-19  Andrew M. Bishop  <amb>
 
 	* src/optimiser.c, src/router.c:
 	Made the verbose output consistent between different places.
 
-2009-11-18  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2009-11-18  Andrew M. Bishop  <amb>
 
 	* src/router.c: Fix bug with previous segment-splitting routing.
 
-2009-11-14  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2009-11-14  Andrew M. Bishop  <amb>
 
 	* src/optimiser.c, src/output.c, src/router.c, src/segments.h, src/functions.h, src/nodes.c,
 	src/nodes.h:
 	If a selected waypoint is not very close to an existing node then insert a fake
 	node in the segment that comes closest and use that instead.
 
-2009-11-13  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2009-11-13  Andrew M. Bishop  <amb>
 
 	* src/optimiser.c, src/osmparser.c, src/queue.c, src/results.c, src/results.h, src/types.h:
 	Added in some more constants with the value ~0.
 
-2009-11-06  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2009-11-06  Andrew M. Bishop  <amb>
 
 	* src/filedumper.c:
 	Check the values for the --node=, --segment= and --way= options.
 
-2009-11-03  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2009-11-03  Andrew M. Bishop  <amb>
 
 	* src/output.c, src/planetsplitter.c, src/profiles.c, src/profiles.h, src/router.c,
 	src/types.h, src/ways.c:
 	Rename Way_Unknown to Way_Count to make more sense and match the properties.
 
-2009-11-02  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2009-11-02  Andrew M. Bishop  <amb>
 
 	* src/osmparser.c: Allow the tag "paved" as well as "surface=paved".
 
@@ -6686,7 +7640,7 @@
 	Initially the only choice is either paved or unpaved but the code has been
 	updated to allow any number of properties to be added.
 
-2009-10-27  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2009-10-27  Andrew M. Bishop  <amb>
 
 	* src/osmparser.c:
 	Handle the "designation=..." tag for bridleway, byway and footpath.  (Also
@@ -6697,7 +7651,7 @@
 	Added Moped to the list of transports (and incidentally increased the transport
 	data type to 16 bits and re-ordered the Way data-type in response).
 
-2009-10-26  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2009-10-26  Andrew M. Bishop  <amb>
 
 	* src/profiles.c:
 	Ensure that horses and bicycles have a default speed on trunk even though they
@@ -6712,35 +7666,35 @@
 
 	* src/profiles.c: Remove unneeded spaces at the end of the output.
 
-2009-10-25  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2009-10-25  Andrew M. Bishop  <amb>
 
 	* src/output.c:
 	Fix bug in code that determines waypoints for abbreviated output.
 
-2009-10-24  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2009-10-24  Andrew M. Bishop  <amb>
 
 	* src/functions.h, src/optimiser.c, src/router.c:
 	Fix missing segments in output if start and finish points are found by the start
 	search.
 
-2009-10-22  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2009-10-22  Andrew M. Bishop  <amb>
 
 	* src/files.c, src/nodesx.c, src/segmentsx.c, src/sorting.c, src/superx.c, src/waysx.c:
 	Added some missing comments and corrected some existing ones.
 
-2009-10-21  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2009-10-21  Andrew M. Bishop  <amb>
 
 	Version 1.2 released
 
-2009-10-21  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2009-10-21  Andrew M. Bishop  <amb>
 
 	* doc/README.txt, doc/USAGE.txt, doc/NEWS.txt: Updated for version 1.2.
 
-2009-10-20  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2009-10-20  Andrew M. Bishop  <amb>
 
 	* src/Makefile: Add sorting.o to the Makefile.
 
-2009-10-12  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2009-10-12  Andrew M. Bishop  <amb>
 
 	* src/waysx.c: When sorting we cannot have NULL pointers now.
 
@@ -6751,7 +7705,7 @@
 	* src/nodesx.c, src/planetsplitter.c, src/segmentsx.c, src/sorting.c, src/waysx.c:
 	Rename the tmpdirname variable.
 
-2009-10-10  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2009-10-10  Andrew M. Bishop  <amb>
 
 	* src/nodesx.c, src/osmparser.c, src/segmentsx.c, src/sorting.c, src/waysx.c:
 	Corrections after running with valgrind.
@@ -6761,14 +7715,14 @@
 	* src/nodesx.c, src/nodesx.h, src/segmentsx.c:
 	Remove the nodesx->gdata index.
 
-2009-10-09  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2009-10-09  Andrew M. Bishop  <amb>
 
 	* src/nodesx.c, src/segmentsx.c, src/typesx.h, src/waysx.c, src/waysx.h:
 	Free the nodesx->super array and the segmentsx->firstnode array when finished
 	with them.  Remove wayx->cid and overwrite wayx->id instead.  Overwrite
 	nodex[i]->id=i for later geographically sorted use.
 
-2009-10-08  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2009-10-08  Andrew M. Bishop  <amb>
 
 	* src/nodesx.c, src/planetsplitter.c, src/segmentsx.c, src/segmentsx.h, src/superx.c:
 	Replace node, segment and way indexes with a single index for a set of segments
@@ -6776,7 +7730,7 @@
 
 	* src/nodesx.h: Fix comment.
 
-2009-10-07  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2009-10-07  Andrew M. Bishop  <amb>
 
 	* src/osmparser.c, src/segmentsx.c, src/superx.c:
 	AppendSegment adds a single segment and not a pair.
@@ -6789,7 +7743,7 @@
 	simplifies the lookup of first/next segments at no in-RAM index cost and now
 	that slim mode has sorting of file contents the balance has tipped back.
 
-2009-10-04  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2009-10-04  Andrew M. Bishop  <amb>
 
 	* src/functions.h, src/sorting.c:
 	Change the sort function to allow the indexing callback to veto the write.
@@ -6809,28 +7763,28 @@
 
 	* src/queue.c: Fix bug with binary heap sort.
 
-2009-09-25  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2009-09-25  Andrew M. Bishop  <amb>
 
 	* src/queue.c: Add comments describing the algorithm used.
 
-2009-09-23  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2009-09-23  Andrew M. Bishop  <amb>
 
 	* src/nodesx.c, src/waysx.c:
 	Simplify the de-duplication when sorting and update some comments.
 
-2009-09-22  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2009-09-22  Andrew M. Bishop  <amb>
 
 	* src/nodesx.c, src/nodesx.h:
 	Remove a leftover from the last change on these files.
 
 	* src/segmentsx.c: Improve the super-segment de-duplication.
 
-2009-09-21  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2009-09-21  Andrew M. Bishop  <amb>
 
 	* src/nodesx.c, src/nodesx.h, src/planetsplitter.c:
 	Remove the non-highway nodes without re-sorting the whole list again.
 
-2009-09-17  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2009-09-17  Andrew M. Bishop  <amb>
 
 	* src/osmparser.c, src/planetsplitter.c, src/segmentsx.c, src/superx.c, src/waysx.c,
 	src/waysx.h:
@@ -6843,18 +7797,18 @@
 	* src/files.c, src/functions.h:
 	The WriteFile function now has a const parameter.
 
-2009-09-15  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2009-09-15  Andrew M. Bishop  <amb>
 
 	* src/nodesx.c, src/nodesx.h, src/planetsplitter.c, src/segmentsx.c:
 	Some bug fixes and some missing unmap function calls.
 
-2009-09-07  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2009-09-07  Andrew M. Bishop  <amb>
 
 	* src/segmentsx.h, src/superx.c, src/nodesx.c, src/nodesx.h, src/segmentsx.c:
 	Fixed slim mode for segments and nodes (slim now means mapping only one file
 	into RAM at a time and none when creating the final output).
 
-2009-09-06  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2009-09-06  Andrew M. Bishop  <amb>
 
 	* src/nodesx.h, src/planetsplitter.c, src/segmentsx.c, src/segmentsx.h, src/superx.c,
 	src/superx.h, src/nodesx.c:
@@ -6865,7 +7819,7 @@
 
 	* src/filedumper.c: Allow dumping all nodes, segments or ways.
 
-2009-09-05  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2009-09-05  Andrew M. Bishop  <amb>
 
 	* src/nodesx.c: Don't re-sort unnecessarily.
 
@@ -6874,7 +7828,7 @@
 
 	* src/files.c, src/functions.h: Add some more file functions.
 
-2009-09-03  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2009-09-03  Andrew M. Bishop  <amb>
 
 	* src/nodesx.c, src/files.c, src/functions.h:
 	Remove extra argument from MapFile function.
@@ -6885,7 +7839,7 @@
 	* src/files.c, src/functions.h:
 	Changes to mapping and unmapping files for slim mode.
 
-2009-08-25  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2009-08-25  Andrew M. Bishop  <amb>
 
 	* src/planetsplitter.c: Revert the order that the functions are called.
 
@@ -6893,22 +7847,22 @@
 
 	* src/files.c: Bug fix for mmap().
 
-2009-08-20  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2009-08-20  Andrew M. Bishop  <amb>
 
 	* src/osmparser.c: Fix bug with memory allocation.
 
-2009-08-19  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2009-08-19  Andrew M. Bishop  <amb>
 
 	* src/nodesx.c, src/nodesx.h, src/planetsplitter.c, src/segmentsx.c, src/segmentsx.h,
 	src/superx.c, src/waysx.c, src/waysx.h:
 	Remove "sorted" parameter in data structure and change assert statements.
 
-2009-08-17  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2009-08-17  Andrew M. Bishop  <amb>
 
 	* src/router.c:
 	Increase to 99 the number of waypoints that can be specified.
 
-2009-08-15  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2009-08-15  Andrew M. Bishop  <amb>
 
 	* src/queue.c: Fix comment.
 
@@ -6931,14 +7885,14 @@
 
 	* src/filedumper.c: Fix dumping nodes when they are super-nodes.
 
-2009-07-23  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2009-07-23  Andrew M. Bishop  <amb>
 
 	* src/Makefile, src/optimiser.c, src/results.c, src/results.h, src/superx.c:
 	Split off queue functions into a separate file.
 
 	* src/queue.c: New file.
 
-2009-07-19  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2009-07-19  Andrew M. Bishop  <amb>
 
 	* src/nodesx.c, src/segments.h, src/segmentsx.c, src/ways.h, src/waysx.c, src/filedumper.c,
 	src/nodes.h:
@@ -6953,7 +7907,7 @@
 	src/superx.c:
 	Store only one copy of each segment but index once for each direction.
 
-2009-07-12  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2009-07-12  Andrew M. Bishop  <amb>
 
 	* src/functionsx.h, src/nodesx.c, src/nodesx.h, src/osmparser.c, src/output.c,
 	src/planetsplitter.c, src/profiles.c, src/results.c, src/segments.c, src/segmentsx.c,
@@ -6964,14 +7918,14 @@
 	src/waysx.c, src/filedumper.c, src/nodesx.c, src/optimiser.c:
 	Check all print statements and made them more consistent and/or accurate.
 
-2009-07-11  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2009-07-11  Andrew M. Bishop  <amb>
 
 	* src/nodesx.c, src/nodesx.h, src/planetsplitter.c, src/segmentsx.c, src/waysx.c,
 	src/waysx.h:
 	Free memory at the end of planetsplitter (to aid finding potential leaks
 	earlier).
 
-2009-07-09  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2009-07-09  Andrew M. Bishop  <amb>
 
 	* src/segmentsx.c: Free memory correctly (really).
 
@@ -6994,23 +7948,23 @@
 	Change from float to double for latitude and longitude.
 	Store latitude and longitude as an integer type rather than float (higher precision).
 
-2009-07-08  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2009-07-08  Andrew M. Bishop  <amb>
 
 	* src/superx.c: Ensure that variable is reset before using it.
 
-2009-07-06  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2009-07-06  Andrew M. Bishop  <amb>
 
 	* src/visualiser.c:
 	Print all super-segments within and crossing the border.
 	Don't display speed limits for tracks and paths unless set.
 
-2009-07-04  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2009-07-04  Andrew M. Bishop  <amb>
 
 	* src/segmentsx.h, src/superx.c, src/waysx.c, src/waysx.h:
 	Change data structure to avoid calling realloc() each time to allocate more
 	memory.
 
-2009-07-02  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2009-07-02  Andrew M. Bishop  <amb>
 
 	* src/types.h, src/waysx.c, src/waysx.h:
 	Handle duplicate ways.
@@ -7024,7 +7978,7 @@
 	src/segmentsx.c, src/superx.c, src/ways.c, src/waysx.c:
 	Removed unused header files, change assert statements, tidy some code.
 
-2009-07-01  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2009-07-01  Andrew M. Bishop  <amb>
 
 	* src/nodesx.c, src/nodesx.h, src/planetsplitter.c, src/segmentsx.c, src/segmentsx.h, src/superx.c:
 	Remove the Node structure from the NodeX structure to save memory.
@@ -7032,7 +7986,7 @@
 	* src/filedumper.c:
 	Print latitude and longitude in degrees.
 
-2009-06-30  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2009-06-30  Andrew M. Bishop  <amb>
 
 	* src/segmentsx.h:
 	Re-order the data in the structure.
@@ -7041,7 +7995,7 @@
 	src/segmentsx.h, src/superx.c, src/waysx.h:
 	Remove the Segment structure from the SegmentX structure to save memory.
 
-2009-06-29  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2009-06-29  Andrew M. Bishop  <amb>
 
 	* src/filedumper.c, src/nodes.h, src/nodesx.c, src/segments.c, src/segments.h,
 	src/segmentsx.c, src/superx.c, src/types.h:
@@ -7053,7 +8007,7 @@
 	* src/nodesx.c, src/segmentsx.c, src/segmentsx.h, src/superx.c:
 	Rename SegmentsX sdata to ndata.
 
-2009-06-25  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2009-06-25  Andrew M. Bishop  <amb>
 
 	* src/waysx.c, src/waysx.h: Rename part of the structure.
 
@@ -7066,12 +8020,12 @@
 	Reduce the number of ways in the output by compacting them (sharing the same
 	information between identical ways).
 
-2009-06-24  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2009-06-24  Andrew M. Bishop  <amb>
 
 	* src/filedumper.c, src/nodes.h:
 	Allow dumping out of nodes, segments and ways.
 
-2009-06-15  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2009-06-15  Andrew M. Bishop  <amb>
 
 	* src/segmentsx.c, src/superx.c, src/visualiser.c, src/ways.c, src/ways.h:
 	Rename WaysSame() with WaysCompare() and reverse the sense of the output.
@@ -7093,11 +8047,11 @@
 	* doc/TAGGING.txt, src/osmparser.c:
 	Recognise tags "vehicle" and "motor_vehicle".
 
-2009-06-13  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2009-06-13  Andrew M. Bishop  <amb>
 
 	Version 1.1 released
 
-2009-06-13  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2009-06-13  Andrew M. Bishop  <amb>
 
 	* src/nodesx.c, src/planetsplitter.c, src/segmentsx.c, src/segmentsx.h:
 	Handle nodes that are missing from the .osm file (ignore the segment).
@@ -7110,21 +8064,21 @@
 	* src/Makefile:
 	Delete the executables from the web directory for 'distclean'.
 
-2009-06-12  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2009-06-12  Andrew M. Bishop  <amb>
 
 	* doc/USAGE.txt, doc/INSTALL.txt, doc/README.txt:
 	Update the documentation.
 
 	* src/Makefile: Copy the executables into the web directory.
 
-2009-06-08  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2009-06-08  Andrew M. Bishop  <amb>
 
 	* src/filedumper.c: Change help text.
 
 	* src/visualiser.c:
 	Change format of super-node/segment visualiser output.
 
-2009-06-07  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2009-06-07  Andrew M. Bishop  <amb>
 
 	* doc/TAGGING.txt: Updated with imperial to metric conversions.
 
@@ -7134,22 +8088,22 @@
 
 	* src/visualiser.h, src/visualiser.c: New file.
 
-2009-06-05  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2009-06-05  Andrew M. Bishop  <amb>
 
 	* src/osmparser.c:
 	Improve parsing of imperial units (mph, feet & inches).
 
-2009-06-03  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2009-06-03  Andrew M. Bishop  <amb>
 
 	* src/nodesx.c:
 	Print an error message and exit if a node cannot be found.
 
-2009-05-31  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2009-05-31  Andrew M. Bishop  <amb>
 
 	* src/ways.c, src/ways.h, src/waysx.c, src/waysx.h:
 	Move function from waysx.c to ways.c.
 
-2009-05-29  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2009-05-29  Andrew M. Bishop  <amb>
 
 	* doc/USAGE.txt:
 	Update usage information with new options and copyright.txt usage.
@@ -7157,24 +8111,24 @@
 	* src/nodes.c, src/nodes.h, src/router.c:
 	Make sure that the chosen "nearest point" is a highway that the profile allows.
 
-2009-05-23  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2009-05-23  Andrew M. Bishop  <amb>
 
 	* src/profiles.c:
 	Change the default profile; horses are slower, bicycles may be allowed on
 	footways (and similar).
 
-2009-05-15  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2009-05-15  Andrew M. Bishop  <amb>
 
 	* src/files.c, src/output.c:
 	Error checking on opening files (to read/write data and to write output).
 
-2009-05-14  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2009-05-14  Andrew M. Bishop  <amb>
 
 	* src/output.c, src/results.c, src/router.c, src/segments.c, src/segmentsx.c, src/superx.c,
 	src/types.h, src/nodes.c, src/nodesx.c, src/optimiser.c:
 	Replace ~0 or 0 with NO_NODE value for "no node" condition.
 
-2009-05-13  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2009-05-13  Andrew M. Bishop  <amb>
 
 	* src/output.c:
 	Remove one more NODE macro and fix an output formatting error.
@@ -7192,63 +8146,63 @@
 	* src/optimiser.c, src/results.c, src/results.h:
 	Remove distance and duration from Result structure.
 
-2009-05-09  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2009-05-09  Andrew M. Bishop  <amb>
 
 	* src/output.c:
 	Add better junction detection for deciding on route waypoints.
 
-2009-05-06  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2009-05-06  Andrew M. Bishop  <amb>
 
 	* src/optimiser.c, src/profiles.c, src/profiles.h, src/types.h:
 	Route using preferences for each highway.
 
 	* src/router.c: Print out longitude then latitude.
 
-2009-04-30  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2009-04-30  Andrew M. Bishop  <amb>
 
 	* src/results.h, src/router.c, src/superx.c, src/types.h, src/optimiser.c, src/osmparser.c,
 	src/planetsplitter.c, src/profiles.c, src/profiles.h, src/results.c:
 	First attempt at preferences for highways - uses integer arithmetic and doesn't
 	work well.
 
-2009-04-27  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2009-04-27  Andrew M. Bishop  <amb>
 
 	* src/functions.h, src/optimiser.c, src/output.c, src/results.c, src/results.h, src/router.c:
 	Allow generating a route with intermediate waypoints.
 
-2009-04-24  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2009-04-24  Andrew M. Bishop  <amb>
 
 	* src/functions.h, src/output.c, src/router.c:
 	Split the output functions into separate head/body/tail.
 	Read in an optional copyright.txt file and include contents in output.
 
-2009-04-23  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2009-04-23  Andrew M. Bishop  <amb>
 
 	* src/profiles.c: Improve Javascript and perl print out.
 
 	* src/filedumper.c, src/files.c, src/functions.h, src/planetsplitter.c, src/router.c:
 	Move the filename generation to a new function.
 
-2009-04-22  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2009-04-22  Andrew M. Bishop  <amb>
 
 	* src/Makefile, src/functions.h, src/optimiser.c:
 	Split the function to print the output into a new file.
 
 	* src/output.c: New file.
 
-2009-04-15  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2009-04-15  Andrew M. Bishop  <amb>
 
 	* src/osmparser.c:
 	Fix for parsing nodes from XML (no effect on results).
 
-2009-04-12  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2009-04-12  Andrew M. Bishop  <amb>
 
 	* doc/USAGE.txt, src/optimiser.c:
 	Create a GPX route as well as a track.
 
 	* src/ways.c: Changed the license to Affero GPLv3.
 
-2009-04-10  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2009-04-10  Andrew M. Bishop  <amb>
 
 	* src/optimiser.c:
 	Add a waypoint to the GPX file for the start and finish points.
@@ -7256,11 +8210,11 @@
 	* doc/USAGE.txt:
 	Include more information about the output file formats.
 
-2009-04-08  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2009-04-08  Andrew M. Bishop  <amb>
 
 	Version 1.0 released
 
-2009-04-08  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2009-04-08  Andrew M. Bishop  <amb>
 
 	* Makefile: New file.
 
@@ -7276,23 +8230,23 @@
 	src/ways.h, src/waysx.c, src/waysx.h:
 	Changed the license to Affero GPLv3.
 
-2009-04-07  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2009-04-07  Andrew M. Bishop  <amb>
 
 	* src/planetsplitter.c: Remove the --help-profile command line option.
 
-2009-03-28  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2009-03-28  Andrew M. Bishop  <amb>
 
 	* src/optimiser.c:
 	Fix file headers (again) and fix segment distance/duration for abbreviated text
 	output.
 
-2009-03-24  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2009-03-24  Andrew M. Bishop  <amb>
 
 	* src/osmparser.c, src/profiles.c, src/types.h, src/ways.c:
 	Added highway=path; defaults to foot=yes but also is defaulted for bicycle and
 	horse transport.
 
-2009-03-23  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2009-03-23  Andrew M. Bishop  <amb>
 
 	* src/optimiser.c: Fixed the header in the output text files.
 
@@ -7302,29 +8256,29 @@
 	* src/profiles.h, src/router.c, src/profiles.c:
 	Add a function to output default profiles as perl data structures.
 
-2009-03-21  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2009-03-21  Andrew M. Bishop  <amb>
 
 	* src/nodesx.c:
 	Handle duplicated nodes (e.g. from concatenated input files).
 
 	* src/optimiser.c: Add a header to the output text files.
 
-2009-03-07  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2009-03-07  Andrew M. Bishop  <amb>
 
 	* src/optimiser.c:
 	Renamed the *.txt output to *-all.txt and added a new shorted *.txt output.
 
 	* src/router.c: Renamed the --no-print option to --no-output.
 
-2009-03-04  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2009-03-04  Andrew M. Bishop  <amb>
 
 	* src/nodes.c: Fix bug with finding nearest node.
 
-2009-03-03  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2009-03-03  Andrew M. Bishop  <amb>
 
 	* src/superx.c: Fix the merging of super-segments.
 
-2009-03-01  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2009-03-01  Andrew M. Bishop  <amb>
 
 	* src/profiles.c, src/profiles.h:
 	Added more limits (weight, height, width, length).
@@ -7341,7 +8295,7 @@
 	* src/waysx.c, src/waysx.h:
 	Added a function to test if two ways are the same.
 
-2009-02-28  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2009-02-28  Andrew M. Bishop  <amb>
 
 	* src/nodesx.c:
 	Round the node location to avoid if falling into the wrong bin.
@@ -7354,12 +8308,12 @@
 	* src/profiles.c, src/router.c:
 	Add new command line options to make it more CGI friendly.
 
-2009-02-27  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2009-02-27  Andrew M. Bishop  <amb>
 
 	* src/profiles.c, src/profiles.h, src/router.c:
 	Print out Javascript code containing the profiles.
 
-2009-02-24  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2009-02-24  Andrew M. Bishop  <amb>
 
 	* src/segmentsx.h, src/superx.c, src/nodesx.c, src/segments.c, src/segments.h,
 	src/segmentsx.c:
@@ -7367,7 +8321,7 @@
 
 	* src/profiles.c: Remove track from valid types for most transports.
 
-2009-02-15  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2009-02-15  Andrew M. Bishop  <amb>
 
 	* src/functions.h, src/optimiser.c, src/router.c:
 	Change some function names.
@@ -7398,7 +8352,7 @@
 
 	* src/osmparser.c: Handle oneway=1 and oneway=-1.
 
-2009-02-10  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2009-02-10  Andrew M. Bishop  <amb>
 
 	* src/results.c, src/results.h:
 	Added a new 'sortby' entry to the Result.
@@ -7409,7 +8363,7 @@
 	* src/nodes.c, src/segments.c, src/segments.h:
 	Change the Distance() function to return distance_t.
 
-2009-02-08  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2009-02-08  Andrew M. Bishop  <amb>
 
 	* src/optimiser.c, src/results.c, src/results.h, src/router.c, src/superx.c:
 	Calculate quickest or shortest, not both.
@@ -7417,7 +8371,7 @@
 	* src/optimiser.c, src/profiles.c, src/router.c:
 	Give appropriate error messages if start or end of route are not possible.
 
-2009-02-07  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2009-02-07  Andrew M. Bishop  <amb>
 
 	* src/results.c:
 	Slight speedup by doing a linear search when looking up results and not storing
@@ -7441,14 +8395,14 @@
 
 	* src/optimiser.c, src/types.h: Routing works with super-nodes now.
 
-2009-02-06  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2009-02-06  Andrew M. Bishop  <amb>
 
 	* src/ways.c, src/segments.c, src/segments.h, src/supersegments.c, src/types.h, src/nodes.c,
 	src/nodes.h, src/optimiser.c, src/osmparser.c, src/planetsplitter.c, src/functions.h:
 	Segments now not duplicated in database.
 	Routing with all nodes works, not with super-nodes.
 
-2009-02-04  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2009-02-04  Andrew M. Bishop  <amb>
 
 	* src/router.c: Fix usage output.
 
@@ -7464,20 +8418,20 @@
 	src/supersegments.c, src/types.h, src/filedumper.c, src/nodes.c:
 	Sort the nodes geographically and take coordinates as command line arguments.
 
-2009-02-02  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2009-02-02  Andrew M. Bishop  <amb>
 
 	* src/ways.c, src/ways.h, src/nodes.c, src/nodes.h, src/osmparser.c, src/segments.c,
 	src/segments.h, src/supersegments.c, src/types.h:
 	More variable and function name changes.
 
-2009-02-01  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2009-02-01  Andrew M. Bishop  <amb>
 
 	* src/profiles.c, src/router.c, src/segments.c, src/segments.h, src/supersegments.c,
 	src/ways.c, src/ways.h, src/files.c, src/functions.h, src/nodes.c, src/nodes.h,
 	src/optimiser.c, src/osmparser.c, src/planetsplitter.c, src/filedumper.c:
 	Rename some variable types.
 
-2009-01-31  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2009-01-31  Andrew M. Bishop  <amb>
 
 	* src/segments.c, src/segments.h, src/supersegments.c, src/types.h, src/ways.c, src/ways.h,
 	src/functions.h, src/nodes.c, src/nodes.h, src/optimiser.c, src/planetsplitter.c,
@@ -7494,7 +8448,7 @@
 	* src/planetsplitter.c, src/router.c:
 	Add command line options to specify the directory and filename prefix.
 
-2009-01-30  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2009-01-30  Andrew M. Bishop  <amb>
 
 	* src/results.c, src/planetsplitter.c: Remove gcc warning.
 
@@ -7502,27 +8456,27 @@
 
 	* src/osmparser.c: Remove gcc warning.
 
-2009-01-29  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2009-01-29  Andrew M. Bishop  <amb>
 
 	* src/functions.h, src/nodes.c, src/nodes.h, src/optimiser.c, src/planetsplitter.c,
 	src/router.c, src/segments.c, src/segments.h, src/supersegments.c:
 	Intermediate version while transitioning data format for nodes and segments.
 
-2009-01-28  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2009-01-28  Andrew M. Bishop  <amb>
 
 	* src/Makefile, src/functions.h, src/nodes.c, src/nodes.h, src/optimiser.c, src/osmparser.c,
 	src/planetsplitter.c, src/segments.c, src/segments.h, src/supersegments.c, src/ways.c,
 	src/ways.h:
 	Intermediate version while transitioning data format for nodes and segments.
 
-2009-01-27  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2009-01-27  Andrew M. Bishop  <amb>
 
 	* src/Makefile, src/functions.h, src/nodes.c, src/nodes.h, src/optimiser.c,
 	src/planetsplitter.c, src/router.c, src/segments.c, src/segments.h, src/supersegments.c,
 	src/ways.c, src/ways.h:
 	Intermediate version while transitioning data format for nodes and segments.
 
-2009-01-26  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2009-01-26  Andrew M. Bishop  <amb>
 
 	* src/osmparser.c, src/planetsplitter.c, src/segments.c, src/segments.h,
 	src/supersegments.c, src/ways.c, src/ways.h, src/filedumper.c, src/files.c, src/functions.h,
@@ -7530,7 +8484,7 @@
 	Change Segment to contain index of way not its real ID.
 	Don't store the real way ID to save space.
 
-2009-01-25  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2009-01-25  Andrew M. Bishop  <amb>
 
 	* src/segments.c, src/segments.h:
 	Slightly speed up the Duration calculation by changing the macro.
@@ -7549,7 +8503,7 @@
 	Added profiles to define speed and allowed highways.
 	Added new options to planetsplitter and router to use the profiles.
 
-2009-01-24  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2009-01-24  Andrew M. Bishop  <amb>
 
 	* src/optimiser.c: Changed some variable names for clarity.
 
@@ -7560,7 +8514,7 @@
 	Change the Results structure so that the real data doesn't need to be realloc().
 	Add functions to access the first and subsequent elements of the Results structure.
 
-2009-01-23  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2009-01-23  Andrew M. Bishop  <amb>
 
 	* src/osmparser.c, src/planetsplitter.c:
 	Fix bug with not specifying a method of transport.
@@ -7591,7 +8545,7 @@
 	Create a large or small results structure depending on how many nodes are
 	expected.
 
-2009-01-22  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2009-01-22  Andrew M. Bishop  <amb>
 
 	* src/results.h: Increase the number of bins to 64k.
 
@@ -7611,7 +8565,7 @@
 	src/ways.h:
 	Remove the choice of indexed or non-indexed data structures.
 
-2009-01-21  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2009-01-21  Andrew M. Bishop  <amb>
 
 	* src/optimiser.c:
 	Various small speed-ups including not-reversing direction.
@@ -7626,7 +8580,7 @@
 
 	* src/osmparser.c: Don't change speed on roundabouts.
 
-2009-01-20  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2009-01-20  Andrew M. Bishop  <amb>
 
 	* src/planetsplitter.c:
 	Add command line options for skipping parsing and iteration limit.
@@ -7634,14 +8588,14 @@
 	* src/optimiser.c, src/osmparser.c, src/segments.c, src/segments.h, src/supersegments.c:
 	Remove duration from segment, calculate duration depending on speed.
 
-2009-01-19  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2009-01-19  Andrew M. Bishop  <amb>
 
 	* src/functions.h, src/optimiser.c, src/planetsplitter.c, src/supersegments.c:
 	Iteratively calculate the super-segments.
 
 	* src/ways.h: Redefine Way_TYPE() to include one-way status.
 
-2009-01-18  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2009-01-18  Andrew M. Bishop  <amb>
 
 	* src/optimiser.c, src/supersegments.c:
 	Fix problems with way-type matching and duplicated/missing super-segments.
@@ -7669,7 +8623,7 @@
 	* src/optimiser.c:
 	Fix bugs when start and/or finish nodes are supernodes.
 
-2009-01-17  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2009-01-17  Andrew M. Bishop  <amb>
 
 	* src/Makefile: Add the option to create assembler output files.
 
@@ -7678,7 +8632,7 @@
 
 	* src/router.c: Added an option to not print the result.
 
-2009-01-16  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2009-01-16  Andrew M. Bishop  <amb>
 
 	* src/optimiser.c, src/results.h, src/router.c:
 	Speed optimisation by changing the contents of the Results structure.
@@ -7686,7 +8640,7 @@
 	* src/optimiser.c:
 	Don't bother calculating the distance to go, it takes too long.
 
-2009-01-14  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2009-01-14  Andrew M. Bishop  <amb>
 
 	* src/planetsplitter.c: Remove bad segments and non-way nodes.
 
@@ -7709,7 +8663,7 @@
 	Add segments that correspond to the wrong way along one-way routes with an
 	invalid distance.
 
-2009-01-11  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2009-01-11  Andrew M. Bishop  <amb>
 
 	* src/functions.h, src/optimiser.c, src/router.c:
 	Routes correctly using super-nodes (not Lands End to John O'Groats though).
@@ -7725,7 +8679,7 @@
 	src/results.h, src/router.c, src/segments.c, src/segments.h, src/supersegments.c:
 	Working version with supersegments and junctions.
 
-2009-01-10  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2009-01-10  Andrew M. Bishop  <amb>
 
 	* src/ways.c, src/ways.h, src/osmparser.c, src/segments.c:
 	Store more information about ways.
@@ -7747,7 +8701,7 @@
 	* src/functions.h, src/types.h:
 	Changed after nodes, ways and segment changes.
 
-2009-01-09  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2009-01-09  Andrew M. Bishop  <amb>
 
 	* src/segments.h: New file.
 
@@ -7764,7 +8718,7 @@
 	* src/nodes.c, src/nodes.h:
 	Changed the format of the nodes data type again.
 
-2009-01-07  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2009-01-07  Andrew M. Bishop  <amb>
 
 	* src/nodes.h: New file.
 
@@ -7773,7 +8727,7 @@
 	Data is hashed into multiple bins.
 	Each function takes a nodes structure as an argument.
 
-2009-01-06  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2009-01-06  Andrew M. Bishop  <amb>
 
 	* src/supersegments.c: New file.
 
@@ -7783,7 +8737,7 @@
 	* src/optimiser.c:
 	Tried to optimise the Queue data type.  It was slower than the original.
 
-2009-01-05  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2009-01-05  Andrew M. Bishop  <amb>
 
 	* src/filedumper.c: Print out the longest segment.
 
@@ -7791,7 +8745,7 @@
 	Some optimisations.  Increase the number of result bins and change
 	find_insert_result() into insert_result().
 
-2009-01-04  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2009-01-04  Andrew M. Bishop  <amb>
 
 	* src/optimiser.c: Introduced some new data types to simplify the code.
 
@@ -7804,7 +8758,7 @@
 	Remove the automatic sorting of the data.
 	Added assert statements.
 
-2009-01-03  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2009-01-03  Andrew M. Bishop  <amb>
 
 	* src/ways.c: New file.
 
@@ -7812,20 +8766,20 @@
 	src/optimiser.c, src/osmparser.c, src/planetsplitter.c:
 	Added the ways to the output.
 
-2009-01-02  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2009-01-02  Andrew M. Bishop  <amb>
 
 	* src/optimiser.c, src/osmparser.c, src/segments.c, src/types.h:
 	Added macros to convert between distance/km and duration/hours/minutes.
 	Shortened the Segment data type with shorter distances and durations.
 
-2009-01-01  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2009-01-01  Andrew M. Bishop  <amb>
 
 	* src/functions.h, src/nodes.c, src/planetsplitter.c, src/segments.c, src/types.h:
 	Remove the functions to initialise the node and segment arrays.
 
 	* src/optimiser.c, src/router.c, src/Makefile: Print out the results.
 
-2008-12-31  Andrew M. Bishop  <amb at gedanken.demon.co.uk>
+2008-12-31  Andrew M. Bishop  <amb>
 
 	* src/types.h, src/segments.c, src/router.c, src/planetsplitter.c, src/osmparser.c,
 	src/optimiser.c, src/nodes.c, src/functions.h, src/files.c, src/filedumper.c, src/Makefile:
diff --git a/Makefile b/Makefile
index 1c1cbd3..3dd7b99 100644
--- a/Makefile
+++ b/Makefile
@@ -2,7 +2,7 @@
 #
 # Part of the Routino routing software.
 #
-# This file Copyright 2009-2014 Andrew M. Bishop
+# This file Copyright 2009-2015 Andrew M. Bishop
 #
 # This program is free software: you can redistribute it and/or modify
 # it under the terms of the GNU Affero General Public License as published by
@@ -24,8 +24,7 @@ include Makefile.conf
 
 # Sub-directories and sub-makefiles
 
-SUBFILES=$(wildcard */Makefile)
-SUBDIRS=$(foreach f,$(SUBFILES),$(dir $f))
+SUBDIRS=src xml doc web extras
 
 ########
 
diff --git a/Makefile.conf b/Makefile.conf
index a7976ce..cc112e0 100644
--- a/Makefile.conf
+++ b/Makefile.conf
@@ -2,7 +2,7 @@
 #
 # Part of the Routino routing software.
 #
-# This file Copyright 2013-2014 Andrew M. Bishop
+# This file Copyright 2013-2015 Andrew M. Bishop
 #
 # This program is free software: you can redistribute it and/or modify
 # it under the terms of the GNU Affero General Public License as published by
@@ -18,16 +18,50 @@
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 #
 
+# Automatic operating system detection
+
+UNAME=$(shell uname)
+
+HOST=UNIX
+
+ifneq ($(findstring CYGWIN,$(UNAME)),)
+HOST=CYGWIN
+endif
+
+ifneq ($(findstring MINGW,$(UNAME)),)
+HOST=MINGW
+endif
+
+
+# Simplify handling of executable targets ending in .exe
+
+ifeq ($(HOST),MINGW)
+.EXE=.exe
+else
+.EXE=
+endif
+
+
 # Installation locations (edit if required)
 
+ifneq ($(HOST),MINGW)
 prefix=/usr/local
 bindir=$(prefix)/bin
+incdir=$(prefix)/include
+libdir=$(prefix)/lib
 docdir=$(prefix)/doc/routino
 datadir=$(prefix)/share/routino
+else
+prefix="c:/Program Files/Routino"
+bindir=$(prefix)/bin
+incdir=$(prefix)/include
+libdir=$(prefix)/lib
+docdir=$(prefix)/doc
+datadir=$(prefix)/xml
+endif
 
 
 # Compilation programs
-
 CC=gcc
 LD=gcc
 
@@ -36,7 +70,7 @@ LD=gcc
 CFLAGS=-std=c99
 
 # Warning options
-CFLAGS+=-Wall -Wmissing-prototypes -Wextra -Wno-unused-parameter
+CFLAGS+=-Wall -Wmissing-prototypes -Wextra -Wno-unused-parameter -pedantic
 
 # Optimisation options
 CFLAGS+=-O3
@@ -53,14 +87,30 @@ CFLAGS+=-ffast-math
 LDFLAGS=-lm
 
 
+# Extra flags for compiling libroutino shared library (visibility of symbols, shared)
+CFLAGS_LIB=-fvisibility=hidden
+LDFLAGS_LIB=-shared
+
+ifeq ($(HOST),UNIX)
+# Extra flags for compiling libroutino shared library (position independent code)
+CFLAGS_LIB+=-fPIC
+LDFLAGS_LIB+=-fPIC
+endif
+
+# Put the current directory in the shared library path for the router using libroutino
+LDFLAGS_LDSO=-Wl,-R.
+
+
 # Required for multi-threaded support (comment these two lines out if not required)
 CFLAGS+=-pthread -DUSE_PTHREADS
 LDFLAGS+=-pthread -lpthread
 
 
+ifneq ($(HOST),MINGW)
 # Required for bzip2 support (comment these two lines out if not required)
 CFLAGS+=-DUSE_BZIP2
 LDFLAGS+=-lbz2
+endif
 
 
 # Required for gzip support (comment these two lines out if not required)
@@ -77,5 +127,7 @@ LDFLAGS+=-lz
 CFLAGS+=-D_FILE_OFFSET_BITS=64
 
 
+ifneq ($(HOST),MINGW)
 # Required to compile on Linux without a warning about pread() and pwrite() functions.
 CFLAGS+=-D_POSIX_C_SOURCE=200809L
+endif
diff --git a/doc/INSTALL-MS-WIN.txt b/doc/INSTALL-MS-WIN.txt
new file mode 100644
index 0000000..aee467d
--- /dev/null
+++ b/doc/INSTALL-MS-WIN.txt
@@ -0,0 +1,151 @@
+                   Routino : Installation on MS Windows
+                   ====================================
+
+
+Using Cygwin
+------------
+
+   Cygwin is a large collection of GNU and Open Source tools which provide
+   functionality similar to a Linux distribution on Windows. A Cygwin DLL
+   provides substantial POSIX API functionality therefore providing direct
+   compatibility for most UNIX source code.
+
+   Since Cygwin aims to replicate a Linux-like system on Windows it is the
+   simplest method of compiling Routino. The disadvantage is that all
+   programs compiled with Cygwin require a number of runtime Cygwin
+   libraries which may introduce a runtime speed penalty.
+
+   The installer for Cygwin can be downloaded from http://cygwin.org/;
+   there are 32-bit and 64-bit versions available. For compiling Routino
+   the Cygwin installer should be run and the following packages selected
+   (any dependencies will be automatically be selected at the next step):
+
+     * base packages
+     * gcc-core (in 'Devel' menu)
+     * make (in 'Devel' menu)
+     * libbz2-devel (in 'Libs' menu)
+     * zlib-devel (in 'Libs' menu)
+     * perl (in 'Perl' menu)
+
+   To compile Routino open the "Cygwin Terminal" change to the Routino
+   source directory and compile using the make command.
+
+   The programs that are compiled 'planetsplitter', 'router' will require the
+   Cygwin runtime to be able to run them. The library 'libroutino.so' should
+   be usable with other Cygwin compiled programs.
+
+
+Native Compilation
+------------------
+
+   Routino has limited support in the source code for compiling on
+   Microsoft Windows. This includes a set of functions that can replace
+   the mmap() and munmap() UNIX functions which are not available on
+   Microsoft Windows.
+
+   The source code should be downloaded, either as a release version file
+   or from subversion - no instructions are provided for this step. The
+   release versions include some files (mainly the web icons) which are
+   not included in the subversion source (and which may be difficult to
+   create on Windows).
+
+Using Microsoft Visual C
+- - - - - - - - - - - -
+
+   The Routino source code (for the router at least) has been modified so
+   that it will compile with the Microsoft Visual C compiler.
+
+   Compiling Routino with MSVC is not supported directly since there is
+   only support for using Makefiles in Routino. The files that need to be
+   compiled for the Routino router can be found from the Makefile in the
+   src directory listed in the 'ROUTER_OBJ' variable.
+
+   To compile the router in slim mode the pre-processor definition 'SLIM=0'
+   must be set and for non-slim mode 'SLIM=1' must be set.
+
+   The default directory for the Routino data files must be set in the
+   'ROUTINO_DATADIR' pre-processor variable. If the router command line
+   '--data' option is going to be used then this variable can be set to
+   any value.
+
+   Since Microsoft Visual C does not fully support the C99 standard it is
+   necessary to tell the compiler how to handle the inline functions. This
+   can be done by passing in the command line option '-Dinline=__inline' to
+   the C compiler.
+
+Using MinGW
+- - - - - -
+
+   MinGW is the "Minimalist GNU for Windows" which includes some of the
+   common GNU programs; principally gcc and related programs for software
+   development.
+
+   The installer for MinGW can be downloaded from 'http://mingw.org/'. For
+   compiling Routino the MinGW installer should be run and the following
+   packages selected:
+     * mingw-base
+     * msys-base
+     * mingw32-pthreads-w32
+     * mingw32-libz (dev package)
+     * msys-perl
+
+   To compile Routino open a DOS command window and set the path to the
+   installed MinGW and MSYS software. For example if MinGW was installed
+   in the 'C:/MinGW' directory then the path needs to be set to
+   'C:\MinGW\bin;C:\MinGW\MSYS\1.0\bin'.
+
+   From within this DOS command window change to the Routino source
+   directory and compile using the MinGW version of make with this command
+   'mingw32-make'.
+
+   After compiling Routino a set of library files are created ('routino.dll',
+   'routino.def' and 'routino.lib'). These should be usable for linking with
+   programs compiled with MSVC.
+
+Using MinGW-W64
+- - - - - - - -
+
+   MinGW-w64 is an alernative implementation of the same concept as MinGW
+   but allows for compilation to 32-bit or 64-bit executables.
+
+   The website for MinGW-w64 is 'http://mingw-w64.org/' but the downloads
+   are available from 'http://win-builds.org/'. Installation of MinGW-w64 is
+   slightly different from that for MinGW but a similar set of packages
+   will be required.
+
+   The compilation method for MinGW-w64 is the same as for MinGW and the
+   same files will be compiled, the only difference is that by default a
+   64-bit version will be created.
+
+Limitations
+- - - - - -
+
+   A native Microsoft Windows compilation of Routino is more complicated
+   than compiling on Linux, other UNIX system or Cygwin. This is probably
+   not an option if you are unfamiliar with software development on
+   Microsoft Windows.
+
+   The size of files that can be accessed with an MSVC or MinGW (32-bit)
+   compiled version of Routino is limited to 32-bits (less than 4 GB). The
+   MinGW-w64 compiler on 64-bit is able to handle larger files (bigger
+   than 4 GB).
+
+   The Windows operating system does not have a function equivalent to the
+   'fork()' function on UNIX. This means that it is not possible to use the
+   planetsplitter program's built-in file decompression with an MSVC or
+   MinGW compiled version of Routino.
+
+
+Example Web Pages
+-----------------
+
+   No instructions are available for using the Routino example web pages
+   with the Microsoft Web server (IIS).
+
+   For information on setting up Apache see the "Example Web Pages"
+   section of the main installation instructions.
+
+
+--------
+
+Copyright 2008-2015 Andrew M. Bishop.
diff --git a/doc/INSTALL.txt b/doc/INSTALL.txt
index b92ef90..0ee8b48 100644
--- a/doc/INSTALL.txt
+++ b/doc/INSTALL.txt
@@ -6,8 +6,11 @@ Quick Start Guide
 -----------------
 
    The instructions below are a complete list of the minimum required to
-   get Routino installed and running under Apache on Debian Linux (other
-   Linux versions will be similar).
+   get Routino installed and running under Apache on Debian Linux. Other
+   Linux versions will be similar and other UNIX based systems will also
+   be similar although may have distinct differences. There is some
+   support in Routino for compiling on Microsoft Windows which has its own
+   installation instructions.
 
    ***********************************************************************
    *** These instructions should not be considered as complete or a    ***
@@ -306,4 +309,4 @@ Configuration of Web Server
 
 --------
 
-Copyright 2008-2014 Andrew M. Bishop.
+Copyright 2008-2015 Andrew M. Bishop.
diff --git a/doc/LIBRARY.txt b/doc/LIBRARY.txt
new file mode 100644
index 0000000..fa5bb8e
--- /dev/null
+++ b/doc/LIBRARY.txt
@@ -0,0 +1,683 @@
+                           Routino : Library
+                           =================
+
+
+Library Usage
+-------------
+
+   This page describes the libroutino shared library that can be compiled
+   from the Routino source code and used in other programs.
+
+Compilation
+- - - - - -
+
+   The libroutino shared library is compiled by default when the Routino
+   source code is compiled. There are two versions; a normal version and a
+   'slim' version that uses less memory but is slower. The names of the
+   libraries are libroutino.so and libroutino-slim.so
+
+Including
+- - - - -
+
+   To use the Routino library in another program the source code for that
+   program should include the routino.h file. The functions that are
+   available in the library (both versions) are listed in this file along
+   with all of the constants and data types that are required.
+
+Linking
+- - - -
+
+   After compiling the program that uses the library it needs to be linked
+   to the library. For gcc this requires adding -lroutino or
+   -lroutino-slim to the linker command line, possibly with a -L...
+   parameter to specify the location of the library.
+
+Example Library Interface Code
+- - - - - - - - - - - - - - -
+
+   An example of a program that can link to the libroutino library is
+   provided in the Routino source code called router+lib.c. This is an
+   almost exact re-implementation of the standard Routino router program
+   using the libroutino library.
+
+
+Library License
+---------------
+
+   The source code for the libroutino and libroutino-slim libraries is the
+   GNU Affero General Public License v3 the same as for the rest of the
+   Routino software.
+
+Linking with AGPLv3 Source Code
+- - - - - - - - - - - - - - - -
+
+   If libroutino is linked with other APGLv3 code then the same license
+   applies to the combination as to the two parts.
+
+Linking with GPLv3 Source Code
+- - - - - - - - - - - - - - -
+
+   The AGPLv3 license is almost identical to the GNU General Public
+   License v3 except that network interaction with an AGPLv3 program
+   requires the same source code access as distributing compiled GPLv3
+   programs. This means that libroutino can be linked or combined with
+   code that is released under the GPLv3 without changing the license of
+   that code.
+
+   If there is no network interaction with the resulting program then the
+   Routino source code can be treated as if it was GPLv3 code for the
+   purposes of distribution and use.
+
+   If there is network interaction with the resulting program then the
+   AGPLv3 license will apply since this is required by section 13 of the
+   GPLv3.
+   The Software Freedom Law Center description of the GPLv3 and AGPLv3
+   licenses describes combining GPLv3 and APGLv3.
+   My understanding is that only when modified Routino code is linked with
+   GPLv3 code does network interaction require the modified Routino code
+   to be released.
+
+Linking with Other Source Code
+- - - - - - - - - - - - - - -
+
+   Linking libroutino with code released under any other license must
+   preserve the terms of the Routino license on the combination if the
+   software is distributed or interacted with over a network.
+
+
+Routino Library API
+-------------------
+
+Preprocessor Definitions
+- - - - - - - - - - - -
+
+   A version number for the Routino API.
+   #define ROUTINO_API_VERSION 7
+
+Error Definitions
+
+   No error.
+   #define ROUTINO_ERROR_NONE 0
+
+   A function was called without the database variable set.
+   #define ROUTINO_ERROR_NO_DATABASE 1
+
+   A function was called without the profile variable set.
+   #define ROUTINO_ERROR_NO_PROFILE 2
+
+   A function was called without the translation variable set.
+   #define ROUTINO_ERROR_NO_TRANSLATION 3
+
+   The specified database to load did not exist.
+   #define ROUTINO_ERROR_NO_DATABASE_FILES 11
+
+   The specified database could not be loaded.
+   #define ROUTINO_ERROR_BAD_DATABASE_FILES 12
+
+   The specified profiles XML file did not exist.
+   #define ROUTINO_ERROR_NO_PROFILES_XML 13
+
+   The specified profiles XML file could not be loaded.
+   #define ROUTINO_ERROR_BAD_PROFILES_XML 14
+
+   The specified translations XML file did not exist.
+   #define ROUTINO_ERROR_NO_TRANSLATIONS_XML 15
+
+   The specified translations XML file could not be loaded.
+   #define ROUTINO_ERROR_BAD_TRANSLATIONS_XML 16
+
+   The requested profile name does not exist in the loaded XML file.
+   #define ROUTINO_ERROR_NO_SUCH_PROFILE 21
+
+   The requested translation language does not exist in the loaded XML
+   file.
+   #define ROUTINO_ERROR_NO_SUCH_TRANSLATION 22
+
+   There is no highway near the coordinates to place a waypoint.
+   #define ROUTINO_ERROR_NO_NEARBY_HIGHWAY 31
+
+   The profile and database do not work together.
+   #define ROUTINO_ERROR_PROFILE_DATABASE_ERR 41
+
+   The profile being used has not been validated.
+   #define ROUTINO_ERROR_NOTVALID_PROFILE 42
+
+   The user specified profile contained invalid data.
+   #define ROUTINO_ERROR_BAD_USER_PROFILE 43
+
+   The routing options specified are not consistent with each other.
+   #define ROUTINO_ERROR_BAD_OPTIONS 51
+
+   There is a mismatch between the library and caller API version.
+   #define ROUTINO_ERROR_WRONG_API_VERSION 61
+
+   The progress function returned false.
+   #define ROUTINO_ERROR_PROGRESS_ABORTED 71
+
+   A route could not be found to waypoint 1.
+   #define ROUTINO_ERROR_NO_ROUTE_1 1001
+
+   A route could not be found to waypoint 2.
+   #define ROUTINO_ERROR_NO_ROUTE_2 1002
+
+   A route could not be found to waypoint 3.
+   #define ROUTINO_ERROR_NO_ROUTE_3 1003
+
+Routino Option Definitions
+
+   Calculate the shortest route.
+   #define ROUTINO_ROUTE_SHORTEST 0
+
+   Calculate the quickest route.
+   #define ROUTINO_ROUTE_QUICKEST 1
+
+   Output an HTML route file.
+   #define ROUTINO_ROUTE_FILE_HTML 2
+
+   Output a GPX track file.
+   #define ROUTINO_ROUTE_FILE_GPX_TRACK 4
+
+   Output a GPX route file.
+   #define ROUTINO_ROUTE_FILE_GPX_ROUTE 8
+
+   Output a text file with important junctions.
+   #define ROUTINO_ROUTE_FILE_TEXT 16
+
+   Output a text file with all nodes and segments.
+   #define ROUTINO_ROUTE_FILE_TEXT_ALL 32
+
+   Output a single file type to stdout.
+   #define ROUTINO_ROUTE_FILE_STDOUT 64
+
+   Output a linked list of points containing the HTML file information but
+   as plain text.
+   #define ROUTINO_ROUTE_LIST_HTML 128
+
+   Output a linked list of points containing the HTML file information as
+   plain text and with all points.
+   #define ROUTINO_ROUTE_LIST_HTML_ALL 256
+
+   Output a linked list of points containing the text file information.
+   #define ROUTINO_ROUTE_LIST_TEXT 512
+
+   Output a linked list of points containing the text all file
+   information.
+   #define ROUTINO_ROUTE_LIST_TEXT_ALL 1024
+
+Linked List Output Point Definitions
+
+   An unimportant, intermediate, node.
+   #define ROUTINO_POINT_UNIMPORTANT 0
+
+   A roundabout exit that is not taken.
+   #define ROUTINO_POINT_RB_NOT_EXIT 1
+
+   An un-interesting junction where the route continues without comment.
+   #define ROUTINO_POINT_JUNCT_CONT 2
+
+   The highway changes type but nothing else happens.
+   #define ROUTINO_POINT_CHANGE 3
+
+   An interesting junction to be described.
+   #define ROUTINO_POINT_JUNCT_IMPORT 4
+
+   The entrance to a roundabout.
+   #define ROUTINO_POINT_RB_ENTRY 5
+
+   The exit from a roundabout.
+   #define ROUTINO_POINT_RB_EXIT 6
+
+   The location of a mini-roundabout.
+   #define ROUTINO_POINT_MINI_RB 7
+
+   The location of a U-turn.
+   #define ROUTINO_POINT_UTURN 8
+
+   A waypoint.
+   #define ROUTINO_POINT_WAYPOINT 9
+
+Profile Definitions
+
+   A Motorway highway.
+   #define ROUTINO_HIGHWAY_MOTORWAY 1
+
+   A Trunk highway.
+   #define ROUTINO_HIGHWAY_TRUNK 2
+
+   A Primary highway.
+   #define ROUTINO_HIGHWAY_PRIMARY 3
+
+   A Secondary highway.
+   #define ROUTINO_HIGHWAY_SECONDARY 4
+
+   A Tertiary highway.
+   #define ROUTINO_HIGHWAY_TERTIARY 5
+
+   A Unclassified highway.
+   #define ROUTINO_HIGHWAY_UNCLASSIFIED 6
+
+   A Residential highway.
+   #define ROUTINO_HIGHWAY_RESIDENTIAL 7
+
+   A Service highway.
+   #define ROUTINO_HIGHWAY_SERVICE 8
+
+   A Track highway.
+   #define ROUTINO_HIGHWAY_TRACK 9
+
+   A Cycleway highway.
+   #define ROUTINO_HIGHWAY_CYCLEWAY 10
+
+   A Path highway.
+   #define ROUTINO_HIGHWAY_PATH 11
+
+   A Steps highway.
+   #define ROUTINO_HIGHWAY_STEPS 12
+
+   A Ferry highway.
+   #define ROUTINO_HIGHWAY_FERRY 13
+
+   A Paved highway.
+   #define ROUTINO_PROPERTY_PAVED 1
+
+   A Multilane highway.
+   #define ROUTINO_PROPERTY_MULTILANE 2
+
+   A Bridge highway.
+   #define ROUTINO_PROPERTY_BRIDGE 3
+
+   A Tunnel highway.
+   #define ROUTINO_PROPERTY_TUNNEL 4
+
+   A Footroute highway.
+   #define ROUTINO_PROPERTY_FOOTROUTE 5
+
+   A Bicycleroute highway.
+   #define ROUTINO_PROPERTY_BICYCLEROUTE 6
+
+Type Definitions
+- - - - - - - -
+
+Typedef Routino_Database
+
+   A data structure to hold a Routino database loaded from a file (the
+   contents are private).
+
+   typedef struct _Routino_Database Routino_Database
+
+Typedef Routino_Waypoint
+
+   A data structure to hold a Routino waypoint found within the database
+   (the contents are private).
+
+   typedef struct _Routino_Waypoint Routino_Waypoint
+
+Typedef Routino_Profile
+
+   A data structure to hold a Routino routing profile (the contents are
+   private).
+
+   typedef struct _Routino_Profile Routino_Profile
+
+Typedef Routino_Translation
+
+   A data structure to hold a Routino translation (the contents are
+   private).
+
+   typedef struct _Routino_Translation Routino_Translation
+
+Typedef Routino_UserProfile
+
+   A data structure to hold a routing profile that can be defined by the
+   user.
+
+   typedef struct _Routino_UserProfile Routino_UserProfile
+   struct _Routino_UserProfile
+      {
+         int transport; The type of transport.
+         float highway[14]; A floating point preference for travel on the
+                            highway (range 0 to 1).
+         float speed[14]; The maximum speed on each type of highway
+                          (km/hour).
+         float props[7]; A floating point preference for ways with this
+                         attribute (range 0 to 1).
+         int oneway; A flag to indicate if one-way restrictions apply.
+         int turns; A flag to indicate if turn restrictions apply.
+         float weight; The weight of the vehicle (in tonnes).
+         float height; The height of the vehicle (in metres).
+         float width; The width of vehicle (in metres).
+         float length; The length of vehicle (in metres).
+      }
+
+Typedef Routino_Output
+
+   Forward declaration of the Routino_Output data type.
+
+   typedef struct _Routino_Output Routino_Output
+
+Type struct _Routino_Output
+
+   A linked list output of the calculated route whose contents depend on
+   the ROUTINO_ROUTE_LIST_* options selected.
+
+   struct _Routino_Output
+      {
+         Routino_Output* next; A pointer to the next route section.
+         float lon; The longitude of the point (radians).
+         float lat; The latitude of the point (radians).
+         float dist; The total distance travelled (kilometres) up to the
+                     point.
+         float time; The total journey time (seconds) up to the point.
+         float speed; The speed (km/hr) for this section of the route
+                      (ROUTINO_ROUTE_LIST_TEXT_ALL format only).
+         int type; The type of point (one of the ROUTINO_POINT_* values).
+         int turn; The amount to turn (degrees) for the next section of the
+                   route (ROUTINO_ROUTE_LIST_TEXT or ROUTINO_ROUTE_LIST_HTML
+                   or ROUTINO_ROUTE_LIST_HTML_ALL format).
+
+         int bearing; The compass direction (degrees) for the next section
+                      of the route.
+         char* name; The name of the next section of the route
+                     (ROUTINO_ROUTE_LIST_TEXT or ROUTINO_ROUTE_LIST_HTML
+                     or ROUTINO_ROUTE_LIST_HTML_ALL format) or previous
+                     section of the route (ROUTINO_ROUTE_LIST_TEXT_ALL
+                     format).
+         char* desc1; The first part of the description of the next
+                      section of route (ROUTINO_ROUTE_LIST_HTML or
+                      ROUTINO_ROUTE_LIST_HTML format).
+         char* desc2; The second part of the description of the next
+                      section of route (ROUTINO_ROUTE_LIST_HTML or
+                      ROUTINO_ROUTE_LIST_HTML format).
+         char* desc3; The third part of the description, the total
+                      distance and time at the end of the next section of
+                      route (ROUTINO_ROUTE_LIST_HTML or
+                      ROUTINO_ROUTE_LIST_HTML format).
+      }
+
+Typedef Routino_ProgressFunc
+
+   A type of function that can be used as a callback to indicate routing
+   progress, if it returns false the router stops.
+
+   typedef int (*Routino_ProgressFunc)(double complete)
+
+Variable Definitions
+- - - - - - - - - -
+
+Global Variable Routino_APIVersion
+
+   Contains the libroutino API version number.
+
+   int Routino_APIVersion
+
+Global Variable Routino_errno
+
+   Contains the error number of the most recent Routino function (one of
+   the ROUTINO_ERROR_* values).
+
+   int Routino_errno
+
+Function Definitions
+- - - - - - - - - -
+
+Global Function Routino_CalculateRoute()
+
+   Calculate a route using a loaded database, chosen profile, chosen
+   translation and set of waypoints.
+
+   Routino_Output* Routino_CalculateRoute ( Routino_Database* database,
+   Routino_Profile* profile, Routino_Translation* translation,
+   Routino_Waypoint** waypoints, int nwaypoints, int options,
+   Routino_ProgressFunc progress )
+
+   Routino_Output* Routino_CalculateRoute
+          Returns the head of a linked list of route data (if requested)
+          or NULL.
+
+   Routino_Database* database
+          The loaded database to use.
+
+   Routino_Profile* profile
+          The chosen routing profile to use.
+
+   Routino_Translation* translation
+          The chosen translation information to use.
+
+   Routino_Waypoint** waypoints
+          The set of waypoints.
+
+   int nwaypoints
+          The number of waypoints.
+
+   int options
+          The set of routing options (ROUTINO_ROUTE_*) ORed together.
+
+   Routino_ProgressFunc progress
+          A function to be called occasionally to report progress or NULL.
+
+Global Function Routino_Check_API_Version()
+
+   Check the version of the library used by the caller against the library
+   version
+
+   int Routino_Check_API_Version ( int caller_version )
+
+   int Routino_Check_API_Version
+          Returns ROUTINO_ERROR_NONE if OK or ROUTINO_ERROR_WRONG_VERSION
+          if there is an error.
+
+   int caller_version
+          The version of the API used in the caller.
+
+   This function should not be called directly, use the macro
+   Routino_CheckAPIVersion() which takes no arguments.
+
+   A wrapper function to simplify the API version check.
+   #define Routino_CheckAPIVersion()
+
+Global Function Routino_CreateProfileFromUserProfile()
+
+   Create a fully formed Routino Profile from a Routino User Profile.
+
+   Routino_Profile* Routino_CreateProfileFromUserProfile (
+   Routino_UserProfile* profile )
+
+   Routino_Profile* Routino_CreateProfileFromUserProfile
+          Returns an allocated Routino Profile.
+
+   Routino_UserProfile* profile
+          The user specified profile to convert (not modified by this).
+
+Global Function Routino_CreateUserProfileFromProfile()
+
+   Create a Routino User Profile from a Routino Profile loaded from an XML
+   file.
+
+   Routino_UserProfile* Routino_CreateUserProfileFromProfile (
+   Routino_Profile* profile )
+
+   Routino_UserProfile* Routino_CreateUserProfileFromProfile
+          Returns an allocated Routino User Profile.
+
+   Routino_Profile* profile
+          The Routino Profile to convert (not modified by this).
+
+Global Function Routino_DeleteRoute()
+
+   Delete the linked list created by Routino_CalculateRoute.
+
+   void Routino_DeleteRoute ( Routino_Output* output )
+
+   Routino_Output* output
+          The output to be deleted.
+
+Global Function Routino_FindWaypoint()
+
+   Finds the nearest point in the database to the specified latitude and
+   longitude.
+
+   Routino_Waypoint* Routino_FindWaypoint ( Routino_Database* database,
+   Routino_Profile* profile, double latitude, double longitude )
+
+   Routino_Waypoint* Routino_FindWaypoint
+          Returns a pointer to a newly allocated Routino waypoint or NULL
+          if none could be found.
+
+   Routino_Database* database
+          The Routino database to use.
+
+   Routino_Profile* profile
+          The Routino profile to use.
+
+   double latitude
+          The latitude in degrees of the point.
+
+   double longitude
+          The longitude in degrees of the point.
+
+Global Function Routino_FreeXMLProfiles()
+
+   Free the internal memory that was allocated for the Routino profiles
+   loaded from the XML file.
+
+   void Routino_FreeXMLProfiles ( void )
+
+Global Function Routino_FreeXMLTranslations()
+
+   Free the internal memory that was allocated for the Routino
+   translations loaded from the XML file.
+
+   void Routino_FreeXMLTranslations ( void )
+
+Global Function Routino_GetProfile()
+
+   Select a specific routing profile from the set of Routino profiles that
+   have been loaded from the XML file or NULL in case of an error.
+
+   Routino_Profile* Routino_GetProfile ( const char* name )
+
+   Routino_Profile* Routino_GetProfile
+          Returns a pointer to an internal data structure - do not free.
+
+   const char* name
+          The name of the profile to select.
+
+Global Function Routino_GetProfileNames()
+
+   Return a list of the profile names that have been loaded from the XML
+   file.
+
+   char** Routino_GetProfileNames ( void )
+
+   char** Routino_GetProfileNames
+          Returns a NULL terminated list of strings - all allocated.
+
+Global Function Routino_GetTranslation()
+
+   Select a specific translation from the set of Routino translations that
+   have been loaded from the XML file or NULL in case of an error.
+
+   Routino_Translation* Routino_GetTranslation ( const char* language )
+
+   Routino_Translation* Routino_GetTranslation
+          Returns a pointer to an internal data structure - do not free.
+
+   const char* language
+          The language to select (as a country code, e.g. 'en', 'de') or
+          an empty string for the first in the file or NULL for the
+          built-in English version.
+
+Global Function Routino_GetTranslationLanguageFullNames()
+
+   Return a list of the full names of the translation languages that have
+   been loaded from the XML file.
+
+   char** Routino_GetTranslationLanguageFullNames ( void )
+
+   char** Routino_GetTranslationLanguageFullNames
+          Returns a NULL terminated list of strings - all allocated.
+
+Global Function Routino_GetTranslationLanguages()
+
+   Return a list of the translation languages that have been loaded from
+   the XML file.
+
+   char** Routino_GetTranslationLanguages ( void )
+
+   char** Routino_GetTranslationLanguages
+          Returns a NULL terminated list of strings - all allocated.
+
+Global Function Routino_LoadDatabase()
+
+   Load a database of files for Routino to use for routing.
+
+   Routino_Database* Routino_LoadDatabase ( const char* dirname, const
+   char* prefix )
+
+   Routino_Database* Routino_LoadDatabase
+          Returns a pointer to the database.
+
+   const char* dirname
+          The pathname of the directory containing the database files.
+
+   const char* prefix
+          The prefix of the database files.
+
+Global Function Routino_ParseXMLProfiles()
+
+   Parse a Routino XML file containing profiles, must be called before
+   selecting a profile.
+
+   int Routino_ParseXMLProfiles ( const char* filename )
+
+   int Routino_ParseXMLProfiles
+          Returns non-zero in case of an error or zero if there was no
+          error.
+
+   const char* filename
+          The full pathname of the file to read.
+
+Global Function Routino_ParseXMLTranslations()
+
+   Parse a Routino XML file containing translations, must be called before
+   selecting a translation.
+
+   int Routino_ParseXMLTranslations ( const char* filename )
+
+   int Routino_ParseXMLTranslations
+          Returns non-zero in case of an error or zero if there was no
+          error.
+
+   const char* filename
+          The full pathname of the file to read.
+
+Global Function Routino_UnloadDatabase()
+
+   Close the database files that were opened by a call to
+   Routino_LoadDatabase().
+
+   void Routino_UnloadDatabase ( Routino_Database* database )
+
+   Routino_Database* database
+          The database to close.
+
+Global Function Routino_ValidateProfile()
+
+   Validates that a selected routing profile is valid for use with the
+   selected routing database.
+
+   int Routino_ValidateProfile ( Routino_Database* database,
+   Routino_Profile* profile )
+
+   int Routino_ValidateProfile
+          Returns zero if OK or something else in case of an error.
+
+   Routino_Database* database
+          The Routino database to use.
+
+   Routino_Profile* profile
+          The Routino profile to validate.
+
+--------
+
+Copyright 2015 Andrew M. Bishop.
diff --git a/doc/NEWS.txt b/doc/NEWS.txt
index 2c50b7d..756fe85 100644
--- a/doc/NEWS.txt
+++ b/doc/NEWS.txt
@@ -1,3 +1,45 @@
+Version 3.0 of Routino released : Sat Sep 12 2015
+-------------------------------------------------
+
+Bug fixes:
+  Use a single definition of MAX_SEG_PER_NODE to avoid confusion.
+  Fix bug with built-in translation strings if no XML translations available.
+  Fix bug with makefiles related to creating new translations.
+  Remove some pthread code that was still there when compiling without pthreads.
+  Fix a use-after-free memory error and use of uninitialised allocated memory.
+  Ensure that allocated strings are long enough for temporary filenames.
+
+Programs:
+  Add a '--version' option to all of the programs.
+
+Source Code:
+  Various C language cleanups including using '-pedantic' compiler option.
+  Various changes to allow compiling with Microsoft Visual Studio C compiler.
+  Various changes to allow compiling with MinGW or Cygwin on Microsoft Windows.
+  Makefile updates: 'make clean' = release, 'make distclean' = SVN repository.
+
+API:
+  Create a library API that can perform routing functions.
+
+OSM tagging:
+  Remove cycle_barrier and bicycle_barrier since they do not block bicycles.
+
+Translations:
+  Updated Dutch and German translations.
+  Added Hungarian and Polish translations provided through translation web page.
+
+Documentation:
+  Add meta tags to HTML to help mobile devices, tidy up the CSS.
+  Create instructions for compiling on Microsoft Windows.
+  Create API description for Routino library usage.
+
+Web pages:
+  Allow drag-and-drop of waypoints within the list and onto the map.
+
+
+Note: This version is compatible with databases from versions 2.7.1 - 2.7.3.
+
+
 Version 2.7.3 of Routino released : Sat Nov 8 2014
 --------------------------------------------------
 
@@ -18,7 +60,7 @@ Translations:
   Updated German translations.
 
 
-Note: This version is compatible with databases from version 2.7.1 & 2.7.2.
+Note: This version is compatible with databases from versions 2.7.1 & 2.7.2.
 
 
 Version 2.7.2 of Routino released : Thu June 26 2014
diff --git a/doc/OUTPUT.txt b/doc/OUTPUT.txt
index 497192a..78efe5a 100644
--- a/doc/OUTPUT.txt
+++ b/doc/OUTPUT.txt
@@ -61,11 +61,8 @@ HTML Route Instructions
 <tr class='n'><td class='l'>At:<td class='r'>Junction, go <span class='t'>Straight on</span> heading <span class='b'>South-East</span>
 <tr class='s'><td class='l'>Follow:<td class='r'><span class='h'>Russell Square (A4200)</span> for <span class='d'>0.186 km, 0.2 min</span> [<span class='j'>0.4 km, 1 minutes</span>]
 <tr class='c'><td class='l'>3:<td class='r'>51.521482 -0.124123
-<tr class='n'><td class='l'>At:<td class='r'>Junction, go <span class='t'>Straig
-ht on</span> heading <span class='b'>South-East</span>
-<tr class='s'><td class='l'>Follow:<td class='r'><span class='h'>Southampton Row
- (A4200)</span> for <span class='d'>0.351 km, 0.4 min</span> [<span class='j'>0.
-8 km, 1 minutes</span>]
+<tr class='n'><td class='l'>At:<td class='r'>Junction, go <span class='t'>Straight on</span> heading <span class='b'>South-East</span>
+<tr class='s'><td class='l'>Follow:<td class='r'><span class='h'>Southampton Row (A4200)</span> for <span class='d'>0.351 km, 0.4 min</span> [<span class='j'>0.8 km, 1 minutes</span>]
 ...
 <tr class='c'><td class='l'>21:<td class='r'>51.477678 -0.106792
 <tr class='n'><td class='l'>At:<td class='r'>Junction, go <span class='t'>Slight left</span> heading <span class='b'>South-East</span>
diff --git a/doc/README.txt b/doc/README.txt
index c401e49..993435c 100644
--- a/doc/README.txt
+++ b/doc/README.txt
@@ -129,6 +129,7 @@ Status
    Version 2.7.1 of Routino was released on 17th May 2014.
    Version 2.7.2 of Routino was released on 26th June 2014.
    Version 2.7.3 of Routino was released on 8th November 2014.
+   Version 3.0 of Routino was released on 12th September 2015.
 
    The full version history is available in the NEWS.txt file.
 
@@ -150,7 +151,7 @@ License
 Copyright
 ---------
 
-   Routino is copyright Andrew M. Bishop 2008-2014.
+   Routino is copyright Andrew M. Bishop 2008-2015.
 
 
 Homepage
@@ -185,4 +186,4 @@ Subversion
 
 --------
 
-Copyright 2008-2014 Andrew M. Bishop.
+Copyright 2008-2015 Andrew M. Bishop.
diff --git a/doc/TAGGING.txt b/doc/TAGGING.txt
index e8c7b2d..dd53f91 100644
--- a/doc/TAGGING.txt
+++ b/doc/TAGGING.txt
@@ -532,7 +532,7 @@ Routes
 - - -
 
    The route tag can be used to determine whether a relation is part of a
-   walking of bicycle route so that the footroute and bicycleroute
+   walking or bicycle route so that the footroute or bicycleroute
    properties can be applied to the highways that make up that relation.
 
    The tag transformations that are applied for route relations are
@@ -553,4 +553,4 @@ Turn Restrictions
 
 --------
 
-Copyright 2008-2014 Andrew M. Bishop.
+Copyright 2008-2015 Andrew M. Bishop.
diff --git a/doc/USAGE.txt b/doc/USAGE.txt
index 6405cf7..9cfa855 100644
--- a/doc/USAGE.txt
+++ b/doc/USAGE.txt
@@ -18,7 +18,8 @@ planetsplitter
    This program reads in the OSM format XML file and splits it up to
    create the database that is used for routing.
 
-   Usage: planetsplitter [--help]
+   Usage: planetsplitter [--version]
+                         [--help]
                          [--dir=<dirname>] [--prefix=<name>]
                          [--sort-ram-size=<size>] [--sort-threads=<number>]
                          [--tmpdir=<dirname>]
@@ -39,6 +40,9 @@ planetsplitter
                           | <filename.(osm|osc|o5m|o5c).gz> ...
                           | <filename.(osm|osc|o5m|o5c).xz> ...]
 
+   --version
+          Print the version of Routino.
+
    --help
           Prints out the help information.
 
@@ -204,7 +208,8 @@ router
    This program performs the calculation of the optimum routes using the
    database generated by the planetsplitter program.
 
-   Usage: router [--help | --help-profile | --help-profile-xml |
+   Usage: router [--version]
+                 [--help | --help-profile | --help-profile-xml |
                            --help-profile-json | --help-profile-perl ]
                  [--dir=<dirname>] [--prefix=<name>]
                  [--profiles=<filename>] [--translations=<filename>]
@@ -229,6 +234,9 @@ router
                  [--weight=<weight>]
                  [--height=<height>] [--width=<width>] [--length=<length>]
 
+   --version
+          Print the version of Routino.
+
    --help
           Prints out the help information.
 
@@ -469,7 +477,8 @@ filedumper
    particular information for visualisation purposes or for dumping the
    database contents.
 
-   Usage: filedumper [--help]
+   Usage: filedumper [--version]
+                     [--help]
                      [--dir=<dirname>] [--prefix=<name>]
                      [--statistics]
                      [--visualiser --latmin=<latmin> --latmax=<latmax>
@@ -488,6 +497,9 @@ filedumper
                                         [--data=turn-relation<rel>]
                                         [--data=errorlog<number>]]
 
+   --version
+          Print the version of Routino.
+
    --help
           Prints out the help information.
 
@@ -608,13 +620,17 @@ filedumperx
    for test purposes only and gives no useful information about the
    routing database.
 
-   Usage: filedumperx [--help]
+   Usage: filedumperx [--version]
+                      [--help]
                       [--dir=<dirname>] [--prefix=<name>]
                       [--dump [--nodes]
                               [--ways]
                               [--route-relations]
                               [--turn-relations]]
 
+   --version
+          Print the version of Routino.
+
    --help
           Prints out the help information.
 
@@ -645,4 +661,4 @@ filedumperx
 
 --------
 
-Copyright 2008-2014 Andrew M. Bishop.
+Copyright 2008-2015 Andrew M. Bishop.
diff --git a/doc/html/algorithm.html b/doc/html/algorithm.html
index 7361905..84b56bb 100644
--- a/doc/html/algorithm.html
+++ b/doc/html/algorithm.html
@@ -3,6 +3,7 @@
 
 <head>
 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<meta name="viewport" content="width=device-width, initial-scale=1">
 
 <title>Routino : Algorithm</title>
 
@@ -11,7 +12,7 @@
 
  Part of the Routino routing software.
 
- This file Copyright 2008-2013 Andrew M. Bishop
+ This file Copyright 2008-2015 Andrew M. Bishop
 
  This program is free software: you can redistribute it and/or modify
  it under the terms of the GNU Affero General Public License as published by
@@ -38,7 +39,6 @@
 
 <h1>Routino : Algorithm</h1>
 
-<hr>
 </div>
 
 <!-- Header End -->
@@ -399,7 +399,6 @@ the main node storage with a flag to indicate this information.
 <!-- Footer Start -->
 
 <div class="footer">
-<hr>
 
 <address>
 © Andrew M. Bishop - <a href="http://www.routino.org/">http://www.routino.org/</a>
diff --git a/doc/html/configuration.html b/doc/html/configuration.html
index 9fe7901..1d3ebc3 100644
--- a/doc/html/configuration.html
+++ b/doc/html/configuration.html
@@ -3,6 +3,7 @@
 
 <head>
 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<meta name="viewport" content="width=device-width, initial-scale=1">
 
 <title>Routino : Configuration</title>
 
@@ -11,7 +12,7 @@
 
  Part of the Routino routing software.
 
- This file Copyright 2008-2013 Andrew M. Bishop
+ This file Copyright 2008-2015 Andrew M. Bishop
 
  This program is free software: you can redistribute it and/or modify
  it under the terms of the GNU Affero General Public License as published by
@@ -38,7 +39,6 @@
 
 <h1>Routino : Configuration</h1>
 
-<hr>
 </div>
 
 <!-- Header End -->
@@ -300,7 +300,6 @@ Part of the provided translations.xml file showing some of the English language
 <!-- Footer Start -->
 
 <div class="footer">
-<hr>
 
 <address>
 © Andrew M. Bishop - <a href="http://www.routino.org/">http://www.routino.org/</a>
diff --git a/doc/html/data.html b/doc/html/data.html
index fedf8a9..62895b8 100644
--- a/doc/html/data.html
+++ b/doc/html/data.html
@@ -3,6 +3,7 @@
 
 <head>
 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<meta name="viewport" content="width=device-width, initial-scale=1">
 
 <title>Routino : Data</title>
 
@@ -11,7 +12,7 @@
 
  Part of the Routino routing software.
 
- This file Copyright 2008-2013 Andrew M. Bishop
+ This file Copyright 2008-2015 Andrew M. Bishop
 
  This program is free software: you can redistribute it and/or modify
  it under the terms of the GNU Affero General Public License as published by
@@ -38,7 +39,6 @@
 
 <h1>Routino : Data</h1>
 
-<hr>
 </div>
 
 <!-- Header End -->
@@ -152,7 +152,6 @@ uses the same Routino routing database.
 <!-- Footer Start -->
 
 <div class="footer">
-<hr>
 
 <address>
 © Andrew M. Bishop - <a href="http://www.routino.org/">http://www.routino.org/</a>
diff --git a/doc/html/index.html b/doc/html/index.html
index 31bd22a..f8d4a9b 100644
--- a/doc/html/index.html
+++ b/doc/html/index.html
@@ -3,6 +3,7 @@
 
 <head>
 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<meta name="viewport" content="width=device-width, initial-scale=1">
 
 <title>Routino : Documentation</title>
 
@@ -11,7 +12,7 @@
 
  Part of the Routino routing software.
 
- This file Copyright 2008-2013 Andrew M. Bishop
+ This file Copyright 2008-2015 Andrew M. Bishop
 
  This program is free software: you can redistribute it and/or modify
  it under the terms of the GNU Affero General Public License as published by
@@ -38,7 +39,6 @@
 
 <h1>Routino : Documentation</h1>
 
-<hr>
 </div>
 
 <!-- Header End -->
@@ -107,9 +107,22 @@ important information for rapid routing.
 
 The Routino source code comes with a set of files that can be used to create
 a working server very easily.  The full information about
-<a href="installation.html" title="Installation">installation</a>
-describes how to compile the programs and install them.
+<a href="installation.html" title="Installation">installation</a> describes how
+to compile the programs and install them on UNIX-like systems such as Linux.
 
+<h3 id="H_1_8_1">MS Windows Installation</h3>
+
+Routino can also be compiled and used on Microsoft Windows systems (with some
+limitations).  There are specific
+<a href="installation-ms-windows.html" title="MS Windows Installation">MS Windows installation</a>
+instructions describing how to compile the programs.
+
+
+<h2 id="H_1_9">Library</h2>
+
+The Routino routing algorithm is also available as a
+<a href="library.html" title="Library">shared library</a>
+that can be linked with other programs to allow routing from within them.
 
 </div>
 
@@ -118,7 +131,6 @@ describes how to compile the programs and install them.
 <!-- Footer Start -->
 
 <div class="footer">
-<hr>
 
 <address>
 © Andrew M. Bishop - <a href="http://www.routino.org/">http://www.routino.org/</a>
diff --git a/doc/html/installation-ms-windows.html b/doc/html/installation-ms-windows.html
new file mode 100644
index 0000000..ddc41e4
--- /dev/null
+++ b/doc/html/installation-ms-windows.html
@@ -0,0 +1,247 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<meta name="viewport" content="width=device-width, initial-scale=1">
+
+<title>Routino : Installation on MS Windows</title>
+
+<!--
+ Routino documentation - installation on MS Windows
+
+ Part of the Routino routing software.
+
+ This file Copyright 2008-2015 Andrew M. Bishop
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program.  If not, see http://www.gnu.org/licenses/.
+-->
+
+<link href="style.css" type="text/css" rel="stylesheet">
+</head>
+
+<body>
+
+<!-- Header Start -->
+
+<div class="header">
+
+<h1>Routino : Installation on MS Windows</h1>
+
+</div>
+
+<!-- Header End -->
+
+<!-- Content Start -->
+
+<div class="content">
+
+
+<h2 id="H_1_1">Using Cygwin</h2>
+
+Cygwin is a large collection of GNU and Open Source tools which provide
+functionality similar to a Linux distribution on Windows.  A Cygwin DLL
+provides substantial POSIX API functionality therefore providing direct
+compatibility for most UNIX source code.
+
+<p>
+
+Since Cygwin aims to replicate a Linux-like system on Windows it is the simplest
+method of compiling Routino.  The disadvantage is that all programs compiled
+with Cygwin require a number of runtime Cygwin libraries which may introduce a
+runtime speed penalty.
+
+<p>
+
+The installer for Cygwin can be downloaded from <tt>http://cygwin.org/</tt>;
+there are 32-bit and 64-bit versions available.  For compiling Routino the
+Cygwin installer should be run and the following packages selected (any
+dependencies will be automatically be selected at the next step):
+
+<ul>
+  <li><i>base packages</i>
+  <li>gcc-core (in 'Devel' menu)
+  <li>make (in 'Devel' menu)
+  <li>libbz2-devel (in 'Libs' menu)
+  <li>zlib-devel (in 'Libs' menu)
+  <li>perl (in 'Perl' menu)
+</ul>
+
+<p>
+
+To compile Routino open the "Cygwin Terminal" change to the Routino source
+directory and compile using the <tt>make</tt> command.
+
+<p>
+
+The programs that are compiled <tt>planetsplitter</tt>, <tt>router</tt> will
+require the Cygwin runtime to be able to run them.  The
+library <tt>libroutino.so</tt> should be usable with other Cygwin compiled
+programs.
+
+
+<h2 id="H_1_2">Native Compilation</h2>
+
+Routino has limited support in the source code for compiling on Microsoft
+Windows.  This includes a set of functions that can replace the <tt>mmap()</tt>
+and <tt>munmap()</tt> UNIX functions which are not available on Microsoft
+Windows.
+
+<p>
+
+The source code should be downloaded, either as a release version file or from
+subversion - no instructions are provided for this step.  The release versions
+include some files (mainly the web icons) which are not included in the
+subversion source (and which may be difficult to create on Windows).
+
+
+<h3 id="H_1_2_1">Using Microsoft Visual C</h3>
+
+The Routino source code (for the router at least) has been modified so that it
+will compile with the Microsoft Visual C compiler.
+
+<p>
+
+Compiling Routino with MSVC is not supported directly since there is only
+support for using <tt>Makefile</tt>s in Routino.  The files that need to be
+compiled for the Routino router can be found from the Makefile in
+the <tt>src</tt> directory listed in the <tt>ROUTER_OBJ</tt> variable.
+
+<p>
+
+To compile the router in slim mode the pre-processor definition <tt>SLIM=0</tt>
+must be set and for non-slim mode <tt>SLIM=1</tt> must be set.
+
+<p>
+
+The default directory for the Routino data files must be set in the
+<tt>ROUTINO_DATADIR</tt> pre-processor variable.  If the router command line
+<tt>--data</tt> option is going to be used then this variable can be set to any
+value.
+
+<p>
+
+Since Microsoft Visual C does not fully support the C99 standard it is necessary
+to tell the compiler how to handle the <tt>inline</tt> functions.  This can be
+done by passing in the command line option <tt>-Dinline=__inline</tt> to the C
+compiler.
+
+
+<h3 id="H_1_2_2">Using MinGW</h3>
+
+MinGW is the "Minimalist GNU for Windows" which includes some of the common GNU
+programs; principally gcc and related programs for software development.
+
+<p>
+
+The installer for MinGW can be downloaded from <tt>http://mingw.org/</tt>.  For
+compiling Routino the MinGW installer should be run and the following packages
+selected:
+
+<ul>
+  <li>mingw-base
+  <li>msys-base
+  <li>mingw32-pthreads-w32
+  <li>mingw32-libz (dev package)
+  <li>msys-perl
+</ul>
+
+<p>
+
+To compile Routino open a DOS command window and set the path to the installed
+MinGW and MSYS software.  For example if MinGW was installed in the
+<tt>C:/MinGW</tt> directory then the path needs to be set to
+<tt>C:\MinGW\bin;C:\MinGW\MSYS\1.0\bin</tt>.
+
+<p>
+
+From within this DOS command window change to the Routino source directory and
+compile using the MinGW version of <tt>make</tt> with this command
+<tt>mingw32-make</tt>.
+
+<p>
+
+After compiling Routino a set of library files are created (<tt>routino.dll</tt>,
+<tt>routino.def</tt> and <tt>routino.lib</tt>).  These should be usable for
+linking with programs compiled with MSVC.
+
+
+<h3 id="H_1_2_3">Using MinGW-W64</h3>
+
+MinGW-w64 is an alernative implementation of the same concept as MinGW but
+allows for compilation to 32-bit or 64-bit executables.
+
+<p>
+
+The website for MinGW-w64 is <tt>http://mingw-w64.org/</tt> but the downloads
+are available from <tt>http://win-builds.org/</tt>.  Installation of MinGW-w64
+is slightly different from that for MinGW but a similar set of packages will be
+required.
+
+<p>
+
+The compilation method for MinGW-w64 is the same as for MinGW and the same files
+will be compiled, the only difference is that by default a 64-bit version will
+be created.
+
+
+<h3 id="H_1_2_4">Limitations</h3>
+
+A native Microsoft Windows compilation of Routino is more complicated than
+compiling on Linux, other UNIX system or Cygwin.  This is probably not an option
+if you are unfamiliar with software development on Microsoft Windows.
+
+<p>
+
+The size of files that can be accessed with an MSVC or MinGW (32-bit) compiled
+version of Routino is limited to 32-bits (less than 4 GB).  The MinGW-w64
+compiler on 64-bit is able to handle larger files (bigger than 4 GB).
+
+<p>
+
+The Windows operating system does not have a function equivalent to the
+<tt>fork()</tt> function on UNIX.  This means that it is not possible to use
+the <tt>planetsplitter</tt> program's built-in file decompression with an MSVC
+or MinGW compiled version of Routino.
+
+
+<h2 id="H_1_3">Example Web Pages</h2>
+
+No instructions are available for using the Routino example web pages with the
+Microsoft Web server (IIS).
+
+<p>
+
+For information on setting up Apache see the "Example Web Pages" section of the
+main <a href="installation.html" title="Installation">installation instructions</a>.
+
+</div>
+
+<!-- Content End -->
+
+<!-- Footer Start -->
+
+<div class="footer">
+
+<address>
+© Andrew M. Bishop - <a href="http://www.routino.org/">http://www.routino.org/</a>
+</address>
+
+</div>
+
+<!-- Footer End -->
+
+</body>
+
+</html>
diff --git a/doc/html/installation.html b/doc/html/installation.html
index ccaac7a..1f03175 100644
--- a/doc/html/installation.html
+++ b/doc/html/installation.html
@@ -3,6 +3,7 @@
 
 <head>
 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<meta name="viewport" content="width=device-width, initial-scale=1">
 
 <title>Routino : Installation</title>
 
@@ -11,7 +12,7 @@
 
  Part of the Routino routing software.
 
- This file Copyright 2008-2014 Andrew M. Bishop
+ This file Copyright 2008-2015 Andrew M. Bishop
 
  This program is free software: you can redistribute it and/or modify
  it under the terms of the GNU Affero General Public License as published by
@@ -38,7 +39,6 @@
 
 <h1>Routino : Installation</h1>
 
-<hr>
 </div>
 
 <!-- Header End -->
@@ -51,8 +51,11 @@
 <h2 id="H_1_1">Quick Start Guide</h2>
 
 The instructions below are a complete list of the minimum required to get
-Routino installed and running under Apache on Debian Linux (other Linux versions
-will be similar).
+Routino installed and running under Apache on Debian Linux.  Other Linux
+versions will be similar and other UNIX based systems will also be similar
+although may have distinct differences.  There is some support in Routino for
+compiling on Microsoft Windows which has its own
+<a href="installation-ms-windows.html" title="MS Windows Installation">installation instructions</a>.
 
 <p>
 
@@ -67,6 +70,7 @@ after it has been uncompressed.  Most of the steps will need to be run as the
 root user.
 
 <p>
+
 The first thing to do is to install the packages which are required for
 compilation of Routino as described in the <a href="#H_1_2">Pre-Requisites</a>
 section below.
@@ -415,7 +419,6 @@ the file.
 <!-- Footer Start -->
 
 <div class="footer">
-<hr>
 
 <address>
 © Andrew M. Bishop - <a href="http://www.routino.org/">http://www.routino.org/</a>
diff --git a/doc/html/library.html b/doc/html/library.html
new file mode 100644
index 0000000..a849f6c
--- /dev/null
+++ b/doc/html/library.html
@@ -0,0 +1,967 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<meta name="viewport" content="width=device-width, initial-scale=1">
+
+<title>Routino : Library</title>
+
+<!--
+ Routino documentation - library
+
+ Part of the Routino routing software.
+
+ This file Copyright 2015 Andrew M. Bishop
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program.  If not, see http://www.gnu.org/licenses/.
+-->
+
+<link href="style.css" type="text/css" rel="stylesheet">
+
+<style type="text/css">
+
+/* Pre-processor definitions */
+
+SPAN.cxref-define-comment
+{
+ font-style:  normal;
+}
+
+SPAN.cxref-define
+{
+ font-family: monospace;
+ font-weight: bold;
+ font-style:  normal;
+
+ padding-top: 5px;
+}
+
+/* Type definitions */
+
+SPAN.cxref-type-comment
+{
+ font-style:  normal;
+}
+
+SPAN.cxref-type
+{
+ font-family: monospace;
+ font-weight: bold;
+ font-style:  normal;
+}
+
+/* Variable definitions */
+
+SPAN.cxref-variable-comment
+{
+ font-style:  normal;
+}
+
+SPAN.cxref-variable
+{
+ font-family: monospace;
+ font-weight: bold;
+ font-style:  normal;
+}
+
+/* Function definitions */
+
+SPAN.cxref-function-comment
+{
+ font-style:  normal;
+}
+
+SPAN.cxref-function
+{
+ font-family: monospace;
+ font-weight: bold;
+ font-style:  normal;
+}
+
+</style>
+
+</head>
+
+<body>
+
+<!-- Header Start -->
+
+<div class="header">
+
+<h1>Routino : Library</h1>
+
+</div>
+
+<!-- Header End -->
+
+<!-- Content Start -->
+
+<div class="content">
+
+<h2 id="H_1_1">Library Usage</h2>
+
+This page describes the <tt>libroutino</tt> shared library that can be
+compiled from the Routino source code and used in other programs.
+
+<h3 id="H_1_1_1">Compilation</h3>
+
+The <tt>libroutino</tt> shared library is compiled by default when the
+Routino source code is compiled.  There are two versions; a normal
+version and a 'slim' version that uses less memory but is slower.  The
+names of the libraries are <tt>libroutino.so</tt>
+and <tt>libroutino-slim.so</tt>
+
+<h3 id="H_1_1_2">Including</h3>
+
+To use the Routino library in another program the source code for that
+program should include the <tt>routino.h</tt> file.  The functions
+that are available in the library (both versions) are listed in this
+file along with all of the constants and data types that are required.
+
+<h3 id="H_1_1_3">Linking</h3>
+
+After compiling the program that uses the library it needs to be
+linked to the library.  For gcc this requires adding
+<tt>-lroutino</tt> or <tt>-lroutino-slim</tt> to the linker command
+line, possibly with a <tt>-L...</tt> parameter to specify the location
+of the library.
+
+<h3 id="H_1_1_4">Example Library Interface Code</h3>
+
+An example of a program that can link to the <tt>libroutino</tt>
+library is provided in the Routino source code called
+<tt>router+lib.c</tt>.  This is an almost exact re-implementation of
+the standard Routino <tt>router</tt> program using the
+<tt>libroutino</tt> library.
+
+
+<h2 id="H_1_2">Library License</h2>
+
+The source code for the <tt>libroutino</tt> and <tt>libroutino-slim</tt>
+libraries is the
+<a class="ext" title="Affero GPLv3" href="http://www.gnu.org/licenses/agpl-3.0.html">GNU Affero General Public License v3</a>
+the same as for the rest of the Routino software.
+
+<h3 id="H_1_2_1">Linking with AGPLv3 Source Code</h3>
+
+If <tt>libroutino</tt> is linked with other APGLv3 code then the same
+license applies to the combination as to the two parts.
+
+<h3 id="H_1_2_2">Linking with GPLv3 Source Code</h3>
+
+The AGPLv3 license is almost identical to the 
+<a class="ext" title="GPLv3" href="http://www.gnu.org/licenses/gpl-3.0.html">GNU General Public License v3</a>
+except that network interaction with an AGPLv3 program requires the
+same source code access as distributing compiled GPLv3 programs.
+This means that <tt>libroutino</tt> can be linked or combined with
+code that is released under the GPLv3 without changing the license of
+that code.
+<p>
+If there is no network interaction with the resulting program then the
+Routino source code can be treated as if it was GPLv3 code for the
+purposes of distribution and use.
+<p>
+If there is network interaction with the resulting program then the
+AGPLv3 license will apply since this is required by section 13 of the
+GPLv3.
+<br>
+The Software Freedom Law Center description of the GPLv3 and AGPLv3
+licenses describes
+<a class="ext" title="SFLC" href="http://www.softwarefreedom.org/resources/2014/SFLC-Guide_to_GPL_Compliance_2d_ed.html#section-13-use-with-the-gnu-affero-general-public-license">combining GPLv3 and APGLv3</a>.
+<br>
+My understanding is that only when modified Routino code is linked
+with GPLv3 code does network interaction require the modified Routino
+code to be released.
+
+<h3 id="H_1_2_3">Linking with Other Source Code</h3>
+
+Linking <tt>libroutino</tt> with code released under any other license
+must preserve the terms of the Routino license on the combination if
+the software is distributed or interacted with over a network.
+
+
+<h2 id="H_1_3">Routino Library API</h2>
+
+<h3>Preprocessor Definitions</h3>
+
+<p>
+<span class="cxref-define-comment"> A version number for the Routino API. </span>
+<br>
+<span class="cxref-define">#define ROUTINO_API_VERSION 7</span>
+
+<h4>Error Definitions</h4>
+
+<p>
+<span class="cxref-define-comment"> No error. </span>
+<br>
+<span class="cxref-define">#define ROUTINO_ERROR_NONE 0</span>
+<p>
+<span class="cxref-define-comment"> A function was called without the database variable set. </span>
+<br>
+<span class="cxref-define">#define ROUTINO_ERROR_NO_DATABASE 1</span>
+<p>
+<span class="cxref-define-comment"> A function was called without the profile variable set. </span>
+<br>
+<span class="cxref-define">#define ROUTINO_ERROR_NO_PROFILE 2</span>
+<p>
+<span class="cxref-define-comment"> A function was called without the translation variable set. </span>
+<br>
+<span class="cxref-define">#define ROUTINO_ERROR_NO_TRANSLATION 3</span>
+<p>
+<span class="cxref-define-comment"> The specified database to load did not exist. </span>
+<br>
+<span class="cxref-define">#define ROUTINO_ERROR_NO_DATABASE_FILES 11</span>
+<p>
+<span class="cxref-define-comment"> The specified database could not be loaded. </span>
+<br>
+<span class="cxref-define">#define ROUTINO_ERROR_BAD_DATABASE_FILES 12</span>
+<p>
+<span class="cxref-define-comment"> The specified profiles XML file did not exist. </span>
+<br>
+<span class="cxref-define">#define ROUTINO_ERROR_NO_PROFILES_XML 13</span>
+<p>
+<span class="cxref-define-comment"> The specified profiles XML file could not be loaded. </span>
+<br>
+<span class="cxref-define">#define ROUTINO_ERROR_BAD_PROFILES_XML 14</span>
+<p>
+<span class="cxref-define-comment"> The specified translations XML file did not exist. </span>
+<br>
+<span class="cxref-define">#define ROUTINO_ERROR_NO_TRANSLATIONS_XML 15</span>
+<p>
+<span class="cxref-define-comment"> The specified translations XML file could not be loaded. </span>
+<br>
+<span class="cxref-define">#define ROUTINO_ERROR_BAD_TRANSLATIONS_XML 16</span>
+<p>
+<span class="cxref-define-comment"> The requested profile name does not exist in the loaded XML file. </span>
+<br>
+<span class="cxref-define">#define ROUTINO_ERROR_NO_SUCH_PROFILE 21</span>
+<p>
+<span class="cxref-define-comment"> The requested translation language does not exist in the loaded XML file. </span>
+<br>
+<span class="cxref-define">#define ROUTINO_ERROR_NO_SUCH_TRANSLATION 22</span>
+<p>
+<span class="cxref-define-comment"> There is no highway near the coordinates to place a waypoint. </span>
+<br>
+<span class="cxref-define">#define ROUTINO_ERROR_NO_NEARBY_HIGHWAY 31</span>
+<p>
+<span class="cxref-define-comment"> The profile and database do not work together. </span>
+<br>
+<span class="cxref-define">#define ROUTINO_ERROR_PROFILE_DATABASE_ERR 41</span>
+<p>
+<span class="cxref-define-comment"> The profile being used has not been validated. </span>
+<br>
+<span class="cxref-define">#define ROUTINO_ERROR_NOTVALID_PROFILE 42</span>
+<p>
+<span class="cxref-define-comment"> The user specified profile contained invalid data. </span>
+<br>
+<span class="cxref-define">#define ROUTINO_ERROR_BAD_USER_PROFILE 43</span>
+<p>
+<span class="cxref-define-comment"> The routing options specified are not consistent with each other. </span>
+<br>
+<span class="cxref-define">#define ROUTINO_ERROR_BAD_OPTIONS 51</span>
+<p>
+<span class="cxref-define-comment"> There is a mismatch between the library and caller API version. </span>
+<br>
+<span class="cxref-define">#define ROUTINO_ERROR_WRONG_API_VERSION 61</span>
+<p>
+<span class="cxref-define-comment"> The progress function returned false. </span>
+<br>
+<span class="cxref-define">#define ROUTINO_ERROR_PROGRESS_ABORTED 71</span>
+<p>
+<span class="cxref-define-comment"> A route could not be found to waypoint 1. </span>
+<br>
+<span class="cxref-define">#define ROUTINO_ERROR_NO_ROUTE_1 1001</span>
+<p>
+<span class="cxref-define-comment"> A route could not be found to waypoint 2. </span>
+<br>
+<span class="cxref-define">#define ROUTINO_ERROR_NO_ROUTE_2 1002</span>
+<p>
+<span class="cxref-define-comment"> A route could not be found to waypoint 3. </span>
+<br>
+<span class="cxref-define">#define ROUTINO_ERROR_NO_ROUTE_3 1003</span>
+
+<h4>Routino Option Definitions</h4>
+
+<p>
+<span class="cxref-define-comment"> Calculate the shortest route. </span>
+<br>
+<span class="cxref-define">#define ROUTINO_ROUTE_SHORTEST 0</span>
+<p>
+<span class="cxref-define-comment"> Calculate the quickest route. </span>
+<br>
+<span class="cxref-define">#define ROUTINO_ROUTE_QUICKEST 1</span>
+<p>
+<span class="cxref-define-comment"> Output an HTML route file. </span>
+<br>
+<span class="cxref-define">#define ROUTINO_ROUTE_FILE_HTML 2</span>
+<p>
+<span class="cxref-define-comment"> Output a GPX track file. </span>
+<br>
+<span class="cxref-define">#define ROUTINO_ROUTE_FILE_GPX_TRACK 4</span>
+<p>
+<span class="cxref-define-comment"> Output a GPX route file. </span>
+<br>
+<span class="cxref-define">#define ROUTINO_ROUTE_FILE_GPX_ROUTE 8</span>
+<p>
+<span class="cxref-define-comment"> Output a text file with important junctions. </span>
+<br>
+<span class="cxref-define">#define ROUTINO_ROUTE_FILE_TEXT 16</span>
+<p>
+<span class="cxref-define-comment"> Output a text file with all nodes and segments. </span>
+<br>
+<span class="cxref-define">#define ROUTINO_ROUTE_FILE_TEXT_ALL 32</span>
+<p>
+<span class="cxref-define-comment"> Output a single file type to stdout. </span>
+<br>
+<span class="cxref-define">#define ROUTINO_ROUTE_FILE_STDOUT 64</span>
+<p>
+<span class="cxref-define-comment"> Output a linked list of points containing the HTML file information but as plain text. </span>
+<br>
+<span class="cxref-define">#define ROUTINO_ROUTE_LIST_HTML 128</span>
+<p>
+<span class="cxref-define-comment"> Output a linked list of points containing the HTML file information as plain text and with all points. </span>
+<br>
+<span class="cxref-define">#define ROUTINO_ROUTE_LIST_HTML_ALL 256</span>
+<p>
+<span class="cxref-define-comment"> Output a linked list of points containing the text file information. </span>
+<br>
+<span class="cxref-define">#define ROUTINO_ROUTE_LIST_TEXT 512</span>
+<p>
+<span class="cxref-define-comment"> Output a linked list of points containing the text all file information. </span>
+<br>
+<span class="cxref-define">#define ROUTINO_ROUTE_LIST_TEXT_ALL 1024</span>
+
+<h4>Linked List Output Point Definitions</h4>
+
+<p>
+<span class="cxref-define-comment"> An unimportant, intermediate, node. </span>
+<br>
+<span class="cxref-define">#define ROUTINO_POINT_UNIMPORTANT 0</span>
+<p>
+<span class="cxref-define-comment"> A roundabout exit that is not taken. </span>
+<br>
+<span class="cxref-define">#define ROUTINO_POINT_RB_NOT_EXIT 1</span>
+<p>
+<span class="cxref-define-comment"> An un-interesting junction where the route continues without comment. </span>
+<br>
+<span class="cxref-define">#define ROUTINO_POINT_JUNCT_CONT 2</span>
+<p>
+<span class="cxref-define-comment"> The highway changes type but nothing else happens. </span>
+<br>
+<span class="cxref-define">#define ROUTINO_POINT_CHANGE 3</span>
+<p>
+<span class="cxref-define-comment"> An interesting junction to be described. </span>
+<br>
+<span class="cxref-define">#define ROUTINO_POINT_JUNCT_IMPORT 4</span>
+<p>
+<span class="cxref-define-comment"> The entrance to a roundabout. </span>
+<br>
+<span class="cxref-define">#define ROUTINO_POINT_RB_ENTRY 5</span>
+<p>
+<span class="cxref-define-comment"> The exit from a roundabout. </span>
+<br>
+<span class="cxref-define">#define ROUTINO_POINT_RB_EXIT 6</span>
+<p>
+<span class="cxref-define-comment"> The location of a mini-roundabout. </span>
+<br>
+<span class="cxref-define">#define ROUTINO_POINT_MINI_RB 7</span>
+<p>
+<span class="cxref-define-comment"> The location of a U-turn. </span>
+<br>
+<span class="cxref-define">#define ROUTINO_POINT_UTURN 8</span>
+<p>
+<span class="cxref-define-comment"> A waypoint. </span>
+<br>
+<span class="cxref-define">#define ROUTINO_POINT_WAYPOINT 9</span>
+
+<h4>Profile Definitions</h4>
+
+<p>
+<span class="cxref-define-comment"> A Motorway highway. </span>
+<br>
+<span class="cxref-define">#define ROUTINO_HIGHWAY_MOTORWAY 1</span>
+<p>
+<span class="cxref-define-comment"> A Trunk highway. </span>
+<br>
+<span class="cxref-define">#define ROUTINO_HIGHWAY_TRUNK 2</span>
+<p>
+<span class="cxref-define-comment"> A Primary highway. </span>
+<br>
+<span class="cxref-define">#define ROUTINO_HIGHWAY_PRIMARY 3</span>
+<p>
+<span class="cxref-define-comment"> A Secondary highway. </span>
+<br>
+<span class="cxref-define">#define ROUTINO_HIGHWAY_SECONDARY 4</span>
+<p>
+<span class="cxref-define-comment"> A Tertiary highway. </span>
+<br>
+<span class="cxref-define">#define ROUTINO_HIGHWAY_TERTIARY 5</span>
+<p>
+<span class="cxref-define-comment"> A Unclassified highway. </span>
+<br>
+<span class="cxref-define">#define ROUTINO_HIGHWAY_UNCLASSIFIED 6</span>
+<p>
+<span class="cxref-define-comment"> A Residential highway. </span>
+<br>
+<span class="cxref-define">#define ROUTINO_HIGHWAY_RESIDENTIAL 7</span>
+<p>
+<span class="cxref-define-comment"> A Service highway. </span>
+<br>
+<span class="cxref-define">#define ROUTINO_HIGHWAY_SERVICE 8</span>
+<p>
+<span class="cxref-define-comment"> A Track highway. </span>
+<br>
+<span class="cxref-define">#define ROUTINO_HIGHWAY_TRACK 9</span>
+<p>
+<span class="cxref-define-comment"> A Cycleway highway. </span>
+<br>
+<span class="cxref-define">#define ROUTINO_HIGHWAY_CYCLEWAY 10</span>
+<p>
+<span class="cxref-define-comment"> A Path highway. </span>
+<br>
+<span class="cxref-define">#define ROUTINO_HIGHWAY_PATH 11</span>
+<p>
+<span class="cxref-define-comment"> A Steps highway. </span>
+<br>
+<span class="cxref-define">#define ROUTINO_HIGHWAY_STEPS 12</span>
+<p>
+<span class="cxref-define-comment"> A Ferry highway. </span>
+<br>
+<span class="cxref-define">#define ROUTINO_HIGHWAY_FERRY 13</span>
+<p>
+<span class="cxref-define-comment"> A Paved highway. </span>
+<br>
+<span class="cxref-define">#define ROUTINO_PROPERTY_PAVED 1</span>
+<p>
+<span class="cxref-define-comment"> A Multilane highway. </span>
+<br>
+<span class="cxref-define">#define ROUTINO_PROPERTY_MULTILANE 2</span>
+<p>
+<span class="cxref-define-comment"> A Bridge highway. </span>
+<br>
+<span class="cxref-define">#define ROUTINO_PROPERTY_BRIDGE 3</span>
+<p>
+<span class="cxref-define-comment"> A Tunnel highway. </span>
+<br>
+<span class="cxref-define">#define ROUTINO_PROPERTY_TUNNEL 4</span>
+<p>
+<span class="cxref-define-comment"> A Footroute highway. </span>
+<br>
+<span class="cxref-define">#define ROUTINO_PROPERTY_FOOTROUTE 5</span>
+<p>
+<span class="cxref-define-comment"> A Bicycleroute highway. </span>
+<br>
+<span class="cxref-define">#define ROUTINO_PROPERTY_BICYCLEROUTE 6</span>
+
+
+<h3>Type Definitions</h3>
+
+<h4><a name="type-Routino_Database">Typedef Routino_Database</a></h4>
+
+<p>
+<span class="cxref-type-comment"> A data structure to hold a Routino database loaded from a file (the contents are private). </span>
+<br>
+<span class="cxref-type">typedef struct _Routino_Database Routino_Database</span>
+
+<h4><a name="type-Routino_Waypoint">Typedef Routino_Waypoint</a></h4>
+
+<p>
+<span class="cxref-type-comment"> A data structure to hold a Routino waypoint found within the database (the contents are private). </span>
+<br>
+<span class="cxref-type">typedef struct _Routino_Waypoint Routino_Waypoint</span>
+
+<h4><a name="type-Routino_Profile">Typedef Routino_Profile</a></h4>
+
+<p>
+<span class="cxref-type-comment"> A data structure to hold a Routino routing profile (the contents are private). </span>
+<br>
+<span class="cxref-type">typedef struct _Routino_Profile Routino_Profile</span>
+
+<h4><a name="type-Routino_Translation">Typedef Routino_Translation</a></h4>
+
+<p>
+<span class="cxref-type-comment"> A data structure to hold a Routino translation (the contents are private). </span>
+<br>
+<span class="cxref-type">typedef struct _Routino_Translation Routino_Translation</span>
+
+<h4><a name="type-Routino_UserProfile">Typedef Routino_UserProfile</a></h4>
+
+<p>
+<span class="cxref-type-comment"> A data structure to hold a routing profile that can be defined by the user. </span>
+<br>
+<span class="cxref-type">typedef struct _Routino_UserProfile Routino_UserProfile</span>
+<br>
+<table class="noborder-left">
+  <tr>
+    <td><span class="cxref-type">struct _Routino_UserProfile</span>
+    <td> 
+  </tr>
+  <tr>
+    <td>   <span class="cxref-type">{</span>
+    <td> 
+  </tr>
+  <tr>
+    <td>     
+<span class="cxref-type">int transport;</span>
+    <td><span class="cxref-type-comment"> The type of transport. </span>
+  </tr>
+  <tr>
+    <td>     
+<span class="cxref-type">float highway[14];</span>
+    <td><span class="cxref-type-comment"> A floating point preference for travel on the highway (range 0 to 1). </span>
+  </tr>
+  <tr>
+    <td>     
+<span class="cxref-type">float speed[14];</span>
+    <td><span class="cxref-type-comment"> The maximum speed on each type of highway (km/hour). </span>
+  </tr>
+  <tr>
+    <td>     
+<span class="cxref-type">float props[7];</span>
+    <td><span class="cxref-type-comment"> A floating point preference for ways with this attribute (range 0 to 1). </span>
+  </tr>
+  <tr>
+    <td>     
+<span class="cxref-type">int oneway;</span>
+    <td><span class="cxref-type-comment"> A flag to indicate if one-way restrictions apply. </span>
+  </tr>
+  <tr>
+    <td>     
+<span class="cxref-type">int turns;</span>
+    <td><span class="cxref-type-comment"> A flag to indicate if turn restrictions apply. </span>
+  </tr>
+  <tr>
+    <td>     
+<span class="cxref-type">float weight;</span>
+    <td><span class="cxref-type-comment"> The weight of the vehicle (in tonnes). </span>
+  </tr>
+  <tr>
+    <td>     
+<span class="cxref-type">float height;</span>
+    <td><span class="cxref-type-comment"> The height of the vehicle (in metres). </span>
+  </tr>
+  <tr>
+    <td>     
+<span class="cxref-type">float width;</span>
+    <td><span class="cxref-type-comment"> The width of vehicle (in metres). </span>
+  </tr>
+  <tr>
+    <td>     
+<span class="cxref-type">float length;</span>
+    <td><span class="cxref-type-comment"> The length of vehicle (in metres). </span>
+  </tr>
+  <tr>
+    <td>   <span class="cxref-type">}</span>
+    <td> 
+  </tr>
+</table>
+
+<h4><a name="type-Routino_Output">Typedef Routino_Output</a></h4>
+
+<p>
+<span class="cxref-type-comment"> Forward declaration of the Routino_Output data type. </span>
+<br>
+<span class="cxref-type">typedef struct _Routino_Output Routino_Output</span>
+
+<h4><a name="type-struct-_Routino_Output">Type struct _Routino_Output</a></h4>
+
+<p>
+<span class="cxref-type-comment"> A linked list output of the calculated route whose contents depend on the ROUTINO_ROUTE_LIST_* options selected. </span>
+<br>
+<span class="cxref-type">struct _Routino_Output</span>
+<br>
+<table class="noborder-left">
+  <tr>
+    <td><span class="cxref-type">struct _Routino_Output</span>
+    <td> 
+  </tr>
+  <tr>
+    <td>   <span class="cxref-type">{</span>
+    <td> 
+  </tr>
+  <tr>
+    <td>     
+<span class="cxref-type">Routino_Output* next;</span>
+    <td><span class="cxref-type-comment"> A pointer to the next route section. </span>
+  </tr>
+  <tr>
+    <td>     
+<span class="cxref-type">float lon;</span>
+    <td><span class="cxref-type-comment"> The longitude of the point (radians). </span>
+  </tr>
+  <tr>
+    <td>     
+<span class="cxref-type">float lat;</span>
+    <td><span class="cxref-type-comment"> The latitude of the point (radians). </span>
+  </tr>
+  <tr>
+    <td>     
+<span class="cxref-type">float dist;</span>
+    <td><span class="cxref-type-comment"> The total distance travelled (kilometres) up to the point. </span>
+  </tr>
+  <tr>
+    <td>     
+<span class="cxref-type">float time;</span>
+    <td><span class="cxref-type-comment"> The total journey time (seconds) up to the point. </span>
+  </tr>
+  <tr>
+    <td>     
+<span class="cxref-type">float speed;</span>
+    <td><span class="cxref-type-comment"> The speed (km/hr) for this section of the route (ROUTINO_ROUTE_LIST_TEXT_ALL format only). </span>
+  </tr>
+  <tr>
+    <td>     
+<span class="cxref-type">int type;</span>
+    <td><span class="cxref-type-comment"> The type of point (one of the ROUTINO_POINT_* values). </span>
+  </tr>
+  <tr>
+    <td>     
+<span class="cxref-type">int turn;</span>
+    <td><span class="cxref-type-comment"> The amount to turn (degrees) for the next section of the route (ROUTINO_ROUTE_LIST_TEXT or ROUTINO_ROUTE_LIST_HTML or ROUTINO_ROUTE_LIST_HTML_ALL format). </span>
+  </tr>
+  <tr>
+    <td>     
+<span class="cxref-type">int bearing;</span>
+    <td><span class="cxref-type-comment"> The compass direction (degrees) for the next section of the route. </span>
+  </tr>
+  <tr>
+    <td>     
+<span class="cxref-type">char* name;</span>
+    <td><span class="cxref-type-comment"> The name of the next section of the route (ROUTINO_ROUTE_LIST_TEXT or ROUTINO_ROUTE_LIST_HTML or ROUTINO_ROUTE_LIST_HTML_ALL format) or previous section of the route (ROUTINO_ROUTE_LIST_TEXT_ALL format). </span>
+  </tr>
+  <tr>
+    <td>     
+<span class="cxref-type">char* desc1;</span>
+    <td><span class="cxref-type-comment"> The first part of the description of the next section of route (ROUTINO_ROUTE_LIST_HTML or ROUTINO_ROUTE_LIST_HTML format). </span>
+  </tr>
+  <tr>
+    <td>     
+<span class="cxref-type">char* desc2;</span>
+    <td><span class="cxref-type-comment"> The second part of the description of the next section of route (ROUTINO_ROUTE_LIST_HTML or ROUTINO_ROUTE_LIST_HTML format). </span>
+  </tr>
+  <tr>
+    <td>     
+<span class="cxref-type">char* desc3;</span>
+    <td><span class="cxref-type-comment"> The third part of the description, the total distance and time at the end of the next section of route (ROUTINO_ROUTE_LIST_HTML or ROUTINO_ROUTE_LIST_HTML format). </span>
+  </tr>
+  <tr>
+    <td>   <span class="cxref-type">}</span>
+    <td> 
+  </tr>
+</table>
+
+<h4><a name="type-Routino_ProgressFunc">Typedef Routino_ProgressFunc</a></h4>
+
+<p>
+<span class="cxref-type-comment"> A type of function that can be used as a callback to indicate routing progress, if it returns false the router stops. </span>
+<br>
+<span class="cxref-type">typedef int (*Routino_ProgressFunc)(double complete)</span>
+
+<h3>Variable Definitions</h3>
+
+<h4><a name="var-Routino_APIVersion">Global Variable Routino_APIVersion</a></h4>
+
+<p>
+<span class="cxref-variable-comment"> Contains the libroutino API version number. </span>
+<br>
+<span class="cxref-variable">int Routino_APIVersion</span>
+
+<h4><a name="var-Routino_errno">Global Variable Routino_errno</a></h4>
+
+<p>
+<span class="cxref-variable-comment"> Contains the error number of the most recent Routino function (one of the ROUTINO_ERROR_* values). </span>
+<br>
+<span class="cxref-variable">int Routino_errno</span>
+
+
+<h3>Function Definitions</h3>
+
+<h4><a name="func-Routino_CalculateRoute">Global Function Routino_CalculateRoute()</a></h4>
+
+<p>
+<span class="cxref-function-comment">  Calculate a route using a loaded database, chosen profile, chosen translation and set of waypoints.</span>
+<br>
+<span class="cxref-function">Routino_Output* Routino_CalculateRoute ( Routino_Database* database, Routino_Profile* profile, Routino_Translation* translation, Routino_Waypoint** waypoints, int nwaypoints, int options, Routino_ProgressFunc progress )</span>
+<br>
+<dl>
+  <dt><span class="cxref-function">Routino_Output* Routino_CalculateRoute</span>
+  <dd><span class="cxref-function-comment">Returns the head of a linked list of route data (if requested) or NULL.</span>
+  <dt><span class="cxref-function">Routino_Database* database</span>
+  <dd><span class="cxref-function-comment">The loaded database to use.</span>
+  <dt><span class="cxref-function">Routino_Profile* profile</span>
+  <dd><span class="cxref-function-comment">The chosen routing profile to use.</span>
+  <dt><span class="cxref-function">Routino_Translation* translation</span>
+  <dd><span class="cxref-function-comment">The chosen translation information to use.</span>
+  <dt><span class="cxref-function">Routino_Waypoint** waypoints</span>
+  <dd><span class="cxref-function-comment">The set of waypoints.</span>
+  <dt><span class="cxref-function">int nwaypoints</span>
+  <dd><span class="cxref-function-comment">The number of waypoints.</span>
+  <dt><span class="cxref-function">int options</span>
+  <dd><span class="cxref-function-comment">The set of routing options (ROUTINO_ROUTE_*) ORed together.</span>
+  <dt><span class="cxref-function">Routino_ProgressFunc progress</span>
+  <dd><span class="cxref-function-comment">A function to be called occasionally to report progress or NULL.</span>
+</dl>
+
+<h4><a name="func-Routino_Check_API_Version">Global Function Routino_Check_API_Version()</a></h4>
+
+<p>
+<span class="cxref-function-comment">  Check the version of the library used by the caller against the library version</span>
+<br>
+<span class="cxref-function">int Routino_Check_API_Version ( int caller_version )</span>
+<br>
+<dl>
+  <dt><span class="cxref-function">int Routino_Check_API_Version</span>
+  <dd><span class="cxref-function-comment">Returns ROUTINO_ERROR_NONE if OK or ROUTINO_ERROR_WRONG_VERSION if there is an error.</span>
+  <dt><span class="cxref-function">int caller_version</span>
+  <dd><span class="cxref-function-comment">The version of the API used in the caller.</span>
+</dl>
+<br>
+<span class="cxref-function-comment">  This function should not be called directly, use the macro Routino_CheckAPIVersion() which takes no arguments.</span>
+
+<p>
+<span class="cxref-define-comment"> A wrapper function to simplify the API version check. </span>
+<br>
+<span class="cxref-define">#define Routino_CheckAPIVersion()</span>
+
+<h4><a name="func-Routino_CreateProfileFromUserProfile">Global Function Routino_CreateProfileFromUserProfile()</a></h4>
+
+<p>
+<span class="cxref-function-comment">  Create a fully formed Routino Profile from a Routino User Profile.</span>
+<br>
+<span class="cxref-function">Routino_Profile* Routino_CreateProfileFromUserProfile ( Routino_UserProfile* profile )</span>
+<br>
+<dl>
+  <dt><span class="cxref-function">Routino_Profile* Routino_CreateProfileFromUserProfile</span>
+  <dd><span class="cxref-function-comment">Returns an allocated Routino Profile.</span>
+  <dt><span class="cxref-function">Routino_UserProfile* profile</span>
+  <dd><span class="cxref-function-comment">The user specified profile to convert (not modified by this).</span>
+</dl>
+
+<h4><a name="func-Routino_CreateUserProfileFromProfile">Global Function Routino_CreateUserProfileFromProfile()</a></h4>
+
+<p>
+<span class="cxref-function-comment">  Create a Routino User Profile from a Routino Profile loaded from an XML file.</span>
+<br>
+<span class="cxref-function">Routino_UserProfile* Routino_CreateUserProfileFromProfile ( Routino_Profile* profile )</span>
+<br>
+<dl>
+  <dt><span class="cxref-function">Routino_UserProfile* Routino_CreateUserProfileFromProfile</span>
+  <dd><span class="cxref-function-comment">Returns an allocated Routino User Profile.</span>
+  <dt><span class="cxref-function">Routino_Profile* profile</span>
+  <dd><span class="cxref-function-comment">The Routino Profile to convert (not modified by this).</span>
+</dl>
+
+<h4><a name="func-Routino_DeleteRoute">Global Function Routino_DeleteRoute()</a></h4>
+
+<p>
+<span class="cxref-function-comment">  Delete the linked list created by Routino_CalculateRoute.</span>
+<br>
+<span class="cxref-function">void Routino_DeleteRoute ( Routino_Output* output )</span>
+<br>
+<dl>
+  <dt><span class="cxref-function">Routino_Output* output</span>
+  <dd><span class="cxref-function-comment">The output to be deleted.</span>
+</dl>
+
+<h4><a name="func-Routino_FindWaypoint">Global Function Routino_FindWaypoint()</a></h4>
+
+<p>
+<span class="cxref-function-comment">  Finds the nearest point in the database to the specified latitude and longitude.</span>
+<br>
+<span class="cxref-function">Routino_Waypoint* Routino_FindWaypoint ( Routino_Database* database, Routino_Profile* profile, double latitude, double longitude )</span>
+<br>
+<dl>
+  <dt><span class="cxref-function">Routino_Waypoint* Routino_FindWaypoint</span>
+  <dd><span class="cxref-function-comment">Returns a pointer to a newly allocated Routino waypoint or NULL if none could be found.</span>
+  <dt><span class="cxref-function">Routino_Database* database</span>
+  <dd><span class="cxref-function-comment">The Routino database to use.</span>
+  <dt><span class="cxref-function">Routino_Profile* profile</span>
+  <dd><span class="cxref-function-comment">The Routino profile to use.</span>
+  <dt><span class="cxref-function">double latitude</span>
+  <dd><span class="cxref-function-comment">The latitude in degrees of the point.</span>
+  <dt><span class="cxref-function">double longitude</span>
+  <dd><span class="cxref-function-comment">The longitude in degrees of the point.</span>
+</dl>
+
+<h4><a name="func-Routino_FreeXMLProfiles">Global Function Routino_FreeXMLProfiles()</a></h4>
+
+<p>
+<span class="cxref-function-comment">  Free the internal memory that was allocated for the Routino profiles loaded from the XML file.</span>
+<br>
+<span class="cxref-function">void Routino_FreeXMLProfiles ( void )</span>
+
+<h4><a name="func-Routino_FreeXMLTranslations">Global Function Routino_FreeXMLTranslations()</a></h4>
+
+<p>
+<span class="cxref-function-comment">  Free the internal memory that was allocated for the Routino translations loaded from the XML file.</span>
+<br>
+<span class="cxref-function">void Routino_FreeXMLTranslations ( void )</span>
+
+<h4><a name="func-Routino_GetProfile">Global Function Routino_GetProfile()</a></h4>
+
+<p>
+<span class="cxref-function-comment">  Select a specific routing profile from the set of Routino profiles that have been loaded from the XML file or NULL in case of an error.</span>
+<br>
+<span class="cxref-function">Routino_Profile* Routino_GetProfile ( const char* name )</span>
+<br>
+<dl>
+  <dt><span class="cxref-function">Routino_Profile* Routino_GetProfile</span>
+  <dd><span class="cxref-function-comment">Returns a pointer to an internal data structure - do not free.</span>
+  <dt><span class="cxref-function">const char* name</span>
+  <dd><span class="cxref-function-comment">The name of the profile to select.</span>
+</dl>
+
+<h4><a name="func-Routino_GetProfileNames">Global Function Routino_GetProfileNames()</a></h4>
+
+<p>
+<span class="cxref-function-comment">  Return a list of the profile names that have been loaded from the XML file.</span>
+<br>
+<span class="cxref-function">char** Routino_GetProfileNames ( void )</span>
+<br>
+<dl>
+  <dt><span class="cxref-function">char** Routino_GetProfileNames</span>
+  <dd><span class="cxref-function-comment">Returns a NULL terminated list of strings - all allocated.</span>
+</dl>
+
+<h4><a name="func-Routino_GetTranslation">Global Function Routino_GetTranslation()</a></h4>
+
+<p>
+<span class="cxref-function-comment">  Select a specific translation from the set of Routino translations that have been loaded from the XML file or NULL in case of an error.</span>
+<br>
+<span class="cxref-function">Routino_Translation* Routino_GetTranslation ( const char* language )</span>
+<br>
+<dl>
+  <dt><span class="cxref-function">Routino_Translation* Routino_GetTranslation</span>
+  <dd><span class="cxref-function-comment">Returns a pointer to an internal data structure - do not free.</span>
+  <dt><span class="cxref-function">const char* language</span>
+  <dd><span class="cxref-function-comment">The language to select (as a country code, e.g. 'en', 'de') or an empty string for the first in the file or NULL for the built-in English version.</span>
+</dl>
+
+<h4><a name="func-Routino_GetTranslationLanguageFullNames">Global Function Routino_GetTranslationLanguageFullNames()</a></h4>
+
+<p>
+<span class="cxref-function-comment">  Return a list of the full names of the translation languages that have been loaded from the XML file.</span>
+<br>
+<span class="cxref-function">char** Routino_GetTranslationLanguageFullNames ( void )</span>
+<br>
+<dl>
+  <dt><span class="cxref-function">char** Routino_GetTranslationLanguageFullNames</span>
+  <dd><span class="cxref-function-comment">Returns a NULL terminated list of strings - all allocated.</span>
+</dl>
+
+<h4><a name="func-Routino_GetTranslationLanguages">Global Function Routino_GetTranslationLanguages()</a></h4>
+
+<p>
+<span class="cxref-function-comment">  Return a list of the translation languages that have been loaded from the XML file.</span>
+<br>
+<span class="cxref-function">char** Routino_GetTranslationLanguages ( void )</span>
+<br>
+<dl>
+  <dt><span class="cxref-function">char** Routino_GetTranslationLanguages</span>
+  <dd><span class="cxref-function-comment">Returns a NULL terminated list of strings - all allocated.</span>
+</dl>
+
+<h4><a name="func-Routino_LoadDatabase">Global Function Routino_LoadDatabase()</a></h4>
+
+<p>
+<span class="cxref-function-comment">  Load a database of files for Routino to use for routing.</span>
+<br>
+<span class="cxref-function">Routino_Database* Routino_LoadDatabase ( const char* dirname, const char* prefix )</span>
+<br>
+<dl>
+  <dt><span class="cxref-function">Routino_Database* Routino_LoadDatabase</span>
+  <dd><span class="cxref-function-comment">Returns a pointer to the database.</span>
+  <dt><span class="cxref-function">const char* dirname</span>
+  <dd><span class="cxref-function-comment">The pathname of the directory containing the database files.</span>
+  <dt><span class="cxref-function">const char* prefix</span>
+  <dd><span class="cxref-function-comment">The prefix of the database files.</span>
+</dl>
+
+<h4><a name="func-Routino_ParseXMLProfiles">Global Function Routino_ParseXMLProfiles()</a></h4>
+
+<p>
+<span class="cxref-function-comment">  Parse a Routino XML file containing profiles, must be called before selecting a profile.</span>
+<br>
+<span class="cxref-function">int Routino_ParseXMLProfiles ( const char* filename )</span>
+<br>
+<dl>
+  <dt><span class="cxref-function">int Routino_ParseXMLProfiles</span>
+  <dd><span class="cxref-function-comment">Returns non-zero in case of an error or zero if there was no error.</span>
+  <dt><span class="cxref-function">const char* filename</span>
+  <dd><span class="cxref-function-comment">The full pathname of the file to read.</span>
+</dl>
+
+<h4><a name="func-Routino_ParseXMLTranslations">Global Function Routino_ParseXMLTranslations()</a></h4>
+
+<p>
+<span class="cxref-function-comment">  Parse a Routino XML file containing translations, must be called before selecting a translation.</span>
+<br>
+<span class="cxref-function">int Routino_ParseXMLTranslations ( const char* filename )</span>
+<br>
+<dl>
+  <dt><span class="cxref-function">int Routino_ParseXMLTranslations</span>
+  <dd><span class="cxref-function-comment">Returns non-zero in case of an error or zero if there was no error.</span>
+  <dt><span class="cxref-function">const char* filename</span>
+  <dd><span class="cxref-function-comment">The full pathname of the file to read.</span>
+</dl>
+
+<h4><a name="func-Routino_UnloadDatabase">Global Function Routino_UnloadDatabase()</a></h4>
+
+<p>
+<span class="cxref-function-comment">  Close the database files that were opened by a call to Routino_LoadDatabase().</span>
+<br>
+<span class="cxref-function">void Routino_UnloadDatabase ( Routino_Database* database )</span>
+<br>
+<dl>
+  <dt><span class="cxref-function">Routino_Database* database</span>
+  <dd><span class="cxref-function-comment">The database to close.</span>
+</dl>
+
+<h4><a name="func-Routino_ValidateProfile">Global Function Routino_ValidateProfile()</a></h4>
+
+<p>
+<span class="cxref-function-comment">  Validates that a selected routing profile is valid for use with the selected routing database.</span>
+<br>
+<span class="cxref-function">int Routino_ValidateProfile ( Routino_Database* database, Routino_Profile* profile )</span>
+<br>
+<dl>
+  <dt><span class="cxref-function">int Routino_ValidateProfile</span>
+  <dd><span class="cxref-function-comment">Returns zero if OK or something else in case of an error.</span>
+  <dt><span class="cxref-function">Routino_Database* database</span>
+  <dd><span class="cxref-function-comment">The Routino database to use.</span>
+  <dt><span class="cxref-function">Routino_Profile* profile</span>
+  <dd><span class="cxref-function-comment">The Routino profile to validate.</span>
+</dl>
+
+
+</div>
+
+<!-- Content End -->
+
+<!-- Footer Start -->
+
+<div class="footer">
+
+<address>
+© Andrew M. Bishop - <a href="http://www.routino.org/">http://www.routino.org/</a>
+</address>
+
+</div>
+
+<!-- Footer End -->
+
+</body>
+
+</html>
diff --git a/doc/html/limits.html b/doc/html/limits.html
index f7074bb..eb100bf 100644
--- a/doc/html/limits.html
+++ b/doc/html/limits.html
@@ -3,6 +3,7 @@
 
 <head>
 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<meta name="viewport" content="width=device-width, initial-scale=1">
 
 <title>Routino : Numerical Limits</title>
 
@@ -11,7 +12,7 @@
 
  Part of the Routino routing software.
 
- This file Copyright 2013 Andrew M. Bishop
+ This file Copyright 2013-2015 Andrew M. Bishop
 
  This program is free software: you can redistribute it and/or modify
  it under the terms of the GNU Affero General Public License as published by
@@ -38,7 +39,6 @@
 
 <h1>Routino : Numerical Limits</h1>
 
-<hr>
 </div>
 
 <!-- Header End -->
@@ -229,7 +229,6 @@ about 50% when this change is made.
 <!-- Footer Start -->
 
 <div class="footer">
-<hr>
 
 <address>
 © Andrew M. Bishop - <a href="http://www.routino.org/">http://www.routino.org/</a>
diff --git a/doc/html/output.html b/doc/html/output.html
index 4049f55..467bf4e 100644
--- a/doc/html/output.html
+++ b/doc/html/output.html
@@ -3,6 +3,7 @@
 
 <head>
 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<meta name="viewport" content="width=device-width, initial-scale=1">
 
 <title>Routino : Output</title>
 
@@ -11,7 +12,7 @@
 
  Part of the Routino routing software.
 
- This file Copyright 2008-2013 Andrew M. Bishop
+ This file Copyright 2008-2015 Andrew M. Bishop
 
  This program is free software: you can redistribute it and/or modify
  it under the terms of the GNU Affero General Public License as published by
@@ -38,7 +39,6 @@
 
 <h1>Routino : Output</h1>
 
-<hr>
 </div>
 
 <!-- Header End -->
@@ -395,7 +395,6 @@ For each of the lines the individual fields contain the following:
 <!-- Footer Start -->
 
 <div class="footer">
-<hr>
 
 <address>
 © Andrew M. Bishop - <a href="http://www.routino.org/">http://www.routino.org/</a>
diff --git a/doc/html/readme.html b/doc/html/readme.html
index 4888484..3795486 100644
--- a/doc/html/readme.html
+++ b/doc/html/readme.html
@@ -3,6 +3,7 @@
 
 <head>
 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<meta name="viewport" content="width=device-width, initial-scale=1">
 
 <title>Routino : Software</title>
 
@@ -11,7 +12,7 @@
 
  Part of the Routino routing software.
 
- This file Copyright 2008-2014 Andrew M. Bishop
+ This file Copyright 2008-2015 Andrew M. Bishop
 
  This program is free software: you can redistribute it and/or modify
  it under the terms of the GNU Affero General Public License as published by
@@ -38,7 +39,6 @@
 
 <h1>Routino : Software</h1>
 
-<hr>
 </div>
 
 <!-- Header End -->
@@ -208,151 +208,57 @@ Version 2.7.1 of Routino was released on 17th May 2014.
 Version 2.7.2 of Routino was released on 26th June 2014.
 <br>
 Version 2.7.3 of Routino was released on 8th November 2014.
+<br>
+Version 3.0 of Routino was released on 12th September 2015.
 
 <p>
 
 The full version history is available in the NEWS.txt file.
 
 
-<h3 id="H_1_5_1" title="Changes 2.7">Changes in Versions 2.7</h3>
+<h3 id="H_1_5_1" title="Changes 3.0">Changes in Versions 3.0</h3>
 
-Version 2.7 - mostly web page usability improvements.
+Version 3.0 - Windows compilation and library providing routing API.
 
 <dl>
   <dt>Bug fixes:
-    <dd>Fix web-page CGI bug that did not allow more than 9 waypoints to be routed.
-    <br>Fix typo in documentation strings in filedumper program.
-    <br>Fix error in function prototype that stopped 64-bit node type being used.
-    <br>Don't lose super-segments when merging them with normal segments.
-    <br>Don't exceed the database lat/long limits when searching for visualiser data.
-
-  <dt>planetsplitter:
-    <dd>Don't overflow (and wrap-around) conversions of lengths, weights etc.
-    <br>Add some new formats of length, weight and speed parsing.
-    <br>Add .xz uncompression as a compile-time option (default is disabled).
-
-  <dt>router:
-    <dd>Remove ancient undocumented option to specify lat/lon without --lat/--lon.
-    <br>Add a '--output-stdout' option to output the route in a selected format.
-    <br>Add a '--reverse' option to calculate a route in the reverse order.
-    <br>Add a '--loop' option to calculate a route that returns to the first waypoint.
-    <br>Output valid HTML4 (use strict DTD and use numeric entity for apostrophe).
-
-  <dt>OSM tagging:
-    <dd>Allow bicycles both ways on certain oneway roads if tagging allows.
-    <br>Handle "access=bus" like "access=psv".
-
-  <dt>Configuration Files:
-    <dd>Updated Dutch translations.
-    <br>Updates to the XML parser tagging rules.
-    <br>Added French translations for the routing output.
-
-  <dt>Documentation:
-    <dd>Update the algorithm documentation for finding the shortest path.
-    <br>Update documentation HTML to strict 4.01 DTD.
-
-  <dt>Web pages:
-    <dd>Some changes to HTML, CSS formatting and Javascript to improve usability.
-    <br>Added a French translation of the router web page.
-    <br>Add the option to choose between OpenLayers and Leaflet for map rendering.
-    <br>Check compatible with OpenLayers v2.13.1 and make this the default.
-    <br>Create the router and visualiser pages from templates and translated phrases.
-</dl>
-
-<p>
-<b>Note:</b> This version has removed specific support for IE6 and IE7 browsers.
-<p>
-<b>Note:</b> Note: This version is compatible with databases from version 2.6.
-
-<h3 id="H_1_5_2" title="Changes 2.7.1">Changes in Versions 2.7.1</h3>
-
-Version 2.7.1 - mostly bug fixes (some from version 2.7, but mostly older ones).
-
-<dl>
-  <dt>Bug fixes:
-    <dd>Fix typo in documentation for command to get SVN version.
-    <br>Fix router crash when waypoint is on roundabout.
-    <br>Don't duplicate super-segments when merging them with normal segments.
-    <br>Change routing instructions for bicycle if highways allow cycling both ways.
-    <br>Make translation script work with older versions of Perl.
-    <br>Fix router crash if fewer than two waypoints are specified.
-    <br>Revert router speed decrease with special-case tagging rules.
-    <br>Fix web page search function when it returns non-ASCII text.
-    <br>Fix router failure due to invalid assumption about allowed U-turn.
-    <br>Fix bug with updating XML files in web/data directory (Makefile error).
-    <br>Fix router web page error due to absence of cyclebothways property entry.
-    <br>Fix results error if a waypoint node was passed again on way to next waypoint.
-    <br>Fix router crash when route contains consecutive coincident waypoints.
-    <br>Fix bug with slightly incorrect distances when pruning short segments.
-
-  <dt>Test cases:
-    <dd>Create new test case for roundabout waypoint bug fixed in this version.
-    <br>Create new test case for invalid U-turn assumption bug fixed in this version.
-    <br>Create new test case for cycling both ways.
-    <br>Create new test case for consecutive coincident waypoints.
-
-  <dt>router:
-    <dd>Remove cyclebothways as a property that can be used as a routing preference.
-
-  <dt>Web pages:
-    <dd>Disallow route calculation if fewer than two waypoints are selected.
-    <br>Update visualiser for change of cyclebothways handling.
-
-  <dt>Translations:
-    <dd>Updated Russian translations.
-    <br>Updated German translations.
-</dl>
-
-<p>
-<b>Note:</b> This version is not compatible with databases from previous versions.
+    <dd>Use a single definition of MAX_SEG_PER_NODE to avoid confusion.
+    <br>Fix bug with built-in translation strings if no XML translations available.
+    <br>Fix bug with makefiles related to creating new translations.
+    <br>Remove some pthread code that was still there when compiling without pthreads.
+    <br>Fix a use-after-free memory error and use of uninitialised allocated memory.
+    <br>Ensure that allocated strings are long enough for temporary filenames.
 
+  <dt>Programs:
+    <dd>Add a '--version' option to all of the programs.
 
-<h3 id="H_1_5_3" title="Changes 2.7.2">Changes in Versions 2.7.2</h3>
+  <dt>Source Code:
+    <dd>Various C language cleanups including using '-pedantic' compiler option.
+    <br>Various changes to allow compiling with Microsoft Visual Studio C compiler.
+    <br>Various changes to allow compiling with MinGW or Cygwin on Microsoft Windows.
+    <br>Makefile updates: 'make clean' = release, 'make distclean' = SVN repository.
 
-Version 2.7.2 - mostly bug fixes introduced in version 2.7.1 on 64-bit systems.
-
-<dl>
-  <dt>Bug fixes:
-    <dd>Make the visualiser display all segments including those crossing the border.
-    <br>Fix two errors that cause crashes only on 64-bit systems.
+  <dt>API:
+    <dd>Create a library API that can perform routing functions.
 
-  <dt>planetsplitter / router:
-    <dd>Increase the size of the caches for the slim programs by a factor of four.
+  <dt>OSM tagging:
+    <dd>Remove cycle_barrier and bicycle_barrier since they do not block bicycles.
 
   <dt>Translations:
-    <dd>Updated Russian translations.
-    <br>Updated German translations.
-</dl>
-
-<p>
-<b>Note:</b> This version is compatible with databases from version 2.7.1.
-
+    <dd>Updated Dutch and German translations.
+    <br>Added Hungarian and Polish translations provided through translation web page.
 
-<h3 id="H_1_5_4" title="Changes 2.7.3">Changes in Versions 2.7.3</h3>
-
-Version 2.7.3 - Slightly reduced memory usage and large reduction in time to generate routing database on low memory systems.
-
-<dl>
-  <dt>Bug fixes:
-    <dd>Limit the property preference ratio to 100 instead of 10000.
-    <br>Don't allocate memory for sorting that won't be used.
-
-  <dt>planetsplitter:
-    <dd>Added an option to print out the allocated/mapped memory at each step.
-    <br>Speed up database generation by compacting results after each pruning step.
-    <br>Speed up database generation by sorting nodes geographically before pruning.
-    <br>Reduce memory use while generating the database.  
-
-  <dt>router:
-    <dd>Added the options to print out time and allocated/mapped memory at each step.
+  <dt>Documentation:
+    <dd>Add meta tags to HTML to help mobile devices, tidy up the CSS.
+    <br>Create instructions for compiling on Microsoft Windows.
+    <br>Create API description for Routino library usage.
 
-  <dt>Translations:
-    <dd>Updated German translations.
+  <dt>Web pages:
+    <dd>Allow drag-and-drop of waypoints within the list and onto the map.
 </dl>
 
 <p>
-<b>Note:</b> This version is compatible with databases from version 2.7.1 & 2.7.2.
-
+<b>Note:</b> This version is compatible with databases from version 2.7.1 - 2.7.3.
 
 
 <h2 id="H_1_6">License</h2>
@@ -371,23 +277,23 @@ additional requirements to anybody who provides a networked service using this
 software.
 
 
-<h3 id="H_1_7">Copyright</h3>
+<h3 id="H_1_6_1">Copyright</h3>
 
-Routino is copyright Andrew M. Bishop 2008-2014.
+Routino is copyright Andrew M. Bishop 2008-2015.
 
 
-<h2 id="H_1_8">Homepage</h2>
+<h2 id="H_1_7">Homepage</h2>
 
 The <a title="Homepage" href="http://www.routino.org/">Routino homepage</a>
 has the latest news about the program.
 
 
-<h2 id="H_1_9">Download</h2>
+<h2 id="H_1_8">Download</h2>
 
 The <a title="Download directory" href="http://www.routino.org/download/">download directory</a>
 contains the latest version of the source code.
 
-<h3 id="H_1_9_1">Subversion</h3>
+<h3 id="H_1_8_1">Subversion</h3>
 
 The source code can also be downloaded from the
 <a title="SVN Repository" href="http://routino.org/svn/trunk/">Subversion repository</a>
@@ -411,7 +317,6 @@ which also has a list of the
 <!-- Footer Start -->
 
 <div class="footer">
-<hr>
 
 <address>
 © Andrew M. Bishop - <a href="http://www.routino.org/">http://www.routino.org/</a>
diff --git a/doc/html/style.css b/doc/html/style.css
index 89a3ce7..213879e 100644
--- a/doc/html/style.css
+++ b/doc/html/style.css
@@ -3,7 +3,7 @@
 //
 // Part of the Routino routing software.
 //
-// This file Copyright 2008-2013 Andrew M. Bishop
+// This file Copyright 2008-2015 Andrew M. Bishop
 //
 // This program is free software: you can redistribute it and/or modify
 // it under the terms of the GNU Affero General Public License as published by
@@ -90,16 +90,11 @@ DIV.header
  clear: left;
 }
 
-DIV.header HR  /* Horizontal rule, only visible without CSS */
-{
- display: none;
-}
-
 DIV.header H1
 {
  /* fonts and text styles */
 
- font-size:   xx-large;
+ font-size: 150%;
 
  font-weight: bold;
 
@@ -123,7 +118,7 @@ DIV.footer
 {
  /* fonts and text styles */
 
- font-size: small;
+ font-size: 80%;
 
  /* margins, borders, padding and sizes */
 
@@ -146,11 +141,6 @@ DIV.footer
  clear: left;
 }
 
-DIV.footer HR  /* Horizontal rule, only visible without CSS */
-{
- display: none;
-}
-
 
 /*-----------------------------------*/
 /* Content HTML formatting           */
@@ -169,7 +159,7 @@ DIV.content H1
 {
  /* fonts and text styles */
 
- font-size:   xx-large;
+ font-size:   150%;
  font-weight: bold;
 
  /* margins, borders, padding and sizes */
@@ -184,7 +174,7 @@ DIV.content H2
 {
  /* fonts and text styles */
 
- font-size:   x-large;
+ font-size:   140%;
  font-weight: bold;
 
  /* margins, borders, padding and sizes */
@@ -199,7 +189,7 @@ DIV.content H3
 {
  /* fonts and text styles */
 
- font-size:   large;
+ font-size:   120%;
  font-weight: bold;
 
  /* margins, borders, padding and sizes */
@@ -214,7 +204,7 @@ DIV.content H4
 {
  /* fonts and text styles */
 
- font-size:   medium;
+ font-size:   110%;
  font-weight: bold;
 
  /* margins, borders, padding and sizes */
@@ -421,3 +411,25 @@ DIV.content IMG
 
  border: 0px;
 }
+
+
+/*------------------------------------------------*/
+/*                                                */
+/* Special case layout for narrow screens         */
+/*                                                */
+/*------------------------------------------------*/
+
+ at media screen and (max-width:640px) {
+
+  /*----------------------------------*/
+  /* Body HTML formatting             */
+  /*----------------------------------*/
+
+  BODY
+  {
+   /* fonts and text styles */
+
+   font-size: small;
+  }
+
+}
diff --git a/doc/html/tagging.html b/doc/html/tagging.html
index 50617d3..f6c8173 100644
--- a/doc/html/tagging.html
+++ b/doc/html/tagging.html
@@ -3,6 +3,7 @@
 
 <head>
 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<meta name="viewport" content="width=device-width, initial-scale=1">
 
 <title>Routino : Tagging Rules</title>
 
@@ -11,7 +12,7 @@
 
  Part of the Routino routing software.
 
- This file Copyright 2008-2014 Andrew M. Bishop
+ This file Copyright 2008-2015 Andrew M. Bishop
 
  This program is free software: you can redistribute it and/or modify
  it under the terms of the GNU Affero General Public License as published by
@@ -38,7 +39,6 @@
 
 <h1>Routino : Tagging Rules</h1>
 
-<hr>
 </div>
 
 <!-- Header End -->
@@ -840,12 +840,13 @@ transport permissions on the highway.
 
 <p>
 A highway that is tagged as <em>motorroad</em> with a value of <em>yes</em> will
-deny access to foot, horse, wheelchair, bicycle and moped transport.
+deny access to <em>foot</em>, <em>horse</em>, <em>wheelchair</em>,
+<em>bicycle</em> and <em>moped</em> transport.
 
 <p>
 A highway that is tagged with <em>footway</em> or <em>sidewalk</em> and one of a
-set of popular values will allow foot and wheelchair access even if the road
-type would not normally do so.
+set of popular values will allow <em>foot</em> and <em>wheelchair</em> access
+even if the road type would not normally do so.
 
 <p>
 A highway that is tagged as <em>cycleway</em> with one of several values will
@@ -885,8 +886,8 @@ paved if this is set to a true value.
 
 <p>
 
-The <em>lanes</em> tag is passed through to be used to set
-the <em>multilane</em> highway property.
+The <em>lanes</em> tag is passed through to be used to set the
+<em>multilane</em> highway property.
 
 <p>
 
@@ -903,8 +904,8 @@ the output without modification.
 
 <h4 id="H_1_3_2_7">Roundabouts</h4>
 
-If a highway is tagged as <em>junction=roundabout</em> then
-a <em>roundabout=yes</em> tag created on the output.
+If a highway is tagged as <em>junction=roundabout</em> then a
+<em>roundabout=yes</em> tag created on the output.
 
 
 <h4 id="H_1_3_2_8" title="Names and Refs">Highway Names and References</h4>
@@ -928,8 +929,8 @@ The <em>type</em> tag is passed through without change.
 <h4 id="H_1_3_3_1">Routes</h4>
 
 The <em>route</em> tag can be used to determine whether a relation is part of a
-walking of bicycle route so that the footroute and bicycleroute properties can
-be applied to the highways that make up that relation.
+walking or bicycle route so that the <em>footroute</em> or <em>bicycleroute</em>
+properties can be applied to the highways that make up that relation.
 
 <p>
 
@@ -973,7 +974,6 @@ change.
 <!-- Footer Start -->
 
 <div class="footer">
-<hr>
 
 <address>
 © Andrew M. Bishop - <a href="http://www.routino.org/">http://www.routino.org/</a>
diff --git a/doc/html/usage.html b/doc/html/usage.html
index fce5a2c..8c814f6 100644
--- a/doc/html/usage.html
+++ b/doc/html/usage.html
@@ -3,6 +3,7 @@
 
 <head>
 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<meta name="viewport" content="width=device-width, initial-scale=1">
 
 <title>Routino : Usage</title>
 
@@ -11,7 +12,7 @@
 
  Part of the Routino routing software.
 
- This file Copyright 2008-2014 Andrew M. Bishop
+ This file Copyright 2008-2015 Andrew M. Bishop
 
  This program is free software: you can redistribute it and/or modify
  it under the terms of the GNU Affero General Public License as published by
@@ -38,7 +39,6 @@
 
 <h1>Routino : Usage</h1>
 
-<hr>
 </div>
 
 <!-- Header End -->
@@ -63,7 +63,8 @@ This program reads in the OSM format XML file and splits it up to create the
 database that is used for routing.
 
 <pre class="boxed">
-Usage: planetsplitter [--help]
+Usage: planetsplitter [--version]
+                      [--help]
                       [--dir=<dirname>] [--prefix=<name>]
                       [--sort-ram-size=<size>] [--sort-threads=<number>]
                       [--tmpdir=<dirname>]
@@ -86,6 +87,8 @@ Usage: planetsplitter [--help]
 </pre>
 
 <dl>
+  <dt>--version
+  <dd>Print the version of Routino.
   <dt>--help
   <dd>Prints out the help information.
   <dt>--dir=<dirname>
@@ -227,7 +230,8 @@ This program performs the calculation of the optimum routes using the database
 generated by the planetsplitter program.
 
 <pre class="boxed">
-Usage: router [--help | --help-profile | --help-profile-xml |
+Usage: router [--version]
+              [--help | --help-profile | --help-profile-xml |
                         --help-profile-json | --help-profile-perl ]
               [--dir=<dirname>] [--prefix=<name>]
               [--profiles=<filename>] [--translations=<filename>]
@@ -254,6 +258,8 @@ Usage: router [--help | --help-profile | --help-profile-xml |
 </pre>
 
 <dl>
+  <dt>--version
+  <dd>Print the version of Routino.
   <dt>--help
   <dd>Prints out the help information.
   <dt>--help-profile
@@ -452,7 +458,8 @@ This program is used to extract statistics from the database, extract particular
 information for visualisation purposes or for dumping the database contents.
 
 <pre class="boxed">
-Usage: filedumper [--help]
+Usage: filedumper [--version]
+                  [--help]
                   [--dir=<dirname>] [--prefix=<name>]
                   [--statistics]
                   [--visualiser --latmin=<latmin> --latmax=<latmax>
@@ -473,6 +480,8 @@ Usage: filedumper [--help]
 </pre>
 
 <dl>
+  <dt>--version
+  <dd>Print the version of Routino.
   <dt>--help
   <dd>Prints out the help information.
   <dt>--dir=<dirname>
@@ -573,7 +582,8 @@ the --keep or --changes option.  This is intended for test purposes only and
 gives no useful information about the routing database.
 
 <pre class="boxed">
-Usage: filedumperx [--help]
+Usage: filedumperx [--version]
+                   [--help]
                    [--dir=<dirname>] [--prefix=<name>]
                    [--dump [--nodes]
                            [--ways]
@@ -582,6 +592,8 @@ Usage: filedumperx [--help]
 </pre>
 
 <dl>
+  <dt>--version
+  <dd>Print the version of Routino.
   <dt>--help
   <dd>Prints out the help information.
   <dt>--dir=<dirname>
@@ -611,7 +623,6 @@ Usage: filedumperx [--help]
 <!-- Footer Start -->
 
 <div class="footer">
-<hr>
 
 <address>
 © Andrew M. Bishop - <a href="http://www.routino.org/">http://www.routino.org/</a>
diff --git a/extras/find-fixme/Makefile b/extras/find-fixme/Makefile
index c3334ab..fbd9baf 100644
--- a/extras/find-fixme/Makefile
+++ b/extras/find-fixme/Makefile
@@ -2,7 +2,7 @@
 #
 # Part of the Routino routing software.
 #
-# This file Copyright 2013-2014 Andrew M. Bishop
+# This file Copyright 2013-2015 Andrew M. Bishop
 #
 # This program is free software: you can redistribute it and/or modify
 # it under the terms of the GNU Affero General Public License as published by
@@ -37,7 +37,7 @@ ROUTINO_SRC=../../src
 ROUTINO_WEBWWWDIR=../../web/www/routino
 ROUTINO_DOCDIR=../../doc/html
 
-EXE=fixme-finder fixme-finder-slim fixme-dumper fixme-dumper-slim
+EXE=fixme-finder$(.EXE) fixme-finder-slim$(.EXE) fixme-dumper$(.EXE) fixme-dumper-slim$(.EXE)
 DATA=fixme.xml
 WWW_COPY=page-elements.css page-elements.js maplayout.css mapprops.js maploader.js
 DOC_COPY=style.css
@@ -88,8 +88,12 @@ FIXME_FINDER_OBJ=fixme-finder.o osmparser.o \
 	       	 $(ROUTINO_SRC)/xmlparse.o $(ROUTINO_SRC)/tagging.o \
 	       	 $(ROUTINO_SRC)/uncompress.o $(ROUTINO_SRC)/osmxmlparse.o $(ROUTINO_SRC)/osmpbfparse.o $(ROUTINO_SRC)/osmo5mparse.o
 
-fixme-finder : $(FIXME_FINDER_OBJ)
-	$(LD) $(FIXME_FINDER_OBJ) -o $@ $(LDFLAGS)
+ifeq ($(HOST),MINGW)
+FIXME_FINDER_OBJ+=$(ROUTINO_SRC)/mman-win32.o
+endif
+
+fixme-finder$(.EXE) : $(FIXME_FINDER_OBJ)
+	$(LD) $^ -o $@ $(LDFLAGS)
 
 ########
 
@@ -101,8 +105,12 @@ FIXME_FINDER_SLIM_OBJ=fixme-finder-slim.o osmparser.o \
 	       	      $(ROUTINO_SRC)/xmlparse.o $(ROUTINO_SRC)/tagging.o \
 	       	      $(ROUTINO_SRC)/uncompress.o $(ROUTINO_SRC)/osmxmlparse.o $(ROUTINO_SRC)/osmpbfparse.o $(ROUTINO_SRC)/osmo5mparse.o
 
-fixme-finder-slim : $(FIXME_FINDER_SLIM_OBJ)
-	$(LD) $(FIXME_FINDER_SLIM_OBJ) -o $@ $(LDFLAGS)
+ifeq ($(HOST),MINGW)
+FIXME_FINDER_SLIM_OBJ+=$(ROUTINO_SRC)/mman-win32.o
+endif
+
+fixme-finder-slim$(.EXE) : $(FIXME_FINDER_SLIM_OBJ)
+	$(LD) $^ -o $@ $(LDFLAGS)
 
 ########
 
@@ -110,8 +118,12 @@ FIXME_DUMPER_OBJ=fixme-dumper.o \
 	         $(ROUTINO_SRC)/errorlog.o \
 	         $(ROUTINO_SRC)/files.o $(ROUTINO_SRC)/logging.o $(ROUTINO_SRC)/xmlparse.o
 
-fixme-dumper : $(FIXME_DUMPER_OBJ)
-	$(LD) $(FIXME_DUMPER_OBJ) -o $@ $(LDFLAGS)
+ifeq ($(HOST),MINGW)
+FIXME_DUMPER_OBJ+=$(ROUTINO_SRC)/mman-win32.o
+endif
+
+fixme-dumper$(.EXE) : $(FIXME_DUMPER_OBJ)
+	$(LD) $^ -o $@ $(LDFLAGS)
 
 ########
 
@@ -119,8 +131,12 @@ FIXME_DUMPER_SLIM_OBJ=fixme-dumper-slim.o \
 	              $(ROUTINO_SRC)/errorlog-slim.o \
 	              $(ROUTINO_SRC)/files.o $(ROUTINO_SRC)/logging.o $(ROUTINO_SRC)/xmlparse.o
 
-fixme-dumper-slim : $(FIXME_DUMPER_SLIM_OBJ)
-	$(LD) $(FIXME_DUMPER_SLIM_OBJ) -o $@ $(LDFLAGS)
+ifeq ($(HOST),MINGW)
+FIXME_DUMPER_SLIM_OBJ+=$(ROUTINO_SRC)/mman-win32.o
+endif
+
+fixme-dumper-slim$(.EXE) : $(FIXME_DUMPER_SLIM_OBJ)
+	$(LD) $^ -o $@ $(LDFLAGS)
 
 ########
 
@@ -151,18 +167,18 @@ install:
 clean:
 	rm -f *~
 	rm -f *.o
+	cd $(WEBBINDIR) && rm -f $(EXE)
+	cd $(WEBDATADIR) && rm -f $(DATA)
+	cd $(WEBWWWDIR) && rm -f $(WWW_COPY)
+	cd $(WEBWWWDIR) && rm -f $(DOC_COPY)
+	rm -f $(EXE)
+	rm -f $(D)
+	rm -fr .deps
 	rm -f core
 
 ########
 
 distclean: clean
-	-cd $(WEBBINDIR) && rm -f $(EXE)
-	-cd $(WEBDATADIR) && rm -f $(DATA)
-	-cd $(WEBWWWDIR) && rm -f $(WWW_COPY)
-	-cd $(WEBWWWDIR) && rm -f $(DOC_COPY)
-	-rm -f $(EXE)
-	-rm -f $(D)
-	-rm -fr .deps
 
 ########
 
diff --git a/extras/find-fixme/README.txt b/extras/find-fixme/README.txt
index 0286bab..001e2fa 100644
--- a/extras/find-fixme/README.txt
+++ b/extras/find-fixme/README.txt
@@ -20,7 +20,8 @@ be used on an OSM file to extract the fixme tags and generate a database of
 them.
 
 
-Usage: fixme-finder [--help]
+Usage: fixme-finder [--version]
+                    [--help]
                     [--dir=<dirname>]
                     [--sort-ram-size=<size>] [--sort-threads=<number>]
                     [--tmpdir=<dirname>]
@@ -33,6 +34,8 @@ Usage: fixme-finder [--help]
                      | <filename.(osm|o5m).gz> ...
                      | <filename.(osm|o5m).xz> ...]
 
+--version                 Print the version of Routino.
+
 --help                    Prints this information.
 
 --dir=<dirname>           The directory containing the fixme database.
@@ -69,7 +72,8 @@ This program is a modified version of the Routino filedumper program and is used
 by the web page CGI to display the information on a map.
 
 
-Usage: fixme-dumper [--help]
+Usage: fixme-dumper [--version]
+                    [--help]
                     [--dir=<dirname>]
                     [--statistics]
                     [--visualiser --latmin=<latmin> --latmax=<latmax>
@@ -77,6 +81,8 @@ Usage: fixme-dumper [--help]
                                   --data=<data-type>]
                     [--dump--visualiser [--data=fixme<number>]]
 
+--version                 Print the version of Routino.
+
 --help                    Prints this information.
 
 --dir=<dirname>           The directory containing the fixme database.
diff --git a/extras/find-fixme/fixme-dumper.c b/extras/find-fixme/fixme-dumper.c
index 85b271e..4f8db63 100644
--- a/extras/find-fixme/fixme-dumper.c
+++ b/extras/find-fixme/fixme-dumper.c
@@ -3,7 +3,7 @@
 
  Part of the Routino routing software.
  ******************/ /******************
- This file Copyright 2013-2014 Andrew M. Bishop
+ This file Copyright 2013-2015 Andrew M. Bishop
 
  This program is free software: you can redistribute it and/or modify
  it under the terms of the GNU Affero General Public License as published by
@@ -24,10 +24,11 @@
 #include <stdlib.h>
 #include <string.h>
 #include <sys/stat.h>
-#include <sys/time.h>
 #include <time.h>
 #include <math.h>
 
+#include "version.h"
+
 #include "types.h"
 #include "errorlog.h"
 
@@ -66,7 +67,9 @@ int main(int argc,char** argv)
 
  for(arg=1;arg<argc;arg++)
    {
-    if(!strcmp(argv[arg],"--help"))
+    if(!strcmp(argv[arg],"--version"))
+       print_usage(-1,NULL,NULL);
+    else if(!strcmp(argv[arg],"--help"))
        print_usage(1,NULL,NULL);
     else if(!strncmp(argv[arg],"--dir=",6))
        dirname=&argv[arg][6];
@@ -145,9 +148,9 @@ int main(int argc,char** argv)
     printf("\n");
     stat(errorlogs_filename,&buf);
 #if !SLIM
-    printf("Total strings=%9lu Bytes\n",(unsigned long)buf.st_size-(unsigned long)(OSMErrorLogs->strings-(char*)OSMErrorLogs->data));
+    printf("Total strings=%9zu Bytes\n",(size_t)buf.st_size-(OSMErrorLogs->strings-(char*)OSMErrorLogs->data));
 #else
-    printf("Total strings=%9lu Bytes\n",(unsigned long)buf.st_size-(unsigned long)OSMErrorLogs->stringsoffset);
+    printf("Total strings=%9zu Bytes\n",(size_t)buf.st_size-(size_t)OSMErrorLogs->stringsoffset);
 #endif
    }
 
@@ -262,7 +265,7 @@ static const char* const months[12]={"Jan","Feb","Mar","Apr","May","Jun","Jul","
 
 static char *RFC822Date(time_t t)
 {
- static char value[32];
+ static char value[32]; /* static allocation of return value */
  char weekday[4];
  char month[4];
  struct tm *tim;
@@ -292,7 +295,7 @@ static char *RFC822Date(time_t t)
 /*++++++++++++++++++++++++++++++++++++++
   Print out the usage information.
 
-  int detail The level of detail to use - 0 = low, 1 = high.
+  int detail The level of detail to use: -1 = just version number, 0 = low detail, 1 = full details.
 
   const char *argerr The argument that gave the error (if there is one).
 
@@ -301,28 +304,41 @@ static char *RFC822Date(time_t t)
 
 static void print_usage(int detail,const char *argerr,const char *err)
 {
- fprintf(stderr,
-         "Usage: fixme-dumper [--help]\n"
-         "                    [--dir=<dirname>]\n"
-         "                    [--statistics]\n"
-         "                    [--visualiser --latmin=<latmin> --latmax=<latmax>\n"
-         "                                  --lonmin=<lonmin> --lonmax=<lonmax>\n"
-         "                                  --data=<data-type>]\n"
-         "                    [--dump--visualiser [--data=fixme<number>]]\n");
-
- if(argerr)
+ if(detail<0)
+   {
     fprintf(stderr,
-            "\n"
-            "Error with command line parameter: %s\n",argerr);
+            "Routino version " ROUTINO_VERSION " " ROUTINO_URL ".\n"
+            );
+   }
 
- if(err)
+ if(detail>=0)
+   {
     fprintf(stderr,
-            "\n"
-            "Error: %s\n",err);
+            "Usage: fixme-dumper [--version]\n"
+            "                    [--help]\n"
+            "                    [--dir=<dirname>]\n"
+            "                    [--statistics]\n"
+            "                    [--visualiser --latmin=<latmin> --latmax=<latmax>\n"
+            "                                  --lonmin=<lonmin> --lonmax=<lonmax>\n"
+            "                                  --data=<data-type>]\n"
+            "                    [--dump--visualiser [--data=fixme<number>]]\n");
+
+    if(argerr)
+       fprintf(stderr,
+               "\n"
+               "Error with command line parameter: %s\n",argerr);
+
+    if(err)
+       fprintf(stderr,
+               "\n"
+               "Error: %s\n",err);
+   }
 
- if(detail)
+ if(detail==1)
     fprintf(stderr,
             "\n"
+            "--version                 Print the version of Routino.\n"
+            "\n"
             "--help                    Prints this information.\n"
             "\n"
             "--dir=<dirname>           The directory containing the fixme database.\n"
diff --git a/extras/find-fixme/fixme-finder.c b/extras/find-fixme/fixme-finder.c
index ebdb1a4..fe43c53 100644
--- a/extras/find-fixme/fixme-finder.c
+++ b/extras/find-fixme/fixme-finder.c
@@ -3,7 +3,7 @@
 
  Part of the Routino routing software.
  ******************/ /******************
- This file Copyright 2008-2014 Andrew M. Bishop
+ This file Copyright 2008-2015 Andrew M. Bishop
 
  This program is free software: you can redistribute it and/or modify
  it under the terms of the GNU Affero General Public License as published by
@@ -22,10 +22,11 @@
 
 #include <stdio.h>
 #include <stdlib.h>
-#include <unistd.h>
 #include <string.h>
 #include <errno.h>
 
+#include "version.h"
+
 #include "types.h"
 #include "ways.h"
 
@@ -70,7 +71,7 @@ int main(int argc,char** argv)
  WaysX      *OSMWays;
  RelationsX *OSMRelations;
  ErrorLogsX *OSMErrorLogs;
- char       *dirname=NULL,*prefix=NULL,*tagging="fixme.xml",*errorlog="fixme.log";
+ char       *dirname=NULL,*prefix=NULL,*tagging=NULL;
  int         option_keep=1;
  int         option_filenames=0;
  int         arg;
@@ -81,7 +82,9 @@ int main(int argc,char** argv)
 
  for(arg=1;arg<argc;arg++)
    {
-    if(!strcmp(argv[arg],"--help"))
+    if(!strcmp(argv[arg],"--version"))
+       print_usage(-1,NULL,NULL);
+    else if(!strcmp(argv[arg],"--help"))
        print_usage(1,NULL,NULL);
     else if(!strncmp(argv[arg],"--dir=",6))
        dirname=&argv[arg][6];
@@ -138,11 +141,11 @@ int main(int argc,char** argv)
    }
  else
    {
-    if(ExistsFile(FileName(dirname,prefix,"tagging.xml")))
-       tagging=FileName(dirname,prefix,"tagging.xml");
-    else
+    tagging=FileName(dirname,prefix,"fixme.xml");
+
+    if(!ExistsFile(tagging))
       {
-       fprintf(stderr,"Error: The '--tagging' option was not used and the default 'tagging.xml' does not exist.\n");
+       fprintf(stderr,"Error: The '--tagging' option was not used and the default 'fixme.xml' does not exist.\n");
        exit(EXIT_FAILURE);
       }
    }
@@ -163,8 +166,7 @@ int main(int argc,char** argv)
 
  /* Create the error log file */
 
- if(errorlog)
-    open_errorlog(FileName(dirname,prefix,errorlog),0,option_keep);
+ open_errorlog(FileName(dirname,prefix,"fixme.log"),0,option_keep);
 
  /* Parse the file */
 
@@ -281,7 +283,7 @@ int main(int argc,char** argv)
 /*++++++++++++++++++++++++++++++++++++++
   Print out the usage information.
 
-  int detail The level of detail to use - 0 = low, 1 = high.
+  int detail The level of detail to use: -1 = just version number, 0 = low detail, 1 = full details.
 
   const char *argerr The argument that gave the error (if there is one).
 
@@ -290,44 +292,57 @@ int main(int argc,char** argv)
 
 static void print_usage(int detail,const char *argerr,const char *err)
 {
- fprintf(stderr,
-         "Usage: fixme-finder [--help]\n"
-         "                    [--dir=<dirname>]\n"
+ if(detail<0)
+   {
+    fprintf(stderr,
+            "Routino version " ROUTINO_VERSION " " ROUTINO_URL ".\n"
+            );
+   }
+
+ if(detail>=0)
+   {
+    fprintf(stderr,
+            "Usage: fixme-finder [--version]\n"
+            "                    [--help]\n"
+            "                    [--dir=<dirname>]\n"
 #if defined(USE_PTHREADS) && USE_PTHREADS
-         "                    [--sort-ram-size=<size>] [--sort-threads=<number>]\n"
+            "                    [--sort-ram-size=<size>] [--sort-threads=<number>]\n"
 #else
-         "                    [--sort-ram-size=<size>]\n"
+            "                    [--sort-ram-size=<size>]\n"
 #endif
-         "                    [--tmpdir=<dirname>]\n"
-         "                    [--tagging=<filename>]\n"
-         "                    [--loggable] [--logtime] [--logmemory]\n"
-         "                    [<filename.osm> ...\n"
-         "                     | <filename.pbf> ...\n"
-         "                     | <filename.o5m> ..."
+            "                    [--tmpdir=<dirname>]\n"
+            "                    [--tagging=<filename>]\n"
+            "                    [--loggable] [--logtime] [--logmemory]\n"
+            "                    [<filename.osm> ...\n"
+            "                     | <filename.pbf> ...\n"
+            "                     | <filename.o5m> ..."
 #if defined(USE_BZIP2) && USE_BZIP2
-         "\n                     | <filename.(osm|o5m).bz2> ..."
+            "\n                     | <filename.(osm|o5m).bz2> ..."
 #endif
 #if defined(USE_GZIP) && USE_GZIP
-         "\n                     | <filename.(osm|o5m).gz> ..."
+            "\n                     | <filename.(osm|o5m).gz> ..."
 #endif
 #if defined(USE_XZ) && USE_XZ
-         "\n                     | <filename.(osm|o5m).xz> ..."
+            "\n                     | <filename.(osm|o5m).xz> ..."
 #endif
-         "]\n");
+            "]\n");
 
- if(argerr)
-    fprintf(stderr,
-            "\n"
-            "Error with command line parameter: %s\n",argerr);
+    if(argerr)
+       fprintf(stderr,
+               "\n"
+               "Error with command line parameter: %s\n",argerr);
 
- if(err)
-    fprintf(stderr,
-            "\n"
-            "Error: %s\n",err);
+    if(err)
+       fprintf(stderr,
+               "\n"
+               "Error: %s\n",err);
+   }
 
- if(detail)
+ if(detail==1)
     fprintf(stderr,
             "\n"
+            "--version                 Print the version of Routino.\n"
+            "\n"
             "--help                    Prints this information.\n"
             "\n"
             "--dir=<dirname>           The directory containing the fixme database.\n"
diff --git a/extras/find-fixme/osmparser.c b/extras/find-fixme/osmparser.c
index 782be96..f32e4f7 100644
--- a/extras/find-fixme/osmparser.c
+++ b/extras/find-fixme/osmparser.c
@@ -3,7 +3,7 @@
 
  Part of the Routino routing software.
  ******************/ /******************
- This file Copyright 2008-2014 Andrew M. Bishop
+ This file Copyright 2008-2015 Andrew M. Bishop
 
  This program is free software: you can redistribute it and/or modify
  it under the terms of the GNU Affero General Public License as published by
@@ -36,21 +36,21 @@
 #include "logging.h"
 
 
-/* Local variables */
+/* Local parsing variables (re-initialised for each file) */
 
 static NodesX     *nodes;
 static WaysX      *ways;
 static RelationsX *relations;
 
-static node_t *way_nodes=NULL;
-static int     way_nnodes=0;
+static node_t     *way_nodes;
+static int         way_nnodes;
 
-static node_t     *relation_nodes=NULL;
-static int         relation_nnodes=0;
-static way_t      *relation_ways=NULL;
-static int         relation_nways=0;
-static relation_t *relation_relations=NULL;
-static int         relation_nrelations=0;
+static node_t     *relation_nodes;
+static int         relation_nnodes;
+static way_t      *relation_ways;
+static int         relation_nways;
+static relation_t *relation_relations;
+static int         relation_nrelations;
 
 
 /*++++++++++++++++++++++++++++++++++++++
diff --git a/extras/find-fixme/web/www/index.html b/extras/find-fixme/web/www/index.html
index cc67c4f..dd8c3a4 100644
--- a/extras/find-fixme/web/www/index.html
+++ b/extras/find-fixme/web/www/index.html
@@ -3,6 +3,7 @@
 
 <head>
 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<meta name="viewport" content="width=device-width, initial-scale=1">
 <meta http-equiv="refresh" content="1; URL=fixme.html">
 
 <title>Routino Extras : Viewer for OpenStreetMap "fixme" Tags</title>
@@ -12,7 +13,7 @@
 
  Part of the Routino routing software.
 
- This file Copyright 2008-2013 Andrew M. Bishop
+ This file Copyright 2008-2015 Andrew M. Bishop
 
  This program is free software: you can redistribute it and/or modify
  it under the terms of the GNU Affero General Public License as published by
@@ -39,7 +40,6 @@
 
 <h1>Routino Extras : Viewer for OpenStreetMap "fixme" Tags</h1>
 
-<hr>
 </div>
 
 <!-- Header End -->
@@ -57,7 +57,6 @@
 <!-- Footer Start -->
 
 <div class="footer">
-<hr>
 
 <address>
 © Andrew M. Bishop - <a href="http://www.routino.org/">http://www.routino.org/</a>
diff --git a/extras/tagmodifier/Makefile b/extras/tagmodifier/Makefile
index 72a6e2a..b61014a 100644
--- a/extras/tagmodifier/Makefile
+++ b/extras/tagmodifier/Makefile
@@ -2,7 +2,7 @@
 #
 # Part of the Routino routing software.
 #
-# This file Copyright 2013-2014 Andrew M. Bishop
+# This file Copyright 2013-2015 Andrew M. Bishop
 #
 # This program is free software: you can redistribute it and/or modify
 # it under the terms of the GNU Affero General Public License as published by
@@ -29,7 +29,7 @@ D=$(wildcard .deps/*.d)
 
 ROUTINO_SRC=../../src
 
-EXE=tagmodifier
+EXE=tagmodifier$(.EXE)
 
 ########
 
@@ -41,8 +41,12 @@ TAGMODIFIER_OBJ=tagmodifier.o \
 	        $(ROUTINO_SRC)/files.o $(ROUTINO_SRC)/logging.o $(ROUTINO_SRC)/logerror.o \
 	        $(ROUTINO_SRC)/uncompress.o $(ROUTINO_SRC)/xmlparse.o $(ROUTINO_SRC)/tagging.o
 
-tagmodifier : $(TAGMODIFIER_OBJ)
-	$(LD) $(TAGMODIFIER_OBJ) -o $@ $(LDFLAGS)
+ifeq ($(HOST),MINGW)
+TAGMODIFIER_OBJ+=$(ROUTINO_SRC)/mman-win32.o
+endif
+
+tagmodifier$(.EXE) : $(TAGMODIFIER_OBJ)
+	$(LD) $^ -o $@ $(LDFLAGS)
 
 ########
 
@@ -66,14 +70,14 @@ install:
 clean:
 	rm -f *~
 	rm -f *.o
+	rm -f $(EXE)
+	rm -f $(D)
+	rm -fr .deps
 	rm -f core
 
 ########
 
 distclean: clean
-	-rm -f $(EXE)
-	-rm -f $(D)
-	-rm -fr .deps
 
 ########
 
diff --git a/extras/tagmodifier/README.txt b/extras/tagmodifier/README.txt
index f70b736..9198c18 100644
--- a/extras/tagmodifier/README.txt
+++ b/extras/tagmodifier/README.txt
@@ -9,13 +9,17 @@ make automatic rule-based modifications to tags within an XML file.
 tagmodifier
 -----------
 
-Usage: tagmodifier [--help]
+Usage: tagmodifier [--version]
+                   [--help]
                    [--tagging=<filename>]
-                   [--loggable] [--logtime]
+                   [--loggable] [--logtime] [--logmemory]
                    [--errorlog[<name>]]
                    [<filename.osm> | <filename.osm.bz2> |
                     <filename.osm.gz> | <filename.osm.xz>]
 
+--version
+       Print the version of Routino.
+
 --help
        Prints out the help information.
 
@@ -31,6 +35,9 @@ Usage: tagmodifier [--help]
 --logtime
        Print the elapsed time for the processing.
 
+--logmemory
+       Print the used memory for the processing.
+
 --errorlog[=<name>]
        Log parsing errors to 'error.log' or the specified file name.
 
diff --git a/extras/tagmodifier/tagmodifier.c b/extras/tagmodifier/tagmodifier.c
index 2f884eb..6400937 100644
--- a/extras/tagmodifier/tagmodifier.c
+++ b/extras/tagmodifier/tagmodifier.c
@@ -3,7 +3,7 @@
 
  Part of the Routino routing software.
  ******************/ /******************
- This file Copyright 2010-2014 Andrew M. Bishop
+ This file Copyright 2010-2015 Andrew M. Bishop
 
  This program is free software: you can redistribute it and/or modify
  it under the terms of the GNU Affero General Public License as published by
@@ -22,12 +22,13 @@
 
 #include <stdio.h>
 #include <stdlib.h>
-#include <unistd.h>
 #include <string.h>
 #include <ctype.h>
 #include <inttypes.h>
 #include <stdint.h>
 
+#include "version.h"
+
 #include "xmlparse.h"
 #include "tagging.h"
 
@@ -35,11 +36,11 @@
 #include "uncompress.h"
 
 
-/* Local variables */
+/* Local variables (re-initialised for each file) */
 
-static uint64_t nnodes=0,nways=0,nrelations=0;
+static uint64_t nnodes,nways,nrelations;
 
-TagList *current_tags=NULL;
+TagList *current_tags;
 
 
 /* Local functions */
@@ -64,70 +65,70 @@ static int boundsType_function(const char *_tag_,int _type_,const char *minlat,c
 /* The XML tag definitions */
 
 /*+ The boundsType type tag. +*/
-static xmltag boundsType_tag=
+static const xmltag boundsType_tag=
               {"bounds",
                5, {"minlat","minlon","maxlat","maxlon","origin"},
                boundsType_function,
                {NULL}};
 
 /*+ The boundType type tag. +*/
-static xmltag boundType_tag=
+static const xmltag boundType_tag=
               {"bound",
                2, {"box","origin"},
                boundType_function,
                {NULL}};
 
 /*+ The tagType type tag. +*/
-static xmltag tagType_tag=
+static const xmltag tagType_tag=
               {"tag",
                2, {"k","v"},
                tagType_function,
                {NULL}};
 
 /*+ The nodeType type tag. +*/
-static xmltag nodeType_tag=
+static const xmltag nodeType_tag=
               {"node",
                9, {"id","lat","lon","timestamp","uid","user","visible","version","action"},
                nodeType_function,
                {&tagType_tag,NULL}};
 
 /*+ The ndType type tag. +*/
-static xmltag ndType_tag=
+static const xmltag ndType_tag=
               {"nd",
                1, {"ref"},
                ndType_function,
                {NULL}};
 
 /*+ The memberType type tag. +*/
-static xmltag memberType_tag=
+static const xmltag memberType_tag=
               {"member",
                3, {"type","ref","role"},
                memberType_function,
                {NULL}};
 
 /*+ The wayType type tag. +*/
-static xmltag wayType_tag=
+static const xmltag wayType_tag=
               {"way",
                7, {"id","timestamp","uid","user","visible","version","action"},
                wayType_function,
                {&ndType_tag,&tagType_tag,NULL}};
 
 /*+ The relationType type tag. +*/
-static xmltag relationType_tag=
+static const xmltag relationType_tag=
               {"relation",
                7, {"id","timestamp","uid","user","visible","version","action"},
                relationType_function,
                {&memberType_tag,&tagType_tag,NULL}};
 
 /*+ The osmType type tag. +*/
-static xmltag osmType_tag=
+static const xmltag osmType_tag=
               {"osm",
                2, {"version","generator"},
                osmType_function,
                {&boundsType_tag,&boundType_tag,&nodeType_tag,&wayType_tag,&relationType_tag,NULL}};
 
 /*+ The xmlDeclaration type tag. +*/
-static xmltag xmlDeclaration_tag=
+static const xmltag xmlDeclaration_tag=
               {"xml",
                2, {"version","encoding"},
                xmlDeclaration_function,
@@ -135,7 +136,7 @@ static xmltag xmlDeclaration_tag=
 
 
 /*+ The complete set of tags at the top level. +*/
-static xmltag *xml_toplevel_tags[]={&xmlDeclaration_tag,&osmType_tag,NULL};
+static const xmltag *const xml_toplevel_tags[]={&xmlDeclaration_tag,&osmType_tag,NULL};
 
 
 /* The XML tag processing functions */
@@ -256,7 +257,7 @@ static int tagType_function(const char *_tag_,int _type_,const char *k,const cha
 
 static int nodeType_function(const char *_tag_,int _type_,const char *id,const char *lat,const char *lon,const char *timestamp,const char *uid,const char *user,const char *visible,const char *version,const char *action)
 {
- static int64_t llid;
+ static int64_t llid; /* static variable to store attributes from <node> tag until </node> tag */
 
  if(_type_&XMLPARSE_TAG_START)
    {
@@ -378,7 +379,7 @@ static int memberType_function(const char *_tag_,int _type_,const char *type,con
 
 static int wayType_function(const char *_tag_,int _type_,const char *id,const char *timestamp,const char *uid,const char *user,const char *visible,const char *version,const char *action)
 {
- static int64_t llid;
+ static int64_t llid; /* static variable to store attributes from <way> tag until </way> tag */
 
  if(_type_&XMLPARSE_TAG_START)
    {
@@ -450,7 +451,7 @@ static int wayType_function(const char *_tag_,int _type_,const char *id,const ch
 
 static int relationType_function(const char *_tag_,int _type_,const char *id,const char *timestamp,const char *uid,const char *user,const char *visible,const char *version,const char *action)
 {
- static int64_t llid;
+ static int64_t llid; /* static variable to store attributes from <relation> tag until </relation> tag */
 
  if(_type_&XMLPARSE_TAG_START)
    {
@@ -559,7 +560,9 @@ int main(int argc,char **argv)
 
  for(arg=1;arg<argc;arg++)
    {
-    if(!strcmp(argv[arg],"--help"))
+    if(!strcmp(argv[arg],"--version"))
+       print_usage(-1,NULL,NULL);
+    else if(!strcmp(argv[arg],"--help"))
        print_usage(1,NULL,NULL);
     else if(!strncmp(argv[arg],"--tagging=",10))
        tagging=&argv[arg][10];
@@ -567,6 +570,8 @@ int main(int argc,char **argv)
        option_loggable=1;
     else if(!strcmp(argv[arg],"--logtime"))
        option_logtime=1;
+    else if(!strcmp(argv[arg],"--logmemory"))
+       option_logmemory=1;
     else if(!strcmp(argv[arg],"--errorlog"))
        errorlog="error.log";
     else if(!strncmp(argv[arg],"--errorlog=",11))
@@ -629,6 +634,12 @@ int main(int argc,char **argv)
 
  /* Parse the file */
 
+ nnodes=0;
+ nways=0;
+ nrelations=0;
+
+ current_tags=NULL;
+
  fprintf_first(stderr,"Reading: Lines=0 Nodes=0 Ways=0 Relations=0");
 
  retval=ParseXML(fd,xml_toplevel_tags,XMLPARSE_UNKNOWN_ATTR_IGNORE);
@@ -651,7 +662,7 @@ int main(int argc,char **argv)
 /*++++++++++++++++++++++++++++++++++++++
   Print out the usage information.
 
-  int detail The level of detail to use - 0 = low, 1 = high.
+  int detail The level of detail to use: -1 = just version number, 0 = low detail, 1 = full details.
 
   const char *argerr The argument that gave the error (if there is one).
 
@@ -660,36 +671,49 @@ int main(int argc,char **argv)
 
 static void print_usage(int detail,const char *argerr,const char *err)
 {
- fprintf(stderr,
-         "Usage: tagmodifier [--help]\n"
-         "                   [--tagging=<filename>]\n"
-         "                   [--loggable] [--logtime]\n"
-         "                   [--errorlog[=<name>]]\n"
-         "                   <filename.osm>"
+ if(detail<0)
+   {
+    fprintf(stderr,
+            "Routino version " ROUTINO_VERSION " " ROUTINO_URL ".\n"
+            );
+   }
+
+ if(detail>=0)
+   {
+    fprintf(stderr,
+            "Usage: tagmodifier [--version]\n"
+            "                   [--help]\n"
+            "                   [--tagging=<filename>]\n"
+            "                   [--loggable] [--logtime] [--logmemory]\n"
+            "                   [--errorlog[=<name>]]\n"
+            "                   <filename.osm>"
 #if defined(USE_BZIP2) && USE_BZIP2
-         " | <filename.osm.bz2>"
+            " | <filename.osm.bz2>"
 #endif
 #if defined(USE_GZIP) && USE_GZIP
-         " | <filename.osm.gz>"
+            " | <filename.osm.gz>"
 #endif
 #if defined(USE_XZ) && USE_XZ
-         " | <filename.osm.xz>"
+            " | <filename.osm.xz>"
 #endif
-         "\n");
+            "\n");
 
- if(argerr)
-    fprintf(stderr,
-            "\n"
-            "Error with command line parameter: %s\n",argerr);
+    if(argerr)
+       fprintf(stderr,
+               "\n"
+               "Error with command line parameter: %s\n",argerr);
 
- if(err)
-    fprintf(stderr,
-            "\n"
-            "Error: %s\n",err);
+    if(err)
+       fprintf(stderr,
+               "\n"
+               "Error: %s\n",err);
+   }
 
- if(detail)
+ if(detail==1)
     fprintf(stderr,
             "\n"
+            "--version                 Print the version of Routino.\n"
+            "\n"
             "--help                    Prints this information.\n"
             "\n"
             "--tagging=<filename>      The name of the XML file containing the tagging rules\n"
@@ -697,6 +721,7 @@ static void print_usage(int detail,const char *argerr,const char *err)
             "\n"
             "--loggable                Print progress messages suitable for logging to file.\n"
             "--logtime                 Print the elapsed time for the processing.\n"
+            "--logmemory               Print the max allocated/mapped memory for each step.\n"
             "--errorlog[=<name>]       Log parsing errors to 'error.log' or the given name.\n"
             "\n"
             "<filename.osm>            The name of the file to process.\n"
diff --git a/src/Makefile b/src/Makefile
index 2857c85..554eb10 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -2,7 +2,7 @@
 #
 # Part of the Routino routing software.
 #
-# This file Copyright 2008-2014 Andrew M. Bishop
+# This file Copyright 2008-2015 Andrew M. Bishop
 #
 # This program is free software: you can redistribute it and/or modify
 # it under the terms of the GNU Affero General Public License as published by
@@ -22,26 +22,28 @@
 
 include ../Makefile.conf
 
-# Debugging options
-
-#CFLAGS+=-O0 -g
-#CFLAGS+=-pg
-#CFLAGS+=-fprofile-arcs -ftest-coverage
-
-#LDFLAGS+=-pg -static
-#LDFLAGS+=-fprofile-arcs -ftest-coverage
-
 # Sub-directories and sub-makefiles
 
-SUBFILES=$(wildcard */Makefile)
-SUBDIRS=$(foreach f,$(SUBFILES),$(dir $f))
+SUBDIRS=xml test
 
 # Compilation targets
 
 C=$(wildcard *.c)
 D=$(wildcard .deps/*.d)
 
-EXE=planetsplitter planetsplitter-slim router router-slim filedumperx filedumper filedumper-slim
+EXE=planetsplitter$(.EXE) planetsplitter-slim$(.EXE) router$(.EXE) router-slim$(.EXE) \
+    filedumperx$(.EXE) filedumper$(.EXE) filedumper-slim$(.EXE) \
+    router+lib$(.EXE) router+lib-slim$(.EXE)
+
+LIB=libroutino.so libroutino-slim.so
+
+ifeq ($(HOST),MINGW)
+LIB+=routino.dll routino-slim.dll
+LIB+=routino.def routino-slim.def
+LIB+=routino.lib routino-slim.lib
+endif
+
+INC=routino.h
 
 ########
 
@@ -50,7 +52,7 @@ all: all-local
 	   ( cd $$dir && $(MAKE) $@ ); \
 	done
 
-all-local: $(EXE)
+all-local: $(EXE) $(LIB)
 
 ########
 
@@ -62,8 +64,12 @@ PLANETSPLITTER_OBJ=planetsplitter.o \
 	           xmlparse.o tagging.o \
 	           uncompress.o osmxmlparse.o osmpbfparse.o osmo5mparse.o osmparser.o
 
-planetsplitter : $(PLANETSPLITTER_OBJ)
-	$(LD) $(PLANETSPLITTER_OBJ) -o $@ $(LDFLAGS)
+ifeq ($(HOST),MINGW)
+PLANETSPLITTER_OBJ+=mman-win32.o
+endif
+
+planetsplitter$(.EXE) : $(PLANETSPLITTER_OBJ)
+	$(LD) $^ -o $@ $(LDFLAGS)
 
 ########
 
@@ -75,8 +81,12 @@ PLANETSPLITTER_SLIM_OBJ=planetsplitter-slim.o \
 	                xmlparse.o tagging.o \
 	                uncompress.o osmxmlparse.o osmpbfparse.o osmo5mparse.o osmparser.o
 
-planetsplitter-slim : $(PLANETSPLITTER_SLIM_OBJ)
-	$(LD) $(PLANETSPLITTER_SLIM_OBJ) -o $@ $(LDFLAGS)
+ifeq ($(HOST),MINGW)
+PLANETSPLITTER_SLIM_OBJ+=mman-win32.o
+endif
+
+planetsplitter-slim$(.EXE) : $(PLANETSPLITTER_SLIM_OBJ)
+	$(LD) $^ -o $@ $(LDFLAGS)
 
 ########
 
@@ -86,8 +96,12 @@ ROUTER_OBJ=router.o \
 	   files.o logging.o profiles.o xmlparse.o \
 	   results.o queue.o translations.o
 
-router : $(ROUTER_OBJ)
-	$(LD) $(ROUTER_OBJ) -o $@ $(LDFLAGS)
+ifeq ($(HOST),MINGW)
+ROUTER_OBJ+=mman-win32.o
+endif
+
+router$(.EXE) : $(ROUTER_OBJ)
+	$(LD) $^ -o $@ $(LDFLAGS)
 
 ########
 
@@ -97,16 +111,24 @@ ROUTER_SLIM_OBJ=router-slim.o \
 	        files.o logging.o profiles.o xmlparse.o \
 	        results.o queue.o translations.o
 
-router-slim : $(ROUTER_SLIM_OBJ)
-	$(LD) $(ROUTER_SLIM_OBJ) -o $@ $(LDFLAGS)
+ifeq ($(HOST),MINGW)
+ROUTER_SLIM_OBJ+=mman-win32.o
+endif
+
+router-slim$(.EXE) : $(ROUTER_SLIM_OBJ)
+	$(LD) $^ -o $@ $(LDFLAGS)
 
 ########
 
 FILEDUMPERX_OBJ=filedumperx.o \
 	        files.o logging.o
 
-filedumperx : $(FILEDUMPERX_OBJ)
-	$(LD) $(FILEDUMPERX_OBJ) -o $@ $(LDFLAGS)
+ifeq ($(HOST),MINGW)
+FILEDUMPERX_OBJ+=mman-win32.o
+endif
+
+filedumperx$(.EXE) : $(FILEDUMPERX_OBJ)
+	$(LD) $^ -o $@ $(LDFLAGS)
 
 ########
 
@@ -115,28 +137,104 @@ FILEDUMPER_OBJ=filedumper.o \
                visualiser.o \
 	       files.o logging.o xmlparse.o
 
-filedumper : $(FILEDUMPER_OBJ)
-	$(LD) $(FILEDUMPER_OBJ) -o $@ $(LDFLAGS)
+ifeq ($(HOST),MINGW)
+FILEDUMPER_OBJ+=mman-win32.o
+endif
+
+filedumper$(.EXE) : $(FILEDUMPER_OBJ)
+	$(LD) $^ -o $@ $(LDFLAGS)
 
 ########
 
 FILEDUMPER_SLIM_OBJ=filedumper-slim.o \
 	       nodes-slim.o segments-slim.o ways-slim.o relations-slim.o types.o fakes-slim.o errorlog-slim.o \
-               visualiser-slim.o \
+	       visualiser-slim.o \
 	       files.o logging.o xmlparse.o
 
-filedumper-slim : $(FILEDUMPER_SLIM_OBJ)
-	$(LD) $(FILEDUMPER_SLIM_OBJ) -o $@ $(LDFLAGS)
+ifeq ($(HOST),MINGW)
+FILEDUMPER_SLIM_OBJ+=mman-win32.o
+endif
+
+filedumper-slim$(.EXE) : $(FILEDUMPER_SLIM_OBJ)
+	$(LD) $^ -o $@ $(LDFLAGS)
 
 ########
 
 %.o : %.c
 	@[ -d .deps ] || mkdir .deps
-	$(CC) -c $(CFLAGS) -DSLIM=0 -DDATADIR=\"$(datadir)\" $< -o $@ -MMD -MP -MF $(addprefix .deps/,$(addsuffix .d,$(basename $@)))
+	$(CC) -c $(CFLAGS) -DSLIM=0 -DROUTINO_DATADIR=\"$(datadir)\" $< -o $@ -MMD -MP -MF $(addprefix .deps/,$(addsuffix .d,$(basename $@)))
 
 %-slim.o : %.c
 	@[ -d .deps ] || mkdir .deps
-	$(CC) -c $(CFLAGS) -DSLIM=1 -DDATADIR=\"$(datadir)\" $< -o $@ -MMD -MP -MF $(addprefix .deps/,$(addsuffix .d,$(basename $@)))
+	$(CC) -c $(CFLAGS) -DSLIM=1 -DROUTINO_DATADIR=\"$(datadir)\" $< -o $@ -MMD -MP -MF $(addprefix .deps/,$(addsuffix .d,$(basename $@)))
+
+########
+
+ROUTER_LIB_OBJ=router+lib.o
+
+router+lib$(.EXE) : $(ROUTER_LIB_OBJ) libroutino.so
+	$(LD) $^ -o $@ $(LDFLAGS) $(LDFLAGS_LDSO)
+
+router+lib-slim$(.EXE) : $(ROUTER_LIB_OBJ) libroutino-slim.so
+	$(LD) $^ -o $@ $(LDFLAGS) $(LDFLAGS_LDSO)
+
+########
+
+LIBROUTINO_OBJ=routino-lib.o \
+	        nodes-lib.o segments-lib.o ways-lib.o relations-lib.o types-lib.o fakes-lib.o \
+	        optimiser-lib.o output-lib.o \
+	        files-lib.o profiles-lib.o xmlparse-lib.o \
+	        results-lib.o queue-lib.o translations-lib.o
+
+ifeq ($(HOST),MINGW)
+LIBROUTINO_OBJ+=mman-win32.o
+endif
+
+libroutino.so : $(LIBROUTINO_OBJ)
+	$(LD) $^ -o $@ $(LDFLAGS) $(LDFLAGS_LIB)
+
+routino.dll : libroutino.so
+	cp $< $@
+
+routino.def : routino-lib.o
+	dlltool -v --output-def $@ $<
+
+routino.lib : routino.dll routino.def
+	dlltool -v --dllname routino.dll --def routino.def --output-lib $@
+
+########
+
+LIBROUTINO_SLIM_OBJ=routino-slim-lib.o \
+	        nodes-slim-lib.o segments-slim-lib.o ways-slim-lib.o relations-slim-lib.o types-lib.o fakes-slim-lib.o \
+	        optimiser-slim-lib.o output-slim-lib.o \
+	        files-lib.o profiles-lib.o xmlparse-lib.o \
+	        results-lib.o queue-lib.o translations-lib.o
+
+ifeq ($(HOST),MINGW)
+LIBROUTINO_SLIM_OBJ+=mman-win32.o
+endif
+
+libroutino-slim.so : $(LIBROUTINO_SLIM_OBJ)
+	$(LD) $^ -o $@ $(LDFLAGS) $(LDFLAGS_LIB)
+
+routino-slim.dll : libroutino-slim.so
+	cp $< $@
+
+routino-slim.def : routino-slim-lib.o
+	dlltool -v --output-def $@ $<
+
+routino-slim.lib : routino-slim.dll routino-slim.def
+	dlltool -v --dllname routino-slim.dll --def routino-slim.def --output-lib $@
+
+########
+
+%-lib.o : %.c
+	@[ -d .deps ] || mkdir .deps
+	$(CC) -c $(CFLAGS) $(CFLAGS_LIB) -DSLIM=0 -DLIBROUTINO $< -o $@ -MMD -MP -MF $(addprefix .deps/,$(addsuffix .d,$(basename $@)))
+
+%-slim-lib.o : %.c
+	@[ -d .deps ] || mkdir .deps
+	$(CC) -c $(CFLAGS) $(CFLAGS_LIB) -DSLIM=1 -DLIBROUTINO $< -o $@ -MMD -MP -MF $(addprefix .deps/,$(addsuffix .d,$(basename $@)))
 
 ########
 
@@ -157,8 +255,24 @@ install: install-local
 install-local: all-local
 	@[ -d $(DESTDIR)$(bindir) ] || mkdir -p $(DESTDIR)$(bindir)
 	@for file in $(EXE); do \
-	    echo cp $$file $(DESTDIR)$(bindir) ;\
-	    cp -f $$file $(DESTDIR)$(bindir) ;\
+	    if [ -f $$file ]; then \
+	       echo cp $$file $(DESTDIR)$(bindir) ;\
+	       cp -f $$file $(DESTDIR)$(bindir) ;\
+	    fi ;\
+	 done
+	@[ -d $(DESTDIR)$(incdir) ] || mkdir -p $(DESTDIR)$(incdir)
+	@for file in $(INC); do \
+	    if [ -f $$file ]; then \
+	       echo cp $$file $(DESTDIR)$(incdir) ;\
+	       cp -f $$file $(DESTDIR)$(incdir) ;\
+	    fi ;\
+	 done
+	@[ -d $(DESTDIR)$(libdir) ] || mkdir -p $(DESTDIR)$(libdir)
+	@for file in $(LIB); do \
+	    if [ -f $$file ]; then \
+	       echo cp $$file $(DESTDIR)$(libdir) ;\
+	       cp -f $$file $(DESTDIR)$(libdir) ;\
+	    fi ;\
 	 done
 
 ########
@@ -171,6 +285,10 @@ clean: clean-local
 clean-local:
 	rm -f *~
 	rm -f *.o
+	rm -f $(EXE)
+	rm -f $(LIB)
+	rm -f $(D)
+	rm -fr .deps
 	rm -f core
 	rm -f *.gcda *.gcno *.gcov gmon.out
 
@@ -182,9 +300,6 @@ distclean: distclean-local
 	done
 
 distclean-local: clean-local
-	-rm -f $(EXE)
-	-rm -f $(D)
-	-rm -fr .deps
 
 ########
 
diff --git a/src/cache.h b/src/cache.h
index a10bb65..5ed6d3e 100644
--- a/src/cache.h
+++ b/src/cache.h
@@ -3,7 +3,7 @@
 
  Part of the Routino routing software.
  ******************/ /******************
- This file Copyright 2013-2014 Andrew M. Bishop
+ This file Copyright 2013-2015 Andrew M. Bishop
 
  This program is free software: you can redistribute it and/or modify
  it under the terms of the GNU Affero General Public License as published by
@@ -25,7 +25,6 @@
 #ifndef CACHE_H
 #define CACHE_H    /*+ To stop multiple inclusions. +*/
 
-#include <unistd.h>
 #include <stdlib.h>
 
 #include "types.h"
@@ -62,9 +61,9 @@ struct _##type##Cache                                                     \
 
 #define CACHE_DELETECACHE_PROTO(type) static inline void Delete##type##Cache(type##Cache *cache);
 
-#define CACHE_FETCHCACHE_PROTO(type) static inline type *FetchCached##type(type##Cache *cache,index_t index,int fd,off_t offset);
+#define CACHE_FETCHCACHE_PROTO(type) static inline type *FetchCached##type(type##Cache *cache,index_t index,int fd,offset_t offset);
 
-#define CACHE_REPLACECACHE_PROTO(type) static inline void ReplaceCached##type(type##Cache *cache,type *value,index_t index,int fd,off_t offset);
+#define CACHE_REPLACECACHE_PROTO(type) static inline void ReplaceCached##type(type##Cache *cache,type *value,index_t index,int fd,offset_t offset);
 
 #define CACHE_INVALIDATECACHE_PROTO(type) static inline void Invalidate##type##Cache(type##Cache *cache);
 
@@ -98,7 +97,7 @@ static inline void Delete##type##Cache(type##Cache *cache)      \
 /*+ A macro to create a function that fetches an item from a cache data structure or reads from file. +*/
 #define CACHE_FETCHCACHE(type) \
                                \
-static inline type *FetchCached##type(type##Cache *cache,index_t index,int fd,off_t offset) \
+static inline type *FetchCached##type(type##Cache *cache,index_t index,int fd,offset_t offset) \
 {                                                                                           \
  int row=index%CACHEWIDTH;                                                                  \
  int col;                                                                                   \
@@ -111,7 +110,7 @@ static inline type *FetchCached##type(type##Cache *cache,index_t index,int fd,of
                                                                                             \
  cache->first[row]=(cache->first[row]+1)%CACHEDEPTH;                                        \
                                                                                             \
- SlimFetch(fd,&cache->data[row][col],sizeof(type),offset+(off_t)index*sizeof(type));        \
+ SlimFetch(fd,&cache->data[row][col],sizeof(type),offset+(offset_t)index*sizeof(type));     \
                                                                                             \
  cache->indices[row][col]=index;                                                            \
                                                                                             \
@@ -122,7 +121,7 @@ static inline type *FetchCached##type(type##Cache *cache,index_t index,int fd,of
 /*+ A macro to create a function that replaces an item in a cache data structure and writes to file. +*/
 #define CACHE_REPLACECACHE(type) \
                                  \
-static inline void ReplaceCached##type(type##Cache *cache,type *value,index_t index,int fd,off_t offset) \
+static inline void ReplaceCached##type(type##Cache *cache,type *value,index_t index,int fd,offset_t offset) \
 {                                                                                                        \
  int row=index%CACHEWIDTH;                                                                               \
  int col;                                                                                                \
@@ -142,7 +141,7 @@ static inline void ReplaceCached##type(type##Cache *cache,type *value,index_t in
                                                                                                          \
  cache->data[row][col]=*value;                                                                           \
                                                                                                          \
- SlimReplace(fd,&cache->data[row][col],sizeof(type),offset+(off_t)index*sizeof(type));                   \
+ SlimReplace(fd,&cache->data[row][col],sizeof(type),offset+(offset_t)index*sizeof(type));                \
 }
 
 
diff --git a/src/errorlog.h b/src/errorlog.h
index 3b7f790..9ec276c 100644
--- a/src/errorlog.h
+++ b/src/errorlog.h
@@ -3,7 +3,7 @@
 
  Part of the Routino routing software.
  ******************/ /******************
- This file Copyright 2013-2014 Andrew M. Bishop
+ This file Copyright 2013-2015 Andrew M. Bishop
 
  This program is free software: you can redistribute it and/or modify
  it under the terms of the GNU Affero General Public License as published by
@@ -67,7 +67,7 @@ typedef struct _ErrorLogs
 
 #if !SLIM
 
- void     *data;                /*+ The memory mapped data in the file. +*/
+ char     *data;                /*+ The memory mapped data in the file. +*/
 
  index_t  *offsets;             /*+ A pointer to the array of offsets in the file. +*/
 
@@ -80,12 +80,12 @@ typedef struct _ErrorLogs
 
  int       fd;                  /*+ The file descriptor for the file. +*/
 
- off_t     offsetsoffset;       /*+ An allocated array with a copy of the file offsets. +*/
+ offset_t  offsetsoffset;       /*+ An allocated array with a copy of the file offsets. +*/
 
- off_t     errorlogsoffset_geo;    /*+ The offset of the geographical error logs within the file. +*/
- off_t     errorlogsoffset_nongeo; /*+ The offset of the non-geographical error logs within the file. +*/
+ offset_t  errorlogsoffset_geo;    /*+ The offset of the geographical error logs within the file. +*/
+ offset_t  errorlogsoffset_nongeo; /*+ The offset of the non-geographical error logs within the file. +*/
 
- off_t     stringsoffset;       /*+ The offset of the error strings within the file. +*/
+ offset_t  stringsoffset;       /*+ The offset of the error strings within the file. +*/
 
  ErrorLog  cached[2];           /*+ Some cached error logs read from the file in slim mode. +*/
 
@@ -144,7 +144,7 @@ static inline char *LookupErrorLogString(ErrorLogs *errorlogs,index_t index);
 
 static inline ErrorLog *LookupErrorLog(ErrorLogs *errorlogs,index_t index,int position)
 {
- SlimFetch(errorlogs->fd,&errorlogs->cached[position-1],sizeof(ErrorLog),errorlogs->errorlogsoffset_geo+(off_t)index*sizeof(ErrorLog));
+ SlimFetch(errorlogs->fd,&errorlogs->cached[position-1],sizeof(ErrorLog),errorlogs->errorlogsoffset_geo+(offset_t)index*sizeof(ErrorLog));
 
  return(&errorlogs->cached[position-1]);
 }
@@ -164,7 +164,7 @@ static inline index_t LookupErrorLogOffset(ErrorLogs *errorlogs,index_t index)
 {
  index_t offset;
 
- SlimFetch(errorlogs->fd,&offset,sizeof(index_t),errorlogs->offsetsoffset+(off_t)index*sizeof(index_t));
+ SlimFetch(errorlogs->fd,&offset,sizeof(index_t),errorlogs->offsetsoffset+(offset_t)index*sizeof(index_t));
 
  return(offset);
 }
diff --git a/src/errorlogx.c b/src/errorlogx.c
index c961505..6e7a1fd 100644
--- a/src/errorlogx.c
+++ b/src/errorlogx.c
@@ -3,7 +3,7 @@
 
  Part of the Routino routing software.
  ******************/ /******************
- This file Copyright 2013-2014 Andrew M. Bishop
+ This file Copyright 2013-2015 Andrew M. Bishop
 
  This program is free software: you can redistribute it and/or modify
  it under the terms of the GNU Affero General Public License as published by
@@ -42,7 +42,7 @@ extern char *errorbinfilename;
 
 /* Local variables */
 
-/*+ Temporary file-local variables for use by the sort functions. +*/
+/*+ Temporary file-local variables for use by the sort functions (re-initialised for each sort). +*/
 static latlong_t lat_min,lat_max,lon_min,lon_max;
 
 /* Local functions */
@@ -146,11 +146,7 @@ void ProcessErrorLogs(ErrorLogsX *errorlogsx,NodesX *nodesx,WaysX *waysx,Relatio
 
  /* Open the binary log file read-only and a new file writeable */
 
- oldfd=ReOpenFileBuffered(errorbinfilename);
-
- DeleteFile(errorbinfilename);
-
- newfd=OpenFileBufferedNew(errorbinfilename);
+ newfd=ReplaceFileBuffered(errorbinfilename,&oldfd);
 
  /* Loop through the file and merge the raw data into coordinates */
 
@@ -361,16 +357,16 @@ static void reindex_ways(WaysX *waysx)
 {
  FILESORT_VARINT waysize;
  int fd;
- off_t position=0;
- index_t index=0;
+ offset_t position=0;
+ index_t  index=0;
 
  waysx->number=waysx->knumber;
 
  waysx->idata=(way_t*)malloc(waysx->number*sizeof(way_t));
- waysx->odata=(off_t*)malloc(waysx->number*sizeof(off_t));
+ waysx->odata=(offset_t*)malloc(waysx->number*sizeof(offset_t));
 
  log_malloc(waysx->idata,waysx->number*sizeof(way_t));
- log_malloc(waysx->odata,waysx->number*sizeof(off_t));
+ log_malloc(waysx->odata,waysx->number*sizeof(offset_t));
 
  /* Get the way id and the offset for each way in the file */
 
@@ -406,7 +402,7 @@ static void reindex_relations(RelationsX *relationsx)
 {
  FILESORT_VARINT relationsize;
  int fd;
- off_t position=0;
+ offset_t position=0;
  index_t index;
  TurnRelX turnrelx;
 
@@ -415,10 +411,10 @@ static void reindex_relations(RelationsX *relationsx)
  relationsx->rrnumber=relationsx->rrknumber;
 
  relationsx->rridata=(relation_t*)malloc(relationsx->rrnumber*sizeof(relation_t));
- relationsx->rrodata=(off_t*)malloc(relationsx->rrnumber*sizeof(off_t));
+ relationsx->rrodata=(offset_t*)malloc(relationsx->rrnumber*sizeof(offset_t));
 
  log_malloc(relationsx->rridata,relationsx->rrnumber*sizeof(relation_t));
- log_malloc(relationsx->rrodata,relationsx->rrnumber*sizeof(off_t));
+ log_malloc(relationsx->rrodata,relationsx->rrnumber*sizeof(offset_t));
 
  /* Get the relation id and the offset for each relation in the file */
 
@@ -529,7 +525,7 @@ static int lookup_lat_long_way(WaysX *waysx,NodesX *nodesx,way_t way,latlong_t *
  else
    {
     int count=1;
-    off_t offset=waysx->odata[index];
+    offset_t offset=waysx->odata[index];
     node_t node1,node2,prevnode,node;
     latlong_t latitude1,longitude1,latitude2,longitude2;
 
@@ -624,7 +620,7 @@ static int lookup_lat_long_relation(RelationsX *relationsx,WaysX *waysx,NodesX *
  else
    {
     int count;
-    off_t offset=relationsx->rrodata[index];
+    offset_t offset=relationsx->rrodata[index];
     node_t node=NO_NODE_ID,tempnode;
     way_t way=NO_WAY_ID,tempway;
     relation_t relation=NO_RELATION_ID,temprelation;
@@ -702,11 +698,7 @@ void SortErrorLogsGeographically(ErrorLogsX *errorlogsx)
 
  /* Re-open the file read-only and a new file writeable */
 
- oldfd=ReOpenFileBuffered(errorbinfilename);
-
- DeleteFile(errorbinfilename);
-
- newfd=OpenFileBufferedNew(errorbinfilename);
+ newfd=ReplaceFileBuffered(errorbinfilename,&oldfd);
 
  /* Sort errors geographically */
 
@@ -832,7 +824,7 @@ void SaveErrorLogs(ErrorLogsX *errorlogsx,char *filename)
  ll_bin2_t latlonbin=0,maxlatlonbins;
  index_t *offsets;
  index_t number=0,number_geo=0,number_nongeo=0;
- off_t size;
+ offset_t size;
 
  /* Print the start message */
 
@@ -939,7 +931,7 @@ void SaveErrorLogs(ErrorLogsX *errorlogsx,char *filename)
    {
     int i;
     char buffer[4096];
-    off_t chunksize=(size>(off_t)sizeof(buffer)?(off_t)sizeof(buffer):size);
+    offset_t chunksize=(size>(offset_t)sizeof(buffer)?(offset_t)sizeof(buffer):size);
 
     ReadFileBuffered(oldfd,buffer,chunksize);
 
diff --git a/src/fakes.c b/src/fakes.c
index 863066f..625b445 100644
--- a/src/fakes.c
+++ b/src/fakes.c
@@ -3,7 +3,7 @@
 
  Part of the Routino routing software.
  ******************/ /******************
- This file Copyright 2008-2014 Andrew M. Bishop
+ This file Copyright 2008-2015 Andrew M. Bishop
 
  This program is free software: you can redistribute it and/or modify
  it under the terms of the GNU Affero General Public License as published by
@@ -31,6 +31,8 @@
 #define MINSEGMENT 0.005
 
 
+/* Local variables (re-initialised by DeleteFakeNodes() function) */
+
 /*+ A set of fake segments to allow start/finish in the middle of a segment. +*/
 static Segment fake_segments[4*NWAYPOINTS+1];
 
@@ -73,7 +75,7 @@ index_t CreateFakes(Nodes *nodes,Segments *segments,int point,Segment *segmentp,
  index_t fakenode;
  double lat1,lon1,lat2,lon2;
 
- /* Initialise the segments to fake values */
+ /* Initialise all the connecting segments to fake values */
 
  fake_segments[4*point-4].node1=NO_NODE;
  fake_segments[4*point-4].node2=NO_NODE;
@@ -231,6 +233,27 @@ index_t CreateFakeNullSegment(Segments *segments,index_t node,index_t segment,in
 
 
 /*++++++++++++++++++++++++++++++++++++++
+  Re-initialise the fake node data storage.
+  ++++++++++++++++++++++++++++++++++++++*/
+
+void DeleteFakeNodes(void)
+{
+ unsigned int i;
+
+ for(i=0;i<sizeof(fake_segments)/sizeof(fake_segments[0]);i++)
+   {
+    fake_segments[i].node1=NO_NODE;
+    fake_segments[i].node2=NO_NODE;
+   }
+
+ for(i=0;i<sizeof(real_segments)/sizeof(real_segments[0]);i++)
+    real_segments[i]=NO_SEGMENT;
+
+ prevpoint=0;
+}
+
+
+/*++++++++++++++++++++++++++++++++++++++
   Lookup the latitude and longitude of a fake node.
 
   index_t fakenode The fake node to lookup.
@@ -345,7 +368,7 @@ Segment *LookupFakeSegment(index_t fakesegment)
 
 index_t IndexFakeSegment(Segment *fakesegmentp)
 {
- index_t whichsegment=fakesegmentp-&fake_segments[0];
+ index_t whichsegment=(index_t)(fakesegmentp-&fake_segments[0]);
 
  return(whichsegment+SEGMENT_FAKE);
 }
diff --git a/src/fakes.h b/src/fakes.h
index 26a138f..0bb73a3 100644
--- a/src/fakes.h
+++ b/src/fakes.h
@@ -3,7 +3,7 @@
 
  Part of the Routino routing software.
  ******************/ /******************
- This file Copyright 2008-2014 Andrew M. Bishop
+ This file Copyright 2008-2015 Andrew M. Bishop
 
  This program is free software: you can redistribute it and/or modify
  it under the terms of the GNU Affero General Public License as published by
@@ -41,6 +41,8 @@ index_t CreateFakes(Nodes *nodes,Segments *segments,int point,Segment *segmentp,
 
 index_t CreateFakeNullSegment(Segments *segments,index_t node,index_t segment,int point);
 
+void DeleteFakeNodes(void);
+
 void GetFakeLatLong(index_t fakenode, double *latitude,double *longitude);
 
 Segment *FirstFakeSegment(index_t fakenode);
diff --git a/src/filedumper.c b/src/filedumper.c
index 3a36036..99050dc 100644
--- a/src/filedumper.c
+++ b/src/filedumper.c
@@ -3,7 +3,7 @@
 
  Part of the Routino routing software.
  ******************/ /******************
- This file Copyright 2008-2014 Andrew M. Bishop
+ This file Copyright 2008-2015 Andrew M. Bishop
 
  This program is free software: you can redistribute it and/or modify
  it under the terms of the GNU Affero General Public License as published by
@@ -24,10 +24,11 @@
 #include <stdlib.h>
 #include <string.h>
 #include <sys/stat.h>
-#include <sys/time.h>
 #include <time.h>
 #include <math.h>
 
+#include "version.h"
+
 #include "types.h"
 #include "nodes.h"
 #include "segments.h"
@@ -92,7 +93,9 @@ int main(int argc,char** argv)
 
  for(arg=1;arg<argc;arg++)
    {
-    if(!strcmp(argv[arg],"--help"))
+    if(!strcmp(argv[arg],"--version"))
+       print_usage(-1,NULL,NULL);
+    else if(!strcmp(argv[arg],"--help"))
        print_usage(1,NULL,NULL);
     else if(!strncmp(argv[arg],"--dir=",6))
        dirname=&argv[arg][6];
@@ -253,7 +256,7 @@ int main(int argc,char** argv)
     printf("-----\n");
     printf("\n");
 
-    printf("sizeof(Node) =%9lu Bytes\n",(unsigned long)sizeof(Node));
+    printf("sizeof(Node) =%9zu Bytes\n",sizeof(Node));
     printf("Number       =%9"Pindex_t"\n",OSMNodes->file.number);
     printf("Number(super)=%9"Pindex_t"\n",OSMNodes->file.snumber);
     printf("\n");
@@ -272,7 +275,7 @@ int main(int argc,char** argv)
     printf("--------\n");
     printf("\n");
 
-    printf("sizeof(Segment)=%9lu Bytes\n",(unsigned long)sizeof(Segment));
+    printf("sizeof(Segment)=%9zu Bytes\n",sizeof(Segment));
     printf("Number(total)  =%9"Pindex_t"\n",OSMSegments->file.number);
     printf("Number(super)  =%9"Pindex_t"\n",OSMSegments->file.snumber);
     printf("Number(normal) =%9"Pindex_t"\n",OSMSegments->file.nnumber);
@@ -284,12 +287,12 @@ int main(int argc,char** argv)
     printf("----\n");
     printf("\n");
 
-    printf("sizeof(Way)=%9lu Bytes\n",(unsigned long)sizeof(Way));
+    printf("sizeof(Way)=%9zu Bytes\n",sizeof(Way));
     printf("Number     =%9"Pindex_t"\n",OSMWays->file.number);
     printf("\n");
 
     stat(ways_filename,&buf);
-    printf("Total names=%9lu Bytes\n",(unsigned long)buf.st_size-(unsigned long)sizeof(Ways)-(unsigned long)OSMWays->file.number*(unsigned long)sizeof(Way));
+    printf("Total names=%9zu Bytes\n",(size_t)buf.st_size-sizeof(Ways)-OSMWays->file.number*sizeof(Way));
     printf("\n");
 
     printf("Included highways  : %s\n",HighwaysNameList(OSMWays->file.highways));
@@ -303,7 +306,7 @@ int main(int argc,char** argv)
     printf("---------\n");
     printf("\n");
 
-    printf("sizeof(TurnRelation)=%9lu Bytes\n",(unsigned long)sizeof(TurnRelation));
+    printf("sizeof(TurnRelation)=%9zu Bytes\n",sizeof(TurnRelation));
     printf("Number              =%9"Pindex_t"\n",OSMRelations->file.trnumber);
 
     if(errorlogs_filename)
@@ -320,9 +323,9 @@ int main(int argc,char** argv)
        printf("\n");
        stat(errorlogs_filename,&buf);
 #if !SLIM
-       printf("Total strings=%9lu Bytes\n",(unsigned long)buf.st_size-(unsigned long)(OSMErrorLogs->strings-(char*)OSMErrorLogs->data));
+       printf("Total strings=%9zu Bytes\n",(size_t)buf.st_size-(OSMErrorLogs->strings-(char*)OSMErrorLogs->data));
 #else
-       printf("Total strings=%9lu Bytes\n",(unsigned long)buf.st_size-(unsigned long)OSMErrorLogs->stringsoffset);
+       printf("Total strings=%9zu Bytes\n",(size_t)buf.st_size-(size_t)OSMErrorLogs->stringsoffset);
 #endif
       }
    }
@@ -796,10 +799,10 @@ static void print_node_osm(Nodes *nodes,index_t item)
  GetLatLong(nodes,item,nodep,&latitude,&longitude);
 
  if(nodep->allow==Transports_ALL && nodep->flags==0)
-    printf("  <node id='%lu' lat='%.7f' lon='%.7f' version='1' />\n",(unsigned long)item+1,radians_to_degrees(latitude),radians_to_degrees(longitude));
+    printf("  <node id='%"Pindex_t"' lat='%.7f' lon='%.7f' version='1' />\n",item+1,radians_to_degrees(latitude),radians_to_degrees(longitude));
  else
    {
-    printf("  <node id='%lu' lat='%.7f' lon='%.7f' version='1'>\n",(unsigned long)item+1,radians_to_degrees(latitude),radians_to_degrees(longitude));
+    printf("  <node id='%"Pindex_t"' lat='%.7f' lon='%.7f' version='1'>\n",item+1,radians_to_degrees(latitude),radians_to_degrees(longitude));
 
     if(nodep->flags & NODE_SUPER)
        printf("    <tag k='routino:super' v='yes' />\n");
@@ -839,17 +842,17 @@ static void print_segment_osm(Segments *segments,index_t item,Ways *ways)
  char *name=WayName(ways,wayp);
  int i;
 
- printf("  <way id='%lu' version='1'>\n",(unsigned long)item+1);
+ printf("  <way id='%"Pindex_t"' version='1'>\n",item+1);
 
  if(IsOnewayTo(segmentp,segmentp->node1))
    {
-    printf("    <nd ref='%lu' />\n",(unsigned long)segmentp->node2+1);
-    printf("    <nd ref='%lu' />\n",(unsigned long)segmentp->node1+1);
+    printf("    <nd ref='%"Pindex_t"' />\n",segmentp->node2+1);
+    printf("    <nd ref='%"Pindex_t"' />\n",segmentp->node1+1);
    }
  else
    {
-    printf("    <nd ref='%lu' />\n",(unsigned long)segmentp->node1+1);
-    printf("    <nd ref='%lu' />\n",(unsigned long)segmentp->node2+1);
+    printf("    <nd ref='%"Pindex_t"' />\n",segmentp->node1+1);
+    printf("    <nd ref='%"Pindex_t"' />\n",segmentp->node2+1);
    }
 
  if(IsSuperSegment(segmentp))
@@ -929,16 +932,16 @@ static void print_turn_relation_osm(Relations *relations,index_t item,Segments *
  else
     restriction="no_straight_on";
 
- printf("  <relation id='%lu' version='1'>\n",(unsigned long)item+1);
+ printf("  <relation id='%"Pindex_t"' version='1'>\n",item+1);
  printf("    <tag k='type' v='restriction' />\n");
  printf("    <tag k='restriction' v='%s'/>\n",restriction);
 
  if(relationp->except)
     printf("    <tag k='except' v='%s' />\n",AllowedNameList(relationp->except));
 
- printf("    <member type='way' ref='%lu' role='from' />\n",(unsigned long)relationp->from+1);
- printf("    <member type='node' ref='%lu' role='via' />\n",(unsigned long)relationp->via+1);
- printf("    <member type='way' ref='%lu' role='to' />\n",(unsigned long)relationp->to+1);
+ printf("    <member type='way' ref='%"Pindex_t"' role='from' />\n",relationp->from+1);
+ printf("    <member type='node' ref='%"Pindex_t"' role='via' />\n",relationp->via+1);
+ printf("    <member type='way' ref='%"Pindex_t"' role='to' />\n",relationp->to+1);
 
  printf("  </relation>\n");
 }
@@ -971,10 +974,10 @@ static void print_node_visualiser(Nodes *nodes,index_t item)
  GetLatLong(nodes,item,nodep,&latitude,&longitude);
 
  if(nodep->allow==Transports_ALL && nodep->flags==0)
-    printf("<routino:node id='%lu' lat='%.7f' lon='%.7f' />\n",(unsigned long)item+1,radians_to_degrees(latitude),radians_to_degrees(longitude));
+    printf("<routino:node id='%"Pindex_t"' lat='%.7f' lon='%.7f' />\n",item+1,radians_to_degrees(latitude),radians_to_degrees(longitude));
  else
    {
-    printf("<routino:node id='%lu' lat='%.7f' lon='%.7f'>\n",(unsigned long)item+1,radians_to_degrees(latitude),radians_to_degrees(longitude));
+    printf("<routino:node id='%"Pindex_t"' lat='%.7f' lon='%.7f'>\n",item+1,radians_to_degrees(latitude),radians_to_degrees(longitude));
 
     if(nodep->flags & NODE_SUPER)
        printf("   <tag k='routino:super' v='yes' />\n");
@@ -1014,17 +1017,17 @@ static void print_segment_visualiser(Segments *segments,index_t item,Ways *ways)
  char *name=WayName(ways,wayp);
  int i;
 
- printf("<routino:way id='%lu'>\n",(unsigned long)item+1);
+ printf("<routino:way id='%"Pindex_t"'>\n",item+1);
 
  if(IsOnewayTo(segmentp,segmentp->node1))
    {
-    printf("   <nd ref='%lu' />\n",(unsigned long)segmentp->node2+1);
-    printf("   <nd ref='%lu' />\n",(unsigned long)segmentp->node1+1);
+    printf("   <nd ref='%"Pindex_t"' />\n",segmentp->node2+1);
+    printf("   <nd ref='%"Pindex_t"' />\n",segmentp->node1+1);
    }
  else
    {
-    printf("   <nd ref='%lu' />\n",(unsigned long)segmentp->node1+1);
-    printf("   <nd ref='%lu' />\n",(unsigned long)segmentp->node2+1);
+    printf("   <nd ref='%"Pindex_t"' />\n",segmentp->node1+1);
+    printf("   <nd ref='%"Pindex_t"' />\n",segmentp->node2+1);
    }
 
  if(IsSuperSegment(segmentp))
@@ -1104,16 +1107,16 @@ static void print_turn_relation_visualiser(Relations *relations,index_t item,Seg
  else
     restriction="no_straight_on";
 
- printf("<routino:relation id='%lu'>\n",(unsigned long)item+1);
+ printf("<routino:relation id='%"Pindex_t"'>\n",item+1);
  printf("   <tag k='type' v='restriction' />\n");
  printf("   <tag k='restriction' v='%s'/>\n",restriction);
 
  if(relationp->except)
     printf("   <tag k='except' v='%s' />\n",AllowedNameList(relationp->except));
 
- printf("   <member type='way' ref='%lu' role='from' />\n",(unsigned long)relationp->from+1);
- printf("   <member type='node' ref='%lu' role='via' />\n",(unsigned long)relationp->via+1);
- printf("   <member type='way' ref='%lu' role='to' />\n",(unsigned long)relationp->to+1);
+ printf("   <member type='way' ref='%"Pindex_t"' role='from' />\n",relationp->from+1);
+ printf("   <member type='node' ref='%"Pindex_t"' role='via' />\n",relationp->via+1);
+ printf("   <member type='way' ref='%"Pindex_t"' role='to' />\n",relationp->to+1);
 
  printf("</routino:relation>\n");
 }
@@ -1152,7 +1155,7 @@ static const char* const months[12]={"Jan","Feb","Mar","Apr","May","Jun","Jul","
 
 static char *RFC822Date(time_t t)
 {
- static char value[32];
+ static char value[32]; /* static allocation of return value */
  char weekday[4];
  char month[4];
  struct tm *tim;
@@ -1182,7 +1185,7 @@ static char *RFC822Date(time_t t)
 /*++++++++++++++++++++++++++++++++++++++
   Print out the usage information.
 
-  int detail The level of detail to use - 0 = low, 1 = high.
+  int detail The level of detail to use: -1 = just version number, 0 = low detail, 1 = full details.
 
   const char *argerr The argument that gave the error (if there is one).
 
@@ -1191,39 +1194,52 @@ static char *RFC822Date(time_t t)
 
 static void print_usage(int detail,const char *argerr,const char *err)
 {
- fprintf(stderr,
-         "Usage: filedumper [--help]\n"
-         "                  [--dir=<dirname>] [--prefix=<name>]\n"
-         "                  [--statistics]\n"
-         "                  [--visualiser --latmin=<latmin> --latmax=<latmax>\n"
-         "                                --lonmin=<lonmin> --lonmax=<lonmax>\n"
-         "                                --data=<data-type>]\n"
-         "                  [--dump [--node=<node> ...]\n"
-         "                          [--segment=<segment> ...]\n"
-         "                          [--way=<way> ...]\n"
-         "                          [--turn-relation=<rel> ...]\n"
-         "                          [--errorlog=<number> ...]]\n"
-         "                  [--dump-osm [--no-super]\n"
-         "                              [--latmin=<latmin> --latmax=<latmax>\n"
-         "                               --lonmin=<lonmin> --lonmax=<lonmax>]]\n"
-         "                  [--dump-visualiser [--data=node<node>]\n"
-         "                                     [--data=segment<segment>]\n"
-         "                                     [--data=turn-relation<rel>]\n"
-         "                                     [--data=errorlog<number>]]\n");
-
- if(argerr)
+ if(detail<0)
+   {
     fprintf(stderr,
-            "\n"
-            "Error with command line parameter: %s\n",argerr);
+            "Routino version " ROUTINO_VERSION " " ROUTINO_URL ".\n"
+            );
+   }
 
- if(err)
+ if(detail>=0)
+   {
     fprintf(stderr,
-            "\n"
-            "Error: %s\n",err);
+            "Usage: filedumper [--version]\n"
+            "                  [--help]\n"
+            "                  [--dir=<dirname>] [--prefix=<name>]\n"
+            "                  [--statistics]\n"
+            "                  [--visualiser --latmin=<latmin> --latmax=<latmax>\n"
+            "                                --lonmin=<lonmin> --lonmax=<lonmax>\n"
+            "                                --data=<data-type>]\n"
+            "                  [--dump [--node=<node> ...]\n"
+            "                          [--segment=<segment> ...]\n"
+            "                          [--way=<way> ...]\n"
+            "                          [--turn-relation=<rel> ...]\n"
+            "                          [--errorlog=<number> ...]]\n"
+            "                  [--dump-osm [--no-super]\n"
+            "                              [--latmin=<latmin> --latmax=<latmax>\n"
+            "                               --lonmin=<lonmin> --lonmax=<lonmax>]]\n"
+            "                  [--dump-visualiser [--data=node<node>]\n"
+            "                                     [--data=segment<segment>]\n"
+            "                                     [--data=turn-relation<rel>]\n"
+            "                                     [--data=errorlog<number>]]\n");
+
+    if(argerr)
+       fprintf(stderr,
+               "\n"
+               "Error with command line parameter: %s\n",argerr);
+
+    if(err)
+       fprintf(stderr,
+               "\n"
+               "Error: %s\n",err);
+   }
 
- if(detail)
+ if(detail==1)
     fprintf(stderr,
             "\n"
+            "--version                 Print the version of Routino.\n"
+            "\n"
             "--help                    Prints this information.\n"
             "\n"
             "--dir=<dirname>           The directory containing the routing database.\n"
diff --git a/src/filedumperx.c b/src/filedumperx.c
index 8f6300f..6eb971d 100644
--- a/src/filedumperx.c
+++ b/src/filedumperx.c
@@ -3,7 +3,7 @@
 
  Part of the Routino routing software.
  ******************/ /******************
- This file Copyright 2008-2014 Andrew M. Bishop
+ This file Copyright 2008-2015 Andrew M. Bishop
 
  This program is free software: you can redistribute it and/or modify
  it under the terms of the GNU Affero General Public License as published by
@@ -25,6 +25,8 @@
 #include <string.h>
 #include <sys/stat.h>
 
+#include "version.h"
+
 #include "typesx.h"
 #include "nodesx.h"
 #include "waysx.h"
@@ -59,7 +61,9 @@ int main(int argc,char** argv)
 
  for(arg=1;arg<argc;arg++)
    {
-    if(!strcmp(argv[arg],"--help"))
+    if(!strcmp(argv[arg],"--version"))
+       print_usage(-1,NULL,NULL);
+    else if(!strcmp(argv[arg],"--help"))
        print_usage(1,NULL,NULL);
     else if(!strncmp(argv[arg],"--dir=",6))
        dirname=&argv[arg][6];
@@ -82,7 +86,7 @@ int main(int argc,char** argv)
  if((option_dump)!=1)
     print_usage(0,NULL,"Must choose --dump.");
 
- /* Load in the data - Note: No error checking because Load*List() will call exit() in case of an error. */
+ /* Get the filenames. */
 
  nodes_filename=FileName(dirname,prefix,"nodesx.parsed.mem");
 
@@ -285,7 +289,7 @@ static void print_turn_relations(const char *filename)
 /*++++++++++++++++++++++++++++++++++++++
   Print out the usage information.
 
-  int detail The level of detail to use - 0 = low, 1 = high.
+  int detail The level of detail to use: -1 = just version number, 0 = low detail, 1 = full details.
 
   const char *argerr The argument that gave the error (if there is one).
 
@@ -294,27 +298,40 @@ static void print_turn_relations(const char *filename)
 
 static void print_usage(int detail,const char *argerr,const char *err)
 {
- fprintf(stderr,
-         "Usage: filedumperx [--help]\n"
-         "                   [--dir=<dirname>] [--prefix=<name>]\n"
-         "                   [--dump [--nodes]\n"
-         "                           [--ways]\n"
-         "                           [--route-relations]\n"
-         "                           [--turn-relations]]\n");
-
- if(argerr)
+ if(detail<0)
+   {
     fprintf(stderr,
-            "\n"
-            "Error with command line parameter: %s\n",argerr);
+            "Routino version " ROUTINO_VERSION " " ROUTINO_URL ".\n"
+            );
+   }
 
- if(err)
+ if(detail>=0)
+   {
     fprintf(stderr,
-            "\n"
-            "Error: %s\n",err);
+            "Usage: filedumperx [--version]\n"
+            "                   [--help]\n"
+            "                   [--dir=<dirname>] [--prefix=<name>]\n"
+            "                   [--dump [--nodes]\n"
+            "                           [--ways]\n"
+            "                           [--route-relations]\n"
+            "                           [--turn-relations]]\n");
+
+    if(argerr)
+       fprintf(stderr,
+               "\n"
+               "Error with command line parameter: %s\n",argerr);
+
+    if(err)
+       fprintf(stderr,
+               "\n"
+               "Error: %s\n",err);
+   }
 
- if(detail)
+ if(detail==1)
     fprintf(stderr,
             "\n"
+            "--version                 Print the version of Routino.\n"
+            "\n"
             "--help                    Prints this information.\n"
             "\n"
             "--dir=<dirname>           The directory containing the routing database.\n"
diff --git a/src/files.c b/src/files.c
index 586c256..8c5b6ca 100644
--- a/src/files.c
+++ b/src/files.c
@@ -3,7 +3,7 @@
 
  Part of the Routino routing software.
  ******************/ /******************
- This file Copyright 2008-2014 Andrew M. Bishop
+ This file Copyright 2008-2015 Andrew M. Bishop
 
  This program is free software: you can redistribute it and/or modify
  it under the terms of the GNU Affero General Public License as published by
@@ -20,14 +20,41 @@
  ***************************************/
 
 
+#if defined(_MSC_VER)
+#include <io.h>
+#include <basetsd.h>
+#define read(fd,address,length)  _read(fd,address,(unsigned int)(length))
+#define write(fd,address,length) _write(fd,address,(unsigned int)(length))
+#define open    _open
+#define close   _close
+#define unlink  _unlink
+#define ssize_t SSIZE_T
+#else
 #include <unistd.h>
+#endif
+
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
 #include <fcntl.h>
 #include <errno.h>
 #include <sys/stat.h>
+
+#if defined(_MSC_VER) || defined(__MINGW32__)
+#undef lseek
+#undef stat
+#undef fstat
+#define lseek _lseeki64
+#define stat  _stati64
+#define fstat _fstati64
+#endif
+
+#if defined(_MSC_VER) || defined(__MINGW32__)
+#include "mman-win32.h"
+#else
 #include <sys/mman.h>
+#endif
+
 #include <sys/types.h>
 
 #include "files.h"
@@ -38,7 +65,7 @@ struct mmapinfo
 {
  const char  *filename;         /*+ The name of the file (the index of the list). +*/
        int    fd;               /*+ The file descriptor used when it was opened. +*/
-       void  *address;          /*+ The address the file was mapped to. +*/
+       char  *address;          /*+ The address the file was mapped to. +*/
        size_t length;           /*+ The length of the file. +*/
 };
 
@@ -54,7 +81,6 @@ static int nmappedfiles=0;
 /*+ A structure to contain the list of file buffers. +*/
 struct filebuffer
 {
- int    fd;                     /*+ The file descriptor used when it was opened. +*/
  char   buffer[BUFFLEN];        /*+ The data buffer. +*/
  size_t pointer;                /*+ The read/write pointer for the file buffer. +*/
  size_t length;                 /*+ The read pointer for the file buffer. +*/
@@ -68,10 +94,34 @@ static struct filebuffer **filebuffers=NULL;
 static int nfilebuffers=0;
 
 
+#if defined(_MSC_VER) || defined(__MINGW32__)
+
+/*+ A structure to contain the list of opened files to record which are to be deleted when closed. +*/
+struct openedfile
+{
+ const char *filename;          /*+ The name of the file. +*/
+       int   delete;            /*+ Set to non-zero value if the file is to be deleted when closed. +*/
+};
+
+/*+ The list of opened files. +*/
+static struct openedfile **openedfiles=NULL;
+
+/*+ The number of allocated opened file buffer pointers. +*/
+static int nopenedfiles=0;
+
+#endif
+
+
 /* Local functions */
 
 static void CreateFileBuffer(int fd,int read_write);
 
+#if defined(_MSC_VER) || defined(__MINGW32__)
+
+static void CreateOpenedFile(int fd,const char *filename);
+
+#endif
+
 
 /*++++++++++++++++++++++++++++++++++++++
   Return a filename composed of the dirname, prefix and name.
@@ -107,25 +157,37 @@ void *MapFile(const char *filename)
 {
  int fd;
  struct stat buf;
- off_t size;
+ offset_t size;
  void *address;
 
  /* Open the file */
 
+#if defined(_MSC_VER) || defined(__MINGW32__)
+ fd=open(filename,O_RDONLY|O_BINARY|O_RANDOM);
+#else
  fd=open(filename,O_RDONLY);
+#endif
 
  if(fd<0)
    {
+#ifdef LIBROUTINO
+    return(NULL);
+#else
     fprintf(stderr,"Cannot open file '%s' for reading [%s].\n",filename,strerror(errno));
     exit(EXIT_FAILURE);
+#endif
    }
 
  /* Get its size */
 
  if(stat(filename,&buf))
    {
+#ifdef LIBROUTINO
+    return(NULL);
+#else
     fprintf(stderr,"Cannot stat file '%s' [%s].\n",filename,strerror(errno));
     exit(EXIT_FAILURE);
+#endif
    }
 
  size=buf.st_size;
@@ -138,11 +200,17 @@ void *MapFile(const char *filename)
    {
     close(fd);
 
+#ifdef LIBROUTINO
+    return(NULL);
+#else
     fprintf(stderr,"Cannot mmap file '%s' for reading [%s].\n",filename,strerror(errno));
     exit(EXIT_FAILURE);
+#endif
    }
 
+#ifndef LIBROUTINO
  log_mmap(size);
+#endif
 
  /* Store the information about the mapped file */
 
@@ -171,25 +239,37 @@ void *MapFileWriteable(const char *filename)
 {
  int fd;
  struct stat buf;
- off_t size;
+ offset_t size;
  void *address;
 
  /* Open the file */
 
+#if defined(_MSC_VER) || defined(__MINGW32__)
+ fd=open(filename,O_RDWR|O_BINARY|O_RANDOM);
+#else
  fd=open(filename,O_RDWR);
+#endif
 
  if(fd<0)
    {
+#ifdef LIBROUTINO
+    return(NULL);
+#else
     fprintf(stderr,"Cannot open file '%s' for reading and writing [%s].\n",filename,strerror(errno));
     exit(EXIT_FAILURE);
+#endif
    }
 
  /* Get its size */
 
  if(stat(filename,&buf))
    {
+#ifdef LIBROUTINO
+    return(NULL);
+#else
     fprintf(stderr,"Cannot stat file '%s' [%s].\n",filename,strerror(errno));
     exit(EXIT_FAILURE);
+#endif
    }
 
  size=buf.st_size;
@@ -202,11 +282,17 @@ void *MapFileWriteable(const char *filename)
    {
     close(fd);
 
+#ifdef LIBROUTINO
+    return(NULL);
+#else
     fprintf(stderr,"Cannot mmap file '%s' for reading and writing [%s].\n",filename,strerror(errno));
     exit(EXIT_FAILURE);
+#endif
    }
 
+#ifndef LIBROUTINO
  log_mmap(size);
+#endif
 
  /* Store the information about the mapped file */
 
@@ -241,8 +327,12 @@ void *UnmapFile(const void *address)
 
  if(i==nmappedfiles)
    {
+#ifdef LIBROUTINO
+    return(NULL);
+#else
     fprintf(stderr,"The data at address %p was not mapped using MapFile().\n",address);
     exit(EXIT_FAILURE);
+#endif
    }
 
  /* Close the file */
@@ -253,7 +343,9 @@ void *UnmapFile(const void *address)
 
  munmap(mappedfiles[i].address,mappedfiles[i].length);
 
+#ifndef LIBROUTINO
  log_munmap(mappedfiles[i].length);
+#endif
 
  /* Shuffle the list of files */
 
@@ -280,12 +372,20 @@ int SlimMapFile(const char *filename)
 
  /* Open the file */
 
+#if defined(_MSC_VER) || defined(__MINGW32__)
+ fd=open(filename,O_RDONLY|O_BINARY|O_RANDOM);
+#else
  fd=open(filename,O_RDONLY);
+#endif
 
  if(fd<0)
    {
+#ifdef LIBROUTINO
+    return(-1);
+#else
     fprintf(stderr,"Cannot open file '%s' for reading [%s].\n",filename,strerror(errno));
     exit(EXIT_FAILURE);
+#endif
    }
 
  CreateFileBuffer(fd,0);
@@ -308,12 +408,20 @@ int SlimMapFileWriteable(const char *filename)
 
  /* Open the file */
 
+#if defined(_MSC_VER) || defined(__MINGW32__)
+ fd=open(filename,O_RDWR|O_BINARY|O_RANDOM);
+#else
  fd=open(filename,O_RDWR);
+#endif
 
  if(fd<0)
    {
+#ifdef LIBROUTINO
+    return(-1);
+#else
     fprintf(stderr,"Cannot open file '%s' for reading and writing [%s].\n",filename,strerror(errno));
     exit(EXIT_FAILURE);
+#endif
    }
 
  CreateFileBuffer(fd,0);
@@ -352,16 +460,28 @@ int OpenFileBufferedNew(const char *filename)
 
  /* Open the file */
 
- fd=open(filename,O_WRONLY|O_CREAT|O_TRUNC,S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
+#if defined(_MSC_VER) || defined(__MINGW32__)
+ fd=open(filename,O_WRONLY|O_CREAT|O_TRUNC|O_BINARY|O_RANDOM,S_IREAD|S_IWRITE);
+#else
+ fd=open(filename,O_WRONLY|O_CREAT|O_TRUNC                  ,S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
+#endif
 
  if(fd<0)
    {
+#ifdef LIBROUTINO
+    return(-1);
+#else
     fprintf(stderr,"Cannot open file '%s' for writing [%s].\n",filename,strerror(errno));
     exit(EXIT_FAILURE);
+#endif
    }
 
  CreateFileBuffer(fd,-1);
 
+#if defined(_MSC_VER) || defined(__MINGW32__)
+ CreateOpenedFile(fd,filename);
+#endif
+
  return(fd);
 }
 
@@ -380,16 +500,28 @@ int OpenFileBufferedAppend(const char *filename)
 
  /* Open the file */
 
- fd=open(filename,O_WRONLY|O_CREAT|O_APPEND,S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
+#if defined(_MSC_VER) || defined(__MINGW32__)
+ fd=open(filename,O_WRONLY|O_CREAT|O_APPEND|O_BINARY|O_RANDOM,S_IREAD|S_IWRITE);
+#else
+ fd=open(filename,O_WRONLY|O_CREAT|O_APPEND                  ,S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
+#endif
 
  if(fd<0)
    {
+#ifdef LIBROUTINO
+    return(-1);
+#else
     fprintf(stderr,"Cannot open file '%s' for appending [%s].\n",filename,strerror(errno));
     exit(EXIT_FAILURE);
+#endif
    }
 
  CreateFileBuffer(fd,-1);
 
+#if defined(_MSC_VER) || defined(__MINGW32__)
+ CreateOpenedFile(fd,filename);
+#endif
+
  return(fd);
 }
 
@@ -408,21 +540,75 @@ int ReOpenFileBuffered(const char *filename)
 
  /* Open the file */
 
+#if defined(_MSC_VER) || defined(__MINGW32__)
+ fd=open(filename,O_RDONLY|O_BINARY|O_RANDOM);
+#else
  fd=open(filename,O_RDONLY);
+#endif
 
  if(fd<0)
    {
+#ifdef LIBROUTINO
+    return(-1);
+#else
     fprintf(stderr,"Cannot open file '%s' for reading [%s].\n",filename,strerror(errno));
     exit(EXIT_FAILURE);
+#endif
    }
 
  CreateFileBuffer(fd,1);
 
+#if defined(_MSC_VER) || defined(__MINGW32__)
+ CreateOpenedFile(fd,filename);
+#endif
+
  return(fd);
 }
 
 
 /*++++++++++++++++++++++++++++++++++++++
+  Open an existing file on disk for reading (with buffering), delete
+  it and open a new file on disk for writing (with buffering).
+
+  int ReplaceFileBuffered Returns the file descriptor of the new writable file.
+
+  const char *filename The name of the file to open, delete and replace.
+
+  int *oldfd Returns the file descriptor of the old, readable file.
+  ++++++++++++++++++++++++++++++++++++++*/
+
+int ReplaceFileBuffered(const char *filename,int *oldfd)
+{
+ int newfd;
+
+#if defined(_MSC_VER) || defined(__MINGW32__)
+
+ char *filename2;
+
+ filename2=strcpy(malloc(strlen(filename)+2),filename);
+ strcat(filename2,"2");
+
+ RenameFile(filename,filename2);
+
+ *oldfd=ReOpenFileBuffered(filename2);
+ 
+ DeleteFile(filename2);
+
+#else
+
+ *oldfd=ReOpenFileBuffered(filename);
+ 
+ DeleteFile(filename);
+
+#endif
+
+ newfd=OpenFileBufferedNew(filename);
+
+ return(newfd);
+}
+
+
+/*++++++++++++++++++++++++++++++++++++++
   Write data to a file descriptor (via a buffer).
 
   int WriteFileBuffered Returns 0 if OK or something else in case of an error.
@@ -436,11 +622,13 @@ int ReOpenFileBuffered(const char *filename)
 
 int WriteFileBuffered(int fd,const void *address,size_t length)
 {
+#ifndef LIBROUTINO
  logassert(fd!=-1,"File descriptor is in error - report a bug");
 
  logassert(fd<nfilebuffers && filebuffers[fd],"File descriptor has no buffer - report a bug");
 
  logassert(!filebuffers[fd]->reading,"File descriptor was not opened for writing - report a bug");
+#endif
 
  /* Write the data */
 
@@ -482,11 +670,13 @@ int WriteFileBuffered(int fd,const void *address,size_t length)
 
 int ReadFileBuffered(int fd,void *address,size_t length)
 {
+#ifndef LIBROUTINO
  logassert(fd!=-1,"File descriptor is in error - report a bug");
 
  logassert(fd<nfilebuffers && filebuffers[fd],"File descriptor has no buffer - report a bug");
 
  logassert(filebuffers[fd]->reading,"File descriptor was not opened for reading - report a bug");
+#endif
 
  /* Read the data */
 
@@ -495,7 +685,7 @@ int ReadFileBuffered(int fd,void *address,size_t length)
       {
        memcpy(address,filebuffers[fd]->buffer+filebuffers[fd]->pointer,filebuffers[fd]->length-filebuffers[fd]->pointer);
 
-       address+=filebuffers[fd]->length-filebuffers[fd]->pointer;
+       address=(char*)address+filebuffers[fd]->length-filebuffers[fd]->pointer;
        length-=filebuffers[fd]->length-filebuffers[fd]->pointer;
 
        filebuffers[fd]->pointer=0;
@@ -517,7 +707,6 @@ int ReadFileBuffered(int fd,void *address,size_t length)
     if(len<=0)
        return(-1);
 
-
     filebuffers[fd]->length=len;
     filebuffers[fd]->pointer=0;
    }
@@ -540,14 +729,16 @@ int ReadFileBuffered(int fd,void *address,size_t length)
 
   int fd The file descriptor to seek within.
 
-  off_t position The position to seek to.
+  offset_t position The position to seek to.
   ++++++++++++++++++++++++++++++++++++++*/
 
-int SeekFileBuffered(int fd,off_t position)
+int SeekFileBuffered(int fd,offset_t position)
 {
+#ifndef LIBROUTINO
  logassert(fd!=-1,"File descriptor is in error - report a bug");
 
  logassert(fd<nfilebuffers && filebuffers[fd],"File descriptor has no buffer - report a bug");
+#endif
 
  /* Seek the data - doesn't need to be highly optimised */
 
@@ -572,22 +763,24 @@ int SeekFileBuffered(int fd,off_t position)
 
   int fd The file descriptor to skip within.
 
-  off_t skip The amount to skip forward.
+  offset_t skip The amount to skip forward.
   ++++++++++++++++++++++++++++++++++++++*/
 
-int SkipFileBuffered(int fd,off_t skip)
+int SkipFileBuffered(int fd,offset_t skip)
 {
+#ifndef LIBROUTINO
  logassert(fd!=-1,"File descriptor is in error - report a bug");
 
  logassert(fd<nfilebuffers && filebuffers[fd],"File descriptor has no buffer - report a bug");
 
  logassert(filebuffers[fd]->reading,"File descriptor was not opened for reading - report a bug");
+#endif
 
  /* Skip the data - needs to be optimised */
 
  if((filebuffers[fd]->pointer+skip)>filebuffers[fd]->length)
    {
-    skip-=filebuffers[fd]->length-filebuffers[fd]->pointer;
+    skip-=(offset_t)(filebuffers[fd]->length-filebuffers[fd]->pointer);
 
     filebuffers[fd]->pointer=0;
     filebuffers[fd]->length=0;
@@ -605,19 +798,23 @@ int SkipFileBuffered(int fd,off_t skip)
 /*++++++++++++++++++++++++++++++++++++++
   Get the size of a file.
 
-  off_t SizeFile Returns the file size if OK or exits in case of an error.
+  offset_t SizeFile Returns the file size if OK or exits in case of an error.
 
   const char *filename The name of the file to check.
   ++++++++++++++++++++++++++++++++++++++*/
 
-off_t SizeFile(const char *filename)
+offset_t SizeFile(const char *filename)
 {
  struct stat buf;
 
  if(stat(filename,&buf))
    {
+#ifdef LIBROUTINO
+    return(-1);
+#else
     fprintf(stderr,"Cannot stat file '%s' [%s].\n",filename,strerror(errno));
     exit(EXIT_FAILURE);
+#endif
    }
 
  return(buf.st_size);
@@ -627,19 +824,23 @@ off_t SizeFile(const char *filename)
 /*++++++++++++++++++++++++++++++++++++++
   Get the size of a file from a file descriptor.
 
-  off_t SizeFileFD Returns the file size if OK or exits in case of an error.
+  offset_t SizeFileFD Returns the file size if OK or exits in case of an error.
 
   int fd The file descriptor to check.
   ++++++++++++++++++++++++++++++++++++++*/
 
-off_t SizeFileFD(int fd)
+offset_t SizeFileFD(int fd)
 {
  struct stat buf;
 
  if(fstat(fd,&buf))
    {
+#ifdef LIBROUTINO
+    return(-1);
+#else
     fprintf(stderr,"Cannot stat file descriptor '%d' [%s].\n",fd,strerror(errno));
     exit(EXIT_FAILURE);
+#endif
    }
 
  return(buf.st_size);
@@ -675,7 +876,9 @@ int ExistsFile(const char *filename)
 
 int CloseFileBuffered(int fd)
 {
+#ifndef LIBROUTINO
  logassert(fd<nfilebuffers && filebuffers[fd],"File descriptor has no buffer - report a bug");
+#endif
 
  if(!filebuffers[fd]->reading)
     if(write(fd,filebuffers[fd]->buffer,filebuffers[fd]->pointer)!=(ssize_t)filebuffers[fd]->pointer)
@@ -684,9 +887,22 @@ int CloseFileBuffered(int fd)
  close(fd);
 
  free(filebuffers[fd]);
-
  filebuffers[fd]=NULL;
 
+#if defined(_MSC_VER) || defined(__MINGW32__)
+
+#ifndef LIBROUTINO
+ logassert(fd<nopenedfiles && openedfiles[fd],"File descriptor has no record of opening - report a bug");
+#endif
+
+ if(openedfiles[fd]->delete)
+    unlink(openedfiles[fd]->filename);
+
+ free(openedfiles[fd]);
+ openedfiles[fd]=NULL;
+
+#endif
+
  return(-1);
 }
 
@@ -705,14 +921,26 @@ int OpenFile(const char *filename)
 
  /* Open the file */
 
+#if defined(_MSC_VER) || defined(__MINGW32__)
+ fd=open(filename,O_RDONLY|O_BINARY|O_RANDOM);
+#else
  fd=open(filename,O_RDONLY);
+#endif
 
  if(fd<0)
    {
+#ifdef LIBROUTINO
+    return(-1);
+#else
     fprintf(stderr,"Cannot open file '%s' for reading [%s].\n",filename,strerror(errno));
     exit(EXIT_FAILURE);
+#endif
    }
 
+#if defined(_MSC_VER) || defined(__MINGW32__)
+ CreateOpenedFile(fd,filename);
+#endif
+
  return(fd);
 }
 
@@ -726,6 +954,20 @@ int OpenFile(const char *filename)
 void CloseFile(int fd)
 {
  close(fd);
+
+#if defined(_MSC_VER) || defined(__MINGW32__)
+
+#ifndef LIBROUTINO
+ logassert(fd<nopenedfiles && openedfiles[fd],"File descriptor has no record of opening - report a bug");
+#endif
+
+ if(openedfiles[fd]->delete)
+    unlink(openedfiles[fd]->filename);
+
+ free(openedfiles[fd]);
+ openedfiles[fd]=NULL;
+
+#endif
 }
 
 
@@ -739,6 +981,19 @@ void CloseFile(int fd)
 
 int DeleteFile(const char *filename)
 {
+#if defined(_MSC_VER) || defined(__MINGW32__)
+
+ int fd;
+
+ for(fd=0;fd<nopenedfiles;fd++)
+    if(openedfiles[fd] && !strcmp(openedfiles[fd]->filename,filename))
+      {
+       openedfiles[fd]->delete=1;
+       return(0);
+      }
+
+#endif
+
  unlink(filename);
 
  return(0);
@@ -792,3 +1047,36 @@ static void CreateFileBuffer(int fd,int read_write)
     filebuffers[fd]->reading=(read_write==1);
    }
 }
+
+
+#if defined(_MSC_VER) || defined(__MINGW32__)
+
+/*++++++++++++++++++++++++++++++++++++++
+  Create an opened file record.
+
+  int fd The file descriptor.
+
+  const char *filename The name of the file.
+  ++++++++++++++++++++++++++++++++++++++*/
+
+static void CreateOpenedFile(int fd,const char *filename)
+{
+ if(nopenedfiles<=fd)
+   {
+    int i;
+
+    openedfiles=(struct openedfile**)realloc((void*)openedfiles,(fd+1)*sizeof(struct openedfile*));
+
+    for(i=nopenedfiles;i<=fd;i++)
+       openedfiles[i]=NULL;
+
+    nopenedfiles=fd+1;
+   }
+
+ openedfiles[fd]=(struct openedfile*)calloc(sizeof(struct openedfile),1);
+
+ openedfiles[fd]->filename=strcpy(malloc(strlen(filename)+1),filename);
+ openedfiles[fd]->delete=0;
+}
+
+#endif
diff --git a/src/files.h b/src/files.h
index 726457f..5a58fe1 100644
--- a/src/files.h
+++ b/src/files.h
@@ -3,7 +3,7 @@
 
  Part of the Routino routing software.
  ******************/ /******************
- This file Copyright 2008-2014 Andrew M. Bishop
+ This file Copyright 2008-2015 Andrew M. Bishop
 
  This program is free software: you can redistribute it and/or modify
  it under the terms of the GNU Affero General Public License as published by
@@ -26,15 +26,41 @@
 /* If your system does not have the pread() and pwrite() system calls then you
  * will need to change this line to the value 0 so that seek() and
  * read()/write() are used instead of pread()/pwrite(). */
-#define HAVE_PREAD_PWRITE 1
 
+#if defined(_MSC_VER) || defined(__MINGW32__)
+#define HAVE_PREAD_PWRITE 0
+#else
+#define HAVE_PREAD_PWRITE 1
+#endif
 
+#if defined(_MSC_VER)
+#include <io.h>
+#include <basetsd.h>
+#define read(fd,address,length)  _read(fd,address,(unsigned int)(length))
+#define write(fd,address,length) _write(fd,address,(unsigned int)(length))
+#define ssize_t SSIZE_T
+#else
 #include <unistd.h>
+#endif
+
+#if defined(_MSC_VER) || defined(__MINGW32__)
+#undef lseek
+#define lseek _lseeki64
+#endif
+
 #include <sys/types.h>
+#include <inttypes.h>
 
 #include "logging.h"
 
 
+/* Types */
+
+/*+ A 64-bit file offset since a 32-bit off_t (which is signed) is smaller than a
+    32-bit size_t (which is unsigned) that can be writtento or read from a file. +*/
+typedef int64_t offset_t;
+
+
 /* Functions in files.c */
 
 char *FileName(const char *dirname,const char *prefix, const char *name);
@@ -54,11 +80,13 @@ int OpenFileBufferedAppend(const char *filename);
 
 int ReOpenFileBuffered(const char *filename);
 
+int ReplaceFileBuffered(const char *filename,int *oldfd);
+
 int WriteFileBuffered(int fd,const void *address,size_t length);
 int ReadFileBuffered(int fd,void *address,size_t length);
 
-int SeekFileBuffered(int fd,off_t position);
-int SkipFileBuffered(int fd,off_t skip);
+int SeekFileBuffered(int fd,offset_t position);
+int SkipFileBuffered(int fd,offset_t skip);
 
 int CloseFileBuffered(int fd);
 
@@ -66,8 +94,8 @@ int OpenFile(const char *filename);
 
 void CloseFile(int fd);
 
-off_t SizeFile(const char *filename);
-off_t SizeFileFD(int fd);
+offset_t SizeFile(const char *filename);
+offset_t SizeFileFD(int fd);
 int ExistsFile(const char *filename);
 
 int DeleteFile(const char *filename);
@@ -76,8 +104,8 @@ int RenameFile(const char *oldfilename,const char *newfilename);
 
 /* Functions in files.h */
 
-static inline int SlimReplace(int fd,const void *address,size_t length,off_t position);
-static inline int SlimFetch(int fd,void *address,size_t length,off_t position);
+static inline int SlimReplace(int fd,const void *address,size_t length,offset_t position);
+static inline int SlimFetch(int fd,void *address,size_t length,offset_t position);
 
 
 /* Inline the frequently called functions */
@@ -93,10 +121,10 @@ static inline int SlimFetch(int fd,void *address,size_t length,off_t position);
 
   size_t length The length of data to write.
 
-  off_t position The position in the file to seek to.
+  offset_t position The position in the file to seek to.
   ++++++++++++++++++++++++++++++++++++++*/
 
-static inline int SlimReplace(int fd,const void *address,size_t length,off_t position)
+static inline int SlimReplace(int fd,const void *address,size_t length,offset_t position)
 {
  /* Seek and write the data */
 
@@ -110,7 +138,7 @@ static inline int SlimReplace(int fd,const void *address,size_t length,off_t pos
  if(lseek(fd,position,SEEK_SET)!=position)
     return(-1);
 
- if(write(fd,address,length)!=length)
+ if(write(fd,address,length)!=(ssize_t)length)
     return(-1);
 
 #endif
@@ -130,10 +158,10 @@ static inline int SlimReplace(int fd,const void *address,size_t length,off_t pos
 
   size_t length The length of data to read.
 
-  off_t position The position in the file to seek to.
+  offset_t position The position in the file to seek to.
   ++++++++++++++++++++++++++++++++++++++*/
 
-static inline int SlimFetch(int fd,void *address,size_t length,off_t position)
+static inline int SlimFetch(int fd,void *address,size_t length,offset_t position)
 {
  /* Seek and read the data */
 
@@ -147,7 +175,7 @@ static inline int SlimFetch(int fd,void *address,size_t length,off_t position)
  if(lseek(fd,position,SEEK_SET)!=position)
     return(-1);
 
- if(read(fd,address,length)!=length)
+ if(read(fd,address,length)!=(ssize_t)length)
     return(-1);
 
 #endif
diff --git a/src/functions.h b/src/functions.h
index 8aa7c27..85e921e 100644
--- a/src/functions.h
+++ b/src/functions.h
@@ -3,7 +3,7 @@
 
  Part of the Routino routing software.
  ******************/ /******************
- This file Copyright 2008-2013 Andrew M. Bishop
+ This file Copyright 2008-2015 Andrew M. Bishop
 
  This program is free software: you can redistribute it and/or modify
  it under the terms of the GNU Affero General Public License as published by
@@ -26,29 +26,22 @@
 #include "types.h"
 
 #include "profiles.h"
+#include "translations.h"
 #include "results.h"
 
+#include "routino.h"
 
-/* Functions in optimiser.c */
-
-Results *FindNormalRoute(Nodes *nodes,Segments *segments,Ways *ways,Relations *relations,Profile *profile,index_t start_node,index_t prev_segment,index_t finish_node);
-
-Results *FindMiddleRoute(Nodes *supernodes,Segments *supersegments,Ways *superways,Relations *relations,Profile *profile,Results *begin,Results *end);
-
-Results *FindStartRoutes(Nodes *nodes,Segments *segments,Ways *ways,Relations *relations,Profile *profile,index_t start_node,index_t prev_segment,index_t finish_node);
 
-Results *ExtendStartRoutes(Nodes *nodes,Segments *segments,Ways *ways,Relations *relations,Profile *profile,Results *begin,index_t finish_node);
-
-Results *FindFinishRoutes(Nodes *nodes,Segments *segments,Ways *ways,Relations *relations,Profile *profile,index_t finish_node);
-
-Results *CombineRoutes(Nodes *nodes,Segments *segments,Ways *ways,Relations *relations,Profile *profile,Results *begin,Results *middle);
+/* Functions in optimiser.c */
 
-void FixForwardRoute(Results *results,Result *finish_result);
+Results *CalculateRoute(Nodes *nodes,Segments *segments,Ways *ways,Relations *relations,Profile *profile,
+                        index_t start_node,index_t prev_segment,index_t finish_node,
+                        int start_waypoint,int finish_waypoint);
 
 
 /* Functions in output.c */
 
-void PrintRoute(Results **results,int nresults,Nodes *nodes,Segments *segments,Ways *ways,Profile *profile);
+Routino_Output *PrintRoute(Results **results,int nresults,Nodes *nodes,Segments *segments,Ways *ways,Profile *profile,Translation *translation);
 
 
 #endif /* FUNCTIONS_H */
diff --git a/src/logerror.c b/src/logerror.c
index d9d18a8..a8a4cce 100644
--- a/src/logerror.c
+++ b/src/logerror.c
@@ -3,7 +3,7 @@
 
  Part of the Routino routing software.
  ******************/ /******************
- This file Copyright 2013 Andrew M. Bishop
+ This file Copyright 2013, 2015 Andrew M. Bishop
 
  This program is free software: you can redistribute it and/or modify
  it under the terms of the GNU Affero General Public License as published by
@@ -39,7 +39,7 @@ char *errorlogfilename=NULL;
 char *errorbinfilename=NULL;
 
 
-/* Local variables */
+/* Local variables (re-initialised by open_errorlog() function) */
 
 /*+ The file handle for the error log file. +*/
 static FILE *errorlogfile=NULL;
@@ -48,7 +48,7 @@ static FILE *errorlogfile=NULL;
 static int errorbinfile=-1;
 
 /*+ The offset of the error message in the error log file. +*/
-static off_t errorfileoffset=0;
+static offset_t errorfileoffset=0;
 
 
 /*++++++++++++++++++++++++++++++++++++++
@@ -69,7 +69,11 @@ void open_errorlog(const char *filename,int append,int bin)
 
  strcpy(errorlogfilename,filename);
 
- errorlogfile=fopen(errorlogfilename,append?"a":"w");
+#if defined(_MSC_VER) || defined(__MINGW32__)
+ errorlogfile=fopen(errorlogfilename,append?"ab":"wb");
+#else
+ errorlogfile=fopen(errorlogfilename,append?"a" :"w" );
+#endif
 
  if(!errorlogfile)
    {
diff --git a/src/logging.c b/src/logging.c
index 2f3c560..11cd399 100644
--- a/src/logging.c
+++ b/src/logging.c
@@ -3,7 +3,7 @@
 
  Part of the Routino routing software.
  ******************/ /******************
- This file Copyright 2008-2014 Andrew M. Bishop
+ This file Copyright 2008-2015 Andrew M. Bishop
 
  This program is free software: you can redistribute it and/or modify
  it under the terms of the GNU Affero General Public License as published by
@@ -25,8 +25,36 @@
 #include <stdlib.h>
 #include <string.h>
 #include <errno.h>
+
+#if defined(_MSC_VER)
+
+#include <WinSock2.h>
+#include <stdint.h>
+
+static const uint64_t EPOCH = ((uint64_t) 116444736000000000ULL);
+
+int gettimeofday(struct timeval * tp, struct timezone * tzp)
+{
+ FILETIME    file_time;
+ SYSTEMTIME  system_time;
+ ULARGE_INTEGER ularge;
+
+ GetSystemTime(&system_time);
+ SystemTimeToFileTime(&system_time, &file_time);
+ ularge.LowPart = file_time.dwLowDateTime;
+ ularge.HighPart = file_time.dwHighDateTime;
+
+ tp->tv_sec = (long) ((ularge.QuadPart - EPOCH) / 10000000L);
+ tp->tv_usec = (long) (system_time.wMilliseconds * 1000);
+ return 0;
+}
+
+#else
+
 #include <sys/time.h>
 
+#endif
+
 #include "logging.h"
 
 
@@ -557,7 +585,7 @@ static void fprintf_elapsed_time(FILE *file,struct timeval *start)
 
 static void fprintf_max_memory(FILE *file,size_t max_alloc,size_t max_mmap)
 {
- fprintf(file,"[%3d, %3d MB] ",max_alloc/(1024*1024),max_mmap/(1024*1024));
+ fprintf(file,"[%3zu, %3zu MB] ",max_alloc/(1024*1024),max_mmap/(1024*1024));
 }
 
 
diff --git a/src/logging.h b/src/logging.h
index dbe83f0..3d5ca9a 100644
--- a/src/logging.h
+++ b/src/logging.h
@@ -3,7 +3,7 @@
 
  Part of the Routino routing software.
  ******************/ /******************
- This file Copyright 2008-2014 Andrew M. Bishop
+ This file Copyright 2008-2015 Andrew M. Bishop
 
  This program is free software: you can redistribute it and/or modify
  it under the terms of the GNU Affero General Public License as published by
@@ -24,7 +24,6 @@
 #define LOGGING_H    /*+ To stop multiple inclusions. +*/
 
 #include <stdio.h>
-#include <sys/time.h>
 
 #include "typesx.h"
 
diff --git a/src/mman-win32.c b/src/mman-win32.c
new file mode 100644
index 0000000..2fd5f63
--- /dev/null
+++ b/src/mman-win32.c
@@ -0,0 +1,206 @@
+/***************************************
+ Windows 32 memory management functions from https://code.google.com/p/mman-win32
+
+ File header comment created by Andrew M. Bishop, all source code unchanged from original.
+ ******************/ /******************
+ Copyright (c) 2010,2012 Viktor Kutuzov
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ***************************************/
+
+
+#include <windows.h>
+#include <errno.h>
+#include <io.h>
+
+#include "mman-win32.h"
+
+#ifndef FILE_MAP_EXECUTE
+#define FILE_MAP_EXECUTE    0x0020
+#endif /* FILE_MAP_EXECUTE */
+
+static int __map_mman_error(const DWORD err, const int deferr)
+{
+    if (err == 0)
+        return 0;
+    //TODO: implement
+    return err;
+}
+
+static DWORD __map_mmap_prot_page(const int prot)
+{
+    DWORD protect = 0;
+    
+    if (prot == PROT_NONE)
+        return protect;
+        
+    if ((prot & PROT_EXEC) != 0)
+    {
+        protect = ((prot & PROT_WRITE) != 0) ? 
+                    PAGE_EXECUTE_READWRITE : PAGE_EXECUTE_READ;
+    }
+    else
+    {
+        protect = ((prot & PROT_WRITE) != 0) ?
+                    PAGE_READWRITE : PAGE_READONLY;
+    }
+    
+    return protect;
+}
+
+static DWORD __map_mmap_prot_file(const int prot)
+{
+    DWORD desiredAccess = 0;
+    
+    if (prot == PROT_NONE)
+        return desiredAccess;
+        
+    if ((prot & PROT_READ) != 0)
+        desiredAccess |= FILE_MAP_READ;
+    if ((prot & PROT_WRITE) != 0)
+        desiredAccess |= FILE_MAP_WRITE;
+    if ((prot & PROT_EXEC) != 0)
+        desiredAccess |= FILE_MAP_EXECUTE;
+    
+    return desiredAccess;
+}
+
+void* mmap(void *addr, size_t len, int prot, int flags, int fildes, off_t off)
+{
+    HANDLE fm, h;
+    
+    void * map = MAP_FAILED;
+    
+#ifdef _MSC_VER
+#pragma warning(push)
+#pragma warning(disable: 4293)
+#endif
+
+    const DWORD dwFileOffsetLow = (sizeof(off_t) <= sizeof(DWORD)) ? 
+                    (DWORD)off : (DWORD)(off & 0xFFFFFFFFL);
+    const DWORD dwFileOffsetHigh = (sizeof(off_t) <= sizeof(DWORD)) ?
+                    (DWORD)0 : (DWORD)((off >> 32) & 0xFFFFFFFFL);
+    const DWORD protect = __map_mmap_prot_page(prot);
+    const DWORD desiredAccess = __map_mmap_prot_file(prot);
+
+    const off_t maxSize = off + (off_t)len;
+
+    const DWORD dwMaxSizeLow = (sizeof(off_t) <= sizeof(DWORD)) ? 
+                    (DWORD)maxSize : (DWORD)(maxSize & 0xFFFFFFFFL);
+    const DWORD dwMaxSizeHigh = (sizeof(off_t) <= sizeof(DWORD)) ?
+                    (DWORD)0 : (DWORD)((maxSize >> 32) & 0xFFFFFFFFL);
+
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
+
+    errno = 0;
+    
+    if (len == 0 
+        /* Unsupported flag combinations */
+        || (flags & MAP_FIXED) != 0
+        /* Usupported protection combinations */
+        || prot == PROT_EXEC)
+    {
+        errno = EINVAL;
+        return MAP_FAILED;
+    }
+    
+    h = ((flags & MAP_ANONYMOUS) == 0) ? 
+                    (HANDLE)_get_osfhandle(fildes) : INVALID_HANDLE_VALUE;
+
+    if ((flags & MAP_ANONYMOUS) == 0 && h == INVALID_HANDLE_VALUE)
+    {
+        errno = EBADF;
+        return MAP_FAILED;
+    }
+
+    fm = CreateFileMapping(h, NULL, protect, dwMaxSizeHigh, dwMaxSizeLow, NULL);
+
+    if (fm == NULL)
+    {
+        errno = __map_mman_error(GetLastError(), EPERM);
+        return MAP_FAILED;
+    }
+  
+    map = MapViewOfFile(fm, desiredAccess, dwFileOffsetHigh, dwFileOffsetLow, len);
+
+    CloseHandle(fm);
+  
+    if (map == NULL)
+    {
+        errno = __map_mman_error(GetLastError(), EPERM);
+        return MAP_FAILED;
+    }
+
+    return map;
+}
+
+int munmap(void *addr, size_t len)
+{
+    if (UnmapViewOfFile(addr))
+        return 0;
+        
+    errno =  __map_mman_error(GetLastError(), EPERM);
+    
+    return -1;
+}
+
+int mprotect(void *addr, size_t len, int prot)
+{
+    DWORD newProtect = __map_mmap_prot_page(prot);
+    DWORD oldProtect = 0;
+    
+    if (VirtualProtect(addr, len, newProtect, &oldProtect))
+        return 0;
+    
+    errno =  __map_mman_error(GetLastError(), EPERM);
+    
+    return -1;
+}
+
+int msync(void *addr, size_t len, int flags)
+{
+    if (FlushViewOfFile(addr, len))
+        return 0;
+    
+    errno =  __map_mman_error(GetLastError(), EPERM);
+    
+    return -1;
+}
+
+int mlock(const void *addr, size_t len)
+{
+    if (VirtualLock((LPVOID)addr, len))
+        return 0;
+        
+    errno =  __map_mman_error(GetLastError(), EPERM);
+    
+    return -1;
+}
+
+int munlock(const void *addr, size_t len)
+{
+    if (VirtualUnlock((LPVOID)addr, len))
+        return 0;
+        
+    errno =  __map_mman_error(GetLastError(), EPERM);
+    
+    return -1;
+}
diff --git a/src/mman-win32.h b/src/mman-win32.h
new file mode 100644
index 0000000..3dca196
--- /dev/null
+++ b/src/mman-win32.h
@@ -0,0 +1,77 @@
+/***************************************
+ Windows 32 memory management functions from https://code.google.com/p/mman-win32
+
+ File header comment created by Andrew M. Bishop, all source code unchanged from original.
+ ******************/ /******************
+ Copyright (c) 2010,2012 Viktor Kutuzov
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ***************************************/
+
+
+#ifndef _SYS_MMAN_H_
+#define _SYS_MMAN_H_
+
+#ifndef _WIN32_WINNT		// Allow use of features specific to Windows XP or later.                   
+#define _WIN32_WINNT 0x0501	// Change this to the appropriate value to target other versions of Windows.
+#endif						
+
+/* All the headers include this file. */
+#ifndef _MSC_VER
+#include <_mingw.h>
+#endif
+
+#include <sys/types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define PROT_NONE       0
+#define PROT_READ       1
+#define PROT_WRITE      2
+#define PROT_EXEC       4
+
+#define MAP_FILE        0
+#define MAP_SHARED      1
+#define MAP_PRIVATE     2
+#define MAP_TYPE        0xf
+#define MAP_FIXED       0x10
+#define MAP_ANONYMOUS   0x20
+#define MAP_ANON        MAP_ANONYMOUS
+
+#define MAP_FAILED      ((void *)-1)
+
+/* Flags for msync. */
+#define MS_ASYNC        1
+#define MS_SYNC         2
+#define MS_INVALIDATE   4
+
+void*   mmap(void *addr, size_t len, int prot, int flags, int fildes, off_t off);
+int     munmap(void *addr, size_t len);
+int     mprotect(void *addr, size_t len, int prot);
+int     msync(void *addr, size_t len, int flags);
+int     mlock(const void *addr, size_t len);
+int     munlock(const void *addr, size_t len);
+
+#ifdef __cplusplus
+};
+#endif
+
+#endif /*  _SYS_MMAN_H_ */
diff --git a/src/nodes.c b/src/nodes.c
index a3b7f26..31c890c 100644
--- a/src/nodes.c
+++ b/src/nodes.c
@@ -3,7 +3,7 @@
 
  Part of the Routino routing software.
  ******************/ /******************
- This file Copyright 2008-2014 Andrew M. Bishop
+ This file Copyright 2008-2015 Andrew M. Bishop
 
  This program is free software: you can redistribute it and/or modify
  it under the terms of the GNU Affero General Public License as published by
@@ -78,14 +78,18 @@ Nodes *LoadNodeList(const char *filename)
  sizeoffsets=(nodes->file.latbins*nodes->file.lonbins+1)*sizeof(index_t);
 
  nodes->offsets=(index_t*)malloc(sizeoffsets);
+#ifndef LIBROUTINO
  log_malloc(nodes->offsets,sizeoffsets);
+#endif
 
  SlimFetch(nodes->fd,nodes->offsets,sizeoffsets,sizeof(NodesFile));
 
- nodes->nodesoffset=sizeof(NodesFile)+sizeoffsets;
+ nodes->nodesoffset=(offset_t)(sizeof(NodesFile)+sizeoffsets);
 
  nodes->cache=NewNodeCache();
+#ifndef LIBROUTINO
  log_malloc(nodes->cache,sizeof(*nodes->cache));
+#endif
 
 #endif
 
@@ -109,10 +113,14 @@ void DestroyNodeList(Nodes *nodes)
 
  nodes->fd=SlimUnmapFile(nodes->fd);
 
+#ifndef LIBROUTINO
  log_free(nodes->offsets);
+#endif
  free(nodes->offsets);
 
+#ifndef LIBROUTINO
  log_free(nodes->cache);
+#endif
  DeleteNodeCache(nodes->cache);
 
 #endif
diff --git a/src/nodes.h b/src/nodes.h
index 6dc7064..c50c664 100644
--- a/src/nodes.h
+++ b/src/nodes.h
@@ -3,7 +3,7 @@
 
  Part of the Routino routing software.
  ******************/ /******************
- This file Copyright 2008-2014 Andrew M. Bishop
+ This file Copyright 2008-2015 Andrew M. Bishop
 
  This program is free software: you can redistribute it and/or modify
  it under the terms of the GNU Affero General Public License as published by
@@ -71,7 +71,7 @@ struct _Nodes
 
 #if !SLIM
 
- void     *data;                /*+ The memory mapped data in the file. +*/
+ char     *data;                /*+ The memory mapped data in the file. +*/
 
  index_t  *offsets;             /*+ A pointer to the array of offsets in the file. +*/
 
@@ -83,7 +83,7 @@ struct _Nodes
 
  index_t  *offsets;             /*+ An allocated array with a copy of the file offsets. +*/
 
- off_t     nodesoffset;         /*+ The offset of the nodes within the file. +*/
+ offset_t  nodesoffset;         /*+ The offset of the nodes within the file. +*/
 
  Node      cached[6];           /*+ Some cached nodes read from the file in slim mode. +*/
 
@@ -140,10 +140,12 @@ CACHE_DELETECACHE_PROTO(Node)
 CACHE_FETCHCACHE_PROTO(Node)
 CACHE_INVALIDATECACHE_PROTO(Node)
 
+/* Data type */
+
+CACHE_STRUCTURE(Node)
 
 /* Inline functions */
 
-CACHE_STRUCTURE(Node)
 CACHE_NEWCACHE(Node)
 CACHE_DELETECACHE(Node)
 CACHE_FETCHCACHE(Node)
diff --git a/src/nodesx.c b/src/nodesx.c
index 186fcb4..b2b0421 100644
--- a/src/nodesx.c
+++ b/src/nodesx.c
@@ -3,7 +3,7 @@
 
  Part of the Routino routing software.
  ******************/ /******************
- This file Copyright 2008-2014 Andrew M. Bishop
+ This file Copyright 2008-2015 Andrew M. Bishop
 
  This program is free software: you can redistribute it and/or modify
  it under the terms of the GNU Affero General Public License as published by
@@ -43,7 +43,7 @@ extern char *option_tmpdirname;
 
 /* Local variables */
 
-/*+ Temporary file-local variables for use by the sort functions. +*/
+/*+ Temporary file-local variables for use by the sort functions (re-initialised for each sort). +*/
 static NodesX *sortnodesx;
 static latlong_t lat_min,lat_max,lon_min,lon_max;
 
@@ -76,7 +76,7 @@ NodesX *NewNodeList(int append,int readonly)
  logassert(nodesx,"Failed to allocate memory (try using slim mode?)"); /* Check calloc() worked */
 
  nodesx->filename    =(char*)malloc(strlen(option_tmpdirname)+32);
- nodesx->filename_tmp=(char*)malloc(strlen(option_tmpdirname)+32);
+ nodesx->filename_tmp=(char*)malloc(strlen(option_tmpdirname)+40); /* allow %p to be up to 20 bytes */
 
  sprintf(nodesx->filename    ,"%s/nodesx.parsed.mem",option_tmpdirname);
  sprintf(nodesx->filename_tmp,"%s/nodesx.%p.tmp"    ,option_tmpdirname,(void*)nodesx);
@@ -84,7 +84,7 @@ NodesX *NewNodeList(int append,int readonly)
  if(append || readonly)
     if(ExistsFile(nodesx->filename))
       {
-       off_t size;
+       offset_t size;
 
        size=SizeFile(nodesx->filename);
 
@@ -283,11 +283,7 @@ void SortNodeList(NodesX *nodesx)
 
  /* Re-open the file read-only and a new file writeable */
 
- nodesx->fd=ReOpenFileBuffered(nodesx->filename_tmp);
-
- DeleteFile(nodesx->filename_tmp);
-
- fd=OpenFileBufferedNew(nodesx->filename_tmp);
+ fd=ReplaceFileBuffered(nodesx->filename_tmp,&nodesx->fd);
 
  /* Allocate the array of indexes */
 
@@ -355,9 +351,9 @@ static int sort_by_id(NodeX *a,NodeX *b)
 
 static int deduplicate_and_index_by_id(NodeX *nodex,index_t index)
 {
- static node_t previd=NO_NODE_ID;
+ static node_t previd; /* internal variable (reset by first call in each sort; index==0) */
 
- if(nodex->id!=previd)
+ if(index==0 || nodex->id!=previd)
    {
     previd=nodex->id;
 
@@ -472,14 +468,16 @@ void RemoveNonHighwayNodes(NodesX *nodesx,WaysX *waysx,int keep)
 
  /* Re-open the file read-only and a new file writeable */
 
- nodesx->fd=ReOpenFileBuffered(nodesx->filename_tmp);
-
  if(keep)
+   {
     RenameFile(nodesx->filename_tmp,nodesx->filename);
- else
-    DeleteFile(nodesx->filename_tmp);
 
- fd=OpenFileBufferedNew(nodesx->filename_tmp);
+    nodesx->fd=ReOpenFileBuffered(nodesx->filename);
+
+    fd=OpenFileBufferedNew(nodesx->filename_tmp);
+   }
+ else
+    fd=ReplaceFileBuffered(nodesx->filename_tmp,&nodesx->fd);
 
  /* Modify the on-disk image */
 
@@ -550,11 +548,7 @@ void RemovePrunedNodes(NodesX *nodesx,SegmentsX *segmentsx)
 
  /* Re-open the file read-only and a new file writeable */
 
- nodesx->fd=ReOpenFileBuffered(nodesx->filename_tmp);
-
- DeleteFile(nodesx->filename_tmp);
-
- fd=OpenFileBufferedNew(nodesx->filename_tmp);
+ fd=ReplaceFileBuffered(nodesx->filename_tmp,&nodesx->fd);
 
  /* Modify the on-disk image */
 
@@ -637,11 +631,7 @@ void SortNodeListGeographically(NodesX *nodesx)
 
  /* Re-open the file read-only and a new file writeable */
 
- nodesx->fd=ReOpenFileBuffered(nodesx->filename_tmp);
-
- DeleteFile(nodesx->filename_tmp);
-
- fd=OpenFileBufferedNew(nodesx->filename_tmp);
+ fd=ReplaceFileBuffered(nodesx->filename_tmp,&nodesx->fd);
 
  /* Sort nodes geographically and index them */
 
diff --git a/src/nodesx.h b/src/nodesx.h
index 84bd380..04946f9 100644
--- a/src/nodesx.h
+++ b/src/nodesx.h
@@ -3,7 +3,7 @@
 
  Part of the Routino routing software.
  ******************/ /******************
- This file Copyright 2008-2013 Andrew M. Bishop
+ This file Copyright 2008-2015 Andrew M. Bishop
 
  This program is free software: you can redistribute it and/or modify
  it under the terms of the GNU Affero General Public License as published by
@@ -132,10 +132,12 @@ CACHE_FETCHCACHE_PROTO(NodeX)
 CACHE_REPLACECACHE_PROTO(NodeX)
 CACHE_INVALIDATECACHE_PROTO(NodeX)
 
+/* Data type */
+
+CACHE_STRUCTURE(NodeX)
 
 /* Inline functions */
 
-CACHE_STRUCTURE(NodeX)
 CACHE_NEWCACHE(NodeX)
 CACHE_DELETECACHE(NodeX)
 CACHE_FETCHCACHE(NodeX)
diff --git a/src/optimiser.c b/src/optimiser.c
index e61571e..b64702e 100644
--- a/src/optimiser.c
+++ b/src/optimiser.c
@@ -3,7 +3,7 @@
 
  Part of the Routino routing software.
  ******************/ /******************
- This file Copyright 2008-2014 Andrew M. Bishop
+ This file Copyright 2008-2015 Andrew M. Bishop
 
  This program is free software: you can redistribute it and/or modify
  it under the terms of the GNU Affero General Public License as published by
@@ -31,6 +31,21 @@
 #include "fakes.h"
 #include "results.h"
 
+#ifdef LIBROUTINO
+
+#include "routino.h"
+
+/*+ The function to be called to report on the routing progress. +*/
+extern Routino_ProgressFunc progress_func;
+
+/*+ The current state of the routing progress. +*/
+extern double progress_value;
+
+/*+ Set when the progress callback returns false in the routing function. +*/
+extern int progress_abort;
+
+#endif
+
 
 /*+ To help when debugging +*/
 #define DEBUG 0
@@ -47,8 +62,201 @@ extern int option_quickest;
 
 /* Local functions */
 
+static Results *FindNormalRoute(Nodes *nodes,Segments *segments,Ways *ways,Relations *relations,Profile *profile,index_t start_node,index_t prev_segment,index_t finish_node);
+static Results *FindMiddleRoute(Nodes *supernodes,Segments *supersegments,Ways *superways,Relations *relations,Profile *profile,Results *begin,Results *end);
 static index_t FindSuperSegment(Nodes *nodes,Segments *segments,Ways *ways,Relations *relations,Profile *profile,index_t finish_node,index_t finish_segment);
 static Results *FindSuperRoute(Nodes *nodes,Segments *segments,Ways *ways,Relations *relations,Profile *profile,index_t start_node,index_t finish_node);
+static Results *FindStartRoutes(Nodes *nodes,Segments *segments,Ways *ways,Relations *relations,Profile *profile,index_t start_node,index_t prev_segment,index_t finish_node);
+static Results *FindFinishRoutes(Nodes *nodes,Segments *segments,Ways *ways,Relations *relations,Profile *profile,index_t finish_node);
+static Results *CombineRoutes(Nodes *nodes,Segments *segments,Ways *ways,Relations *relations,Profile *profile,Results *begin,Results *middle,Results *end);
+static void FixForwardRoute(Results *results,Result *finish_result);
+
+
+/*++++++++++++++++++++++++++++++++++++++
+  Find a complete route from a specified node to another node.
+
+  Results *CalculateRoute Returns a set of results.
+
+  Nodes *nodes The set of nodes to use.
+
+  Segments *segments The set of segments to use.
+
+  Ways *ways The set of ways to use.
+
+  Relations *relations The set of relations to use.
+
+  Profile *profile The profile containing the transport type, speeds and allowed highways.
+
+  index_t start_node The start node.
+
+  index_t prev_segment The previous segment before the start node.
+
+  index_t finish_node The finish node.
+
+  int start_waypoint The starting waypoint.
+
+  int finish_waypoint The finish waypoint.
+  ++++++++++++++++++++++++++++++++++++++*/
+
+Results *CalculateRoute(Nodes *nodes,Segments *segments,Ways *ways,Relations *relations,Profile *profile,
+                        index_t start_node,index_t prev_segment,index_t finish_node,
+                        int start_waypoint,int finish_waypoint)
+{
+ Results *complete=NULL;
+
+ /* A special case if the first and last nodes are the same */
+
+ if(start_node==finish_node)
+   {
+    index_t fake_segment;
+    Result *result1,*result2;
+
+    complete=NewResultsList(8);
+
+    if(prev_segment==NO_SEGMENT)
+      {
+       double lat,lon;
+       distance_t distmin,dist1,dist2;
+       index_t node1,node2;
+
+       GetLatLong(nodes,start_node,NULL,&lat,&lon);
+
+       prev_segment=FindClosestSegment(nodes,segments,ways,lat,lon,1,profile,&distmin,&node1,&node2,&dist1,&dist2);
+      }
+
+    fake_segment=CreateFakeNullSegment(segments,start_node,prev_segment,finish_waypoint);
+
+    result1=InsertResult(complete,start_node,prev_segment);
+    result2=InsertResult(complete,finish_node,fake_segment);
+
+    result1->next=result2;
+
+    complete->start_node=start_node;
+    complete->prev_segment=prev_segment;
+
+    complete->finish_node=finish_node;
+    complete->last_segment=fake_segment;
+   }
+ else
+   {
+    Results *begin;
+
+    /* Calculate the beginning of the route */
+
+    begin=FindStartRoutes(nodes,segments,ways,relations,profile,start_node,prev_segment,finish_node);
+
+    if(begin)
+      {
+       /* Check if the end of the route was reached */
+
+       if(begin->finish_node!=NO_NODE)
+          complete=begin;
+      }
+    else
+      {
+       if(prev_segment!=NO_SEGMENT)
+         {
+          /* Try again but allow a U-turn at the start waypoint -
+             this solves the problem of facing a dead-end that contains no super-nodes. */
+
+          prev_segment=NO_SEGMENT;
+
+          begin=FindStartRoutes(nodes,segments,ways,relations,profile,start_node,prev_segment,finish_node);
+         }
+
+       if(begin)
+         {
+          /* Check if the end of the route was reached */
+
+          if(begin->finish_node!=NO_NODE)
+             complete=begin;
+         }
+       else
+         {
+#ifndef LIBROUTINO
+          fprintf(stderr,"Error: Cannot find initial section of route compatible with profile.\n");
+#endif
+          return(NULL);
+         }
+      }
+
+    /* Calculate the rest of the route */
+
+    if(!complete)
+      {
+       Results *middle,*end;
+
+       /* Calculate the end of the route */
+
+       end=FindFinishRoutes(nodes,segments,ways,relations,profile,finish_node);
+
+       if(!end)
+         {
+#ifndef LIBROUTINO
+          fprintf(stderr,"Error: Cannot find final section of route compatible with profile.\n");
+#endif
+          return(NULL);
+         }
+
+       /* Calculate the middle of the route */
+
+       middle=FindMiddleRoute(nodes,segments,ways,relations,profile,begin,end);
+
+       if(!middle && prev_segment!=NO_SEGMENT)
+         {
+          /* Try again but allow a U-turn at the start waypoint -
+             this solves the problem of facing a dead-end that contains some super-nodes. */
+
+          FreeResultsList(begin);
+
+          begin=FindStartRoutes(nodes,segments,ways,relations,profile,start_node,NO_SEGMENT,finish_node);
+
+          if(begin)
+             middle=FindMiddleRoute(nodes,segments,ways,relations,profile,begin,end);
+         }
+
+       if(!middle)
+         {
+#ifndef LIBROUTINO
+          fprintf(stderr,"Error: Cannot find super-route compatible with profile.\n");
+#endif
+          return(NULL);
+         }
+
+       complete=CombineRoutes(nodes,segments,ways,relations,profile,begin,middle,end);
+
+       if(!complete)
+         {
+#ifndef LIBROUTINO
+          fprintf(stderr,"Error: Cannot create combined route following super-route.\n");
+#endif
+          return(NULL);
+         }
+
+       FreeResultsList(begin);
+       FreeResultsList(middle);
+       FreeResultsList(end);
+      }
+   }
+
+ complete->start_waypoint=start_waypoint;
+ complete->finish_waypoint=finish_waypoint;
+
+#if DEBUG
+ Result *r=FindResult(complete,complete->start_node,complete->prev_segment);
+
+ printf("The final route is:\n");
+
+ while(r)
+   {
+    printf("  node=%"Pindex_t" segment=%"Pindex_t" score=%f\n",r->node,r->segment,r->score);
+
+    r=r->next;
+   }
+#endif
+
+ return(complete);
+}
 
 
 /*++++++++++++++++++++++++++++++++++++++
@@ -73,7 +281,7 @@ static Results *FindSuperRoute(Nodes *nodes,Segments *segments,Ways *ways,Relati
   index_t finish_node The finish node.
   ++++++++++++++++++++++++++++++++++++++*/
 
-Results *FindNormalRoute(Nodes *nodes,Segments *segments,Ways *ways,Relations *relations,Profile *profile,index_t start_node,index_t prev_segment,index_t finish_node)
+static Results *FindNormalRoute(Nodes *nodes,Segments *segments,Ways *ways,Relations *relations,Profile *profile,index_t start_node,index_t prev_segment,index_t finish_node)
 {
  Results *results;
  Queue   *queue;
@@ -84,7 +292,7 @@ Results *FindNormalRoute(Nodes *nodes,Segments *segments,Ways *ways,Relations *r
  int     force_uturn=0;
 
 #if DEBUG
- printf("  FindNormalRoute(...,start_node=%"Pindex_t" prev_segment=%"Pindex_t" finish_node=%"Pindex_t")\n",start_node,prev_segment,finish_node);
+ printf("    FindNormalRoute(...,start_node=%"Pindex_t" prev_segment=%"Pindex_t" finish_node=%"Pindex_t")\n",start_node,prev_segment,finish_node);
 #endif
 
  /* Set up the finish conditions */
@@ -252,6 +460,7 @@ Results *FindNormalRoute(Nodes *nodes,Segments *segments,Ways *ways,Relations *r
        if(node2p && node2!=finish_node && !(node2p->allow&profile->allow))
           goto endloop;
 
+       /* calculate the score for the segment and cumulative */
        if(option_quickest==0)
           segment_score=(score_t)DISTANCE(segmentp->distance)/segment_pref;
        else
@@ -263,6 +472,7 @@ Results *FindNormalRoute(Nodes *nodes,Segments *segments,Ways *ways,Relations *r
        if(cumulative_score>=finish_score)
           goto endloop;
 
+       /* find whether the node/segment combination already exists */
        result2=FindResult(results,node2,seg2);
 
        if(!result2) /* New end node/segment combination */
@@ -284,6 +494,9 @@ Results *FindNormalRoute(Nodes *nodes,Segments *segments,Ways *ways,Relations *r
          {
           finish_score=cumulative_score;
           finish_result=result2;
+
+          results->finish_node=node2;
+          results->last_segment=seg2;
          }
        else
           InsertInQueue(queue,result2,result2->score);
@@ -311,7 +524,7 @@ Results *FindNormalRoute(Nodes *nodes,Segments *segments,Ways *ways,Relations *r
  if(!finish_result)
    {
 #if DEBUG
-    printf("    Failed\n");
+    printf("      Failed\n");
 #endif
 
     FreeResultsList(results);
@@ -323,9 +536,14 @@ Results *FindNormalRoute(Nodes *nodes,Segments *segments,Ways *ways,Relations *r
 #if DEBUG
  Result *r=FindResult(results,results->start_node,results->prev_segment);
 
+ printf("      -------- normal route (between super-nodes)\n");
+
  while(r)
    {
-    printf("    node=%"Pindex_t" segment=%"Pindex_t" score=%f\n",r->node,r->segment,r->score);
+    printf("      node=%"Pindex_t" segment=%"Pindex_t" score=%f%s%s%s\n",r->node,r->segment,r->score,
+                                                                         (IsSuperNode(LookupNode(nodes,r->node,1))?" (super)":""),
+                                                                         (r->node==results->start_node&&r->segment==results->prev_segment?" (start)":""),
+                                                                         (r->node==results->finish_node?" (finish)":""));
 
     r=r->next;
    }
@@ -355,7 +573,7 @@ Results *FindNormalRoute(Nodes *nodes,Segments *segments,Ways *ways,Relations *r
   Results *end The final portion of the route.
   ++++++++++++++++++++++++++++++++++++++*/
 
-Results *FindMiddleRoute(Nodes *nodes,Segments *segments,Ways *ways,Relations *relations,Profile *profile,Results *begin,Results *end)
+static Results *FindMiddleRoute(Nodes *nodes,Segments *segments,Ways *ways,Relations *relations,Profile *profile,Results *begin,Results *end)
 {
  Results *results;
  Queue   *queue;
@@ -364,12 +582,15 @@ Results *FindMiddleRoute(Nodes *nodes,Segments *segments,Ways *ways,Relations *r
  double  finish_lat,finish_lon;
  Result  *result1,*result2,*result3,*result4;
  int     force_uturn=0;
+#ifdef LIBROUTINO
+ int     loopcount=0;
+#endif
 
 #if DEBUG
  printf("  FindMiddleRoute(...,[begin has %d nodes],[end has %d nodes])\n",begin->number,end->number);
 #endif
 
-#if !DEBUG
+#if !DEBUG && !defined(LIBROUTINO)
  if(!option_quiet)
     printf_first("Finding Middle Route: Super-Nodes checked = 0");
 #endif
@@ -392,16 +613,11 @@ Results *FindMiddleRoute(Nodes *nodes,Segments *segments,Ways *ways,Relations *r
  results->start_node=begin->start_node;
  results->prev_segment=begin->prev_segment;
 
- if(begin->number==1)
+ if(begin->number==1 && begin->prev_segment!=NO_SEGMENT)
    {
-    if(begin->prev_segment==NO_SEGMENT)
-       results->prev_segment=NO_SEGMENT;
-    else
-      {
-       index_t superseg=FindSuperSegment(nodes,segments,ways,relations,profile,begin->start_node,begin->prev_segment);
+    index_t superseg=FindSuperSegment(nodes,segments,ways,relations,profile,begin->start_node,begin->prev_segment);
 
-       results->prev_segment=superseg;
-      }
+    results->prev_segment=superseg;
    }
 
  result1=InsertResult(results,results->start_node,results->prev_segment);
@@ -574,6 +790,7 @@ Results *FindMiddleRoute(Nodes *nodes,Segments *segments,Ways *ways,Relations *r
        if(node2!=end->finish_node && !(node2p->allow&profile->allow))
           goto endloop;
 
+       /* calculate the score for the segment and cumulative */
        if(option_quickest==0)
           segment_score=(score_t)DISTANCE(segmentp->distance)/segment_pref;
        else
@@ -585,6 +802,7 @@ Results *FindMiddleRoute(Nodes *nodes,Segments *segments,Ways *ways,Relations *r
        if(cumulative_score>=finish_score)
           goto endloop;
 
+       /* find whether the node/segment combination already exists */
        result2=FindResult(results,node2,seg2);
 
        if(!result2) /* New end node/segment pair */
@@ -607,6 +825,9 @@ Results *FindMiddleRoute(Nodes *nodes,Segments *segments,Ways *ways,Relations *r
             {
              finish_score=result2->score+result3->score;
              finish_result=result2;
+
+             results->finish_node=node2;
+             results->last_segment=seg2;
             }
          }
        else
@@ -632,6 +853,15 @@ Results *FindMiddleRoute(Nodes *nodes,Segments *segments,Ways *ways,Relations *r
 
        segmentp=NextSegment(segments,segmentp,node1); /* node1 cannot be a fake node (must be a super-node) */
       }
+
+#ifdef LIBROUTINO
+    if(!(++loopcount%100000))
+       if(progress_func && !progress_func(progress_value))
+         {
+          progress_abort=1;
+          break;
+         }
+#endif
    }
 
  FreeQueueList(queue);
@@ -644,7 +874,7 @@ Results *FindMiddleRoute(Nodes *nodes,Segments *segments,Ways *ways,Relations *r
     printf("    Failed\n");
 #endif
 
-#if !DEBUG
+#if !DEBUG && !defined(LIBROUTINO)
     if(!option_quiet)
        printf_last("Found Middle Route: Super-Nodes checked = %d - Fail",results->number);
 #endif
@@ -653,32 +883,25 @@ Results *FindMiddleRoute(Nodes *nodes,Segments *segments,Ways *ways,Relations *r
     return(NULL);
    }
 
- /* Finish off the end part of the route */
-
- if(finish_result->node!=end->finish_node)
-   {
-    result3=InsertResult(results,end->finish_node,NO_SEGMENT);
-
-    result3->prev=finish_result;
-    result3->score=finish_score;
-
-    finish_result=result3;
-   }
-
  FixForwardRoute(results,finish_result);
 
 #if DEBUG
  Result *r=FindResult(results,results->start_node,results->prev_segment);
 
+ printf("    -------- middle route (start route then via super-nodes/segments)\n");
+
  while(r)
    {
-    printf("    node=%"Pindex_t" segment=%"Pindex_t" score=%f\n",r->node,r->segment,r->score);
+    printf("    node=%"Pindex_t" segment=%"Pindex_t" score=%f%s%s%s\n",r->node,r->segment,r->score,
+                                                                       (IsSuperNode(LookupNode(nodes,r->node,1))?" (super)":""),
+                                                                       (r->node==results->start_node&&r->segment==results->prev_segment?" (start)":""),
+                                                                       (r->node==results->finish_node?" (finish)":""));
 
     r=r->next;
    }
 #endif
 
-#if !DEBUG
+#if !DEBUG && !defined(LIBROUTINO)
  if(!option_quiet)
     printf_last("Found Middle Route: Super-Nodes checked = %d",results->number);
 #endif
@@ -787,7 +1010,7 @@ static Results *FindSuperRoute(Nodes *nodes,Segments *segments,Ways *ways,Relati
  Result  *result1,*result2;
 
 #if DEBUG
- printf("    FindSuperRoute(...,start_node=%"Pindex_t" finish_node=%"Pindex_t")\n",start_node,finish_node);
+ printf("      FindSuperRoute(...,start_node=%"Pindex_t" finish_node=%"Pindex_t")\n",start_node,finish_node);
 #endif
 
  /* Create the list of results and insert the first node into the queue */
@@ -889,13 +1112,28 @@ static Results *FindSuperRoute(Nodes *nodes,Segments *segments,Ways *ways,Relati
  FreeQueueList(queue);
 
 #if DEBUG
- Result *r=FindResult(results,results->start_node,results->prev_segment);
+ Result *s=FirstResult(results);
 
- while(r)
+ while(s)
    {
-    printf("      node=%"Pindex_t" segment=%"Pindex_t" score=%f\n",r->node,r->segment,r->score);
+    if(s->node==finish_node)
+      {
+       Result *r=FindResult(results,s->node,s->segment);
 
-    r=r->next;
+       printf("        -------- super-route\n");
+
+       while(r)
+         {
+          printf("        node=%"Pindex_t" segment=%"Pindex_t" score=%f%s%s%s\n",r->node,r->segment,r->score,
+                                                                                (IsSuperNode(LookupNode(nodes,r->node,1))?" (super)":""),
+                                                                                (r->node==start_node?" (start)":""),
+                                                                                (r->node==finish_node?" (finish)":""));
+
+          r=r->prev;
+         }
+      }
+
+    s=NextResult(results,s);
    }
 #endif
 
@@ -925,18 +1163,20 @@ static Results *FindSuperRoute(Nodes *nodes,Segments *segments,Ways *ways,Relati
   index_t finish_node The finish node.
   ++++++++++++++++++++++++++++++++++++++*/
 
-Results *FindStartRoutes(Nodes *nodes,Segments *segments,Ways *ways,Relations *relations,Profile *profile,index_t start_node,index_t prev_segment,index_t finish_node)
+static Results *FindStartRoutes(Nodes *nodes,Segments *segments,Ways *ways,Relations *relations,Profile *profile,index_t start_node,index_t prev_segment,index_t finish_node)
 {
  Results *results;
- Queue   *queue;
+ Queue   *queue,*superqueue;
  Result  *result1,*result2;
+ Result  *finish_result=NULL;
+ score_t finish_score=INF_SCORE;
  int     nsuper=0,force_uturn=0;
 
 #if DEBUG
  printf("  FindStartRoutes(...,start_node=%"Pindex_t" prev_segment=%"Pindex_t" finish_node=%"Pindex_t")\n",start_node,prev_segment,finish_node);
 #endif
 
-#if !DEBUG
+#if !DEBUG && !defined(LIBROUTINO)
  if(!option_quiet)
     printf_first("Finding Start Route: Nodes checked = 0");
 #endif
@@ -945,6 +1185,7 @@ Results *FindStartRoutes(Nodes *nodes,Segments *segments,Ways *ways,Relations *r
 
  results=NewResultsList(8);
  queue=NewQueueList(8);
+ superqueue=NewQueueList(8);
 
  results->start_node=start_node;
  results->prev_segment=prev_segment;
@@ -972,6 +1213,10 @@ Results *FindStartRoutes(Nodes *nodes,Segments *segments,Ways *ways,Relations *r
     index_t node1,seg1,seg1r;
     index_t turnrelation=NO_RELATION;
 
+    /* score must be better than current best score */
+    if(result1->score>=finish_score)
+       continue;
+
     node1=result1->node;
     seg1=result1->segment;
 
@@ -1088,13 +1333,23 @@ Results *FindStartRoutes(Nodes *nodes,Segments *segments,Ways *ways,Relations *r
        if(node2p && node2!=finish_node && !(node2p->allow&profile->allow))
           goto endloop;
 
+       /* calculate the score for the segment and cumulative */
        if(option_quickest==0)
           segment_score=(score_t)DISTANCE(segmentp->distance)/segment_pref;
        else
           segment_score=(score_t)Duration(segmentp,wayp,profile)/segment_pref;
 
+       /* prefer not to follow two fake segments when one would do (special case) */
+       if(IsFakeSegment(seg2))
+          segment_score*=1.01f;
+
        cumulative_score=result1->score+segment_score;
 
+       /* score must be better than current best score */
+       if(cumulative_score>=finish_score)
+          goto endloop;
+
+       /* find whether the node/segment combination already exists */
        result2=FindResult(results,node2,seg2);
 
        if(!result2) /* New end node/segment combination */
@@ -1105,32 +1360,39 @@ Results *FindStartRoutes(Nodes *nodes,Segments *segments,Ways *ways,Relations *r
 
           if(node2p && IsSuperNode(node2p))
              nsuper++;
-
-          if(node2==finish_node)
-             nsuper++;
-
-          if(node2==finish_node)
-            {
-             results->finish_node=finish_node;
-             results->last_segment=seg2;
-            }
          }
        else if(cumulative_score<result2->score) /* New score for end node/segment combination is better */
          {
           result2->prev=result1;
           result2->score=cumulative_score;
+         }
+       else
+          goto endloop;
 
-          if(node2==finish_node)
+       if(node2==finish_node)
+         {
+          if(!finish_result)
+            {
+             Result *result3;
+
+             while((result3=PopFromQueue(superqueue)))
+                InsertInQueue(queue,result3,result3->score);
+            }
+
+          if(cumulative_score<finish_score)
             {
-             results->finish_node=finish_node;
+             finish_score=cumulative_score;
+             finish_result=result2;
+
+             results->finish_node=node2;
              results->last_segment=seg2;
             }
          }
-       else
-          goto endloop;
 
-       if(node2p && !IsSuperNode(node2p))
+       if(finish_result || (node2p && !IsSuperNode(node2p)))
           InsertInQueue(queue,result2,result2->score);
+       else if(node2p && IsSuperNode(node2p))
+          InsertInQueue(superqueue,result2,result2->score);
 
       endloop:
 
@@ -1149,16 +1411,17 @@ Results *FindStartRoutes(Nodes *nodes,Segments *segments,Ways *ways,Relations *r
    }
 
  FreeQueueList(queue);
+ FreeQueueList(superqueue);
 
  /* Check it worked */
 
- if(results->number==1 || nsuper==0)
+ if(results->number==1 || (nsuper==0 && !finish_result))
    {
 #if DEBUG
     printf("    Failed (%d results, %d super)\n",results->number,nsuper);
 #endif
 
-#if !DEBUG
+#if !DEBUG && !defined(LIBROUTINO)
     if(!option_quiet)
        printf_last("Found Start Route: Nodes checked = %d - Fail",results->number);
 #endif
@@ -1167,49 +1430,38 @@ Results *FindStartRoutes(Nodes *nodes,Segments *segments,Ways *ways,Relations *r
     return(NULL);
    }
 
+ /* If we found the finish node then make a proper route */
+
+ if(finish_result)
+    FixForwardRoute(results,finish_result);
+
 #if DEBUG
  Result *s=FirstResult(results);
 
  while(s)
    {
-    if(s->node==finish_node)
+    if(s->node==finish_node || (!IsFakeNode(s->node) && IsSuperNode(LookupNode(nodes,s->node,1))))
       {
        Result *r=FindResult(results,s->node,s->segment);
 
-       printf("    -------- route to finish node\n");
+       printf("    -------- possible start route\n");
 
        while(r)
          {
-          printf("    node=%"Pindex_t" segment=%"Pindex_t" score=%f\n",r->node,r->segment,r->score);
+          printf("    node=%"Pindex_t" segment=%"Pindex_t" score=%f%s%s%s\n",r->node,r->segment,r->score,
+                                                                            (IsSuperNode(LookupNode(nodes,r->node,1))?" (super)":""),
+                                                                            (r->node==start_node&&r->segment==prev_segment?" (start)":""),
+                                                                            (r->node==finish_node?" (finish)":""));
 
           r=r->prev;
          }
       }
 
-    if(!IsFakeNode(s->node))
-      {
-       Node *n=LookupNode(nodes,s->node,1);
-
-       if(IsSuperNode(n))
-         {
-          Result *r=FindResult(results,s->node,s->segment);
-
-          printf("    -------- route to super node\n");
-
-          while(r)
-            {
-             printf("    node=%"Pindex_t" segment=%"Pindex_t" score=%f\n",r->node,r->segment,r->score);
-
-             r=r->prev;
-            }
-         }
-      }
-
     s=NextResult(results,s);
    }
 #endif
 
-#if !DEBUG
+#if !DEBUG && !defined(LIBROUTINO)
  if(!option_quiet)
     printf_last("Found Start Route: Nodes checked = %d",results->number);
 #endif
@@ -1219,265 +1471,6 @@ Results *FindStartRoutes(Nodes *nodes,Segments *segments,Ways *ways,Relations *r
 
 
 /*++++++++++++++++++++++++++++++++++++++
-  Continue finding routes from a set of super-nodes to a finish point.
-
-  Results *ExtendStartRoutes Returns the set of results that were passed in.
-
-  Nodes *nodes The set of nodes to use.
-
-  Segments *segments The set of segments to use.
-
-  Ways *ways The set of ways to use.
-
-  Relations *relations The set of relations to use.
-
-  Profile *profile The profile containing the transport type, speeds and allowed highways.
-
-  Results *begin The partial set of routes already computed.
-
-  index_t finish_node The finish node.
-  ++++++++++++++++++++++++++++++++++++++*/
-
-Results *ExtendStartRoutes(Nodes *nodes,Segments *segments,Ways *ways,Relations *relations,Profile *profile,Results *begin,index_t finish_node)
-{
- Results *results=begin;
- Queue   *queue;
- Result  *result1,*result2,*result3;
- Result  *finish_result=NULL;
- score_t finish_score=INF_SCORE;
-
-#if DEBUG
- printf("  ExtendStartRoutes(...,[begin has %d nodes],finish_node=%"Pindex_t")\n",begin->number,finish_node);
-#endif
-
-#if !DEBUG
- if(!option_quiet)
-    printf_first("Extending Start Route: Nodes checked = 0");
-#endif
-
- /* Check the list of results and insert the super nodes into the queue */
-
- queue=NewQueueList(8);
-
- result3=FirstResult(begin);
-
- while(result3)
-   {
-    if(result3->node==finish_node)
-       if(result3->score<finish_score)
-         {
-          finish_score=result3->score;
-          finish_result=result3;
-         }
-
-    if(!IsFakeNode(result3->node))
-       if(IsSuperNode(LookupNode(nodes,result3->node,3)))
-          InsertInQueue(queue,result3,result3->score);
-
-    result3=NextResult(results,result3);
-   }
-
- /* Loop across all nodes in the queue */
-
- while((result1=PopFromQueue(queue)))
-   {
-    Node *node1p=NULL;
-    Segment *segmentp;
-    index_t node1,seg1,seg1r;
-    index_t turnrelation=NO_RELATION;
-
-    /* score must be better than current best score */
-    if(result1->score>=finish_score)
-       continue;
-
-    node1=result1->node;
-    seg1=result1->segment;
-
-    if(IsFakeSegment(seg1))
-       seg1r=IndexRealSegment(seg1);
-    else
-       seg1r=seg1;
-
-    if(!IsFakeNode(node1))
-       node1p=LookupNode(nodes,node1,1);
-
-    /* lookup if a turn restriction applies */
-    if(profile->turns && node1p && IsTurnRestrictedNode(node1p))
-       turnrelation=FindFirstTurnRelation2(relations,node1,seg1r);
-
-    /* Loop across all segments */
-
-    if(IsFakeNode(node1))
-       segmentp=FirstFakeSegment(node1);
-    else
-       segmentp=FirstSegment(segments,node1p,1);
-
-    while(segmentp)
-      {
-       Node *node2p=NULL;
-       Way *wayp;
-       index_t node2,seg2,seg2r;
-       score_t segment_pref,segment_score,cumulative_score;
-       int i;
-
-       node2=OtherNode(segmentp,node1); /* need this here because we use node2 at the end of the loop */
-
-       /* must be a normal segment */
-       if(!IsNormalSegment(segmentp))
-          goto endloop;
-
-       /* must obey one-way restrictions (unless profile allows) */
-       if(profile->oneway && IsOnewayTo(segmentp,node1))
-         {
-          if(profile->allow!=Transports_Bicycle)
-             goto endloop;
-
-          wayp=LookupWay(ways,segmentp->way,1);
-
-          if(!(wayp->type&Highway_CycleBothWays))
-             goto endloop;
-         }
-
-       if(IsFakeNode(node1) || IsFakeNode(node2))
-         {
-          seg2 =IndexFakeSegment(segmentp);
-          seg2r=IndexRealSegment(seg2);
-         }
-       else
-         {
-          seg2 =IndexSegment(segments,segmentp);
-          seg2r=seg2;
-         }
-
-       /* must not perform U-turn (unless profile allows) */
-       if(profile->turns && (seg1==seg2 || seg1==seg2r || seg1r==seg2 || (seg1r==seg2r && IsFakeUTurn(seg1,seg2))))
-          goto endloop;
-
-       /* must obey turn relations */
-       if(turnrelation!=NO_RELATION && !IsTurnAllowed(relations,turnrelation,node1,seg1r,seg2r,profile->allow))
-          goto endloop;
-
-       wayp=LookupWay(ways,segmentp->way,1);
-
-       /* mode of transport must be allowed on the highway */
-       if(!(wayp->allow&profile->allow))
-          goto endloop;
-
-       /* must obey weight restriction (if exists) */
-       if(wayp->weight && wayp->weight<profile->weight)
-          goto endloop;
-
-       /* must obey height/width/length restriction (if exists) */
-       if((wayp->height && wayp->height<profile->height) ||
-          (wayp->width  && wayp->width <profile->width ) ||
-          (wayp->length && wayp->length<profile->length))
-          goto endloop;
-
-       segment_pref=profile->highway[HIGHWAY(wayp->type)];
-
-       /* highway preferences must allow this highway */
-       if(segment_pref==0)
-          goto endloop;
-
-       for(i=1;i<Property_Count;i++)
-          if(ways->file.props & PROPERTIES(i))
-            {
-             if(wayp->props & PROPERTIES(i))
-                segment_pref*=profile->props_yes[i];
-             else
-                segment_pref*=profile->props_no[i];
-            }
-
-       /* profile preferences must allow this highway */
-       if(segment_pref==0)
-          goto endloop;
-
-       if(!IsFakeNode(node2))
-          node2p=LookupNode(nodes,node2,2);
-
-       /* mode of transport must be allowed through node2 unless it is the final node */
-       if(node2p && node2!=finish_node && !(node2p->allow&profile->allow))
-          goto endloop;
-
-       if(option_quickest==0)
-          segment_score=(score_t)DISTANCE(segmentp->distance)/segment_pref;
-       else
-          segment_score=(score_t)Duration(segmentp,wayp,profile)/segment_pref;
-
-       cumulative_score=result1->score+segment_score;
-
-       /* score must be better than current best score */
-       if(cumulative_score>=finish_score)
-          goto endloop;
-
-       result2=FindResult(results,node2,seg2);
-
-       if(!result2) /* New end node/segment combination */
-         {
-          result2=InsertResult(results,node2,seg2);
-          result2->prev=result1;
-          result2->score=cumulative_score;
-         }
-       else if(cumulative_score<result2->score) /* New score for end node/segment combination is better */
-         {
-          result2->prev=result1;
-          result2->score=cumulative_score;
-         }
-       else
-          goto endloop;
-
-       if(node2==finish_node)
-         {
-          if(cumulative_score<finish_score)
-            {
-             finish_score=cumulative_score;
-             finish_result=result2;
-            }
-         }
-       else
-          InsertInQueue(queue,result2,result2->score);
-
-      endloop:
-
-       if(IsFakeNode(node1))
-          segmentp=NextFakeSegment(segmentp,node1);
-       else if(IsFakeNode(node2))
-          segmentp=NULL; /* cannot call NextSegment() with a fake segment */
-       else
-         {
-          segmentp=NextSegment(segments,segmentp,node1);
-
-          if(!segmentp && IsFakeNode(finish_node))
-             segmentp=ExtraFakeSegment(node1,finish_node);
-         }
-      }
-   }
-
- FreeQueueList(queue);
-
- FixForwardRoute(results,finish_result);
-
-#if DEBUG
- Result *r=FindResult(results,results->start_node,results->prev_segment);
-
- while(r)
-   {
-    printf("    node=%"Pindex_t" segment=%"Pindex_t" score=%f\n",r->node,r->segment,r->score);
-
-    r=r->next;
-   }
-#endif
-
-#if !DEBUG
- if(!option_quiet)
-    printf_last("Extended Start Route: Nodes checked = %d",results->number);
-#endif
-
- return(results);
-}
-
-
-/*++++++++++++++++++++++++++++++++++++++
   Find all routes from any super-node to a specific node (by working backwards from the specific node to all super-nodes).
 
   Results *FindFinishRoutes Returns a set of results.
@@ -1495,7 +1488,7 @@ Results *ExtendStartRoutes(Nodes *nodes,Segments *segments,Ways *ways,Relations
   index_t finish_node The finishing node.
   ++++++++++++++++++++++++++++++++++++++*/
 
-Results *FindFinishRoutes(Nodes *nodes,Segments *segments,Ways *ways,Relations *relations,Profile *profile,index_t finish_node)
+static Results *FindFinishRoutes(Nodes *nodes,Segments *segments,Ways *ways,Relations *relations,Profile *profile,index_t finish_node)
 {
  Results *results,*results2;
  Queue   *queue;
@@ -1505,7 +1498,7 @@ Results *FindFinishRoutes(Nodes *nodes,Segments *segments,Ways *ways,Relations *
  printf("  FindFinishRoutes(...,finish_node=%"Pindex_t")\n",finish_node);
 #endif
 
-#if !DEBUG
+#if !DEBUG && !defined(LIBROUTINO)
  if(!option_quiet)
     printf_first("Finding Finish Route: Nodes checked = 0");
 #endif
@@ -1661,13 +1654,19 @@ Results *FindFinishRoutes(Nodes *nodes,Segments *segments,Ways *ways,Relations *
        if(node2p && !(node2p->allow&profile->allow))
           goto endloop;
 
+       /* calculate the score for the segment and cumulative */
        if(option_quickest==0)
           segment_score=(score_t)DISTANCE(segmentp->distance)/segment_pref;
        else
           segment_score=(score_t)Duration(segmentp,wayp,profile)/segment_pref;
 
+       /* prefer not to follow two fake segments when one would do (special case) */
+       if(IsFakeSegment(seg1))
+          segment_score*=1.01f;
+
        cumulative_score=result1->score+segment_score;
 
+       /* find whether the node/segment combination already exists */
        result2=FindResult(results,node2,seg2);
 
        if(!result2) /* New end node */
@@ -1706,7 +1705,7 @@ Results *FindFinishRoutes(Nodes *nodes,Segments *segments,Ways *ways,Relations *
     printf("    Failed\n");
 #endif
 
-#if !DEBUG
+#if !DEBUG && !defined(LIBROUTINO)
  if(!option_quiet)
     printf_last("Found Finish Route: Nodes checked = %d - Fail",results->number);
 #endif
@@ -1752,29 +1751,24 @@ Results *FindFinishRoutes(Nodes *nodes,Segments *segments,Ways *ways,Relations *
     result3=NextResult(results,result3);
    }
 
- FreeResultsList(results);
-
 #if DEBUG
  Result *s=FirstResult(results2);
 
  while(s)
    {
-    if(!IsFakeNode(s->node))
+    if(!IsFakeNode(s->node) && IsSuperNode(LookupNode(nodes,s->node,1)))
       {
-       Node *n=LookupNode(nodes,s->node,1);
+       Result *r=FindResult(results2,s->node,s->segment);
 
-       if(IsSuperNode(n))
-         {
-          Result *r=FindResult(results2,s->node,s->segment);
-
-          printf("    --------\n");
+       printf("    -------- possible finish route\n");
 
-          while(r)
-            {
-             printf("    node=%"Pindex_t" segment=%"Pindex_t" score=%f\n",r->node,r->segment,r->score);
+       while(r)
+         {
+          printf("    node=%"Pindex_t" segment=%"Pindex_t" score=%f%s%s\n",r->node,r->segment,r->score,
+                                                                           (IsSuperNode(LookupNode(nodes,r->node,1))?" (super)":""),
+                                                                           (r->node==finish_node?" (finish)":""));
 
-             r=r->next;
-            }
+          r=r->next;
          }
       }
 
@@ -1782,11 +1776,13 @@ Results *FindFinishRoutes(Nodes *nodes,Segments *segments,Ways *ways,Relations *
    }
 #endif
 
-#if !DEBUG
+#if !DEBUG && !defined(LIBROUTINO)
  if(!option_quiet)
     printf_last("Found Finish Route: Nodes checked = %d",results->number);
 #endif
 
+ FreeResultsList(results);
+
  return(results2);
 }
 
@@ -1809,18 +1805,20 @@ Results *FindFinishRoutes(Nodes *nodes,Segments *segments,Ways *ways,Relations *
   Results *begin The set of results for the start of the route.
 
   Results *middle The set of results from the super-node route.
+
+  Results *end The set of results for the end of the route.
   ++++++++++++++++++++++++++++++++++++++*/
 
-Results *CombineRoutes(Nodes *nodes,Segments *segments,Ways *ways,Relations *relations,Profile *profile,Results *begin,Results *middle)
+static Results *CombineRoutes(Nodes *nodes,Segments *segments,Ways *ways,Relations *relations,Profile *profile,Results *begin,Results *middle,Results *end)
 {
- Result *midres,*comres1;
+ Result *midres,*comres;
  Results *combined;
 
 #if DEBUG
- printf("  CombineRoutes(...,[begin has %d nodes],[middle has %d nodes])\n",begin->number,middle->number);
+ printf("  CombineRoutes(...,[begin has %d nodes],[middle has %d nodes],[end has %d nodes])\n",begin->number,middle->number,end->number);
 #endif
 
-#if !DEBUG
+#if !DEBUG && !defined(LIBROUTINO)
  if(!option_quiet)
     printf_first("Finding Combined Route: Nodes = 0");
 #endif
@@ -1834,7 +1832,7 @@ Results *CombineRoutes(Nodes *nodes,Segments *segments,Ways *ways,Relations *rel
 
  midres=FindResult(middle,middle->start_node,middle->prev_segment);
 
- comres1=InsertResult(combined,combined->start_node,combined->prev_segment);
+ comres=InsertResult(combined,combined->start_node,combined->prev_segment);
 
  /* Insert the start of the route */
 
@@ -1862,90 +1860,116 @@ Results *CombineRoutes(Nodes *nodes,Segments *segments,Ways *ways,Relations *rel
        comres2=InsertResult(combined,begres->node,begres->segment);
 
        comres2->score=begres->score;
-       comres2->prev=comres1;
+       comres2->prev=comres;
 
        begres=begres->next;
 
-       comres1=comres2;
+       comres=comres2;
       }
     while(begres);
    }
 
  /* Sort out the combined route */
 
- do
+ while(midres->next)
    {
+    Results *results=FindNormalRoute(nodes,segments,ways,relations,profile,comres->node,comres->segment,midres->next->node);
     Result *result;
 
-    if(midres->next)
+    if(!results)
       {
-       Results *results=FindNormalRoute(nodes,segments,ways,relations,profile,comres1->node,comres1->segment,midres->next->node);
-
-       if(!results)
-         {
-#if !DEBUG
-          if(!option_quiet)
-             printf_last("Found Combined Route: Nodes = %d - Fail",combined->number);
+#if !DEBUG && !defined(LIBROUTINO)
+       if(!option_quiet)
+          printf_last("Found Combined Route: Nodes = %d - Fail",combined->number);
 #endif
 
-          FreeResultsList(combined);
-          return(NULL);
-         }
+       FreeResultsList(combined);
+       return(NULL);
+      }
 
-       result=FindResult(results,midres->node,comres1->segment);
+    result=FindResult(results,midres->node,comres->segment);
 
-       result=result->next;
+    result=result->next;
 
-       /*
-        *      midres                          midres->next
-        *         =                                  =
-        *      ---*----------------------------------*  = middle
-        *
-        *      ---*----.----.----.----.----.----.----*  = results
-        *              =
-        *             result
-        *
-        *      ---*----.----.----.----.----.----.----*  = combined
-        *         =    =
-        *   comres1  comres2
-        */
-
-       do
-         {
-          Result *comres2;
+    /*
+     *      midres                          midres->next
+     *         =                                  =
+     *      ---*----------------------------------*  = middle
+     *
+     *      ---*----.----.----.----.----.----.----*  = results
+     *              =
+     *             result
+     *
+     *      ---*----.----.----.----.----.----.----*  = combined
+     *         =    =
+     *     comres  comres2
+     */
 
-          comres2=InsertResult(combined,result->node,result->segment);
+    do
+      {
+       Result *comres2;
 
-          comres2->score=midres->score+result->score;
-          comres2->prev=comres1;
+       comres2=InsertResult(combined,result->node,result->segment);
 
-          result=result->next;
+       comres2->score=midres->score+result->score;
+       comres2->prev=comres;
 
-          comres1=comres2;
-         }
-       while(result);
+       result=result->next;
 
-       FreeResultsList(results);
+       comres=comres2;
       }
+    while(result);
+
+    FreeResultsList(results);
 
     midres=midres->next;
    }
- while(midres);
 
- FixForwardRoute(combined,comres1);
+ /* Insert the end of the route */
+
+ if(end->number>1)
+   {
+    Result *endres=FindResult(end,midres->node,midres->segment);
+
+    while(endres->next)
+      {
+       Result *comres2;
+
+       comres2=InsertResult(combined,endres->next->node,endres->next->segment);
+
+       comres2->score=comres->score+(endres->score-endres->next->score);
+       comres2->prev=comres;
+
+       endres=endres->next;
+
+       comres=comres2;
+      }
+   }
+
+ /* Turn the route round */
+
+ combined->finish_node=comres->node;
+ combined->last_segment=comres->segment;
+
+ FixForwardRoute(combined,comres);
 
 #if DEBUG
  Result *r=FindResult(combined,combined->start_node,combined->prev_segment);
 
+ printf("      -------- combined route (end-to-end)\n");
+
  while(r)
    {
-    printf("    node=%"Pindex_t" segment=%"Pindex_t" score=%f\n",r->node,r->segment,r->score);
+    printf("    node=%"Pindex_t" segment=%"Pindex_t" score=%f%s%s%s\n",r->node,r->segment,r->score,
+                                                                       (IsSuperNode(LookupNode(nodes,r->node,1))?" (super)":""),
+                                                                       (r->node==combined->start_node&&r->segment==combined->prev_segment?" (start)":""),
+                                                                       (r->node==combined->finish_node?" (finish)":""));
 
     r=r->next;
    }
 #endif
 
-#if !DEBUG
+#if !DEBUG && !defined(LIBROUTINO)
  if(!option_quiet)
     printf_last("Found Combined Route: Nodes = %d",combined->number);
 #endif
@@ -1962,7 +1986,7 @@ Results *CombineRoutes(Nodes *nodes,Segments *segments,Ways *ways,Relations *rel
   Result *finish_result The result for the finish point.
   ++++++++++++++++++++++++++++++++++++++*/
 
-void FixForwardRoute(Results *results,Result *finish_result)
+static void FixForwardRoute(Results *results,Result *finish_result)
 {
  Result *result2=finish_result;
 
@@ -1993,7 +2017,9 @@ void FixForwardRoute(Results *results,Result *finish_result)
 
        result1=FindResult(results,node1,seg1);
 
+#ifndef LIBROUTINO
        logassert(!result1->next,"Unable to reverse route through results (report a bug)"); /* Bugs elsewhere can lead to infinite loop here. */
+#endif
 
        result1->next=result2;
 
diff --git a/src/osmo5mparse.c b/src/osmo5mparse.c
index 26c7467..22d7769 100644
--- a/src/osmo5mparse.c
+++ b/src/osmo5mparse.c
@@ -3,7 +3,7 @@
 
  Part of the Routino routing software.
  ******************/ /******************
- This file Copyright 2012-2014 Andrew M. Bishop
+ This file Copyright 2012-2015 Andrew M. Bishop
 
  This program is free software: you can redistribute it and/or modify
  it under the terms of the GNU Affero General Public License as published by
@@ -21,7 +21,16 @@
 
 
 #include <stdio.h>
+
+#if defined(_MSC_VER)
+#include <io.h>
+#include <basetsd.h>
+#define read(fd,address,length) _read(fd,address,(unsigned int)(length))
+#define ssize_t SSIZE_T
+#else
 #include <unistd.h>
+#endif
+
 #include <stdlib.h>
 #include <string.h>
 #include <inttypes.h>
@@ -56,9 +65,7 @@
 #define O5M_ERROR_EXPECTED_O5C     104
 #define O5M_ERROR_FILE_LEVEL       105
 
-
-
-/* Parsing variables and functions */
+/* Local parsing variables (re-initialised for each file) */
 
 static uint64_t byteno=0;
 static uint64_t nnodes=0,nways=0,nrelations=0;
diff --git a/src/osmparser.c b/src/osmparser.c
index f0437c0..88f6e22 100644
--- a/src/osmparser.c
+++ b/src/osmparser.c
@@ -3,7 +3,7 @@
 
  Part of the Routino routing software.
  ******************/ /******************
- This file Copyright 2008-2014 Andrew M. Bishop
+ This file Copyright 2008-2015 Andrew M. Bishop
 
  This program is free software: you can redistribute it and/or modify
  it under the terms of the GNU Affero General Public License as published by
@@ -45,26 +45,26 @@
 /*+ Checks if a value in the XML is one of the allowed values for false. +*/
 #define ISFALSE(xx) (!strcmp(xx,"false") || !strcmp(xx,"no") || !strcmp(xx,"0"))
 
-/* Local variables */
+/* Local parsing variables (re-initialised for each file) */
 
 static NodesX     *nodes;
 static WaysX      *ways;
 static RelationsX *relations;
 
-static node_t *way_nodes=NULL;
-static int     way_nnodes=0;
+static node_t     *way_nodes;
+static int         way_nnodes;
 
-static node_t     *relation_nodes=NULL;
-static int         relation_nnodes=0;
-static way_t      *relation_ways=NULL;
-static int         relation_nways=0;
-static relation_t *relation_relations=NULL;
-static int         relation_nrelations=0;
-static way_t       relation_from=NO_WAY_ID;
-static way_t       relation_to=NO_WAY_ID;
-static node_t      relation_via=NO_NODE_ID;
+static node_t     *relation_nodes;
+static int         relation_nnodes;
+static way_t      *relation_ways;
+static int         relation_nways;
+static relation_t *relation_relations;
+static int         relation_nrelations;
+static way_t       relation_from;
+static way_t       relation_to;
+static node_t      relation_via;
 
-/* Local functions */
+/* Local parsing functions */
 
 static double parse_speed(way_t id,const char *k,const char *v);
 static double parse_weight(way_t id,const char *k,const char *v);
diff --git a/src/osmpbfparse.c b/src/osmpbfparse.c
index c388151..56d8f0c 100644
--- a/src/osmpbfparse.c
+++ b/src/osmpbfparse.c
@@ -3,7 +3,7 @@
 
  Part of the Routino routing software.
  ******************/ /******************
- This file Copyright 2012-2014 Andrew M. Bishop
+ This file Copyright 2012-2015 Andrew M. Bishop
 
  This program is free software: you can redistribute it and/or modify
  it under the terms of the GNU Affero General Public License as published by
@@ -21,7 +21,16 @@
 
 
 #include <stdio.h>
+
+#if defined(_MSC_VER)
+#include <io.h>
+#include <basetsd.h>
+#define read(fd,address,length) _read(fd,address,(unsigned int)(length))
+#define ssize_t SSIZE_T
+#else
 #include <unistd.h>
+#endif
+
 #include <stdlib.h>
 #include <stdint.h>
 #include <string.h>
@@ -120,10 +129,10 @@
 #define PBF_ERROR_TOO_MANY_GROUPS 112
 
 
-/* Parsing variables and functions */
+/* Local parsing variables (re-initialised for each file) */
 
-static uint64_t byteno=0;
-static uint64_t nnodes=0,nways=0,nrelations=0;
+static uint64_t byteno;
+static uint64_t nnodes,nways,nrelations;
 
 static uint32_t buffer_allocated,zbuffer_allocated;
 static unsigned char *buffer=NULL,*zbuffer=NULL;
@@ -367,6 +376,8 @@ static int ParsePBF(int fd)
 
  /* The actual parser. */
 
+ byteno=0;
+
  nnodes=0,nways=0,nrelations=0;
 
  string_table_allocated=16384;
diff --git a/src/osmxmlparse.c b/src/osmxmlparse.c
index 39af899..b38155f 100644
--- a/src/osmxmlparse.c
+++ b/src/osmxmlparse.c
@@ -3,7 +3,7 @@
 
  Part of the Routino routing software.
  ******************/ /******************
- This file Copyright 2008-2013 Andrew M. Bishop
+ This file Copyright 2008-2015 Andrew M. Bishop
 
  This program is free software: you can redistribute it and/or modify
  it under the terms of the GNU Affero General Public License as published by
@@ -31,13 +31,13 @@
 #include "logging.h"
 
 
-/* Local variables */
+/* Local parsing variables (re-initialised for each file) */
 
 static int current_mode=MODE_NORMAL;
 
-static uint64_t nnodes=0,nways=0,nrelations=0;
+static uint64_t nnodes,nways,nrelations;
 
-static TagList *current_tags=NULL;
+static TagList *current_tags;
 
 
 /* The XML tag processing function prototypes */
@@ -61,131 +61,131 @@ static int memberType_function(const char *_tag_,int _type_,const char *type,con
 
 /* The XML tag definitions (forward declarations) */
 
-static xmltag xmlDeclaration_tag;
-static xmltag osmType_tag;
-static xmltag osmChangeType_tag;
-static xmltag boundsType_tag;
-static xmltag boundType_tag;
-static xmltag changesetType_tag;
-static xmltag modifyType_tag;
-static xmltag createType_tag;
-static xmltag deleteType_tag;
-static xmltag nodeType_tag;
-static xmltag wayType_tag;
-static xmltag relationType_tag;
-static xmltag tagType_tag;
-static xmltag ndType_tag;
-static xmltag memberType_tag;
+static const xmltag xmlDeclaration_tag;
+static const xmltag osmType_tag;
+static const xmltag osmChangeType_tag;
+static const xmltag boundsType_tag;
+static const xmltag boundType_tag;
+static const xmltag changesetType_tag;
+static const xmltag modifyType_tag;
+static const xmltag createType_tag;
+static const xmltag deleteType_tag;
+static const xmltag nodeType_tag;
+static const xmltag wayType_tag;
+static const xmltag relationType_tag;
+static const xmltag tagType_tag;
+static const xmltag ndType_tag;
+static const xmltag memberType_tag;
 
 
 /* The XML tag definition values */
 
 /*+ The complete set of tags at the top level for OSM. +*/
-static xmltag *xml_osm_toplevel_tags[]={&xmlDeclaration_tag,&osmType_tag,NULL};
+static const xmltag * const xml_osm_toplevel_tags[]={&xmlDeclaration_tag,&osmType_tag,NULL};
 
 /*+ The complete set of tags at the top level for OSC. +*/
-static xmltag *xml_osc_toplevel_tags[]={&xmlDeclaration_tag,&osmChangeType_tag,NULL};
+static const xmltag * const xml_osc_toplevel_tags[]={&xmlDeclaration_tag,&osmChangeType_tag,NULL};
 
 /*+ The xmlDeclaration type tag. +*/
-static xmltag xmlDeclaration_tag=
+static const xmltag xmlDeclaration_tag=
               {"xml",
                2, {"version","encoding"},
                NULL,
                {NULL}};
 
 /*+ The osmType type tag. +*/
-static xmltag osmType_tag=
+static const xmltag osmType_tag=
               {"osm",
                1, {"version"},
                osmType_function,
                {&boundsType_tag,&boundType_tag,&changesetType_tag,&nodeType_tag,&wayType_tag,&relationType_tag,NULL}};
 
 /*+ The osmChangeType type tag. +*/
-static xmltag osmChangeType_tag=
+static const xmltag osmChangeType_tag=
               {"osmChange",
                1, {"version"},
                osmChangeType_function,
                {&boundsType_tag,&modifyType_tag,&createType_tag,&deleteType_tag,NULL}};
 
 /*+ The boundsType type tag. +*/
-static xmltag boundsType_tag=
+static const xmltag boundsType_tag=
               {"bounds",
                0, {NULL},
                NULL,
                {NULL}};
 
 /*+ The boundType type tag. +*/
-static xmltag boundType_tag=
+static const xmltag boundType_tag=
               {"bound",
                0, {NULL},
                NULL,
                {NULL}};
 
 /*+ The changesetType type tag. +*/
-static xmltag changesetType_tag=
+static const xmltag changesetType_tag=
               {"changeset",
                0, {NULL},
                changesetType_function,
                {&tagType_tag,NULL}};
 
 /*+ The modifyType type tag. +*/
-static xmltag modifyType_tag=
+static const xmltag modifyType_tag=
               {"modify",
                0, {NULL},
                modifyType_function,
                {&nodeType_tag,&wayType_tag,&relationType_tag,NULL}};
 
 /*+ The createType type tag. +*/
-static xmltag createType_tag=
+static const xmltag createType_tag=
               {"create",
                0, {NULL},
                createType_function,
                {&nodeType_tag,&wayType_tag,&relationType_tag,NULL}};
 
 /*+ The deleteType type tag. +*/
-static xmltag deleteType_tag=
+static const xmltag deleteType_tag=
               {"delete",
                0, {NULL},
                deleteType_function,
                {&nodeType_tag,&wayType_tag,&relationType_tag,NULL}};
 
 /*+ The nodeType type tag. +*/
-static xmltag nodeType_tag=
+static const xmltag nodeType_tag=
               {"node",
                3, {"id","lat","lon"},
                nodeType_function,
                {&tagType_tag,NULL}};
 
 /*+ The wayType type tag. +*/
-static xmltag wayType_tag=
+static const xmltag wayType_tag=
               {"way",
                1, {"id"},
                wayType_function,
                {&ndType_tag,&tagType_tag,NULL}};
 
 /*+ The relationType type tag. +*/
-static xmltag relationType_tag=
+static const xmltag relationType_tag=
               {"relation",
                1, {"id"},
                relationType_function,
                {&memberType_tag,&tagType_tag,NULL}};
 
 /*+ The tagType type tag. +*/
-static xmltag tagType_tag=
+static const xmltag tagType_tag=
               {"tag",
                2, {"k","v"},
                tagType_function,
                {NULL}};
 
 /*+ The ndType type tag. +*/
-static xmltag ndType_tag=
+static const xmltag ndType_tag=
               {"nd",
                1, {"ref"},
                ndType_function,
                {NULL}};
 
 /*+ The memberType type tag. +*/
-static xmltag memberType_tag=
+static const xmltag memberType_tag=
               {"member",
                3, {"type","ref","role"},
                memberType_function,
@@ -414,8 +414,8 @@ static int deleteType_function(const char *_tag_,int _type_)
 
 static int nodeType_function(const char *_tag_,int _type_,const char *id,const char *lat,const char *lon)
 {
- static int64_t llid;
- static double latitude,longitude;
+ static int64_t llid;              /* static variable to store attributes from <node> tag until </node> tag */
+ static double latitude,longitude; /* static variable to store attributes from <node> tag until </node> tag */
 
  if(_type_&XMLPARSE_TAG_START)
    {
@@ -465,7 +465,7 @@ static int nodeType_function(const char *_tag_,int _type_,const char *id,const c
 
 static int wayType_function(const char *_tag_,int _type_,const char *id)
 {
- static int64_t llid;
+ static int64_t llid; /* static variable to store attributes from <way> tag until </way> tag */
 
  if(_type_&XMLPARSE_TAG_START)
    {
@@ -511,7 +511,7 @@ static int wayType_function(const char *_tag_,int _type_,const char *id)
 
 static int relationType_function(const char *_tag_,int _type_,const char *id)
 {
- static int64_t llid;
+ static int64_t llid; /* static variable to store attributes from <relation> tag until </relation> tag */
 
  if(_type_&XMLPARSE_TAG_START)
    {
@@ -659,6 +659,10 @@ int ParseOSMFile(int fd,NodesX *OSMNodes,WaysX *OSMWays,RelationsX *OSMRelations
 
  /* Parse the file */
 
+ nnodes=0,nways=0,nrelations=0;
+
+ current_tags=NULL;
+
  retval=ParseXML(fd,xml_osm_toplevel_tags,XMLPARSE_UNKNOWN_ATTR_IGNORE);
 
  /* Cleanup the parser */
@@ -693,6 +697,10 @@ int ParseOSCFile(int fd,NodesX *OSMNodes,WaysX *OSMWays,RelationsX *OSMRelations
 
  /* Parse the file */
 
+ nnodes=0,nways=0,nrelations=0;
+
+ current_tags=NULL;
+
  retval=ParseXML(fd,xml_osc_toplevel_tags,XMLPARSE_UNKNOWN_ATTR_IGNORE);
 
  /* Cleanup the parser */
diff --git a/src/output.c b/src/output.c
index 87e9325..42ebd23 100644
--- a/src/output.c
+++ b/src/output.c
@@ -3,7 +3,7 @@
 
  Part of the Routino routing software.
  ******************/ /******************
- This file Copyright 2008-2014 Andrew M. Bishop
+ This file Copyright 2008-2015 Andrew M. Bishop
 
  This program is free software: you can redistribute it and/or modify
  it under the terms of the GNU Affero General Public License as published by
@@ -26,7 +26,6 @@
 #include <stdio.h>
 #include <math.h>
 #include <errno.h>
-#include <unistd.h>
 
 #include "types.h"
 #include "nodes.h"
@@ -39,37 +38,33 @@
 #include "results.h"
 #include "xmlparse.h"
 
+#include "routino.h"
 
+
+/*+ To help when debugging +*/
 #define DEBUG 0
 
 /* Constants */
 
-#define IMP_IGNORE      -1      /*+ Ignore this point. +*/
-#define IMP_UNIMPORTANT  0      /*+ An unimportant, intermediate, node. +*/
-#define IMP_RB_NOT_EXIT  1      /*+ A roundabout exit that is not taken. +*/
-#define IMP_JUNCT_CONT   2      /*+ An un-interesting junction where the route continues without comment. +*/
-#define IMP_CHANGE       3      /*+ The highway changes type but nothing else happens. +*/
-#define IMP_JUNCT_IMPORT 4      /*+ An interesting junction to be described. +*/
-#define IMP_RB_ENTRY     5      /*+ The entrance to a roundabout. +*/
-#define IMP_RB_EXIT      6      /*+ The exit from a roundabout. +*/
-#define IMP_MINI_RB      7      /*+ The location of a mini-roundabout. +*/
-#define IMP_UTURN        8      /*+ The location of a U-turn. +*/
-#define IMP_WAYPOINT     9      /*+ A waypoint. +*/
+#define ROUTINO_POINT_IGNORE      -1      /*+ Ignore this point. +*/
 
 
 /* Global variables */
 
 /*+ The option to calculate the quickest route insted of the shortest. +*/
-extern int option_quickest;
+int option_quickest=0;
+
+/*+ The options to select the format of the file output. +*/
+int option_file_html=0,option_file_gpx_track=0,option_file_gpx_route=0,option_file_text=0,option_file_text_all=0,option_file_stdout=0;
 
-/*+ The options to select the format of the output. +*/
-extern int option_html,option_gpx_track,option_gpx_route,option_text,option_text_all,option_stdout;
+/*+ The options to select the format of the linked list output. +*/
+int option_list_html=0,option_list_html_all=0,option_list_text=0,option_list_text_all=0;
 
 
 /* Local variables */
 
 /*+ Heuristics for determining if a junction is important. +*/
-static char junction_other_way[Highway_Count][Highway_Count]=
+static const char junction_other_way[Highway_Count][Highway_Count]=
  { /* M, T, P, S, T, U, R, S, T, C, P, S, F = Way type of route not taken */
   {   1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }, /* Motorway     */
   {   1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }, /* Trunk        */
@@ -90,6 +85,8 @@ static char junction_other_way[Highway_Count][Highway_Count]=
 /*++++++++++++++++++++++++++++++++++++++
   Print the optimum route between two nodes.
 
+  Routino_Output *PrintRoute Returns a linked list of data structures representing the route if required.
+
   Results **results The set of results to print (consecutive in array even if not consecutive waypoints).
 
   int nresults The number of results in the list.
@@ -101,13 +98,16 @@ static char junction_other_way[Highway_Count][Highway_Count]=
   Ways *ways The set of ways to use.
 
   Profile *profile The profile containing the transport type, speeds and allowed highways.
+
+  Translation *translation The set of translated strings.
   ++++++++++++++++++++++++++++++++++++++*/
 
-void PrintRoute(Results **results,int nresults,Nodes *nodes,Segments *segments,Ways *ways,Profile *profile)
+Routino_Output *PrintRoute(Results **results,int nresults,Nodes *nodes,Segments *segments,Ways *ways,Profile *profile,Translation *translation)
 {
- FILE *htmlfile=NULL,*gpxtrackfile=NULL,*gpxroutefile=NULL,*textfile=NULL,*textallfile=NULL;
+ FILE                          *htmlfile=NULL,*gpxtrackfile=NULL,*gpxroutefile=NULL,*textfile=NULL,*textallfile=NULL;
+ Routino_Output *listhead=NULL,*htmllist=NULL,                                      *textlist=NULL,*textalllist=NULL,*htmlalllist=NULL;
 
- char *prev_bearing=NULL,*prev_wayname=NULL;
+ char *prev_bearing=NULL,*prev_wayname=NULL,*prev_waynameraw=NULL;
  index_t prev_node=NO_NODE;
  distance_t cum_distance=0;
  duration_t cum_duration=0;
@@ -119,72 +119,82 @@ void PrintRoute(Results **results,int nresults,Nodes *nodes,Segments *segments,W
 
  /* Open the files */
 
- if(option_stdout)
+ if(option_file_stdout)
    {
-    if(option_html)
+    if(option_file_html)
        htmlfile    =stdout;
-    if(option_gpx_track)
+    if(option_file_gpx_track)
        gpxtrackfile=stdout;
-    if(option_gpx_route)
+    if(option_file_gpx_route)
        gpxroutefile=stdout;
-    if(option_text)
+    if(option_file_text)
        textfile    =stdout;
-    if(option_text_all)
+    if(option_file_text_all)
        textallfile =stdout;
    }
  else
    {
+#if defined(_MSC_VER) || defined(__MINGW32__)
+    const char *open_mode="wb";
+#else
+    const char *open_mode="w";
+#endif
+
     if(option_quickest==0)
       {
        /* Print the result for the shortest route */
 
-       if(option_html)
-          htmlfile    =fopen("shortest.html","w");
-       if(option_gpx_track)
-          gpxtrackfile=fopen("shortest-track.gpx","w");
-       if(option_gpx_route)
-          gpxroutefile=fopen("shortest-route.gpx","w");
-       if(option_text)
-          textfile    =fopen("shortest.txt","w");
-       if(option_text_all)
-          textallfile =fopen("shortest-all.txt","w");
-
-       if(option_html && !htmlfile)
+       if(option_file_html)
+          htmlfile    =fopen("shortest.html",open_mode);
+       if(option_file_gpx_track)
+          gpxtrackfile=fopen("shortest-track.gpx",open_mode);
+       if(option_file_gpx_route)
+          gpxroutefile=fopen("shortest-route.gpx",open_mode);
+       if(option_file_text)
+          textfile    =fopen("shortest.txt",open_mode);
+       if(option_file_text_all)
+          textallfile =fopen("shortest-all.txt",open_mode);
+
+#ifndef LIBROUTINO
+       if(option_file_html && !htmlfile)
           fprintf(stderr,"Warning: Cannot open file 'shortest.html' for writing [%s].\n",strerror(errno));
-       if(option_gpx_track && !gpxtrackfile)
+       if(option_file_gpx_track && !gpxtrackfile)
           fprintf(stderr,"Warning: Cannot open file 'shortest-track.gpx' for writing [%s].\n",strerror(errno));
-       if(option_gpx_route && !gpxroutefile)
+       if(option_file_gpx_route && !gpxroutefile)
           fprintf(stderr,"Warning: Cannot open file 'shortest-route.gpx' for writing [%s].\n",strerror(errno));
-       if(option_text && !textfile)
+       if(option_file_text && !textfile)
           fprintf(stderr,"Warning: Cannot open file 'shortest.txt' for writing [%s].\n",strerror(errno));
-       if(option_text_all && !textallfile)
+       if(option_file_text_all && !textallfile)
           fprintf(stderr,"Warning: Cannot open file 'shortest-all.txt' for writing [%s].\n",strerror(errno));
+#endif
       }
     else
       {
        /* Print the result for the quickest route */
 
-       if(option_html)
-          htmlfile    =fopen("quickest.html","w");
-       if(option_gpx_track)
-          gpxtrackfile=fopen("quickest-track.gpx","w");
-       if(option_gpx_route)
-          gpxroutefile=fopen("quickest-route.gpx","w");
-       if(option_text)
-          textfile    =fopen("quickest.txt","w");
-       if(option_text_all)
-          textallfile =fopen("quickest-all.txt","w");
-
-       if(option_html && !htmlfile)
+       if(option_file_html)
+          htmlfile    =fopen("quickest.html",open_mode);
+       if(option_file_gpx_track)
+          gpxtrackfile=fopen("quickest-track.gpx",open_mode);
+       if(option_file_gpx_route)
+          gpxroutefile=fopen("quickest-route.gpx",open_mode);
+       if(option_file_text)
+          textfile    =fopen("quickest.txt",open_mode);
+       if(option_file_text_all)
+          textallfile =fopen("quickest-all.txt",open_mode);
+
+#ifndef LIBROUTINO
+       if(option_file_html && !htmlfile)
           fprintf(stderr,"Warning: Cannot open file 'quickest.html' for writing [%s].\n",strerror(errno));
-       if(option_gpx_track && !gpxtrackfile)
+       if(option_file_gpx_track && !gpxtrackfile)
           fprintf(stderr,"Warning: Cannot open file 'quickest-track.gpx' for writing [%s].\n",strerror(errno));
-       if(option_gpx_route && !gpxroutefile)
+       if(option_file_gpx_route && !gpxroutefile)
           fprintf(stderr,"Warning: Cannot open file 'quickest-route.gpx' for writing [%s].\n",strerror(errno));
-       if(option_text && !textfile)
+       if(option_file_text && !textfile)
           fprintf(stderr,"Warning: Cannot open file 'quickest.txt' for writing [%s].\n",strerror(errno));
-       if(option_text_all && !textallfile)
+       if(option_file_text_all && !textallfile)
           fprintf(stderr,"Warning: Cannot open file 'quickest-all.txt' for writing [%s].\n",strerror(errno));
+#endif
       }
    }
 
@@ -194,15 +204,15 @@ void PrintRoute(Results **results,int nresults,Nodes *nodes,Segments *segments,W
    {
     fprintf(htmlfile,"<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\" \"http://www.w3.org/TR/html4/strict.dtd\">\n");
     fprintf(htmlfile,"<html>\n");
-    if(translate_xml_copyright_creator[0] && translate_xml_copyright_creator[1])
-       fprintf(htmlfile,"<!-- %s : %s -->\n",translate_xml_copyright_creator[0],translate_xml_copyright_creator[1]);
-    if(translate_xml_copyright_source[0] && translate_xml_copyright_source[1])
-       fprintf(htmlfile,"<!-- %s : %s -->\n",translate_xml_copyright_source[0],translate_xml_copyright_source[1]);
-    if(translate_xml_copyright_license[0] && translate_xml_copyright_license[1])
-       fprintf(htmlfile,"<!-- %s : %s -->\n",translate_xml_copyright_license[0],translate_xml_copyright_license[1]);
+    if(translation->xml_copyright_creator[0] && translation->xml_copyright_creator[1])
+       fprintf(htmlfile,"<!-- %s : %s -->\n",translation->xml_copyright_creator[0],translation->xml_copyright_creator[1]);
+    if(translation->xml_copyright_source[0] && translation->xml_copyright_source[1])
+       fprintf(htmlfile,"<!-- %s : %s -->\n",translation->xml_copyright_source[0],translation->xml_copyright_source[1]);
+    if(translation->xml_copyright_license[0] && translation->xml_copyright_license[1])
+       fprintf(htmlfile,"<!-- %s : %s -->\n",translation->xml_copyright_license[0],translation->xml_copyright_license[1]);
     fprintf(htmlfile,"<head>\n");
     fprintf(htmlfile,"<title>");
-    fprintf(htmlfile,translate_html_title,option_quickest?translate_xml_route_quickest:translate_xml_route_shortest);
+    fprintf(htmlfile,translation->html_title,option_quickest?translation->xml_route_quickest:translation->xml_route_shortest);
     fprintf(htmlfile,"</title>\n");
     fprintf(htmlfile,"<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n");
     fprintf(htmlfile,"<style type=\"text/css\">\n");
@@ -227,7 +237,7 @@ void PrintRoute(Results **results,int nresults,Nodes *nodes,Segments *segments,W
     fprintf(htmlfile,"</head>\n");
     fprintf(htmlfile,"<body>\n");
     fprintf(htmlfile,"<h1>");
-    fprintf(htmlfile,translate_html_title,option_quickest?translate_xml_route_quickest:translate_xml_route_shortest);
+    fprintf(htmlfile,translation->html_title,option_quickest?translation->xml_route_quickest:translation->xml_route_shortest);
     fprintf(htmlfile,"</h1>\n");
     fprintf(htmlfile,"<table>\n");
    }
@@ -238,13 +248,13 @@ void PrintRoute(Results **results,int nresults,Nodes *nodes,Segments *segments,W
     fprintf(gpxtrackfile,"<gpx version=\"1.1\" creator=\"Routino\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns=\"http://www.topografix.com/GPX/1/1\" xsi:schemaLocation=\"http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd\">\n");
 
     fprintf(gpxtrackfile,"<metadata>\n");
-    fprintf(gpxtrackfile,"<desc>%s : %s</desc>\n",translate_xml_copyright_creator[0],translate_xml_copyright_creator[1]);
-    if(translate_xml_copyright_source[1])
+    fprintf(gpxtrackfile,"<desc>%s : %s</desc>\n",translation->xml_copyright_creator[0],translation->xml_copyright_creator[1]);
+    if(translation->xml_copyright_source[1])
       {
-       fprintf(gpxtrackfile,"<copyright author=\"%s\">\n",translate_xml_copyright_source[1]);
+       fprintf(gpxtrackfile,"<copyright author=\"%s\">\n",translation->xml_copyright_source[1]);
 
-       if(translate_xml_copyright_license[1])
-          fprintf(gpxtrackfile,"<license>%s</license>\n",translate_xml_copyright_license[1]);
+       if(translation->xml_copyright_license[1])
+          fprintf(gpxtrackfile,"<license>%s</license>\n",translation->xml_copyright_license[1]);
 
        fprintf(gpxtrackfile,"</copyright>\n");
       }
@@ -252,10 +262,10 @@ void PrintRoute(Results **results,int nresults,Nodes *nodes,Segments *segments,W
 
     fprintf(gpxtrackfile,"<trk>\n");
     fprintf(gpxtrackfile,"<name>");
-    fprintf(gpxtrackfile,translate_gpx_name,option_quickest?translate_xml_route_quickest:translate_xml_route_shortest);
+    fprintf(gpxtrackfile,translation->gpx_name,option_quickest?translation->xml_route_quickest:translation->xml_route_shortest);
     fprintf(gpxtrackfile,"</name>\n");
     fprintf(gpxtrackfile,"<desc>");
-    fprintf(gpxtrackfile,translate_gpx_desc,option_quickest?translate_xml_route_quickest:translate_xml_route_shortest);
+    fprintf(gpxtrackfile,translation->gpx_desc,option_quickest?translation->xml_route_quickest:translation->xml_route_shortest);
     fprintf(gpxtrackfile,"</desc>\n");
    }
 
@@ -265,13 +275,13 @@ void PrintRoute(Results **results,int nresults,Nodes *nodes,Segments *segments,W
     fprintf(gpxroutefile,"<gpx version=\"1.1\" creator=\"Routino\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns=\"http://www.topografix.com/GPX/1/1\" xsi:schemaLocation=\"http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd\">\n");
 
     fprintf(gpxroutefile,"<metadata>\n");
-    fprintf(gpxroutefile,"<desc>%s : %s</desc>\n",translate_xml_copyright_creator[0],translate_xml_copyright_creator[1]);
-    if(translate_xml_copyright_source[1])
+    fprintf(gpxroutefile,"<desc>%s : %s</desc>\n",translation->xml_copyright_creator[0],translation->xml_copyright_creator[1]);
+    if(translation->xml_copyright_source[1])
       {
-       fprintf(gpxroutefile,"<copyright author=\"%s\">\n",translate_xml_copyright_source[1]);
+       fprintf(gpxroutefile,"<copyright author=\"%s\">\n",translation->xml_copyright_source[1]);
 
-       if(translate_xml_copyright_license[1])
-          fprintf(gpxroutefile,"<license>%s</license>\n",translate_xml_copyright_license[1]);
+       if(translation->xml_copyright_license[1])
+          fprintf(gpxroutefile,"<license>%s</license>\n",translation->xml_copyright_license[1]);
 
        fprintf(gpxroutefile,"</copyright>\n");
       }
@@ -279,24 +289,24 @@ void PrintRoute(Results **results,int nresults,Nodes *nodes,Segments *segments,W
 
     fprintf(gpxroutefile,"<rte>\n");
     fprintf(gpxroutefile,"<name>");
-    fprintf(gpxroutefile,translate_gpx_name,option_quickest?translate_xml_route_quickest:translate_xml_route_shortest);
+    fprintf(gpxroutefile,translation->gpx_name,option_quickest?translation->xml_route_quickest:translation->xml_route_shortest);
     fprintf(gpxroutefile,"</name>\n");
     fprintf(gpxroutefile,"<desc>");
-    fprintf(gpxroutefile,translate_gpx_desc,option_quickest?translate_xml_route_quickest:translate_xml_route_shortest);
+    fprintf(gpxroutefile,translation->gpx_desc,option_quickest?translation->xml_route_quickest:translation->xml_route_shortest);
     fprintf(gpxroutefile,"</desc>\n");
    }
 
  if(textfile)
    {
-    if(translate_raw_copyright_creator[0] && translate_raw_copyright_creator[1])
-       fprintf(textfile,"# %s : %s\n",translate_raw_copyright_creator[0],translate_raw_copyright_creator[1]);
-    if(translate_raw_copyright_source[0] && translate_raw_copyright_source[1])
-       fprintf(textfile,"# %s : %s\n",translate_raw_copyright_source[0],translate_raw_copyright_source[1]);
-    if(translate_raw_copyright_license[0] && translate_raw_copyright_license[1])
-       fprintf(textfile,"# %s : %s\n",translate_raw_copyright_license[0],translate_raw_copyright_license[1]);
-    if((translate_raw_copyright_creator[0] && translate_raw_copyright_creator[1]) ||
-       (translate_raw_copyright_source[0]  && translate_raw_copyright_source[1]) ||
-       (translate_raw_copyright_license[0] && translate_raw_copyright_license[1]))
+    if(translation->raw_copyright_creator[0] && translation->raw_copyright_creator[1])
+       fprintf(textfile,"# %s : %s\n",translation->raw_copyright_creator[0],translation->raw_copyright_creator[1]);
+    if(translation->raw_copyright_source[0] && translation->raw_copyright_source[1])
+       fprintf(textfile,"# %s : %s\n",translation->raw_copyright_source[0],translation->raw_copyright_source[1]);
+    if(translation->raw_copyright_license[0] && translation->raw_copyright_license[1])
+       fprintf(textfile,"# %s : %s\n",translation->raw_copyright_license[0],translation->raw_copyright_license[1]);
+    if((translation->raw_copyright_creator[0] && translation->raw_copyright_creator[1]) ||
+       (translation->raw_copyright_source[0]  && translation->raw_copyright_source[1]) ||
+       (translation->raw_copyright_license[0] && translation->raw_copyright_license[1]))
        fprintf(textfile,"#\n");
 
     fprintf(textfile,"#Latitude\tLongitude\tSection \tSection \tTotal   \tTotal   \tPoint\tTurn\tBearing\tHighway\n");
@@ -306,15 +316,15 @@ void PrintRoute(Results **results,int nresults,Nodes *nodes,Segments *segments,W
 
  if(textallfile)
    {
-    if(translate_raw_copyright_creator[0] && translate_raw_copyright_creator[1])
-       fprintf(textallfile,"# %s : %s\n",translate_raw_copyright_creator[0],translate_raw_copyright_creator[1]);
-    if(translate_raw_copyright_source[0] && translate_raw_copyright_source[1])
-       fprintf(textallfile,"# %s : %s\n",translate_raw_copyright_source[0],translate_raw_copyright_source[1]);
-    if(translate_raw_copyright_license[0] && translate_raw_copyright_license[1])
-       fprintf(textallfile,"# %s : %s\n",translate_raw_copyright_license[0],translate_raw_copyright_license[1]);
-    if((translate_raw_copyright_creator[0] && translate_raw_copyright_creator[1]) ||
-       (translate_raw_copyright_source[0]  && translate_raw_copyright_source[1]) ||
-       (translate_raw_copyright_license[0] && translate_raw_copyright_license[1]))
+    if(translation->raw_copyright_creator[0] && translation->raw_copyright_creator[1])
+       fprintf(textallfile,"# %s : %s\n",translation->raw_copyright_creator[0],translation->raw_copyright_creator[1]);
+    if(translation->raw_copyright_source[0] && translation->raw_copyright_source[1])
+       fprintf(textallfile,"# %s : %s\n",translation->raw_copyright_source[0],translation->raw_copyright_source[1]);
+    if(translation->raw_copyright_license[0] && translation->raw_copyright_license[1])
+       fprintf(textallfile,"# %s : %s\n",translation->raw_copyright_license[0],translation->raw_copyright_license[1]);
+    if((translation->raw_copyright_creator[0] && translation->raw_copyright_creator[1]) ||
+       (translation->raw_copyright_source[0]  && translation->raw_copyright_source[1]) ||
+       (translation->raw_copyright_license[0] && translation->raw_copyright_license[1]))
        fprintf(textallfile,"#\n");
 
     fprintf(textallfile,"#Latitude\tLongitude\t    Node\tType\tSegment\tSegment\tTotal\tTotal  \tSpeed\tBearing\tHighway\n");
@@ -322,6 +332,17 @@ void PrintRoute(Results **results,int nresults,Nodes *nodes,Segments *segments,W
                         /* "%10.6f\t%11.6f\t%8d%c\t%s\t%5.3f\t%5.2f\t%5.2f\t%5.1f\t%3d\t%4d\t%s\n" */
    }
 
+ /* Create the head of the linked list */
+
+ if(option_list_html)
+    listhead=htmllist=calloc(sizeof(Routino_Output),1);
+ if(option_list_html_all)
+    listhead=htmlalllist=htmllist=calloc(sizeof(Routino_Output),1);
+ if(option_list_text)
+    listhead=textlist=calloc(sizeof(Routino_Output),1);
+ if(option_list_text_all)
+    listhead=textalllist=calloc(sizeof(Routino_Output),1);
+
  /* Loop through all the sections of the route and print them */
 
  do
@@ -364,14 +385,14 @@ void PrintRoute(Results **results,int nresults,Nodes *nodes,Segments *segments,W
        Segment *resultsegmentp=NULL,*next_resultsegmentp=NULL;
        Way *resultwayp=NULL,*next_resultwayp=NULL;
        Result *next_result;
-       int important=IMP_UNIMPORTANT;
+       int important=ROUTINO_POINT_UNIMPORTANT;
 
        distance_t seg_distance=0;
        duration_t seg_duration=0;
        speed_t seg_speed=0;
        char *waynameraw=NULL,*wayname=NULL,*next_waynameraw=NULL,*next_wayname=NULL;
        int bearing_int=0,turn_int=0,next_bearing_int=0;
-       char *turn=NULL,*next_bearing=NULL;
+       char *turn=NULL,*turnraw=NULL,*next_bearing=NULL,*next_bearingraw=NULL;
 
        /* Calculate the information about this point */
 
@@ -454,7 +475,7 @@ void PrintRoute(Results **results,int nresults,Nodes *nodes,Segments *segments,W
              if(roundabout==0)
                {
                 roundabout++;
-                important=IMP_RB_ENTRY;
+                important=ROUTINO_POINT_RB_ENTRY;
                }
              else
                {
@@ -500,7 +521,7 @@ void PrintRoute(Results **results,int nresults,Nodes *nodes,Segments *segments,W
                          if(!(wayp->type&Highway_Roundabout))
                            {
                             roundabout++;
-                            important=IMP_RB_NOT_EXIT;
+                            important=ROUTINO_POINT_RB_NOT_EXIT;
                            }
                         }
                      }
@@ -517,24 +538,24 @@ void PrintRoute(Results **results,int nresults,Nodes *nodes,Segments *segments,W
              if(roundabout)
                {
                 roundabout++;
-                important=IMP_RB_EXIT;
+                important=ROUTINO_POINT_RB_EXIT;
                }
          }
 
        /* Decide if this is an important junction */
 
        if(point_count==0)  /* first point overall = Waypoint */
-          important=IMP_WAYPOINT;
+          important=ROUTINO_POINT_WAYPOINT;
        else if(result->next==NULL) /* Waypoint */
-          important=IMP_WAYPOINT;
+          important=ROUTINO_POINT_WAYPOINT;
        else if(first)           /* first point of a section of the route */
-          important=IMP_IGNORE;
+          important=ROUTINO_POINT_IGNORE;
        else if(roundabout)      /* roundabout */
           ;
        else if(realsegment==next_realsegment) /* U-turn */
-          important=IMP_UTURN;
+          important=ROUTINO_POINT_UTURN;
        else if(resultnodep && (resultnodep->flags&NODE_MINIRNDBT))
-          important=IMP_MINI_RB; /* mini-roundabout */
+          important=ROUTINO_POINT_MINI_RB; /* mini-roundabout */
        else
          {
           Segment *segmentp=FirstSegment(segments,resultnodep,3);
@@ -567,17 +588,17 @@ void PrintRoute(Results **results,int nresults,Nodes *nodes,Segments *segments,W
                    if(seg==next_realsegment) /* the next segment that we follow */
                      {
                       if(HIGHWAY(wayp->type)!=HIGHWAY(resultwayp->type))
-                         if(important<IMP_CHANGE)
-                            important=IMP_CHANGE;
+                         if(important<ROUTINO_POINT_CHANGE)
+                            important=ROUTINO_POINT_CHANGE;
                      }
                    else /* a segment that we don't follow */
                      {
                       if(junction_other_way[HIGHWAY(resultwayp->type)-1][HIGHWAY(wayp->type)-1])
-                         if(important<IMP_JUNCT_IMPORT)
-                            important=IMP_JUNCT_IMPORT;
+                         if(important<ROUTINO_POINT_JUNCT_IMPORT)
+                            important=ROUTINO_POINT_JUNCT_IMPORT;
 
-                      if(important<IMP_JUNCT_CONT)
-                         important=IMP_JUNCT_CONT;
+                      if(important<ROUTINO_POINT_JUNCT_CONT)
+                         important=ROUTINO_POINT_JUNCT_CONT;
                      }
                   }
                }
@@ -589,136 +610,244 @@ void PrintRoute(Results **results,int nresults,Nodes *nodes,Segments *segments,W
 
        /* Calculate the strings to be used */
 
-       if(!first && textallfile)
+       if(!first && (textallfile || textalllist))
          {
           waynameraw=WayName(ways,resultwayp);
           if(!*waynameraw)
-             waynameraw=translate_raw_highway[HIGHWAY(resultwayp->type)];
+             waynameraw=translation->raw_highway[HIGHWAY(resultwayp->type)];
 
           bearing_int=(int)BearingAngle(nodes,resultsegmentp,result->node);
 
           seg_speed=profile->speed[HIGHWAY(resultwayp->type)];
          }
 
-       if(next_result && important>IMP_JUNCT_CONT)
+       if(next_result && (important>ROUTINO_POINT_JUNCT_CONT || htmlalllist))
          {
-          if(!first && (htmlfile || textfile))
+          if(!first && (htmlfile || htmllist || textfile || textlist))
             {
              if(DISTANCE(resultsegmentp->distance)==0 || DISTANCE(next_resultsegmentp->distance)==0)
                 turn_int=0;
              else
                 turn_int=(int)TurnAngle(nodes,resultsegmentp,next_resultsegmentp,result->node);
 
-             turn=translate_xml_turn[((202+turn_int)/45)%8];
+             turn   =translation->xml_turn[((202+turn_int)/45)%8];
+             turnraw=translation->notxml_turn[((202+turn_int)/45)%8];
             }
 
-          if(gpxroutefile || htmlfile)
+          if(gpxroutefile || htmlfile || htmllist)
             {
              next_waynameraw=WayName(ways,next_resultwayp);
              if(!*next_waynameraw)
-                next_waynameraw=translate_raw_highway[HIGHWAY(next_resultwayp->type)];
+                next_waynameraw=translation->raw_highway[HIGHWAY(next_resultwayp->type)];
 
              next_wayname=ParseXML_Encode_Safe_XML(next_waynameraw);
             }
 
-          if(htmlfile || gpxroutefile || textfile)
+          if(htmlfile || htmllist || gpxroutefile || textfile || textlist)
             {
              if(!first && DISTANCE(next_resultsegmentp->distance)==0)
                 next_bearing_int=(int)BearingAngle(nodes,resultsegmentp,result->node);
              else
                 next_bearing_int=(int)BearingAngle(nodes,next_resultsegmentp,next_result->node);
 
-             next_bearing=translate_xml_heading[(4+(22+next_bearing_int)/45)%8];
+             next_bearing   =translation->xml_heading[(4+(22+next_bearing_int)/45)%8];
+             next_bearingraw=translation->notxml_heading[(4+(22+next_bearing_int)/45)%8];
             }
          }
 
        /* Print out the important points (junctions / waypoints) */
 
-       if(important>IMP_JUNCT_CONT)
+       if(important>ROUTINO_POINT_JUNCT_CONT)
          {
           if(htmlfile)
             {
              char *type;
 
-             if(important==IMP_WAYPOINT)
-                type=translate_html_waypoint;
-             else if(important==IMP_MINI_RB)
-                type=translate_html_roundabout;
+             if(important==ROUTINO_POINT_WAYPOINT)
+                type=translation->html_waypoint;
+             else if(important==ROUTINO_POINT_MINI_RB)
+                type=translation->html_roundabout;
              else
-                type=translate_html_junction;
+                type=translation->html_junction;
 
              if(point_count>0)  /* not the first point */
                {
-                /* <tr class='s'><td class='l'>Follow:<td class='r'><span class='h'>*highway name*</span> for <span class='d'>*distance* km, *time* min</span> [<span class='j'>*distance* km, *time* minutes</span>] */
-                fprintf(htmlfile,"<tr class='s'><td class='l'>%s:<td class='r'>",translate_html_segment[0]);
-                fprintf(htmlfile,translate_html_segment[1],
-                                 (roundabout>1?translate_html_roundabout:prev_wayname),
+                /* <tr class='s'><td>Follow <span class='h'>*highway name*</span> for <span class='d'>*distance* km, *time* min</span> [<span class='j'>*distance* km, *time* minutes</span>] */
+                fprintf(htmlfile,translation->html_segment,
+                                 (roundabout>1?translation->html_roundabout:prev_wayname),
                                  distance_to_km(junc_distance),duration_to_minutes(junc_duration));
-                fprintf(htmlfile," [<span class='j'>");
-                fprintf(htmlfile,translate_html_total[1],
+                fprintf(htmlfile,translation->html_subtotal,
                                  distance_to_km(cum_distance),duration_to_minutes(cum_duration));
-                fprintf(htmlfile,"</span>]\n");
                }
 
-             /* <tr class='c'><td class='l'>*N*:<td class='r'>*latitude* *longitude* */
-             fprintf(htmlfile,"<tr class='c'><td class='l'>%d:<td class='r'>%.6f %.6f\n",
+             /* <tr class='c'>*N*: *latitude* *longitude* */
+             fprintf(htmlfile,"<tr class='c'><td>%d: %.6f %.6f\n",
                               point_count+1,
                               radians_to_degrees(latitude),radians_to_degrees(longitude));
 
              if(point_count==0) /* first point */
                {
-                /* <tr class='n'><td class='l'>Start:<td class='r'>At <span class='w'>Waypoint</span>, head <span class='b'>*heading*</span> */
-                fprintf(htmlfile,"<tr class='n'><td class='l'>%s:<td class='r'>",translate_html_start[0]);
-                fprintf(htmlfile,translate_html_start[1],
-                                 translate_html_waypoint,
+                /* <tr class='n'><td>Start at <span class='w'>Waypoint</span>, head <span class='b'>*heading*</span> */
+                fprintf(htmlfile,translation->html_start,
+                                 translation->html_waypoint,
                                  next_bearing);
-                fprintf(htmlfile,"\n");
                }
              else if(next_result) /* middle point */
                {
-                if(roundabout>1 && important!=IMP_WAYPOINT)
+                if(roundabout>1 && important!=ROUTINO_POINT_WAYPOINT)
                   {
-                   /* <tr class='n'><td class='l'>At:<td class='r'>Roundabout, take <span class='t'>the *Nth* exit</span> heading <span class='b'>*heading*</span> */
-                   fprintf(htmlfile,"<tr class='n'><td class='l'>%s:<td class='r'>",translate_html_rbnode[0]);
-                   fprintf(htmlfile,translate_html_rbnode[1],
-                                    translate_html_roundabout,
-                                    translate_xml_ordinal[roundabout-2],
+                   /* <tr class='n'><td>leave roundabout, take <span class='t'>the *Nth* exit</span> heading <span class='b'>*heading*</span> */
+                   fprintf(htmlfile,translation->html_rbnode,
+                                    translation->html_roundabout,
+                                    translation->xml_ordinal[roundabout-2],
                                     next_bearing);
-                   fprintf(htmlfile,"\n");
                   }
                 else
                   {
-                   /* <tr class='n'><td class='l'>At:<td class='r'>Junction, go <span class='t'>*direction*</span> heading <span class='b'>*heading*</span> */
-                   fprintf(htmlfile,"<tr class='n'><td class='l'>%s:<td class='r'>",translate_html_node[0]);
-                   fprintf(htmlfile,translate_html_node[1],
+                   /* <tr class='n'><td>At junction, go <span class='t'>*direction*</span> heading <span class='b'>*heading*</span> */
+                   fprintf(htmlfile,translation->html_node,
                                     type,
                                     turn,
                                     next_bearing);
-                   fprintf(htmlfile,"\n");
                   }
                }
              else            /* end point */
                {
-                /* <tr class='n'><td class='l'>Stop:<td class='r'>At <span class='w'>Waypoint</span> */
-                fprintf(htmlfile,"<tr class='n'><td class='l'>%s:<td class='r'>",translate_html_stop[0]);
-                fprintf(htmlfile,translate_html_stop[1],
-                                 translate_html_waypoint);
-                fprintf(htmlfile,"\n");
-
-                /* <tr class='t'><td class='l'>Total:<td class='r'><span class='j'>*distance* km, *time* minutes</span> */
-                fprintf(htmlfile,"<tr class='t'><td class='l'>%s:<td class='r'><span class='j'>",translate_html_total[0]);
-                fprintf(htmlfile,translate_html_total[1],
+                /* <tr class='n'><td>Stop at <span class='w'>Waypoint</span> */
+                fprintf(htmlfile,translation->html_stop,
+                                 translation->html_waypoint);
+
+                /* <tr class='t'><td><span class='j'>Total *distance* km, *time* minutes</span> */
+                fprintf(htmlfile,translation->html_total,
                                  distance_to_km(cum_distance),duration_to_minutes(cum_duration));
-                fprintf(htmlfile,"</span>\n");
                }
             }
 
+          if(htmllist)
+            {
+             int strl;
+             char *type;
+
+             if(important==ROUTINO_POINT_WAYPOINT)
+                type=translation->nothtml_waypoint;
+             else if(important==ROUTINO_POINT_MINI_RB)
+                type=translation->nothtml_roundabout;
+             else
+                type=translation->nothtml_junction;
+
+             if(point_count>0)  /* not the first point */
+               {
+                /* Follow: *highway name* for *distance* km, *time* min */
+                strl=strlen(translation->nothtml_segment)+
+                     strlen(roundabout>1?translation->nothtml_roundabout:prev_waynameraw)+8+8+1;
+
+                htmllist->desc2=malloc(strl);
+
+                sprintf(htmllist->desc2,translation->nothtml_segment,
+                                        (roundabout>1?translation->nothtml_roundabout:prev_waynameraw),
+                                        distance_to_km(junc_distance),duration_to_minutes(junc_duration));
+
+                /* *distance* km, *time* minutes */
+                strl=strlen(translation->nothtml_subtotal)+8+8+1;
+
+                htmllist->desc3=malloc(strl);
+
+                sprintf(htmllist->desc3,translation->nothtml_subtotal,
+                                        distance_to_km(cum_distance),duration_to_minutes(cum_duration));
+
+                if(htmlalllist)
+                   htmllist=htmlalllist;
+
+                htmllist->next=calloc(sizeof(Routino_Output),1);
+                htmllist=htmllist->next;
+
+                if(htmlalllist)
+                   htmlalllist=htmllist;
+               }
+
+             htmllist->lon=longitude;
+             htmllist->lat=latitude;
+             htmllist->type=important;
+             htmllist->dist=distance_to_km(cum_distance);
+             htmllist->time=duration_to_minutes(cum_duration);
+
+             if(point_count==0) /* first point */
+               {
+                /* Start: At Waypoint, head *heading* */
+                strl=strlen(translation->nothtml_start)+
+                     strlen(translation->nothtml_waypoint)+strlen(next_bearingraw)+1;
+
+                htmllist->desc1=malloc(strl);
+
+                sprintf(htmllist->desc1,translation->nothtml_start,
+                                        translation->nothtml_waypoint,
+                                        next_bearingraw);
+
+                htmllist->name=strcpy(malloc(strlen(next_waynameraw)+1),next_waynameraw);
+               }
+             else if(next_result) /* middle point */
+               {
+                if(roundabout>1 && important!=ROUTINO_POINT_WAYPOINT)
+                  {
+                   /* At: Roundabout, take the *Nth* exit heading *heading* */
+                   strl=strlen(translation->nothtml_rbnode)+
+                        strlen(translation->nothtml_roundabout)+strlen(translation->notxml_ordinal[roundabout-2])+strlen(next_bearingraw)+1;
+
+                   htmllist->desc1=malloc(strl);
+
+                   sprintf(htmllist->desc1,translation->nothtml_rbnode,
+                                           translation->nothtml_roundabout,
+                                           translation->notxml_ordinal[roundabout-2],
+                                           next_bearingraw);
+                  }
+                else
+                  {
+                   /* At: Junction, go *direction* heading *heading* */
+                   strl=strlen(translation->nothtml_node)+
+                        strlen(type)+strlen(turnraw)+strlen(next_bearingraw)+1;
+
+                   htmllist->desc1=malloc(strl);
+
+                   sprintf(htmllist->desc1,translation->nothtml_node,
+                                           type,
+                                           turnraw,
+                                           next_bearingraw);
+                  }
+
+                htmllist->turn=turn_int;
+                htmllist->name=strcpy(malloc(strlen(next_waynameraw)+1),next_waynameraw);
+               }
+             else            /* end point */
+               {
+                /* Stop: At Waypoint */
+                strl=strlen(translation->nothtml_stop)+
+                     strlen(translation->nothtml_waypoint)+1;
+
+                htmllist->desc1=malloc(strl);
+
+                sprintf(htmllist->desc1,translation->nothtml_stop,
+                                        translation->nothtml_waypoint);
+
+                /* Total: *distance* km, *time* minutes */
+                strl=strlen(translation->nothtml_total)+8+8+1;
+
+                htmllist->desc2=malloc(strl);
+
+                sprintf(htmllist->desc2,translation->nothtml_total,
+                                        distance_to_km(cum_distance),duration_to_minutes(cum_duration));
+
+                htmllist->turn=turn_int;
+               }
+
+             htmllist->bearing=next_bearing_int;
+            }
+
           if(gpxroutefile)
             {
              if(point_count>0) /* not first point */
                {
                 fprintf(gpxroutefile,"<desc>");
-                fprintf(gpxroutefile,translate_gpx_step,
+                fprintf(gpxroutefile,translation->gpx_step,
                                      prev_bearing,
                                      prev_wayname,
                                      distance_to_km(junc_distance),duration_to_minutes(junc_duration));
@@ -729,28 +858,28 @@ void PrintRoute(Results **results,int nresults,Nodes *nodes,Segments *segments,W
                {
                 fprintf(gpxroutefile,"<rtept lat=\"%.6f\" lon=\"%.6f\"><name>%s</name>\n",
                                      radians_to_degrees(latitude),radians_to_degrees(longitude),
-                                     translate_gpx_start);
+                                     translation->gpx_start);
                }
              else if(!next_result) /* end point */
                {
                 fprintf(gpxroutefile,"<rtept lat=\"%.6f\" lon=\"%.6f\"><name>%s</name>\n",
                                      radians_to_degrees(latitude),radians_to_degrees(longitude),
-                                     translate_gpx_finish);
+                                     translation->gpx_finish);
                 fprintf(gpxroutefile,"<desc>");
-                fprintf(gpxroutefile,translate_gpx_final,
+                fprintf(gpxroutefile,translation->gpx_final,
                                      distance_to_km(cum_distance),duration_to_minutes(cum_duration));
                 fprintf(gpxroutefile,"</desc></rtept>\n");
                }
              else            /* middle point */
                {
-                if(important==IMP_WAYPOINT)
+                if(important==ROUTINO_POINT_WAYPOINT)
                    fprintf(gpxroutefile,"<rtept lat=\"%.6f\" lon=\"%.6f\"><name>%s%d</name>\n",
                                         radians_to_degrees(latitude),radians_to_degrees(longitude),
-                                        translate_gpx_inter,++segment_count);
+                                        translation->gpx_inter,++segment_count);
                 else
                    fprintf(gpxroutefile,"<rtept lat=\"%.6f\" lon=\"%.6f\"><name>%s%03d</name>\n",
                                         radians_to_degrees(latitude),radians_to_degrees(longitude),
-                                        translate_gpx_trip,++route_count);
+                                        translation->gpx_trip,++route_count);
                }
             }
 
@@ -758,7 +887,7 @@ void PrintRoute(Results **results,int nresults,Nodes *nodes,Segments *segments,W
             {
              char *type;
 
-             if(important==IMP_WAYPOINT)
+             if(important==ROUTINO_POINT_WAYPOINT)
                 type="Waypt";
              else
                 type="Junct";
@@ -793,10 +922,44 @@ void PrintRoute(Results **results,int nresults,Nodes *nodes,Segments *segments,W
                }
             }
 
+          if(textlist)
+            {
+             textlist->lon=longitude;
+             textlist->lat=latitude;
+             textlist->type=important;
+
+             if(point_count==0) /* first point */
+               {
+                textlist->next=calloc(sizeof(Routino_Output),1);
+
+                textlist->bearing=next_bearing_int;
+                textlist->name=strcpy(malloc(strlen(next_waynameraw)+1),next_waynameraw);
+               }
+             else if(!next_result) /* end point */
+               {
+                textlist->next=NULL;
+
+                textlist->dist=distance_to_km(cum_distance);
+                textlist->time=duration_to_minutes(cum_duration);
+               }
+             else               /* middle point */
+               {
+                textlist->next=calloc(sizeof(Routino_Output),1);
+
+                textlist->dist=distance_to_km(cum_distance);
+                textlist->time=duration_to_minutes(cum_duration);
+                textlist->turn=turn_int;
+                textlist->bearing=next_bearing_int;
+                textlist->name=strcpy(malloc(strlen(next_waynameraw)+1),next_waynameraw);
+               }
+
+             textlist=textlist->next;
+            }
+
           junc_distance=0;
           junc_duration=0;
 
-          if(htmlfile || gpxroutefile)
+          if(htmlfile || htmllist || gpxroutefile)
             {
              if(prev_wayname)
                 free(prev_wayname);
@@ -806,8 +969,13 @@ void PrintRoute(Results **results,int nresults,Nodes *nodes,Segments *segments,W
              else
                 prev_wayname=NULL;
 
-             if(next_wayname && next_wayname!=next_waynameraw)
-                free(next_wayname);
+             if(prev_waynameraw)
+                free(prev_waynameraw);
+
+             if(next_waynameraw)
+                prev_waynameraw=strcpy((char*)malloc(strlen(next_waynameraw)+1),next_waynameraw);
+             else
+                prev_waynameraw=NULL;
             }
 
           if(gpxroutefile)
@@ -816,6 +984,22 @@ void PrintRoute(Results **results,int nresults,Nodes *nodes,Segments *segments,W
           if(roundabout>1)
              roundabout=0;
          }
+       else
+         {
+          if(htmlalllist)
+            {
+             htmlalllist->next=calloc(sizeof(Routino_Output),1);
+             htmlalllist=htmlalllist->next;
+
+             htmlalllist->lon=longitude;
+             htmlalllist->lat=latitude;
+             htmlalllist->type=important;
+             htmlalllist->dist=distance_to_km(cum_distance);
+             htmlalllist->time=duration_to_minutes(cum_duration);
+             htmlalllist->turn=turn_int;
+             htmlalllist->bearing=next_bearing_int;
+            }
+         }
 
        /* Print out all of the results */
 
@@ -823,23 +1007,23 @@ void PrintRoute(Results **results,int nresults,Nodes *nodes,Segments *segments,W
           fprintf(gpxtrackfile,"<trkpt lat=\"%.6f\" lon=\"%.6f\"/>\n",
                                radians_to_degrees(latitude),radians_to_degrees(longitude));
 
-       if(important>IMP_IGNORE)
+       if(important>ROUTINO_POINT_IGNORE)
          {
           if(textallfile)
             {
              char *type;
 
-             if(important==IMP_WAYPOINT)
+             if(important==ROUTINO_POINT_WAYPOINT)
                 type="Waypt";
-             else if(important==IMP_UTURN)
+             else if(important==ROUTINO_POINT_UTURN)
                 type="U-turn";
-             else if(important==IMP_MINI_RB)
+             else if(important==ROUTINO_POINT_MINI_RB)
                 type="Mini-RB";
-             else if(important==IMP_CHANGE)
+             else if(important==ROUTINO_POINT_CHANGE)
                 type="Change";
-             else if(important==IMP_JUNCT_CONT || important==IMP_RB_NOT_EXIT)
+             else if(important==ROUTINO_POINT_JUNCT_CONT || important==ROUTINO_POINT_RB_NOT_EXIT)
                 type="Junct-";
-             else if(important==IMP_UNIMPORTANT)
+             else if(important==ROUTINO_POINT_UNIMPORTANT)
                 type="Inter";
              else
                 type="Junct";
@@ -865,6 +1049,27 @@ void PrintRoute(Results **results,int nresults,Nodes *nodes,Segments *segments,W
                                     waynameraw);
                }
             }
+
+          if(textalllist)
+            {
+             if(point_count==0) /* first point */
+                ;
+             else               /* not the first point */
+               {
+                textalllist->next=calloc(sizeof(Routino_Output),1);
+                textalllist=textalllist->next;
+
+                textalllist->dist=distance_to_km(cum_distance);
+                textalllist->time=duration_to_minutes(cum_duration);
+                textalllist->speed=speed_to_kph(seg_speed);
+                textalllist->bearing=next_bearing_int;
+                textalllist->name=strcpy(malloc(strlen(waynameraw)+1),waynameraw);
+               }
+
+             textalllist->lon=longitude;
+             textalllist->lat=latitude;
+             textalllist->type=important;
+            }
          }
 
        if(wayname && wayname!=waynameraw)
@@ -872,7 +1077,7 @@ void PrintRoute(Results **results,int nresults,Nodes *nodes,Segments *segments,W
 
        result=next_result;
 
-       if(important>IMP_JUNCT_CONT)
+       if(important>ROUTINO_POINT_JUNCT_CONT)
           point_count++;
 
        first=0;
@@ -899,18 +1104,18 @@ void PrintRoute(Results **results,int nresults,Nodes *nodes,Segments *segments,W
    {
     fprintf(htmlfile,"</table>\n");
 
-    if((translate_xml_copyright_creator[0] && translate_xml_copyright_creator[1]) ||
-       (translate_xml_copyright_source[0]  && translate_xml_copyright_source[1]) ||
-       (translate_xml_copyright_license[0] && translate_xml_copyright_license[1]))
+    if((translation->xml_copyright_creator[0] && translation->xml_copyright_creator[1]) ||
+       (translation->xml_copyright_source[0]  && translation->xml_copyright_source[1]) ||
+       (translation->xml_copyright_license[0] && translation->xml_copyright_license[1]))
       {
        fprintf(htmlfile,"<p>\n");
        fprintf(htmlfile,"<table class='c'>\n");
-       if(translate_xml_copyright_creator[0] && translate_xml_copyright_creator[1])
-          fprintf(htmlfile,"<tr><td class='l'>%s:<td class='r'>%s\n",translate_xml_copyright_creator[0],translate_xml_copyright_creator[1]);
-       if(translate_xml_copyright_source[0] && translate_xml_copyright_source[1])
-          fprintf(htmlfile,"<tr><td class='l'>%s:<td class='r'>%s\n",translate_xml_copyright_source[0],translate_xml_copyright_source[1]);
-       if(translate_xml_copyright_license[0] && translate_xml_copyright_license[1])
-          fprintf(htmlfile,"<tr><td class='l'>%s:<td class='r'>%s\n",translate_xml_copyright_license[0],translate_xml_copyright_license[1]);
+       if(translation->xml_copyright_creator[0] && translation->xml_copyright_creator[1])
+          fprintf(htmlfile,"<tr><td class='l'>%s:<td class='r'>%s\n",translation->xml_copyright_creator[0],translation->xml_copyright_creator[1]);
+       if(translation->xml_copyright_source[0] && translation->xml_copyright_source[1])
+          fprintf(htmlfile,"<tr><td class='l'>%s:<td class='r'>%s\n",translation->xml_copyright_source[0],translation->xml_copyright_source[1]);
+       if(translation->xml_copyright_license[0] && translation->xml_copyright_license[1])
+          fprintf(htmlfile,"<tr><td class='l'>%s:<td class='r'>%s\n",translation->xml_copyright_license[0],translation->xml_copyright_license[1]);
        fprintf(htmlfile,"</table>\n");
       }
 
@@ -932,7 +1137,7 @@ void PrintRoute(Results **results,int nresults,Nodes *nodes,Segments *segments,W
 
  /* Close the files */
 
- if(!option_stdout)
+ if(!option_file_stdout)
    {
     if(htmlfile)
        fclose(htmlfile);
@@ -945,4 +1150,6 @@ void PrintRoute(Results **results,int nresults,Nodes *nodes,Segments *segments,W
     if(textallfile)
        fclose(textallfile);
    }
+
+ return(listhead);
 }
diff --git a/src/planetsplitter.c b/src/planetsplitter.c
index f4a7910..f0e8ce1 100644
--- a/src/planetsplitter.c
+++ b/src/planetsplitter.c
@@ -3,7 +3,7 @@
 
  Part of the Routino routing software.
  ******************/ /******************
- This file Copyright 2008-2014 Andrew M. Bishop
+ This file Copyright 2008-2015 Andrew M. Bishop
 
  This program is free software: you can redistribute it and/or modify
  it under the terms of the GNU Affero General Public License as published by
@@ -22,10 +22,11 @@
 
 #include <stdio.h>
 #include <stdlib.h>
-#include <unistd.h>
 #include <string.h>
 #include <errno.h>
 
+#include "version.h"
+
 #include "types.h"
 #include "ways.h"
 
@@ -88,7 +89,9 @@ int main(int argc,char** argv)
 
  for(arg=1;arg<argc;arg++)
    {
-    if(!strcmp(argv[arg],"--help"))
+    if(!strcmp(argv[arg],"--version"))
+       print_usage(-1,NULL,NULL);
+    else if(!strcmp(argv[arg],"--help"))
        print_usage(1,NULL,NULL);
     else if(!strncmp(argv[arg],"--dir=",6))
        dirname=&argv[arg][6];
@@ -190,14 +193,19 @@ int main(int argc,char** argv)
       }
     else
       {
-       if(ExistsFile(FileName(dirname,prefix,"tagging.xml")))
-          tagging=FileName(dirname,prefix,"tagging.xml");
-       else if(ExistsFile(FileName(DATADIR,NULL,"tagging.xml")))
-          tagging=FileName(DATADIR,NULL,"tagging.xml");
-       else
+       tagging=FileName(dirname,prefix,"tagging.xml");
+
+       if(!ExistsFile(tagging))
          {
-          fprintf(stderr,"Error: The '--tagging' option was not used and the default 'tagging.xml' does not exist.\n");
-          exit(EXIT_FAILURE);
+          free(tagging);
+
+          tagging=FileName(ROUTINO_DATADIR,NULL,"tagging.xml");
+
+          if(!ExistsFile(tagging))
+            {
+             fprintf(stderr,"Error: The '--tagging' option was not used and the default 'tagging.xml' does not exist.\n");
+             exit(EXIT_FAILURE);
+            }
          }
       }
 
@@ -377,7 +385,7 @@ if(!option_process_only)
 
  /* Sort the turn relations geographically */
 
- SortTurnRelationListGeographically(OSMRelations,OSMNodes,OSMSegments);
+ SortTurnRelationListGeographically(OSMRelations,OSMNodes,OSMSegments,0);
 
  /* Prune unwanted nodes/segments */
 
@@ -527,7 +535,7 @@ if(!option_process_only)
 
  /* Sort the turn relations geographically */
 
- SortTurnRelationListGeographically(OSMRelations,OSMNodes,OSMSegments);
+ SortTurnRelationListGeographically(OSMRelations,OSMNodes,OSMSegments,1);
 
  /* Output the results */
 
@@ -597,7 +605,7 @@ if(!option_process_only)
 /*++++++++++++++++++++++++++++++++++++++
   Print out the usage information.
 
-  int detail The level of detail to use - 0 = low, 1 = high.
+  int detail The level of detail to use: -1 = just version number, 0 = low detail, 1 = full details.
 
   const char *argerr The argument that gave the error (if there is one).
 
@@ -606,52 +614,65 @@ if(!option_process_only)
 
 static void print_usage(int detail,const char *argerr,const char *err)
 {
- fprintf(stderr,
-         "Usage: planetsplitter [--help]\n"
-         "                      [--dir=<dirname>] [--prefix=<name>]\n"
+ if(detail<0)
+   {
+    fprintf(stderr,
+            "Routino version " ROUTINO_VERSION " " ROUTINO_URL ".\n"
+            );
+   }
+
+ if(detail>=0)
+   {
+    fprintf(stderr,
+            "Usage: planetsplitter [--version]\n"
+            "                      [--help]\n"
+            "                      [--dir=<dirname>] [--prefix=<name>]\n"
 #if defined(USE_PTHREADS) && USE_PTHREADS
-         "                      [--sort-ram-size=<size>] [--sort-threads=<number>]\n"
+            "                      [--sort-ram-size=<size>] [--sort-threads=<number>]\n"
 #else
-         "                      [--sort-ram-size=<size>]\n"
+            "                      [--sort-ram-size=<size>]\n"
 #endif
-         "                      [--tmpdir=<dirname>]\n"
-         "                      [--tagging=<filename>]\n"
-         "                      [--loggable] [--logtime] [--logmemory]\n"
-         "                      [--errorlog[=<name>]]\n"
-         "                      [--parse-only | --process-only]\n"
-         "                      [--append] [--keep] [--changes]\n"
-         "                      [--max-iterations=<number>]\n"
-         "                      [--prune-none]\n"
-         "                      [--prune-isolated=<len>]\n"
-         "                      [--prune-short=<len>]\n"
-         "                      [--prune-straight=<len>]\n"
-         "                      [<filename.osm> ... | <filename.osc> ...\n"
-         "                       | <filename.pbf> ...\n"
-         "                       | <filename.o5m> ... | <filename.o5c> ..."
+            "                      [--tmpdir=<dirname>]\n"
+            "                      [--tagging=<filename>]\n"
+            "                      [--loggable] [--logtime] [--logmemory]\n"
+            "                      [--errorlog[=<name>]]\n"
+            "                      [--parse-only | --process-only]\n"
+            "                      [--append] [--keep] [--changes]\n"
+            "                      [--max-iterations=<number>]\n"
+            "                      [--prune-none]\n"
+            "                      [--prune-isolated=<len>]\n"
+            "                      [--prune-short=<len>]\n"
+            "                      [--prune-straight=<len>]\n"
+            "                      [<filename.osm> ... | <filename.osc> ...\n"
+            "                       | <filename.pbf> ...\n"
+            "                       | <filename.o5m> ... | <filename.o5c> ..."
 #if defined(USE_BZIP2) && USE_BZIP2
-         "\n                       | <filename.(osm|osc|o5m|o5c).bz2> ..."
+            "\n                       | <filename.(osm|osc|o5m|o5c).bz2> ..."
 #endif
 #if defined(USE_GZIP) && USE_GZIP
-         "\n                       | <filename.(osm|osc|o5m|o5c).gz> ..."
+            "\n                       | <filename.(osm|osc|o5m|o5c).gz> ..."
 #endif
 #if defined(USE_XZ) && USE_XZ
-         "\n                       | <filename.(osm|osc|o5m|o5c).xz> ..."
+            "\n                       | <filename.(osm|osc|o5m|o5c).xz> ..."
 #endif
-         "]\n");
+            "]\n");
 
- if(argerr)
-    fprintf(stderr,
-            "\n"
-            "Error with command line parameter: %s\n",argerr);
+    if(argerr)
+       fprintf(stderr,
+               "\n"
+               "Error with command line parameter: %s\n",argerr);
 
- if(err)
-    fprintf(stderr,
-            "\n"
-            "Error: %s\n",err);
+    if(err)
+       fprintf(stderr,
+               "\n"
+               "Error: %s\n",err);
+   }
 
- if(detail)
+ if(detail==1)
     fprintf(stderr,
             "\n"
+            "--version                 Print the version of Routino.\n"
+            "\n"
             "--help                    Prints this information.\n"
             "\n"
             "--dir=<dirname>           The directory containing the routing database.\n"
@@ -673,7 +694,7 @@ static void print_usage(int detail,const char *argerr,const char *err)
             "--tagging=<filename>      The name of the XML file containing the tagging rules\n"
             "                          (defaults to 'tagging.xml' with '--dir' and\n"
             "                           '--prefix' options or the file installed in\n"
-            "                           '" DATADIR "').\n"
+            "                           '" ROUTINO_DATADIR "').\n"
             "\n"
             "--loggable                Print progress messages suitable for logging to file.\n"
             "--logtime                 Print the elapsed time for each processing step.\n"
diff --git a/src/profiles.c b/src/profiles.c
index 26accad..22247fa 100644
--- a/src/profiles.c
+++ b/src/profiles.c
@@ -3,7 +3,7 @@
 
  Part of the Routino routing software.
  ******************/ /******************
- This file Copyright 2008-2014 Andrew M. Bishop
+ This file Copyright 2008-2015 Andrew M. Bishop
 
  This program is free software: you can redistribute it and/or modify
  it under the terms of the GNU Affero General Public License as published by
@@ -33,7 +33,7 @@
 #include "xmlparse.h"
 
 
-/* Local variables */
+/* Local variables (re-intialised by FreeXMLProfiles() function) */
 
 /*+ The profiles that have been loaded from file. +*/
 static Profile **loaded_profiles=NULL;
@@ -42,6 +42,18 @@ static Profile **loaded_profiles=NULL;
 static int nloaded_profiles=0;
 
 
+/* Local variables (re-initialised for each file) */
+
+/*+ Store all of the profiles. +*/
+static int store_all;
+
+/*+ The profile name that is to be stored. +*/
+static const char *store_name;
+
+/*+ This current profile is to be stored. +*/
+static int store;
+
+
 /* The XML tag processing function prototypes */
 
 //static int xmlDeclaration_function(const char *_tag_,int _type_,const char *version,const char *encoding);
@@ -64,136 +76,136 @@ static int lengthType_function(const char *_tag_,int _type_,const char *limit);
 
 /* The XML tag definitions (forward declarations) */
 
-static xmltag xmlDeclaration_tag;
-static xmltag RoutinoProfilesType_tag;
-static xmltag profileType_tag;
-static xmltag speedsType_tag;
-static xmltag preferencesType_tag;
-static xmltag propertiesType_tag;
-static xmltag restrictionsType_tag;
-static xmltag speedType_tag;
-static xmltag preferenceType_tag;
-static xmltag propertyType_tag;
-static xmltag onewayType_tag;
-static xmltag turnsType_tag;
-static xmltag weightType_tag;
-static xmltag heightType_tag;
-static xmltag widthType_tag;
-static xmltag lengthType_tag;
+static const xmltag xmlDeclaration_tag;
+static const xmltag RoutinoProfilesType_tag;
+static const xmltag profileType_tag;
+static const xmltag speedsType_tag;
+static const xmltag preferencesType_tag;
+static const xmltag propertiesType_tag;
+static const xmltag restrictionsType_tag;
+static const xmltag speedType_tag;
+static const xmltag preferenceType_tag;
+static const xmltag propertyType_tag;
+static const xmltag onewayType_tag;
+static const xmltag turnsType_tag;
+static const xmltag weightType_tag;
+static const xmltag heightType_tag;
+static const xmltag widthType_tag;
+static const xmltag lengthType_tag;
 
 
 /* The XML tag definition values */
 
 /*+ The complete set of tags at the top level. +*/
-static xmltag *xml_toplevel_tags[]={&xmlDeclaration_tag,&RoutinoProfilesType_tag,NULL};
+static const xmltag * const xml_toplevel_tags[]={&xmlDeclaration_tag,&RoutinoProfilesType_tag,NULL};
 
 /*+ The xmlDeclaration type tag. +*/
-static xmltag xmlDeclaration_tag=
+static const xmltag xmlDeclaration_tag=
               {"xml",
                2, {"version","encoding"},
                NULL,
                {NULL}};
 
 /*+ The RoutinoProfilesType type tag. +*/
-static xmltag RoutinoProfilesType_tag=
+static const xmltag RoutinoProfilesType_tag=
               {"routino-profiles",
                0, {NULL},
                NULL,
                {&profileType_tag,NULL}};
 
 /*+ The profileType type tag. +*/
-static xmltag profileType_tag=
+static const xmltag profileType_tag=
               {"profile",
                2, {"name","transport"},
                profileType_function,
                {&speedsType_tag,&preferencesType_tag,&propertiesType_tag,&restrictionsType_tag,NULL}};
 
 /*+ The speedsType type tag. +*/
-static xmltag speedsType_tag=
+static const xmltag speedsType_tag=
               {"speeds",
                0, {NULL},
                NULL,
                {&speedType_tag,NULL}};
 
 /*+ The preferencesType type tag. +*/
-static xmltag preferencesType_tag=
+static const xmltag preferencesType_tag=
               {"preferences",
                0, {NULL},
                NULL,
                {&preferenceType_tag,NULL}};
 
 /*+ The propertiesType type tag. +*/
-static xmltag propertiesType_tag=
+static const xmltag propertiesType_tag=
               {"properties",
                0, {NULL},
                NULL,
                {&propertyType_tag,NULL}};
 
 /*+ The restrictionsType type tag. +*/
-static xmltag restrictionsType_tag=
+static const xmltag restrictionsType_tag=
               {"restrictions",
                0, {NULL},
                NULL,
                {&onewayType_tag,&turnsType_tag,&weightType_tag,&heightType_tag,&widthType_tag,&lengthType_tag,NULL}};
 
 /*+ The speedType type tag. +*/
-static xmltag speedType_tag=
+static const xmltag speedType_tag=
               {"speed",
                2, {"highway","kph"},
                speedType_function,
                {NULL}};
 
 /*+ The preferenceType type tag. +*/
-static xmltag preferenceType_tag=
+static const xmltag preferenceType_tag=
               {"preference",
                2, {"highway","percent"},
                preferenceType_function,
                {NULL}};
 
 /*+ The propertyType type tag. +*/
-static xmltag propertyType_tag=
+static const xmltag propertyType_tag=
               {"property",
                2, {"type","percent"},
                propertyType_function,
                {NULL}};
 
 /*+ The onewayType type tag. +*/
-static xmltag onewayType_tag=
+static const xmltag onewayType_tag=
               {"oneway",
                1, {"obey"},
                onewayType_function,
                {NULL}};
 
 /*+ The turnsType type tag. +*/
-static xmltag turnsType_tag=
+static const xmltag turnsType_tag=
               {"turns",
                1, {"obey"},
                turnsType_function,
                {NULL}};
 
 /*+ The weightType type tag. +*/
-static xmltag weightType_tag=
+static const xmltag weightType_tag=
               {"weight",
                1, {"limit"},
                weightType_function,
                {NULL}};
 
 /*+ The heightType type tag. +*/
-static xmltag heightType_tag=
+static const xmltag heightType_tag=
               {"height",
                1, {"limit"},
                heightType_function,
                {NULL}};
 
 /*+ The widthType type tag. +*/
-static xmltag widthType_tag=
+static const xmltag widthType_tag=
               {"width",
                1, {"limit"},
                widthType_function,
                {NULL}};
 
 /*+ The lengthType type tag. +*/
-static xmltag lengthType_tag=
+static const xmltag lengthType_tag=
               {"length",
                1, {"limit"},
                lengthType_function,
@@ -261,28 +273,42 @@ static int profileType_function(const char *_tag_,int _type_,const char *name,co
     int i;
 
     XMLPARSE_ASSERT_STRING(_tag_,name);
-    XMLPARSE_ASSERT_STRING(_tag_,transport);
 
-    for(i=0;i<nloaded_profiles;i++)
-       if(!strcmp(name,loaded_profiles[i]->name))
-          XMLPARSE_MESSAGE(_tag_,"profile name must be unique");
+    if(store_all)
+       store=1;
+    else if(store_name && !strcmp(store_name,name))
+       store=1;
+    else
+       store=0;
 
-    transporttype=TransportType(transport);
+    if(store)
+      {
+       for(i=0;i<nloaded_profiles;i++)
+          if(!strcmp(name,loaded_profiles[i]->name))
+             XMLPARSE_MESSAGE(_tag_,"profile name must be unique");
 
-    if(transporttype==Transport_None)
-       XMLPARSE_INVALID(_tag_,transport);
+       XMLPARSE_ASSERT_STRING(_tag_,transport);
 
-    if((nloaded_profiles%16)==0)
-       loaded_profiles=(Profile**)realloc((void*)loaded_profiles,(nloaded_profiles+16)*sizeof(Profile*));
+       transporttype=TransportType(transport);
 
-    nloaded_profiles++;
+       if(transporttype==Transport_None)
+          XMLPARSE_INVALID(_tag_,transport);
 
-    loaded_profiles[nloaded_profiles-1]=(Profile*)calloc(1,sizeof(Profile));
+       if((nloaded_profiles%16)==0)
+          loaded_profiles=(Profile**)realloc((void*)loaded_profiles,(nloaded_profiles+16)*sizeof(Profile*));
 
-    loaded_profiles[nloaded_profiles-1]->name=strcpy(malloc(strlen(name)+1),name);
-    loaded_profiles[nloaded_profiles-1]->transport=transporttype;
+       nloaded_profiles++;
+
+       loaded_profiles[nloaded_profiles-1]=(Profile*)calloc(1,sizeof(Profile));
+
+       loaded_profiles[nloaded_profiles-1]->name=strcpy(malloc(strlen(name)+1),name);
+       loaded_profiles[nloaded_profiles-1]->transport=transporttype;
+      }
    }
 
+ if(_type_&XMLPARSE_TAG_END && store)
+    store=0;
+
  return(0);
 }
 
@@ -367,7 +393,7 @@ static int profileType_function(const char *_tag_,int _type_,const char *name,co
 
 static int speedType_function(const char *_tag_,int _type_,const char *highway,const char *kph)
 {
- if(_type_&XMLPARSE_TAG_START)
+ if(_type_&XMLPARSE_TAG_START && store)
    {
     double speed;
     Highway highwaytype;
@@ -381,6 +407,9 @@ static int speedType_function(const char *_tag_,int _type_,const char *highway,c
 
     XMLPARSE_ASSERT_FLOATING(_tag_,kph); speed=atof(kph);
 
+    if(speed<0)
+       XMLPARSE_INVALID(_tag_,kph);
+
     loaded_profiles[nloaded_profiles-1]->speed[highwaytype]=kph_to_speed(speed);
    }
 
@@ -404,7 +433,7 @@ static int speedType_function(const char *_tag_,int _type_,const char *highway,c
 
 static int preferenceType_function(const char *_tag_,int _type_,const char *highway,const char *percent)
 {
- if(_type_&XMLPARSE_TAG_START)
+ if(_type_&XMLPARSE_TAG_START && store)
    {
     Highway highwaytype;
     double p;
@@ -418,7 +447,10 @@ static int preferenceType_function(const char *_tag_,int _type_,const char *high
 
     XMLPARSE_ASSERT_FLOATING(_tag_,percent); p=atof(percent);
 
-    loaded_profiles[nloaded_profiles-1]->highway[highwaytype]=p;
+    if(p<0 || p>100)
+       XMLPARSE_INVALID(_tag_,percent);
+
+    loaded_profiles[nloaded_profiles-1]->highway[highwaytype]=(score_t)(p/100);
    }
 
  return(0);
@@ -441,7 +473,7 @@ static int preferenceType_function(const char *_tag_,int _type_,const char *high
 
 static int propertyType_function(const char *_tag_,int _type_,const char *type,const char *percent)
 {
- if(_type_&XMLPARSE_TAG_START)
+ if(_type_&XMLPARSE_TAG_START && store)
    {
     Property property;
     double p;
@@ -455,7 +487,10 @@ static int propertyType_function(const char *_tag_,int _type_,const char *type,c
 
     XMLPARSE_ASSERT_FLOATING(_tag_,percent); p=atof(percent);
 
-    loaded_profiles[nloaded_profiles-1]->props_yes[property]=p;
+    if(p<0 || p>100)
+       XMLPARSE_INVALID(_tag_,percent);
+
+    loaded_profiles[nloaded_profiles-1]->props[property]=(score_t)(p/100);
    }
 
  return(0);
@@ -476,7 +511,7 @@ static int propertyType_function(const char *_tag_,int _type_,const char *type,c
 
 static int onewayType_function(const char *_tag_,int _type_,const char *obey)
 {
- if(_type_&XMLPARSE_TAG_START)
+ if(_type_&XMLPARSE_TAG_START && store)
    {
     int o;
 
@@ -503,7 +538,7 @@ static int onewayType_function(const char *_tag_,int _type_,const char *obey)
 
 static int turnsType_function(const char *_tag_,int _type_,const char *obey)
 {
- if(_type_&XMLPARSE_TAG_START)
+ if(_type_&XMLPARSE_TAG_START && store)
    {
     int o;
 
@@ -530,12 +565,15 @@ static int turnsType_function(const char *_tag_,int _type_,const char *obey)
 
 static int weightType_function(const char *_tag_,int _type_,const char *limit)
 {
- if(_type_&XMLPARSE_TAG_START)
+ if(_type_&XMLPARSE_TAG_START && store)
    {
     double l;
 
     XMLPARSE_ASSERT_FLOATING(_tag_,limit); l=atof(limit);
 
+    if(l<0)
+       XMLPARSE_INVALID(_tag_,limit);
+
     loaded_profiles[nloaded_profiles-1]->weight=tonnes_to_weight(l);
    }
 
@@ -557,12 +595,15 @@ static int weightType_function(const char *_tag_,int _type_,const char *limit)
 
 static int heightType_function(const char *_tag_,int _type_,const char *limit)
 {
- if(_type_&XMLPARSE_TAG_START)
+ if(_type_&XMLPARSE_TAG_START && store)
    {
     double l;
 
     XMLPARSE_ASSERT_FLOATING(_tag_,limit); l=atof(limit);
 
+    if(l<0)
+       XMLPARSE_INVALID(_tag_,limit);
+
     loaded_profiles[nloaded_profiles-1]->height=metres_to_height(l);
    }
 
@@ -584,12 +625,15 @@ static int heightType_function(const char *_tag_,int _type_,const char *limit)
 
 static int widthType_function(const char *_tag_,int _type_,const char *limit)
 {
- if(_type_&XMLPARSE_TAG_START)
+ if(_type_&XMLPARSE_TAG_START && store)
    {
     double l;
 
     XMLPARSE_ASSERT_FLOATING(_tag_,limit); l=atof(limit);
 
+    if(l<0)
+       XMLPARSE_INVALID(_tag_,limit);
+
     loaded_profiles[nloaded_profiles-1]->width=metres_to_width(l);
    }
 
@@ -611,12 +655,15 @@ static int widthType_function(const char *_tag_,int _type_,const char *limit)
 
 static int lengthType_function(const char *_tag_,int _type_,const char *limit)
 {
- if(_type_&XMLPARSE_TAG_START)
+ if(_type_&XMLPARSE_TAG_START && store)
    {
     double l;
 
     XMLPARSE_ASSERT_FLOATING(_tag_,limit); l=atof(limit);
 
+    if(l<0)
+       XMLPARSE_INVALID(_tag_,limit);
+
     loaded_profiles[nloaded_profiles-1]->length=metres_to_length(l);
    }
 
@@ -630,36 +677,46 @@ static int lengthType_function(const char *_tag_,int _type_,const char *limit)
   int ParseXMLProfiles Returns 0 if OK or something else in case of an error.
 
   const char *filename The name of the file to read.
+
+  const char *name The name of the profile to read.
+
+  int all Set to true to load all the profiles.
   ++++++++++++++++++++++++++++++++++++++*/
 
-int ParseXMLProfiles(const char *filename)
+int ParseXMLProfiles(const char *filename,const char *name,int all)
 {
  int fd;
  int retval;
 
  if(!ExistsFile(filename))
-   {
-    fprintf(stderr,"Error: Specified profiles file '%s' does not exist.\n",filename);
     return(1);
-   }
 
  fd=OpenFile(filename);
 
+ /* Delete the existing profiles */
+
+ if(nloaded_profiles)
+    FreeXMLProfiles();
+
+ /* Initialise variables used for parsing */
+
+ store_all=all;
+
+ store_name=name;
+
+ store=0;
+
+ /* Parse the file */
+
  retval=ParseXML(fd,xml_toplevel_tags,XMLPARSE_UNKNOWN_ATTR_ERRNONAME);
 
  CloseFile(fd);
 
  if(retval)
    {
-    int i;
-
-    for(i=0;i<nloaded_profiles;i++)
-       free(loaded_profiles[i]);
-    free(loaded_profiles);
+    FreeXMLProfiles();
 
-    nloaded_profiles=0;
-
-    return(1);
+    return(2);
    }
 
  return(0);
@@ -667,6 +724,24 @@ int ParseXMLProfiles(const char *filename)
 
 
 /*++++++++++++++++++++++++++++++++++++++
+  Return a list of the profile names that have been loaded from the XML file.
+
+  char **GetProfileNames Returns a NULL terminated list of strings - all allocated.
+  ++++++++++++++++++++++++++++++++++++++*/
+
+char **GetProfileNames(void)
+{
+ char **list=calloc(1+nloaded_profiles,sizeof(char*));
+ int i;
+
+ for(i=0;i<nloaded_profiles;i++)
+    list[i]=strcpy(malloc(strlen(loaded_profiles[i]->name)+1),loaded_profiles[i]->name);
+
+ return(list);
+}
+
+
+/*++++++++++++++++++++++++++++++++++++++
   Get a named profile.
 
   Profile *GetProfile Returns a pointer to the profile.
@@ -687,6 +762,32 @@ Profile *GetProfile(const char *name)
 
 
 /*++++++++++++++++++++++++++++++++++++++
+  Free the memory allocated when reading the profiles.
+  ++++++++++++++++++++++++++++++++++++++*/
+
+void FreeXMLProfiles(void)
+{
+ int i;
+
+ if(!loaded_profiles)
+    return;
+
+ for(i=0;i<nloaded_profiles;i++)
+   {
+    if(loaded_profiles[i]->name)
+       free(loaded_profiles[i]->name);
+
+    free(loaded_profiles[i]);
+   }
+
+ free(loaded_profiles);
+
+ loaded_profiles=NULL;
+ nloaded_profiles=0;
+}
+
+
+/*++++++++++++++++++++++++++++++++++++++
   Update a profile with the highway preference scaling factors.
 
   int UpdateProfile Returns 1 in case of a problem.
@@ -698,10 +799,9 @@ Profile *GetProfile(const char *name)
 
 int UpdateProfile(Profile *profile,Ways *ways)
 {
- score_t hmax=0;
  int i;
 
- /* Fix up the allowed transport types. */
+ /* Check the allowed transport type */
 
  profile->allow=TRANSPORTS(profile->transport);
 
@@ -710,51 +810,45 @@ int UpdateProfile(Profile *profile,Ways *ways)
 
  /* Normalise the highway preferences into the range ~0 -> 1 */
 
+ profile->max_pref=0;
+
  for(i=1;i<Highway_Count;i++)
    {
     if(profile->highway[i]<0)
        profile->highway[i]=0;
 
-    if(profile->highway[i]>hmax)
-       hmax=profile->highway[i];
-   }
-
- if(hmax==0)
-    return(1);
+    if(profile->highway[i]>1)
+       profile->highway[i]=1;
 
- for(i=1;i<Highway_Count;i++)
-   {
-    profile->highway[i]/=hmax;
-
-    if(profile->highway[i]<0.0001)
-       profile->highway[i]=0.0001;
+    if(profile->highway[i]>profile->max_pref)
+       profile->max_pref=profile->highway[i];
    }
 
  /* Normalise the property preferences into the range ~0 -> 1 */
 
  for(i=1;i<Property_Count;i++)
    {
-    if(profile->props_yes[i]<0)
-       profile->props_yes[i]=0;
+    if(profile->props[i]<0)
+       profile->props[i]=0;
 
-    if(profile->props_yes[i]>100)
-       profile->props_yes[i]=100;
+    if(profile->props[i]>1)
+       profile->props[i]=1;
 
-    profile->props_yes[i]/=100;
-    profile->props_no [i] =1-profile->props_yes[i];
+    profile->props_yes[i]=profile->props[i];
+    profile->props_no [i]=1-profile->props_yes[i];
 
     /* Squash the properties; selecting 60% preference without the sqrt() allows
        routes 50% longer on highways with the property compared to ones without.
        With the sqrt() function the ratio is only 22% allowing finer control. */
 
-    profile->props_yes[i] =sqrt(profile->props_yes[i]);
-    profile->props_no [i] =sqrt(profile->props_no[i] );
+    profile->props_yes[i]=(score_t)sqrt(profile->props_yes[i]);
+    profile->props_no [i]=(score_t)sqrt(profile->props_no[i] );
 
-    if(profile->props_yes[i]<0.01)
-       profile->props_yes[i]=0.01;
+    if(profile->props_yes[i]<0.01f)
+       profile->props_yes[i]=0.01f;
 
-    if(profile->props_no[i]<0.01)
-       profile->props_no[i]=0.01;
+    if(profile->props_no[i]<0.01f)
+       profile->props_no[i]=0.01f;
    }
 
  /* Find the fastest preferred speed */
@@ -762,16 +856,16 @@ int UpdateProfile(Profile *profile,Ways *ways)
  profile->max_speed=0;
 
  for(i=1;i<Highway_Count;i++)
+   {
+    if(profile->speed[i]<0.01f)
+       profile->speed[i]=0.01f;
+
     if(profile->speed[i]>profile->max_speed)
        profile->max_speed=profile->speed[i];
-
- if(profile->max_speed==0)
-    return(1);
+   }
 
  /* Find the most preferred property combination */
 
- profile->max_pref=1; /* since highway prefs were normalised to 1 */
-
  for(i=1;i<Property_Count;i++)
     if(ways->file.props & PROPERTIES(i))
       {
@@ -804,7 +898,7 @@ void PrintProfile(const Profile *profile)
  printf("\n");
 
  for(i=1;i<Highway_Count;i++)
-    printf("Highway %-12s: %3d%%\n",HighwayName(i),(int)profile->highway[i]);
+    printf("Highway %-12s: %3d%%\n",HighwayName(i),(int)(0.5+profile->highway[i]*100));
 
  printf("\n");
 
@@ -815,7 +909,7 @@ void PrintProfile(const Profile *profile)
  printf("\n");
 
  for(i=1;i<Property_Count;i++)
-    printf("Highway property %-12s: %3d%%\n",PropertyName(i),(int)profile->props_yes[i]);
+    printf("Highway property %-12s: %3d%%\n",PropertyName(i),(int)(0.5+profile->props[i]*100));
 
  printf("\n");
 
@@ -835,7 +929,7 @@ void PrintProfile(const Profile *profile)
 void PrintProfilesXML(void)
 {
  int i,j;
- char *padding="                ";
+ char *padding="                    ";
 
  printf("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n");
  printf("\n");
@@ -849,17 +943,17 @@ void PrintProfilesXML(void)
 
     printf("    <speeds>\n");
     for(i=1;i<Highway_Count;i++)
-       printf("      <speed highway=\"%s\"%s kph=\"%d\" />\n",HighwayName(i),padding+3+strlen(HighwayName(i)),loaded_profiles[j]->speed[i]);
+       printf("      <speed highway=\"%s\"%s kph=\"%d\" />\n",HighwayName(i),padding+8+strlen(HighwayName(i)),loaded_profiles[j]->speed[i]);
     printf("    </speeds>\n");
 
     printf("    <preferences>\n");
     for(i=1;i<Highway_Count;i++)
-       printf("      <preference highway=\"%s\"%s percent=\"%.0f\" />\n",HighwayName(i),padding+3+strlen(HighwayName(i)),loaded_profiles[j]->highway[i]);
+       printf("      <preference highway=\"%s\"%s percent=\"%.0f\" />\n",HighwayName(i),padding+8+strlen(HighwayName(i)),loaded_profiles[j]->highway[i]*100);
     printf("    </preferences>\n");
 
     printf("    <properties>\n");
     for(i=1;i<Property_Count;i++)
-       printf("      <property type=\"%s\"%s percent=\"%.0f\" />\n",PropertyName(i),padding+6+strlen(PropertyName(i)),loaded_profiles[j]->props_yes[i]);
+       printf("      <property type=\"%s\"%s percent=\"%.0f\" />\n",PropertyName(i),padding+8+strlen(PropertyName(i)),loaded_profiles[j]->props[i]*100);
     printf("    </properties>\n");
 
     printf("    <restrictions>\n");
@@ -925,7 +1019,7 @@ void PrintProfilesJSON(void)
    {
     printf("    %12s: { ",HighwayName(i));
     for(j=0;j<nloaded_profiles;j++)
-       printf("%s%s: %3d",j==0?"":", ",TransportName(loaded_profiles[j]->transport),(int)loaded_profiles[j]->highway[i]);
+       printf("%s%s: %3d",j==0?"":", ",TransportName(loaded_profiles[j]->transport),(int)(0.5+loaded_profiles[j]->highway[i]*100));
     printf(" }%s\n",i==(Highway_Count-1)?"":",");
    }
  printf("     },\n");
@@ -949,7 +1043,7 @@ void PrintProfilesJSON(void)
    {
     printf("    %13s: { ",PropertyName(i));
     for(j=0;j<nloaded_profiles;j++)
-       printf("%s%s: %3d",j==0?"":", ",TransportName(loaded_profiles[j]->transport),(int)loaded_profiles[j]->props_yes[i]);
+       printf("%s%s: %3d",j==0?"":", ",TransportName(loaded_profiles[j]->transport),(int)(0.5+loaded_profiles[j]->props[i]*100));
     printf(" }%s\n",i==(Property_Count-1)?"":",");
    }
  printf("     },\n");
@@ -1034,7 +1128,7 @@ void PrintProfilesPerl(void)
    {
     printf("  %12s => {",HighwayName(i));
     for(j=0;j<nloaded_profiles;j++)
-       printf("%s %s => %3d",j==0?"":", ",TransportName(loaded_profiles[j]->transport),(int)loaded_profiles[j]->highway[i]);
+       printf("%s %s => %3d",j==0?"":", ",TransportName(loaded_profiles[j]->transport),(int)(0.5+loaded_profiles[j]->highway[i]*100));
     printf(" }%s\n",i==(Highway_Count-1)?"":",");
    }
  printf("     },\n");
@@ -1058,7 +1152,7 @@ void PrintProfilesPerl(void)
    {
     printf("  %13s => {",PropertyName(i));
     for(j=0;j<nloaded_profiles;j++)
-       printf("%s %s => %3d",j==0?"":", ",TransportName(loaded_profiles[j]->transport),(int)loaded_profiles[j]->props_yes[i]);
+       printf("%s %s => %3d",j==0?"":", ",TransportName(loaded_profiles[j]->transport),(int)(0.5+loaded_profiles[j]->props[i]*100));
     printf(" }%s\n",i==(Property_Count-1)?"":",");
    }
  printf("     },\n");
diff --git a/src/profiles.h b/src/profiles.h
index 41975af..86b1e0f 100644
--- a/src/profiles.h
+++ b/src/profiles.h
@@ -3,7 +3,7 @@
 
  Part of the Routino routing software.
  ******************/ /******************
- This file Copyright 2008-2012 Andrew M. Bishop
+ This file Copyright 2008-2015 Andrew M. Bishop
 
  This program is free software: you can redistribute it and/or modify
  it under the terms of the GNU Affero General Public License as published by
@@ -33,18 +33,15 @@ typedef struct _Profile
 {
  char        *name;                      /*+ The name of the profile. +*/
 
- Transport    transport;                 /*+ The type of transport. +*/
+ /* The parts that are read from the XML file */
 
- transports_t allow;                     /*+ The type of transport expressed as a bitmask. +*/
+ Transport    transport;                 /*+ The type of transport. +*/
 
  score_t      highway[Highway_Count];    /*+ A floating point preference for travel on the highway. +*/
- score_t      max_pref;                  /*+ The maximum preference for any highway type. +*/
 
  speed_t      speed[Highway_Count];      /*+ The maximum speed on each type of highway. +*/
- speed_t      max_speed;                 /*+ The maximum speed for any highway type. +*/
 
- score_t      props_yes[Property_Count]; /*+ A floating point preference for ways with this attribute. +*/
- score_t      props_no [Property_Count]; /*+ A floating point preference for ways without this attribute. +*/
+ score_t      props[Property_Count];     /*+ A floating point preference for ways with this attribute. +*/
 
  int          oneway;                    /*+ A flag to indicate if one-way restrictions apply. +*/
  int          turns;                     /*+ A flag to indicate if turn restrictions apply. +*/
@@ -54,16 +51,30 @@ typedef struct _Profile
  height_t     height;                    /*+ The minimum height of vehicles on the route. +*/
  width_t      width;                     /*+ The minimum width of vehicles on the route. +*/
  length_t     length;                    /*+ The minimum length of vehicles on the route. +*/
+
+ /* The derived parts */
+
+ transports_t allow;                     /*+ The type of transport expressed as a bitmask. +*/
+
+ score_t      props_yes[Property_Count]; /*+ A floating point preference for ways with this attribute. +*/
+ score_t      props_no [Property_Count]; /*+ A floating point preference for ways without this attribute. +*/
+
+ score_t      max_pref;                  /*+ The maximum preference for any highway type. +*/
+ speed_t      max_speed;                 /*+ The maximum speed for any highway type. +*/
 }
  Profile;
 
 
 /* Functions in profiles.c */
 
-int ParseXMLProfiles(const char *filename);
+int ParseXMLProfiles(const char *filename,const char *name,int all);
+
+char **GetProfileNames(void);
 
 Profile *GetProfile(const char *name);
 
+void FreeXMLProfiles(void);
+
 int UpdateProfile(Profile *profile,Ways *ways);
 
 void PrintProfile(const Profile *profile);
diff --git a/src/relations.c b/src/relations.c
index 06a2e53..09f73bd 100644
--- a/src/relations.c
+++ b/src/relations.c
@@ -3,7 +3,7 @@
 
  Part of the Routino routing software.
  ******************/ /******************
- This file Copyright 2008-2014 Andrew M. Bishop
+ This file Copyright 2008-2015 Andrew M. Bishop
 
  This program is free software: you can redistribute it and/or modify
  it under the terms of the GNU Affero General Public License as published by
@@ -66,7 +66,9 @@ Relations *LoadRelationList(const char *filename)
  relations->troffset=sizeof(RelationsFile);
 
  relations->cache=NewTurnRelationCache();
+#ifndef LIBROUTINO
  log_malloc(relations->cache,sizeof(*relations->cache));
+#endif
 
 #endif
 
@@ -103,7 +105,9 @@ void DestroyRelationList(Relations *relations)
 
  relations->fd=SlimUnmapFile(relations->fd);
 
+#ifndef LIBROUTINO
  log_free(relations->cache);
+#endif
  DeleteTurnRelationCache(relations->cache);
 
 #endif
diff --git a/src/relations.h b/src/relations.h
index 039bd1c..0899b6e 100644
--- a/src/relations.h
+++ b/src/relations.h
@@ -3,7 +3,7 @@
 
  Part of the Routino routing software.
  ******************/ /******************
- This file Copyright 2008-2013 Andrew M. Bishop
+ This file Copyright 2008-2015 Andrew M. Bishop
 
  This program is free software: you can redistribute it and/or modify
  it under the terms of the GNU Affero General Public License as published by
@@ -62,7 +62,7 @@ struct _Relations
 
 #if !SLIM
 
- void         *data;            /*+ The memory mapped data. +*/
+ char         *data;            /*+ The memory mapped data. +*/
 
  TurnRelation *turnrelations;   /*+ An array of nodes. +*/
 
@@ -70,7 +70,7 @@ struct _Relations
 
  int           fd;              /*+ The file descriptor for the file. +*/
 
- off_t         troffset;        /*+ The offset of the turn relations in the file. +*/
+ offset_t      troffset;        /*+ The offset of the turn relations in the file. +*/
 
  TurnRelation  cached[2];       /*+ Two cached relations read from the file in slim mode. +*/
 
@@ -116,10 +116,12 @@ CACHE_DELETECACHE_PROTO(TurnRelation)
 CACHE_FETCHCACHE_PROTO(TurnRelation)
 CACHE_INVALIDATECACHE_PROTO(TurnRelation)
 
+/* Data type */
+
+CACHE_STRUCTURE(TurnRelation)
 
 /* Inline functions */
 
-CACHE_STRUCTURE(TurnRelation)
 CACHE_NEWCACHE(TurnRelation)
 CACHE_DELETECACHE(TurnRelation)
 CACHE_FETCHCACHE(TurnRelation)
diff --git a/src/relationsx.c b/src/relationsx.c
index 9455dd5..a687a1d 100644
--- a/src/relationsx.c
+++ b/src/relationsx.c
@@ -3,7 +3,7 @@
 
  Part of the Routino routing software.
  ******************/ /******************
- This file Copyright 2010-2014 Andrew M. Bishop
+ This file Copyright 2010-2015 Andrew M. Bishop
 
  This program is free software: you can redistribute it and/or modify
  it under the terms of the GNU Affero General Public License as published by
@@ -44,7 +44,7 @@ extern char *option_tmpdirname;
 
 /* Local variables */
 
-/*+ Temporary file-local variables for use by the sort functions. +*/
+/*+ Temporary file-local variables for use by the sort functions (re-initialised for each sort). +*/
 static SegmentsX *sortsegmentsx;
 static NodesX *sortnodesx;
 
@@ -83,7 +83,7 @@ RelationsX *NewRelationList(int append,int readonly)
  /* Route Relations */
 
  relationsx->rrfilename    =(char*)malloc(strlen(option_tmpdirname)+32);
- relationsx->rrfilename_tmp=(char*)malloc(strlen(option_tmpdirname)+32);
+ relationsx->rrfilename_tmp=(char*)malloc(strlen(option_tmpdirname)+48); /* allow %p to be up to 20 bytes */
 
  sprintf(relationsx->rrfilename    ,"%s/relationsx.route.parsed.mem",option_tmpdirname);
  sprintf(relationsx->rrfilename_tmp,"%s/relationsx.route.%p.tmp"    ,option_tmpdirname,(void*)relationsx);
@@ -119,7 +119,7 @@ RelationsX *NewRelationList(int append,int readonly)
  /* Turn Restriction Relations */
 
  relationsx->trfilename    =(char*)malloc(strlen(option_tmpdirname)+32);
- relationsx->trfilename_tmp=(char*)malloc(strlen(option_tmpdirname)+32);
+ relationsx->trfilename_tmp=(char*)malloc(strlen(option_tmpdirname)+48); /* allow %p to be up to 20 bytes */
 
  sprintf(relationsx->trfilename    ,"%s/relationsx.turn.parsed.mem",option_tmpdirname);
  sprintf(relationsx->trfilename_tmp,"%s/relationsx.turn.%p.tmp"    ,option_tmpdirname,(void*)relationsx);
@@ -127,7 +127,7 @@ RelationsX *NewRelationList(int append,int readonly)
  if(append || readonly)
     if(ExistsFile(relationsx->trfilename))
       {
-       off_t size;
+       offset_t size;
 
        size=SizeFile(relationsx->trfilename);
 
@@ -452,11 +452,7 @@ void SortRelationList(RelationsX* relationsx)
 
     /* Re-open the file read-only and a new file writeable */
 
-    relationsx->rrfd=ReOpenFileBuffered(relationsx->rrfilename_tmp);
-
-    DeleteFile(relationsx->rrfilename_tmp);
-
-    rrfd=OpenFileBufferedNew(relationsx->rrfilename_tmp);
+    rrfd=ReplaceFileBuffered(relationsx->rrfilename_tmp,&relationsx->rrfd);
 
     /* Sort the relations */
 
@@ -491,11 +487,7 @@ void SortRelationList(RelationsX* relationsx)
 
     /* Re-open the file read-only and a new file writeable */
 
-    relationsx->trfd=ReOpenFileBuffered(relationsx->trfilename_tmp);
-
-    DeleteFile(relationsx->trfilename_tmp);
-
-    trfd=OpenFileBufferedNew(relationsx->trfilename_tmp);
+    trfd=ReplaceFileBuffered(relationsx->trfilename_tmp,&relationsx->trfd);
 
     /* Sort the relations */
 
@@ -555,9 +547,9 @@ static int sort_route_by_id(RouteRelX *a,RouteRelX *b)
 
 static int deduplicate_route_by_id(RouteRelX *relationx,index_t index)
 {
- static relation_t previd=NO_RELATION_ID;
+ static relation_t previd; /* internal variable (reset by first call in each sort; index==0) */
 
- if(relationx->id!=previd)
+ if(index==0 || relationx->id!=previd)
    {
     previd=relationx->id;
 
@@ -607,9 +599,9 @@ static int sort_turn_by_id(TurnRelX *a,TurnRelX *b)
 
 static int deduplicate_turn_by_id(TurnRelX *relationx,index_t index)
 {
- static relation_t previd=NO_RELATION_ID;
+ static relation_t previd; /* internal variable (reset by first call in each sort; index==0) */
 
- if(relationx->id!=previd)
+ if(index==0 || relationx->id!=previd)
    {
     previd=relationx->id;
 
@@ -858,14 +850,16 @@ void ProcessTurnRelations(RelationsX *relationsx,NodesX *nodesx,SegmentsX *segme
 
  /* Re-open the file read-only and a new file writeable */
 
- relationsx->trfd=ReOpenFileBuffered(relationsx->trfilename_tmp);
-
  if(keep)
+   {
     RenameFile(relationsx->trfilename_tmp,relationsx->trfilename);
- else
-    DeleteFile(relationsx->trfilename_tmp);
 
- trfd=OpenFileBufferedNew(relationsx->trfilename_tmp);
+    relationsx->trfd=ReOpenFileBuffered(relationsx->trfilename);
+
+    trfd=OpenFileBufferedNew(relationsx->trfilename_tmp);
+   }
+ else
+    trfd=ReplaceFileBuffered(relationsx->trfilename_tmp,&relationsx->trfd);
 
  /* Process all of the relations */
 
@@ -1181,11 +1175,7 @@ void RemovePrunedTurnRelations(RelationsX *relationsx,NodesX *nodesx)
 
  /* Re-open the file read-only and a new file writeable */
 
- relationsx->trfd=ReOpenFileBuffered(relationsx->trfilename_tmp);
-
- DeleteFile(relationsx->trfilename_tmp);
-
- trfd=OpenFileBufferedNew(relationsx->trfilename_tmp);
+ trfd=ReplaceFileBuffered(relationsx->trfilename_tmp,&relationsx->trfd);
 
  /* Process all of the relations */
 
@@ -1231,11 +1221,12 @@ void RemovePrunedTurnRelations(RelationsX *relationsx,NodesX *nodesx)
   NodesX *nodesx The set of nodes to use.
 
   SegmentsX *segmentsx The set of segments to use.
+
+  int convert Set to 1 to convert the segments as well as sorting them (the second time it is called).
   ++++++++++++++++++++++++++++++++++++++*/
 
-void SortTurnRelationListGeographically(RelationsX *relationsx,NodesX *nodesx,SegmentsX *segmentsx)
+void SortTurnRelationListGeographically(RelationsX *relationsx,NodesX *nodesx,SegmentsX *segmentsx,int convert)
 {
- static int which=1;
  int trfd;
 
  if(segmentsx->number==0)
@@ -1257,18 +1248,14 @@ void SortTurnRelationListGeographically(RelationsX *relationsx,NodesX *nodesx,Se
 
  /* Re-open the file read-only and a new file writeable */
 
- relationsx->trfd=ReOpenFileBuffered(relationsx->trfilename_tmp);
-
- DeleteFile(relationsx->trfilename_tmp);
-
- trfd=OpenFileBufferedNew(relationsx->trfilename_tmp);
+ trfd=ReplaceFileBuffered(relationsx->trfilename_tmp,&relationsx->trfd);
 
  /* Update the segments with geographically sorted node indexes and sort them */
 
  sortnodesx=nodesx;
  sortsegmentsx=segmentsx;
 
- if(which==1)
+ if(!convert)
     filesort_fixed(relationsx->trfd,trfd,sizeof(TurnRelX),(int (*)(void*,index_t))geographically_index,
                                                           (int (*)(const void*,const void*))sort_by_via,
                                                           NULL);
@@ -1277,8 +1264,6 @@ void SortTurnRelationListGeographically(RelationsX *relationsx,NodesX *nodesx,Se
                                                           (int (*)(const void*,const void*))sort_by_via,
                                                           NULL);
 
- which++;
-
  /* Close the files */
 
  relationsx->trfd=CloseFileBuffered(relationsx->trfd);
diff --git a/src/relationsx.h b/src/relationsx.h
index d405980..3068f9f 100644
--- a/src/relationsx.h
+++ b/src/relationsx.h
@@ -3,7 +3,7 @@
 
  Part of the Routino routing software.
  ******************/ /******************
- This file Copyright 2010-2014 Andrew M. Bishop
+ This file Copyright 2010-2015 Andrew M. Bishop
 
  This program is free software: you can redistribute it and/or modify
  it under the terms of the GNU Affero General Public License as published by
@@ -70,7 +70,7 @@ struct _RelationsX
  index_t     rrknumber;        /*+ The number of extended route relations kept for next time. +*/
 
  relation_t *rridata;          /*+ The extended relation IDs (sorted by ID). +*/
- off_t      *rrodata;          /*+ The offset of the route relation in the file (used for error log). +*/
+ offset_t   *rrodata;          /*+ The offset of the route relation in the file (used for error log). +*/
 
  /* Turn restriction relations */
 
@@ -112,7 +112,7 @@ void ProcessTurnRelations(RelationsX *relationsx,NodesX *nodesx,SegmentsX *segme
 
 void RemovePrunedTurnRelations(RelationsX *relationsx,NodesX *nodesx);
 
-void SortTurnRelationListGeographically(RelationsX *relationsx,NodesX *nodesx,SegmentsX *segmentsx);
+void SortTurnRelationListGeographically(RelationsX *relationsx,NodesX *nodesx,SegmentsX *segmentsx,int convert);
 
 void SaveRelationList(RelationsX* relationsx,const char *filename);
 
diff --git a/src/results.c b/src/results.c
index 6e038a3..0496798 100644
--- a/src/results.c
+++ b/src/results.c
@@ -3,7 +3,7 @@
 
  Part of the Routino routing software.
  ******************/ /******************
- This file Copyright 2008-2014 Andrew M. Bishop
+ This file Copyright 2008-2015 Andrew M. Bishop
 
  This program is free software: you can redistribute it and/or modify
  it under the terms of the GNU Affero General Public License as published by
@@ -54,8 +54,10 @@ Results *NewResultsList(uint8_t log2bins)
  results->count=(uint8_t*)calloc(results->nbins,sizeof(uint8_t));
  results->point=(Result**)calloc(results->nbins,sizeof(Result*));
 
+#ifndef LIBROUTINO
  log_malloc(results->count,results->nbins*sizeof(uint8_t));
  log_malloc(results->point,results->nbins*sizeof(Result*));
+#endif
 
  results->ndata1=0;
  results->nallocdata1=0;
@@ -115,16 +117,22 @@ void FreeResultsList(Results *results)
 
  for(i=0;i<results->nallocdata1;i++)
    {
+#ifndef LIBROUTINO
     log_free(results->data[i]);
+#endif
     free(results->data[i]);
    }
 
  free(results->data);
 
+#ifndef LIBROUTINO
  log_free(results->point);
+#endif
  free(results->point);
 
+#ifndef LIBROUTINO
  log_free(results->count);
+#endif
  free(results->count);
 
  free(results);
@@ -161,8 +169,10 @@ Result *InsertResult(Results *results,index_t node,index_t segment)
     results->count=(uint8_t*)realloc((void*)results->count,results->nbins*sizeof(uint8_t));
     results->point=(Result**)realloc((void*)results->point,results->nbins*sizeof(Result*));
 
+#ifndef LIBROUTINO
     log_malloc(results->count,results->nbins*sizeof(uint8_t));
     log_malloc(results->point,results->nbins*sizeof(Result*));
+#endif
 
     for(i=0;i<results->nbins/2;i++)
       {
@@ -210,7 +220,9 @@ Result *InsertResult(Results *results,index_t node,index_t segment)
        results->nallocdata1++;
        results->data=(Result**)realloc((void*)results->data,results->nallocdata1*sizeof(Result*));
        results->data[results->nallocdata1-1]=(Result*)malloc(results->ndata2*sizeof(Result));
+#ifndef LIBROUTINO
        log_malloc(results->data[results->nallocdata1-1],results->ndata2*sizeof(Result));
+#endif
       }
    }
 
diff --git a/src/router+lib.c b/src/router+lib.c
new file mode 100644
index 0000000..e59dbc6
--- /dev/null
+++ b/src/router+lib.c
@@ -0,0 +1,599 @@
+/***************************************
+ OSM router using libroutino library.
+
+ Part of the Routino routing software.
+ ******************/ /******************
+ This file Copyright 2008-2015 Andrew M. Bishop
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ ***************************************/
+
+
+#include <unistd.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <math.h>
+
+#include "version.h"
+
+#include "routino.h"
+
+
+#ifndef M_PI
+#define M_PI 3.14159265358979323846
+#endif
+
+
+/*+ The maximum number of waypoints +*/
+#define NWAYPOINTS 99
+
+
+/* Local functions */
+
+static char *FileName(const char *dirname,const char *prefix, const char *name);
+static void print_usage(int detail,const char *argerr,const char *err);
+
+
+/*++++++++++++++++++++++++++++++++++++++
+  The main program for the router.
+  ++++++++++++++++++++++++++++++++++++++*/
+
+int main(int argc,char** argv)
+{
+ Routino_Database    *database;
+ Routino_Profile     *profile;
+ Routino_Translation *translation;
+ Routino_Waypoint   **waypoints;
+ Routino_Output      *route;
+ int                  point_used[NWAYPOINTS+1]={0};
+ double               point_lon[NWAYPOINTS+1],point_lat[NWAYPOINTS+1];
+ char                *dirname=NULL,*prefix=NULL;
+ char                *profiles=NULL,*profilename="motorcar";
+ char                *translations=NULL,*language="en";
+ int                  reverse=0,loop=0;
+ int                  quickest=0;
+ int                  html=0,gpx_track=0,gpx_route=0,text=0,text_all=0,none=0,use_stdout=0;
+ int                  list_html=0,list_html_all=0,list_text=0,list_text_all=0;
+ int                  arg;
+ int                  first_waypoint=NWAYPOINTS,last_waypoint=1,inc_dec_waypoint,waypoint,nwaypoints=0;
+ int                  routing_options;
+
+ /* Check the libroutino API version */
+
+ if(Routino_CheckAPIVersion()!=ROUTINO_ERROR_NONE)
+   {
+    fprintf(stderr,"Error: Executable version (%d) and library version (%d) do not match.\n",ROUTINO_API_VERSION,Routino_APIVersion);
+    exit(EXIT_FAILURE);
+   }
+
+ /* Parse the command line arguments */
+
+ if(argc<2)
+    print_usage(0,NULL,NULL);
+
+ /* Get the non-routing, general program options */
+
+ for(arg=1;arg<argc;arg++)
+   {
+    if(!strcmp(argv[arg],"--version"))
+       print_usage(-1,NULL,NULL);
+    else if(!strcmp(argv[arg],"--help"))
+       print_usage(1,NULL,NULL);
+    else if(!strncmp(argv[arg],"--dir=",6))
+       dirname=&argv[arg][6];
+    else if(!strncmp(argv[arg],"--prefix=",9))
+       prefix=&argv[arg][9];
+    else if(!strncmp(argv[arg],"--profiles=",11))
+       profiles=&argv[arg][11];
+    else if(!strncmp(argv[arg],"--translations=",15))
+       translations=&argv[arg][15];
+    else if(!strcmp(argv[arg],"--reverse"))
+       reverse=1;
+    else if(!strcmp(argv[arg],"--loop"))
+       loop=1;
+    else if(!strcmp(argv[arg],"--output-html"))
+       html=1;
+    else if(!strcmp(argv[arg],"--output-gpx-track"))
+       gpx_track=1;
+    else if(!strcmp(argv[arg],"--output-gpx-route"))
+       gpx_route=1;
+    else if(!strcmp(argv[arg],"--output-text"))
+       text=1;
+    else if(!strcmp(argv[arg],"--output-text-all"))
+       text_all=1;
+    else if(!strcmp(argv[arg],"--output-none"))
+       none=1;
+    else if(!strcmp(argv[arg],"--output-stdout"))
+       use_stdout=1;
+    else if(!strcmp(argv[arg],"--list-html"))
+       list_html=1;
+    else if(!strcmp(argv[arg],"--list-html-all"))
+       list_html_all=1;
+    else if(!strcmp(argv[arg],"--list-text"))
+       list_text=1;
+    else if(!strcmp(argv[arg],"--list-text-all"))
+       list_text_all=1;
+    else if(!strncmp(argv[arg],"--profile=",10))
+       profilename=&argv[arg][10];
+    else if(!strncmp(argv[arg],"--language=",11))
+       language=&argv[arg][11];
+    else if(!strcmp(argv[arg],"--shortest"))
+       quickest=0;
+    else if(!strcmp(argv[arg],"--quickest"))
+       quickest=1;
+    else if(!strncmp(argv[arg],"--lon",5) && isdigit(argv[arg][5]))
+      {
+       int point;
+       char *p=&argv[arg][6];
+
+       while(isdigit(*p)) p++;
+       if(*p++!='=')
+          print_usage(0,argv[arg],NULL);
+
+       point=atoi(&argv[arg][5]);
+       if(point>NWAYPOINTS || point_used[point]&1)
+          print_usage(0,argv[arg],NULL);
+
+       point_lon[point]=atof(p);
+       point_used[point]+=1;
+
+       if(point<first_waypoint)
+          first_waypoint=point;
+       if(point>last_waypoint)
+          last_waypoint=point;
+      }
+    else if(!strncmp(argv[arg],"--lat",5) && isdigit(argv[arg][5]))
+      {
+       int point;
+       char *p=&argv[arg][6];
+
+       while(isdigit(*p)) p++;
+       if(*p++!='=')
+          print_usage(0,argv[arg],NULL);
+
+       point=atoi(&argv[arg][5]);
+       if(point>NWAYPOINTS || point_used[point]&2)
+          print_usage(0,argv[arg],NULL);
+
+       point_lat[point]=atof(p);
+       point_used[point]+=2;
+
+       if(point<first_waypoint)
+          first_waypoint=point;
+       if(point>last_waypoint)
+          last_waypoint=point;
+      }
+    else
+       print_usage(0,argv[arg],NULL);
+
+    argv[arg]=NULL;
+   }
+
+ /* Check the specified command line options */
+
+ if(use_stdout && (html+gpx_track+gpx_route+text+text_all)!=1)
+   {
+    fprintf(stderr,"Error: The '--output-stdout' option requires exactly one other output option (but not '--output-none').\n");
+    exit(EXIT_FAILURE);
+   }
+
+ if(html==0 && gpx_track==0 && gpx_route==0 && text==0 && text_all==0 && none==0)
+    html=gpx_track=gpx_route=text=text_all=1;
+
+ /* Load in the selected profiles */
+
+ if(profiles)
+   {
+    if(access(profiles,F_OK))
+      {
+       fprintf(stderr,"Error: The '--profiles' option specifies a file that does not exist.\n");
+       exit(EXIT_FAILURE);
+      }
+   }
+ else
+   {
+    profiles=FileName(dirname,prefix,"profiles.xml");
+
+    if(access(profiles,F_OK))
+      {
+       free(profiles);
+
+       profiles=FileName(ROUTINO_DATADIR,NULL,"profiles.xml");
+
+       if(access(profiles,F_OK))
+         {
+          fprintf(stderr,"Error: The '--profiles' option was not used and the default 'profiles.xml' does not exist.\n");
+          exit(EXIT_FAILURE);
+         }
+      }
+   }
+
+ if(!profilename)
+   {
+    fprintf(stderr,"Error: A profile name must be specified.\n");
+    exit(EXIT_FAILURE);
+   }
+
+ if(Routino_ParseXMLProfiles(profiles))
+   {
+    fprintf(stderr,"Error: Cannot read the profiles in the file '%s'.\n",profiles);
+    exit(EXIT_FAILURE);
+   }
+
+ profile=Routino_GetProfile(profilename);
+
+ if(!profile)
+   {
+    char **list=Routino_GetProfileNames();
+
+    fprintf(stderr,"Error: Cannot find a profile called '%s' in '%s'.\n",profilename,profiles);
+
+    fprintf(stderr,"Profiles available are: %s",*list++);
+    while(*list)
+       fprintf(stderr,", %s",*list++);
+    fprintf(stderr,"\n");
+
+    exit(EXIT_FAILURE);
+   }
+
+ /* Load in the selected translation */
+
+  if(translations)
+    {
+     if(access(translations,F_OK))
+       {
+        fprintf(stderr,"Error: The '--translations' option specifies a file that does not exist.\n");
+        exit(EXIT_FAILURE);
+       }
+    }
+  else
+    {
+     translations=FileName(dirname,prefix,"translations.xml");
+
+     if(access(translations,F_OK))
+       {
+        free(translations);
+
+        translations=FileName(ROUTINO_DATADIR,NULL,"translations.xml");
+
+        if(access(translations,F_OK))
+          {
+           fprintf(stderr,"Error: The '--translations' option was not used and the default 'translations.xml' does not exist.\n");
+           exit(EXIT_FAILURE);
+          }
+       }
+    }
+
+  if(Routino_ParseXMLTranslations(translations))
+    {
+     fprintf(stderr,"Error: Cannot read the translations in the file '%s'.\n",translations);
+     exit(EXIT_FAILURE);
+    }
+
+  if(language)
+    {
+     translation=Routino_GetTranslation(language);
+
+     if(!translation)
+       {
+        char **list1=Routino_GetTranslationLanguages();
+        char **list2=Routino_GetTranslationLanguageFullNames();
+
+        fprintf(stderr,"Warning: Cannot find a translation called '%s' in '%s'.\n",language,translations);
+
+        fprintf(stderr,"Languages available are: %s (%s)",*list1++,*list2++);
+        while(*list1)
+           fprintf(stderr,", %s (%s)",*list1++,*list2++);
+        fprintf(stderr,"\n");
+
+        exit(EXIT_FAILURE);
+       }
+    }
+  else
+    {
+     translation=Routino_GetTranslation(""); /* first in file */
+
+     if(!translation)
+       {
+        fprintf(stderr,"Warning: No translations in '%s'.\n",translations);
+        exit(EXIT_FAILURE);
+       }
+    }
+
+ /* Check the waypoints are valid */
+
+ for(waypoint=first_waypoint;waypoint<=last_waypoint;waypoint++)
+    if(point_used[waypoint]==1 || point_used[waypoint]==2)
+       print_usage(0,NULL,"All waypoints must have latitude and longitude.");
+    else if(point_used[waypoint]==3)
+       nwaypoints++;
+
+ if(first_waypoint>=last_waypoint)
+   {
+    fprintf(stderr,"Error: At least two waypoints must be specified.\n");
+    exit(EXIT_FAILURE);
+   }
+
+ waypoints=calloc(sizeof(Routino_Waypoint*),nwaypoints+2);
+
+ /* Load in the routing database */
+
+ database=Routino_LoadDatabase(dirname,prefix);
+
+ /* Check the profile is valid for use with this database */
+
+ Routino_ValidateProfile(database,profile);
+
+ /* Check for reverse direction */
+
+ if(reverse)
+   {
+    int temp;
+
+    temp=first_waypoint;
+    first_waypoint=last_waypoint;
+    last_waypoint=temp;
+
+    last_waypoint--;
+
+    inc_dec_waypoint=-1;
+   }
+ else
+   {
+    last_waypoint++;
+
+    inc_dec_waypoint=1;
+   }
+
+ /* Loop through all waypoints */
+
+ nwaypoints=0;
+
+ for(waypoint=first_waypoint;waypoint!=last_waypoint;waypoint+=inc_dec_waypoint)
+    if(point_used[waypoint]==3)
+      {
+       waypoints[nwaypoints]=Routino_FindWaypoint(database,profile,point_lat[waypoint],point_lon[waypoint]);
+
+       if(!waypoints[nwaypoints])
+         {
+          fprintf(stderr,"Error: Cannot find node close to specified point %d.\n",waypoint);
+          exit(EXIT_FAILURE);
+         }
+
+       nwaypoints++;
+      }
+
+ if(loop)
+    waypoints[nwaypoints++]=waypoints[0];
+
+ /* Create the route */
+
+ routing_options=0;
+
+ if(quickest)
+    routing_options|=ROUTINO_ROUTE_QUICKEST;
+ else
+    routing_options|=ROUTINO_ROUTE_SHORTEST;
+
+ if(html     ) routing_options|=ROUTINO_ROUTE_FILE_HTML;
+ if(gpx_track) routing_options|=ROUTINO_ROUTE_FILE_GPX_TRACK;
+ if(gpx_route) routing_options|=ROUTINO_ROUTE_FILE_GPX_ROUTE;
+ if(text     ) routing_options|=ROUTINO_ROUTE_FILE_TEXT;
+ if(text_all ) routing_options|=ROUTINO_ROUTE_FILE_TEXT_ALL;
+
+ if(list_html)     routing_options|=ROUTINO_ROUTE_LIST_HTML;
+ if(list_html_all) routing_options|=ROUTINO_ROUTE_LIST_HTML_ALL;
+ if(list_text)     routing_options|=ROUTINO_ROUTE_LIST_TEXT;
+ if(list_text_all) routing_options|=ROUTINO_ROUTE_LIST_TEXT_ALL;
+
+ route=Routino_CalculateRoute(database,profile,translation,waypoints,nwaypoints,routing_options,NULL);
+
+ if(Routino_errno>=ROUTINO_ERROR_NO_ROUTE_1)
+   {
+    fprintf(stderr,"Error: Cannot find a route between specified waypoints.\n");
+    exit(EXIT_FAILURE);
+   }
+ else if(Routino_errno!=ROUTINO_ERROR_NONE)
+   {
+    fprintf(stderr,"Error: Internal error (%d).\n",Routino_errno);
+    exit(EXIT_FAILURE);
+   }
+
+ /* Print the list output */
+
+ if(list_html || list_html_all || list_text || list_text_all)
+   {
+    Routino_Output *list=route;
+    int first=1,last;
+
+    while(list)
+      {
+       last=list->next?0:1;
+
+       printf("----------------\n");
+       printf("Lon,Lat: %.5f, %.5f\n",(180.0/M_PI)*list->lon,(180.0/M_PI)*list->lat);
+
+       if(list_html || list_html_all || list_text || list_text_all)
+          printf("Dist,Time: %.3f km, %.1f minutes\n",list->dist,list->time);
+
+       if(list_text_all && !first)
+          printf("Speed: %.0f km/hr\n",list->speed);
+
+       printf("Point type: %d\n",list->type);
+
+       if((list_html || list_html_all || list_text) && !first && !last)
+          printf("Turn: %d degrees\n",list->turn);
+
+       if(((list_html || list_html_all || list_text) && !last) || (list_text_all && !first))
+          printf("Bearing: %d degrees\n",list->bearing);
+
+       if(((list_html || list_text) && !last) || (list_html_all && list->name) || (list_text_all && !first))
+          printf("Name: %s\n",list->name);
+
+       if(list_html || (list_html_all && list->name))
+         {
+          printf("Desc1: %s\n",list->desc1);
+          printf("Desc2: %s\n",list->desc2);
+
+          if(!last)
+             printf("Desc3: %s\n",list->desc3);
+         }
+
+       list=list->next;
+       first=0;
+      }
+   }
+
+ /* Tidy up and exit */
+
+ Routino_DeleteRoute(route);
+
+ Routino_UnloadDatabase(database);
+
+ Routino_FreeXMLProfiles();
+
+ Routino_FreeXMLTranslations();
+
+ for(waypoint=0;waypoint<nwaypoints;waypoint++)
+    free(waypoints[waypoint]);
+
+ free(waypoints);
+
+ exit(EXIT_SUCCESS);
+}
+
+
+/*++++++++++++++++++++++++++++++++++++++
+  Return a filename composed of the dirname, prefix and name.
+
+  char *FileName Returns a pointer to memory allocated to the filename.
+
+  const char *dirname The directory name.
+
+  const char *prefix The file prefix.
+
+  const char *name The main part of the name.
+  ++++++++++++++++++++++++++++++++++++++*/
+
+static char *FileName(const char *dirname,const char *prefix, const char *name)
+{
+ char *filename=(char*)malloc((dirname?strlen(dirname):0)+1+(prefix?strlen(prefix):0)+1+strlen(name)+1);
+
+ sprintf(filename,"%s%s%s%s%s",dirname?dirname:"",dirname?"/":"",prefix?prefix:"",prefix?"-":"",name);
+
+ return(filename);
+}
+
+
+/*++++++++++++++++++++++++++++++++++++++
+  Print out the usage information.
+
+  int detail The level of detail to use: -1 = just version number, 0 = low detail, 1 = full details.
+
+  const char *argerr The argument that gave the error (if there is one).
+
+  const char *err Other error message (if there is one).
+  ++++++++++++++++++++++++++++++++++++++*/
+
+static void print_usage(int detail,const char *argerr,const char *err)
+{
+ if(detail<0)
+   {
+    fprintf(stderr,
+            "Routino version " ROUTINO_VERSION " " ROUTINO_URL ".\n"
+            );
+   }
+
+ if(detail>=0)
+   {
+    fprintf(stderr,
+            "Usage: router [--version]\n"
+            "              [--help ]\n"
+            "              [--dir=<dirname>] [--prefix=<name>]\n"
+            "              [--profiles=<filename>] [--translations=<filename>]\n"
+            "              [--language=<lang>]\n"
+            "              [--output-html]\n"
+            "              [--output-gpx-track] [--output-gpx-route]\n"
+            "              [--output-text] [--output-text-all]\n"
+            "              [--output-none] [--output-stdout]\n"
+            "              [--list-html | --list-html-all |\n"
+            "               --list-text | --list-text-all]\n"
+            "              [--profile=<name>]\n"
+            "              [--shortest | --quickest]\n"
+            "              --lon1=<longitude> --lat1=<latitude>\n"
+            "              --lon2=<longitude> --lon2=<latitude>\n"
+            "              [ ... --lon99=<longitude> --lon99=<latitude>]\n"
+            "              [--reverse] [--loop]\n");
+
+    if(argerr)
+       fprintf(stderr,
+               "\n"
+               "Error with command line parameter: %s\n",argerr);
+
+    if(err)
+       fprintf(stderr,
+               "\n"
+               "Error: %s\n",err);
+   }
+
+ if(detail==1)
+    fprintf(stderr,
+            "\n"
+            "--version               Print the version of Routino.\n"
+            "\n"
+            "--help                  Prints this information.\n"
+            "\n"
+            "--dir=<dirname>         The directory containing the routing database.\n"
+            "--prefix=<name>         The filename prefix for the routing database.\n"
+            "--profiles=<filename>   The name of the XML file containing the profiles\n"
+            "                        (defaults to 'profiles.xml' with '--dir' and\n"
+            "                         '--prefix' options or the file installed in\n"
+            "                         '" ROUTINO_DATADIR "').\n"
+            "--translations=<fname>  The name of the XML file containing the translations\n"
+            "                        (defaults to 'translations.xml' with '--dir' and\n"
+            "                         '--prefix' options or the file installed in\n"
+            "                         '" ROUTINO_DATADIR "').\n"
+            "\n"
+            "--language=<lang>       Use the translations for specified language.\n"
+            "--output-html           Write an HTML description of the route.\n"
+            "--output-gpx-track      Write a GPX track file with all route points.\n"
+            "--output-gpx-route      Write a GPX route file with interesting junctions.\n"
+            "--output-text           Write a plain text file with interesting junctions.\n"
+            "--output-text-all       Write a plain text file with all route points.\n"
+            "--output-none           Don't write any output files or read any translations.\n"
+            "                        (If no output option is given then all are written.)\n"
+            "--output-stdout         Write to stdout instead of a file (requires exactly\n"
+            "                        one output format option, implies '--quiet').\n"
+            "\n"
+            "--list-html             Create an HTML list of the route.\n"
+            "--list-html-all         Create an HTML list of the route with all points.\n"
+            "--list-text             Create a plain text list with interesting junctions.\n"
+            "--list-text-all         Create a plain text list with all route points.\n"
+            "\n"
+            "--profile=<name>        Select the loaded profile with this name.\n"
+            "\n"
+            "--shortest              Find the shortest route between the waypoints.\n"
+            "--quickest              Find the quickest route between the waypoints.\n"
+            "\n"
+            "--lon<n>=<longitude>    Specify the longitude of the n'th waypoint.\n"
+            "--lat<n>=<latitude>     Specify the latitude of the n'th waypoint.\n"
+            "\n"
+            "--reverse               Find a route between the waypoints in reverse order.\n"
+            "--loop                  Find a route that returns to the first waypoint.\n"
+            "\n");
+
+ exit(!detail);
+}
diff --git a/src/router.c b/src/router.c
index 46c68a9..8cb667a 100644
--- a/src/router.c
+++ b/src/router.c
@@ -3,7 +3,7 @@
 
  Part of the Routino routing software.
  ******************/ /******************
- This file Copyright 2008-2014 Andrew M. Bishop
+ This file Copyright 2008-2015 Andrew M. Bishop
 
  This program is free software: you can redistribute it and/or modify
  it under the terms of the GNU Affero General Public License as published by
@@ -25,6 +25,8 @@
 #include <stdlib.h>
 #include <ctype.h>
 
+#include "version.h"
+
 #include "types.h"
 #include "nodes.h"
 #include "segments.h"
@@ -39,9 +41,6 @@
 #include "profiles.h"
 
 
-/*+ To help when debugging +*/
-#define DEBUG 0
-
 /*+ The maximum distance from the specified point to search for a node or segment (in km). +*/
 #define MAXSEARCH  1
 
@@ -51,21 +50,18 @@
 /*+ The option not to print any progress information. +*/
 int option_quiet=0;
 
-/*+ The options to select the format of the output. +*/
-int option_html=0,option_gpx_track=0,option_gpx_route=0,option_text=0,option_text_all=0,option_none=0,option_stdout=0;
-
 /*+ The option to calculate the quickest route insted of the shortest. +*/
-int option_quickest=0;
+extern int option_quickest;
+
+/*+ The options to select the format of the file output. +*/
+extern int option_file_html,option_file_gpx_track,option_file_gpx_route,option_file_text,option_file_text_all,option_file_stdout;
+int option_file_none=0;
 
 
 /* Local functions */
 
 static void print_usage(int detail,const char *argerr,const char *err);
 
-static Results *CalculateRoute(Nodes *nodes,Segments *segments,Ways *ways,Relations *relations,Profile *profile,
-                               index_t start_node,index_t prev_segment,index_t finish_node,
-                               int start_waypoint,int finish_waypoint);
-
 
 /*++++++++++++++++++++++++++++++++++++++
   The main program for the router.
@@ -73,30 +69,29 @@ static Results *CalculateRoute(Nodes *nodes,Segments *segments,Ways *ways,Relati
 
 int main(int argc,char** argv)
 {
- Nodes     *OSMNodes;
- Segments  *OSMSegments;
- Ways      *OSMWays;
- Relations *OSMRelations;
- Results   *results[NWAYPOINTS+1]={NULL};
- int        point_used[NWAYPOINTS+1]={0};
- double     point_lon[NWAYPOINTS+1],point_lat[NWAYPOINTS+1];
- double     heading=-999;
- int        help_profile=0,help_profile_xml=0,help_profile_json=0,help_profile_pl=0;
- char      *dirname=NULL,*prefix=NULL;
- char      *profiles=NULL,*profilename=NULL;
- char      *translations=NULL,*language=NULL;
- int        exactnodes=0,reverse=0,loop=0;
- Transport  transport=Transport_None;
- Profile   *profile=NULL;
- index_t    start_node,finish_node=NO_NODE,first_node=NO_NODE;
- index_t    join_segment=NO_SEGMENT;
- int        arg,nresults=0;
- waypoint_t start_waypoint,finish_waypoint=NO_WAYPOINT;
- waypoint_t first_waypoint=NWAYPOINTS,last_waypoint=1,inc_dec_waypoint,waypoint;
-
-#if !DEBUG
+ Nodes       *OSMNodes;
+ Segments    *OSMSegments;
+ Ways        *OSMWays;
+ Relations   *OSMRelations;
+ Results     *results[NWAYPOINTS+1]={NULL};
+ int          point_used[NWAYPOINTS+1]={0};
+ double       point_lon[NWAYPOINTS+1],point_lat[NWAYPOINTS+1];
+ double       heading=-999;
+ int          help_profile=0,help_profile_xml=0,help_profile_json=0,help_profile_pl=0;
+ char        *dirname=NULL,*prefix=NULL;
+ char        *profiles=NULL,*profilename=NULL;
+ char        *translations=NULL,*language=NULL;
+ int          exactnodes=0,reverse=0,loop=0;
+ Transport    transport=Transport_None;
+ Profile     *profile=NULL;
+ Translation *translation=NULL;
+ index_t      start_node,finish_node=NO_NODE,first_node=NO_NODE;
+ index_t      join_segment=NO_SEGMENT;
+ int          arg,nresults=0;
+ waypoint_t   start_waypoint,finish_waypoint=NO_WAYPOINT;
+ waypoint_t   first_waypoint=NWAYPOINTS,last_waypoint=1,inc_dec_waypoint,waypoint;
+
  printf_program_start();
-#endif
 
  /* Parse the command line arguments */
 
@@ -107,7 +102,9 @@ int main(int argc,char** argv)
 
  for(arg=1;arg<argc;arg++)
    {
-    if(!strcmp(argv[arg],"--help"))
+    if(!strcmp(argv[arg],"--version"))
+       print_usage(-1,NULL,NULL);
+    else if(!strcmp(argv[arg],"--help"))
        print_usage(1,NULL,NULL);
     else if(!strcmp(argv[arg],"--help-profile"))
        help_profile=1;
@@ -140,19 +137,19 @@ int main(int argc,char** argv)
     else if(!strcmp(argv[arg],"--logmemory"))
        option_logmemory=1;
     else if(!strcmp(argv[arg],"--output-html"))
-       option_html=1;
+       option_file_html=1;
     else if(!strcmp(argv[arg],"--output-gpx-track"))
-       option_gpx_track=1;
+       option_file_gpx_track=1;
     else if(!strcmp(argv[arg],"--output-gpx-route"))
-       option_gpx_route=1;
+       option_file_gpx_route=1;
     else if(!strcmp(argv[arg],"--output-text"))
-       option_text=1;
+       option_file_text=1;
     else if(!strcmp(argv[arg],"--output-text-all"))
-       option_text_all=1;
+       option_file_text_all=1;
     else if(!strcmp(argv[arg],"--output-none"))
-       option_none=1;
+       option_file_none=1;
     else if(!strcmp(argv[arg],"--output-stdout"))
-      { option_stdout=1; option_quiet=1; }
+      { option_file_stdout=1; option_quiet=1; }
     else if(!strncmp(argv[arg],"--profile=",10))
        profilename=&argv[arg][10];
     else if(!strncmp(argv[arg],"--language=",11))
@@ -172,13 +169,16 @@ int main(int argc,char** argv)
 
  /* Check the specified command line options */
 
- if(option_stdout && (option_html+option_gpx_track+option_gpx_route+option_text+option_text_all)!=1)
+ if(option_file_stdout && (option_file_html+option_file_gpx_track+option_file_gpx_route+option_file_text+option_file_text_all)!=1)
    {
     fprintf(stderr,"Error: The '--output-stdout' option requires exactly one other output option (but not '--output-none').\n");
     exit(EXIT_FAILURE);
    }
 
- /* Load in the profiles */
+ if(option_file_html==0 && option_file_gpx_track==0 && option_file_gpx_route==0 && option_file_text==0 && option_file_text_all==0 && option_file_none==0)
+    option_file_html=option_file_gpx_track=option_file_gpx_route=option_file_text=option_file_text_all=1;
+
+ /* Load in the selected profiles */
 
  if(transport==Transport_None)
     transport=Transport_Motorcar;
@@ -193,40 +193,37 @@ int main(int argc,char** argv)
    }
  else
    {
-    if(ExistsFile(FileName(dirname,prefix,"profiles.xml")))
-       profiles=FileName(dirname,prefix,"profiles.xml");
-    else if(ExistsFile(FileName(DATADIR,NULL,"profiles.xml")))
-       profiles=FileName(DATADIR,NULL,"profiles.xml");
-    else
+    profiles=FileName(dirname,prefix,"profiles.xml");
+
+    if(!ExistsFile(profiles))
       {
-       fprintf(stderr,"Error: The '--profiles' option was not used and the default 'profiles.xml' does not exist.\n");
-       exit(EXIT_FAILURE);
+       free(profiles);
+
+       profiles=FileName(ROUTINO_DATADIR,NULL,"profiles.xml");
+
+       if(!ExistsFile(profiles))
+         {
+          fprintf(stderr,"Error: The '--profiles' option was not used and the default 'profiles.xml' does not exist.\n");
+          exit(EXIT_FAILURE);
+         }
       }
    }
 
- if(ParseXMLProfiles(profiles))
+ if(!profilename)
+    profilename=(char*)TransportName(transport);
+
+ if(ParseXMLProfiles(profiles,profilename,(help_profile_xml|help_profile_json|help_profile_pl)))
    {
     fprintf(stderr,"Error: Cannot read the profiles in the file '%s'.\n",profiles);
     exit(EXIT_FAILURE);
    }
 
- /* Choose the selected profile. */
-
- if(profilename)
-   {
-    profile=GetProfile(profilename);
-
-    if(!profile)
-      {
-       fprintf(stderr,"Error: Cannot find a profile called '%s' in '%s'.\n",profilename,profiles);
-       exit(EXIT_FAILURE);
-      }
-   }
- else
-    profile=GetProfile(TransportName(transport));
+ profile=GetProfile(profilename);
 
  if(!profile)
    {
+    fprintf(stderr,"Error: Cannot find a profile called '%s' in '%s'.\n",profilename,profiles);
+
     profile=(Profile*)calloc(1,sizeof(Profile));
     profile->transport=transport;
    }
@@ -249,11 +246,11 @@ int main(int argc,char** argv)
        while(isdigit(*p)) p++;
        if(*p++!='=')
           print_usage(0,argv[arg],NULL);
- 
+
        point=atoi(&argv[arg][5]);
        if(point>NWAYPOINTS || point_used[point]&1)
           print_usage(0,argv[arg],NULL);
- 
+
        point_lon[point]=degrees_to_radians(atof(p));
        point_used[point]+=1;
 
@@ -270,11 +267,11 @@ int main(int argc,char** argv)
        while(isdigit(*p)) p++;
        if(*p++!='=')
           print_usage(0,argv[arg],NULL);
- 
+
        point=atoi(&argv[arg][5]);
        if(point>NWAYPOINTS || point_used[point]&2)
           print_usage(0,argv[arg],NULL);
- 
+
        point_lat[point]=degrees_to_radians(atof(p));
        point_used[point]+=2;
 
@@ -301,6 +298,7 @@ int main(int argc,char** argv)
        Highway highway;
        char *equal=strchr(argv[arg],'=');
        char *string;
+       double p;
 
        if(!equal)
            print_usage(0,argv[arg],NULL);
@@ -313,7 +311,12 @@ int main(int argc,char** argv)
        if(highway==Highway_None)
           print_usage(0,argv[arg],NULL);
 
-       profile->highway[highway]=atof(equal+1);
+       p=atof(equal+1);
+
+       if(p<0 || p>100)
+          print_usage(0,argv[arg],NULL);
+
+       profile->highway[highway]=(score_t)(p/100);
 
        free(string);
       }
@@ -322,6 +325,7 @@ int main(int argc,char** argv)
        Highway highway;
        char *equal=strchr(argv[arg],'=');
        char *string;
+       double s;
 
        if(!equal)
           print_usage(0,argv[arg],NULL);
@@ -334,7 +338,12 @@ int main(int argc,char** argv)
        if(highway==Highway_None)
           print_usage(0,argv[arg],NULL);
 
-       profile->speed[highway]=kph_to_speed(atof(equal+1));
+       s=atof(equal+1);
+
+       if(s<0)
+          print_usage(0,argv[arg],NULL);
+
+       profile->speed[highway]=kph_to_speed(s);
 
        free(string);
       }
@@ -343,6 +352,7 @@ int main(int argc,char** argv)
        Property property;
        char *equal=strchr(argv[arg],'=');
        char *string;
+       double p;
 
        if(!equal)
           print_usage(0,argv[arg],NULL);
@@ -355,7 +365,12 @@ int main(int argc,char** argv)
        if(property==Property_None)
           print_usage(0,argv[arg],NULL);
 
-       profile->props_yes[property]=atof(equal+1);
+       p=atof(equal+1);
+
+       if(p<0 || p>100)
+          print_usage(0,argv[arg],NULL);
+
+       profile->props[property]=(score_t)(p/100);
 
        free(string);
       }
@@ -411,12 +426,9 @@ int main(int argc,char** argv)
  if(first_waypoint>=last_waypoint)
     print_usage(0,NULL,"At least two waypoints must be specified.");
 
- /* Load in the translations */
+ /* Load in the selected translation */
 
- if(option_html==0 && option_gpx_track==0 && option_gpx_route==0 && option_text==0 && option_text_all==0 && option_none==0)
-    option_html=option_gpx_track=option_gpx_route=option_text=option_text_all=1;
-
- if(option_html || option_gpx_route || option_gpx_track)
+ if(option_file_html || option_file_gpx_route || option_file_gpx_track || option_file_text || option_file_text_all)
    {
     if(translations)
       {
@@ -428,30 +440,54 @@ int main(int argc,char** argv)
       }
     else
       {
-       if(ExistsFile(FileName(dirname,prefix,"translations.xml")))
-          translations=FileName(dirname,prefix,"translations.xml");
-       else if(ExistsFile(FileName(DATADIR,NULL,"translations.xml")))
-          translations=FileName(DATADIR,NULL,"translations.xml");
-       else
+       translations=FileName(dirname,prefix,"translations.xml");
+
+       if(!ExistsFile(translations))
          {
-          fprintf(stderr,"Error: The '--translations' option was not used and the default 'translations.xml' does not exist.\n");
-          exit(EXIT_FAILURE);
+          free(translations);
+
+          translations=FileName(ROUTINO_DATADIR,NULL,"translations.xml");
+
+          if(!ExistsFile(translations))
+            {
+             fprintf(stderr,"Error: The '--translations' option was not used and the default 'translations.xml' does not exist.\n");
+             exit(EXIT_FAILURE);
+            }
          }
       }
 
-    if(ParseXMLTranslations(translations,language))
+    if(ParseXMLTranslations(translations,language,0))
       {
        fprintf(stderr,"Error: Cannot read the translations in the file '%s'.\n",translations);
        exit(EXIT_FAILURE);
       }
+
+    if(language)
+      {
+       translation=GetTranslation(language);
+
+       if(!translation)
+         {
+          fprintf(stderr,"Warning: Cannot find a translation called '%s' in '%s'.\n",language,translations);
+          exit(EXIT_FAILURE);
+         }
+      }
+    else
+      {
+       translation=GetTranslation("");
+
+       if(!translation)
+         {
+          fprintf(stderr,"Warning: No translations in '%s'.\n",translations);
+          exit(EXIT_FAILURE);
+         }
+      }
    }
 
  /* Load in the data - Note: No error checking because Load*List() will call exit() in case of an error. */
 
-#if !DEBUG
  if(!option_quiet)
     printf_first("Loading Files:");
-#endif
 
  OSMNodes=LoadNodeList(FileName(dirname,prefix,"nodes.mem"));
 
@@ -461,10 +497,8 @@ int main(int argc,char** argv)
 
  OSMRelations=LoadRelationList(FileName(dirname,prefix,"relations.mem"));
 
-#if !DEBUG
  if(!option_quiet)
     printf_last("Loaded Files: nodes, segments, ways & relations");
-#endif
 
  /* Check the profile compared to the types of ways available */
 
@@ -507,10 +541,8 @@ int main(int argc,char** argv)
     if(point_used[waypoint]!=3)
        continue;
 
-#if !DEBUG
     if(!option_quiet)
        printf_first("Finding Closest Point: Waypoint %d",waypoint);
-#endif
 
     /* Find the closest point */
 
@@ -533,10 +565,8 @@ int main(int argc,char** argv)
           finish_node=NO_NODE;
       }
 
-#if !DEBUG
     if(!option_quiet)
        printf_last("Found Closest Point: Waypoint %d",waypoint);
-#endif
 
     if(finish_node==NO_NODE)
       {
@@ -578,6 +608,9 @@ int main(int argc,char** argv)
 
     results[nresults]=CalculateRoute(OSMNodes,OSMSegments,OSMWays,OSMRelations,profile,start_node,join_segment,finish_node,start_waypoint,finish_waypoint);
 
+    if(!results[nresults])
+       exit(EXIT_FAILURE);
+
     join_segment=results[nresults]->last_segment;
 
     nresults++;
@@ -600,18 +633,14 @@ int main(int argc,char** argv)
 
  /* Print out the combined route */
 
-#if !DEBUG
  if(!option_quiet)
     printf_first("Generating Result Outputs");
-#endif
 
- if(!option_none)
-    PrintRoute(results,nresults,OSMNodes,OSMSegments,OSMWays,profile);
+ if(!option_file_none)
+    PrintRoute(results,nresults,OSMNodes,OSMSegments,OSMWays,profile,translation);
 
-#if !DEBUG
  if(!option_quiet)
     printf_last("Generated Result Outputs");
-#endif
 
  /* Destroy the remaining results lists and data structures */
 
@@ -625,204 +654,23 @@ int main(int argc,char** argv)
  DestroyWayList(OSMWays);
  DestroyRelationList(OSMRelations);
 
+ FreeXMLProfiles();
+
+ FreeXMLTranslations();
+
 #endif
 
-#if !DEBUG
  if(!option_quiet)
     printf_program_end();
-#endif
 
  exit(EXIT_SUCCESS);
 }
 
 
 /*++++++++++++++++++++++++++++++++++++++
-  Find a complete route from a specified node to another node.
-
-  Results *CalculateRoute Returns a set of results.
-
-  Nodes *nodes The set of nodes to use.
-
-  Segments *segments The set of segments to use.
-
-  Ways *ways The set of ways to use.
-
-  Relations *relations The set of relations to use.
-
-  Profile *profile The profile containing the transport type, speeds and allowed highways.
-
-  index_t start_node The start node.
-
-  index_t prev_segment The previous segment before the start node.
-
-  index_t finish_node The finish node.
-
-  int start_waypoint The starting waypoint.
-
-  int finish_waypoint The finish waypoint.
-  ++++++++++++++++++++++++++++++++++++++*/
-
-static Results *CalculateRoute(Nodes *nodes,Segments *segments,Ways *ways,Relations *relations,Profile *profile,
-                               index_t start_node,index_t prev_segment,index_t finish_node,
-                               int start_waypoint,int finish_waypoint)
-{
- Results *complete=NULL;
-
- /* A special case if the first and last nodes are the same */
-
- if(start_node==finish_node)
-   {
-    index_t fake_segment;
-    Result *result1,*result2;
-
-    complete=NewResultsList(8);
-
-    if(prev_segment==NO_SEGMENT)
-      {
-       double lat,lon;
-       distance_t distmin,dist1,dist2;
-       index_t node1,node2;
-
-       GetLatLong(nodes,start_node,NULL,&lat,&lon);
-
-       prev_segment=FindClosestSegment(nodes,segments,ways,lat,lon,1,profile,&distmin,&node1,&node2,&dist1,&dist2);
-      }
-
-    fake_segment=CreateFakeNullSegment(segments,start_node,prev_segment,finish_waypoint);
-
-    result1=InsertResult(complete,start_node,prev_segment);
-    result2=InsertResult(complete,finish_node,fake_segment);
-
-    result1->next=result2;
-
-    complete->start_node=start_node;
-    complete->prev_segment=prev_segment;
-
-    complete->finish_node=finish_node;
-    complete->last_segment=prev_segment;
-
-    complete->last_segment=result2->segment;
-   }
- else
-   {
-    Results *begin,*end;
-
-    /* Calculate the beginning of the route */
-
-    begin=FindStartRoutes(nodes,segments,ways,relations,profile,start_node,prev_segment,finish_node);
-
-    if(begin)
-      {
-       /* Check if the end of the route was reached */
-
-       if(begin->finish_node!=NO_NODE)
-          complete=ExtendStartRoutes(nodes,segments,ways,relations,profile,begin,finish_node);
-      }
-    else
-      {
-       if(prev_segment!=NO_SEGMENT)
-         {
-          /* Try again but allow a U-turn at the start waypoint -
-             this solves the problem of facing a dead-end that contains no super-nodes. */
-
-          prev_segment=NO_SEGMENT;
-
-          begin=FindStartRoutes(nodes,segments,ways,relations,profile,start_node,prev_segment,finish_node);
-         }
-
-       if(begin)
-         {
-          /* Check if the end of the route was reached */
-
-          if(begin->finish_node!=NO_NODE)
-             complete=ExtendStartRoutes(nodes,segments,ways,relations,profile,begin,finish_node);
-         }
-       else
-         {
-          fprintf(stderr,"Error: Cannot find initial section of route compatible with profile.\n");
-          exit(EXIT_FAILURE);
-         }
-      }
-
-    /* Calculate the rest of the route */
-
-    if(!complete)
-      {
-       Results *middle;
-
-       /* Calculate the end of the route */
-
-       end=FindFinishRoutes(nodes,segments,ways,relations,profile,finish_node);
-
-       if(!end)
-         {
-          fprintf(stderr,"Error: Cannot find final section of route compatible with profile.\n");
-          exit(EXIT_FAILURE);
-         }
-
-       /* Calculate the middle of the route */
-
-       middle=FindMiddleRoute(nodes,segments,ways,relations,profile,begin,end);
-
-       if(!middle && prev_segment!=NO_SEGMENT)
-         {
-          /* Try again but allow a U-turn at the start waypoint -
-             this solves the problem of facing a dead-end that contains some super-nodes. */
-
-          FreeResultsList(begin);
-
-          begin=FindStartRoutes(nodes,segments,ways,relations,profile,start_node,NO_SEGMENT,finish_node);
-
-          if(begin)
-             middle=FindMiddleRoute(nodes,segments,ways,relations,profile,begin,end);
-         }
-
-       FreeResultsList(end);
-
-       if(!middle)
-         {
-          fprintf(stderr,"Error: Cannot find super-route compatible with profile.\n");
-          exit(EXIT_FAILURE);
-         }
-
-       complete=CombineRoutes(nodes,segments,ways,relations,profile,begin,middle);
-
-       if(!complete)
-         {
-          fprintf(stderr,"Error: Cannot create combined route following super-route.\n");
-          exit(EXIT_FAILURE);
-         }
-
-       FreeResultsList(begin);
-
-       FreeResultsList(middle);
-      }
-   }
-
- complete->start_waypoint=start_waypoint;
- complete->finish_waypoint=finish_waypoint;
-
-#if DEBUG
- Result *r=FindResult(complete,complete->start_node,complete->prev_segment);
-
- printf("The final route is:\n");
-
- while(r)
-   {
-    printf("  node=%"Pindex_t" segment=%"Pindex_t" score=%f\n",r->node,r->segment,r->score);
-
-    r=r->next;
-   }
-#endif
-
- return(complete);
-}
-
-
-/*++++++++++++++++++++++++++++++++++++++
   Print out the usage information.
 
-  int detail The level of detail to use - 0 = low, 1 = high.
+  int detail The level of detail to use: -1 = just version number, 0 = low detail, 1 = full details.
 
   const char *argerr The argument that gave the error (if there is one).
 
@@ -831,45 +679,58 @@ static Results *CalculateRoute(Nodes *nodes,Segments *segments,Ways *ways,Relati
 
 static void print_usage(int detail,const char *argerr,const char *err)
 {
- fprintf(stderr,
-         "Usage: router [--help | --help-profile | --help-profile-xml |\n"
-         "                        --help-profile-json | --help-profile-perl ]\n"
-         "              [--dir=<dirname>] [--prefix=<name>]\n"
-         "              [--profiles=<filename>] [--translations=<filename>]\n"
-         "              [--exact-nodes-only]\n"
-         "              [--quiet | [--loggable] [--logtime] [--logmemory]]\n"
-         "              [--language=<lang>]\n"
-         "              [--output-html]\n"
-         "              [--output-gpx-track] [--output-gpx-route]\n"
-         "              [--output-text] [--output-text-all]\n"
-         "              [--output-none] [--output-stdout]\n"
-         "              [--profile=<name>]\n"
-         "              [--transport=<transport>]\n"
-         "              [--shortest | --quickest]\n"
-         "              --lon1=<longitude> --lat1=<latitude>\n"
-         "              --lon2=<longitude> --lon2=<latitude>\n"
-         "              [ ... --lon99=<longitude> --lon99=<latitude>]\n"
-         "              [--reverse] [--loop]\n"
-         "              [--highway-<highway>=<preference> ...]\n"
-         "              [--speed-<highway>=<speed> ...]\n"
-         "              [--property-<property>=<preference> ...]\n"
-         "              [--oneway=(0|1)] [--turns=(0|1)]\n"
-         "              [--weight=<weight>]\n"
-         "              [--height=<height>] [--width=<width>] [--length=<length>]\n");
-
- if(argerr)
+ if(detail<0)
+   {
     fprintf(stderr,
-            "\n"
-            "Error with command line parameter: %s\n",argerr);
+            "Routino version " ROUTINO_VERSION " " ROUTINO_URL ".\n"
+            );
+   }
 
- if(err)
+ if(detail>=0)
+   {
     fprintf(stderr,
-            "\n"
-            "Error: %s\n",err);
+            "Usage: router [--version]\n"
+            "              [--help | --help-profile | --help-profile-xml |\n"
+            "                        --help-profile-json | --help-profile-perl ]\n"
+            "              [--dir=<dirname>] [--prefix=<name>]\n"
+            "              [--profiles=<filename>] [--translations=<filename>]\n"
+            "              [--exact-nodes-only]\n"
+            "              [--quiet | [--loggable] [--logtime] [--logmemory]]\n"
+            "              [--language=<lang>]\n"
+            "              [--output-html]\n"
+            "              [--output-gpx-track] [--output-gpx-route]\n"
+            "              [--output-text] [--output-text-all]\n"
+            "              [--output-none] [--output-stdout]\n"
+            "              [--profile=<name>]\n"
+            "              [--transport=<transport>]\n"
+            "              [--shortest | --quickest]\n"
+            "              --lon1=<longitude> --lat1=<latitude>\n"
+            "              --lon2=<longitude> --lon2=<latitude>\n"
+            "              [ ... --lon99=<longitude> --lon99=<latitude>]\n"
+            "              [--reverse] [--loop]\n"
+            "              [--highway-<highway>=<preference> ...]\n"
+            "              [--speed-<highway>=<speed> ...]\n"
+            "              [--property-<property>=<preference> ...]\n"
+            "              [--oneway=(0|1)] [--turns=(0|1)]\n"
+            "              [--weight=<weight>]\n"
+            "              [--height=<height>] [--width=<width>] [--length=<length>]\n");
+
+    if(argerr)
+       fprintf(stderr,
+               "\n"
+               "Error with command line parameter: %s\n",argerr);
+
+    if(err)
+       fprintf(stderr,
+               "\n"
+               "Error: %s\n",err);
+   }
 
- if(detail)
+ if(detail==1)
     fprintf(stderr,
             "\n"
+            "--version               Print the version of Routino.\n"
+            "\n"
             "--help                  Prints this information.\n"
             "--help-profile          Prints the information about the selected profile.\n"
             "--help-profile-xml      Prints all loaded profiles in XML format.\n"
@@ -881,11 +742,11 @@ static void print_usage(int detail,const char *argerr,const char *err)
             "--profiles=<filename>   The name of the XML file containing the profiles\n"
             "                        (defaults to 'profiles.xml' with '--dir' and\n"
             "                         '--prefix' options or the file installed in\n"
-            "                         '" DATADIR "').\n"
+            "                         '" ROUTINO_DATADIR "').\n"
             "--translations=<fname>  The name of the XML file containing the translations\n"
             "                        (defaults to 'translations.xml' with '--dir' and\n"
             "                         '--prefix' options or the file installed in\n"
-            "                         '" DATADIR "').\n"
+            "                         '" ROUTINO_DATADIR "').\n"
             "\n"
             "--exact-nodes-only      Only route between nodes (don't find closest segment).\n"
             "\n"
@@ -899,7 +760,7 @@ static void print_usage(int detail,const char *argerr,const char *err)
             "--output-gpx-track      Write a GPX track file with all route points.\n"
             "--output-gpx-route      Write a GPX route file with interesting junctions.\n"
             "--output-text           Write a plain text file with interesting junctions.\n"
-            "--output-text-all       Write a plain test file with all route points.\n"
+            "--output-text-all       Write a plain text file with all route points.\n"
             "--output-none           Don't write any output files or read any translations.\n"
             "                        (If no output option is given then all are written.)\n"
             "--output-stdout         Write to stdout instead of a file (requires exactly\n"
diff --git a/src/routino.c b/src/routino.c
new file mode 100644
index 0000000..f193a85
--- /dev/null
+++ b/src/routino.c
@@ -0,0 +1,728 @@
+/***************************************
+ Routino library functions file.
+
+ Part of the Routino routing software.
+ ******************/ /******************
+ This file Copyright 2015 Andrew M. Bishop
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ ***************************************/
+
+#include <stdlib.h>
+
+#include "routino.h"
+
+#include "types.h"
+#include "nodes.h"
+#include "segments.h"
+#include "ways.h"
+#include "relations.h"
+
+#include "fakes.h"
+#include "results.h"
+#include "functions.h"
+#include "profiles.h"
+#include "translations.h"
+
+
+/* Global variables */
+
+/*+ Contains the libroutino API version number. +*/
+DLL_PUBLIC int Routino_APIVersion=ROUTINO_API_VERSION;
+
+/*+ Contains the error number of the most recent Routino function (one of the ROUTINO_ERROR_* values). +*/
+DLL_PUBLIC int Routino_errno=ROUTINO_ERROR_NONE;
+
+/*+ The function to be called to report on the routing progress. +*/
+Routino_ProgressFunc progress_func=NULL;
+
+/*+ The current state of the routing progress. +*/
+double progress_value=0;
+
+/*+ Set when the progress callback returns false in the routing function. +*/
+int progress_abort=0;
+
+/*+ The option to calculate the quickest route insted of the shortest. +*/
+extern int option_quickest;
+
+/*+ The options to select the format of the file output. +*/
+extern int option_file_html,option_file_gpx_track,option_file_gpx_route,option_file_text,option_file_text_all,option_file_stdout;
+
+/*+ The options to select the format of the linked list output. +*/
+extern int option_list_html,option_list_html_all,option_list_text,option_list_text_all;
+
+
+/* Static variables */
+
+static distance_t distmax=km_to_distance(1);
+
+
+/* Local types */
+
+struct _Routino_Database
+{
+ Nodes      *nodes;
+ Segments   *segments;
+ Ways       *ways;
+ Relations  *relations;
+};
+
+struct _Routino_Waypoint
+{
+ index_t segment;
+ index_t node1,node2;
+ distance_t dist1,dist2;
+};
+
+
+/*++++++++++++++++++++++++++++++++++++++
+  Check the version of the library used by the caller against the library version
+
+  int Routino_Check_API_Version Returns ROUTINO_ERROR_NONE if OK or ROUTINO_ERROR_WRONG_VERSION if there is an error.
+
+  int caller_version The version of the API used in the caller.
+
+  This function should not be called directly, use the macro Routino_CheckAPIVersion() which takes no arguments.
+  ++++++++++++++++++++++++++++++++++++++*/
+
+DLL_PUBLIC int Routino_Check_API_Version(int caller_version)
+{
+ if(caller_version==Routino_APIVersion)
+    return(ROUTINO_ERROR_NONE);
+ else
+    return(ROUTINO_ERROR_WRONG_API_VERSION);
+}
+
+
+/*++++++++++++++++++++++++++++++++++++++
+  Load a database of files for Routino to use for routing.
+
+  Routino_Database *Routino_LoadDatabase Returns a pointer to the database.
+
+  const char *dirname The pathname of the directory containing the database files.
+
+  const char *prefix The prefix of the database files.
+  ++++++++++++++++++++++++++++++++++++++*/
+
+DLL_PUBLIC Routino_Database *Routino_LoadDatabase(const char *dirname,const char *prefix)
+{
+ char *nodes_filename;
+ char *segments_filename;
+ char *ways_filename;
+ char *relations_filename;
+ Routino_Database *database=NULL;
+
+ nodes_filename    =FileName(dirname,prefix,"nodes.mem");
+ segments_filename =FileName(dirname,prefix,"segments.mem");
+ ways_filename     =FileName(dirname,prefix,"ways.mem");
+ relations_filename=FileName(dirname,prefix,"relations.mem");
+
+ if(!ExistsFile(nodes_filename) || !ExistsFile(nodes_filename) || !ExistsFile(nodes_filename) || !ExistsFile(nodes_filename))
+    Routino_errno=ROUTINO_ERROR_NO_DATABASE_FILES;
+ else
+   {
+    database=calloc(sizeof(Routino_Database),1);
+
+    database->nodes    =LoadNodeList    (nodes_filename);
+    database->segments =LoadSegmentList (segments_filename);
+    database->ways     =LoadWayList     (ways_filename);
+    database->relations=LoadRelationList(relations_filename);
+   }
+
+ free(nodes_filename);
+ free(segments_filename);
+ free(ways_filename);
+ free(relations_filename);
+
+ if(!database->nodes || !database->segments || !database->ways || !database->relations)
+   {
+    Routino_UnloadDatabase(database);
+    database=NULL;
+
+    Routino_errno=ROUTINO_ERROR_BAD_DATABASE_FILES;
+   }
+
+ if(database)
+   {
+    Routino_errno=ROUTINO_ERROR_NONE;
+    return(database);
+   }
+ else
+    return(NULL);
+}
+
+
+/*++++++++++++++++++++++++++++++++++++++
+  Close the database files that were opened by a call to Routino_LoadDatabase().
+
+  Routino_Database *database The database to close.
+  ++++++++++++++++++++++++++++++++++++++*/
+
+DLL_PUBLIC void Routino_UnloadDatabase(Routino_Database *database)
+{
+ if(!database)
+    Routino_errno=ROUTINO_ERROR_NO_DATABASE;
+ else
+   {
+    if(database->nodes)     DestroyNodeList    (database->nodes);
+    if(database->segments)  DestroySegmentList (database->segments);
+    if(database->ways)      DestroyWayList     (database->ways);
+    if(database->relations) DestroyRelationList(database->relations);
+
+    free(database);
+
+    Routino_errno=ROUTINO_ERROR_NONE;
+   }
+}
+
+
+/*++++++++++++++++++++++++++++++++++++++
+  Parse a Routino XML file containing profiles, must be called before selecting a profile.
+
+  int Routino_ParseXMLProfiles Returns non-zero in case of an error or zero if there was no error.
+
+  const char *filename The full pathname of the file to read.
+  ++++++++++++++++++++++++++++++++++++++*/
+
+DLL_PUBLIC int Routino_ParseXMLProfiles(const char *filename)
+{
+ int retval;
+
+ retval=ParseXMLProfiles(filename,NULL,1);
+
+ if(retval==1)
+    retval=ROUTINO_ERROR_NO_PROFILES_XML;
+ else if(retval==2)
+    retval=ROUTINO_ERROR_BAD_PROFILES_XML;
+
+ Routino_errno=retval;
+ return(retval);
+}
+
+
+/*++++++++++++++++++++++++++++++++++++++
+  Return a list of the profile names that have been loaded from the XML file.
+
+  char **Routino_GetProfileNames Returns a NULL terminated list of strings - all allocated.
+  ++++++++++++++++++++++++++++++++++++++*/
+
+DLL_PUBLIC char **Routino_GetProfileNames(void)
+{
+ Routino_errno=ROUTINO_ERROR_NONE;
+
+ return(GetProfileNames());
+}
+
+
+/*++++++++++++++++++++++++++++++++++++++
+  Select a specific routing profile from the set of Routino profiles that have been loaded from the XML file or NULL in case of an error.
+
+  Routino_Profile *Routino_GetProfile Returns a pointer to an internal data structure - do not free.
+
+  const char *name The name of the profile to select.
+  ++++++++++++++++++++++++++++++++++++++*/
+
+DLL_PUBLIC Routino_Profile *Routino_GetProfile(const char *name)
+{
+ Profile *profile=GetProfile(name);
+
+ if(profile)
+    Routino_errno=ROUTINO_ERROR_NONE;
+ else
+    Routino_errno=ROUTINO_ERROR_NO_SUCH_PROFILE;
+
+ return(profile);
+}
+
+
+/*++++++++++++++++++++++++++++++++++++++
+  Free the internal memory that was allocated for the Routino profiles loaded from the XML file.
+  ++++++++++++++++++++++++++++++++++++++*/
+
+DLL_PUBLIC void Routino_FreeXMLProfiles(void)
+{
+ Routino_errno=ROUTINO_ERROR_NONE;
+
+ FreeXMLProfiles();
+}
+
+
+/*++++++++++++++++++++++++++++++++++++++
+  Parse a Routino XML file containing translations, must be called before selecting a translation.
+
+  int Routino_ParseXMLTranslations Returns non-zero in case of an error or zero if there was no error.
+
+  const char *filename The full pathname of the file to read.
+  ++++++++++++++++++++++++++++++++++++++*/
+
+DLL_PUBLIC int Routino_ParseXMLTranslations(const char *filename)
+{
+ int retval;
+
+ retval=ParseXMLTranslations(filename,NULL,1);
+
+ if(retval==1)
+    retval=ROUTINO_ERROR_NO_TRANSLATIONS_XML;
+ else if(retval==2)
+    retval=ROUTINO_ERROR_BAD_TRANSLATIONS_XML;
+
+ Routino_errno=retval;
+ return(retval);
+}
+
+
+/*++++++++++++++++++++++++++++++++++++++
+  Return a list of the translation languages that have been loaded from the XML file.
+
+  char **Routino_GetTranslationLanguages Returns a NULL terminated list of strings - all allocated.
+  ++++++++++++++++++++++++++++++++++++++*/
+
+DLL_PUBLIC char **Routino_GetTranslationLanguages(void)
+{
+ Routino_errno=ROUTINO_ERROR_NONE;
+
+ return(GetTranslationLanguages());
+}
+
+
+/*++++++++++++++++++++++++++++++++++++++
+  Return a list of the full names of the translation languages that have been loaded from the XML file.
+
+  char **Routino_GetTranslationLanguageFullNames Returns a NULL terminated list of strings - all allocated.
+  ++++++++++++++++++++++++++++++++++++++*/
+
+DLL_PUBLIC char **Routino_GetTranslationLanguageFullNames(void)
+{
+ Routino_errno=ROUTINO_ERROR_NONE;
+
+ return(GetTranslationLanguageFullNames());
+}
+
+
+/*++++++++++++++++++++++++++++++++++++++
+  Select a specific translation from the set of Routino translations that have been loaded from the XML file or NULL in case of an error.
+
+  Routino_Translation *Routino_GetTranslation Returns a pointer to an internal data structure - do not free.
+
+  const char *language The language to select (as a country code, e.g. 'en', 'de') or an empty string for the first in the file or NULL for the built-in English version.
+  ++++++++++++++++++++++++++++++++++++++*/
+
+DLL_PUBLIC Routino_Translation *Routino_GetTranslation(const char *language)
+{
+ Translation *translation=GetTranslation(language);
+
+ if(translation)
+    Routino_errno=ROUTINO_ERROR_NONE;
+ else
+    Routino_errno=ROUTINO_ERROR_NO_SUCH_TRANSLATION;
+
+ return(translation);
+}
+
+
+/*++++++++++++++++++++++++++++++++++++++
+  Free the internal memory that was allocated for the Routino translations loaded from the XML file.
+  ++++++++++++++++++++++++++++++++++++++*/
+
+DLL_PUBLIC void Routino_FreeXMLTranslations(void)
+{
+ Routino_errno=ROUTINO_ERROR_NONE;
+
+ FreeXMLTranslations();
+}
+
+
+/*++++++++++++++++++++++++++++++++++++++
+  Create a fully formed Routino Profile from a Routino User Profile.
+
+  Routino_Profile *Routino_CreateProfileFromUserProfile Returns an allocated Routino Profile.
+
+  Routino_UserProfile *profile The user specified profile to convert (not modified by this).
+  ++++++++++++++++++++++++++++++++++++++*/
+
+DLL_PUBLIC Routino_Profile *Routino_CreateProfileFromUserProfile(Routino_UserProfile *profile)
+{
+ Routino_Profile *rprofile=calloc(1,sizeof(Routino_Profile));
+ int i;
+
+ Routino_errno=ROUTINO_ERROR_NONE;
+
+ if(profile->transport<=0 || profile->transport>=Transport_Count)
+    Routino_errno=ROUTINO_ERROR_BAD_USER_PROFILE;
+ else
+    rprofile->transport=profile->transport;
+
+ for(i=1;i<Highway_Count;i++)
+   {
+    if(profile->highway[i]<0 || profile->highway[i]>1)
+       Routino_errno=ROUTINO_ERROR_BAD_USER_PROFILE;
+    else
+       rprofile->highway[i]=profile->highway[i];
+
+    if(profile->speed[i]<=0)
+       Routino_errno=ROUTINO_ERROR_BAD_USER_PROFILE;
+    else
+       rprofile->speed[i]=kph_to_speed(profile->speed[i]);
+   }
+
+ for(i=1;i<Property_Count;i++)
+   {
+    if(profile->props[i]<0 || profile->props[i]>1)
+       Routino_errno=ROUTINO_ERROR_BAD_USER_PROFILE;
+    else
+       rprofile->props[i]=profile->props[i];
+   }
+
+ if(profile->weight<=0)
+    Routino_errno=ROUTINO_ERROR_BAD_USER_PROFILE;
+ else
+    rprofile->weight=tonnes_to_weight(profile->weight);
+
+ if(profile->height<=0)
+    Routino_errno=ROUTINO_ERROR_BAD_USER_PROFILE;
+ else
+    rprofile->height=metres_to_height(profile->height);
+
+ if(profile->width<=0)
+    Routino_errno=ROUTINO_ERROR_BAD_USER_PROFILE;
+ else
+    rprofile->width=metres_to_width(profile->width);
+
+ if(profile->length<=0)
+    Routino_errno=ROUTINO_ERROR_BAD_USER_PROFILE;
+ else
+    rprofile->length=metres_to_length(profile->length);
+
+ if(Routino_errno==ROUTINO_ERROR_NONE)
+    return(rprofile);
+
+ free(rprofile);
+ return(NULL);
+}
+
+
+/*++++++++++++++++++++++++++++++++++++++
+  Create a Routino User Profile from a Routino Profile loaded from an XML file.
+
+  Routino_UserProfile *Routino_CreateUserProfileFromProfile Returns an allocated Routino User Profile.
+
+  Routino_Profile *profile The Routino Profile to convert (not modified by this).
+  ++++++++++++++++++++++++++++++++++++++*/
+
+DLL_PUBLIC Routino_UserProfile *Routino_CreateUserProfileFromProfile(Routino_Profile *profile)
+{
+ Routino_UserProfile *uprofile=calloc(1,sizeof(Routino_UserProfile));
+ int i;
+
+ Routino_errno=ROUTINO_ERROR_NONE;
+
+ uprofile->transport=profile->transport;
+
+ for(i=1;i<Highway_Count;i++)
+   {
+    uprofile->highway[i]=profile->highway[i];
+
+    uprofile->speed[i]=speed_to_kph(profile->speed[i]);
+   }
+
+ for(i=1;i<Property_Count;i++)
+    uprofile->props[i]=profile->props[i];
+
+ uprofile->weight=weight_to_tonnes(profile->weight);
+
+ uprofile->height=height_to_metres(profile->height);
+
+ uprofile->width=width_to_metres(profile->width);
+
+ uprofile->length=length_to_metres(profile->length);
+
+ return(uprofile);
+}
+
+
+/*++++++++++++++++++++++++++++++++++++++
+  Validates that a selected routing profile is valid for use with the selected routing database.
+
+  int Routino_ValidateProfile Returns zero if OK or something else in case of an error.
+
+  Routino_Database *database The Routino database to use.
+
+  Routino_Profile *profile The Routino profile to validate.
+  ++++++++++++++++++++++++++++++++++++++*/
+
+DLL_PUBLIC int Routino_ValidateProfile(Routino_Database *database,Routino_Profile *profile)
+{
+ Routino_errno=ROUTINO_ERROR_NONE;
+
+ if(UpdateProfile(profile,database->ways))
+    Routino_errno=ROUTINO_ERROR_PROFILE_DATABASE_ERR;
+
+ return(Routino_errno);
+}
+
+
+/*++++++++++++++++++++++++++++++++++++++
+  Finds the nearest point in the database to the specified latitude and longitude.
+
+  Routino_Waypoint *Routino_FindWaypoint Returns a pointer to a newly allocated Routino waypoint or NULL if none could be found.
+
+  Routino_Database *database The Routino database to use.
+
+  Routino_Profile *profile The Routino profile to use.
+
+  double latitude The latitude in degrees of the point.
+
+  double longitude The longitude in degrees of the point.
+  ++++++++++++++++++++++++++++++++++++++*/
+
+DLL_PUBLIC Routino_Waypoint *Routino_FindWaypoint(Routino_Database *database,Routino_Profile *profile,double latitude,double longitude)
+{
+ distance_t dist;
+ Routino_Waypoint *waypoint;
+
+ if(!database)
+   {
+    Routino_errno=ROUTINO_ERROR_NO_DATABASE;
+    return(NULL);
+   }
+
+ if(!profile)
+   {
+    Routino_errno=ROUTINO_ERROR_NO_PROFILE;
+    return(NULL);
+   }
+
+ if(!profile->allow)
+   {
+    Routino_errno=ROUTINO_ERROR_NOTVALID_PROFILE;
+    return(NULL);
+   }
+
+ waypoint=calloc(sizeof(Routino_Waypoint),1);
+
+ waypoint->segment=FindClosestSegment(database->nodes,database->segments,database->ways,
+                                      degrees_to_radians(latitude),degrees_to_radians(longitude),distmax,profile,
+                                      &dist,&waypoint->node1,&waypoint->node2,&waypoint->dist1,&waypoint->dist2);
+
+ if(waypoint->segment==NO_SEGMENT)
+   {
+    free(waypoint);
+
+    Routino_errno=ROUTINO_ERROR_NO_NEARBY_HIGHWAY;
+    return(NULL);
+   }
+
+ Routino_errno=ROUTINO_ERROR_NONE;
+ return(waypoint);
+}
+
+
+/*++++++++++++++++++++++++++++++++++++++
+  Calculate a route using a loaded database, chosen profile, chosen translation and set of waypoints.
+
+  Routino_Output *Routino_CalculateRoute Returns the head of a linked list of route data (if requested) or NULL.
+
+  Routino_Database *database The loaded database to use.
+
+  Routino_Profile *profile The chosen routing profile to use.
+
+  Routino_Translation *translation The chosen translation information to use.
+
+  Routino_Waypoint **waypoints The set of waypoints.
+
+  int nwaypoints The number of waypoints.
+
+  int options The set of routing options (ROUTINO_ROUTE_*) ORed together.
+
+  Routino_ProgressFunc progress A function to be called occasionally to report progress or NULL.
+  ++++++++++++++++++++++++++++++++++++++*/
+
+DLL_PUBLIC Routino_Output *Routino_CalculateRoute(Routino_Database *database,Routino_Profile *profile,Routino_Translation *translation,
+                                                  Routino_Waypoint **waypoints,int nwaypoints,int options,Routino_ProgressFunc progress)
+{
+ int waypoint;
+ index_t start_node,finish_node=NO_NODE;
+ index_t join_segment=NO_SEGMENT;
+ Results **results;
+ Routino_Output *output=NULL;
+
+ /* Check the input data */
+
+ if(!database)
+   {
+    Routino_errno=ROUTINO_ERROR_NO_DATABASE;
+    return(NULL);
+   }
+
+ if(!profile)
+   {
+    Routino_errno=ROUTINO_ERROR_NO_PROFILE;
+    return(NULL);
+   }
+
+ if(!profile->allow)
+   {
+    Routino_errno=ROUTINO_ERROR_NOTVALID_PROFILE;
+    return(NULL);
+   }
+
+ if(!translation)
+   {
+    Routino_errno=ROUTINO_ERROR_NO_TRANSLATION;
+    return(NULL);
+   }
+
+ /* Extract the options */
+
+ if(options&ROUTINO_ROUTE_QUICKEST) option_quickest=1; else option_quickest=0;
+
+ if(options&ROUTINO_ROUTE_FILE_HTML)      option_file_html=1;      else option_file_html=0;
+ if(options&ROUTINO_ROUTE_FILE_GPX_TRACK) option_file_gpx_track=1; else option_file_gpx_track=0;
+ if(options&ROUTINO_ROUTE_FILE_GPX_ROUTE) option_file_gpx_route=1; else option_file_gpx_route=0;
+ if(options&ROUTINO_ROUTE_FILE_TEXT)      option_file_text=1;      else option_file_text=0;
+ if(options&ROUTINO_ROUTE_FILE_TEXT_ALL)  option_file_text_all=1;  else option_file_text_all=0;
+
+ if(options&ROUTINO_ROUTE_FILE_STDOUT)    option_file_stdout=1;    else option_file_stdout=0;
+
+ if(option_file_stdout && (option_file_html+option_file_gpx_track+option_file_gpx_route+option_file_text+option_file_text_all)!=1)
+   {
+    Routino_errno=ROUTINO_ERROR_BAD_OPTIONS;
+    return(NULL);
+   }
+
+ if(options&ROUTINO_ROUTE_LIST_HTML)     option_list_html=1;      else option_list_html=0;
+ if(options&ROUTINO_ROUTE_LIST_HTML_ALL) option_list_html_all=1;  else option_list_html_all=0;
+ if(options&ROUTINO_ROUTE_LIST_TEXT)     option_list_text=1;      else option_list_text=0;
+ if(options&ROUTINO_ROUTE_LIST_TEXT_ALL) option_list_text_all=1;  else option_list_text_all=0;
+
+ if((option_list_html+option_list_html_all+option_list_text+option_list_text_all)>1)
+   {
+    Routino_errno=ROUTINO_ERROR_BAD_OPTIONS;
+    return(NULL);
+   }
+
+ /* Set up the progress callback */
+
+ progress_func=progress;
+ progress_value=0.0;
+ progress_abort=0;
+
+ /* Loop through all pairs of waypoints */
+
+ results=calloc(sizeof(Results*),nwaypoints);
+
+ for(waypoint=0;waypoint<nwaypoints;waypoint++)
+   {
+    if(progress_func)
+      {
+       progress_value=(double)waypoint/(double)(nwaypoints+1);
+
+       if(!progress_func(progress_value))
+         {
+          Routino_errno=ROUTINO_ERROR_PROGRESS_ABORTED;
+          goto tidy_and_exit;
+         }
+      }
+
+    start_node=finish_node;
+
+    finish_node=CreateFakes(database->nodes,database->segments,waypoint+1,
+                            LookupSegment(database->segments,waypoints[waypoint]->segment,1),
+                            waypoints[waypoint]->node1,waypoints[waypoint]->node2,waypoints[waypoint]->dist1,waypoints[waypoint]->dist2);
+
+    if(waypoint==0)
+       continue;
+
+    results[waypoint-1]=CalculateRoute(database->nodes,database->segments,database->ways,database->relations,
+                                       profile,start_node,join_segment,finish_node,waypoint,waypoint+1);
+
+    if(!results[waypoint-1])
+      {
+       if(progress_func && progress_abort)
+          Routino_errno=ROUTINO_ERROR_PROGRESS_ABORTED;
+       else
+          Routino_errno=ROUTINO_ERROR_NO_ROUTE_1+waypoint-1;
+
+       goto tidy_and_exit;
+      }
+
+    join_segment=results[waypoint-1]->last_segment;
+   }
+
+ if(progress_func)
+   {
+    progress_value=(double)waypoint/(double)(nwaypoints+1);
+
+    if(!progress_func(progress_value))
+      {
+       Routino_errno=ROUTINO_ERROR_PROGRESS_ABORTED;
+       goto tidy_and_exit;
+      }
+   }
+
+ /* Print the route */
+
+ output=PrintRoute(results,nwaypoints-1,database->nodes,database->segments,database->ways,profile,translation);
+
+ if(progress_func && !progress_func(1.0))
+   {
+    Routino_errno=ROUTINO_ERROR_PROGRESS_ABORTED;
+    goto tidy_and_exit;
+   }
+
+ /* Tidy up and exit */
+
+ tidy_and_exit:
+
+ DeleteFakeNodes();
+
+ for(waypoint=0;waypoint<nwaypoints;waypoint++)
+    if(results[waypoint])
+       FreeResultsList(results[waypoint]);
+
+ free(results);
+
+ return(output);
+}
+
+
+/*++++++++++++++++++++++++++++++++++++++
+  Delete the linked list created by Routino_CalculateRoute.
+
+  Routino_Output *output The output to be deleted.
+  ++++++++++++++++++++++++++++++++++++++*/
+
+DLL_PUBLIC void Routino_DeleteRoute(Routino_Output *output)
+{
+ while(output)
+   {
+    Routino_Output *next=output->next;
+
+    if(output->name)
+       free(output->name);
+
+    if(output->desc1)
+       free(output->desc1);
+
+    if(output->desc2)
+       free(output->desc2);
+
+    if(output->desc3)
+       free(output->desc3);
+
+    free(output);
+
+    output=next;
+   }
+}
diff --git a/src/routino.h b/src/routino.h
new file mode 100644
index 0000000..f1c5ab2
--- /dev/null
+++ b/src/routino.h
@@ -0,0 +1,286 @@
+/***************************************
+ Routino library header file.
+
+ Part of the Routino routing software.
+ ******************/ /******************
+ This file Copyright 2015 Andrew M. Bishop
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ ***************************************/
+
+
+#ifndef ROUTINO_H
+#define ROUTINO_H    /*+ To stop multiple inclusions. +*/
+
+/* Limit the exported symbols in the library */
+
+#if defined(_MSC_VER)
+  #ifdef LIBROUTINO
+    #define DLL_PUBLIC __declspec(dllexport)
+  #else
+    #define DLL_PUBLIC __declspec(dllimport)
+  #endif
+#endif
+
+#if defined(__GNUC__) && __GNUC__ >= 4
+  #if defined(__MINGW32__) || defined(__CYGWIN__)
+    #ifdef LIBROUTINO
+      #define DLL_PUBLIC __attribute__ ((dllexport))
+    #else
+      #define DLL_PUBLIC __attribute__ ((dllimport))
+    #endif
+  #else
+    #ifdef LIBROUTINO
+      #define DLL_PUBLIC __attribute__ ((visibility ("default")))
+    #endif
+  #endif
+#endif
+
+#ifndef DLL_PUBLIC
+  #define DLL_PUBLIC
+#endif
+
+
+/* Handle compilation with a C++ compiler */
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+ /* Routino library API version */
+
+#define ROUTINO_API_VERSION                 7 /*+ A version number for the Routino API. +*/
+
+
+ /* Routino error constants */
+
+#define ROUTINO_ERROR_NONE                  0 /*+ No error. +*/
+
+#define ROUTINO_ERROR_NO_DATABASE           1 /*+ A function was called without the database variable set. +*/
+#define ROUTINO_ERROR_NO_PROFILE            2 /*+ A function was called without the profile variable set. +*/
+#define ROUTINO_ERROR_NO_TRANSLATION        3 /*+ A function was called without the translation variable set. +*/
+
+#define ROUTINO_ERROR_NO_DATABASE_FILES    11 /*+ The specified database to load did not exist. +*/
+#define ROUTINO_ERROR_BAD_DATABASE_FILES   12 /*+ The specified database could not be loaded. +*/
+#define ROUTINO_ERROR_NO_PROFILES_XML      13 /*+ The specified profiles XML file did not exist. +*/
+#define ROUTINO_ERROR_BAD_PROFILES_XML     14 /*+ The specified profiles XML file could not be loaded. +*/
+#define ROUTINO_ERROR_NO_TRANSLATIONS_XML  15 /*+ The specified translations XML file did not exist. +*/
+#define ROUTINO_ERROR_BAD_TRANSLATIONS_XML 16 /*+ The specified translations XML file could not be loaded. +*/
+
+#define ROUTINO_ERROR_NO_SUCH_PROFILE      21 /*+ The requested profile name does not exist in the loaded XML file. +*/
+#define ROUTINO_ERROR_NO_SUCH_TRANSLATION  22 /*+ The requested translation language does not exist in the loaded XML file. +*/
+
+#define ROUTINO_ERROR_NO_NEARBY_HIGHWAY    31 /*+ There is no highway near the coordinates to place a waypoint. +*/
+
+#define ROUTINO_ERROR_PROFILE_DATABASE_ERR 41 /*+ The profile and database do not work together. +*/
+#define ROUTINO_ERROR_NOTVALID_PROFILE     42 /*+ The profile being used has not been validated. +*/
+#define ROUTINO_ERROR_BAD_USER_PROFILE     43 /*+ The user specified profile contained invalid data. +*/
+
+#define ROUTINO_ERROR_BAD_OPTIONS          51 /*+ The routing options specified are not consistent with each other. +*/
+
+#define ROUTINO_ERROR_WRONG_API_VERSION    61 /*+ There is a mismatch between the library and caller API version. +*/
+
+#define ROUTINO_ERROR_PROGRESS_ABORTED     71 /*+ The progress function returned false. +*/
+
+#define ROUTINO_ERROR_NO_ROUTE_1         1001 /*+ A route could not be found to waypoint 1. +*/
+#define ROUTINO_ERROR_NO_ROUTE_2         1002 /*+ A route could not be found to waypoint 2. +*/
+#define ROUTINO_ERROR_NO_ROUTE_3         1003 /*+ A route could not be found to waypoint 3. +*/
+/*  Higher values of the error number refer to later waypoints. */
+
+
+ /* Routino routing option constants */
+
+#define ROUTINO_ROUTE_SHORTEST              0 /*+ Calculate the shortest route. +*/
+#define ROUTINO_ROUTE_QUICKEST              1 /*+ Calculate the quickest route. +*/
+
+#define ROUTINO_ROUTE_FILE_HTML             2 /*+ Output an HTML route file. +*/
+#define ROUTINO_ROUTE_FILE_GPX_TRACK        4 /*+ Output a GPX track file. +*/
+#define ROUTINO_ROUTE_FILE_GPX_ROUTE        8 /*+ Output a GPX route file. +*/
+#define ROUTINO_ROUTE_FILE_TEXT            16 /*+ Output a text file with important junctions. +*/
+#define ROUTINO_ROUTE_FILE_TEXT_ALL        32 /*+ Output a text file with all nodes and segments. +*/
+
+#define ROUTINO_ROUTE_FILE_STDOUT          64 /*+ Output a single file type to stdout. +*/
+
+#define ROUTINO_ROUTE_LIST_HTML           128 /*+ Output a linked list of points containing the HTML file information but as plain text. +*/
+#define ROUTINO_ROUTE_LIST_HTML_ALL       256 /*+ Output a linked list of points containing the HTML file information as plain text and with all points. +*/
+#define ROUTINO_ROUTE_LIST_TEXT           512 /*+ Output a linked list of points containing the text file information. +*/
+#define ROUTINO_ROUTE_LIST_TEXT_ALL      1024 /*+ Output a linked list of points containing the text all file information. +*/
+
+
+ /* Routino output point types */
+
+#define ROUTINO_POINT_UNIMPORTANT  0      /*+ An unimportant, intermediate, node. +*/
+#define ROUTINO_POINT_RB_NOT_EXIT  1      /*+ A roundabout exit that is not taken. +*/
+#define ROUTINO_POINT_JUNCT_CONT   2      /*+ An un-interesting junction where the route continues without comment. +*/
+#define ROUTINO_POINT_CHANGE       3      /*+ The highway changes type but nothing else happens. +*/
+#define ROUTINO_POINT_JUNCT_IMPORT 4      /*+ An interesting junction to be described. +*/
+#define ROUTINO_POINT_RB_ENTRY     5      /*+ The entrance to a roundabout. +*/
+#define ROUTINO_POINT_RB_EXIT      6      /*+ The exit from a roundabout. +*/
+#define ROUTINO_POINT_MINI_RB      7      /*+ The location of a mini-roundabout. +*/
+#define ROUTINO_POINT_UTURN        8      /*+ The location of a U-turn. +*/
+#define ROUTINO_POINT_WAYPOINT     9      /*+ A waypoint. +*/
+
+
+ /* Routino user profile array indexes */
+
+#define ROUTINO_HIGHWAY_MOTORWAY            1 /*+ A Motorway highway. +*/
+#define ROUTINO_HIGHWAY_TRUNK               2 /*+ A Trunk highway. +*/
+#define ROUTINO_HIGHWAY_PRIMARY             3 /*+ A Primary highway. +*/
+#define ROUTINO_HIGHWAY_SECONDARY           4 /*+ A Secondary highway. +*/
+#define ROUTINO_HIGHWAY_TERTIARY            5 /*+ A Tertiary highway. +*/
+#define ROUTINO_HIGHWAY_UNCLASSIFIED        6 /*+ A Unclassified highway. +*/
+#define ROUTINO_HIGHWAY_RESIDENTIAL         7 /*+ A Residential highway. +*/
+#define ROUTINO_HIGHWAY_SERVICE             8 /*+ A Service highway. +*/
+#define ROUTINO_HIGHWAY_TRACK               9 /*+ A Track highway. +*/
+#define ROUTINO_HIGHWAY_CYCLEWAY           10 /*+ A Cycleway highway. +*/
+#define ROUTINO_HIGHWAY_PATH               11 /*+ A Path highway. +*/
+#define ROUTINO_HIGHWAY_STEPS              12 /*+ A Steps highway. +*/
+#define ROUTINO_HIGHWAY_FERRY              13 /*+ A Ferry highway. +*/
+
+#define ROUTINO_PROPERTY_PAVED              1 /*+ A Paved highway. +*/
+#define ROUTINO_PROPERTY_MULTILANE          2 /*+ A Multilane highway. +*/
+#define ROUTINO_PROPERTY_BRIDGE             3 /*+ A Bridge highway. +*/
+#define ROUTINO_PROPERTY_TUNNEL             4 /*+ A Tunnel highway. +*/
+#define ROUTINO_PROPERTY_FOOTROUTE          5 /*+ A Footroute highway. +*/
+#define ROUTINO_PROPERTY_BICYCLEROUTE       6 /*+ A Bicycleroute highway. +*/
+
+
+ /* Routino types */
+
+ /*+ A data structure to hold a Routino database loaded from a file (the contents are private). +*/
+ typedef struct _Routino_Database Routino_Database;
+
+ /*+ A data structure to hold a Routino waypoint found within the database (the contents are private). +*/
+ typedef struct _Routino_Waypoint Routino_Waypoint;
+
+ /*+ A data structure to hold a Routino routing profile (the contents are private). +*/
+#ifdef LIBROUTINO
+ typedef struct _Profile             Routino_Profile;
+#else
+ typedef struct _Routino_Profile     Routino_Profile;
+#endif
+
+ /*+ A data structure to hold a Routino translation (the contents are private). +*/
+#ifdef LIBROUTINO
+ typedef struct _Translation         Routino_Translation;
+#else
+ typedef struct _Routino_Translation Routino_Translation;
+#endif
+
+ /*+ A data structure to hold a routing profile that can be defined by the user. +*/
+ typedef struct _Routino_UserProfile
+ {
+  int    transport;              /*+ The type of transport. +*/
+
+  float  highway[14];            /*+ A floating point preference for travel on the highway (range 0 to 1). +*/
+
+  float  speed[14];              /*+ The maximum speed on each type of highway (km/hour). +*/
+
+  float  props[7];               /*+ A floating point preference for ways with this attribute (range 0 to 1). +*/
+
+  int    oneway;                 /*+ A flag to indicate if one-way restrictions apply. +*/
+  int    turns;                  /*+ A flag to indicate if turn restrictions apply. +*/
+
+  float  weight;                 /*+ The weight of the vehicle (in tonnes). +*/
+
+  float  height;                 /*+ The height of the vehicle (in metres). +*/
+  float  width;                  /*+ The width of vehicle (in metres). +*/
+  float  length;                 /*+ The length of vehicle (in metres). +*/
+ }
+  Routino_UserProfile;
+
+
+ /*+ Forward declaration of the Routino_Output data type. +*/
+ typedef struct _Routino_Output Routino_Output;
+
+ /*+ A linked list output of the calculated route whose contents depend on the ROUTINO_ROUTE_LIST_* options selected. +*/
+ struct _Routino_Output
+ {
+  Routino_Output *next;         /*+ A pointer to the next route section. +*/
+
+  float           lon;          /*+ The longitude of the point (radians). +*/
+  float           lat;          /*+ The latitude of the point (radians). +*/
+
+  float           dist;         /*+ The total distance travelled (kilometres) up to the point. +*/
+  float           time;         /*+ The total journey time (seconds) up to the point. +*/
+
+  float           speed;        /*+ The speed (km/hr) for this section of the route (ROUTINO_ROUTE_LIST_TEXT_ALL format only). +*/
+
+  int             type;         /*+ The type of point (one of the ROUTINO_POINT_* values). +*/
+
+  int             turn;         /*+ The amount to turn (degrees) for the next section of the route (ROUTINO_ROUTE_LIST_TEXT or ROUTINO_ROUTE_LIST_HTML or ROUTINO_ROUTE_LIST_HTML_ALL format). +*/
+  int             bearing;      /*+ The compass direction (degrees) for the next section of the route. +*/
+
+  char           *name;         /*+ The name of the next section of the route (ROUTINO_ROUTE_LIST_TEXT or ROUTINO_ROUTE_LIST_HTML or ROUTINO_ROUTE_LIST_HTML_ALL format) or previous section of the route (ROUTINO_ROUTE_LIST_TEXT_ALL format). +*/
+
+  char           *desc1;        /*+ The first part of the description of the next section of route (ROUTINO_ROUTE_LIST_HTML or ROUTINO_ROUTE_LIST_HTML format). +*/
+  char           *desc2;        /*+ The second part of the description of the next section of route (ROUTINO_ROUTE_LIST_HTML or ROUTINO_ROUTE_LIST_HTML format). +*/
+  char           *desc3;        /*+ The third part of the description, the total distance and time at the end of the next section of route (ROUTINO_ROUTE_LIST_HTML or ROUTINO_ROUTE_LIST_HTML format). +*/
+ };
+
+
+ /*+ A type of function that can be used as a callback to indicate routing progress, if it returns false the router stops. +*/
+ typedef int (*Routino_ProgressFunc)(double complete);
+
+
+ /* Routino error number variable */
+
+ /*+ Contains the libroutino API version number. +*/
+ DLL_PUBLIC extern int Routino_APIVersion;
+
+ /*+ Contains the error number of the most recent Routino function (one of the ROUTINO_ERROR_* values). +*/
+ DLL_PUBLIC extern int Routino_errno;
+
+
+ /* Routino library functions */
+
+#define Routino_CheckAPIVersion() Routino_Check_API_Version(ROUTINO_API_VERSION) /*+ A wrapper function to simplify the API version check. +*/
+
+ DLL_PUBLIC int Routino_Check_API_Version(int caller_version);
+
+ DLL_PUBLIC Routino_Database *Routino_LoadDatabase(const char *dirname,const char *prefix);
+ DLL_PUBLIC void Routino_UnloadDatabase(Routino_Database *database);
+
+ DLL_PUBLIC int Routino_ParseXMLProfiles(const char *filename);
+ DLL_PUBLIC char **Routino_GetProfileNames(void);
+ DLL_PUBLIC Routino_Profile *Routino_GetProfile(const char *name);
+ DLL_PUBLIC void Routino_FreeXMLProfiles(void);
+
+ DLL_PUBLIC int Routino_ParseXMLTranslations(const char *filename);
+ DLL_PUBLIC char **Routino_GetTranslationLanguages(void);
+ DLL_PUBLIC char **Routino_GetTranslationLanguageFullNames(void);
+ DLL_PUBLIC Routino_Translation *Routino_GetTranslation(const char *language);
+ DLL_PUBLIC void Routino_FreeXMLTranslations(void);
+
+ DLL_PUBLIC Routino_Profile *Routino_CreateProfileFromUserProfile(Routino_UserProfile *profile);
+ DLL_PUBLIC Routino_UserProfile *Routino_CreateUserProfileFromProfile(Routino_Profile *profile);
+
+ DLL_PUBLIC int Routino_ValidateProfile(Routino_Database *database,Routino_Profile *profile);
+
+ DLL_PUBLIC Routino_Waypoint *Routino_FindWaypoint(Routino_Database *database,Routino_Profile *profile,double latitude,double longitude);
+
+ DLL_PUBLIC Routino_Output *Routino_CalculateRoute(Routino_Database *database,Routino_Profile *profile,Routino_Translation *translation,
+                                                   Routino_Waypoint **waypoints,int nwaypoints,int options,Routino_ProgressFunc progress);
+
+ DLL_PUBLIC void Routino_DeleteRoute(Routino_Output *output);
+
+
+/* Handle compilation with a C++ compiler */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ROUTINO_H */
diff --git a/src/segments.c b/src/segments.c
index fb83b5f..baa9737 100644
--- a/src/segments.c
+++ b/src/segments.c
@@ -3,7 +3,7 @@
 
  Part of the Routino routing software.
  ******************/ /******************
- This file Copyright 2008-2014 Andrew M. Bishop
+ This file Copyright 2008-2015 Andrew M. Bishop
 
  This program is free software: you can redistribute it and/or modify
  it under the terms of the GNU Affero General Public License as published by
@@ -68,7 +68,9 @@ Segments *LoadSegmentList(const char *filename)
  SlimFetch(segments->fd,&segments->file,sizeof(SegmentsFile),0);
 
  segments->cache=NewSegmentCache();
+#ifndef LIBROUTINO
  log_malloc(segments->cache,sizeof(*segments->cache));
+#endif
 
 #endif
 
@@ -92,7 +94,9 @@ void DestroySegmentList(Segments *segments)
 
  segments->fd=SlimUnmapFile(segments->fd);
 
+#ifndef LIBROUTINO
  log_free(segments->cache);
+#endif
  DeleteSegmentCache(segments->cache);
 
 #endif
diff --git a/src/segments.h b/src/segments.h
index 3b51605..d07e0a2 100644
--- a/src/segments.h
+++ b/src/segments.h
@@ -5,7 +5,7 @@
 
  Part of the Routino routing software.
  ******************/ /******************
- This file Copyright 2008-2014 Andrew M. Bishop
+ This file Copyright 2008-2015 Andrew M. Bishop
 
  This program is free software: you can redistribute it and/or modify
  it under the terms of the GNU Affero General Public License as published by
@@ -68,7 +68,7 @@ struct _Segments
 
 #if !SLIM
 
- void        *data;             /*+ The memory mapped data. +*/
+ char        *data;             /*+ The memory mapped data. +*/
 
  Segment     *segments;         /*+ An array of segments. +*/
 
@@ -182,10 +182,12 @@ CACHE_DELETECACHE_PROTO(Segment)
 CACHE_FETCHCACHE_PROTO(Segment)
 CACHE_INVALIDATECACHE_PROTO(Segment)
 
+/* Data type */
+
+CACHE_STRUCTURE(Segment)
 
 /* Inline functions */
 
-CACHE_STRUCTURE(Segment)
 CACHE_NEWCACHE(Segment)
 CACHE_DELETECACHE(Segment)
 CACHE_FETCHCACHE(Segment)
@@ -226,7 +228,7 @@ static inline Segment *LookupSegment(Segments *segments,index_t index,int positi
 
 static inline index_t IndexSegment(Segments *segments,Segment *segmentp)
 {
- int position1=segmentp-&segments->cached[0];
+ int position1=(int)(segmentp-&segments->cached[0]);
 
  return(segments->incache[position1]);
 }
@@ -246,7 +248,7 @@ static inline index_t IndexSegment(Segments *segments,Segment *segmentp)
 
 static inline Segment *NextSegment(Segments *segments,Segment *segmentp,index_t node)
 {
- int position=segmentp-&segments->cached[-1];
+ int position=(int)(segmentp-&segments->cached[-1]);
 
  if(segmentp->node1==node)
    {
diff --git a/src/segmentsx.c b/src/segmentsx.c
index c54aac7..bcd2ccc 100644
--- a/src/segmentsx.c
+++ b/src/segmentsx.c
@@ -3,7 +3,7 @@
 
  Part of the Routino routing software.
  ******************/ /******************
- This file Copyright 2008-2014 Andrew M. Bishop
+ This file Copyright 2008-2015 Andrew M. Bishop
 
  This program is free software: you can redistribute it and/or modify
  it under the terms of the GNU Affero General Public License as published by
@@ -45,7 +45,7 @@ extern char *option_tmpdirname;
 
 /* Local variables */
 
-/*+ Temporary file-local variables for use by the sort functions. +*/
+/*+ Temporary file-local variables for use by the sort functions (re-initialised for each sort). +*/
 static NodesX *sortnodesx;
 static SegmentsX *sortsegmentsx;
 static WaysX *sortwaysx;
@@ -77,7 +77,7 @@ SegmentsX *NewSegmentList(void)
 
  logassert(segmentsx,"Failed to allocate memory (try using slim mode?)"); /* Check calloc() worked */
 
- segmentsx->filename_tmp=(char*)malloc(strlen(option_tmpdirname)+32);
+ segmentsx->filename_tmp=(char*)malloc(strlen(option_tmpdirname)+40); /* allow %p to be up to 20 bytes */
 
  sprintf(segmentsx->filename_tmp,"%s/segmentsx.%p.tmp",option_tmpdirname,(void*)segmentsx);
 
@@ -294,11 +294,7 @@ void SortSegmentList(SegmentsX *segmentsx)
 
  /* Re-open the file read-only and a new file writeable */
 
- segmentsx->fd=ReOpenFileBuffered(segmentsx->filename_tmp);
-
- DeleteFile(segmentsx->filename_tmp);
-
- fd=OpenFileBufferedNew(segmentsx->filename_tmp);
+ fd=ReplaceFileBuffered(segmentsx->filename_tmp,&segmentsx->fd);
 
  /* Sort by node indexes */
 
@@ -413,11 +409,7 @@ void ProcessSegments(SegmentsX *segmentsx,NodesX *nodesx,WaysX *waysx)
 
  /* Re-open the file read-only and a new file writeable */
 
- segmentsx->fd=ReOpenFileBuffered(segmentsx->filename_tmp);
-
- DeleteFile(segmentsx->filename_tmp);
-
- fd=OpenFileBufferedNew(segmentsx->filename_tmp);
+ fd=ReplaceFileBuffered(segmentsx->filename_tmp,&segmentsx->fd);
 
  /* Modify the on-disk image */
 
@@ -654,11 +646,7 @@ void RemovePrunedSegments(SegmentsX *segmentsx,WaysX *waysx)
 
  /* Re-open the file read-only and a new file writeable */
 
- segmentsx->fd=ReOpenFileBuffered(segmentsx->filename_tmp);
-
- DeleteFile(segmentsx->filename_tmp);
-
- fd=OpenFileBufferedNew(segmentsx->filename_tmp);
+ fd=ReplaceFileBuffered(segmentsx->filename_tmp,&segmentsx->fd);
 
  /* Sort by node indexes */
 
@@ -734,11 +722,7 @@ void DeduplicateSuperSegments(SegmentsX *segmentsx,WaysX *waysx)
 
  /* Re-open the file read-only and a new file writeable */
 
- segmentsx->fd=ReOpenFileBuffered(segmentsx->filename_tmp);
-
- DeleteFile(segmentsx->filename_tmp);
-
- fd=OpenFileBufferedNew(segmentsx->filename_tmp);
+ fd=ReplaceFileBuffered(segmentsx->filename_tmp,&segmentsx->fd);
 
  /* Sort by node indexes */
 
@@ -782,10 +766,10 @@ void DeduplicateSuperSegments(SegmentsX *segmentsx,WaysX *waysx)
 
 static int deduplicate_super(SegmentX *segmentx,index_t index)
 {
- static int nprev=0;
- static index_t prevnode1=NO_NODE,prevnode2=NO_NODE;
- static SegmentX prevsegx[MAX_SEG_PER_NODE];
- static Way prevway[MAX_SEG_PER_NODE];
+ static int nprev;                           /* internal variable (reset by first call in each sort; index==0) */
+ static index_t prevnode1,prevnode2;         /* internal variable (reset by first call in each sort; index==0) */
+ static SegmentX prevsegx[MAX_SEG_PER_NODE]; /* internal variable (reset by first call in each sort; index==0) */
+ static Way prevway[MAX_SEG_PER_NODE];       /* internal variable (reset by first call in each sort; index==0) */
 
  WayX *wayx=LookupWayX(sortwaysx,segmentx->way,1);
  int isduplicate=0;
@@ -858,11 +842,7 @@ void SortSegmentListGeographically(SegmentsX *segmentsx,NodesX *nodesx)
 
  /* Re-open the file read-only and a new file writeable */
 
- segmentsx->fd=ReOpenFileBuffered(segmentsx->filename_tmp);
-
- DeleteFile(segmentsx->filename_tmp);
-
- fd=OpenFileBufferedNew(segmentsx->filename_tmp);
+ fd=ReplaceFileBuffered(segmentsx->filename_tmp,&segmentsx->fd);
 
  /* Update the segments with geographically sorted node indexes and sort them */
 
diff --git a/src/segmentsx.h b/src/segmentsx.h
index df04c62..818cf7d 100644
--- a/src/segmentsx.h
+++ b/src/segmentsx.h
@@ -3,7 +3,7 @@
 
  Part of the Routino routing software.
  ******************/ /******************
- This file Copyright 2008-2013 Andrew M. Bishop
+ This file Copyright 2008-2015 Andrew M. Bishop
 
  This program is free software: you can redistribute it and/or modify
  it under the terms of the GNU Affero General Public License as published by
@@ -140,10 +140,12 @@ CACHE_FETCHCACHE_PROTO(SegmentX)
 CACHE_REPLACECACHE_PROTO(SegmentX)
 CACHE_INVALIDATECACHE_PROTO(SegmentX)
 
+/* Data type */
+
+CACHE_STRUCTURE(SegmentX)
 
 /* Inline functions */
 
-CACHE_STRUCTURE(SegmentX)
 CACHE_NEWCACHE(SegmentX)
 CACHE_DELETECACHE(SegmentX)
 CACHE_FETCHCACHE(SegmentX)
diff --git a/src/sorting.c b/src/sorting.c
index 7141d60..6390c33 100644
--- a/src/sorting.c
+++ b/src/sorting.c
@@ -3,7 +3,7 @@
 
  Part of the Routino routing software.
  ******************/ /******************
- This file Copyright 2009-2014 Andrew M. Bishop
+ This file Copyright 2009-2015 Andrew M. Bishop
 
  This program is free software: you can redistribute it and/or modify
  it under the terms of the GNU Affero General Public License as published by
@@ -52,11 +52,15 @@ extern int option_filesort_threads;
 /*+ A data type for holding data for a thread. +*/
 typedef struct _thread_data
  {
+#if defined(USE_PTHREADS) && USE_PTHREADS
+
   pthread_t thread;             /*+ The thread identifier. +*/
 
   int       running;            /*+ A flag indicating the current state of the thread. +*/
 
-  void     *data;               /*+ The main data array. +*/
+#endif
+
+  char     *data;               /*+ The main data array. +*/
   void    **datap;              /*+ An array of pointers to the data objects. +*/
   size_t    n;                  /*+ The number of pointers. +*/
 
@@ -122,7 +126,8 @@ index_t filesort_fixed(int fd_in,int fd_out,size_t itemsize,int (*pre_sort_funct
  int nfiles=0,ndata=0;
  index_t count_out=0,count_in=0,total=0;
  size_t nitems;
- void *data,**datap;
+ char *data;
+ void **datap;
  thread_data *threads;
  size_t item;
  int i,more=1;
@@ -142,12 +147,10 @@ index_t filesort_fixed(int fd_in,int fd_out,size_t itemsize,int (*pre_sort_funct
  else
     nitems=option_filesort_ramsize/(option_filesort_threads*(itemsize+sizeof(void*)));
 
- threads=(thread_data*)malloc(option_filesort_threads*sizeof(thread_data));
+ threads=(thread_data*)calloc(option_filesort_threads,sizeof(thread_data));
 
  for(i=0;i<option_filesort_threads;i++)
    {
-    threads[i].running=0;
-
     threads[i].data=malloc(nitems*itemsize);
     threads[i].datap=malloc(nitems*sizeof(void*));
 
@@ -502,7 +505,8 @@ index_t filesort_vary(int fd_in,int fd_out,int (*pre_sort_function)(void*,index_
  index_t count_out=0,count_in=0,total=0;
  size_t datasize;
  FILESORT_VARINT nextitemsize,largestitemsize=0;
- void *data,**datap;
+ char *data;
+ void **datap;
  thread_data *threads;
  size_t item;
  int i,more=1;
@@ -517,17 +521,19 @@ index_t filesort_vary(int fd_in,int fd_out,int (*pre_sort_function)(void*,index_
  if(datasize==0)
     return(0);
 
- if((datasize*2)<option_filesort_ramsize) /* estimate that data and pointer are same size */
-    datasize=(datasize*2)/option_filesort_threads;
+ /* We can not know in advance how many data items there are.  Each
+    one will require RAM for data, FILESORT_VARALIGN and sizeof(void*)
+    Assume that data+FILESORT_VARALIGN+sizeof(void*) is 4*data. */
+
+ if((datasize*4)<option_filesort_ramsize)
+    datasize=(datasize*4)/option_filesort_threads;
  else
     datasize=option_filesort_ramsize/option_filesort_threads;
 
- threads=(thread_data*)malloc(option_filesort_threads*sizeof(thread_data));
+ threads=(thread_data*)calloc(option_filesort_threads,sizeof(thread_data));
 
  for(i=0;i<option_filesort_threads;i++)
    {
-    threads[i].running=0;
-
     threads[i].data=malloc(datasize);
     threads[i].datap=NULL;
 
@@ -565,13 +571,13 @@ index_t filesort_vary(int fd_in,int fd_out,int (*pre_sort_function)(void*,index_
 
 #endif
 
-    threads[thread].datap=threads[thread].data+datasize;
+    threads[thread].datap=(void**)(threads[thread].data+datasize);
 
     threads[thread].n=0;
 
     /* Read in the data and create pointers */
 
-    while((ramused+FILESORT_VARSIZE+nextitemsize)<=(unsigned)((void*)threads[thread].datap-sizeof(void*)-threads[thread].data))
+    while((ramused+FILESORT_VARSIZE+nextitemsize)<=(size_t)((char*)threads[thread].datap-sizeof(void*)-threads[thread].data))
       {
        FILESORT_VARINT itemsize=nextitemsize;
 
@@ -701,9 +707,9 @@ index_t filesort_vary(int fd_in,int fd_out,int (*pre_sort_function)(void*,index_
       {
        if(!post_sort_function || post_sort_function(threads[0].datap[item],count_out))
          {
-          FILESORT_VARINT itemsize=*(FILESORT_VARINT*)(threads[0].datap[item]-FILESORT_VARSIZE);
+          FILESORT_VARINT itemsize=*(FILESORT_VARINT*)((char*)threads[0].datap[item]-FILESORT_VARSIZE);
 
-          WriteFileBuffered(fd_out,threads[0].datap[item]-FILESORT_VARSIZE,itemsize+FILESORT_VARSIZE);
+          WriteFileBuffered(fd_out,(char*)threads[0].datap[item]-FILESORT_VARSIZE,itemsize+FILESORT_VARSIZE);
           count_out++;
          }
       }
@@ -739,7 +745,7 @@ index_t filesort_vary(int fd_in,int fd_out,int (*pre_sort_function)(void*,index_
  heap=(int*)malloc((1+nfiles)*sizeof(int));
 
  data=threads[0].data;
- datap=data+datasize-nfiles*sizeof(void*);
+ datap=(void**)(data+datasize-nfiles*sizeof(void*));
 
  /* Fill the heap to start with */
 
@@ -752,7 +758,7 @@ index_t filesort_vary(int fd_in,int fd_out,int (*pre_sort_function)(void*,index_
 
     ReadFileBuffered(fds[i],&itemsize,FILESORT_VARSIZE);
 
-    *(FILESORT_VARINT*)(datap[i]-FILESORT_VARSIZE)=itemsize;
+    *(FILESORT_VARINT*)((char*)datap[i]-FILESORT_VARSIZE)=itemsize;
 
     ReadFileBuffered(fds[i],datap[i],itemsize);
 
@@ -791,9 +797,9 @@ index_t filesort_vary(int fd_in,int fd_out,int (*pre_sort_function)(void*,index_
 
     if(!post_sort_function || post_sort_function(datap[heap[index]],count_out))
       {
-       itemsize=*(FILESORT_VARINT*)(datap[heap[index]]-FILESORT_VARSIZE);
+       itemsize=*(FILESORT_VARINT*)((char*)datap[heap[index]]-FILESORT_VARSIZE);
 
-       WriteFileBuffered(fd_out,datap[heap[index]]-FILESORT_VARSIZE,itemsize+FILESORT_VARSIZE);
+       WriteFileBuffered(fd_out,(char*)datap[heap[index]]-FILESORT_VARSIZE,itemsize+FILESORT_VARSIZE);
        count_out++;
       }
 
@@ -804,7 +810,7 @@ index_t filesort_vary(int fd_in,int fd_out,int (*pre_sort_function)(void*,index_
       }
     else
       {
-       *(FILESORT_VARINT*)(datap[heap[index]]-FILESORT_VARSIZE)=itemsize;
+       *(FILESORT_VARINT*)((char*)datap[heap[index]]-FILESORT_VARSIZE)=itemsize;
 
        ReadFileBuffered(fds[heap[index]],datap[heap[index]],itemsize);
       }
@@ -947,9 +953,9 @@ static void *filesort_vary_heapsort_thread(thread_data *thread)
 
  for(item=0;item<thread->n;item++)
    {
-    FILESORT_VARINT itemsize=*(FILESORT_VARINT*)(thread->datap[item]-FILESORT_VARSIZE);
+    FILESORT_VARINT itemsize=*(FILESORT_VARINT*)((char*)thread->datap[item]-FILESORT_VARSIZE);
 
-    WriteFileBuffered(fd,thread->datap[item]-FILESORT_VARSIZE,itemsize+FILESORT_VARSIZE);
+    WriteFileBuffered(fd,(char*)thread->datap[item]-FILESORT_VARSIZE,itemsize+FILESORT_VARSIZE);
    }
 
  CloseFileBuffered(fd);
diff --git a/src/superx.c b/src/superx.c
index c8e504e..b7fc96b 100644
--- a/src/superx.c
+++ b/src/superx.c
@@ -3,7 +3,7 @@
 
  Part of the Routino routing software.
  ******************/ /******************
- This file Copyright 2008-2014 Andrew M. Bishop
+ This file Copyright 2008-2015 Andrew M. Bishop
 
  This program is free software: you can redistribute it and/or modify
  it under the terms of the GNU Affero General Public License as published by
@@ -492,8 +492,8 @@ SegmentsX *MergeSuperSegments(SegmentsX *segmentsx,SegmentsX *supersegmentsx)
 
 static Results *FindSuperRoutes(NodesX *nodesx,SegmentsX *segmentsx,WaysX *waysx,node_t start,Way *match)
 {
- static Results *results=NULL;
- static Queue *queue=NULL;
+ static Results *results=NULL; /* static allocation of return value (reset each call) */
+ static Queue *queue=NULL;     /* static allocation of internal value (reset each call) */
  Result *result1,*result2;
  WayX *wayx;
 
diff --git a/src/tagging.c b/src/tagging.c
index cba2e68..97af158 100644
--- a/src/tagging.c
+++ b/src/tagging.c
@@ -3,7 +3,7 @@
 
  Part of the Routino routing software.
  ******************/ /******************
- This file Copyright 2010-2014 Andrew M. Bishop
+ This file Copyright 2010-2015 Andrew M. Bishop
 
  This program is free software: you can redistribute it and/or modify
  it under the terms of the GNU Affero General Public License as published by
@@ -44,8 +44,14 @@
 #define TAGACTION_OUTPUT   6
 #define TAGACTION_LOGERROR 7
 
+static const char* const default_logerror_message="ignoring it";
 
-/* Local variables */
+
+/* Local variable (intialised before each use) */
+
+static int64_t current_id;
+
+/* Local parsing variables (re-initialised by DeleteXMLTaggingRules() function) */
 
 static TaggingRuleList NodeRules={NULL,0};
 static TaggingRuleList WayRules={NULL,0};
@@ -55,12 +61,7 @@ static int current_list_stack_depth=0;
 static TaggingRuleList **current_list_stack=NULL;
 static TaggingRuleList *current_list=NULL;
 
-static int64_t current_id;
-
-static char *default_logerror_message="ignoring it";
-
-
-/* Local functions */
+/* Local parsing functions */
 
 static TaggingRuleList *AppendTaggingRule(TaggingRuleList *rules,const char *k,const char *v,int action);
 static void AppendTaggingAction(TaggingRuleList *rules,const char *k,const char *v,int action,const char *message);
@@ -86,96 +87,96 @@ static int LogErrorType_function(const char *_tag_,int _type_,const char *k,cons
 
 /* The XML tag definitions (forward declarations) */
 
-static xmltag xmlDeclaration_tag;
-static xmltag RoutinoTaggingType_tag;
-static xmltag NodeType_tag;
-static xmltag WayType_tag;
-static xmltag RelationType_tag;
-static xmltag IfType_tag;
-static xmltag IfNotType_tag;
-static xmltag SetType_tag;
-static xmltag UnsetType_tag;
-static xmltag OutputType_tag;
-static xmltag LogErrorType_tag;
+static const xmltag xmlDeclaration_tag;
+static const xmltag RoutinoTaggingType_tag;
+static const xmltag NodeType_tag;
+static const xmltag WayType_tag;
+static const xmltag RelationType_tag;
+static const xmltag IfType_tag;
+static const xmltag IfNotType_tag;
+static const xmltag SetType_tag;
+static const xmltag UnsetType_tag;
+static const xmltag OutputType_tag;
+static const xmltag LogErrorType_tag;
 
 
 /* The XML tag definition values */
 
 /*+ The complete set of tags at the top level. +*/
-static xmltag *xml_toplevel_tags[]={&xmlDeclaration_tag,&RoutinoTaggingType_tag,NULL};
+static const xmltag * const xml_toplevel_tags[]={&xmlDeclaration_tag,&RoutinoTaggingType_tag,NULL};
 
 /*+ The xmlDeclaration type tag. +*/
-static xmltag xmlDeclaration_tag=
+static const xmltag xmlDeclaration_tag=
               {"xml",
                2, {"version","encoding"},
                NULL,
                {NULL}};
 
 /*+ The RoutinoTaggingType type tag. +*/
-static xmltag RoutinoTaggingType_tag=
+static const xmltag RoutinoTaggingType_tag=
               {"routino-tagging",
                0, {NULL},
                NULL,
                {&NodeType_tag,&WayType_tag,&RelationType_tag,NULL}};
 
 /*+ The NodeType type tag. +*/
-static xmltag NodeType_tag=
+static const xmltag NodeType_tag=
               {"node",
                0, {NULL},
                NodeType_function,
                {&IfType_tag,&IfNotType_tag,NULL}};
 
 /*+ The WayType type tag. +*/
-static xmltag WayType_tag=
+static const xmltag WayType_tag=
               {"way",
                0, {NULL},
                WayType_function,
                {&IfType_tag,&IfNotType_tag,NULL}};
 
 /*+ The RelationType type tag. +*/
-static xmltag RelationType_tag=
+static const xmltag RelationType_tag=
               {"relation",
                0, {NULL},
                RelationType_function,
                {&IfType_tag,&IfNotType_tag,NULL}};
 
 /*+ The IfType type tag. +*/
-static xmltag IfType_tag=
+static const xmltag IfType_tag=
               {"if",
                2, {"k","v"},
                IfType_function,
                {&IfType_tag,&IfNotType_tag,&SetType_tag,&UnsetType_tag,&OutputType_tag,&LogErrorType_tag,NULL}};
 
 /*+ The IfNotType type tag. +*/
-static xmltag IfNotType_tag=
+static const xmltag IfNotType_tag=
               {"ifnot",
                2, {"k","v"},
                IfNotType_function,
                {&IfType_tag,&IfNotType_tag,&SetType_tag,&UnsetType_tag,&OutputType_tag,&LogErrorType_tag,NULL}};
 
 /*+ The SetType type tag. +*/
-static xmltag SetType_tag=
+static const xmltag SetType_tag=
               {"set",
                2, {"k","v"},
                SetType_function,
                {NULL}};
 
 /*+ The UnsetType type tag. +*/
-static xmltag UnsetType_tag=
+static const xmltag UnsetType_tag=
               {"unset",
                1, {"k"},
                UnsetType_function,
                {NULL}};
 
 /*+ The OutputType type tag. +*/
-static xmltag OutputType_tag=
+static const xmltag OutputType_tag=
               {"output",
                2, {"k","v"},
                OutputType_function,
                {NULL}};
 
 /*+ The LogErrorType type tag. +*/
-static xmltag LogErrorType_tag=
+static const xmltag LogErrorType_tag=
               {"logerror",
                3, {"k","v","message"},
                LogErrorType_function,
@@ -466,6 +467,8 @@ int ParseXMLTaggingRules(const char *filename)
 
  fd=OpenFile(filename);
 
+ /* Initialise variables used for parsing */
+
  retval=ParseXML(fd,xml_toplevel_tags,XMLPARSE_UNKNOWN_ATTR_ERRNONAME);
 
  CloseFile(fd);
@@ -486,6 +489,10 @@ int ParseXMLTaggingRules(const char *filename)
 
 void DeleteXMLTaggingRules(void)
 {
+ current_list_stack_depth=0;
+ current_list_stack=NULL;
+ current_list=NULL;
+
  DeleteTaggingRuleList(&NodeRules);
  DeleteTaggingRuleList(&WayRules);
  DeleteTaggingRuleList(&RelationRules);
@@ -569,7 +576,7 @@ static void AppendTaggingAction(TaggingRuleList *rules,const char *k,const char
  if(message)
     rules->rules[rules->nrules-1].message=strcpy(malloc(strlen(message)+1),message);
  else
-    rules->rules[rules->nrules-1].message=default_logerror_message;
+    rules->rules[rules->nrules-1].message=(char*)default_logerror_message;
 
  rules->rules[rules->nrules-1].rulelist=NULL;
 }
@@ -603,6 +610,9 @@ void DeleteTaggingRuleList(TaggingRuleList *rules)
 
  if(rules->rules)
     free(rules->rules);
+
+ rules->rules=NULL;
+ rules->nrules=0;
 }
 
 
@@ -740,7 +750,7 @@ void DeleteTag(TagList *tags,const char *k)
 
 char *StringifyTag(TagList *tags)
 {
- static char *string=NULL;
+ static char *string=NULL; /* static allocation of return value */
  int i,length=0,used=0;
 
  for(i=0;i<tags->ntags;i++)
diff --git a/src/test/Makefile b/src/test/Makefile
index 3f038a5..66ab1a7 100644
--- a/src/test/Makefile
+++ b/src/test/Makefile
@@ -2,7 +2,7 @@
 #
 # Part of the Routino routing software.
 #
-# This file Copyright 2011-2014 Andrew M. Bishop
+# This file Copyright 2011-2015 Andrew M. Bishop
 #
 # This program is free software: you can redistribute it and/or modify
 # it under the terms of the GNU Affero General Public License as published by
@@ -24,11 +24,12 @@ include ../../Makefile.conf
 
 # executables
 
-ROUTINO_EXE=../planetsplitter ../planetsplitter-slim \
-            ../router ../router-slim \
-            ../filedumper ../filedumper-slim
+ROUTINO_EXE=planetsplitter$(.EXE) planetsplitter-slim$(.EXE) \
+            router$(.EXE)         router-slim$(.EXE) \
+            router+lib$(.EXE)     router+lib-slim$(.EXE) \
+            filedumper$(.EXE)     filedumper-slim$(.EXE)
 
-EXE=is-fast-math
+EXE=is-fast-math$(.EXE)
 
 # Compilation targets
 
@@ -41,54 +42,15 @@ all :
 
 ########
 
-test : $(ROUTINO_EXE) $(EXE)
-	@status=true ;\
-	echo ""; \
-	./is-fast-math message; \
-	for script in $(S); do \
-	   echo "" ;\
-	   echo "Testing: $$script (non-slim, no pruning) ... " ;\
-	   if ./$$script fat; then echo "... passed"; else echo "... FAILED"; status=false; fi ;\
-	done ;\
-	for script in $(S); do \
-	   echo "" ;\
-	   echo "Testing: $$script (slim, no pruning) ... " ;\
-	   if ./$$script slim; then echo "... passed"; else echo "... FAILED"; status=false; fi ;\
-	done ;\
-	echo "" ;\
-	if $$status; then echo "Success: all tests passed"; else echo "Warning: Some tests FAILED"; fi ;\
-	$$status || exit 1 ;\
-	echo "" ;\
-	echo "Comparing: slim and non-slim results ... " ;\
-	if diff -q -r slim fat; then echo "... matched"; else echo "... match FAILED"; status=false; fi ;\
-	echo "" ;\
-	if $$status; then echo "Success: slim and non-slim results match"; else echo "Warning: slim and non-slim results are different - FAILED"; fi ;\
-	for script in $(S); do \
-	   echo "" ;\
-	   echo "Testing: $$script (non-slim, pruning) ... " ;\
-	   if ./$$script fat prune; then echo "... passed"; else echo "... FAILED"; status=false; fi ;\
-	done ;\
-	for script in $(S); do \
-	   echo "" ;\
-	   echo "Testing: $$script (slim, pruning) ... " ;\
-	   if ./$$script slim prune; then echo "... passed"; else echo "... FAILED"; status=false; fi ;\
-	done ;\
-	echo "" ;\
-	if $$status; then echo "Success: all tests passed"; else echo "Warning: Some tests FAILED"; fi ;\
-	$$status || exit 1 ;\
-	echo "" ;\
-	echo "Comparing: slim and non-slim results ... " ;\
-	if diff -q -r slim-pruned fat-pruned; then echo "... matched"; else echo "... match FAILED"; status=false; fi ;\
-	echo "" ;\
-	if $$status; then echo "Success: slim and non-slim results match"; else echo "Warning: slim and non-slim results are different - FAILED"; fi ;\
-	$$status
+test : test-exe $(EXE)
+	@./run-tests.sh $(S)
 
 ########
 
-$(ROUTINO_EXE) ::
-	cd .. && $(MAKE) $(notdir $@)
+test-exe :
+	cd .. && $(MAKE) $(ROUTINO_EXE)
 
-is-fast-math : is-fast-math.o
+is-fast-math$(.EXE) : is-fast-math.o
 	$(LD) $< -o $@ $(LDFLAGS)
 
 is-fast-math.o : is-fast-math.c
@@ -103,19 +65,23 @@ install:
 clean:
 	rm -rf fat
 	rm -rf slim
+	rm -rf fat+lib
+	rm -rf slim+lib
 	rm -rf fat-pruned
 	rm -rf slim-pruned
 	rm -f *.log
 	rm -f *~
 	rm -f *.o
+	rm -f $(EXE)
 	rm -f core
 	rm -f *.gcda *.gcno *.gcov gmon.out
 
 ########
 
 distclean: clean
-	rm -f is-fast-math
 
 ########
 
 .PHONY:: all test install clean distclean
+
+.PHONY:: test-exe
diff --git a/src/test/a-b-c-d.sh b/src/test/a-b-c-d.sh
index d1cbdf2..833e0fc 100755
--- a/src/test/a-b-c-d.sh
+++ b/src/test/a-b-c-d.sh
@@ -18,6 +18,17 @@ else
     dir="fat"
 fi
 
+# Libroutino or not libroutino
+
+LD_LIBRARY_PATH=$PWD/..:$LD_LIBRARY_PATH
+export LD_LIBRARY_PATH
+
+if [ "$2" = "lib" ]; then
+    lib="+lib"
+else
+    lib=""
+fi
+
 # Pruned or non-pruned
 
 if [ "$2" = "prune" ]; then
@@ -30,7 +41,7 @@ fi
 
 # Create the output directory
 
-dir="$dir$pruned"
+dir=$dir$lib$pruned
 
 [ -d $dir ] || mkdir $dir
 
@@ -42,7 +53,7 @@ debugger=
 # Name related options
 
 osm=$name.osm
-log=$name$slim$pruned.log
+log=$name$slim$lib$pruned.log
 
 option_prefix="--prefix=$name"
 option_dir="--dir=$dir"
@@ -50,8 +61,14 @@ option_dir="--dir=$dir"
 # Generic program options
 
 option_planetsplitter="--loggable --tagging=../../xml/routino-tagging.xml --errorlog $prune"
+
 option_filedumper="--dump-osm"
-option_router="--loggable --transport=motorcar --profiles=../../xml/routino-profiles.xml --translations=copyright.xml"
+
+option_router="--profile=motorcar --profiles=../../xml/routino-profiles.xml --translations=copyright.xml"
+
+if [ ! "$2" = "lib" ]; then
+    option_router="$option_router --loggable"
+fi
 
 # Run planetsplitter
 
@@ -89,8 +106,8 @@ for waypoint in $waypoints; do
 
     [ -d $dir/$name-$waypoint ] || mkdir $dir/$name-$waypoint
 
-    echo ../router$slim $option_dir $option_prefix $option_osm $option_router $waypoint_a $waypoint_b $waypoint_c $waypoint_d >> $log
-    $debugger ../router$slim $option_dir $option_prefix $option_osm $option_router $waypoint_a $waypoint_b $waypoint_c $waypoint_d >> $log
+    echo ../router$lib$slim $option_dir $option_prefix $option_osm $option_router $waypoint_a $waypoint_b $waypoint_c $waypoint_d >> $log
+    $debugger ../router$lib$slim $option_dir $option_prefix $option_osm $option_router $waypoint_a $waypoint_b $waypoint_c $waypoint_d >> $log
 
     mv shortest* $dir/$name-$waypoint
 
diff --git a/src/test/a-b-c.sh b/src/test/a-b-c.sh
index f13f51b..b99cf7f 100755
--- a/src/test/a-b-c.sh
+++ b/src/test/a-b-c.sh
@@ -18,6 +18,17 @@ else
     dir="fat"
 fi
 
+# Libroutino or not libroutino
+
+LD_LIBRARY_PATH=$PWD/..:$LD_LIBRARY_PATH
+export LD_LIBRARY_PATH
+
+if [ "$2" = "lib" ]; then
+    lib="+lib"
+else
+    lib=""
+fi
+
 # Pruned or non-pruned
 
 if [ "$2" = "prune" ]; then
@@ -30,7 +41,7 @@ fi
 
 # Create the output directory
 
-dir="$dir$pruned"
+dir="$dir$lib$pruned"
 
 [ -d $dir ] || mkdir $dir
 
@@ -42,7 +53,7 @@ debugger=
 # Name related options
 
 osm=$name.osm
-log=$name$slim$pruned.log
+log=$name$lib$slim$pruned.log
 
 option_prefix="--prefix=$name"
 option_dir="--dir=$dir"
@@ -50,8 +61,14 @@ option_dir="--dir=$dir"
 # Generic program options
 
 option_planetsplitter="--loggable --tagging=../../xml/routino-tagging.xml --errorlog $prune"
+
 option_filedumper="--dump-osm"
-option_router="--loggable --transport=motorcar --profiles=../../xml/routino-profiles.xml --translations=copyright.xml"
+
+option_router="--profile=motorcar --profiles=../../xml/routino-profiles.xml --translations=copyright.xml"
+
+if [ ! "$2" = "lib" ]; then
+    option_router="$option_router --loggable"
+fi
 
 # Run planetsplitter
 
@@ -88,8 +105,8 @@ for waypoint in $waypoints; do
 
     [ -d $dir/$name-$waypoint ] || mkdir $dir/$name-$waypoint
 
-    echo ../router$slim $option_dir $option_prefix $option_osm $option_router $waypoint_a $waypoint_b $waypoint_c >> $log
-    $debugger ../router$slim $option_dir $option_prefix $option_osm $option_router $waypoint_a $waypoint_b $waypoint_c >> $log
+    echo ../router$lib$slim $option_dir $option_prefix $option_osm $option_router $waypoint_a $waypoint_b $waypoint_c >> $log
+    $debugger ../router$lib$slim $option_dir $option_prefix $option_osm $option_router $waypoint_a $waypoint_b $waypoint_c >> $log
 
     mv shortest* $dir/$name-$waypoint
 
diff --git a/src/test/a-b.sh b/src/test/a-b.sh
index 9064d79..04ed49a 100755
--- a/src/test/a-b.sh
+++ b/src/test/a-b.sh
@@ -18,6 +18,17 @@ else
     dir="fat"
 fi
 
+# Libroutino or not libroutino
+
+LD_LIBRARY_PATH=$PWD/..:$LD_LIBRARY_PATH
+export LD_LIBRARY_PATH
+
+if [ "$2" = "lib" ]; then
+    lib="+lib"
+else
+    lib=""
+fi
+
 # Pruned or non-pruned
 
 if [ "$2" = "prune" ]; then
@@ -30,7 +41,7 @@ fi
 
 # Create the output directory
 
-dir="$dir$pruned"
+dir="$dir$lib$pruned"
 
 [ -d $dir ] || mkdir $dir
 
@@ -42,7 +53,7 @@ debugger=
 # Name related options
 
 osm=$name.osm
-log=$name$slim$pruned.log
+log=$name$lib$slim$pruned.log
 
 option_prefix="--prefix=$name"
 option_dir="--dir=$dir"
@@ -50,8 +61,14 @@ option_dir="--dir=$dir"
 # Generic program options
 
 option_planetsplitter="--loggable --tagging=../../xml/routino-tagging.xml --errorlog $prune"
+
 option_filedumper="--dump-osm"
-option_router="--loggable --transport=motorcar --profiles=../../xml/routino-profiles.xml --translations=copyright.xml"
+
+option_router="--profile=motorcar --profiles=../../xml/routino-profiles.xml --translations=copyright.xml"
+
+if [ ! "$2" = "lib" ]; then
+    option_router="$option_router --loggable"
+fi
 
 # Run planetsplitter
 
@@ -87,8 +104,8 @@ for waypoint in $waypoints; do
 
     [ -d $dir/$name-$waypoint ] || mkdir $dir/$name-$waypoint
 
-    echo ../router$slim $option_dir $option_prefix $option_osm $option_router $waypoint_a $waypoint_b >> $log
-    $debugger ../router$slim $option_dir $option_prefix $option_osm $option_router $waypoint_a $waypoint_b >> $log
+    echo ../router$lib$slim $option_dir $option_prefix $option_osm $option_router $waypoint_a $waypoint_b >> $log
+    $debugger ../router$lib$slim $option_dir $option_prefix $option_osm $option_router $waypoint_a $waypoint_b >> $log
 
     mv shortest* $dir/$name-$waypoint
 
diff --git a/src/test/copyright.xml b/src/test/copyright.xml
index 8cbc553..d5f8fcd 100644
--- a/src/test/copyright.xml
+++ b/src/test/copyright.xml
@@ -5,7 +5,7 @@
 
      Part of the Routino routing software.
      ============================================================
-     This file Copyright 2010-2011 Andrew M. Bishop
+     This file Copyright 2010-2015 Andrew M. Bishop
 
      This program is free software: you can redistribute it and/or modify
      it under the terms of the GNU Affero General Public License as published by
@@ -16,7 +16,7 @@
 <routino-translations xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                       xsi:noNamespaceSchemaLocation="http://www.routino.org/xml/routino-translations.xsd">
 
-  <language lang="en">
+  <language lang="en" language="English">
 
     <!-- Copyright of the data being routed, not of this file  -->
     <copyright>
diff --git a/src/test/cycle-drive.sh b/src/test/cycle-drive.sh
index 4e7a329..d63e394 100755
--- a/src/test/cycle-drive.sh
+++ b/src/test/cycle-drive.sh
@@ -18,6 +18,17 @@ else
     dir="fat"
 fi
 
+# Libroutino or not libroutino
+
+LD_LIBRARY_PATH=$PWD/..:$LD_LIBRARY_PATH
+export LD_LIBRARY_PATH
+
+if [ "$2" = "lib" ]; then
+    lib="+lib"
+else
+    lib=""
+fi
+
 # Pruned or non-pruned
 
 if [ "$2" = "prune" ]; then
@@ -30,7 +41,7 @@ fi
 
 # Create the output directory
 
-dir="$dir$pruned"
+dir=$dir$lib$pruned
 
 [ -d $dir ] || mkdir $dir
 
@@ -42,7 +53,7 @@ debugger=
 # Name related options
 
 osm=$name.osm
-log=$name$slim$pruned.log
+log=$name$lib$slim$pruned.log
 
 option_prefix="--prefix=$name"
 option_dir="--dir=$dir"
@@ -50,8 +61,14 @@ option_dir="--dir=$dir"
 # Generic program options
 
 option_planetsplitter="--loggable --tagging=../../xml/routino-tagging.xml --errorlog $prune"
+
 option_filedumper="--dump-osm"
-option_router="--loggable --profiles=../../xml/routino-profiles.xml --translations=copyright.xml"
+
+option_router="--profiles=../../xml/routino-profiles.xml --translations=copyright.xml"
+
+if [ ! "$2" = "lib" ]; then
+    option_router="$option_router --loggable"
+fi
 
 # Run planetsplitter
 
@@ -74,13 +91,13 @@ waypoints=`perl waypoints.pl $osm list`
 waypoint_start=`perl waypoints.pl $osm WPstart 1`
 waypoint_finish=`perl waypoints.pl $osm WPfinish 2`
 
-# Run the router for each transport type
+# Run the router for each profile type
 
-transports="motorcar bicycle"
+profiles="motorcar bicycle"
 
-for transport in $transports; do
+for profile in $profiles; do
 
-    case $transport in
+    case $profile in
         motorcar) waypoint=WP01 ;;
         *)        waypoint=WP02 ;;
     esac
@@ -89,8 +106,8 @@ for transport in $transports; do
 
     [ -d $dir/$name-$waypoint ] || mkdir $dir/$name-$waypoint
 
-    echo ../router$slim $option_dir $option_prefix $option_osm $option_router --transport=$transport $waypoint_start $waypoint_finish >> $log
-    $debugger ../router$slim $option_dir $option_prefix $option_osm $option_router --transport=$transport $waypoint_start $waypoint_finish >> $log
+    echo ../router$lib$slim $option_dir $option_prefix $option_osm $option_router --profile=$profile $waypoint_start $waypoint_finish >> $log
+    $debugger ../router$lib$slim $option_dir $option_prefix $option_osm $option_router --profile=$profile $waypoint_start $waypoint_finish >> $log
 
     mv shortest* $dir/$name-$waypoint
 
diff --git a/src/test/only-split.sh b/src/test/only-split.sh
index b823d8c..1a228ea 100755
--- a/src/test/only-split.sh
+++ b/src/test/only-split.sh
@@ -18,6 +18,17 @@ else
     dir="fat"
 fi
 
+# Libroutino or not libroutino
+
+LD_LIBRARY_PATH=$PWD/..:$LD_LIBRARY_PATH
+export LD_LIBRARY_PATH
+
+if [ "$2" = "lib" ]; then
+    lib="+lib"
+else
+    lib=""
+fi
+
 # Pruned or non-pruned
 
 if [ "$2" = "prune" ]; then
@@ -37,7 +48,7 @@ fi
 
 # Create the output directory
 
-dir="$dir$pruned"
+dir=$dir$lib$pruned
 
 [ -d $dir ] || mkdir $dir
 
@@ -49,7 +60,7 @@ debugger=
 # Name related options
 
 osm=$name.osm
-log=$name$slim$pruned.log
+log=$name$lib$slim$pruned.log
 
 option_prefix="--prefix=$name"
 option_dir="--dir=$dir"
diff --git a/src/test/run-tests.sh b/src/test/run-tests.sh
new file mode 100755
index 0000000..3ba5326
--- /dev/null
+++ b/src/test/run-tests.sh
@@ -0,0 +1,101 @@
+#!/bin/sh
+
+status=true
+
+run_a_test ()
+{
+    script=$1
+    shift
+
+    if ./$script $@ ; then
+        echo "... passed"
+    else
+        echo "... FAILED"
+        status=false
+    fi
+}
+
+compare_results ()
+{
+    if diff -q -r $1 $2; then
+        echo "... matched"
+    else
+        echo "... match FAILED"
+        status=false
+    fi
+}
+
+
+# Initial informational message
+
+echo ""
+./is-fast-math message
+
+
+# Loop round the different test types
+
+for type in 1 2 3; do
+
+    case $type in
+        1)
+            suffix=""
+            arg=""
+            description=""
+            ;;
+        2)
+            suffix="+lib"
+            arg="lib"
+            description="libroutino"
+            ;;
+        3)
+            suffix="-pruned"
+            arg="prune"
+            description="pruned"
+            ;;
+    esac
+
+    # Normal mode
+
+    for script in $@; do
+        echo ""
+        echo "Testing: $script (non-slim, $description) ... "
+        run_a_test $script fat $arg
+    done
+
+    # Normal mode
+
+    for script in $@; do
+        echo ""
+        echo "Testing: $script (slim, $description) ... "
+        run_a_test $script slim $arg
+    done
+
+    # Check results
+
+    if $status; then
+        echo "Success: all tests passed"
+    else
+        echo "Warning: Some tests FAILED"
+        exit 1
+    fi
+
+    # Compare normal/slim results
+
+    echo ""
+
+    echo "Comparing: slim and non-slim results ($description) ... "
+
+    compare_results fat$suffix slim$suffix
+
+    # Check comparison
+
+    if $status; then
+        echo "Success: slim and non-slim results match"
+    else
+        echo "Warning: slim and non-slim results are different"
+        exit 1
+    fi
+
+done
+
+exit 0
diff --git a/src/test/start-1-finish.sh b/src/test/start-1-finish.sh
index a448943..c105524 100755
--- a/src/test/start-1-finish.sh
+++ b/src/test/start-1-finish.sh
@@ -18,6 +18,17 @@ else
     dir="fat"
 fi
 
+# Libroutino or not libroutino
+
+LD_LIBRARY_PATH=$PWD/..:$LD_LIBRARY_PATH
+export LD_LIBRARY_PATH
+
+if [ "$2" = "lib" ]; then
+    lib="+lib"
+else
+    lib=""
+fi
+
 # Pruned or non-pruned
 
 if [ "$2" = "prune" ]; then
@@ -30,7 +41,7 @@ fi
 
 # Create the output directory
 
-dir="$dir$pruned"
+dir=$dir$lib$pruned
 
 [ -d $dir ] || mkdir $dir
 
@@ -42,7 +53,7 @@ debugger=
 # Name related options
 
 osm=$name.osm
-log=$name$slim$pruned.log
+log=$name$lib$slim$pruned.log
 
 option_prefix="--prefix=$name"
 option_dir="--dir=$dir"
@@ -50,8 +61,14 @@ option_dir="--dir=$dir"
 # Generic program options
 
 option_planetsplitter="--loggable --tagging=../../xml/routino-tagging.xml --errorlog $prune"
+
 option_filedumper="--dump-osm"
-option_router="--loggable --transport=motorcar --profiles=../../xml/routino-profiles.xml --translations=copyright.xml"
+
+option_router="--profile=motorcar --profiles=../../xml/routino-profiles.xml --translations=copyright.xml"
+
+if [ ! "$2" = "lib" ]; then
+    option_router="$option_router --loggable"
+fi
 
 # Run planetsplitter
 
@@ -87,8 +104,8 @@ for waypoint in $waypoints; do
 
     [ -d $dir/$name-$waypoint ] || mkdir $dir/$name-$waypoint
 
-    echo ../router$slim $option_dir $option_prefix $option_osm $option_router $waypoint_start $waypoint_test $waypoint_finish >> $log
-    $debugger ../router$slim $option_dir $option_prefix $option_osm $option_router $waypoint_start $waypoint_test $waypoint_finish >> $log
+    echo ../router$lib$slim $option_dir $option_prefix $option_osm $option_router $waypoint_start $waypoint_test $waypoint_finish >> $log
+    $debugger ../router$lib$slim $option_dir $option_prefix $option_osm $option_router $waypoint_start $waypoint_test $waypoint_finish >> $log
 
     mv shortest* $dir/$name-$waypoint
 
diff --git a/src/translations.c b/src/translations.c
index ff2796a..8ca2d5c 100644
--- a/src/translations.c
+++ b/src/translations.c
@@ -3,7 +3,7 @@
 
  Part of the Routino routing software.
  ******************/ /******************
- This file Copyright 2010-2013 Andrew M. Bishop
+ This file Copyright 2010-2015 Andrew M. Bishop
 
  This program is free software: you can redistribute it and/or modify
  it under the terms of the GNU Affero General Public License as published by
@@ -29,65 +29,101 @@
 #include "xmlparse.h"
 
 
-/* Global variables - default English values - Must not require any UTF-8 encoding */
+/* Default English translations - Must not require any UTF-8 encoding */
 
-char *translate_raw_copyright_creator[2]={"Creator","Routino - http://www.routino.org/"};
-char *translate_raw_copyright_source[2] ={NULL,NULL};
-char *translate_raw_copyright_license[2]={NULL,NULL};
+static Translation default_translation=
+{
+ .lang = "--",
+ .language = "English (built-in)",
+
+ .raw_copyright_creator = {"Creator","Routino - http://www.routino.org/"},
+ .raw_copyright_source  = {NULL,NULL},
+ .raw_copyright_license = {NULL,NULL},
+
+ .xml_copyright_creator = {"Creator","Routino - http://www.routino.org/"},
+ .xml_copyright_source  = {NULL,NULL},
+ .xml_copyright_license = {NULL,NULL},
+
+ .xml_heading = {"South","South-West","West","North-West","North","North-East","East","South-East","South"},
+ .xml_turn    = {"Very sharp left","Sharp left","Left","Slight left","Straight on","Slight right","Right","Sharp right","Very sharp right"},
+ .xml_ordinal = {"First","Second","Third","Fourth","Fifth","Sixth","Seventh","Eighth","Ninth","Tenth"},
+
+ .notxml_heading = {"South","South-West","West","North-West","North","North-East","East","South-East","South"},
+ .notxml_turn    = {"Very sharp left","Sharp left","Left","Slight left","Straight on","Slight right","Right","Sharp right","Very sharp right"},
+ .notxml_ordinal = {"First","Second","Third","Fourth","Fifth","Sixth","Seventh","Eighth","Ninth","Tenth"},
+
+ .raw_highway = {"","motorway","trunk road","primary road","secondary road","tertiary road","unclassified road","residential road","service road","track","cycleway","path","steps","ferry"},
+
+ .xml_route_shortest = "Shortest",
+ .xml_route_quickest = "Quickest",
+
+ .html_waypoint   = "<span class='w'>Waypoint</span>", /* span tag added when reading XML translations file */
+ .html_junction   = "Junction",
+ .html_roundabout = "Roundabout",
+
+ .html_title   = "%s Route",
+ .html_start   = "<tr class='n'>Start at %s, head <span class='b'>%s</span>\n", /* span tags added when reading XML translations file */
+ .html_node    = "<tr class='n'>At %s, go <span class='t'>%s</span> heading <span class='b'>%s</span>\n", /* span tags added when reading XML translations file */
+ .html_rbnode  = "<tr class='n'>Leave %s, take the <span class='b'>%s</span> exit heading <span class='b'>%s</span>\n", /* span tags added when reading XML translations file */
+ .html_segment = "<tr class='s'>Follow <span class='h'>%s</span> for <span class='d'>%.3f km, %.1f min</span>", /* span tags added when reading XML translations file */
+ .html_stop    = "<tr class='n'>Stop at %s\n",
+ .html_total   = "<tr class='t'><span class='j'>Total %.1f km, %.0f minutes</span>\n",/* span tags added when reading XML translations file */
+ .html_subtotal= "<span class='j'>%.1f km, %.0f minutes</span>\n",/* span tag added when reading XML translations file */
 
-char *translate_xml_copyright_creator[2]={"Creator","Routino - http://www.routino.org/"};
-char *translate_xml_copyright_source[2] ={NULL,NULL};
-char *translate_xml_copyright_license[2]={NULL,NULL};
+ .nothtml_waypoint   = "Waypoint",
+ .nothtml_junction   = "Junction",
+ .nothtml_roundabout = "Roundabout",
 
-char *translate_xml_heading[9] ={"South","South-West","West","North-West","North","North-East","East","South-East","South"};
-char *translate_xml_turn[9]    ={"Very sharp left","Sharp left","Left","Slight left","Straight on","Slight right","Right","Sharp right","Very sharp right"};
-char *translate_xml_ordinal[10]={"First","Second","Third","Fourth","Fifth","Sixth","Seventh","Eighth","Ninth","Tenth"};
+ .nothtml_title   = "%s Route",
+ .nothtml_start   = "Start at %s, head %s",
+ .nothtml_node    = "At %s, go %s heading %s",
+ .nothtml_rbnode  = "Leave %s, take the %s exit heading %s",
+ .nothtml_segment = "Follow %s for %.3f km, %.1f min",
+ .nothtml_stop    = "Stop at %s",
+ .nothtml_total   = "Total %.1f km, %.0f minutes",
+ .nothtml_subtotal= "%.1f km, %.0f minutes",
 
-char *translate_raw_highway[Highway_Count]={"","motorway","trunk road","primary road","secondary road","tertiary road","unclassified road","residential road","service road","track","cycleway","path","steps","ferry"};
+ .gpx_desc  = "%s route between 'start' and 'finish' waypoints",
+ .gpx_name  = "%s route",
+ .gpx_step  = "%s on '%s' for %.3f km, %.1f min",
+ .gpx_final = "Total Journey %.1f km, %.0f minutes",
 
-char *translate_xml_route_shortest="Shortest";
-char *translate_xml_route_quickest="Quickest";
+ .gpx_start  = "START",
+ .gpx_inter  = "INTER",
+ .gpx_trip   = "TRIP",
+ .gpx_finish = "FINISH"
+};
 
-char *translate_html_waypoint  ="<span class='w'>Waypoint</span>"; /* when reading XML translations file span is added */
-char *translate_html_junction  ="Junction";
-char *translate_html_roundabout="Roundabout";
 
-char *translate_html_title     ="%s Route";
-char *translate_html_start[2]  ={"Start" ,"At %s, head %s"};
-char *translate_html_node[2]   ={"At"    ,"%s, go %s heading %s"};
-char *translate_html_rbnode[2] ={"Leave" ,"%s, take the %s exit heading %s"};
-char *translate_html_segment[2]={"Follow","%s for %.3f km, %.1f min"};
-char *translate_html_stop[2]   ={"Stop"  ,"At %s"};
-char *translate_html_total[2]  ={"Total" ,"%.1f km, %.0f minutes"};
+/* Local variables (re-intialised by FreeXMLTranslations() function) */
 
-char *translate_gpx_desc ="%s route between 'start' and 'finish' waypoints";
-char *translate_gpx_name ="%s route";
-char *translate_gpx_step ="%s on '%s' for %.3f km, %.1f min";
-char *translate_gpx_final="Total Journey %.1f km, %.0f minutes";
+/*+ The translations that have been loaded from file. +*/
+static Translation **loaded_translations=NULL;
 
-char *translate_gpx_start ="START";
-char *translate_gpx_inter ="INTER";
-char *translate_gpx_trip  ="TRIP";
-char *translate_gpx_finish="FINISH";
+/*+ The number of translations that have been loaded from file. +*/
+static int nloaded_translations=0;
 
 
-/* Local variables */
+/* Local variables (re-initialised for each file) */
 
-/*+ The language that is to be stored. +*/
-static const char *store_lang=NULL;
+/*+ Store all of the translations. +*/
+static int store_all;
+
+/*+ The translation language that is to be stored. +*/
+static const char *store_lang;
 
 /*+ This current language is to be stored. +*/
-static int store=0;
+static int store;
 
 /*+ The chosen language has been stored. +*/
-static int stored=0;
+static int stored;
 
 
 /* The XML tag processing function prototypes */
 
 //static int xmlDeclaration_function(const char *_tag_,int _type_,const char *version,const char *encoding);
 //static int RoutinoTranslationsType_function(const char *_tag_,int _type_);
-static int LanguageType_function(const char *_tag_,int _type_,const char *lang);
+static int LanguageType_function(const char *_tag_,int _type_,const char *lang,const char *language);
 //static int CopyrightType_function(const char *_tag_,int _type_);
 static int TurnType_function(const char *_tag_,int _type_,const char *direction,const char *string);
 static int HeadingType_function(const char *_tag_,int _type_,const char *direction,const char *string);
@@ -101,12 +137,13 @@ static int CopyrightSourceType_function(const char *_tag_,int _type_,const char
 static int CopyrightLicenseType_function(const char *_tag_,int _type_,const char *string,const char *text);
 static int HTMLWaypointType_function(const char *_tag_,int _type_,const char *type,const char *string);
 static int HTMLTitleType_function(const char *_tag_,int _type_,const char *text);
-static int HTMLStartType_function(const char *_tag_,int _type_,const char *string,const char *text);
-static int HTMLNodeType_function(const char *_tag_,int _type_,const char *string,const char *text);
-static int HTMLRBNodeType_function(const char *_tag_,int _type_,const char *string,const char *text);
-static int HTMLSegmentType_function(const char *_tag_,int _type_,const char *string,const char *text);
-static int HTMLStopType_function(const char *_tag_,int _type_,const char *string,const char *text);
-static int HTMLTotalType_function(const char *_tag_,int _type_,const char *string,const char *text);
+static int HTMLStartType_function(const char *_tag_,int _type_,const char *text);
+static int HTMLNodeType_function(const char *_tag_,int _type_,const char *text);
+static int HTMLRBNodeType_function(const char *_tag_,int _type_,const char *text);
+static int HTMLSegmentType_function(const char *_tag_,int _type_,const char *text);
+static int HTMLStopType_function(const char *_tag_,int _type_,const char *text);
+static int HTMLTotalType_function(const char *_tag_,int _type_,const char *text);
+static int HTMLSubtotalType_function(const char *_tag_,int _type_,const char *text);
 static int GPXWaypointType_function(const char *_tag_,int _type_,const char *type,const char *string);
 static int GPXDescType_function(const char *_tag_,int _type_,const char *text);
 static int GPXNameType_function(const char *_tag_,int _type_,const char *text);
@@ -116,224 +153,232 @@ static int GPXFinalType_function(const char *_tag_,int _type_,const char *text);
 
 /* The XML tag definitions (forward declarations) */
 
-static xmltag xmlDeclaration_tag;
-static xmltag RoutinoTranslationsType_tag;
-static xmltag LanguageType_tag;
-static xmltag CopyrightType_tag;
-static xmltag TurnType_tag;
-static xmltag HeadingType_tag;
-static xmltag OrdinalType_tag;
-static xmltag HighwayType_tag;
-static xmltag RouteType_tag;
-static xmltag HTMLType_tag;
-static xmltag GPXType_tag;
-static xmltag CopyrightCreatorType_tag;
-static xmltag CopyrightSourceType_tag;
-static xmltag CopyrightLicenseType_tag;
-static xmltag HTMLWaypointType_tag;
-static xmltag HTMLTitleType_tag;
-static xmltag HTMLStartType_tag;
-static xmltag HTMLNodeType_tag;
-static xmltag HTMLRBNodeType_tag;
-static xmltag HTMLSegmentType_tag;
-static xmltag HTMLStopType_tag;
-static xmltag HTMLTotalType_tag;
-static xmltag GPXWaypointType_tag;
-static xmltag GPXDescType_tag;
-static xmltag GPXNameType_tag;
-static xmltag GPXStepType_tag;
-static xmltag GPXFinalType_tag;
+static const xmltag xmlDeclaration_tag;
+static const xmltag RoutinoTranslationsType_tag;
+static const xmltag LanguageType_tag;
+static const xmltag CopyrightType_tag;
+static const xmltag TurnType_tag;
+static const xmltag HeadingType_tag;
+static const xmltag OrdinalType_tag;
+static const xmltag HighwayType_tag;
+static const xmltag RouteType_tag;
+static const xmltag HTMLType_tag;
+static const xmltag GPXType_tag;
+static const xmltag CopyrightCreatorType_tag;
+static const xmltag CopyrightSourceType_tag;
+static const xmltag CopyrightLicenseType_tag;
+static const xmltag HTMLWaypointType_tag;
+static const xmltag HTMLTitleType_tag;
+static const xmltag HTMLStartType_tag;
+static const xmltag HTMLNodeType_tag;
+static const xmltag HTMLRBNodeType_tag;
+static const xmltag HTMLSegmentType_tag;
+static const xmltag HTMLStopType_tag;
+static const xmltag HTMLTotalType_tag;
+static const xmltag HTMLSubtotalType_tag;
+static const xmltag GPXWaypointType_tag;
+static const xmltag GPXDescType_tag;
+static const xmltag GPXNameType_tag;
+static const xmltag GPXStepType_tag;
+static const xmltag GPXFinalType_tag;
 
 
 /* The XML tag definition values */
 
 /*+ The complete set of tags at the top level. +*/
-static xmltag *xml_toplevel_tags[]={&xmlDeclaration_tag,&RoutinoTranslationsType_tag,NULL};
+static const xmltag * const xml_toplevel_tags[]={&xmlDeclaration_tag,&RoutinoTranslationsType_tag,NULL};
 
 /*+ The xmlDeclaration type tag. +*/
-static xmltag xmlDeclaration_tag=
+static const xmltag xmlDeclaration_tag=
               {"xml",
                2, {"version","encoding"},
                NULL,
                {NULL}};
 
 /*+ The RoutinoTranslationsType type tag. +*/
-static xmltag RoutinoTranslationsType_tag=
+static const xmltag RoutinoTranslationsType_tag=
               {"routino-translations",
                0, {NULL},
                NULL,
                {&LanguageType_tag,NULL}};
 
 /*+ The LanguageType type tag. +*/
-static xmltag LanguageType_tag=
+static const xmltag LanguageType_tag=
               {"language",
-               1, {"lang"},
+               2, {"lang","language"},
                LanguageType_function,
                {&CopyrightType_tag,&TurnType_tag,&HeadingType_tag,&OrdinalType_tag,&HighwayType_tag,&RouteType_tag,&HTMLType_tag,&GPXType_tag,NULL}};
 
 /*+ The CopyrightType type tag. +*/
-static xmltag CopyrightType_tag=
+static const xmltag CopyrightType_tag=
               {"copyright",
                0, {NULL},
                NULL,
                {&CopyrightCreatorType_tag,&CopyrightSourceType_tag,&CopyrightLicenseType_tag,NULL}};
 
 /*+ The TurnType type tag. +*/
-static xmltag TurnType_tag=
+static const xmltag TurnType_tag=
               {"turn",
                2, {"direction","string"},
                TurnType_function,
                {NULL}};
 
 /*+ The HeadingType type tag. +*/
-static xmltag HeadingType_tag=
+static const xmltag HeadingType_tag=
               {"heading",
                2, {"direction","string"},
                HeadingType_function,
                {NULL}};
 
 /*+ The OrdinalType type tag. +*/
-static xmltag OrdinalType_tag=
+static const xmltag OrdinalType_tag=
               {"ordinal",
                2, {"number","string"},
                OrdinalType_function,
                {NULL}};
 
 /*+ The HighwayType type tag. +*/
-static xmltag HighwayType_tag=
+static const xmltag HighwayType_tag=
               {"highway",
                2, {"type","string"},
                HighwayType_function,
                {NULL}};
 
 /*+ The RouteType type tag. +*/
-static xmltag RouteType_tag=
+static const xmltag RouteType_tag=
               {"route",
                2, {"type","string"},
                RouteType_function,
                {NULL}};
 
 /*+ The HTMLType type tag. +*/
-static xmltag HTMLType_tag=
+static const xmltag HTMLType_tag=
               {"output-html",
                0, {NULL},
                NULL,
-               {&HTMLWaypointType_tag,&HTMLTitleType_tag,&HTMLStartType_tag,&HTMLNodeType_tag,&HTMLRBNodeType_tag,&HTMLSegmentType_tag,&HTMLStopType_tag,&HTMLTotalType_tag,NULL}};
+               {&HTMLWaypointType_tag,&HTMLTitleType_tag,&HTMLStartType_tag,&HTMLNodeType_tag,&HTMLRBNodeType_tag,&HTMLSegmentType_tag,&HTMLStopType_tag,&HTMLTotalType_tag,&HTMLSubtotalType_tag,NULL}};
 
 /*+ The GPXType type tag. +*/
-static xmltag GPXType_tag=
+static const xmltag GPXType_tag=
               {"output-gpx",
                0, {NULL},
                NULL,
                {&GPXWaypointType_tag,&GPXDescType_tag,&GPXNameType_tag,&GPXStepType_tag,&GPXFinalType_tag,NULL}};
 
 /*+ The CopyrightCreatorType type tag. +*/
-static xmltag CopyrightCreatorType_tag=
+static const xmltag CopyrightCreatorType_tag=
               {"creator",
                2, {"string","text"},
                CopyrightCreatorType_function,
                {NULL}};
 
 /*+ The CopyrightSourceType type tag. +*/
-static xmltag CopyrightSourceType_tag=
+static const xmltag CopyrightSourceType_tag=
               {"source",
                2, {"string","text"},
                CopyrightSourceType_function,
                {NULL}};
 
 /*+ The CopyrightLicenseType type tag. +*/
-static xmltag CopyrightLicenseType_tag=
+static const xmltag CopyrightLicenseType_tag=
               {"license",
                2, {"string","text"},
                CopyrightLicenseType_function,
                {NULL}};
 
 /*+ The HTMLWaypointType type tag. +*/
-static xmltag HTMLWaypointType_tag=
+static const xmltag HTMLWaypointType_tag=
               {"waypoint",
                2, {"type","string"},
                HTMLWaypointType_function,
                {NULL}};
 
 /*+ The HTMLTitleType type tag. +*/
-static xmltag HTMLTitleType_tag=
+static const xmltag HTMLTitleType_tag=
               {"title",
                1, {"text"},
                HTMLTitleType_function,
                {NULL}};
 
 /*+ The HTMLStartType type tag. +*/
-static xmltag HTMLStartType_tag=
+static const xmltag HTMLStartType_tag=
               {"start",
-               2, {"string","text"},
+               1, {"text"},
                HTMLStartType_function,
                {NULL}};
 
 /*+ The HTMLNodeType type tag. +*/
-static xmltag HTMLNodeType_tag=
+static const xmltag HTMLNodeType_tag=
               {"node",
-               2, {"string","text"},
+               1, {"text"},
                HTMLNodeType_function,
                {NULL}};
 
 /*+ The HTMLRBNodeType type tag. +*/
-static xmltag HTMLRBNodeType_tag=
+static const xmltag HTMLRBNodeType_tag=
               {"rbnode",
-               2, {"string","text"},
+               1, {"text"},
                HTMLRBNodeType_function,
                {NULL}};
 
 /*+ The HTMLSegmentType type tag. +*/
-static xmltag HTMLSegmentType_tag=
+static const xmltag HTMLSegmentType_tag=
               {"segment",
-               2, {"string","text"},
+               1, {"text"},
                HTMLSegmentType_function,
                {NULL}};
 
 /*+ The HTMLStopType type tag. +*/
-static xmltag HTMLStopType_tag=
+static const xmltag HTMLStopType_tag=
               {"stop",
-               2, {"string","text"},
+               1, {"text"},
                HTMLStopType_function,
                {NULL}};
 
 /*+ The HTMLTotalType type tag. +*/
-static xmltag HTMLTotalType_tag=
+static const xmltag HTMLTotalType_tag=
               {"total",
-               2, {"string","text"},
+               1, {"text"},
                HTMLTotalType_function,
                {NULL}};
 
+/*+ The HTMLSubtotalType type tag. +*/
+static const xmltag HTMLSubtotalType_tag=
+              {"subtotal",
+               1, {"text"},
+               HTMLSubtotalType_function,
+               {NULL}};
+
 /*+ The GPXWaypointType type tag. +*/
-static xmltag GPXWaypointType_tag=
+static const xmltag GPXWaypointType_tag=
               {"waypoint",
                2, {"type","string"},
                GPXWaypointType_function,
                {NULL}};
 
 /*+ The GPXDescType type tag. +*/
-static xmltag GPXDescType_tag=
+static const xmltag GPXDescType_tag=
               {"desc",
                1, {"text"},
                GPXDescType_function,
                {NULL}};
 
 /*+ The GPXNameType type tag. +*/
-static xmltag GPXNameType_tag=
+static const xmltag GPXNameType_tag=
               {"name",
                1, {"text"},
                GPXNameType_function,
                {NULL}};
 
 /*+ The GPXStepType type tag. +*/
-static xmltag GPXStepType_tag=
+static const xmltag GPXStepType_tag=
               {"step",
                1, {"text"},
                GPXStepType_function,
                {NULL}};
 
 /*+ The GPXFinalType type tag. +*/
-static xmltag GPXFinalType_tag=
+static const xmltag GPXFinalType_tag=
               {"final",
                1, {"text"},
                GPXFinalType_function,
@@ -389,24 +434,46 @@ static xmltag GPXFinalType_tag=
   int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag.
 
   const char *lang The contents of the 'lang' attribute (or NULL if not defined).
+
+  const char *language The contents of the 'language' attribute (or NULL if not defined).
   ++++++++++++++++++++++++++++++++++++++*/
 
-static int LanguageType_function(const char *_tag_,int _type_,const char *lang)
+static int LanguageType_function(const char *_tag_,int _type_,const char *lang,const char *language)
 {
- static int first=1;
-
  if(_type_&XMLPARSE_TAG_START)
    {
     XMLPARSE_ASSERT_STRING(_tag_,lang);
+    XMLPARSE_ASSERT_STRING(_tag_,language);
 
-    if(!store_lang && first)
+    if(store_all)
+       store=1;
+    else if(!store_lang && !stored)
        store=1;
     else if(store_lang && !strcmp(store_lang,lang))
        store=1;
     else
        store=0;
 
-    first=0;
+    if(store)
+      {
+       int i;
+
+       for(i=0;i<nloaded_translations;i++)
+          if(!strcmp(lang,loaded_translations[i]->lang))
+             XMLPARSE_MESSAGE(_tag_,"translation name must be unique");
+
+       if((nloaded_translations%16)==0)
+          loaded_translations=(Translation**)realloc((void*)loaded_translations,(nloaded_translations+16)*sizeof(Translation*));
+
+       nloaded_translations++;
+
+       loaded_translations[nloaded_translations-1]=(Translation*)calloc(1,sizeof(Translation));
+
+       *loaded_translations[nloaded_translations-1]=default_translation;
+
+       loaded_translations[nloaded_translations-1]->lang    =strcpy(malloc(strlen(lang    )+1),lang    );
+       loaded_translations[nloaded_translations-1]->language=strcpy(malloc(strlen(language)+1),language);
+      }
    }
 
  if(_type_&XMLPARSE_TAG_END && store)
@@ -464,9 +531,10 @@ static int TurnType_function(const char *_tag_,int _type_,const char *direction,
     if(d<0 || d>8)
        XMLPARSE_INVALID(_tag_,direction);
 
-    xmlstring=ParseXML_Encode_Safe_XML(string);
+    loaded_translations[nloaded_translations-1]->notxml_turn[d]=strcpy(malloc(strlen(string)+1),string);
 
-    translate_xml_turn[d]=strcpy(malloc(strlen(xmlstring)+1),xmlstring);
+    xmlstring=ParseXML_Encode_Safe_XML(string);
+    loaded_translations[nloaded_translations-1]->xml_turn[d]=strcpy(malloc(strlen(xmlstring)+1),xmlstring);
    }
 
  return(0);
@@ -502,9 +570,10 @@ static int HeadingType_function(const char *_tag_,int _type_,const char *directi
     if(d<0 || d>8)
        XMLPARSE_INVALID(_tag_,direction);
 
-    xmlstring=ParseXML_Encode_Safe_XML(string);
+    loaded_translations[nloaded_translations-1]->notxml_heading[d]=strcpy(malloc(strlen(string)+1),string);
 
-    translate_xml_heading[d]=strcpy(malloc(strlen(xmlstring)+1),xmlstring);
+    xmlstring=ParseXML_Encode_Safe_XML(string);
+    loaded_translations[nloaded_translations-1]->xml_heading[d]=strcpy(malloc(strlen(xmlstring)+1),xmlstring);
    }
 
  return(0);
@@ -538,9 +607,10 @@ static int OrdinalType_function(const char *_tag_,int _type_,const char *number,
     if(n<1 || n>10)
        XMLPARSE_INVALID(_tag_,number);
 
-    xmlstring=ParseXML_Encode_Safe_XML(string);
+    loaded_translations[nloaded_translations-1]->notxml_ordinal[n-1]=strcpy(malloc(strlen(string)+1),string);
 
-    translate_xml_ordinal[n-1]=strcpy(malloc(strlen(xmlstring)+1),xmlstring);
+    xmlstring=ParseXML_Encode_Safe_XML(string);
+    loaded_translations[nloaded_translations-1]->xml_ordinal[n-1]=strcpy(malloc(strlen(xmlstring)+1),xmlstring);
    }
 
  return(0);
@@ -575,7 +645,7 @@ static int HighwayType_function(const char *_tag_,int _type_,const char *type,co
     if(highway==Highway_None)
        XMLPARSE_INVALID(_tag_,type);
 
-    translate_raw_highway[highway]=strcpy(malloc(strlen(string)+1),string);
+    loaded_translations[nloaded_translations-1]->raw_highway[highway]=strcpy(malloc(strlen(string)+1),string);
    }
 
  return(0);
@@ -608,9 +678,9 @@ static int RouteType_function(const char *_tag_,int _type_,const char *type,cons
     xmlstring=ParseXML_Encode_Safe_XML(string);
 
     if(!strcmp(type,"shortest"))
-       translate_xml_route_shortest=strcpy(malloc(strlen(xmlstring)+1),xmlstring);
+       loaded_translations[nloaded_translations-1]->xml_route_shortest=strcpy(malloc(strlen(xmlstring)+1),xmlstring);
     else if(!strcmp(type,"quickest"))
-       translate_xml_route_quickest=strcpy(malloc(strlen(xmlstring)+1),xmlstring);
+       loaded_translations[nloaded_translations-1]->xml_route_quickest=strcpy(malloc(strlen(xmlstring)+1),xmlstring);
     else
        XMLPARSE_INVALID(_tag_,type);
    }
@@ -674,14 +744,14 @@ static int CopyrightCreatorType_function(const char *_tag_,int _type_,const char
     XMLPARSE_ASSERT_STRING(_tag_,string);
     XMLPARSE_ASSERT_STRING(_tag_,text);
 
-    translate_raw_copyright_creator[0]=strcpy(malloc(strlen(string)+1),string);
-    translate_raw_copyright_creator[1]=strcpy(malloc(strlen(text)+1)  ,text);
+    loaded_translations[nloaded_translations-1]->raw_copyright_creator[0]=strcpy(malloc(strlen(string)+1),string);
+    loaded_translations[nloaded_translations-1]->raw_copyright_creator[1]=strcpy(malloc(strlen(text)+1)  ,text);
 
     xmlstring=ParseXML_Encode_Safe_XML(string);
-    xmltext  =ParseXML_Encode_Safe_XML(text);
+    loaded_translations[nloaded_translations-1]->xml_copyright_creator[0]=strcpy(malloc(strlen(xmlstring)+1),xmlstring);
 
-    translate_xml_copyright_creator[0]=strcpy(malloc(strlen(xmlstring)+1),xmlstring);
-    translate_xml_copyright_creator[1]=strcpy(malloc(strlen(xmltext)+1)  ,xmltext);
+    xmltext=ParseXML_Encode_Safe_XML(text);
+    loaded_translations[nloaded_translations-1]->xml_copyright_creator[1]=strcpy(malloc(strlen(xmltext)+1),xmltext);
    }
 
  return(0);
@@ -711,14 +781,14 @@ static int CopyrightSourceType_function(const char *_tag_,int _type_,const char
     XMLPARSE_ASSERT_STRING(_tag_,string);
     XMLPARSE_ASSERT_STRING(_tag_,text);
 
-    translate_raw_copyright_source[0]=strcpy(malloc(strlen(string)+1),string);
-    translate_raw_copyright_source[1]=strcpy(malloc(strlen(text)+1)  ,text);
+    loaded_translations[nloaded_translations-1]->raw_copyright_source[0]=strcpy(malloc(strlen(string)+1),string);
+    loaded_translations[nloaded_translations-1]->raw_copyright_source[1]=strcpy(malloc(strlen(text)+1)  ,text);
 
     xmlstring=ParseXML_Encode_Safe_XML(string);
-    xmltext  =ParseXML_Encode_Safe_XML(text);
+    loaded_translations[nloaded_translations-1]->xml_copyright_source[0]=strcpy(malloc(strlen(xmlstring)+1),xmlstring);
 
-    translate_xml_copyright_source[0]=strcpy(malloc(strlen(xmlstring)+1),xmlstring);
-    translate_xml_copyright_source[1]=strcpy(malloc(strlen(xmltext)+1)  ,xmltext);
+    xmltext=ParseXML_Encode_Safe_XML(text);
+    loaded_translations[nloaded_translations-1]->xml_copyright_source[1]=strcpy(malloc(strlen(xmltext)+1),xmltext);
    }
 
  return(0);
@@ -748,14 +818,14 @@ static int CopyrightLicenseType_function(const char *_tag_,int _type_,const char
     XMLPARSE_ASSERT_STRING(_tag_,string);
     XMLPARSE_ASSERT_STRING(_tag_,text);
 
-    translate_raw_copyright_license[0]=strcpy(malloc(strlen(string)+1),string);
-    translate_raw_copyright_license[1]=strcpy(malloc(strlen(text)+1)  ,text);
+    loaded_translations[nloaded_translations-1]->raw_copyright_license[0]=strcpy(malloc(strlen(string)+1),string);
+    loaded_translations[nloaded_translations-1]->raw_copyright_license[1]=strcpy(malloc(strlen(text)+1)  ,text);
 
     xmlstring=ParseXML_Encode_Safe_XML(string);
-    xmltext  =ParseXML_Encode_Safe_XML(text);
+    loaded_translations[nloaded_translations-1]->xml_copyright_license[0]=strcpy(malloc(strlen(xmlstring)+1),xmlstring);
 
-    translate_xml_copyright_license[0]=strcpy(malloc(strlen(xmlstring)+1),xmlstring);
-    translate_xml_copyright_license[1]=strcpy(malloc(strlen(xmltext)+1)  ,xmltext);
+    xmltext=ParseXML_Encode_Safe_XML(text);
+    loaded_translations[nloaded_translations-1]->xml_copyright_license[1]=strcpy(malloc(strlen(xmltext)+1),xmltext);
    }
 
  return(0);
@@ -789,13 +859,23 @@ static int HTMLWaypointType_function(const char *_tag_,int _type_,const char *ty
 
     if(!strcmp(type,"waypoint"))
       {
-       translate_html_waypoint=malloc(strlen(xmlstring)+1+sizeof("<span class='w'>")+sizeof("</span>"));
-       sprintf(translate_html_waypoint,"<span class='w'>%s</span>",xmlstring);
+       loaded_translations[nloaded_translations-1]->nothtml_waypoint=strcpy(malloc(strlen(string)+1),string);
+
+       loaded_translations[nloaded_translations-1]->html_waypoint=malloc(strlen(xmlstring)+1+sizeof("<span class='w'>")+sizeof("</span>"));
+       sprintf(loaded_translations[nloaded_translations-1]->html_waypoint,"<span class='w'>%s</span>",xmlstring);
       }
     else if(!strcmp(type,"junction"))
-       translate_html_junction=strcpy(malloc(strlen(xmlstring)+1),xmlstring);
+      {
+       loaded_translations[nloaded_translations-1]->nothtml_junction=strcpy(malloc(strlen(string)+1),string);
+
+       loaded_translations[nloaded_translations-1]->html_junction=strcpy(malloc(strlen(xmlstring)+1),xmlstring);
+      }
     else if(!strcmp(type,"roundabout"))
-       translate_html_roundabout=strcpy(malloc(strlen(xmlstring)+1),xmlstring);
+      {
+       loaded_translations[nloaded_translations-1]->nothtml_roundabout=strcpy(malloc(strlen(string)+1),string);
+
+       loaded_translations[nloaded_translations-1]->html_roundabout=strcpy(malloc(strlen(xmlstring)+1),xmlstring);
+      }
     else
        XMLPARSE_INVALID(_tag_,type);
    }
@@ -826,7 +906,9 @@ static int HTMLTitleType_function(const char *_tag_,int _type_,const char *text)
 
     xmltext=ParseXML_Encode_Safe_XML(text);
 
-    translate_html_title=strcpy(malloc(strlen(xmltext)+1),xmltext);
+    loaded_translations[nloaded_translations-1]->nothtml_title=strcpy(malloc(strlen(text)+1),text);
+
+    loaded_translations[nloaded_translations-1]->html_title=strcpy(malloc(strlen(xmltext)+1),xmltext);
    }
 
  return(0);
@@ -842,26 +924,43 @@ static int HTMLTitleType_function(const char *_tag_,int _type_,const char *text)
 
   int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag.
 
-  const char *string The contents of the 'string' attribute (or NULL if not defined).
-
   const char *text The contents of the 'text' attribute (or NULL if not defined).
   ++++++++++++++++++++++++++++++++++++++*/
 
-static int HTMLStartType_function(const char *_tag_,int _type_,const char *string,const char *text)
+static int HTMLStartType_function(const char *_tag_,int _type_,const char *text)
 {
  if(_type_&XMLPARSE_TAG_START && store)
    {
-    char *xmlstring,*xmltext;
+    char *xmltext;
+    const char *p;
+    char *q;
 
-    XMLPARSE_ASSERT_STRING(_tag_,string);
     XMLPARSE_ASSERT_STRING(_tag_,text);
 
-    xmlstring=ParseXML_Encode_Safe_XML(string);
-    xmltext  =ParseXML_Encode_Safe_XML(text);
+    xmltext=ParseXML_Encode_Safe_XML(text);
+
+    loaded_translations[nloaded_translations-1]->nothtml_start=strcpy(malloc(strlen(text)+1),text);
+
+    loaded_translations[nloaded_translations-1]->html_start=malloc(sizeof("<tr class='n'><td>")+strlen(xmltext)+sizeof("<span class='b'>")+sizeof("</span>")+1+1);
+
+    p=xmltext;
+    q=loaded_translations[nloaded_translations-1]->html_start;
+
+    strcpy(q,"<tr class='n'><td>"); q+=sizeof("<tr class='n'><td>")-1;
+
+    while(*p!='%')
+       *q++=*p++;
+
+    *q++=*p++;
+
+    while(*p!='%')
+       *q++=*p++;
 
-    translate_html_start[0]=strcpy(malloc(strlen(xmlstring)+1),xmlstring);
-    translate_html_start[1]=malloc(strlen(xmltext)+1+sizeof("<span class='b'>")+sizeof("</span>"));
-    sprintf(translate_html_start[1],xmltext,"%s","<span class='b'>%s</span>");
+    p+=2;
+    strcpy(q,"<span class='b'>%s</span>"); q+=sizeof("<span class='b'>%s</span>")-1;
+
+    strcpy(q,p);
+    strcat(q,"\n");
    }
 
  return(0);
@@ -877,26 +976,49 @@ static int HTMLStartType_function(const char *_tag_,int _type_,const char *strin
 
   int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag.
 
-  const char *string The contents of the 'string' attribute (or NULL if not defined).
-
   const char *text The contents of the 'text' attribute (or NULL if not defined).
   ++++++++++++++++++++++++++++++++++++++*/
 
-static int HTMLNodeType_function(const char *_tag_,int _type_,const char *string,const char *text)
+static int HTMLNodeType_function(const char *_tag_,int _type_,const char *text)
 {
  if(_type_&XMLPARSE_TAG_START && store)
    {
-    char *xmlstring,*xmltext;
+    char *xmltext;
+    const char *p;
+    char *q;
 
-    XMLPARSE_ASSERT_STRING(_tag_,string);
     XMLPARSE_ASSERT_STRING(_tag_,text);
 
-    xmlstring=ParseXML_Encode_Safe_XML(string);
-    xmltext  =ParseXML_Encode_Safe_XML(text);
+    xmltext=ParseXML_Encode_Safe_XML(text);
+
+    loaded_translations[nloaded_translations-1]->nothtml_node=strcpy(malloc(strlen(text)+1),text);
 
-    translate_html_node[0]=strcpy(malloc(strlen(xmlstring)+1),xmlstring);
-    translate_html_node[1]=malloc(strlen(xmltext)+1+2*sizeof("<span class='b'>")+2*sizeof("</span>"));
-    sprintf(translate_html_node[1],xmltext,"%s","<span class='t'>%s</span>","<span class='b'>%s</span>");
+    loaded_translations[nloaded_translations-1]->html_node=malloc(sizeof("<tr class='n'><td>")+strlen(xmltext)+2*sizeof("<span class='b'>")+2*sizeof("</span>")+1+1);
+
+    p=xmltext;
+    q=loaded_translations[nloaded_translations-1]->html_node;
+
+    strcpy(q,"<tr class='n'><td>"); q+=sizeof("<tr class='n'><td>")-1;
+
+    while(*p!='%')
+       *q++=*p++;
+
+    *q++=*p++;
+
+    while(*p!='%')
+       *q++=*p++;
+
+    p+=2;
+    strcpy(q,"<span class='t'>%s</span>"); q+=sizeof("<span class='t'>%s</span>")-1;
+
+    while(*p!='%')
+       *q++=*p++;
+
+    p+=2;
+    strcpy(q,"<span class='b'>%s</span>"); q+=sizeof("<span class='b'>%s</span>")-1;
+
+    strcpy(q,p);
+    strcat(q,"\n");
    }
 
  return(0);
@@ -912,26 +1034,49 @@ static int HTMLNodeType_function(const char *_tag_,int _type_,const char *string
 
   int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag.
 
-  const char *string The contents of the 'string' attribute (or NULL if not defined).
-
   const char *text The contents of the 'text' attribute (or NULL if not defined).
   ++++++++++++++++++++++++++++++++++++++*/
 
-static int HTMLRBNodeType_function(const char *_tag_,int _type_,const char *string,const char *text)
+static int HTMLRBNodeType_function(const char *_tag_,int _type_,const char *text)
 {
  if(_type_&XMLPARSE_TAG_START && store)
    {
-    char *xmlstring,*xmltext;
+    char *xmltext;
+    const char *p;
+    char *q;
 
-    XMLPARSE_ASSERT_STRING(_tag_,string);
     XMLPARSE_ASSERT_STRING(_tag_,text);
 
-    xmlstring=ParseXML_Encode_Safe_XML(string);
-    xmltext  =ParseXML_Encode_Safe_XML(text);
+    xmltext=ParseXML_Encode_Safe_XML(text);
+
+    loaded_translations[nloaded_translations-1]->nothtml_rbnode=strcpy(malloc(strlen(text)+1),text);
+
+    loaded_translations[nloaded_translations-1]->html_rbnode=malloc(sizeof("<tr class='n'><td>")+strlen(xmltext)+2*sizeof("<span class='b'>")+2*sizeof("</span>")+1+1);
+
+    p=xmltext;
+    q=loaded_translations[nloaded_translations-1]->html_rbnode;
+
+    strcpy(q,"<tr class='n'><td>"); q+=sizeof("<tr class='n'><td>")-1;
+
+    while(*p!='%')
+       *q++=*p++;
+
+    *q++=*p++;
 
-    translate_html_rbnode[0]=strcpy(malloc(strlen(xmlstring)+1),xmlstring);
-    translate_html_rbnode[1]=malloc(strlen(xmltext)+1+2*sizeof("<span class='b'>")+2*sizeof("</span>"));
-    sprintf(translate_html_rbnode[1],xmltext,"%s","<span class='t'>%s</span>","<span class='b'>%s</span>");
+    while(*p!='%')
+       *q++=*p++;
+
+    p+=2;
+    strcpy(q,"<span class='t'>%s</span>"); q+=sizeof("<span class='t'>%s</span>")-1;
+
+    while(*p!='%')
+       *q++=*p++;
+
+    p+=2;
+    strcpy(q,"<span class='b'>%s</span>"); q+=sizeof("<span class='b'>%s</span>")-1;
+
+    strcpy(q,p);
+    strcat(q,"\n");
    }
 
  return(0);
@@ -947,32 +1092,31 @@ static int HTMLRBNodeType_function(const char *_tag_,int _type_,const char *stri
 
   int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag.
 
-  const char *string The contents of the 'string' attribute (or NULL if not defined).
-
   const char *text The contents of the 'text' attribute (or NULL if not defined).
   ++++++++++++++++++++++++++++++++++++++*/
 
-static int HTMLSegmentType_function(const char *_tag_,int _type_,const char *string,const char *text)
+static int HTMLSegmentType_function(const char *_tag_,int _type_,const char *text)
 {
  if(_type_&XMLPARSE_TAG_START && store)
    {
-    char *xmlstring,*xmltext;
+    char *xmltext;
     const char *p;
     char *q;
 
-    XMLPARSE_ASSERT_STRING(_tag_,string);
     XMLPARSE_ASSERT_STRING(_tag_,text);
 
-    xmlstring=ParseXML_Encode_Safe_XML(string);
-    xmltext  =ParseXML_Encode_Safe_XML(text);
+    xmltext=ParseXML_Encode_Safe_XML(text);
+
+    loaded_translations[nloaded_translations-1]->nothtml_segment=strcpy(malloc(strlen(text)+1),text);
 
-    translate_html_segment[0]=strcpy(malloc(strlen(xmlstring)+1),xmlstring);
-    translate_html_segment[1]=malloc(strlen(xmltext)+1+2*sizeof("<span class='b'>")+2*sizeof("</span>"));
+    loaded_translations[nloaded_translations-1]->html_segment=malloc(sizeof("<tr class='s'><td>")+strlen(xmltext)+2*sizeof("<span class='b'>")+2*sizeof("</span>")+1);
 
     p=xmltext;
-    q=translate_html_segment[1];
+    q=loaded_translations[nloaded_translations-1]->html_segment;
 
-    while(*p!='%' && *(p+1)!='s')
+    strcpy(q,"<tr class='s'><td>"); q+=sizeof("<tr class='s'><td>")-1;
+
+    while(*p!='%')
        *q++=*p++;
 
     p+=2;
@@ -1000,25 +1144,26 @@ static int HTMLSegmentType_function(const char *_tag_,int _type_,const char *str
 
   int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag.
 
-  const char *string The contents of the 'string' attribute (or NULL if not defined).
-
   const char *text The contents of the 'text' attribute (or NULL if not defined).
   ++++++++++++++++++++++++++++++++++++++*/
 
-static int HTMLStopType_function(const char *_tag_,int _type_,const char *string,const char *text)
+static int HTMLStopType_function(const char *_tag_,int _type_,const char *text)
 {
  if(_type_&XMLPARSE_TAG_START && store)
    {
-    char *xmlstring,*xmltext;
+    char *xmltext;
 
-    XMLPARSE_ASSERT_STRING(_tag_,string);
     XMLPARSE_ASSERT_STRING(_tag_,text);
 
-    xmlstring=ParseXML_Encode_Safe_XML(string);
-    xmltext  =ParseXML_Encode_Safe_XML(text);
+    xmltext=ParseXML_Encode_Safe_XML(text);
 
-    translate_html_stop[0]=strcpy(malloc(strlen(xmlstring)+1),xmlstring);
-    translate_html_stop[1]=strcpy(malloc(strlen(xmltext)+1)  ,xmltext);
+    loaded_translations[nloaded_translations-1]->nothtml_stop=strcpy(malloc(strlen(text)+1),text);
+
+    loaded_translations[nloaded_translations-1]->html_stop=malloc(sizeof("<tr class='n'><td>")+strlen(xmltext)+1+1);
+
+    strcpy(loaded_translations[nloaded_translations-1]->html_stop,"<tr class='n'><td>");
+    strcat(loaded_translations[nloaded_translations-1]->html_stop,xmltext);
+    strcat(loaded_translations[nloaded_translations-1]->html_stop,"\n");
    }
 
  return(0);
@@ -1034,25 +1179,64 @@ static int HTMLStopType_function(const char *_tag_,int _type_,const char *string
 
   int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag.
 
-  const char *string The contents of the 'string' attribute (or NULL if not defined).
+  const char *text The contents of the 'text' attribute (or NULL if not defined).
+  ++++++++++++++++++++++++++++++++++++++*/
+
+static int HTMLTotalType_function(const char *_tag_,int _type_,const char *text)
+{
+ if(_type_&XMLPARSE_TAG_START && store)
+   {
+    char *xmltext;
+
+    XMLPARSE_ASSERT_STRING(_tag_,text);
+
+    xmltext=ParseXML_Encode_Safe_XML(text);
+
+    loaded_translations[nloaded_translations-1]->nothtml_total=strcpy(malloc(strlen(text)+1),text);
+
+    loaded_translations[nloaded_translations-1]->html_total=malloc(sizeof("<tr class='t'><td>")+strlen(xmltext)+sizeof("<span class='j'>")+sizeof("</span>")+1+1);
+
+    strcpy(loaded_translations[nloaded_translations-1]->html_total,"<tr class='t'><td>");
+    strcat(loaded_translations[nloaded_translations-1]->html_total,"<span class='j'>");
+    strcat(loaded_translations[nloaded_translations-1]->html_total,xmltext);
+    strcat(loaded_translations[nloaded_translations-1]->html_total,"</span>");
+    strcat(loaded_translations[nloaded_translations-1]->html_total,"\n");
+   }
+
+ return(0);
+}
+
+
+/*++++++++++++++++++++++++++++++++++++++
+  The function that is called when the HTMLSubtotalType XSD type is seen
+
+  int HTMLSubtotalType_function Returns 0 if no error occured or something else otherwise.
+
+  const char *_tag_ Set to the name of the element tag that triggered this function call.
+
+  int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag.
 
   const char *text The contents of the 'text' attribute (or NULL if not defined).
   ++++++++++++++++++++++++++++++++++++++*/
 
-static int HTMLTotalType_function(const char *_tag_,int _type_,const char *string,const char *text)
+static int HTMLSubtotalType_function(const char *_tag_,int _type_,const char *text)
 {
  if(_type_&XMLPARSE_TAG_START && store)
    {
-    char *xmlstring,*xmltext;
+    char *xmltext;
 
-    XMLPARSE_ASSERT_STRING(_tag_,string);
     XMLPARSE_ASSERT_STRING(_tag_,text);
 
-    xmlstring=ParseXML_Encode_Safe_XML(string);
-    xmltext  =ParseXML_Encode_Safe_XML(text);
+    xmltext=ParseXML_Encode_Safe_XML(text);
 
-    translate_html_total[0]=strcpy(malloc(strlen(xmlstring)+1),xmlstring);
-    translate_html_total[1]=strcpy(malloc(strlen(xmltext)+1)  ,xmltext);
+    loaded_translations[nloaded_translations-1]->nothtml_subtotal=strcpy(malloc(strlen(text)+1),text);
+
+    loaded_translations[nloaded_translations-1]->html_subtotal=malloc(sizeof(" [<span class='j'>")+strlen(xmltext)+sizeof("</span>]")+1+1);
+
+    strcpy(loaded_translations[nloaded_translations-1]->html_subtotal," [<span class='j'>");
+    strcat(loaded_translations[nloaded_translations-1]->html_subtotal,xmltext);
+    strcat(loaded_translations[nloaded_translations-1]->html_subtotal,"</span>]");
+    strcat(loaded_translations[nloaded_translations-1]->html_subtotal,"\n");
    }
 
  return(0);
@@ -1085,13 +1269,13 @@ static int GPXWaypointType_function(const char *_tag_,int _type_,const char *typ
     xmlstring=ParseXML_Encode_Safe_XML(string);
 
     if(!strcmp(type,"start"))
-       translate_gpx_start=strcpy(malloc(strlen(xmlstring)+1),xmlstring);
+       loaded_translations[nloaded_translations-1]->gpx_start=strcpy(malloc(strlen(xmlstring)+1),xmlstring);
     else if(!strcmp(type,"inter"))
-       translate_gpx_inter=strcpy(malloc(strlen(xmlstring)+1),xmlstring);
+       loaded_translations[nloaded_translations-1]->gpx_inter=strcpy(malloc(strlen(xmlstring)+1),xmlstring);
     else if(!strcmp(type,"trip"))
-       translate_gpx_trip=strcpy(malloc(strlen(xmlstring)+1),xmlstring);
+       loaded_translations[nloaded_translations-1]->gpx_trip=strcpy(malloc(strlen(xmlstring)+1),xmlstring);
     else if(!strcmp(type,"finish"))
-       translate_gpx_finish=strcpy(malloc(strlen(xmlstring)+1),xmlstring);
+       loaded_translations[nloaded_translations-1]->gpx_finish=strcpy(malloc(strlen(xmlstring)+1),xmlstring);
     else
        XMLPARSE_INVALID(_tag_,type);
    }
@@ -1121,8 +1305,7 @@ static int GPXDescType_function(const char *_tag_,int _type_,const char *text)
     XMLPARSE_ASSERT_STRING(_tag_,text);
 
     xmltext=ParseXML_Encode_Safe_XML(text);
-
-    translate_gpx_desc=strcpy(malloc(strlen(xmltext)+1),xmltext);
+    loaded_translations[nloaded_translations-1]->gpx_desc=strcpy(malloc(strlen(xmltext)+1),xmltext);
    }
 
  return(0);
@@ -1150,8 +1333,7 @@ static int GPXNameType_function(const char *_tag_,int _type_,const char *text)
     XMLPARSE_ASSERT_STRING(_tag_,text);
 
     xmltext=ParseXML_Encode_Safe_XML(text);
-
-    translate_gpx_name=strcpy(malloc(strlen(xmltext)+1),xmltext);
+    loaded_translations[nloaded_translations-1]->gpx_name=strcpy(malloc(strlen(xmltext)+1),xmltext);
    }
 
  return(0);
@@ -1179,8 +1361,7 @@ static int GPXStepType_function(const char *_tag_,int _type_,const char *text)
     XMLPARSE_ASSERT_STRING(_tag_,text);
 
     xmltext=ParseXML_Encode_Safe_XML(text);
-
-    translate_gpx_step=strcpy(malloc(strlen(xmltext)+1),xmltext);
+    loaded_translations[nloaded_translations-1]->gpx_step=strcpy(malloc(strlen(xmltext)+1),xmltext);
    }
 
  return(0);
@@ -1208,8 +1389,7 @@ static int GPXFinalType_function(const char *_tag_,int _type_,const char *text)
     XMLPARSE_ASSERT_STRING(_tag_,text);
 
     xmltext=ParseXML_Encode_Safe_XML(text);
-
-    translate_gpx_final=strcpy(malloc(strlen(xmltext)+1),xmltext);
+    loaded_translations[nloaded_translations-1]->gpx_final=strcpy(malloc(strlen(xmltext)+1),xmltext);
    }
 
  return(0);
@@ -1223,33 +1403,207 @@ static int GPXFinalType_function(const char *_tag_,int _type_,const char *text)
 
   const char *filename The name of the file to read.
 
-  const char *language The language to search for (NULL means first in file).
+  const char *lang The abbreviated language name to search for (NULL means first in file).
+
+  int all Set to true to load all the translations.
   ++++++++++++++++++++++++++++++++++++++*/
 
-int ParseXMLTranslations(const char *filename,const char *language)
+int ParseXMLTranslations(const char *filename,const char *lang,int all)
 {
  int fd;
  int retval;
 
- store_lang=language;
-
  if(!ExistsFile(filename))
-   {
-    fprintf(stderr,"Error: Specified translations file '%s' does not exist.\n",filename);
     return(1);
-   }
 
  fd=OpenFile(filename);
 
+ /* Delete the existing translations */
+
+ if(nloaded_translations)
+    FreeXMLTranslations();
+
+ /* Initialise variables used for parsing */
+
+ store_all=all;
+
+ store_lang=lang;
+
+ store=0;
+ stored=0;
+
+ /* Parse the file */
+
  retval=ParseXML(fd,xml_toplevel_tags,XMLPARSE_UNKNOWN_ATTR_ERRNONAME|XMLPARSE_RETURN_ATTR_ENCODED);
 
  CloseFile(fd);
 
  if(retval)
-    return(1);
+   {
+    FreeXMLTranslations();
 
- if(language && !stored)
-    fprintf(stderr,"Warning: Cannot find translations for language '%s' using English instead.\n",language);
+    return(2);
+   }
 
  return(0);
 }
+
+
+/*++++++++++++++++++++++++++++++++++++++
+  Return a list of the languages that have been loaded from the XML file.
+
+  char **GetTranslationLanguages Returns a NULL terminated list of strings - all allocated.
+  ++++++++++++++++++++++++++++++++++++++*/
+
+char **GetTranslationLanguages(void)
+{
+ char **list=calloc(1+nloaded_translations,sizeof(char*));
+ int i;
+
+ for(i=0;i<nloaded_translations;i++)
+    list[i]=strcpy(malloc(strlen(loaded_translations[i]->lang)+1),loaded_translations[i]->lang);
+
+ return(list);
+}
+
+
+/*++++++++++++++++++++++++++++++++++++++
+  Return a list of the full names of the languages that have been loaded from the XML file.
+
+  char **GetTranslationLanguageFullNames Returns a NULL terminated list of strings - all allocated.
+  ++++++++++++++++++++++++++++++++++++++*/
+
+char **GetTranslationLanguageFullNames(void)
+{
+ char **list=calloc(1+nloaded_translations,sizeof(char*));
+ int i;
+
+ for(i=0;i<nloaded_translations;i++)
+    list[i]=strcpy(malloc(strlen(loaded_translations[i]->language)+1),loaded_translations[i]->language);
+
+ return(list);
+}
+
+
+/*++++++++++++++++++++++++++++++++++++++
+  Get a named translation.
+
+  Translation *GetTranslation Returns a pointer to the translation.
+
+  const char *lang The abbreviated name of the language of the translation or NULL to get the default or an empty string to get the first one.
+  ++++++++++++++++++++++++++++++++++++++*/
+
+Translation *GetTranslation(const char *lang)
+{
+ int i;
+
+ if(!lang)
+    return(&default_translation);
+
+ if(!*lang && nloaded_translations>0)
+    return(loaded_translations[0]);
+
+ for(i=0;i<nloaded_translations;i++)
+    if(!strcmp(loaded_translations[i]->lang,lang))
+       return(loaded_translations[i]);
+
+ return(NULL);
+}
+
+
+/*++++++++++++++++++++++++++++++++++++++
+  Free the memory that has been allocated for the translations.
+  ++++++++++++++++++++++++++++++++++++++*/
+
+void FreeXMLTranslations()
+{
+ int i,j;
+
+ if(!loaded_translations)
+    return;
+
+ for(i=0;i<nloaded_translations;i++)
+   {
+    free(loaded_translations[i]->lang);
+
+    for(j=0;j<2;j++)
+      {
+       if(loaded_translations[i]->raw_copyright_creator[j] != default_translation.raw_copyright_creator[j]) free(loaded_translations[i]->raw_copyright_creator[j]);
+       if(loaded_translations[i]->raw_copyright_source[j]  != default_translation.raw_copyright_source[j])  free(loaded_translations[i]->raw_copyright_source[j]);
+       if(loaded_translations[i]->raw_copyright_license[j] != default_translation.raw_copyright_license[j]) free(loaded_translations[i]->raw_copyright_license[j]);
+
+       if(loaded_translations[i]->xml_copyright_creator[j] != default_translation.xml_copyright_creator[j]) free(loaded_translations[i]->xml_copyright_creator[j]);
+       if(loaded_translations[i]->xml_copyright_source[j]  != default_translation.xml_copyright_source[j])  free(loaded_translations[i]->xml_copyright_source[j]);
+       if(loaded_translations[i]->xml_copyright_license[j] != default_translation.xml_copyright_license[j]) free(loaded_translations[i]->xml_copyright_license[j]);
+      }
+
+    for(j=0;j<9;j++)
+      {
+       if(loaded_translations[i]->xml_heading[j] != default_translation.xml_heading[j]) free(loaded_translations[i]->xml_heading[j]);
+       if(loaded_translations[i]->xml_turn[j]    != default_translation.xml_turn[j])    free(loaded_translations[i]->xml_turn[j]);
+      }
+
+    for(j=0;j<10;j++)
+       if(loaded_translations[i]->xml_ordinal[j] != default_translation.xml_ordinal[j]) free(loaded_translations[i]->xml_ordinal[j]);
+
+    for(j=0;j<9;j++)
+      {
+       if(loaded_translations[i]->notxml_heading[j] != default_translation.notxml_heading[j]) free(loaded_translations[i]->notxml_heading[j]);
+       if(loaded_translations[i]->notxml_turn[j]    != default_translation.notxml_turn[j])    free(loaded_translations[i]->notxml_turn[j]);
+      }
+
+    for(j=0;j<10;j++)
+       if(loaded_translations[i]->notxml_ordinal[j] != default_translation.notxml_ordinal[j]) free(loaded_translations[i]->notxml_ordinal[j]);
+
+    for(j=0;j<Highway_Count;j++)
+       if(loaded_translations[i]->raw_highway[j] != default_translation.raw_highway[j]) free(loaded_translations[i]->raw_highway[j]);
+
+    if(loaded_translations[i]->xml_route_shortest != default_translation.xml_route_shortest) free(loaded_translations[i]->xml_route_shortest);
+    if(loaded_translations[i]->xml_route_quickest != default_translation.xml_route_quickest) free(loaded_translations[i]->xml_route_quickest);
+
+    if(loaded_translations[i]->html_waypoint   != default_translation.html_waypoint)   free(loaded_translations[i]->html_waypoint);
+    if(loaded_translations[i]->html_junction   != default_translation.html_junction)   free(loaded_translations[i]->html_junction);
+    if(loaded_translations[i]->html_roundabout != default_translation.html_roundabout) free(loaded_translations[i]->html_roundabout);
+
+    if(loaded_translations[i]->html_title != default_translation.html_title) free(loaded_translations[i]->html_title);
+
+    if(loaded_translations[i]->html_start   != default_translation.html_start)   free(loaded_translations[i]->html_start);
+    if(loaded_translations[i]->html_node    != default_translation.html_node)    free(loaded_translations[i]->html_node);
+    if(loaded_translations[i]->html_rbnode  != default_translation.html_rbnode)  free(loaded_translations[i]->html_rbnode);
+    if(loaded_translations[i]->html_segment != default_translation.html_segment) free(loaded_translations[i]->html_segment);
+    if(loaded_translations[i]->html_stop    != default_translation.html_stop)    free(loaded_translations[i]->html_stop);
+    if(loaded_translations[i]->html_total   != default_translation.html_total)   free(loaded_translations[i]->html_total);
+    if(loaded_translations[i]->html_subtotal!= default_translation.html_subtotal)free(loaded_translations[i]->html_subtotal);
+
+    if(loaded_translations[i]->nothtml_waypoint   != default_translation.nothtml_waypoint)   free(loaded_translations[i]->nothtml_waypoint);
+    if(loaded_translations[i]->nothtml_junction   != default_translation.nothtml_junction)   free(loaded_translations[i]->nothtml_junction);
+    if(loaded_translations[i]->nothtml_roundabout != default_translation.nothtml_roundabout) free(loaded_translations[i]->nothtml_roundabout);
+
+    if(loaded_translations[i]->nothtml_title != default_translation.nothtml_title) free(loaded_translations[i]->nothtml_title);
+
+    if(loaded_translations[i]->nothtml_start   != default_translation.nothtml_start)   free(loaded_translations[i]->nothtml_start);
+    if(loaded_translations[i]->nothtml_node    != default_translation.nothtml_node)    free(loaded_translations[i]->nothtml_node);
+    if(loaded_translations[i]->nothtml_rbnode  != default_translation.nothtml_rbnode)  free(loaded_translations[i]->nothtml_rbnode);
+    if(loaded_translations[i]->nothtml_segment != default_translation.nothtml_segment) free(loaded_translations[i]->nothtml_segment);
+    if(loaded_translations[i]->nothtml_stop    != default_translation.nothtml_stop)    free(loaded_translations[i]->nothtml_stop);
+    if(loaded_translations[i]->nothtml_total   != default_translation.nothtml_total)   free(loaded_translations[i]->nothtml_total);
+    if(loaded_translations[i]->nothtml_subtotal!= default_translation.nothtml_subtotal)free(loaded_translations[i]->nothtml_subtotal);
+
+    if(loaded_translations[i]->gpx_desc  != default_translation.gpx_desc)  free(loaded_translations[i]->gpx_desc);
+    if(loaded_translations[i]->gpx_name  != default_translation.gpx_name)  free(loaded_translations[i]->gpx_name);
+    if(loaded_translations[i]->gpx_step  != default_translation.gpx_step)  free(loaded_translations[i]->gpx_step);
+    if(loaded_translations[i]->gpx_final != default_translation.gpx_final) free(loaded_translations[i]->gpx_final);
+
+    if(loaded_translations[i]->gpx_start  != default_translation.gpx_start)  free(loaded_translations[i]->gpx_start);
+    if(loaded_translations[i]->gpx_inter  != default_translation.gpx_inter)  free(loaded_translations[i]->gpx_inter);
+    if(loaded_translations[i]->gpx_trip   != default_translation.gpx_trip)   free(loaded_translations[i]->gpx_trip);
+    if(loaded_translations[i]->gpx_finish != default_translation.gpx_finish) free(loaded_translations[i]->gpx_finish);
+
+    free(loaded_translations[i]);
+   }
+
+ free(loaded_translations);
+
+ loaded_translations=NULL;
+ nloaded_translations=0;
+}
diff --git a/src/translations.h b/src/translations.h
index e98ec8c..8a863ff 100644
--- a/src/translations.h
+++ b/src/translations.h
@@ -3,7 +3,7 @@
 
  Part of the Routino routing software.
  ******************/ /******************
- This file Copyright 2010-2012 Andrew M. Bishop
+ This file Copyright 2010-2015 Andrew M. Bishop
 
  This program is free software: you can redistribute it and/or modify
  it under the terms of the GNU Affero General Public License as published by
@@ -26,51 +26,83 @@
 #include "types.h"
 
 
-/* Global variable declarations */
+/* Type declarations */
 
-extern char *translate_raw_copyright_creator[2];
-extern char *translate_raw_copyright_source[2];
-extern char *translate_raw_copyright_license[2];
+typedef struct _Translation
+{
+ char *lang;
+ char *language;
 
-extern char *translate_xml_copyright_creator[2];
-extern char *translate_xml_copyright_source[2];
-extern char *translate_xml_copyright_license[2];
+ char *raw_copyright_creator[2];
+ char *raw_copyright_source[2];
+ char *raw_copyright_license[2];
 
-extern char *translate_xml_heading[9];
-extern char *translate_xml_turn[9];
-extern char *translate_xml_ordinal[10];
+ char *xml_copyright_creator[2];
+ char *xml_copyright_source[2];
+ char *xml_copyright_license[2];
 
-extern char *translate_raw_highway[Highway_Count];
+ char *xml_heading[9];
+ char *xml_turn[9];
+ char *xml_ordinal[10];
 
-extern char *translate_xml_route_shortest;
-extern char *translate_xml_route_quickest;
+ char *notxml_heading[9];
+ char *notxml_turn[9];
+ char *notxml_ordinal[10];
 
-extern char *translate_html_waypoint;
-extern char *translate_html_junction;
-extern char *translate_html_roundabout;
+ char *raw_highway[Highway_Count];
 
-extern char *translate_html_title;
-extern char *translate_html_start[2];
-extern char *translate_html_segment[2];
-extern char *translate_html_node[2];
-extern char *translate_html_rbnode[2];
-extern char *translate_html_stop[2];
-extern char *translate_html_total[2];
+ char *xml_route_shortest;
+ char *xml_route_quickest;
 
-extern char *translate_gpx_desc;
-extern char *translate_gpx_name;
-extern char *translate_gpx_step;
-extern char *translate_gpx_final;
+ char *html_waypoint;
+ char *html_junction;
+ char *html_roundabout;
 
-extern char *translate_gpx_start;
-extern char *translate_gpx_inter;
-extern char *translate_gpx_trip;
-extern char *translate_gpx_finish;
+ char *html_title;
+ char *html_start;
+ char *html_segment;
+ char *html_node;
+ char *html_rbnode;
+ char *html_stop;
+ char *html_total;
+ char *html_subtotal;
+
+ char *nothtml_waypoint;
+ char *nothtml_junction;
+ char *nothtml_roundabout;
+
+ char *nothtml_title;
+ char *nothtml_start;
+ char *nothtml_segment;
+ char *nothtml_node;
+ char *nothtml_rbnode;
+ char *nothtml_stop;
+ char *nothtml_total;
+ char *nothtml_subtotal;
+
+ char *gpx_desc;
+ char *gpx_name;
+ char *gpx_step;
+ char *gpx_final;
+
+ char *gpx_start;
+ char *gpx_inter;
+ char *gpx_trip;
+ char *gpx_finish;
+}
+ Translation;
 
 
 /* Functions in translations.c */
 
-int ParseXMLTranslations(const char *filename,const char *language);
+int ParseXMLTranslations(const char *filename,const char *lang,int all);
+
+char **GetTranslationLanguages(void);
+char **GetTranslationLanguageFullNames(void);
+
+Translation *GetTranslation(const char *lang);
+
+void FreeXMLTranslations(void);
 
 
 #endif /* TRANSLATIONS_H */
diff --git a/src/types.c b/src/types.c
index 7dd2577..87d54a3 100644
--- a/src/types.c
+++ b/src/types.c
@@ -3,7 +3,7 @@
 
  Part of the Routino routing software.
  ******************/ /******************
- This file Copyright 2008-2014 Andrew M. Bishop
+ This file Copyright 2008-2015 Andrew M. Bishop
 
  This program is free software: you can redistribute it and/or modify
  it under the terms of the GNU Affero General Public License as published by
@@ -345,7 +345,7 @@ const char *PropertyName(Property property)
 
 const char *HighwaysNameList(highways_t highways)
 {
- static char string[256];
+ static char string[256]; /* static allocation of return value (set each call) */
 
  string[0]=0;
 
@@ -432,7 +432,7 @@ const char *HighwaysNameList(highways_t highways)
 
 const char *AllowedNameList(transports_t allowed)
 {
- static char string[256];
+ static char string[256]; /* static allocation of return value (set each call) */
 
  string[0]=0;
 
@@ -507,7 +507,7 @@ const char *AllowedNameList(transports_t allowed)
 
 const char *PropertiesNameList(properties_t properties)
 {
- static char string[256];
+ static char string[256]; /* static allocation of return value (set each call) */
 
  string[0]=0;
 
diff --git a/src/typesx.h b/src/typesx.h
index 2aad40f..2febbd2 100644
--- a/src/typesx.h
+++ b/src/typesx.h
@@ -42,7 +42,7 @@
 #define NO_RELATION_ID ((relation_t)~0)
 
 /*+ The maximum number of segments per node (used to size temporary storage). +*/
-#define MAX_SEG_PER_NODE 32
+#define MAX_SEG_PER_NODE 64
 
 
 /* Bit mask macro types and functions */
diff --git a/src/uncompress.c b/src/uncompress.c
index aee16d1..329c8ff 100644
--- a/src/uncompress.c
+++ b/src/uncompress.c
@@ -3,7 +3,7 @@
 
  Part of the Routino routing software.
  ******************/ /******************
- This file Copyright 2012-2014 Andrew M. Bishop
+ This file Copyright 2012-2015 Andrew M. Bishop
 
  This program is free software: you can redistribute it and/or modify
  it under the terms of the GNU Affero General Public License as published by
@@ -21,7 +21,16 @@
 
 
 #include <stdlib.h>
+
+#if defined(_MSC_VER)
+#include <io.h>
+#define read(fd,address,length)  _read(fd,address,(unsigned int)(length))
+#define write(fd,address,length) _write(fd,address,(unsigned int)(length))
+#define close                    _close
+#else
 #include <unistd.h>
+#endif
+
 #include <signal.h>
 
 #if defined(USE_BZIP2) && USE_BZIP2
@@ -43,7 +52,11 @@
 
 /* Local functions */
 
+#if !defined(_MSC_VER) && !defined(__MINGW32__)
+
+#if (defined(USE_BZIP2) && USE_BZIP2) || (defined(USE_GZIP) && USE_GZIP) || (defined(USE_XZ) && USE_XZ)
 static int pipe_and_fork(int filefd,int *pipefd);
+#endif
 
 #if defined(USE_BZIP2) && USE_BZIP2
 static void uncompress_bzip2_pipe(int filefd,int pipefd);
@@ -57,6 +70,8 @@ static void uncompress_gzip_pipe(int filefd,int pipefd);
 static void uncompress_xz_pipe(int filefd,int pipefd);
 #endif
 
+#endif /* !defined(_MSC_VER) && !defined(__MINGW32__) */
+
 
 /*++++++++++++++++++++++++++++++++++++++
   Create a child process to uncompress data on a file descriptor as if it were a pipe.
@@ -68,7 +83,7 @@ static void uncompress_xz_pipe(int filefd,int pipefd);
 
 int Uncompress_Bzip2(int filefd)
 {
-#if defined(USE_BZIP2) && USE_BZIP2
+#if defined(USE_BZIP2) && USE_BZIP2 && !defined(_MSC_VER) && !defined(__MINGW32__)
 
  int pipefd=-1;
 
@@ -99,7 +114,7 @@ int Uncompress_Bzip2(int filefd)
 
 int Uncompress_Gzip(int filefd)
 {
-#if defined(USE_GZIP) && USE_GZIP
+#if defined(USE_GZIP) && USE_GZIP && !defined(_MSC_VER) && !defined(__MINGW32__)
 
  int pipefd=-1;
 
@@ -130,7 +145,7 @@ int Uncompress_Gzip(int filefd)
 
 int Uncompress_Xz(int filefd)
 {
-#if defined(USE_XZ) && USE_XZ
+#if defined(USE_XZ) && USE_XZ && !defined(_MSC_VER) && !defined(__MINGW32__)
 
  int pipefd=-1;
 
@@ -151,6 +166,10 @@ int Uncompress_Xz(int filefd)
 }
 
 
+#if !defined(_MSC_VER) && !defined(__MINGW32__)
+
+#if (defined(USE_BZIP2) && USE_BZIP2) || (defined(USE_GZIP) && USE_GZIP) || (defined(USE_XZ) && USE_XZ)
+
 /*++++++++++++++++++++++++++++++++++++++
   Create a pipe and then fork returning in the parent and child with a different end of the pipe.
 
@@ -224,6 +243,8 @@ static int pipe_and_fork(int filefd,int *pipefd)
    }
 }
 
+#endif /* (defined(USE_BZIP2) && USE_BZIP2) || (defined(USE_GZIP) && USE_GZIP) || (defined(USE_XZ) && USE_XZ) */
+
 
 #if defined(USE_BZIP2) && USE_BZIP2
 
@@ -448,3 +469,5 @@ static void uncompress_xz_pipe(int filefd,int pipefd)
 }
 
 #endif /* USE_XZ */
+
+#endif /* !defined(_MSC_VER) && !defined(__MINGW32__) */
diff --git a/src/version.h b/src/version.h
new file mode 100644
index 0000000..deeff25
--- /dev/null
+++ b/src/version.h
@@ -0,0 +1,30 @@
+/***************************************
+ Routino version.
+
+ Part of the Routino routing software.
+ ******************/ /******************
+ This file Copyright 2015 Andrew M. Bishop
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ ***************************************/
+
+
+#ifndef VERSION_H
+#define VERSION_H    /*+ To stop multiple inclusions. +*/
+
+#define ROUTINO_VERSION "3.0"
+
+#define ROUTINO_URL     "<http://www.routino.org/>"
+
+#endif /* VERSION_H */
diff --git a/src/visualiser.c b/src/visualiser.c
index 4062074..cd79ec1 100644
--- a/src/visualiser.c
+++ b/src/visualiser.c
@@ -3,7 +3,7 @@
 
  Part of the Routino routing software.
  ******************/ /******************
- This file Copyright 2008-2014 Andrew M. Bishop
+ This file Copyright 2008-2015 Andrew M. Bishop
 
  This program is free software: you can redistribute it and/or modify
  it under the terms of the GNU Affero General Public License as published by
@@ -31,11 +31,10 @@
 #include "relations.h"
 #include "errorlog.h"
 
-#include "visualiser.h"
+#include "typesx.h"
 
+#include "visualiser.h"
 
-/*+ The maximum number of segments per node (used to size temporary storage). +*/
-#define MAX_SEG_PER_NODE 32
 
 /* Limit types */
 
@@ -49,7 +48,7 @@
 
 typedef void (*callback_t)(index_t node,double latitude,double longitude);
 
-/* Local variables */
+/* Local variables (intialised by entry-point function before later use) */
 
 static Nodes     *OSMNodes;
 static Segments  *OSMSegments;
diff --git a/src/ways.c b/src/ways.c
index b265a98..a9d42f6 100644
--- a/src/ways.c
+++ b/src/ways.c
@@ -3,7 +3,7 @@
 
  Part of the Routino routing software.
  ******************/ /******************
- This file Copyright 2008-2014 Andrew M. Bishop
+ This file Copyright 2008-2015 Andrew M. Bishop
 
  This program is free software: you can redistribute it and/or modify
  it under the terms of the GNU Affero General Public License as published by
@@ -64,8 +64,12 @@ Ways *LoadWayList(const char *filename)
 
  ways->namesoffset=sizeof(WaysFile)+ways->file.number*sizeof(Way);
 
+ memset(ways->ncached,0,sizeof(ways->ncached));
+
  ways->cache=NewWayCache();
+#ifndef LIBROUTINO
  log_malloc(ways->cache,sizeof(*ways->cache));
+#endif
 
 #endif
 
@@ -89,7 +93,9 @@ void DestroyWayList(Ways *ways)
 
  ways->fd=SlimUnmapFile(ways->fd);
 
+#ifndef LIBROUTINO
  log_free(ways->cache);
+#endif
  DeleteWayCache(ways->cache);
 
 #endif
diff --git a/src/ways.h b/src/ways.h
index b4f4066..cec3b39 100644
--- a/src/ways.h
+++ b/src/ways.h
@@ -3,7 +3,7 @@
 
  Part of the Routino routing software.
  ******************/ /******************
- This file Copyright 2008-2013 Andrew M. Bishop
+ This file Copyright 2008-2015 Andrew M. Bishop
 
  This program is free software: you can redistribute it and/or modify
  it under the terms of the GNU Affero General Public License as published by
@@ -74,7 +74,7 @@ struct _Ways
 
 #if !SLIM
 
- void      *data;               /*+ The memory mapped data. +*/
+ char      *data;               /*+ The memory mapped data. +*/
 
  Way       *ways;               /*+ An array of ways. +*/
  char      *names;              /*+ An array of characters containing the names. +*/
@@ -82,7 +82,7 @@ struct _Ways
 #else
 
  int        fd;                 /*+ The file descriptor for the file. +*/
- off_t      namesoffset;        /*+ The offset of the names within the file. +*/
+ offset_t   namesoffset;        /*+ The offset of the names within the file. +*/
 
  Way        cached[3];          /*+ Two cached nodes read from the file in slim mode. +*/
 
@@ -124,10 +124,12 @@ CACHE_DELETECACHE_PROTO(Way)
 CACHE_FETCHCACHE_PROTO(Way)
 CACHE_INVALIDATECACHE_PROTO(Way)
 
+/* Data type */
+
+CACHE_STRUCTURE(Way)
 
 /* Inline functions */
 
-CACHE_STRUCTURE(Way)
 CACHE_NEWCACHE(Way)
 CACHE_DELETECACHE(Way)
 CACHE_FETCHCACHE(Way)
@@ -166,7 +168,7 @@ static inline Way *LookupWay(Ways *ways,index_t index,int position)
 
 static inline char *WayName(Ways *ways,Way *wayp)
 {
- int position=wayp-&ways->cached[-1];
+ int position=(int)(wayp-&ways->cached[-1]);
  int n=0;
 
  if(!ways->ncached[position-1])
diff --git a/src/waysx.c b/src/waysx.c
index 89485dc..7588acc 100644
--- a/src/waysx.c
+++ b/src/waysx.c
@@ -3,7 +3,7 @@
 
  Part of the Routino routing software.
  ******************/ /******************
- This file Copyright 2008-2014 Andrew M. Bishop
+ This file Copyright 2008-2015 Andrew M. Bishop
 
  This program is free software: you can redistribute it and/or modify
  it under the terms of the GNU Affero General Public License as published by
@@ -43,7 +43,7 @@ extern char *option_tmpdirname;
 
 /* Local variables */
 
-/*+ Temporary file-local variables for use by the sort functions. +*/
+/*+ Temporary file-local variables for use by the sort functions (re-initialised for each sort). +*/
 static WaysX *sortwaysx;
 static SegmentsX *sortsegmentsx;
 
@@ -78,7 +78,7 @@ WaysX *NewWayList(int append,int readonly)
  logassert(waysx,"Failed to allocate memory (try using slim mode?)"); /* Check calloc() worked */
 
  waysx->filename    =(char*)malloc(strlen(option_tmpdirname)+32);
- waysx->filename_tmp=(char*)malloc(strlen(option_tmpdirname)+32);
+ waysx->filename_tmp=(char*)malloc(strlen(option_tmpdirname)+32); /* allow %p to be up to 20 bytes */
 
  sprintf(waysx->filename    ,"%s/waysx.parsed.mem",option_tmpdirname);
  sprintf(waysx->filename_tmp,"%s/waysx.%p.tmp"    ,option_tmpdirname,(void*)waysx);
@@ -116,7 +116,7 @@ WaysX *NewWayList(int append,int readonly)
 #endif
 
 
- waysx->nfilename_tmp=(char*)malloc(strlen(option_tmpdirname)+32);
+ waysx->nfilename_tmp=(char*)malloc(strlen(option_tmpdirname)+40); /* allow %p to be up to 20 bytes */
 
  sprintf(waysx->nfilename_tmp,"%s/waynames.%p.tmp",option_tmpdirname,(void*)waysx);
 
@@ -303,11 +303,7 @@ void SortWayList(WaysX *waysx)
 
  /* Re-open the file read-only and a new file writeable */
 
- waysx->fd=ReOpenFileBuffered(waysx->filename_tmp);
-
- DeleteFile(waysx->filename_tmp);
-
- fd=OpenFileBufferedNew(waysx->filename_tmp);
+ fd=ReplaceFileBuffered(waysx->filename_tmp,&waysx->fd);
 
  /* Allocate the array of indexes */
 
@@ -375,9 +371,9 @@ static int sort_by_id(WayX *a,WayX *b)
 
 static int deduplicate_and_index_by_id(WayX *wayx,index_t index)
 {
- static way_t previd=NO_WAY_ID;
+ static way_t previd; /* internal variable (reset by first call in each sort; index==0) */
 
- if(wayx->id!=previd)
+ if(index==0 || wayx->id!=previd)
    {
     previd=wayx->id;
 
@@ -423,14 +419,16 @@ SegmentsX *SplitWays(WaysX *waysx,NodesX *nodesx,int keep)
 
  /* Re-open the file read-only and a new file writeable */
 
- waysx->fd=ReOpenFileBuffered(waysx->filename_tmp);
-
  if(keep)
+   {
     RenameFile(waysx->filename_tmp,waysx->filename);
- else
-    DeleteFile(waysx->filename_tmp);
 
- fd=OpenFileBufferedNew(waysx->filename_tmp);
+    waysx->fd=ReOpenFileBuffered(waysx->filename);
+
+    fd=OpenFileBufferedNew(waysx->filename_tmp);
+   }
+ else
+    fd=ReplaceFileBuffered(waysx->filename_tmp,&waysx->fd);
 
  nfd=OpenFileBufferedNew(waysx->nfilename_tmp);
 
@@ -542,11 +540,7 @@ void SortWayNames(WaysX *waysx)
 
  /* Re-open the file read-only and new file writeable */
 
- waysx->nfd=ReOpenFileBuffered(waysx->nfilename_tmp);
-
- DeleteFile(waysx->nfilename_tmp);
-
- nfd=OpenFileBufferedNew(waysx->nfilename_tmp);
+ nfd=ReplaceFileBuffered(waysx->nfilename_tmp,&waysx->nfd);
 
  /* Sort the way names */
 
@@ -580,11 +574,7 @@ void SortWayNames(WaysX *waysx)
 
  /* Re-open the file read-only and new file writeable */
 
- waysx->nfd=ReOpenFileBuffered(waysx->nfilename_tmp);
-
- DeleteFile(waysx->nfilename_tmp);
-
- nfd=OpenFileBufferedNew(waysx->nfilename_tmp);
+ nfd=ReplaceFileBuffered(waysx->nfilename_tmp,&waysx->nfd);
 
  /* Update the ways and de-duplicate the names */
 
@@ -698,11 +688,7 @@ void CompactWayList(WaysX *waysx,SegmentsX *segmentsx)
 
  /* Re-open the file read-only and a new file writeable */
 
- waysx->fd=ReOpenFileBuffered(waysx->filename_tmp);
-
- DeleteFile(waysx->filename_tmp);
-
- fd=OpenFileBufferedNew(waysx->filename_tmp);
+ fd=ReplaceFileBuffered(waysx->filename_tmp,&waysx->fd);
 
  /* Sort the ways to allow compacting according to the properties */
 
@@ -800,7 +786,7 @@ static int sort_by_name_and_prop_and_id(WayX *a,WayX *b)
 
 static int deduplicate_and_index_by_compact_id(WayX *wayx,index_t index)
 {
- static Way lastway;
+ static Way lastway; /* internal variable (reset by first call in each sort; index==0) */
 
  if(index==0 || wayx->way.name!=lastway.name || WaysCompare(&lastway,&wayx->way))
    {
@@ -871,7 +857,7 @@ void SaveWayList(WaysX *waysx,const char *filename)
 
  /* Write out the ways names */
 
- SeekFileBuffered(fd,sizeof(WaysFile)+(off_t)waysx->number*sizeof(Way));
+ SeekFileBuffered(fd,sizeof(WaysFile)+(offset_t)waysx->number*sizeof(Way));
 
  while(position<waysx->nlength)
    {
diff --git a/src/waysx.h b/src/waysx.h
index 24cab2a..5406f1e 100644
--- a/src/waysx.h
+++ b/src/waysx.h
@@ -3,7 +3,7 @@
 
  Part of the Routino routing software.
  ******************/ /******************
- This file Copyright 2008-2014 Andrew M. Bishop
+ This file Copyright 2008-2015 Andrew M. Bishop
 
  This program is free software: you can redistribute it and/or modify
  it under the terms of the GNU Affero General Public License as published by
@@ -72,16 +72,16 @@ struct _WaysX
 
 #endif
 
- way_t   *idata;                /*+ The extended way IDs (sorted by ID). +*/
- off_t   *odata;                /*+ The offset of the way in the file (used for error log). +*/
+ way_t    *idata;               /*+ The extended way IDs (sorted by ID). +*/
+ offset_t *odata;               /*+ The offset of the way in the file (used for error log). +*/
 
- index_t *cdata;                /*+ The compacted way IDs (same order as sorted ways). +*/
+ index_t  *cdata;               /*+ The compacted way IDs (same order as sorted ways). +*/
 
- char    *nfilename_tmp;        /*+ The name of the temporary file (for the WaysX names). +*/
+ char     *nfilename_tmp;       /*+ The name of the temporary file (for the WaysX names). +*/
 
- int      nfd;                  /*+ The file descriptor of the temporary file (for the WaysX names). +*/
+ int       nfd;                 /*+ The file descriptor of the temporary file (for the WaysX names). +*/
 
- uint32_t nlength;              /*+ The length of the string of name entries. +*/
+ uint32_t  nlength;             /*+ The length of the string of name entries. +*/
 };
 
 
@@ -129,10 +129,12 @@ CACHE_FETCHCACHE_PROTO(WayX)
 CACHE_REPLACECACHE_PROTO(WayX)
 CACHE_INVALIDATECACHE_PROTO(WayX)
 
+/* Data type */
+
+CACHE_STRUCTURE(WayX)
 
 /* Inline functions */
 
-CACHE_STRUCTURE(WayX)
 CACHE_NEWCACHE(WayX)
 CACHE_DELETECACHE(WayX)
 CACHE_FETCHCACHE(WayX)
diff --git a/src/xml/Makefile b/src/xml/Makefile
index c4ddf87..bd38869 100644
--- a/src/xml/Makefile
+++ b/src/xml/Makefile
@@ -2,7 +2,7 @@
 #
 # Part of the Routino routing software.
 #
-# This file Copyright 2010-2014 Andrew M. Bishop
+# This file Copyright 2010-2015 Andrew M. Bishop
 #
 # This program is free software: you can redistribute it and/or modify
 # it under the terms of the GNU Affero General Public License as published by
@@ -30,9 +30,9 @@ X=$(notdir $(wildcard $(XMLDIR)/*.xsd))
 C=$(foreach f,$(X),$(addsuffix -skeleton.c,$(basename $f)))
 D=$(wildcard .deps/*.d)
 O=$(foreach f,$(C),$(addsuffix .o,$(basename $f)))
-E=$(foreach f,$(C),$(basename $f))
+E=$(foreach f,$(C),$(addsuffix $(.EXE),$(basename $f)))
 
-EXE=xsd-to-xmlparser
+EXE=xsd-to-xmlparser$(.EXE)
 
 ########
 
@@ -40,17 +40,17 @@ all: $(EXE) $(C) $(E)
 
 ########
 
-xsd-to-xmlparser : xsd-to-xmlparser.o ../xmlparse.o
-	$(LD) xsd-to-xmlparser.o ../xmlparse.o -o $@ $(LDFLAGS)
+xsd-to-xmlparser$(.EXE) : xsd-to-xmlparser.o ../xmlparse.o
+	$(LD) $^ -o $@ $(LDFLAGS)
 
 ########
 
-%-skeleton.c : $(XMLDIR)/%.xsd xsd-to-xmlparser
+%-skeleton.c : $(XMLDIR)/%.xsd xsd-to-xmlparser$(.EXE)
 	-./xsd-to-xmlparser < $< > $@
 	@test -s $@ || rm $@
 
-%-skeleton : %-skeleton.o ../xmlparse.o
-	$(LD) $< ../xmlparse.o -o $@ $(LDFLAGS)
+%-skeleton$(.EXE) : %-skeleton.o ../xmlparse.o
+	$(LD) $^ -o $@ $(LDFLAGS)
 
 .SECONDARY : $(O)
 
@@ -67,7 +67,7 @@ xsd-to-xmlparser : xsd-to-xmlparser.o ../xmlparse.o
 
 ########
 
-test: test-skeleton
+test: test-skeleton$(.EXE)
 	@status=true ;\
 	echo "" ;\
 	for good in test/good*.xml; do \
@@ -83,10 +83,10 @@ test: test-skeleton
 	if $$status; then echo "Success: all tests passed"; else echo "Warning: Some tests FAILED"; fi ;\
 	$$status
 
-test-skeleton : test-skeleton.o
-	$(LD) $< ../xmlparse.o -o $@ $(LDFLAGS)
+test-skeleton$(.EXE) : test-skeleton.o ../xmlparse.o
+	$(LD) $^ -o $@ $(LDFLAGS)
 
-test-skeleton.c : test/test.xsd xsd-to-xmlparser
+test-skeleton.c : test/test.xsd xsd-to-xmlparser$(.EXE)
 	./xsd-to-xmlparser < $< | sed -e 's/XMLPARSE_UNKNOWN_ATTR_WARN/XMLPARSE_UNKNOWN_ATTR_ERROR/' > $@
 
 ########
@@ -98,17 +98,17 @@ install:
 clean:
 	rm -f *~
 	rm -f *.o
+	rm -f $(EXE)
+	rm -f $(E) test-skeleton$(.EXE)
+	rm -f $(D) .deps/test-skeleton.d
+	rm -f $(C) test-skeleton.c
+	rm -fr .deps
 	rm -f core
 	rm -f *.gcda *.gcno *.gcov gmon.out
 
 ########
 
 distclean: clean
-	-rm -f $(EXE)
-	-rm -f $(E) test-skeleton
-	-rm -f $(D) .deps/test-skeleton.d
-	-rm -f $(C) test-skeleton.c
-	-rm -fr .deps
 
 ########
 
diff --git a/src/xml/xsd-to-xmlparser.c b/src/xml/xsd-to-xmlparser.c
index 7f27a35..18a38e1 100644
--- a/src/xml/xsd-to-xmlparser.c
+++ b/src/xml/xsd-to-xmlparser.c
@@ -5,7 +5,7 @@
 
  Part of the Routino routing software.
  ******************/ /******************
- This file Copyright 2010-2012 Andrew M. Bishop
+ This file Copyright 2010-2015 Andrew M. Bishop
 
  This program is free software: you can redistribute it and/or modify
  it under the terms of the GNU Affero General Public License as published by
@@ -23,7 +23,9 @@
 
 
 #include <stdio.h>
+#if !defined(_MSC_VER)
 #include <unistd.h>
+#endif
 #include <ctype.h>
 #include <stdlib.h>
 #include <string.h>
@@ -70,56 +72,56 @@ static int attributeType_function(const char *_tag_,int _type_,const char *name,
 
 /* The XML tag definitions (forward declarations) */
 
-static xmltag xmlDeclaration_tag;
-static xmltag schemaType_tag;
-static xmltag elementType_tag;
-static xmltag complexType_tag;
-static xmltag sequenceType_tag;
-static xmltag attributeType_tag;
+static const xmltag xmlDeclaration_tag;
+static const xmltag schemaType_tag;
+static const xmltag elementType_tag;
+static const xmltag complexType_tag;
+static const xmltag sequenceType_tag;
+static const xmltag attributeType_tag;
 
 
 /* The XML tag definition values */
 
 /*+ The complete set of tags at the top level. +*/
-static xmltag *xml_toplevel_tags[]={&xmlDeclaration_tag,&schemaType_tag,NULL};
+static const xmltag * const xml_toplevel_tags[]={&xmlDeclaration_tag,&schemaType_tag,NULL};
 
 /*+ The xmlDeclaration type tag. +*/
-static xmltag xmlDeclaration_tag=
+static const xmltag xmlDeclaration_tag=
               {"xml",
                2, {"version","encoding"},
                xmlDeclaration_function,
                {NULL}};
 
 /*+ The schemaType type tag. +*/
-static xmltag schemaType_tag=
+static const xmltag schemaType_tag=
               {"xsd:schema",
                2, {"elementFormDefault","xmlns:xsd"},
                schemaType_function,
                {&elementType_tag,&complexType_tag,NULL}};
 
 /*+ The elementType type tag. +*/
-static xmltag elementType_tag=
+static const xmltag elementType_tag=
               {"xsd:element",
                4, {"name","type","minOccurs","maxOccurs"},
                elementType_function,
                {NULL}};
 
 /*+ The complexType type tag. +*/
-static xmltag complexType_tag=
+static const xmltag complexType_tag=
               {"xsd:complexType",
                1, {"name"},
                complexType_function,
                {&sequenceType_tag,&attributeType_tag,NULL}};
 
 /*+ The sequenceType type tag. +*/
-static xmltag sequenceType_tag=
+static const xmltag sequenceType_tag=
               {"xsd:sequence",
                0, {NULL},
                sequenceType_function,
                {&elementType_tag,NULL}};
 
 /*+ The attributeType type tag. +*/
-static xmltag attributeType_tag=
+static const xmltag attributeType_tag=
               {"xsd:attribute",
                2, {"name","type"},
                attributeType_function,
@@ -338,7 +340,9 @@ int main(int argc,char **argv)
  printf("\n");
  printf("\n");
  printf("#include <stdio.h>\n");
+ printf("#if !defined(_MSC_VER)\n");
  printf("#include <unistd.h>\n");
+ printf("#endif\n");
  printf("\n");
  printf("#include \"xmlparse.h\"\n");
 
@@ -368,7 +372,7 @@ int main(int argc,char **argv)
  printf("\n");
 
  for(i=0;i<ntagsx;i++)
-    printf("static xmltag %s_tag;\n",safe(tagsx[i]->type));
+    printf("static const xmltag %s_tag;\n",safe(tagsx[i]->type));
 
  printf("\n");
  printf("\n");
@@ -376,7 +380,7 @@ int main(int argc,char **argv)
 
  printf("\n");
  printf("/*+ The complete set of tags at the top level. +*/\n");
- printf("static xmltag *xml_toplevel_tags[]={");
+ printf("static const xmltag * const xml_toplevel_tags[]={");
  printf("&%s_tag,",safe(tagsx[0]->type));
  printf("&%s_tag,",safe(tagsx[1]->type));
  printf("NULL};\n");
@@ -385,7 +389,7 @@ int main(int argc,char **argv)
    {
     printf("\n");
     printf("/*+ The %s type tag. +*/\n",tagsx[i]->type);
-    printf("static xmltag %s_tag=\n",safe(tagsx[i]->type));
+    printf("static const xmltag %s_tag=\n",safe(tagsx[i]->type));
     printf("              {\"%s\",\n",tagsx[i]->name);
 
     printf("               %d, {",tagsx[i]->nattributes);
@@ -494,7 +498,7 @@ int main(int argc,char **argv)
 
 static char *safe(const char *name)
 {
- static char *safe=NULL;
+ static char *safe=NULL; /* static allocation of return value */
  int i;
 
  safe=realloc(safe,strlen(name)+1);
diff --git a/src/xmlparse.c b/src/xmlparse.c
index a2ed901..eba82c5 100644
--- a/src/xmlparse.c
+++ b/src/xmlparse.c
@@ -5,7 +5,7 @@
 
  Part of the Routino routing software.
  ******************/ /******************
- This file Copyright 2010-2014 Andrew M. Bishop
+ This file Copyright 2010-2015 Andrew M. Bishop
 
  This program is free software: you can redistribute it and/or modify
  it under the terms of the GNU Affero General Public License as published by
@@ -23,12 +23,29 @@
 
 
 #include <stdio.h>
+
+#if defined(_MSC_VER)
+#include <io.h>
+#include <basetsd.h>
+#define read(fd,address,length)  _read(fd,address,(unsigned int)(length))
+#define snprintf _snprintf
+#define ssize_t SSIZE_T
+#else
 #include <unistd.h>
+#endif
+
 #include <stdlib.h>
 #include <inttypes.h>
+#include <stdarg.h>
 #include <stdint.h>
 #include <string.h>
+
+#if defined(_MSC_VER) || defined(__MINGW32__)
+#define strcasecmp _stricmp
+#else
 #include <strings.h>
+#endif
+
 #include <ctype.h>
 
 #include "xmlparse.h"
@@ -81,11 +98,10 @@
 #define LEX_ERROR_UNEXP_EOF      205
 #define LEX_ERROR_XML_NOT_FIRST  206
 
-#define LEX_ERROR_OUT_OF_MEMORY  254
 #define LEX_ERROR_CALLBACK       255
 
 
-/* Parsing variables and functions */
+/* Parsing variables and functions (re-initialised for each file) */
 
 static uint64_t lineno;
 
@@ -93,6 +109,8 @@ static unsigned char buffer[2][16384];
 static unsigned char *buffer_token,*buffer_end,*buffer_ptr;
 static int buffer_active=0;
 
+static char *stored_message=NULL;
+
 
 /*++++++++++++++++++++++++++++++++++++++
   Refill the data buffer making sure that the string starting at buffer_token is contiguous.
@@ -239,8 +257,8 @@ static inline int call_callback(const char *name,int (*callback)(),int type,int
    case 16: return (*callback)(name,type,attributes[0],attributes[1],attributes[2],attributes[3],attributes[4],attributes[5],attributes[6],attributes[7],attributes[8],attributes[9],attributes[10],attributes[11],attributes[12],attributes[13],attributes[14],attributes[15]);
 
    default:
-    fprintf(stderr,"XML Parser: Error on line %"PRIu64": too many attributes for tag '%s' source code needs changing.\n",lineno,name);
-    exit(1);
+    ParseXML_SetError("Too many attributes for tag '%s' source code needs changing.",name);
+    return(1);
    }
 }
 
@@ -252,12 +270,12 @@ static inline int call_callback(const char *name,int (*callback)(),int type,int
 
   int fd The file descriptor of the file to parse.
 
-  xmltag **tags The array of pointers to tags for the top level.
+  const xmltag *const *tags The array of pointers to tags for the top level.
 
   int options A list of XML Parser options OR-ed together.
   ++++++++++++++++++++++++++++++++++++++*/
 
-int ParseXML(int fd,xmltag **tags,int options)
+int ParseXML(int fd,const xmltag *const *tags,int options)
 {
  int i;
  int state,next_state,after_attr;
@@ -268,14 +286,18 @@ int ParseXML(int fd,xmltag **tags,int options)
  int attribute=0;
 
  int stackdepth=0,stackused=0;
- xmltag ***tags_stack=NULL;
- xmltag **tag_stack=NULL;
- xmltag *tag=NULL;
+ const xmltag * const **tags_stack=NULL;
+ const xmltag **tag_stack=NULL;
+ const xmltag *tag=NULL;
 
  /* The actual parser. */
 
  lineno=1;
 
+ if(stored_message)
+    free(stored_message);
+ stored_message=NULL;
+
  buffer_end=buffer[buffer_active]+sizeof(buffer[0])-1;
  buffer_token=NULL;
 
@@ -970,8 +992,8 @@ int ParseXML(int fd,xmltag **tags,int options)
 
     if(stackused==stackdepth)
       {
-       tag_stack =(xmltag**) realloc((void*)tag_stack ,(stackdepth+=8)*sizeof(xmltag*));
-       tags_stack=(xmltag***)realloc((void*)tags_stack,(stackdepth+=8)*sizeof(xmltag**));
+       tag_stack =realloc(tag_stack ,(stackdepth+=8)*sizeof(xmltag*));
+       tags_stack=realloc(tags_stack,(stackdepth+=8)*sizeof(xmltag**));
       }
 
     tag_stack [stackused]=tag;
@@ -1056,8 +1078,10 @@ int ParseXML(int fd,xmltag **tags,int options)
        if((options&XMLPARSE_UNKNOWN_ATTRIBUTES)==XMLPARSE_UNKNOWN_ATTR_ERROR ||
           ((options&XMLPARSE_UNKNOWN_ATTRIBUTES)==XMLPARSE_UNKNOWN_ATTR_ERRNONAME && !strchr((char*)buffer_token,':')))
           BEGIN(LEX_ERROR_UNEXP_ATT);
+#ifndef LIBROUTINO
        else if((options&XMLPARSE_UNKNOWN_ATTRIBUTES)==XMLPARSE_UNKNOWN_ATTR_WARN)
-          fprintf(stderr,"XML Parser: Warning on line %"PRIu64": unexpected attribute '%s' for tag '%s'.\n",lineno,buffer_token,tag->name);
+          ParseXML_SetError("Warning on line %"PRIu64": unexpected attribute '%s' for tag '%s'.",lineno,buffer_token,tag->name);
+#endif
       }
 
     END_TOKEN;
@@ -1090,78 +1114,91 @@ int ParseXML(int fd,xmltag **tags,int options)
 
 
    case LEX_ERROR_TAG_START:
-    fprintf(stderr,"XML Parser: Error on line %"PRIu64": character '<' seen not at start of tag.\n",lineno);
+    ParseXML_SetError("Character '<' seen not at start of tag.");
     break;
 
    case LEX_ERROR_XML_DECL_START:
-    fprintf(stderr,"XML Parser: Error on line %"PRIu64": characters '<?' seen not at start of XML declaration.\n",lineno);
+    ParseXML_SetError("Characters '<?' seen not at start of XML declaration.");
     break;
 
    case LEX_ERROR_TAG:
-    fprintf(stderr,"XML Parser: Error on line %"PRIu64": invalid character seen inside tag '<%s...>'.\n",lineno,tag->name);
+    ParseXML_SetError("Invalid character seen inside tag '<%s...>'.",tag->name);
     break;
 
    case LEX_ERROR_XML_DECL:
-    fprintf(stderr,"XML Parser: Error on line %"PRIu64": invalid character seen inside XML declaration '<?xml...>'.\n",lineno);
+    ParseXML_SetError("Invalid character seen inside XML declaration '<?xml...>'.");
     break;
 
    case LEX_ERROR_ATTR:
-    fprintf(stderr,"XML Parser: Error on line %"PRIu64": invalid attribute definition seen in tag.\n",lineno);
+    ParseXML_SetError("Invalid attribute definition seen in tag.");
     break;
     
    case LEX_ERROR_END_TAG:
-    fprintf(stderr,"XML Parser: Error on line %"PRIu64": invalid character seen in end-tag.\n",lineno);
+    ParseXML_SetError("Invalid character seen in end-tag.");
     break;
 
    case LEX_ERROR_COMMENT:
-    fprintf(stderr,"XML Parser: Error on line %"PRIu64": invalid comment seen.\n",lineno);
+    ParseXML_SetError("Invalid comment seen.");
     break;
 
    case LEX_ERROR_CLOSE:
-    fprintf(stderr,"XML Parser: Error on line %"PRIu64": character '>' seen not at end of tag.\n",lineno);
+    ParseXML_SetError("Character '>' seen not at end of tag.");
     break;
 
    case LEX_ERROR_ATTR_VAL:
-    fprintf(stderr,"XML Parser: Error on line %"PRIu64": invalid character '%c' seen in attribute value.\n",lineno,*buffer_ptr);
+    ParseXML_SetError("Invalid character '%c' seen in attribute value.",*buffer_ptr);
     break;
 
    case LEX_ERROR_ENTITY_REF:
-    fprintf(stderr,"XML Parser: Error on line %"PRIu64": invalid entity reference '%s' seen in attribute value.\n",lineno,buffer_ptr);
+    ParseXML_SetError("Invalid entity reference '%s' seen in attribute value.",buffer_ptr);
     break;
 
    case LEX_ERROR_CHAR_REF:
-    fprintf(stderr,"XML Parser: Error on line %"PRIu64": invalid character reference '%s' seen in attribute value.\n",lineno,buffer_ptr);
+    ParseXML_SetError("Invalid character reference '%s' seen in attribute value.",buffer_ptr);
     break;
 
    case LEX_ERROR_TEXT_OUTSIDE:
-    fprintf(stderr,"XML Parser: Error on line %"PRIu64": non-whitespace '%c' seen outside tag.\n",lineno,*buffer_ptr);
+    ParseXML_SetError("Non-whitespace '%c' seen outside tag.",*buffer_ptr);
     break;
 
    case LEX_ERROR_UNEXP_TAG:
-    fprintf(stderr,"XML Parser: Error on line %"PRIu64": unexpected tag '%s'.\n",lineno,buffer_token);
+    ParseXML_SetError("Unexpected tag '%s'.",buffer_token);
     break;
 
    case LEX_ERROR_UNBALANCED:
-    fprintf(stderr,"XML Parser: Error on line %"PRIu64": end tag '</%s>' doesn't match start tag '<%s ...>'.\n",lineno,buffer_token,tag->name);
+    ParseXML_SetError("End tag '</%s>' doesn't match start tag '<%s ...>'.",buffer_token,tag->name);
     break;
 
    case LEX_ERROR_NO_START:
-    fprintf(stderr,"XML Parser: Error on line %"PRIu64": end tag '</%s>' seen but there was no start tag '<%s ...>'.\n",lineno,buffer_token,buffer_token);
+    ParseXML_SetError("End tag '</%s>' seen but there was no start tag '<%s ...>'.",buffer_token,buffer_token);
     break;
 
    case LEX_ERROR_UNEXP_ATT:
-    fprintf(stderr,"XML Parser: Error on line %"PRIu64": unexpected attribute '%s' for tag '%s'.\n",lineno,buffer_token,tag->name);
+    ParseXML_SetError("Unexpected attribute '%s' for tag '%s'.",buffer_token,tag->name);
     break;
 
    case LEX_ERROR_UNEXP_EOF:
-    fprintf(stderr,"XML Parser: Error on line %"PRIu64": end of file seen without end tag '</%s>'.\n",lineno,tag->name);
+    ParseXML_SetError("End of file seen without end tag '</%s>'.",tag->name);
     break;
 
    case LEX_ERROR_XML_NOT_FIRST:
-    fprintf(stderr,"XML Parser: Error on line %"PRIu64": XML declaration '<?xml...>' not before all other tags.\n",lineno);
+    ParseXML_SetError("XML declaration '<?xml...>' not before all other tags.");
+    break;
+
+   case LEX_ERROR_CALLBACK:
+    /* The error message should have been set by the callback function, have a fallback just in case */
+    if(!stored_message)
+       ParseXML_SetError("Unknown error from tag callback function.");
     break;
    }
 
+ /* Print the error message */
+
+#ifndef LIBROUTINO
+ if(state)
+    fprintf(stderr,"XML Parser: %s\n",stored_message);
+#endif
+
  /* Delete the tagdata */
 
  if(stackdepth)
@@ -1187,6 +1224,51 @@ uint64_t ParseXML_LineNumber(void)
 
 
 /*++++++++++++++++++++++++++++++++++++++
+  Store an error message for later.
+
+  const char *format The format string.
+
+  ... The other arguments.
+  ++++++++++++++++++++++++++++++++++++++*/
+
+void ParseXML_SetError(const char *format, ...)
+{
+ va_list ap;
+ char temp[2];
+ int line_length,error_length;
+
+ line_length=snprintf(temp,1,"Error on line %" PRIu64 ": ",lineno);
+
+ va_start(ap,format);
+ error_length=vsnprintf(temp,1,format,ap);
+ va_end(ap);
+
+ if(stored_message)
+    free(stored_message);
+
+ stored_message=malloc(error_length+line_length+1);
+
+ line_length=sprintf(stored_message,"Error on line %" PRIu64 ": ",lineno);
+
+ va_start(ap,format);
+ vsprintf(stored_message+line_length,format,ap);
+ va_end(ap);
+}
+
+
+/*++++++++++++++++++++++++++++++++++++++
+  Return a stored error message.
+
+  char *ParseXML_GetError Returns the most recent stored error.
+  ++++++++++++++++++++++++++++++++++++++*/
+
+char *ParseXML_GetError(void)
+{
+ return(stored_message);
+}
+
+
+/*++++++++++++++++++++++++++++++++++++++
   Convert an XML entity reference into an ASCII string.
 
   char *ParseXML_Decode_Entity_Ref Returns a pointer to the replacement decoded string.
@@ -1215,7 +1297,7 @@ char *ParseXML_Decode_Entity_Ref(const char *string)
 
 char *ParseXML_Decode_Char_Ref(const char *string)
 {
- static char result[5]="";
+ static char result[5]=""; /* static allocation of return value (set each call) */
  long int unicode;
 
  if(string[2]=='x') unicode=strtol(string+3,NULL,16);
@@ -1224,37 +1306,37 @@ char *ParseXML_Decode_Char_Ref(const char *string)
  if(unicode<0x80)
    {
     /* 0000 0000-0000 007F  =>  0xxxxxxx */
-    result[0]=unicode;
+    result[0]=(char)unicode;
     result[1]=0;
    }
  else if(unicode<0x07FF)
    {
     /* 0000 0080-0000 07FF  =>  110xxxxx 10xxxxxx */
-    result[0]=0xC0+((unicode&0x07C0)>>6);
-    result[1]=0x80+ (unicode&0x003F);
+    result[0]=(char)(0xC0+((unicode&0x07C0)>>6));
+    result[1]=(char)(0x80+ (unicode&0x003F));
     result[2]=0;
    }
  else if(unicode<0xFFFF)
    {
     /* 0000 0800-0000 FFFF  =>  1110xxxx 10xxxxxx 10xxxxxx */
-    result[0]=0xE0+((unicode&0xF000)>>12);
-    result[1]=0x80+((unicode&0x0FC0)>>6);
-    result[2]=0x80+ (unicode&0x003F);
+    result[0]=(char)(0xE0+((unicode&0xF000)>>12));
+    result[1]=(char)(0x80+((unicode&0x0FC0)>>6));
+    result[2]=(char)(0x80+ (unicode&0x003F));
     result[3]=0;
    }
  else if(unicode<0x1FFFFF)
    {
     /* 0001 0000-001F FFFF  =>  11110xxx 10xxxxxx 10xxxxxx 10xxxxxx */
-    result[0]=0xF0+((unicode&0x1C0000)>>18);
-    result[1]=0x80+((unicode&0x03F000)>>12);
-    result[2]=0x80+((unicode&0x000FC0)>>6);
-    result[3]=0x80+ (unicode&0x00003F);
+    result[0]=(char)(0xF0+((unicode&0x1C0000)>>18));
+    result[1]=(char)(0x80+((unicode&0x03F000)>>12));
+    result[2]=(char)(0x80+((unicode&0x000FC0)>>6));
+    result[3]=(char)(0x80+ (unicode&0x00003F));
     result[4]=0;
    }
  else
    {
-    result[0]=0xFF;
-    result[1]=0xFD;
+    result[0]=(char)0xFF;
+    result[1]=(char)0xFD;
     result[2]=0;
    }
 
@@ -1265,16 +1347,16 @@ char *ParseXML_Decode_Char_Ref(const char *string)
 /*++++++++++++++++++++++++++++++++++++++
   Convert a string into something that is safe to output in an XML file.
 
-  char *ParseXML_Encode_Safe_XML Returns a pointer to the replacement encoded string (or the original if no change needed).
+  char *ParseXML_Encode_Safe_XML Returns a pointer to a static replacement encoded string (or the original if no change needed).
 
   const char *string The string to convert.
   ++++++++++++++++++++++++++++++++++++++*/
 
 char *ParseXML_Encode_Safe_XML(const char *string)
 {
- static const char hexstring[17]="0123456789ABCDEF";
+ static const char hexstring[17]="0123456789ABCDEF"; /* local lookup table */
+ static char *result=NULL;                           /* static allocation of return value */
  int i=0,j=0,len;
- char *result;
 
  for(i=0;string[i];i++)
     if(string[i]=='<' || string[i]=='>' || string[i]=='&' || string[i]=='\'' || string[i]=='"' || string[i]<32 || (unsigned char)string[i]>127)
@@ -1285,7 +1367,7 @@ char *ParseXML_Encode_Safe_XML(const char *string)
 
  len=i+256-6;
 
- result=(char*)malloc(len+7);
+ result=(char*)realloc((void*)result,len+7);
  strncpy(result,string,j=i);
 
  do
diff --git a/src/xmlparse.h b/src/xmlparse.h
index f4cb595..ec8119f 100644
--- a/src/xmlparse.h
+++ b/src/xmlparse.h
@@ -3,7 +3,7 @@
 
  Part of the Routino routing software.
  ******************/ /******************
- This file Copyright 2010-2014 Andrew M. Bishop
+ This file Copyright 2010-2015 Andrew M. Bishop
 
  This program is free software: you can redistribute it and/or modify
  it under the terms of the GNU Affero General Public License as published by
@@ -45,14 +45,14 @@ typedef struct _xmltag xmltag;
 /*+ A structure to hold the definition of a tag. +*/
 struct _xmltag
 {
- char *name;                            /*+ The name of the tag - must be in lower case. +*/
+ const char * const name;                            /*+ The name of the tag - must be in lower case. +*/
 
- int  nattributes;                      /*+ The number of valid attributes for the tag. +*/
- char *attributes[XMLPARSE_MAX_ATTRS];  /*+ The valid attributes for the tag. +*/
+ const int  nattributes;                             /*+ The number of valid attributes for the tag. +*/
+ const char * const attributes[XMLPARSE_MAX_ATTRS];  /*+ The valid attributes for the tag. +*/
 
- int  (*callback)();                    /*+ The callback function when the tag is seen. +*/
+ int  (*callback)();                                 /*+ The callback function when the tag is seen. +*/
 
- xmltag *subtags[XMLPARSE_MAX_SUBTAGS]; /*+ The list of valid tags contained within this one (null terminated). +*/
+ const xmltag * const subtags[XMLPARSE_MAX_SUBTAGS]; /*+ The list of valid tags contained within this one (null terminated). +*/
 };
 
 
@@ -69,10 +69,13 @@ struct _xmltag
 
 /* XML parser functions */
 
-int ParseXML(int fd,xmltag **tags,int options);
+int ParseXML(int fd,const xmltag * const *tags,int options);
 
 uint64_t ParseXML_LineNumber(void);
 
+void ParseXML_SetError(const char *format, ...);
+char *ParseXML_GetError(void);
+
 char *ParseXML_Decode_Entity_Ref(const char *string);
 char *ParseXML_Decode_Char_Ref(const char *string);
 char *ParseXML_Encode_Safe_XML(const char *string);
@@ -85,7 +88,7 @@ int ParseXML_IsFloating(const char *string);
 #define XMLPARSE_MESSAGE(tag,message) \
  do \
    { \
-    fprintf(stderr,"XML Parser: Error on line %" PRIu64 ": " message " in <%s> tag.\n",ParseXML_LineNumber(),tag); \
+    ParseXML_SetError(message " in <%s> tag.",tag); \
     return(1); \
    } \
     while(0)
@@ -93,7 +96,7 @@ int ParseXML_IsFloating(const char *string);
 #define XMLPARSE_INVALID(tag,attribute) \
  do \
    { \
-    fprintf(stderr,"XML Parser: Error on line %" PRIu64 ": Invalid value for '" #attribute "' attribute in <%s> tag.\n",ParseXML_LineNumber(),tag); \
+    ParseXML_SetError("Invalid value for '" #attribute "' attribute in <%s> tag.",tag); \
     return(1); \
    } \
     while(0)
@@ -103,7 +106,7 @@ int ParseXML_IsFloating(const char *string);
    { \
     if(!attribute) \
       { \
-       fprintf(stderr,"XML Parser: Error on line %" PRIu64 ": '" #attribute "' attribute must be specified in <%s> tag.\n",ParseXML_LineNumber(),tag); \
+       ParseXML_SetError("'" #attribute "' attribute must be specified in <%s> tag.",tag); \
        return(1); \
       } \
    } \
@@ -114,7 +117,7 @@ int ParseXML_IsFloating(const char *string);
    { \
     if(!attribute || !*attribute || !ParseXML_IsInteger(attribute)) \
       { \
-       fprintf(stderr,"XML Parser: Error on line %" PRIu64 ": '" #attribute "' attribute must be a integer in <%s> tag.\n",ParseXML_LineNumber(),tag); \
+       ParseXML_SetError("'" #attribute "' attribute must be a integer in <%s> tag.",tag); \
        return(1); \
       } \
    } \
@@ -125,7 +128,7 @@ int ParseXML_IsFloating(const char *string);
    { \
     if(!attribute || !*attribute || !ParseXML_IsFloating(attribute)) \
       { \
-       fprintf(stderr,"XML Parser: Error on line %" PRIu64 ": '" #attribute "' attribute must be a number in <%s> tag.\n",ParseXML_LineNumber(),tag); \
+       ParseXML_SetError("'" #attribute "' attribute must be a number in <%s> tag.",tag); \
        return(1); \
       } \
    } \
diff --git a/web/Makefile b/web/Makefile
index a280054..84f0ad8 100644
--- a/web/Makefile
+++ b/web/Makefile
@@ -2,7 +2,7 @@
 #
 # Part of the Routino routing software.
 #
-# This file Copyright 2010-2014 Andrew M. Bishop
+# This file Copyright 2010-2015 Andrew M. Bishop
 #
 # This program is free software: you can redistribute it and/or modify
 # it under the terms of the GNU Affero General Public License as published by
@@ -52,24 +52,25 @@ TRANS_FILES=$(wildcard $(WEBTRANSDIR)/translation.*.txt)
 
 DOC_FILES=$(notdir $(wildcard $(DOCDIR)/html/*.html)) $(notdir $(wildcard $(DOCDIR)/html/*.css))
 
-EXE_FILES=planetsplitter planetsplitter-slim \
-	  router         router-slim \
-	  filedumper     filedumper-slim \
-	  filedumperx
+EXE_FILES=planetsplitter$(.EXE) planetsplitter-slim$(.EXE) router$(.EXE) router-slim$(.EXE) filedumperx$(.EXE) filedumper$(.EXE) filedumper-slim$(.EXE)
 
 ########
 
-all: all-bin all-data all-doc all-profiles all-icons all-translations
+all: all-bin all-data all-doc all-profiles all-translations all-icons
+
+####
 
 all-bin: all-exe
 	@[ -d $(WEBBINDIR) ] || mkdir -p $(WEBBINDIR)
 	@for file in $(EXE_FILES); do \
-	    if [ ! -f $(WEBBINDIR)/$$file ] || [ $(SRCDIR)/$$file -nt $(WEBBINDIR)/$$file ]; then \
+	    if [ -f $(SRCDIR)/$$file -a ! -f $(WEBBINDIR)/$$file ] || [ $(SRCDIR)/$$file -nt $(WEBBINDIR)/$$file ]; then \
 	       echo cp $(SRCDIR)/$$file $(WEBBINDIR) ;\
 	       cp -f $(SRCDIR)/$$file $(WEBBINDIR) ;\
 	    fi ;\
 	 done
 
+####
+
 all-data: all-xml
 	@[ -d $(WEBDATADIR) ] || mkdir -p $(WEBDATADIR)
 	@for file in $(STANDARD_XML_FILES); do \
@@ -85,6 +86,8 @@ all-data: all-xml
 	    fi ;\
 	 done
 
+####
+
 all-doc:
 	@[ -d $(WEBDOCDIR) ] || mkdir -p $(WEBDOCDIR)
 	@for file in $(DOC_FILES); do \
@@ -94,6 +97,8 @@ all-doc:
 	    fi ;\
 	 done
 
+####
+
 all-profiles: all-exe all-data
 	@if [ ! -f $(WEBWWWDIR)/profiles.js ] || [ ! -f $(WEBWWWDIR)/profiles.pl ] || \
 	     [ $(WEBDATADIR)/profiles.xml -nt $(WEBWWWDIR)/profiles.pl ] || \
@@ -102,13 +107,33 @@ all-profiles: all-exe all-data
 	    ( cd $(WEBWWWDIR) ; perl update-profiles.pl ) ;\
 	 fi
 
-all-icons: $(WEBICONDIR)/ball-0.png
+####
 
-$(WEBICONDIR)/ball-0.png: $(WEBICONDIR)/create-icons.pl
-	@echo create-icons.pl
-	@cd $(WEBICONDIR) && perl create-icons.pl
+all-translations: $(WEBWWWDIR)/router.html    $(WEBWWWDIR)/visualiser.html \
+	          $(WEBWWWDIR)/router.html.en $(WEBWWWDIR)/visualiser.html.en \
+	          $(XMLDIR)/routino-translations.xml
+
+ifeq ($(HOST),MINGW)
+
+$(WEBWWWDIR)/router.html: $(WEBWWWDIR)/router.html.en
+	@echo cp $< $@
+	@cp -f $< $@
+
+$(WEBWWWDIR)/visualiser.html: $(WEBWWWDIR)/visualiser.html.en
+	@echo cp $< $@
+	@cp -f $< $@
 
-all-translations: $(WEBWWWDIR)/router.html.en $(WEBWWWDIR)/visualiser.html.en $(XMLDIR)/routino-translations.xml
+else
+
+$(WEBWWWDIR)/router.html: $(WEBWWWDIR)/router.html.en
+	@echo ln -s `basename $<` $@
+	@ln -s -f `basename $<` $@
+
+$(WEBWWWDIR)/visualiser.html: $(WEBWWWDIR)/visualiser.html.en
+	@echo ln -s `basename $<` $@
+	@ln -s -f `basename $<` $@
+
+endif
 
 $(WEBWWWDIR)/router.html.en: $(WEBTRANSDIR)/router.html $(TRANS_FILES) $(WEBTRANSDIR)/translate.pl
 	@echo translate.pl
@@ -122,10 +147,22 @@ $(XMLDIR)/routino-translations.xml: $(WEBTRANSDIR)/translations-head.xml $(WEBTR
 	@echo translate.pl
 	@cd $(WEBTRANSDIR) && perl translate.pl
 
+####
+
+all-icons: $(WEBICONDIR)/ball-0.png
+
+$(WEBICONDIR)/ball-0.png: $(WEBICONDIR)/create-icons.pl
+	@echo create-icons.pl
+	@cd $(WEBICONDIR) && perl create-icons.pl
+
+####
+
 all-exe:
 	cd $(SRCDIR) && $(MAKE) $(EXE_FILES)
 
-all-xml:
+####
+
+all-xml: $(XMLDIR)/routino-translations.xml
 	cd $(XMLDIR) && $(MAKE) all
 
 ########
@@ -141,19 +178,51 @@ install: all
 
 ########
 
-clean:
+clean: clean clean-all-bin clean-all-data clean-all-doc clean-all-profiles clean-all-translations clean-all-icons
 	rm -f *~
 
-########
-
-distclean: clean
+clean-all-bin:
 	-cd $(WEBBINDIR)  && rm -f $(EXE_FILES)
-	-cd $(WEBDATADIR) && rm -f $(STANDARD_XML_FILES) $(SPECIAL_XML_FILES)
+
+clean-all-data:
+	-cd $(WEBDATADIR) && rm -f $(STANDARD_XML_FILES)
+	-cd $(WEBDATADIR) && rm -f $(SPECIAL_XML_FILES)
+
+clean-all-doc:
 	-cd $(WEBDOCDIR)  && rm -f $(DOC_FILES)
+
+clean-all-profiles:
+
+clean-all-translations:
+
+clean-all-icons:
+
+########
+
+distclean: distclean-all-bin distclean-all-data distclean-all-doc distclean-all-profiles distclean-all-translations distclean-all-icons
+
+distclean-all-bin: clean-all-bin
+
+distclean-all-data: clean-all-data
+
+distclean-all-doc: clean-all-doc
+
+distclean-all-profiles: clean-all-profiles
 	-cd $(WEBWWWDIR)  && rm -f $(PROFILE_FILES)
 
+distclean-all-translations: clean-all-translations
+	-cd $(WEBWWWDIR)  && rm -f router.html*
+	-cd $(WEBWWWDIR)  && rm -f visualiser.html*
+
+distclean-all-icons: clean-all-icons
+	-cd $(WEBICONDIR) && rm -f ball-*.png limit-*.png marker-*.png
+
 ########
 
 .PHONY:: all test install clean distclean
 
 .PHONY:: all-bin all-data all-doc all-profiles all-icons all-translations all-exe all-xml
+
+.PHONY:: clean-all-bin clean-all-data clean-all-doc clean-all-profiles clean-all-translations clean-all-icons
+
+.PHONY:: distclean-all-bin distclean-all-data distclean-all-doc distclean-all-profiles distclean-all-translations distclean-all-icons
diff --git a/web/translations/router.html b/web/translations/router.html
index e28d6b5..125d3e6 100644
--- a/web/translations/router.html
+++ b/web/translations/router.html
@@ -13,7 +13,7 @@
 
  Part of the Routino routing software.
 
- This file Copyright 2008-2014 Andrew M. Bishop
+ This file Copyright 2008-2015 Andrew M. Bishop
 
  This program is free software: you can redistribute it and/or modify
  it under the terms of the GNU Affero General Public License as published by
@@ -95,24 +95,17 @@
         <span id="hideshow_waypoint_hide" onclick="hideshow_hide('waypoint');" class="hideshow_show">-</span>
         <span class="hideshow_title">@@WAYPOINTS-BOX@@</span>
         <div id="hideshow_waypoint_div">
-          <table id="waypoints">
-            <colgroup>
-              <col style="width: 22px;">
-              <col>
-              <col style="width: 76px;">
-            </colgroup>
-            <tr id="waypointXXX" style="display: none;">
-              <td>
-                <img id="iconXXX" src="icons/marker-XXX-grey.png" title="@@WAYPOINT-POSITION@@" alt="Waypoint XXX" onmousedown="markerToggleMap(XXX);">
-              <td>
-                <span id="coordsXXX">
-                  <input name="lonXXX" type="text" size="7" title="@@WAYPOINT-LONGITUDE@@" onchange="formSetCoords(XXX);">E
-                  <input name="latXXX" type="text" size="7" title="@@WAYPOINT-LATITUDE@@"  onchange="formSetCoords(XXX);">N
-                </span>
-                <span id="searchXXX" style="display: none;">
-                  <input name="searchXXX" type="text" size="18" title="@@WAYPOINT-LOCATION@@"> <!-- uses Javascript event for triggering -->
-                </span>
-              <td>
+          <div id="waypoints">
+            <div id="waypointXXX" class="waypoint" style="display: none;">
+              <img id="iconXXX" class="waypoint-icon" src="icons/marker-XXX-grey.png" title="@@WAYPOINT-POSITION@@" alt="Waypoint XXX" onmouseup="markerToggleMap(XXX);" draggable="true">
+              <span id="coordsXXX">
+                <input name="lonXXX" type="text" size="7" title="@@WAYPOINT-LONGITUDE@@" onchange="formSetCoords(XXX);">E
+                <input name="latXXX" type="text" size="7" title="@@WAYPOINT-LATITUDE@@"  onchange="formSetCoords(XXX);">N
+              </span>
+              <span id="searchXXX" style="display: none;">
+                <input name="searchXXX" type="text" size="18" title="@@WAYPOINT-LOCATION@@"> <!-- uses Javascript event for triggering -->
+              </span>
+              <div class="waypoint-buttons" style="display: inline-block;">
                 <img alt="?" src="icons/waypoint-search.png"   title="@@WAYPOINT-SEARCH@@"  onmousedown="markerSearch(XXX);"  >
                 <img alt="G" src="icons/waypoint-locate.png"   title="@@WAYPOINT-GET@@"     onmousedown="markerLocate(XXX);"  >
                 <img alt="O" src="icons/waypoint-recentre.png" title="@@WAYPOINT-CENTRE1@@" onmousedown="markerRecentre(XXX);">
@@ -124,14 +117,15 @@
                 <img alt="o" src="icons/waypoint-centre.png"   title="@@WAYPOINT-CENTRE2@@" onmousedown="markerCentre(XXX);"  >
                 <img alt="v" src="icons/waypoint-down.png"     title="@@WAYPOINT-DOWN@@"    onmousedown="markerMoveDown(XXX);">
                 <img alt="-" src="icons/waypoint-remove.png"   title="@@WAYPOINT-REMOVE@@"  onmousedown="markerRemove(XXX);"  >
-            <tr id="searchresultsXXX" style="display: none;">
-              <td colspan="3">
-            <!-- The waypoints are inserted by the JavaScript, see the "maxmarkers" variable in router.js.  -->
-            <tr>
-              <td colspan="3" class="center">
-                <input type="button" title="@@WAYPOINT-REVERSE@@" value="@@WAYPOINT-REVERSE-BUTTON@@" onmousedown="markersReverse();">
-                <input type="button" title="@@WAYPOINT-LOOP@@"    value="@@WAYPOINT-LOOP-BUTTON@@"    onmousedown="markersLoop();">
-          </table>
+              </div>
+              <div id="searchresultsXXX" style="display: none;">
+              </div>
+            </div>
+          </div>
+          <div id="waypoints-buttons" class="center">
+            <input type="button" title="@@WAYPOINT-REVERSE@@" value="@@WAYPOINT-REVERSE-BUTTON@@" onmousedown="markersReverse();">
+            <input type="button" title="@@WAYPOINT-LOOP@@"    value="@@WAYPOINT-LOOP-BUTTON@@"    onmousedown="markersLoop();">
+          </div>
         </div>
       </div>
 
@@ -223,8 +217,8 @@
         <span class="hideshow_title">@@OTHER-RESTRICTIONS-BOX@@</span>
         <div id="hideshow_restriction_div" style="display: none;">
           <table>
-            <tr><td>@@RESTRICT-ONEWAY@@:   <td><input name="restrict-oneway" type="checkbox" onchange="formSetRestriction('oneway');">
-            <tr><td>@@RESTRICT-TURNS@@:<td><input name="restrict-turns"  type="checkbox" onchange="formSetRestriction('turns' );">
+            <tr><td>@@RESTRICT-ONEWAY@@:<td><input name="restrict-oneway" type="checkbox" onchange="formSetRestriction('oneway');">
+            <tr><td>@@RESTRICT-TURNS@@: <td><input name="restrict-turns"  type="checkbox" onchange="formSetRestriction('turns' );">
           </table>
           <table>
             <tr><td>@@RESTRICT-WEIGHT@@:<td><input name="restrict-weight" type="text" size="3" onchange="formSetRestriction('weight','=');"><td>tonnes<td><img alt="<" src="icons/waypoint-left.png" title="-" onmousedown="formSetRestriction('weight','-');">–/+<img alt=">" src="icons/waypoint-right.png" title="+" onmousedown="formSetRestriction('weight','+');">
diff --git a/web/translations/translate.pl b/web/translations/translate.pl
index d579660..4125851 100755
--- a/web/translations/translate.pl
+++ b/web/translations/translate.pl
@@ -4,7 +4,7 @@
 #
 # Part of the Routino routing software.
 #
-# This file Copyright 2014 Andrew M. Bishop
+# This file Copyright 2014-2015 Andrew M. Bishop
 #
 # This program is free software: you can redistribute it and/or modify
 # it under the terms of the GNU Affero General Public License as published by
@@ -34,6 +34,10 @@ my %languages=();
 my %translations=();
 
 
+# Sort so that English is first
+
+ at translation_files=sort {if($a eq "translation.en.txt"){return -1;} if($b eq "translation.en.txt"){return 1;} return $a <=> $b;} @translation_files;
+
 # Read in the translations
 
 foreach my $translation_file (@translation_files)
@@ -135,6 +139,14 @@ foreach my $translation_file (@translation_files)
             $translations{$language}->{codes}->{$code}->{usedR}=0;
             $translations{$language}->{codes}->{$code}->{usedV}=0;
            }
+
+         my($n_strings_en)=$translations{en}->{codes}->{$code}->{text} =~ s/%s/%s/g;
+         my($n_strings)   =$text =~ s/%s/%s/g;
+
+         if($n_strings != $n_strings_en)
+           {
+            print STDERR "Language: $language WRONG number of '%s' in text '$text' ($translations{en}->{codes}->{$code}->{text})\n";
+           }
         }
      }
 
@@ -307,6 +319,7 @@ foreach my $language (@languages)
       my $line=$_;
 
       $line =~ s%~~lang~~%$language%g;
+      $line =~ s%~~language~~%$translations{$language}->{codes}->{'@@LANGUAGE@@'}->{text}%g;
 
       # Replace with translated phrases
 
diff --git a/web/translations/translation.de.txt b/web/translations/translation.de.txt
index 372844e..b74169b 100644
--- a/web/translations/translation.de.txt
+++ b/web/translations/translation.de.txt
@@ -11,7 +11,7 @@
 %%copyright_source_text%%	Basierend auf OpenStreetMap-Daten, erhältlich via http://www.openstreetmap.org/
 %%copyright_license_string%%	Lizenz
 
-%%turn_-4%%	Spitzkehre nach links
+%%turn_-4%%	Sehr scharf links
 %%turn_-3%%	Scharf links
 %%turn_-2%%	Links
 %%turn_-1%%	Halb links
@@ -19,7 +19,7 @@
 %%turn_1%%	Halb rechts
 %%turn_2%%	Rechts
 %%turn_3%%	Scharf rechts
-%%turn_4%%	Spitzkehre nach rechts
+%%turn_4%%	Sehr scharf rechts
 
 %%heading_-4%%	Süd
 %%heading_-3%%	Süd-West
@@ -45,14 +45,14 @@
 %%highway_motorway%%	Autobahn
 %%highway_trunk%%	Schnellstraße
 %%highway_primary%%	Bundesstraße
-%%highway_secondary%%	Landstraße
+%%highway_secondary%%	Landesstraße
 %%highway_tertiary%%	Kreisstraße
 %%highway_unclassified%%	Nebenstraße
 %%highway_residential%%	Wohngebietsstraße
 %%highway_service%%	Erschließungsweg
-%%highway_track%%	Wirtschaftsweg
+%%highway_track%%	Feld-/Waldweg
 %%highway_cycleway%%	Radweg
-%%highway_path%%	Weg
+%%highway_path%%	Weg/Pfad
 %%highway_steps%%	Treppe
 %%highway_ferry%%	Fähre
 
@@ -63,18 +63,13 @@
 %%output-html_waypoint_junction%%	Anschlussstelle
 %%output-html_waypoint_roundabout%%	Kreisverkehr
 %%output-html_title%%	%s Route
-%%output-html_start_string%%	Start
-%%output-html_start_text%%	Bei %s halten Sie sich Richtung %s
-%%output-html_node_string%%	Bei
-%%output-html_node_text%%	Bei %s wenden Sie sich nach %s Richtung %s
-%%output-html_rbnode_string%%	Verlassen Sie
-%%output-html_rbnode_text%%	%s, nehmen Sie die %s Ausfahrt Richtung %s
-%%output-html_segment_string%%	Folgen
-%%output-html_segment_text%%	Folgen Sie der %s für %.3f km bzw. %.1f min
-%%output-html_stop_string%%	Stop
-%%output-html_stop_text%%	Sie sind bei %s angekommen
-%%output-html_total_string%%	Gesamt
-%%output-html_total_text%%	%.1f km, %.0f minuten
+%%output-html_start%%	Start bei %s halten Sie sich Richtung %s
+%%output-html_node%%	Bei %s wenden Sie sich nach %s Richtung %s
+%%output-html_rbnode%%	Verlassen Sie %s, nehmen Sie die %s Ausfahrt Richtung %s
+%%output-html_segment%%	Folgen Sie der %s für %.3f km bzw. %.1f min
+%%output-html_stop%%	Stop Sie sind bei %s angekommen
+%%output-html_total%%	Gesamt %.1f km, %.0f minuten
+%%output-html_subtotal%%	%.1f km, %.0f minuten
 
 %%output-gpx_waypoint_start%%	START
 %%output-gpx_waypoint_inter%%	INTER
@@ -126,17 +121,24 @@
 @@STATISTICS-BOX@@	Routino Statistik
 @@VISUALISER-BOX@@	Routino Ansichten
 
+@@WAYPOINT-POSITION@@	Wegpunkt XXX Position
+@@WAYPOINT-LONGITUDE@@	Wegpunkt XXX geografische Länge
+@@WAYPOINT-LATITUDE@@	Wegpunkt XXX geografische Breite
+@@WAYPOINT-LOCATION@@	Wegpunkt XXX Ort
 @@WAYPOINT-SEARCH@@	Nach Ort suchen
 @@WAYPOINT-GET@@	Aktuellen Ort bestimmen
 @@WAYPOINT-CENTRE1@@	Karte auf Wegpunkt zentrieren
 @@WAYPOINT-UP@@	wegpunkt nach oben verschieben
 @@WAYPOINT-ADD@@	Neuer Wegpunkt nach diesem
 @@WAYPOINT-COORDS@@	Koordinaten des Orts
+@@WAYPOINT-HOME@@	Umschalten auf den Standort des Zuhauses
 @@WAYPOINT-CENTRE2@@	Wegpunkt auf Karte zentrieren
 @@WAYPOINT-DOWN@@	Wegpunkt nach unten verschieben
 @@WAYPOINT-REMOVE@@	Wegpunkt entfernen
 @@WAYPOINT-REVERSE@@	Rückwärts
 @@WAYPOINT-REVERSE-BUTTON@@	Rückwärts
+@@WAYPOINT-LOOP@@	Einen Wegpunkt hinzufügen um eine Schlaufe zu machen
+@@WAYPOINT-LOOP-BUTTON@@	Schleife schließen
 
 @@TRANSPORT-FOOT@@	Fußgänger
 @@TRANSPORT-HORSE@@	Reiter
@@ -146,8 +148,8 @@
 @@TRANSPORT-MOTORCYCLE@@	Motorrad
 @@TRANSPORT-MOTORCAR@@	Auto
 @@TRANSPORT-GOODS@@	LKW
-@@TRANSPORT-HGV@@	Schwertransport
-@@TRANSPORT-PSV@@	Personenverkehr
+@@TRANSPORT-HGV@@	Schwertransport/LKW
+@@TRANSPORT-PSV@@	Öffentlicher Personenverkehr
 
 @@HIGHWAY-MOTORWAY@@	Autobahn
 @@HIGHWAY-TRUNK@@	Schnellstraße
@@ -160,7 +162,7 @@
 @@HIGHWAY-TRACK@@	Feld-(Wald-)weg
 @@HIGHWAY-CYCLEWAY@@	Fahrradweg
 @@HIGHWAY-PATH@@	Weg
-@@HIGHWAY-STEPS@@	Fußweg
+@@HIGHWAY-STEPS@@	Treppe
 @@HIGHWAY-FERRY@@	Fähre
 
 @@PROPERTY-PAVED@@	befestigt
@@ -223,6 +225,7 @@
 @@VISUALISER-NUM-SEGMENTS@@	# Segmente verarbeitet
 @@VISUALISER-NUM-NODES@@	# Knoten verarbeitet
 @@VISUALISER-NUM-TURNS@@	# Abbiegebeschrängkungen verarbeitet
+@@VISUALISER-NUM-LIMITS@@	# Limit-Änderungen verarbeitet
 @@VISUALISER-NUM-ERRORS@@	# Error Logs erstellt
 
 @@JUNCTIONS-BUTTON@@	Kreuzungen anzeigen
@@ -235,10 +238,20 @@
 
 @@SUPER-BUTTON@@	Super-Segments anzeigen
 
+@@TURNS-BUTTON@@	Zeige Abbiegebeschränkungen
+
+@@SPEED-BUTTON@@	Zeige Geschwindigkeitsbeschränkungen
+
+@@SPEED-LIMIT-80@@	80 km/Stunde Geschwindigkeitsbegrenzung
+
+@@WEIGHT-BUTTON@@	Gewichtswegbeschränkungen anzeigen
+
 @@WEIGHT-LIMIT-8@@	8 Tonnen Wegbeschränkung
 
 @@HEIGHT-BUTTON@@	Maximale Höhe anzeigen 
 
+@@HEIGHT-LIMIT-4@@	4.0 m Höhenbeschränkung
+
 @@WIDTH-BUTTON@@	Maximale Breite anzeigen
 
 @@CLEAR-DATA-BUTTON@@	Daten zurücksetzen
@@ -319,10 +332,10 @@ Vorgaben sollte es erlauben eine Route zu finden.
   <dd>Eine Beschreibung der Route mit Anweisungen für jede wichtige Abzweigung.
   <dt>GPX Track-Datei
   <dd>Die gleichen Informationen, die in der Karte angezeigt werden mit Punkten für jeden Abzweig
-  und Linien für jedes Teilstück.
+      und Linien für jedes Teilstück.
   <dt>GPX Routen-Datei
   <dd>Die gleichen Informationen, die im Text angezeigt werden mit einem Wegpunkt für
-  jede wichtige Richtungsänderung.
+      jede wichtige Richtungsänderung.
   <dt>Volltext-Datei
   <dd>Eine aller Knoten und die Abstände zwischen ihnen, sowie die Gesamtentfernung vom i
       Startpunkt zum jeweiligen Konten.
diff --git a/web/translations/translation.en.txt b/web/translations/translation.en.txt
index ad75945..d8750bd 100644
--- a/web/translations/translation.en.txt
+++ b/web/translations/translation.en.txt
@@ -63,18 +63,13 @@
 %%output-html_waypoint_junction%%	Junction
 %%output-html_waypoint_roundabout%%	Roundabout
 %%output-html_title%%	%s Route
-%%output-html_start_string%%	Start
-%%output-html_start_text%%	At %s, head %s
-%%output-html_node_string%%	At
-%%output-html_node_text%%	%s, go %s heading %s
-%%output-html_rbnode_string%%	Leave
-%%output-html_rbnode_text%%	%s, take the %s exit heading %s
-%%output-html_segment_string%%	Follow
-%%output-html_segment_text%%	%s for %.3f km, %.1f min
-%%output-html_stop_string%%	Stop
-%%output-html_stop_text%%	At %s
-%%output-html_total_string%%	Total
-%%output-html_total_text%%	%.1f km, %.0f minutes
+%%output-html_start%%	Start at %s, head %s
+%%output-html_node%%	At %s, go %s heading %s
+%%output-html_rbnode%%	Leave %s, take the %s exit heading %s
+%%output-html_segment%%	Follow %s for %.3f km, %.1f min
+%%output-html_stop%%	Stop at %s
+%%output-html_total%%	Total %.1f km, %.0f minutes
+%%output-html_subtotal%%	%.1f km, %.0f minutes
 
 %%output-gpx_waypoint_start%%	START
 %%output-gpx_waypoint_inter%%	INTER
@@ -126,7 +121,7 @@
 @@STATISTICS-BOX@@	Routino Statistics
 @@VISUALISER-BOX@@	Routino Visualiser
 
-@@WAYPOINT-POSITION@@	Waypoint XXX Position - (click to add/remove on map)
+@@WAYPOINT-POSITION@@	Waypoint XXX Position
 @@WAYPOINT-LONGITUDE@@	Waypoint XXX Longitude
 @@WAYPOINT-LATITUDE@@	Waypoint XXX Latitude
 @@WAYPOINT-LOCATION@@	Waypoint XXX Location
diff --git a/web/translations/translation.fr.txt b/web/translations/translation.fr.txt
index b04ab4b..91d0fb0 100644
--- a/web/translations/translation.fr.txt
+++ b/web/translations/translation.fr.txt
@@ -63,18 +63,13 @@
 %%output-html_waypoint_junction%%	Croisement
 %%output-html_waypoint_roundabout%%	rond-point
 %%output-html_title%%	Itinéraire %s
-%%output-html_start_string%%	Débute
-%%output-html_start_text%%	à %s, direction %s
-%%output-html_node_string%%	à
-%%output-html_node_text%%	%s, aller %s direction %s
-%%output-html_rbnode_string%%	Quitter
-%%output-html_rbnode_text%%	%s, prendre le %s sortir direction %s
-%%output-html_segment_string%%	Suivre
-%%output-html_segment_text%%	%s pendant %.3f km, %.1f min
-%%output-html_stop_string%%	S'arrêter
-%%output-html_stop_text%%	à %s
-%%output-html_total_string%%	Total
-%%output-html_total_text%%	%.1f km, %.0f minutes
+%%output-html_start%%	Débute à %s, direction %s
+%%output-html_node%%	à %s, aller %s direction %s
+%%output-html_rbnode%%	Quitter %s, prendre le %s sortir direction %s
+%%output-html_segment%%	Suivre %s pendant %.3f km, %.1f min
+%%output-html_stop%%	S'arrêter à %s
+%%output-html_total%%	Total %.1f km, %.0f minutes
+%%output-html_subtotal%%	%.1f km, %.0f minutes
 
 %%output-gpx_waypoint_start%%	DEBUT
 %%output-gpx_waypoint_inter%%	INTER
@@ -125,7 +120,7 @@
 @@STATISTICS-BOX@@	Routino Statistiques
 @@VISUALISER-BOX@@	Routino Visualiser
 
-@@WAYPOINT-POSITION@@	Etape XXX de l'itinéraire - (cliquer pour ajouter/enlever de la carte)
+@@WAYPOINT-POSITION@@	Etape XXX de l'itinéraire
 @@WAYPOINT-LONGITUDE@@	Etape XXX Longitude
 @@WAYPOINT-LATITUDE@@	Etape XXX Latitude
 @@WAYPOINT-LOCATION@@	position de l'étape XXX
diff --git a/web/translations/translation.hu.txt b/web/translations/translation.hu.txt
new file mode 100644
index 0000000..27f6902
--- /dev/null
+++ b/web/translations/translation.hu.txt
@@ -0,0 +1,271 @@
+#
+# Hungarian language translation phrases
+#
+
+#
+# Router output XML definition
+#
+
+%%copyright_creator_string%%	Készítő
+%%copyright_source_string%%	Forrás
+%%copyright_source_text%%	Openstreetmap adatok alapján http://www.openstreetmap.org/
+%%copyright_license_string%%	Liszenc
+
+%%turn_-4%%	Nagyon élesen balra
+%%turn_-3%%	Élesen balra
+%%turn_-2%%	Balra
+%%turn_-1%%	Balra tarts
+%%turn_0%%	Egyenesen
+%%turn_1%%	Jobbra tarts
+%%turn_2%%	Jobbra
+%%turn_3%%	Élesen jobbra
+%%turn_4%%	Nagyon élesen jobbra
+
+%%heading_-4%%	dél
+%%heading_-3%%	délnyugat
+%%heading_-2%%	nyugat
+%%heading_-1%%	északnyugat
+%%heading_0%%	észak
+%%heading_1%%	északkelet
+%%heading_2%%	kelet
+%%heading_3%%	délkelet
+%%heading_4%%	dél
+
+%%ordinal_1%%	első
+%%ordinal_2%%	második
+%%ordinal_3%%	harmadik
+%%ordinal_4%%	negyedik
+%%ordinal_5%%	ötödik
+%%ordinal_6%%	hatodik
+%%ordinal_7%%	hetedik
+%%ordinal_8%%	nyolcadik
+%%ordinal_9%%	kilencedik
+%%ordinal_10%%	tizedik
+
+%%highway_motorway%%	autópálya
+%%highway_trunk%%	autóút
+%%highway_primary%%	főút
+%%highway_secondary%%	összekötőút
+%%highway_tertiary%%	bekötőút
+%%highway_unclassified%%	egyéb közút
+%%highway_residential%%	lakóút
+%%highway_service%%	szervízút
+%%highway_track%%	földút
+%%highway_cycleway%%	kerékpárút
+%%highway_path%%	ösvény
+%%highway_steps%%	lépcső
+%%highway_ferry%%	komp
+
+%%route_shortest%%	Legrövidebb
+%%route_quickest%%	Leggyorsabb
+
+%%output-html_waypoint_waypoint%%	Útpont
+%%output-html_waypoint_junction%%	Kereszteződés
+%%output-html_waypoint_roundabout%%	Körforgalom
+%%output-html_title%%	%s útvonal
+%%output-html_start%%	Indulás %s, %s felé
+%%output-html_node%%	Itt %s, menj %s %s felé
+%%output-html_rbnode%%	Kijárat %s, %s kijárat %s felé
+%%output-html_segment%%	Erre %s, %.3f km, %.1f perc
+%%output-html_total%%	Összesen %.1f km, %.0f perc
+%%output-html_subtotal%%	%.1f km, %.0f perc
+
+%%output-gpx_waypoint_start%%	Indulás
+%%output-gpx_waypoint_trip%%	Utazás
+
+%%output-gpx_desc%%	%s útvonal a kezdő és utolsó pont között
+%%output-gpx_final%%	Az egész út %.1f km, %.0f perc
+
+#
+# Router (and some shared) translations
+#
+
+@@LANGUAGE@@	Magyar
+@@LANGUAGE-WEBPAGE@@	Magyar weblap
+
+@@ROUTER-TITLE@@	Openstreetmap alapú útvonaltervező
+
+@@OPTION-TAB@@	Beállítások
+@@OPTION-TAB-HELP@@	Útvonaltervező beállítások
+
+@@RESULTS-TAB@@	Eredmény
+@@RESULTS-TAB-HELP@@	Útvonaltervező eredmények
+
+@@DATA-TAB@@	Adatok
+@@DATA-TAB-HELP@@	Adatbázis információk
+
+@@ROUTINO-ROUTER@@	Routino openstreetmap útvonaltervező
+@@ROUTINO-WEBSITE@@	Routino weboldal
+@@DOCUMENTATION@@	Dokumentáció
+
+@@LANGUAGE-BOX@@	Nyelv
+@@WAYPOINTS-BOX@@	Útpontok
+@@TRANSPORT-TYPE-BOX@@	Közlekedési mód
+@@HIGHWAY-PREFERENCES-BOX@@	Út preferencia
+@@SPEED-LIMITS-BOX@@	Sebességkorlát
+@@PROPERTY-PREFERENCES-BOX@@	Út tulajdonságok
+@@OTHER-RESTRICTIONS-BOX@@	Kizáró tényezők
+@@LINKS-BOX@@	Linkek
+@@HELP-BOX@@	Súgó
+
+@@STATUS-BOX@@	Állapot
+@@SHORTEST-ROUTE@@	Legrövidebb út
+@@QUICKEST-ROUTE@@	Leggyorsabb út
+
+@@STATISTICS-BOX@@	Routino statisztika
+@@VISUALISER-BOX@@	Routino vizualizáció
+
+@@WAYPOINT-SEARCH@@	Hely keresése
+@@WAYPOINT-GET@@	Aktuális helyzet
+@@WAYPOINT-CENTRE1@@	Legyen ez a pont a térkép közepe
+@@WAYPOINT-UP@@	Mozgasd feljebb ezt a pontot
+@@WAYPOINT-ADD@@	Új pont ezután a pont után
+@@WAYPOINT-COORDS@@	Hely koordinátája
+@@WAYPOINT-CENTRE2@@	Ez legyen a térkép középpontja
+@@WAYPOINT-DOWN@@	Mozgasd ezt a pontot lejjebb
+@@WAYPOINT-REMOVE@@	Pont törlése
+@@WAYPOINT-REVERSE@@	Útirány megfordítása
+@@WAYPOINT-REVERSE-BUTTON@@	Ellenkező irány
+@@WAYPOINT-LOOP@@	Új pont létrehozása a kezdőpontban
+@@WAYPOINT-LOOP-BUTTON@@	Kör bezárása
+
+@@TRANSPORT-FOOT@@	Gyalog
+@@TRANSPORT-HORSE@@	Lovas
+@@TRANSPORT-WHEELCHAIR@@	Kerekesszékes
+@@TRANSPORT-BICYCLE@@	Kerékpáros
+@@TRANSPORT-MOPED@@	Robogós
+@@TRANSPORT-MOTORCYCLE@@	Motoros
+@@TRANSPORT-MOTORCAR@@	Autós
+@@TRANSPORT-GOODS@@	Kisteherautós
+@@TRANSPORT-HGV@@	Kamionos
+@@TRANSPORT-PSV@@	Buszos
+
+@@HIGHWAY-MOTORWAY@@	Autópálya
+@@HIGHWAY-TRUNK@@	Autóút
+@@HIGHWAY-PRIMARY@@	Főút
+@@HIGHWAY-SECONDARY@@	Összekötőút
+@@HIGHWAY-TERTIARY@@	Bekötőút
+@@HIGHWAY-UNCLASSIFIED@@	Egyéb közút
+@@HIGHWAY-RESIDENTIAL@@	Lakóövezeti út
+@@HIGHWAY-SERVICE@@	Szervízút
+@@HIGHWAY-TRACK@@	Földút
+@@HIGHWAY-CYCLEWAY@@	Kerékpárút
+@@HIGHWAY-PATH@@	Ösvény
+@@HIGHWAY-STEPS@@	Lépcső
+@@HIGHWAY-FERRY@@	Komp
+
+@@PROPERTY-PAVED@@	Burkolt
+@@PROPERTY-MULTILANE@@	Többsávos
+@@PROPERTY-BRIDGE@@	Híd
+@@PROPERTY-TUNNEL@@	Alagút
+@@PROPERTY-WALKINGROUTE@@	Gyalogút
+@@PROPERTY-BICYCLEROUTE@@	Kijelölt kerékpárút
+
+@@RESTRICT-ONEWAY@@	Egyirányúsítás mellőzése
+@@RESTRICT-TURNS@@	Kanyarodási tilalmak mellőzése
+@@RESTRICT-WEIGHT@@	Súly
+@@RESTRICT-HEIGHT@@	Magasság
+@@RESTRICT-WIDTH@@	Szélesség
+@@RESTRICT-LENGTH@@	Hosszúság
+
+@@FIND-SHORTEST-ROUTE@@	A legrövidebb út keresése
+@@FIND-QUICKEST-ROUTE@@	A leggyorsabb út keresése
+
+@@MAP-VIEW-LINK@@	Link erre a nézetre
+@@EDIT-OSM-DATA@@	OSM adatok szerkesztése
+
+@@ROUTER-NOT-RUN@@	Az útvonaltervező nem fut
+@@ROUTER-RUNNING@@	Az útvonaltervező számol ...
+@@ROUTER-COMPLETED@@	Az útvonaltervezés kész
+@@ROUTER-ERROR@@	Útvonaltervezési hiba
+@@ROUTER-FAILED@@	Az útvonaltervezőt nem sikerült futtatni
+@@VIEW-DETAILS@@	Részletek
+
+@@NO-INFORMATION@@	Nincs információ
+@@HTML-ROUTE@@	HTML irányok
+@@GPX-TRACK-ROUTE@@	GPX file
+@@FULL-TEXT-ROUTE@@	Teljes szöveges file
+@@TEXT-ROUTE@@	Szöveges file
+@@OPEN-POPUP@@	Új ablak
+
+@@DISPLAY-STATISTICS@@	Statisztika mutatása
+
+@@ROUTER@@	Útvonaltervező
+@@TILES@@	Térképszeletek
+
+#
+# Visualiser specific translations
+#
+
+@@VISUALISER-TITLE@@	Útvonaltervező adatok vizuálisan
+
+@@INSTRUCTIONS-BOX@@	Útmutatók
+@@ROUTER-BOX@@	Routino Útvonaltervező
+
+@@NO-DATA-DISPLAYED@@	Nincs megjelenítendő adat
+
+@@VISUALISER-FAILED@@	Sikertelen az adatok betöltése
+@@VISUALISER-NUM-JUNCTIONS@@	Feldolgozva # kereszteződés
+@@VISUALISER-NUM-SUPER@@	Feldolgozva # szuper-pont/szegmens
+@@VISUALISER-NUM-WAYTYPE@@	Feldolgozva # út típus szegmens
+@@VISUALISER-NUM-SEGMENTS@@	Feldolgozva # szegmens
+@@VISUALISER-NUM-NODES@@	Feldolgozva # pont
+@@VISUALISER-NUM-TURNS@@	Feldolgozva # kanyarodási korlátozás
+
+@@JUNCTIONS-BUTTON@@	Kereszteződések mutatása
+@@JUNCTIONS-3@@	három út talákozása
+@@JUNCTIONS-4@@	négy út találkozása
+@@JUNCTIONS-5@@	öt út találkozása
+@@JUNCTIONS-6@@	hat út találkozása
+@@JUNCTIONS-MORE@@	hét, vagy több út találkozása
+
+@@SUPER-BUTTON@@	Szuper szegmens mutatása
+
+@@WAYTYPE-BUTTON@@	Út típus szakaszok megjelenítese
+
+@@WAYTYPE-ONEWAY@@	Egyirányú szakaszok
+@@WAYTYPE-ROUNDABOUT@@	Körforgalmi szakaszok
+
+@@HIGHWAY-BUTTON@@	Út szakaszok megjelenítése
+
+@@TURNS-BUTTON@@	Kanyarodási korlátozások
+
+@@SPEED-BUTTON@@	Sebességhatárok
+
+@@LIMIT-CHANGE@@	Korlátozás változása
+@@LIMIT-NONE@@	Nincs korlátozás
+@@SPEED-LIMIT-80@@	80 km/óra sebességkorlátozás
+
+@@WEIGHT-BUTTON@@	Súlykorlátozások
+
+@@WEIGHT-LIMIT-8@@	8 tonnás súlykorlátozás
+
+@@HEIGHT-BUTTON@@	Magasságkorlátozások
+
+@@HEIGHT-LIMIT-4@@	4 méter magasságkorlátozás
+
+@@WIDTH-BUTTON@@	Szélességkorlátozások
+
+@@WIDTH-LIMIT-3@@	3 méter szélességkorlátozás
+
+@@LENGTH-BUTTON@@	Hosszúságkorlátozások
+
+@@LENGTH-LIMIT-9@@	9 méter hosszúságkorlátozás
+
+@@PROPERTY-BUTTON@@	Út tulajdonságok megjelenítése
+
+@@ERROR-LOG-BUTTON@@	Hiba logok megmutatása
+$$ERROR-LOG-INFO$$
+Lehetséges hibák fordultak elő az adatok feldolgozása során
+$$ERROR-LOG-INFO$$
+
+@@CLEAR-DATA-BUTTON@@	Adatok törlése
+
+#
+# Multi-line descriptive translations (router)
+#
+
+#
+# Multi-line descriptive translations (visualiser)
+#
+
diff --git a/web/translations/translation.nl.txt b/web/translations/translation.nl.txt
index cfc537a..23c4681 100644
--- a/web/translations/translation.nl.txt
+++ b/web/translations/translation.nl.txt
@@ -63,18 +63,13 @@
 %%output-html_waypoint_junction%%	de splitsing
 %%output-html_waypoint_roundabout%%	rotonde
 %%output-html_title%%	%s Route
-%%output-html_start_string%%	Start
-%%output-html_start_text%%	Bij %s neemt u de richting %s
-%%output-html_node_string%%	Bij
-%%output-html_node_text%%	Bij %s gaat u %s richting %s
-%%output-html_rbnode_string%%	Leave
-%%output-html_rbnode_text%%	Aan de %s, neem de %s afslag richting %s
-%%output-html_segment_string%%	Volg
-%%output-html_segment_text%%	Volgt u de %s voor %.3f km %.1f min
-%%output-html_stop_string%%	Stop
-%%output-html_stop_text%%	U bent bij  %s aangekomen
-%%output-html_total_string%%	Totaal
-%%output-html_total_text%%	%.1f km, %.0f minuten
+%%output-html_start%%	Start bij %s neemt u de richting %s
+%%output-html_node%%	Bij %s gaat u %s richting %s
+%%output-html_rbnode%%	Leave aan de %s, neem de %s afslag richting %s
+%%output-html_segment%%	Volg u de %s voor %.3f km %.1f min
+%%output-html_stop%%	Stop U bent bij %s aangekomen
+%%output-html_total%%	Totaal %.1f km, %.0f minuten
+%%output-html_subtotal%%	%.1f km, %.0f minuten
 
 %%output-gpx_waypoint_start%%	START
 %%output-gpx_waypoint_inter%%	INTER
@@ -84,7 +79,7 @@
 %%output-gpx_desc%%	%s Route tussen 'Start' und 'Finish'
 %%output-gpx_name%%	%s Route
 %%output-gpx_step%%	%s op '%s' voor %.3f km, %.1f min
-%%output-gpx_final%%	Totaal trip  %.1f km, %.0f minuten
+%%output-gpx_final%%	Totaal trip %.1f km, %.0f minuten
 
 #
 # Router (and some shared) translations
@@ -114,7 +109,7 @@
 @@SHORTEST-ROUTE@@	Kortste Route
 @@QUICKEST-ROUTE@@	Snelste Route
 
-@@WAYPOINT-POSITION@@	Waypoint XXX Position - (click voor plaatsen/verwijderen op map)
+@@WAYPOINT-POSITION@@	Waypoint XXX Position
 @@WAYPOINT-UP@@	Beweeg dit punt naar boven
 @@WAYPOINT-ADD@@	Voeg hierna punt toe
 @@WAYPOINT-HOME@@	Toggle als thuis locatie
@@ -174,13 +169,31 @@
 @@HTML-ROUTE@@	HTML directions
 @@GPX-TRACK-ROUTE@@	GPX track bestand
 @@GPX-ROUTE@@	GPX route bestand
-@@FULL-TEXT-ROUTE@@	Full text bestand
-@@TEXT-ROUTE@@	Text bestand
+@@FULL-TEXT-ROUTE@@	Volledig tekst bestand
+@@TEXT-ROUTE@@	Tekst bestand
 
 #
 # Visualiser specific translations
 #
 
+@@INSTRUCTIONS-BOX@@	Instructies
+
+@@NO-DATA-DISPLAYED@@	Geen data getoond
+
+@@SPEED-BUTTON@@	Toon snelheidslimieten
+
+@@WEIGHT-BUTTON@@	Toon massa limieten
+
+@@WEIGHT-LIMIT-8@@	8.0 ton massa limiet
+
+@@HEIGHT-BUTTON@@	Toon hoogte limieten
+
+@@HEIGHT-LIMIT-4@@	4.0 m hoogte limiet
+
+@@WIDTH-BUTTON@@	Toon breedte limieten
+
+@@WIDTH-LIMIT-3@@	3.0 m breedte limiet
+
 #
 # Multi-line descriptive translations (router)
 #
@@ -200,7 +213,7 @@ Het is best om eerst naar straat niveau te zoomen op de kaart.
 Selecteer het transport type, toegestane weg-types,
 snelheidslimieten, wegeigenschappen en andere restricties uit de
 opties.
-Selecteer  "Kortste" of "Snelste" om de route te berekenen en te tekenen op de map.
+Selecteer "Kortste" of "Snelste" om de route te berekenen en te tekenen op de map.
 <p>
 <b>Coordinaten (Waypoints)</b>
 <br>
diff --git a/web/translations/translation.pl.txt b/web/translations/translation.pl.txt
new file mode 100644
index 0000000..3b4c30f
--- /dev/null
+++ b/web/translations/translation.pl.txt
@@ -0,0 +1,217 @@
+#
+# Polish language translation phrases
+#
+
+#
+# Router output XML definition
+#
+
+%%copyright_creator_string%%	Twórca
+%%copyright_source_string%%	Źródło
+%%copyright_source_text%%	Oparte na danych OpenStreetMap ze strony http://www.openstreetmap.org/
+%%copyright_license_string%%	Licencja
+
+%%turn_-4%%	Bardzo ostro w lewo
+%%turn_-3%%	Ostro w lewo
+%%turn_-2%%	W lewo
+%%turn_-1%%	Lekko w lewo
+%%turn_0%%	Prosto
+%%turn_1%%	Lekko w prawo
+%%turn_2%%	W prawo
+%%turn_3%%	Ostro w prawo
+%%turn_4%%	Bardzo ostro w prawo
+
+%%heading_-4%%	Na południe
+%%heading_-3%%	Na południowy zachód
+%%heading_-2%%	Na zachód
+%%heading_-1%%	Na północny zachód
+%%heading_0%%	Na północ
+%%heading_1%%	Na północny wschód
+%%heading_2%%	Na wschód
+%%heading_3%%	Na południowy wschód
+%%heading_4%%	Na południe
+
+%%ordinal_1%%	Pierwszy
+%%ordinal_2%%	Drugi
+%%ordinal_3%%	Trzeci
+%%ordinal_4%%	Czwarty
+%%ordinal_5%%	Piąty
+%%ordinal_6%%	Szósty
+%%ordinal_7%%	Siódmy
+%%ordinal_8%%	Ósmy
+%%ordinal_9%%	Dziewiąty
+%%ordinal_10%%	Dziesiąty
+
+%%highway_motorway%%	Autostrada
+%%highway_trunk%%	Droga ekspresowa
+%%highway_primary%%	Droga krajowa
+%%highway_secondary%%	Droga powiatowa
+%%highway_tertiary%%	Droga lokalna
+%%highway_unclassified%%	Droga nieznanego typu
+%%highway_residential%%	Droga osiedlowa
+%%highway_service%%	Droga dojazdowa
+%%highway_track%%	Droga polna
+%%highway_cycleway%%	Droga rowerowa
+%%highway_path%%	Ścieżka
+%%highway_steps%%	Pieszo
+%%highway_ferry%%	Prom
+
+%%route_shortest%%	Najkrótsza
+%%route_quickest%%	Najszybsza
+
+%%output-html_waypoint_waypoint%%	Punkt
+%%output-html_waypoint_roundabout%%	Rondo
+%%output-html_title%%	%s Trasa
+%%output-html_start%%	Start %s kieruj się na %s
+%%output-html_segment%%	Podążaj %s przez %.3f km, %.1f min.
+%%output-html_stop%%	Stop Na %s
+%%output-html_total%%	Całkowity %.1f km, %.0f min.
+%%output-html_subtotal%%	%.1f km, %.0f min.
+
+%%output-gpx_waypoint_start%%	START
+%%output-gpx_waypoint_inter%%	INTER
+%%output-gpx_waypoint_trip%%	TRIP
+%%output-gpx_waypoint_finish%%	KONIEC
+
+%%output-gpx_desc%%	%s trasa pomiędzy 'start' a 'koniec'
+%%output-gpx_name%%	%s trasa
+%%output-gpx_step%%	%s na %s przez %.3f km, %.1f min.
+%%output-gpx_final%%	Całkowita podróż %.1f km, %.0f min.
+
+#
+# Router (and some shared) translations
+#
+
+@@LANGUAGE@@	Polski
+@@LANGUAGE-WEBPAGE@@	Polski webpage
+
+@@ROUTER-TITLE@@	Planowanie trasy dla Danych OpenStreetMap
+
+@@OPTION-TAB@@	Opcje
+@@OPTION-TAB-HELP@@	Ustaw punkty trasy
+
+@@RESULTS-TAB@@	Wyniki
+@@RESULTS-TAB-HELP@@	Zobacz wyniki
+
+@@DATA-TAB@@	Dane
+@@DATA-TAB-HELP@@	Zobacz informacje bazy danych
+
+@@ROUTINO-ROUTER@@	Routino OpenStreetMap Planowanie Trasy
+@@ROUTINO-WEBSITE@@	Strona Routino
+@@DOCUMENTATION@@	Dokumentacja
+
+@@LANGUAGE-BOX@@	Język
+@@WAYPOINTS-BOX@@	Punkty
+@@TRANSPORT-TYPE-BOX@@	Typ transportu
+@@HIGHWAY-PREFERENCES-BOX@@	Preferowanie autostrad
+@@SPEED-LIMITS-BOX@@	Ograniczenia prędkości
+@@OTHER-RESTRICTIONS-BOX@@	Inne ograniczenia
+@@FIND-BOX@@	Znajdź
+@@LINKS-BOX@@	Połączenia
+@@HELP-BOX@@	Pomoc
+
+@@STATUS-BOX@@	Status
+@@SHORTEST-ROUTE@@	Najkrótsza trasa
+@@QUICKEST-ROUTE@@	Najszybsza trasa
+
+@@STATISTICS-BOX@@	Statystyki Routino
+@@VISUALISER-BOX@@	Wizualizer Routino
+
+@@WAYPOINT-SEARCH@@	Znajdź miejsce
+@@WAYPOINT-GET@@	Pobierz aktualna lokalizację
+@@WAYPOINT-CENTRE1@@	Wycentruj mapę na tym punkcie
+@@WAYPOINT-HOME@@	Współrzędne lokalizacji
+
+@@TRANSPORT-FOOT@@	Pieszo
+@@TRANSPORT-HORSE@@	Konno
+@@TRANSPORT-WHEELCHAIR@@	Wózek inwalidzki
+@@TRANSPORT-BICYCLE@@	Rower
+@@TRANSPORT-MOPED@@	Moped
+@@TRANSPORT-MOTORCYCLE@@	Motocykl
+@@TRANSPORT-MOTORCAR@@	Samochód
+@@TRANSPORT-PSV@@	Pojazd użyteczności publicznej
+
+@@HIGHWAY-MOTORWAY@@	Autostrada
+@@HIGHWAY-PRIMARY@@	Droga krajowa
+@@HIGHWAY-SECONDARY@@	Droga wojewódzka
+@@HIGHWAY-TERTIARY@@	Droga powiatowa
+@@HIGHWAY-UNCLASSIFIED@@	Niesklasyfikowana
+@@HIGHWAY-RESIDENTIAL@@	W obszarze zamieszkania
+@@HIGHWAY-SERVICE@@	Dojazdowa
+@@HIGHWAY-CYCLEWAY@@	Rowerowa
+@@HIGHWAY-PATH@@	Ścieżka
+@@HIGHWAY-FERRY@@	Przeprawa
+
+@@PROPERTY-MULTILANE@@	Wiele pasów
+@@PROPERTY-BRIDGE@@	Most
+@@PROPERTY-TUNNEL@@	Tunel
+@@PROPERTY-WALKINGROUTE@@	Trasa piesza
+@@PROPERTY-BICYCLEROUTE@@	Trasa rowerowa
+
+@@RESTRICT-ONEWAY@@	Respektuj ulice jednokierunkowe
+@@RESTRICT-TURNS@@	Respektuj ograniczenia skrętu
+@@RESTRICT-WEIGHT@@	Waga
+@@RESTRICT-HEIGHT@@	Wysokość
+@@RESTRICT-WIDTH@@	Szerokość
+@@RESTRICT-LENGTH@@	Długość
+
+@@FIND-SHORTEST-ROUTE@@	Znajdź najkrótsza trasę
+@@FIND-QUICKEST-ROUTE@@	Znajdź najdłuższą trasę
+
+@@ROUTER-NOT-RUN@@	Nie uruchomiono wyznaczania trasy
+@@ROUTER-RUNNING@@	Wyznaczanie trasy w trakcie...
+@@ROUTER-COMPLETED@@	Trasa wyznaczona
+@@ROUTER-ERROR@@	Błąd wyznaczania trasy
+@@ROUTER-FAILED@@	Błąd uruchomienia wyznaczania trasy
+@@VIEW-DETAILS@@	Zobacz szczegóły
+
+@@NO-INFORMATION@@	Brak informacji
+@@GPX-TRACK-ROUTE@@	Plik trasy w formacie GPX
+@@GPX-ROUTE@@	Plik nawigacji w formacie GPX
+@@TEXT-ROUTE@@	Plik tekstowy
+
+@@TILES@@	Kafelki
+
+#
+# Visualiser specific translations
+#
+
+@@INSTRUCTIONS-BOX@@	Instrukcje
+
+@@NO-DATA-DISPLAYED@@	Brak danych do wyświetlenia
+
+@@TURNS-BUTTON@@	Wyświetlaj zakazy skrętu
+
+@@SPEED-BUTTON@@	Wyświetlaj ograniczenia prędkości
+
+@@SPEED-LIMIT-80@@	Ograniczenie prędkości do 80 km/h
+
+@@WEIGHT-BUTTON@@	Wyświetlaj ograniczenia ciężaru
+
+@@WEIGHT-LIMIT-8@@	Ograniczenie ciężaru do 8.0 ton
+
+@@HEIGHT-BUTTON@@	Wyświetlaj ograniczenia wysokości
+
+@@HEIGHT-LIMIT-4@@	Ograniczenie wysokości do 4.0 m
+
+@@WIDTH-BUTTON@@	Wyświetlaj ograniczenia szerokości
+
+@@WIDTH-LIMIT-3@@	Ograniczenie szerokości do 3.0 m
+
+@@LENGTH-BUTTON@@	Wyświetlaj ograniczenia długości
+
+@@LENGTH-LIMIT-9@@	Ograniczenie długości do 9.0 m
+
+@@CLEAR-DATA-BUTTON@@	Wyczyść
+
+#
+# Multi-line descriptive translations (router)
+#
+
+#
+# Multi-line descriptive translations (visualiser)
+#
+
+$$VISUALISER-ROUTER-INFO$$
+Aby wyznaczyć trasę na mapie użyj linku poniżej
+$$VISUALISER-ROUTER-INFO$$
diff --git a/web/translations/translation.ru.txt b/web/translations/translation.ru.txt
index 4cf4fbf..496f650 100644
--- a/web/translations/translation.ru.txt
+++ b/web/translations/translation.ru.txt
@@ -62,17 +62,12 @@
 %%output-html_waypoint_waypoint%%	путевая точка
 %%output-html_waypoint_junction%%	перекрестке
 %%output-html_title%%	%s маршрут
-%%output-html_start_string%%	Старт
-%%output-html_start_text%%	 %s, на %s
-%%output-html_node_string%%	на
-%%output-html_node_text%%	%s, %s,  на %s
-%%output-html_rbnode_string%%	Покинуть
-%%output-html_segment_string%%	Следуйте
-%%output-html_segment_text%%	по %s %.3f км, %.1f мин
-%%output-html_stop_string%%	Стоп
-%%output-html_stop_text%%	 %s
-%%output-html_total_string%%	Всего
-%%output-html_total_text%%	%.1f км, %.0f минут
+%%output-html_start%%	Старт  %s, на %s
+%%output-html_node%%	на %s, %s, на %s
+%%output-html_segment%%	Следуйте по %s %.3f км, %.1f мин
+%%output-html_stop%%	Стоп  %s
+%%output-html_total%%	Всего %.1f км, %.0f минут
+%%output-html_subtotal%%	%.1f км, %.0f минут
 
 %%output-gpx_waypoint_start%%	Старт
 %%output-gpx_waypoint_inter%%	INTER
diff --git a/web/translations/translations-body.xml b/web/translations/translations-body.xml
index 7e0c153..c435fa7 100644
--- a/web/translations/translations-body.xml
+++ b/web/translations/translations-body.xml
@@ -1,4 +1,4 @@
-  <language lang="~~lang~~">
+  <language lang="~~lang~~" language="~~language~~">
 
     <!-- Copyright of the data being routed, not of this file  -->
     <copyright>
@@ -68,12 +68,13 @@
 
       <title text="%%output-html_title%%" /> <!-- %s = [shortest|quickest] -->
 
-      <start   string="%%output-html_start_string%%" text="%%output-html_start_text%%" /> <!-- 1st %s = [waypoint|junction], 2nd %s = [heading] -->
-      <node    string="%%output-html_node_string%%" text="%%output-html_node_text%%" /> <!-- 1st %s = [waypoint|junction], 2nd %s = [turn], 3rd %s = [heading] -->
-      <rbnode  string="%%output-html_rbnode_string%%" text="%%output-html_rbnode_text%%" /> <!-- 1st %s = [roundabout], 2nd %s = [first|second|...], 3rd %s = [heading] -->
-      <segment string="%%output-html_segment_string%%" text="%%output-html_segment_text%%" /> <!-- 1st %s = street name -->
-      <stop    string="%%output-html_stop_string%%" text="%%output-html_stop_text%%" /> <!-- 1st %s = [waypoint|junction] -->
-      <total   string="%%output-html_total_string%%" text="%%output-html_total_text%%" />
+      <start    text="%%output-html_start%%" /> <!-- 1st %s = [waypoint|junction], 2nd %s = [heading] -->
+      <node     text="%%output-html_node%%" /> <!-- 1st %s = [waypoint|junction], 2nd %s = [turn], 3rd %s = [heading] -->
+      <rbnode   text="%%output-html_rbnode%%" /> <!-- 1st %s = [roundabout], 2nd %s = [first|second|...], 3rd %s = [heading] -->
+      <segment  text="%%output-html_segment%%" /> <!-- 1st %s = street name -->
+      <stop     text="%%output-html_stop%%" /> <!-- 1st %s = [waypoint|junction] -->
+      <total    text="%%output-html_total%%" />
+      <subtotal text="%%output-html_subtotal%%" />
     </output-html>
 
     <!-- GPX output -->
diff --git a/web/translations/translations-head.xml b/web/translations/translations-head.xml
index 2c0e8d4..16ba5e0 100644
--- a/web/translations/translations-head.xml
+++ b/web/translations/translations-head.xml
@@ -5,7 +5,7 @@
 
      Part of the Routino routing software.
      ============================================================
-     This file Copyright 2010-2014 Andrew M. Bishop
+     This file Copyright 2010-2015 Andrew M. Bishop
 
      This program is free software: you can redistribute it and/or modify
      it under the terms of the GNU Affero General Public License as published by
diff --git a/web/www/leaflet/install.sh b/web/www/leaflet/install.sh
index 30d95bd..1361ad0 100755
--- a/web/www/leaflet/install.sh
+++ b/web/www/leaflet/install.sh
@@ -1,6 +1,6 @@
 #!/bin/sh -x
 
-version=0.7.2
+version=0.7.3
 
 # Download the file.
 
diff --git a/web/www/routino/.htaccess b/web/www/routino/.htaccess
index 29ea962..df36362 100644
--- a/web/www/routino/.htaccess
+++ b/web/www/routino/.htaccess
@@ -38,3 +38,13 @@ AddHandler cgi-script .cgi
    Order deny,allow
    Deny from all
 </FilesMatch>
+
+# The Polish language web page translations will have a '.html.pl' extension for
+# the MultiViews option so they must be allowed specifically and not blocked by
+# the above prohibition on serving Perl scripts.  They must also be served with
+# the HTML mime type.
+
+<FilesMatch .*\.html\.pl$>
+   AddType text/html .pl
+   Allow from all
+</FilesMatch>
diff --git a/web/www/routino/icons/limit-2.6.png b/web/www/routino/icons/limit-2.6.png
index 4e0d2eb..d40e90e 100644
Binary files a/web/www/routino/icons/limit-2.6.png and b/web/www/routino/icons/limit-2.6.png differ
diff --git a/web/www/routino/icons/limit-2.8.png b/web/www/routino/icons/limit-2.8.png
index 6585d61..fc7f1f0 100644
Binary files a/web/www/routino/icons/limit-2.8.png and b/web/www/routino/icons/limit-2.8.png differ
diff --git a/web/www/routino/icons/limit-20.6.png b/web/www/routino/icons/limit-20.6.png
index b439543..37ee6ca 100644
Binary files a/web/www/routino/icons/limit-20.6.png and b/web/www/routino/icons/limit-20.6.png differ
diff --git a/web/www/routino/icons/limit-20.8.png b/web/www/routino/icons/limit-20.8.png
index 6fa6316..b35a2f6 100644
Binary files a/web/www/routino/icons/limit-20.8.png and b/web/www/routino/icons/limit-20.8.png differ
diff --git a/web/www/routino/icons/limit-21.6.png b/web/www/routino/icons/limit-21.6.png
index 5e4eeef..b1a4b55 100644
Binary files a/web/www/routino/icons/limit-21.6.png and b/web/www/routino/icons/limit-21.6.png differ
diff --git a/web/www/routino/icons/limit-21.8.png b/web/www/routino/icons/limit-21.8.png
index cf298f4..4b4c33f 100644
Binary files a/web/www/routino/icons/limit-21.8.png and b/web/www/routino/icons/limit-21.8.png differ
diff --git a/web/www/routino/icons/limit-22.6.png b/web/www/routino/icons/limit-22.6.png
index 95b17ce..ef96e3b 100644
Binary files a/web/www/routino/icons/limit-22.6.png and b/web/www/routino/icons/limit-22.6.png differ
diff --git a/web/www/routino/icons/limit-22.8.png b/web/www/routino/icons/limit-22.8.png
index fef4a76..c387a8c 100644
Binary files a/web/www/routino/icons/limit-22.8.png and b/web/www/routino/icons/limit-22.8.png differ
diff --git a/web/www/routino/icons/limit-23.6.png b/web/www/routino/icons/limit-23.6.png
index eea8028..c872ec1 100644
Binary files a/web/www/routino/icons/limit-23.6.png and b/web/www/routino/icons/limit-23.6.png differ
diff --git a/web/www/routino/icons/limit-23.8.png b/web/www/routino/icons/limit-23.8.png
index 4e1c3b6..71870d4 100644
Binary files a/web/www/routino/icons/limit-23.8.png and b/web/www/routino/icons/limit-23.8.png differ
diff --git a/web/www/routino/icons/limit-24.6.png b/web/www/routino/icons/limit-24.6.png
index f46ec77..111b207 100644
Binary files a/web/www/routino/icons/limit-24.6.png and b/web/www/routino/icons/limit-24.6.png differ
diff --git a/web/www/routino/icons/limit-24.8.png b/web/www/routino/icons/limit-24.8.png
index 2b046cb..5011e9d 100644
Binary files a/web/www/routino/icons/limit-24.8.png and b/web/www/routino/icons/limit-24.8.png differ
diff --git a/web/www/routino/icons/limit-25.5.png b/web/www/routino/icons/limit-25.5.png
index c180ac9..98cc7e2 100644
Binary files a/web/www/routino/icons/limit-25.5.png and b/web/www/routino/icons/limit-25.5.png differ
diff --git a/web/www/routino/icons/limit-25.6.png b/web/www/routino/icons/limit-25.6.png
index 758b68f..9ab690d 100644
Binary files a/web/www/routino/icons/limit-25.6.png and b/web/www/routino/icons/limit-25.6.png differ
diff --git a/web/www/routino/icons/limit-25.8.png b/web/www/routino/icons/limit-25.8.png
index 588fc6f..cdd9841 100644
Binary files a/web/www/routino/icons/limit-25.8.png and b/web/www/routino/icons/limit-25.8.png differ
diff --git a/web/www/routino/icons/limit-26.4.png b/web/www/routino/icons/limit-26.4.png
index 7b77a7e..cad0d2d 100644
Binary files a/web/www/routino/icons/limit-26.4.png and b/web/www/routino/icons/limit-26.4.png differ
diff --git a/web/www/routino/icons/limit-26.6.png b/web/www/routino/icons/limit-26.6.png
index ad61235..9847fde 100644
Binary files a/web/www/routino/icons/limit-26.6.png and b/web/www/routino/icons/limit-26.6.png differ
diff --git a/web/www/routino/icons/limit-26.8.png b/web/www/routino/icons/limit-26.8.png
index 5ab6746..9e5e38c 100644
Binary files a/web/www/routino/icons/limit-26.8.png and b/web/www/routino/icons/limit-26.8.png differ
diff --git a/web/www/routino/icons/limit-26.png b/web/www/routino/icons/limit-26.png
index 18e9e62..6379016 100644
Binary files a/web/www/routino/icons/limit-26.png and b/web/www/routino/icons/limit-26.png differ
diff --git a/web/www/routino/icons/limit-27.6.png b/web/www/routino/icons/limit-27.6.png
index ca95d5d..259a475 100644
Binary files a/web/www/routino/icons/limit-27.6.png and b/web/www/routino/icons/limit-27.6.png differ
diff --git a/web/www/routino/icons/limit-27.8.png b/web/www/routino/icons/limit-27.8.png
index 562c949..bb11f11 100644
Binary files a/web/www/routino/icons/limit-27.8.png and b/web/www/routino/icons/limit-27.8.png differ
diff --git a/web/www/routino/icons/limit-28.4.png b/web/www/routino/icons/limit-28.4.png
index e8de0dd..707cafc 100644
Binary files a/web/www/routino/icons/limit-28.4.png and b/web/www/routino/icons/limit-28.4.png differ
diff --git a/web/www/routino/icons/limit-28.6.png b/web/www/routino/icons/limit-28.6.png
index 923fef7..283027c 100644
Binary files a/web/www/routino/icons/limit-28.6.png and b/web/www/routino/icons/limit-28.6.png differ
diff --git a/web/www/routino/icons/limit-28.8.png b/web/www/routino/icons/limit-28.8.png
index f14137a..c64e756 100644
Binary files a/web/www/routino/icons/limit-28.8.png and b/web/www/routino/icons/limit-28.8.png differ
diff --git a/web/www/routino/icons/limit-28.png b/web/www/routino/icons/limit-28.png
index ffc85ea..4e1e36e 100644
Binary files a/web/www/routino/icons/limit-28.png and b/web/www/routino/icons/limit-28.png differ
diff --git a/web/www/routino/icons/limit-29.6.png b/web/www/routino/icons/limit-29.6.png
index c01b036..4e9bb34 100644
Binary files a/web/www/routino/icons/limit-29.6.png and b/web/www/routino/icons/limit-29.6.png differ
diff --git a/web/www/routino/icons/limit-29.8.png b/web/www/routino/icons/limit-29.8.png
index 78a4396..6fe17ff 100644
Binary files a/web/www/routino/icons/limit-29.8.png and b/web/www/routino/icons/limit-29.8.png differ
diff --git a/web/www/routino/index.html b/web/www/routino/index.html
index 317d734..4d41b24 100644
--- a/web/www/routino/index.html
+++ b/web/www/routino/index.html
@@ -3,6 +3,7 @@
 
 <head>
 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<meta name="viewport" content="width=device-width, initial-scale=1">
 <meta http-equiv="refresh" content="1; URL=router.html">
 
 <title>Routino : Route Planner for OpenStreetMap Data</title>
@@ -12,7 +13,7 @@
 
  Part of the Routino routing software.
 
- This file Copyright 2008-2013 Andrew M. Bishop
+ This file Copyright 2008-2015 Andrew M. Bishop
 
  This program is free software: you can redistribute it and/or modify
  it under the terms of the GNU Affero General Public License as published by
@@ -39,7 +40,6 @@
 
 <h1>Routino : Route Planner for OpenStreetMap Data</h1>
 
-<hr>
 </div>
 
 <!-- Header End -->
@@ -57,7 +57,6 @@
 <!-- Footer Start -->
 
 <div class="footer">
-<hr>
 
 <address>
 © Andrew M. Bishop - <a href="http://www.routino.org/">http://www.routino.org/</a>
diff --git a/web/www/routino/profiles.js b/web/www/routino/profiles.js
new file mode 100644
index 0000000..0867250
--- /dev/null
+++ b/web/www/routino/profiles.js
@@ -0,0 +1,76 @@
+////////////////////////////////////////////////////////////////////////////////
+/////////////////////////// Routino default profile ////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
+
+var routino={ // contains all default Routino options (generated using "--help-profile-json").
+
+  // Default transport type
+  transport: "motorcar",
+
+  // Transport types
+  transports: { foot: 1, horse: 2, wheelchair: 3, bicycle: 4, moped: 5, motorcycle: 6, motorcar: 7, goods: 8, hgv: 9, psv: 10 },
+
+  // Highway types
+  highways: { motorway: 1, trunk: 2, primary: 3, secondary: 4, tertiary: 5, unclassified: 6, residential: 7, service: 8, track: 9, cycleway: 10, path: 11, steps: 12, ferry: 13 },
+
+  // Property types
+  properties: { paved: 1, multilane: 2, bridge: 3, tunnel: 4, footroute: 5, bicycleroute: 6 },
+
+  // Restriction types
+  restrictions: { oneway: 1, turns: 2, weight: 3, height: 4, width: 5, length: 6 },
+
+  // Allowed highways
+  profile_highway: {
+        motorway: { foot:   0, horse:   0, wheelchair:   0, bicycle:   0, moped:   0, motorcycle: 100, motorcar: 100, goods: 100, hgv: 100, psv: 100 },
+           trunk: { foot:  40, horse:  25, wheelchair:  40, bicycle:  30, moped:  90, motorcycle: 100, motorcar: 100, goods: 100, hgv: 100, psv: 100 },
+         primary: { foot:  50, horse:  50, wheelchair:  50, bicycle:  70, moped: 100, motorcycle:  90, motorcar:  90, goods:  90, hgv:  90, psv:  90 },
+       secondary: { foot:  60, horse:  50, wheelchair:  60, bicycle:  80, moped:  90, motorcycle:  80, motorcar:  80, goods:  80, hgv:  80, psv:  80 },
+        tertiary: { foot:  70, horse:  75, wheelchair:  70, bicycle:  90, moped:  80, motorcycle:  70, motorcar:  70, goods:  70, hgv:  70, psv:  70 },
+    unclassified: { foot:  80, horse:  75, wheelchair:  80, bicycle:  90, moped:  70, motorcycle:  60, motorcar:  60, goods:  60, hgv:  60, psv:  60 },
+     residential: { foot:  90, horse:  75, wheelchair:  90, bicycle:  90, moped:  60, motorcycle:  50, motorcar:  50, goods:  50, hgv:  50, psv:  50 },
+         service: { foot:  90, horse:  75, wheelchair:  90, bicycle:  90, moped:  80, motorcycle:  80, motorcar:  80, goods:  80, hgv:  80, psv:  80 },
+           track: { foot:  95, horse: 100, wheelchair:  95, bicycle:  90, moped:   0, motorcycle:   0, motorcar:   0, goods:   0, hgv:   0, psv:   0 },
+        cycleway: { foot:  95, horse:  90, wheelchair:  95, bicycle: 100, moped:   0, motorcycle:   0, motorcar:   0, goods:   0, hgv:   0, psv:   0 },
+            path: { foot: 100, horse: 100, wheelchair: 100, bicycle:  90, moped:   0, motorcycle:   0, motorcar:   0, goods:   0, hgv:   0, psv:   0 },
+           steps: { foot:  80, horse:   0, wheelchair:   0, bicycle:   0, moped:   0, motorcycle:   0, motorcar:   0, goods:   0, hgv:   0, psv:   0 },
+           ferry: { foot:  20, horse:  20, wheelchair:  20, bicycle:  20, moped:  20, motorcycle:  20, motorcar:  20, goods:  20, hgv:  20, psv:  20 }
+     },
+
+  // Speed limits
+  profile_speed: {
+        motorway: { foot:   0, horse:   0, wheelchair:   0, bicycle:   0, moped:  48, motorcycle: 112, motorcar: 112, goods:  96, hgv:  89, psv:  89 },
+           trunk: { foot:   4, horse:   8, wheelchair:   4, bicycle:  20, moped:  48, motorcycle:  96, motorcar:  96, goods:  96, hgv:  80, psv:  80 },
+         primary: { foot:   4, horse:   8, wheelchair:   4, bicycle:  20, moped:  48, motorcycle:  96, motorcar:  96, goods:  96, hgv:  80, psv:  80 },
+       secondary: { foot:   4, horse:   8, wheelchair:   4, bicycle:  20, moped:  48, motorcycle:  88, motorcar:  88, goods:  88, hgv:  80, psv:  80 },
+        tertiary: { foot:   4, horse:   8, wheelchair:   4, bicycle:  20, moped:  48, motorcycle:  80, motorcar:  80, goods:  80, hgv:  80, psv:  80 },
+    unclassified: { foot:   4, horse:   8, wheelchair:   4, bicycle:  20, moped:  48, motorcycle:  64, motorcar:  64, goods:  64, hgv:  64, psv:  64 },
+     residential: { foot:   4, horse:   8, wheelchair:   4, bicycle:  20, moped:  48, motorcycle:  48, motorcar:  48, goods:  48, hgv:  48, psv:  48 },
+         service: { foot:   4, horse:   8, wheelchair:   4, bicycle:  20, moped:  32, motorcycle:  32, motorcar:  32, goods:  32, hgv:  32, psv:  32 },
+           track: { foot:   4, horse:   8, wheelchair:   4, bicycle:  20, moped:  16, motorcycle:  16, motorcar:  16, goods:  16, hgv:  16, psv:  16 },
+        cycleway: { foot:   4, horse:   8, wheelchair:   4, bicycle:  20, moped:   0, motorcycle:   0, motorcar:   0, goods:   0, hgv:   0, psv:   0 },
+            path: { foot:   4, horse:   8, wheelchair:   4, bicycle:  20, moped:   0, motorcycle:   0, motorcar:   0, goods:   0, hgv:   0, psv:   0 },
+           steps: { foot:   4, horse:   0, wheelchair:   4, bicycle:   0, moped:   0, motorcycle:   0, motorcar:   0, goods:   0, hgv:   0, psv:   0 },
+           ferry: { foot:  10, horse:  10, wheelchair:  10, bicycle:  10, moped:  10, motorcycle:  10, motorcar:  10, goods:  10, hgv:  10, psv:  10 }
+     },
+
+  // Highway properties
+  profile_property: {
+            paved: { foot:  50, horse:  20, wheelchair:  90, bicycle:  50, moped: 100, motorcycle: 100, motorcar: 100, goods: 100, hgv: 100, psv: 100 },
+        multilane: { foot:  25, horse:  25, wheelchair:  25, bicycle:  25, moped:  35, motorcycle:  60, motorcar:  60, goods:  60, hgv:  60, psv:  60 },
+           bridge: { foot:  50, horse:  50, wheelchair:  50, bicycle:  50, moped:  50, motorcycle:  50, motorcar:  50, goods:  50, hgv:  50, psv:  50 },
+           tunnel: { foot:  50, horse:  50, wheelchair:  50, bicycle:  50, moped:  50, motorcycle:  50, motorcar:  50, goods:  50, hgv:  50, psv:  50 },
+        footroute: { foot:  55, horse:  50, wheelchair:  55, bicycle:  50, moped:  50, motorcycle:  50, motorcar:  45, goods:  45, hgv:  45, psv:  45 },
+     bicycleroute: { foot:  55, horse:  50, wheelchair:  55, bicycle:  60, moped:  50, motorcycle:  50, motorcar:  45, goods:  45, hgv:  45, psv:  45 }
+     },
+
+  // Restrictions
+  profile_restrictions: {
+          oneway: { foot:    0, horse:    1, wheelchair:    0, bicycle:    1, moped:    1, motorcycle:    1, motorcar:    1, goods:    1, hgv:    1, psv:    1 },
+           turns: { foot:    0, horse:    1, wheelchair:    0, bicycle:    1, moped:    1, motorcycle:    1, motorcar:    1, goods:    1, hgv:    1, psv:    1 },
+          weight: { foot:  0.0, horse:  0.0, wheelchair:  0.0, bicycle:  0.0, moped:  0.0, motorcycle:  0.0, motorcar:  0.0, goods:  5.0, hgv: 10.0, psv: 15.0 },
+          height: { foot:  0.0, horse:  0.0, wheelchair:  0.0, bicycle:  0.0, moped:  0.0, motorcycle:  0.0, motorcar:  0.0, goods:  2.5, hgv:  3.0, psv:  3.0 },
+           width: { foot:  0.0, horse:  0.0, wheelchair:  0.0, bicycle:  0.0, moped:  0.0, motorcycle:  0.0, motorcar:  0.0, goods:  2.0, hgv:  2.5, psv:  2.5 },
+          length: { foot:  0.0, horse:  0.0, wheelchair:  0.0, bicycle:  0.0, moped:  0.0, motorcycle:  0.0, motorcar:  0.0, goods:  5.0, hgv:  6.0, psv:  6.0 }
+     }
+
+}; // end of routino variable
diff --git a/web/www/routino/profiles.pl b/web/www/routino/profiles.pl
new file mode 100644
index 0000000..2479edf
--- /dev/null
+++ b/web/www/routino/profiles.pl
@@ -0,0 +1,78 @@
+################################################################################
+########################### Routino default profile ############################
+################################################################################
+
+$routino={ # contains all default Routino options (generated using "--help-profile-perl").
+
+  # Default transport type
+  transport => "motorcar",
+
+  # Transport types
+  transports => { foot => 1, horse => 2, wheelchair => 3, bicycle => 4, moped => 5, motorcycle => 6, motorcar => 7, goods => 8, hgv => 9, psv => 10 },
+
+  # Highway types
+  highways => { motorway => 1, trunk => 2, primary => 3, secondary => 4, tertiary => 5, unclassified => 6, residential => 7, service => 8, track => 9, cycleway => 10, path => 11, steps => 12, ferry => 13 },
+
+  # Property types
+  properties => { paved => 1, multilane => 2, bridge => 3, tunnel => 4, footroute => 5, bicycleroute => 6 },
+
+  # Restriction types
+  restrictions => { oneway => 1, turns => 2, weight => 3, height => 4, width => 5, length => 6 },
+
+  # Allowed highways
+  profile_highway => {
+      motorway => { foot =>   0,  horse =>   0,  wheelchair =>   0,  bicycle =>   0,  moped =>   0,  motorcycle => 100,  motorcar => 100,  goods => 100,  hgv => 100,  psv => 100 },
+         trunk => { foot =>  40,  horse =>  25,  wheelchair =>  40,  bicycle =>  30,  moped =>  90,  motorcycle => 100,  motorcar => 100,  goods => 100,  hgv => 100,  psv => 100 },
+       primary => { foot =>  50,  horse =>  50,  wheelchair =>  50,  bicycle =>  70,  moped => 100,  motorcycle =>  90,  motorcar =>  90,  goods =>  90,  hgv =>  90,  psv =>  90 },
+     secondary => { foot =>  60,  horse =>  50,  wheelchair =>  60,  bicycle =>  80,  moped =>  90,  motorcycle =>  80,  motorcar =>  80,  goods =>  80,  hgv =>  80,  psv =>  80 },
+      tertiary => { foot =>  70,  horse =>  75,  wheelchair =>  70,  bicycle =>  90,  moped =>  80,  motorcycle =>  70,  motorcar =>  70,  goods =>  70,  hgv =>  70,  psv =>  70 },
+  unclassified => { foot =>  80,  horse =>  75,  wheelchair =>  80,  bicycle =>  90,  moped =>  70,  motorcycle =>  60,  motorcar =>  60,  goods =>  60,  hgv =>  60,  psv =>  60 },
+   residential => { foot =>  90,  horse =>  75,  wheelchair =>  90,  bicycle =>  90,  moped =>  60,  motorcycle =>  50,  motorcar =>  50,  goods =>  50,  hgv =>  50,  psv =>  50 },
+       service => { foot =>  90,  horse =>  75,  wheelchair =>  90,  bicycle =>  90,  moped =>  80,  motorcycle =>  80,  motorcar =>  80,  goods =>  80,  hgv =>  80,  psv =>  80 },
+         track => { foot =>  95,  horse => 100,  wheelchair =>  95,  bicycle =>  90,  moped =>   0,  motorcycle =>   0,  motorcar =>   0,  goods =>   0,  hgv =>   0,  psv =>   0 },
+      cycleway => { foot =>  95,  horse =>  90,  wheelchair =>  95,  bicycle => 100,  moped =>   0,  motorcycle =>   0,  motorcar =>   0,  goods =>   0,  hgv =>   0,  psv =>   0 },
+          path => { foot => 100,  horse => 100,  wheelchair => 100,  bicycle =>  90,  moped =>   0,  motorcycle =>   0,  motorcar =>   0,  goods =>   0,  hgv =>   0,  psv =>   0 },
+         steps => { foot =>  80,  horse =>   0,  wheelchair =>   0,  bicycle =>   0,  moped =>   0,  motorcycle =>   0,  motorcar =>   0,  goods =>   0,  hgv =>   0,  psv =>   0 },
+         ferry => { foot =>  20,  horse =>  20,  wheelchair =>  20,  bicycle =>  20,  moped =>  20,  motorcycle =>  20,  motorcar =>  20,  goods =>  20,  hgv =>  20,  psv =>  20 }
+     },
+
+  # Speed limits
+  profile_speed => {
+      motorway => { foot =>   0,  horse =>   0,  wheelchair =>   0,  bicycle =>   0,  moped =>  48,  motorcycle => 112,  motorcar => 112,  goods =>  96,  hgv =>  89,  psv =>  89 },
+         trunk => { foot =>   4,  horse =>   8,  wheelchair =>   4,  bicycle =>  20,  moped =>  48,  motorcycle =>  96,  motorcar =>  96,  goods =>  96,  hgv =>  80,  psv =>  80 },
+       primary => { foot =>   4,  horse =>   8,  wheelchair =>   4,  bicycle =>  20,  moped =>  48,  motorcycle =>  96,  motorcar =>  96,  goods =>  96,  hgv =>  80,  psv =>  80 },
+     secondary => { foot =>   4,  horse =>   8,  wheelchair =>   4,  bicycle =>  20,  moped =>  48,  motorcycle =>  88,  motorcar =>  88,  goods =>  88,  hgv =>  80,  psv =>  80 },
+      tertiary => { foot =>   4,  horse =>   8,  wheelchair =>   4,  bicycle =>  20,  moped =>  48,  motorcycle =>  80,  motorcar =>  80,  goods =>  80,  hgv =>  80,  psv =>  80 },
+  unclassified => { foot =>   4,  horse =>   8,  wheelchair =>   4,  bicycle =>  20,  moped =>  48,  motorcycle =>  64,  motorcar =>  64,  goods =>  64,  hgv =>  64,  psv =>  64 },
+   residential => { foot =>   4,  horse =>   8,  wheelchair =>   4,  bicycle =>  20,  moped =>  48,  motorcycle =>  48,  motorcar =>  48,  goods =>  48,  hgv =>  48,  psv =>  48 },
+       service => { foot =>   4,  horse =>   8,  wheelchair =>   4,  bicycle =>  20,  moped =>  32,  motorcycle =>  32,  motorcar =>  32,  goods =>  32,  hgv =>  32,  psv =>  32 },
+         track => { foot =>   4,  horse =>   8,  wheelchair =>   4,  bicycle =>  20,  moped =>  16,  motorcycle =>  16,  motorcar =>  16,  goods =>  16,  hgv =>  16,  psv =>  16 },
+      cycleway => { foot =>   4,  horse =>   8,  wheelchair =>   4,  bicycle =>  20,  moped =>   0,  motorcycle =>   0,  motorcar =>   0,  goods =>   0,  hgv =>   0,  psv =>   0 },
+          path => { foot =>   4,  horse =>   8,  wheelchair =>   4,  bicycle =>  20,  moped =>   0,  motorcycle =>   0,  motorcar =>   0,  goods =>   0,  hgv =>   0,  psv =>   0 },
+         steps => { foot =>   4,  horse =>   0,  wheelchair =>   4,  bicycle =>   0,  moped =>   0,  motorcycle =>   0,  motorcar =>   0,  goods =>   0,  hgv =>   0,  psv =>   0 },
+         ferry => { foot =>  10,  horse =>  10,  wheelchair =>  10,  bicycle =>  10,  moped =>  10,  motorcycle =>  10,  motorcar =>  10,  goods =>  10,  hgv =>  10,  psv =>  10 }
+     },
+
+  # Highway properties
+  profile_property => {
+          paved => { foot =>  50,  horse =>  20,  wheelchair =>  90,  bicycle =>  50,  moped => 100,  motorcycle => 100,  motorcar => 100,  goods => 100,  hgv => 100,  psv => 100 },
+      multilane => { foot =>  25,  horse =>  25,  wheelchair =>  25,  bicycle =>  25,  moped =>  35,  motorcycle =>  60,  motorcar =>  60,  goods =>  60,  hgv =>  60,  psv =>  60 },
+         bridge => { foot =>  50,  horse =>  50,  wheelchair =>  50,  bicycle =>  50,  moped =>  50,  motorcycle =>  50,  motorcar =>  50,  goods =>  50,  hgv =>  50,  psv =>  50 },
+         tunnel => { foot =>  50,  horse =>  50,  wheelchair =>  50,  bicycle =>  50,  moped =>  50,  motorcycle =>  50,  motorcar =>  50,  goods =>  50,  hgv =>  50,  psv =>  50 },
+      footroute => { foot =>  55,  horse =>  50,  wheelchair =>  55,  bicycle =>  50,  moped =>  50,  motorcycle =>  50,  motorcar =>  45,  goods =>  45,  hgv =>  45,  psv =>  45 },
+   bicycleroute => { foot =>  55,  horse =>  50,  wheelchair =>  55,  bicycle =>  60,  moped =>  50,  motorcycle =>  50,  motorcar =>  45,  goods =>  45,  hgv =>  45,  psv =>  45 }
+     },
+
+  # Restrictions
+  profile_restrictions => {
+          oneway => { foot =>    0,  horse =>    1,  wheelchair =>    0,  bicycle =>    1,  moped =>    1,  motorcycle =>    1,  motorcar =>    1,  goods =>    1,  hgv =>    1,  psv =>    1 },
+           turns => { foot =>    0,  horse =>    1,  wheelchair =>    0,  bicycle =>    1,  moped =>    1,  motorcycle =>    1,  motorcar =>    1,  goods =>    1,  hgv =>    1,  psv =>    1 },
+          weight => { foot =>  0.0,  horse =>  0.0,  wheelchair =>  0.0,  bicycle =>  0.0,  moped =>  0.0,  motorcycle =>  0.0,  motorcar =>  0.0,  goods =>  5.0,  hgv => 10.0,  psv => 15.0 },
+          height => { foot =>  0.0,  horse =>  0.0,  wheelchair =>  0.0,  bicycle =>  0.0,  moped =>  0.0,  motorcycle =>  0.0,  motorcar =>  0.0,  goods =>  2.5,  hgv =>  3.0,  psv =>  3.0 },
+           width => { foot =>  0.0,  horse =>  0.0,  wheelchair =>  0.0,  bicycle =>  0.0,  moped =>  0.0,  motorcycle =>  0.0,  motorcar =>  0.0,  goods =>  2.0,  hgv =>  2.5,  psv =>  2.5 },
+          length => { foot =>  0.0,  horse =>  0.0,  wheelchair =>  0.0,  bicycle =>  0.0,  moped =>  0.0,  motorcycle =>  0.0,  motorcar =>  0.0,  goods =>  5.0,  hgv =>  6.0,  psv =>  6.0 }
+     }
+
+}; # end of routino variable
+
+1;
diff --git a/web/www/routino/router.css b/web/www/routino/router.css
index 4f8b9f4..cba1b6a 100644
--- a/web/www/routino/router.css
+++ b/web/www/routino/router.css
@@ -3,7 +3,7 @@
 //
 // Part of the Routino routing software.
 //
-// This file Copyright 2008-2014 Andrew M. Bishop
+// This file Copyright 2008-2015 Andrew M. Bishop
 //
 // This program is free software: you can redistribute it and/or modify
 // it under the terms of the GNU Affero General Public License as published by
@@ -46,17 +46,41 @@ DIV.scrollable
 /* Left panel - specific tab options */
 /*-----------------------------------*/
 
-DIV#tab_options_div IMG
+DIV#tab_options_div DIV.waypoint
+{
+ clear: both;
+}
+
+DIV#tab_options_div DIV.waypoint SPAN
+{
+ vertical-align: 50%;
+}
+
+DIV#tab_options_div DIV.waypoint DIV.waypoint-buttons
+{
+ float: right;
+}
+
+DIV#tab_options_div DIV.waypoint IMG
 {
  cursor: pointer;
- vertical-align: bottom;
 }
 
-DIV#tab_options_div IMG:hover
+DIV#tab_options_div DIV.waypoint IMG.waypoint-icon
+{
+ cursor: move;
+}
+
+DIV#tab_options_div DIV.waypoint IMG:hover
 {
  background: #F0F000;
 }
 
+DIV#tab_options_div DIV#waypoints-buttons
+{
+ clear: both;
+}
+
 DIV#tab_options_div TABLE
 {
  padding: 0;
@@ -64,11 +88,6 @@ DIV#tab_options_div TABLE
  margin:  0;
 }
 
-DIV#tab_options_div DIV.center
-{
- text-align: center;
-}
-
 DIV#tab_options_div TABLE TD
 {
  padding: 0;
@@ -76,16 +95,11 @@ DIV#tab_options_div TABLE TD
  margin:  0;
 }
 
-DIV#tab_options_div TABLE TD.center
+DIV#tab_options_div DIV.center
 {
  text-align: center;
 }
 
-DIV#tab_options_div TABLE#waypoints
-{
- width: 100%;
-}
-
 DIV#tab_options_div A:hover
 {
  background: #F0F000;
diff --git a/web/www/routino/router.html.de b/web/www/routino/router.html.de
index c23086d..560b026 100644
--- a/web/www/routino/router.html.de
+++ b/web/www/routino/router.html.de
@@ -13,7 +13,7 @@ Routino router web page.
 
 Part of the Routino routing software.
 
-This file Copyright 2008-2014 Andrew M. Bishop
+This file Copyright 2008-2015 Andrew M. Bishop
 
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU Affero General Public License as published by
@@ -93,10 +93,18 @@ Wähle Start- und Endpunkt (klicke auf die Marker-Symbole unten), wähle die Rou
 <td>(FR)
 <td><input name="language" type="radio" value="fr" onchange="formSetLanguage();" >
 <tr>
+<td><a id="lang_hu_url" href="router.html.hu" title="Magyar weblap">Magyar</a>
+<td>(HU)
+<td><input name="language" type="radio" value="hu" onchange="formSetLanguage();" >
+<tr>
 <td><a id="lang_nl_url" href="router.html.nl" title="Nederlandse web pagina">Nederlands</a>
 <td>(NL)
 <td><input name="language" type="radio" value="nl" onchange="formSetLanguage();" >
 <tr>
+<td><a id="lang_pl_url" href="router.html.pl" title="Polski webpage">Polski</a>
+<td>(PL)
+<td><input name="language" type="radio" value="pl" onchange="formSetLanguage();" >
+<tr>
 <td><a id="lang_ru_url" href="router.html.ru" title="Русский">Русский</a>
 <td>(RU)
 <td><input name="language" type="radio" value="ru" onchange="formSetLanguage();" >
@@ -110,24 +118,17 @@ Wähle Start- und Endpunkt (klicke auf die Marker-Symbole unten), wähle die Rou
 <span id="hideshow_waypoint_hide" onclick="hideshow_hide('waypoint');" class="hideshow_show">-</span>
 <span class="hideshow_title">Wegpunkte</span>
 <div id="hideshow_waypoint_div">
-<table id="waypoints">
-<colgroup>
-<col style="width: 22px;">
-<col>
-<col style="width: 76px;">
-</colgroup>
-<tr id="waypointXXX" style="display: none;">
-<td>
-<img id="iconXXX" src="icons/marker-XXX-grey.png" title="Waypoint XXX Position - (click to add/remove on map)" alt="Waypoint XXX" onmousedown="markerToggleMap(XXX);">
-<td>
+<div id="waypoints">
+<div id="waypointXXX" class="waypoint" style="display: none;">
+<img id="iconXXX" class="waypoint-icon" src="icons/marker-XXX-grey.png" title="Wegpunkt XXX Position" alt="Waypoint XXX" onmouseup="markerToggleMap(XXX);" draggable="true">
 <span id="coordsXXX">
-<input name="lonXXX" type="text" size="7" title="Waypoint XXX Longitude" onchange="formSetCoords(XXX);">E
-<input name="latXXX" type="text" size="7" title="Waypoint XXX Latitude" onchange="formSetCoords(XXX);">N
+<input name="lonXXX" type="text" size="7" title="Wegpunkt XXX geografische Länge" onchange="formSetCoords(XXX);">E
+<input name="latXXX" type="text" size="7" title="Wegpunkt XXX geografische Breite" onchange="formSetCoords(XXX);">N
 </span>
 <span id="searchXXX" style="display: none;">
-<input name="searchXXX" type="text" size="18" title="Waypoint XXX Location"> <!-- uses Javascript event for triggering -->
+<input name="searchXXX" type="text" size="18" title="Wegpunkt XXX Ort"> <!-- uses Javascript event for triggering -->
 </span>
-<td>
+<div class="waypoint-buttons" style="display: inline-block;">
 <img alt="?" src="icons/waypoint-search.png" title="Nach Ort suchen" onmousedown="markerSearch(XXX);" >
 <img alt="G" src="icons/waypoint-locate.png" title="Aktuellen Ort bestimmen" onmousedown="markerLocate(XXX);" >
 <img alt="O" src="icons/waypoint-recentre.png" title="Karte auf Wegpunkt zentrieren" onmousedown="markerRecentre(XXX);">
@@ -135,18 +136,19 @@ Wähle Start- und Endpunkt (klicke auf die Marker-Symbole unten), wähle die Rou
 <img alt="+" src="icons/waypoint-add.png" title="Neuer Wegpunkt nach diesem" onmousedown="markerAddAfter(XXX);">
 <br>
 <img alt="#" src="icons/waypoint-coords.png" title="Koordinaten des Orts" onmousedown="markerCoords(XXX);" >
-<img alt="~" src="icons/waypoint-home.png" title="Toggle as home location" onmousedown="markerHome(XXX);" >
+<img alt="~" src="icons/waypoint-home.png" title="Umschalten auf den Standort des Zuhauses" onmousedown="markerHome(XXX);" >
 <img alt="o" src="icons/waypoint-centre.png" title="Wegpunkt auf Karte zentrieren" onmousedown="markerCentre(XXX);" >
 <img alt="v" src="icons/waypoint-down.png" title="Wegpunkt nach unten verschieben" onmousedown="markerMoveDown(XXX);">
 <img alt="-" src="icons/waypoint-remove.png" title="Wegpunkt entfernen" onmousedown="markerRemove(XXX);" >
-<tr id="searchresultsXXX" style="display: none;">
-<td colspan="3">
-<!-- The waypoints are inserted by the JavaScript, see the "maxmarkers" variable in router.js. -->
-<tr>
-<td colspan="3" class="center">
+</div>
+<div id="searchresultsXXX" style="display: none;">
+</div>
+</div>
+</div>
+<div id="waypoints-buttons" class="center">
 <input type="button" title="Rückwärts" value="Rückwärts" onmousedown="markersReverse();">
-<input type="button" title="Add a new waypoint to make a loop" value="Close loop" onmousedown="markersLoop();">
-</table>
+<input type="button" title="Einen Wegpunkt hinzufügen um eine Schlaufe zu machen" value="Schleife schließen" onmousedown="markersLoop();">
+</div>
 </div>
 </div>
 
@@ -164,8 +166,8 @@ Wähle Start- und Endpunkt (klicke auf die Marker-Symbole unten), wähle die Rou
 <tr><td>Motorrad:<td><input name="transport" type="radio" value="motorcycle" onchange="formSetTransport('motorcycle');">
 <tr><td>Auto: <td><input name="transport" type="radio" value="motorcar" onchange="formSetTransport('motorcar' );">
 <tr><td>LKW: <td><input name="transport" type="radio" value="goods" onchange="formSetTransport('goods' );">
-<tr><td>Schwertransport: <td><input name="transport" type="radio" value="hgv" onchange="formSetTransport('hgv' );">
-<tr><td>Personenverkehr: <td><input name="transport" type="radio" value="psv" onchange="formSetTransport('psv' );">
+<tr><td>Schwertransport/LKW: <td><input name="transport" type="radio" value="hgv" onchange="formSetTransport('hgv' );">
+<tr><td>Öffentlicher Personenverkehr: <td><input name="transport" type="radio" value="psv" onchange="formSetTransport('psv' );">
 </table>
 </div>
 </div>
@@ -187,7 +189,7 @@ Wähle Start- und Endpunkt (klicke auf die Marker-Symbole unten), wähle die Rou
 <tr><td>Feld-(Wald-)weg: <td><input name="highway-track" type="text" size="3" onchange="formSetHighway('track' ,'=');"><td>%<td><img alt="<" src="icons/waypoint-left.png" title="-" onmousedown="formSetHighway('track' ,'-');">–/+<img alt=">" src="icons/waypoint-right.png" title="+" onmousedown="formSetHighway('track' ,'+');">
 <tr><td>Fahrradweg: <td><input name="highway-cycleway" type="text" size="3" onchange="formSetHighway('cycleway' ,'=');"><td>%<td><img alt="<" src="icons/waypoint-left.png" title="-" onmousedown="formSetHighway('cycleway' ,'-');">–/+<img alt=">" src="icons/waypoint-right.png" title="+" onmousedown="formSetHighway('cycleway' ,'+');">
 <tr><td>Weg: <td><input name="highway-path" type="text" size="3" onchange="formSetHighway('path' ,'=');"><td>%<td><img alt="<" src="icons/waypoint-left.png" title="-" onmousedown="formSetHighway('path' ,'-');">–/+<img alt=">" src="icons/waypoint-right.png" title="+" onmousedown="formSetHighway('path' ,'+');">
-<tr><td>Fußweg: <td><input name="highway-steps" type="text" size="3" onchange="formSetHighway('steps' ,'=');"><td>%<td><img alt="<" src="icons/waypoint-left.png" title="-" onmousedown="formSetHighway('steps' ,'-');">–/+<img alt=">" src="icons/waypoint-right.png" title="+" onmousedown="formSetHighway('steps' ,'+');">
+<tr><td>Treppe: <td><input name="highway-steps" type="text" size="3" onchange="formSetHighway('steps' ,'=');"><td>%<td><img alt="<" src="icons/waypoint-left.png" title="-" onmousedown="formSetHighway('steps' ,'-');">–/+<img alt=">" src="icons/waypoint-right.png" title="+" onmousedown="formSetHighway('steps' ,'+');">
 <tr><td>Fähre: <td><input name="highway-ferry" type="text" size="3" onchange="formSetHighway('ferry' ,'=');"><td>%<td><img alt="<" src="icons/waypoint-left.png" title="-" onmousedown="formSetHighway('ferry' ,'-');">–/+<img alt=">" src="icons/waypoint-right.png" title="+" onmousedown="formSetHighway('ferry' ,'+');">
 </table>
 </div>
@@ -210,7 +212,7 @@ Wähle Start- und Endpunkt (klicke auf die Marker-Symbole unten), wähle die Rou
 <tr><td>Feld-(Wald-)weg: <td><input name="speed-track" type="text" size="3" onchange="formSetSpeed('track' ,'=');"><td>km/hr<td><img alt="<" src="icons/waypoint-left.png" title="-" onmousedown="formSetSpeed('track' ,'-');">–/+<img alt=">" src="icons/waypoint-right.png" title="+" onmousedown="formSetSpeed('track' ,'+');">
 <tr><td>Fahrradweg: <td><input name="speed-cycleway" type="text" size="3" onchange="formSetSpeed('cycleway' ,'=');"><td>km/hr<td><img alt="<" src="icons/waypoint-left.png" title="-" onmousedown="formSetSpeed('cycleway' ,'-');">–/+<img alt=">" src="icons/waypoint-right.png" title="+" onmousedown="formSetSpeed('cycleway' ,'+');">
 <tr><td>Weg: <td><input name="speed-path" type="text" size="3" onchange="formSetSpeed('path' ,'=');"><td>km/hr<td><img alt="<" src="icons/waypoint-left.png" title="-" onmousedown="formSetSpeed('path' ,'-');">–/+<img alt=">" src="icons/waypoint-right.png" title="+" onmousedown="formSetSpeed('path' ,'+');">
-<tr><td>Fußweg: <td><input name="speed-steps" type="text" size="3" onchange="formSetSpeed('steps' ,'=');"><td>km/hr<td><img alt="<" src="icons/waypoint-left.png" title="-" onmousedown="formSetSpeed('steps' ,'-');">–/+<img alt=">" src="icons/waypoint-right.png" title="+" onmousedown="formSetSpeed('steps' ,'+');">
+<tr><td>Treppe: <td><input name="speed-steps" type="text" size="3" onchange="formSetSpeed('steps' ,'=');"><td>km/hr<td><img alt="<" src="icons/waypoint-left.png" title="-" onmousedown="formSetSpeed('steps' ,'-');">–/+<img alt=">" src="icons/waypoint-right.png" title="+" onmousedown="formSetSpeed('steps' ,'+');">
 <tr><td>Fähre: <td><input name="speed-ferry" type="text" size="3" onchange="formSetSpeed('ferry' ,'=');"><td>km/hr<td><img alt="<" src="icons/waypoint-left.png" title="-" onmousedown="formSetSpeed('ferry' ,'-');">–/+<img alt=">" src="icons/waypoint-right.png" title="+" onmousedown="formSetSpeed('ferry' ,'+');">
 </table>
 </div>
@@ -238,8 +240,8 @@ Wähle Start- und Endpunkt (klicke auf die Marker-Symbole unten), wähle die Rou
 <span class="hideshow_title">andere Vorgaben</span>
 <div id="hideshow_restriction_div" style="display: none;">
 <table>
-<tr><td>beachte Einbahnstraßen: <td><input name="restrict-oneway" type="checkbox" onchange="formSetRestriction('oneway');">
-<tr><td>beachte Abbiegeverbot:<td><input name="restrict-turns" type="checkbox" onchange="formSetRestriction('turns' );">
+<tr><td>beachte Einbahnstraßen:<td><input name="restrict-oneway" type="checkbox" onchange="formSetRestriction('oneway');">
+<tr><td>beachte Abbiegeverbot: <td><input name="restrict-turns" type="checkbox" onchange="formSetRestriction('turns' );">
 </table>
 <table>
 <tr><td>Gewicht:<td><input name="restrict-weight" type="text" size="3" onchange="formSetRestriction('weight','=');"><td>tonnes<td><img alt="<" src="icons/waypoint-left.png" title="-" onmousedown="formSetRestriction('weight','-');">–/+<img alt=">" src="icons/waypoint-right.png" title="+" onmousedown="formSetRestriction('weight','+');">
diff --git a/web/www/routino/router.html.en b/web/www/routino/router.html.en
index df52d8b..2700388 100644
--- a/web/www/routino/router.html.en
+++ b/web/www/routino/router.html.en
@@ -13,7 +13,7 @@ Routino router web page.
 
 Part of the Routino routing software.
 
-This file Copyright 2008-2014 Andrew M. Bishop
+This file Copyright 2008-2015 Andrew M. Bishop
 
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU Affero General Public License as published by
@@ -93,10 +93,18 @@ Select start and end points (click on the marker icons below), select routing pr
 <td>(FR)
 <td><input name="language" type="radio" value="fr" onchange="formSetLanguage();" >
 <tr>
+<td><a id="lang_hu_url" href="router.html.hu" title="Magyar weblap">Magyar</a>
+<td>(HU)
+<td><input name="language" type="radio" value="hu" onchange="formSetLanguage();" >
+<tr>
 <td><a id="lang_nl_url" href="router.html.nl" title="Nederlandse web pagina">Nederlands</a>
 <td>(NL)
 <td><input name="language" type="radio" value="nl" onchange="formSetLanguage();" >
 <tr>
+<td><a id="lang_pl_url" href="router.html.pl" title="Polski webpage">Polski</a>
+<td>(PL)
+<td><input name="language" type="radio" value="pl" onchange="formSetLanguage();" >
+<tr>
 <td><a id="lang_ru_url" href="router.html.ru" title="Русский">Русский</a>
 <td>(RU)
 <td><input name="language" type="radio" value="ru" onchange="formSetLanguage();" >
@@ -110,16 +118,9 @@ Select start and end points (click on the marker icons below), select routing pr
 <span id="hideshow_waypoint_hide" onclick="hideshow_hide('waypoint');" class="hideshow_show">-</span>
 <span class="hideshow_title">Waypoints</span>
 <div id="hideshow_waypoint_div">
-<table id="waypoints">
-<colgroup>
-<col style="width: 22px;">
-<col>
-<col style="width: 76px;">
-</colgroup>
-<tr id="waypointXXX" style="display: none;">
-<td>
-<img id="iconXXX" src="icons/marker-XXX-grey.png" title="Waypoint XXX Position - (click to add/remove on map)" alt="Waypoint XXX" onmousedown="markerToggleMap(XXX);">
-<td>
+<div id="waypoints">
+<div id="waypointXXX" class="waypoint" style="display: none;">
+<img id="iconXXX" class="waypoint-icon" src="icons/marker-XXX-grey.png" title="Waypoint XXX Position" alt="Waypoint XXX" onmouseup="markerToggleMap(XXX);" draggable="true">
 <span id="coordsXXX">
 <input name="lonXXX" type="text" size="7" title="Waypoint XXX Longitude" onchange="formSetCoords(XXX);">E
 <input name="latXXX" type="text" size="7" title="Waypoint XXX Latitude" onchange="formSetCoords(XXX);">N
@@ -127,7 +128,7 @@ Select start and end points (click on the marker icons below), select routing pr
 <span id="searchXXX" style="display: none;">
 <input name="searchXXX" type="text" size="18" title="Waypoint XXX Location"> <!-- uses Javascript event for triggering -->
 </span>
-<td>
+<div class="waypoint-buttons" style="display: inline-block;">
 <img alt="?" src="icons/waypoint-search.png" title="Search for location" onmousedown="markerSearch(XXX);" >
 <img alt="G" src="icons/waypoint-locate.png" title="Get current location" onmousedown="markerLocate(XXX);" >
 <img alt="O" src="icons/waypoint-recentre.png" title="Centre map on this waypoint" onmousedown="markerRecentre(XXX);">
@@ -139,14 +140,15 @@ Select start and end points (click on the marker icons below), select routing pr
 <img alt="o" src="icons/waypoint-centre.png" title="Centre this waypoint on map" onmousedown="markerCentre(XXX);" >
 <img alt="v" src="icons/waypoint-down.png" title="Move this waypoint down" onmousedown="markerMoveDown(XXX);">
 <img alt="-" src="icons/waypoint-remove.png" title="Remove this waypoint" onmousedown="markerRemove(XXX);" >
-<tr id="searchresultsXXX" style="display: none;">
-<td colspan="3">
-<!-- The waypoints are inserted by the JavaScript, see the "maxmarkers" variable in router.js. -->
-<tr>
-<td colspan="3" class="center">
+</div>
+<div id="searchresultsXXX" style="display: none;">
+</div>
+</div>
+</div>
+<div id="waypoints-buttons" class="center">
 <input type="button" title="Reverse order of waypoints" value="Reverse order" onmousedown="markersReverse();">
 <input type="button" title="Add a new waypoint to make a loop" value="Close loop" onmousedown="markersLoop();">
-</table>
+</div>
 </div>
 </div>
 
@@ -238,8 +240,8 @@ Select start and end points (click on the marker icons below), select routing pr
 <span class="hideshow_title">Other Restrictions</span>
 <div id="hideshow_restriction_div" style="display: none;">
 <table>
-<tr><td>Obey oneway streets: <td><input name="restrict-oneway" type="checkbox" onchange="formSetRestriction('oneway');">
-<tr><td>Obey turn restrictions:<td><input name="restrict-turns" type="checkbox" onchange="formSetRestriction('turns' );">
+<tr><td>Obey oneway streets:<td><input name="restrict-oneway" type="checkbox" onchange="formSetRestriction('oneway');">
+<tr><td>Obey turn restrictions: <td><input name="restrict-turns" type="checkbox" onchange="formSetRestriction('turns' );">
 </table>
 <table>
 <tr><td>Weight:<td><input name="restrict-weight" type="text" size="3" onchange="formSetRestriction('weight','=');"><td>tonnes<td><img alt="<" src="icons/waypoint-left.png" title="-" onmousedown="formSetRestriction('weight','-');">–/+<img alt=">" src="icons/waypoint-right.png" title="+" onmousedown="formSetRestriction('weight','+');">
diff --git a/web/www/routino/router.html.fr b/web/www/routino/router.html.fr
index c352229..75f9d39 100644
--- a/web/www/routino/router.html.fr
+++ b/web/www/routino/router.html.fr
@@ -13,7 +13,7 @@ Routino router web page.
 
 Part of the Routino routing software.
 
-This file Copyright 2008-2014 Andrew M. Bishop
+This file Copyright 2008-2015 Andrew M. Bishop
 
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU Affero General Public License as published by
@@ -93,10 +93,18 @@ Sélectionner les points de départ et d'arrivée (cliquer sur les icones ci-des
 <td>(FR)
 <td><input name="language" type="radio" value="fr" onchange="formSetLanguage();" checked>
 <tr>
+<td><a id="lang_hu_url" href="router.html.hu" title="Magyar weblap">Magyar</a>
+<td>(HU)
+<td><input name="language" type="radio" value="hu" onchange="formSetLanguage();" >
+<tr>
 <td><a id="lang_nl_url" href="router.html.nl" title="Nederlandse web pagina">Nederlands</a>
 <td>(NL)
 <td><input name="language" type="radio" value="nl" onchange="formSetLanguage();" >
 <tr>
+<td><a id="lang_pl_url" href="router.html.pl" title="Polski webpage">Polski</a>
+<td>(PL)
+<td><input name="language" type="radio" value="pl" onchange="formSetLanguage();" >
+<tr>
 <td><a id="lang_ru_url" href="router.html.ru" title="Русский">Русский</a>
 <td>(RU)
 <td><input name="language" type="radio" value="ru" onchange="formSetLanguage();" >
@@ -110,16 +118,9 @@ Sélectionner les points de départ et d'arrivée (cliquer sur les icones ci-des
 <span id="hideshow_waypoint_hide" onclick="hideshow_hide('waypoint');" class="hideshow_show">-</span>
 <span class="hideshow_title">Etapes de l'itinéraire</span>
 <div id="hideshow_waypoint_div">
-<table id="waypoints">
-<colgroup>
-<col style="width: 22px;">
-<col>
-<col style="width: 76px;">
-</colgroup>
-<tr id="waypointXXX" style="display: none;">
-<td>
-<img id="iconXXX" src="icons/marker-XXX-grey.png" title="Etape XXX de l'itinéraire - (cliquer pour ajouter/enlever de la carte)" alt="Waypoint XXX" onmousedown="markerToggleMap(XXX);">
-<td>
+<div id="waypoints">
+<div id="waypointXXX" class="waypoint" style="display: none;">
+<img id="iconXXX" class="waypoint-icon" src="icons/marker-XXX-grey.png" title="Etape XXX de l'itinéraire" alt="Waypoint XXX" onmouseup="markerToggleMap(XXX);" draggable="true">
 <span id="coordsXXX">
 <input name="lonXXX" type="text" size="7" title="Etape XXX Longitude" onchange="formSetCoords(XXX);">E
 <input name="latXXX" type="text" size="7" title="Etape XXX Latitude" onchange="formSetCoords(XXX);">N
@@ -127,7 +128,7 @@ Sélectionner les points de départ et d'arrivée (cliquer sur les icones ci-des
 <span id="searchXXX" style="display: none;">
 <input name="searchXXX" type="text" size="18" title="position de l'étape XXX"> <!-- uses Javascript event for triggering -->
 </span>
-<td>
+<div class="waypoint-buttons" style="display: inline-block;">
 <img alt="?" src="icons/waypoint-search.png" title="Rechercher la position" onmousedown="markerSearch(XXX);" >
 <img alt="G" src="icons/waypoint-locate.png" title="obtenir la position actuelle" onmousedown="markerLocate(XXX);" >
 <img alt="O" src="icons/waypoint-recentre.png" title="Centrer la carte sur cette étape" onmousedown="markerRecentre(XXX);">
@@ -139,14 +140,15 @@ Sélectionner les points de départ et d'arrivée (cliquer sur les icones ci-des
 <img alt="o" src="icons/waypoint-centre.png" title="Centrer cette étape sur la carte" onmousedown="markerCentre(XXX);" >
 <img alt="v" src="icons/waypoint-down.png" title="Placer cette étape après" onmousedown="markerMoveDown(XXX);">
 <img alt="-" src="icons/waypoint-remove.png" title="supprimer cette étape" onmousedown="markerRemove(XXX);" >
-<tr id="searchresultsXXX" style="display: none;">
-<td colspan="3">
-<!-- The waypoints are inserted by the JavaScript, see the "maxmarkers" variable in router.js. -->
-<tr>
-<td colspan="3" class="center">
+</div>
+<div id="searchresultsXXX" style="display: none;">
+</div>
+</div>
+</div>
+<div id="waypoints-buttons" class="center">
 <input type="button" title="Inverser l'ordre des étapes" value="Inverser l'ordre" onmousedown="markersReverse();">
 <input type="button" title="Ajouter une nouvelle étape pour faire une boucle" value="Faire une boucle" onmousedown="markersLoop();">
-</table>
+</div>
 </div>
 </div>
 
@@ -238,8 +240,8 @@ Sélectionner les points de départ et d'arrivée (cliquer sur les icones ci-des
 <span class="hideshow_title">Autres Restrictions</span>
 <div id="hideshow_restriction_div" style="display: none;">
 <table>
-<tr><td>Respecter les sens uniques: <td><input name="restrict-oneway" type="checkbox" onchange="formSetRestriction('oneway');">
-<tr><td>Respecter les obligations de tourner:<td><input name="restrict-turns" type="checkbox" onchange="formSetRestriction('turns' );">
+<tr><td>Respecter les sens uniques:<td><input name="restrict-oneway" type="checkbox" onchange="formSetRestriction('oneway');">
+<tr><td>Respecter les obligations de tourner: <td><input name="restrict-turns" type="checkbox" onchange="formSetRestriction('turns' );">
 </table>
 <table>
 <tr><td>Poids:<td><input name="restrict-weight" type="text" size="3" onchange="formSetRestriction('weight','=');"><td>tonnes<td><img alt="<" src="icons/waypoint-left.png" title="-" onmousedown="formSetRestriction('weight','-');">–/+<img alt=">" src="icons/waypoint-right.png" title="+" onmousedown="formSetRestriction('weight','+');">
diff --git a/web/www/routino/router.html.hu b/web/www/routino/router.html.hu
new file mode 100644
index 0000000..2e11ae8
--- /dev/null
+++ b/web/www/routino/router.html.hu
@@ -0,0 +1,496 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<meta name="keywords" content="openstreetmap routing route planner">
+<meta name="viewport" content="width=device-width, height=device-height, initial-scale=1, user-scalable=no">
+
+<title>Routino : Openstreetmap alapú útvonaltervező</title>
+
+<!--
+Routino router web page.
+
+Part of the Routino routing software.
+
+This file Copyright 2008-2015 Andrew M. Bishop
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU Affero General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Affero General Public License for more details.
+
+You should have received a copy of the GNU Affero General Public License
+along with this program. If not, see http://www.gnu.org/licenses/.
+-->
+
+<!-- Page elements -->
+<script src="page-elements.js" type="text/javascript"></script>
+<link href="page-elements.css" type="text/css" rel="stylesheet">
+
+<!-- Router and visualiser shared features -->
+<link href="maplayout.css" type="text/css" rel="stylesheet">
+
+<!-- Router specific features -->
+<script src="profiles.js" type="text/javascript"></script>
+<link href="router.css" type="text/css" rel="stylesheet">
+
+<!-- Map parameters -->
+<script src="mapprops.js" type="text/javascript"></script>
+
+<!-- Map loader -->
+<script src="maploader.js" type="text/javascript"></script>
+
+</head>
+<body onload="map_load('html_init();map_init();form_init();');">
+
+<!-- Left hand side of window - data panel -->
+
+<div class="left_panel">
+
+<div class="tab_box">
+<span id="tab_options" onclick="tab_select('options');" class="tab_selected" title="Útvonaltervező beállítások">Beállítások</span>
+<span id="tab_results" onclick="tab_select('results');" class="tab_unselected" title="Útvonaltervező eredmények">Eredmény</span>
+<span id="tab_data" onclick="tab_select('data');" class="tab_unselected" title="Adatbázis információk">Adatok</span>
+</div>
+
+<div class="tab_content" id="tab_options_div">
+
+<form name="form" id="form" action="#" method="get" onsubmit="return false;">
+<div class="hideshow_box">
+<span class="hideshow_title">Routino openstreetmap útvonaltervező</span>
+This web page allows routing within the data collected by OpenStreetMap.
+Select start and end points (click on the marker icons below), select routing preferences then find a route.
+<div class="center">
+<a target="other" href="http://www.routino.org/">Routino weboldal</a>
+|
+<a target="other" href="documentation/">Dokumentáció</a>
+</div>
+</div>
+
+<div class="hideshow_box">
+<span id="hideshow_language_show" onclick="hideshow_show('language');" class="hideshow_show">+</span>
+<span id="hideshow_language_hide" onclick="hideshow_hide('language');" class="hideshow_hide">-</span>
+<span class="hideshow_title">Nyelv</span>
+
+<div id="hideshow_language_div" style="display: none;">
+<table>
+<tr>
+<td><a id="lang_en_url" href="router.html.en" title="English language webpage">English</a>
+<td>(EN)
+<td><input name="language" type="radio" value="en" onchange="formSetLanguage();" >
+<tr>
+<td><a id="lang_de_url" href="router.html.de" title="Deutsche Webseite">Deutsch</a>
+<td>(DE)
+<td><input name="language" type="radio" value="de" onchange="formSetLanguage();" >
+<tr>
+<td><a id="lang_fr_url" href="router.html.fr" title="Francais">Francais</a>
+<td>(FR)
+<td><input name="language" type="radio" value="fr" onchange="formSetLanguage();" >
+<tr>
+<td><a id="lang_hu_url" href="router.html.hu" title="Magyar weblap">Magyar</a>
+<td>(HU)
+<td><input name="language" type="radio" value="hu" onchange="formSetLanguage();" checked>
+<tr>
+<td><a id="lang_nl_url" href="router.html.nl" title="Nederlandse web pagina">Nederlands</a>
+<td>(NL)
+<td><input name="language" type="radio" value="nl" onchange="formSetLanguage();" >
+<tr>
+<td><a id="lang_pl_url" href="router.html.pl" title="Polski webpage">Polski</a>
+<td>(PL)
+<td><input name="language" type="radio" value="pl" onchange="formSetLanguage();" >
+<tr>
+<td><a id="lang_ru_url" href="router.html.ru" title="Русский">Русский</a>
+<td>(RU)
+<td><input name="language" type="radio" value="ru" onchange="formSetLanguage();" >
+</table>
+<a target="translation" href="http://www.routino.org/translations/">Routino Translations</a>
+</div>
+</div>
+
+<div class="hideshow_box">
+<span id="hideshow_waypoint_show" onclick="hideshow_show('waypoint');" class="hideshow_hide">+</span>
+<span id="hideshow_waypoint_hide" onclick="hideshow_hide('waypoint');" class="hideshow_show">-</span>
+<span class="hideshow_title">Útpontok</span>
+<div id="hideshow_waypoint_div">
+<div id="waypoints">
+<div id="waypointXXX" class="waypoint" style="display: none;">
+<img id="iconXXX" class="waypoint-icon" src="icons/marker-XXX-grey.png" title="Waypoint XXX Position" alt="Waypoint XXX" onmouseup="markerToggleMap(XXX);" draggable="true">
+<span id="coordsXXX">
+<input name="lonXXX" type="text" size="7" title="Waypoint XXX Longitude" onchange="formSetCoords(XXX);">E
+<input name="latXXX" type="text" size="7" title="Waypoint XXX Latitude" onchange="formSetCoords(XXX);">N
+</span>
+<span id="searchXXX" style="display: none;">
+<input name="searchXXX" type="text" size="18" title="Waypoint XXX Location"> <!-- uses Javascript event for triggering -->
+</span>
+<div class="waypoint-buttons" style="display: inline-block;">
+<img alt="?" src="icons/waypoint-search.png" title="Hely keresése" onmousedown="markerSearch(XXX);" >
+<img alt="G" src="icons/waypoint-locate.png" title="Aktuális helyzet" onmousedown="markerLocate(XXX);" >
+<img alt="O" src="icons/waypoint-recentre.png" title="Legyen ez a pont a térkép közepe" onmousedown="markerRecentre(XXX);">
+<img alt="^" src="icons/waypoint-up.png" title="Mozgasd feljebb ezt a pontot" onmousedown="markerMoveUp(XXX);" >
+<img alt="+" src="icons/waypoint-add.png" title="Új pont ezután a pont után" onmousedown="markerAddAfter(XXX);">
+<br>
+<img alt="#" src="icons/waypoint-coords.png" title="Hely koordinátája" onmousedown="markerCoords(XXX);" >
+<img alt="~" src="icons/waypoint-home.png" title="Toggle as home location" onmousedown="markerHome(XXX);" >
+<img alt="o" src="icons/waypoint-centre.png" title="Ez legyen a térkép középpontja" onmousedown="markerCentre(XXX);" >
+<img alt="v" src="icons/waypoint-down.png" title="Mozgasd ezt a pontot lejjebb" onmousedown="markerMoveDown(XXX);">
+<img alt="-" src="icons/waypoint-remove.png" title="Pont törlése" onmousedown="markerRemove(XXX);" >
+</div>
+<div id="searchresultsXXX" style="display: none;">
+</div>
+</div>
+</div>
+<div id="waypoints-buttons" class="center">
+<input type="button" title="Útirány megfordítása" value="Ellenkező irány" onmousedown="markersReverse();">
+<input type="button" title="Új pont létrehozása a kezdőpontban" value="Kör bezárása" onmousedown="markersLoop();">
+</div>
+</div>
+</div>
+
+<div class="hideshow_box">
+<span id="hideshow_transport_show" onclick="hideshow_show('transport');" class="hideshow_hide">+</span>
+<span id="hideshow_transport_hide" onclick="hideshow_hide('transport');" class="hideshow_show">-</span>
+<span class="hideshow_title">Közlekedési mód</span>
+<div id="hideshow_transport_div">
+<table>
+<tr><td>Gyalog: <td><input name="transport" type="radio" value="foot" onchange="formSetTransport('foot' );">
+<tr><td>Lovas: <td><input name="transport" type="radio" value="horse" onchange="formSetTransport('horse' );">
+<tr><td>Kerekesszékes:<td><input name="transport" type="radio" value="wheelchair" onchange="formSetTransport('wheelchair');">
+<tr><td>Kerékpáros: <td><input name="transport" type="radio" value="bicycle" onchange="formSetTransport('bicycle' );">
+<tr><td>Robogós: <td><input name="transport" type="radio" value="moped" onchange="formSetTransport('moped' );">
+<tr><td>Motoros:<td><input name="transport" type="radio" value="motorcycle" onchange="formSetTransport('motorcycle');">
+<tr><td>Autós: <td><input name="transport" type="radio" value="motorcar" onchange="formSetTransport('motorcar' );">
+<tr><td>Kisteherautós: <td><input name="transport" type="radio" value="goods" onchange="formSetTransport('goods' );">
+<tr><td>Kamionos: <td><input name="transport" type="radio" value="hgv" onchange="formSetTransport('hgv' );">
+<tr><td>Buszos: <td><input name="transport" type="radio" value="psv" onchange="formSetTransport('psv' );">
+</table>
+</div>
+</div>
+
+<div class="hideshow_box">
+<span id="hideshow_highway_show" onclick="hideshow_show('highway');" class="hideshow_show">+</span>
+<span id="hideshow_highway_hide" onclick="hideshow_hide('highway');" class="hideshow_hide">-</span>
+<span class="hideshow_title">Út preferencia</span>
+<div id="hideshow_highway_div" style="display: none;">
+<table>
+<tr><td>Autópálya: <td><input name="highway-motorway" type="text" size="3" onchange="formSetHighway('motorway' ,'=');"><td>%<td><img alt="<" src="icons/waypoint-left.png" title="-" onmousedown="formSetHighway('motorway' ,'-');">–/+<img alt=">" src="icons/waypoint-right.png" title="+" onmousedown="formSetHighway('motorway' ,'+');">
+<tr><td>Autóút: <td><input name="highway-trunk" type="text" size="3" onchange="formSetHighway('trunk' ,'=');"><td>%<td><img alt="<" src="icons/waypoint-left.png" title="-" onmousedown="formSetHighway('trunk' ,'-');">–/+<img alt=">" src="icons/waypoint-right.png" title="+" onmousedown="formSetHighway('trunk' ,'+');">
+<tr><td>Főút: <td><input name="highway-primary" type="text" size="3" onchange="formSetHighway('primary' ,'=');"><td>%<td><img alt="<" src="icons/waypoint-left.png" title="-" onmousedown="formSetHighway('primary' ,'-');">–/+<img alt=">" src="icons/waypoint-right.png" title="+" onmousedown="formSetHighway('primary' ,'+');">
+<tr><td>Összekötőút: <td><input name="highway-secondary" type="text" size="3" onchange="formSetHighway('secondary' ,'=');"><td>%<td><img alt="<" src="icons/waypoint-left.png" title="-" onmousedown="formSetHighway('secondary' ,'-');">–/+<img alt=">" src="icons/waypoint-right.png" title="+" onmousedown="formSetHighway('secondary' ,'+');">
+<tr><td>Bekötőút: <td><input name="highway-tertiary" type="text" size="3" onchange="formSetHighway('tertiary' ,'=');"><td>%<td><img alt="<" src="icons/waypoint-left.png" title="-" onmousedown="formSetHighway('tertiary' ,'-');">–/+<img alt=">" src="icons/waypoint-right.png" title="+" onmousedown="formSetHighway('tertiary' ,'+');">
+<tr><td>Egyéb közút:<td><input name="highway-unclassified" type="text" size="3" onchange="formSetHighway('unclassified','=');"><td>%<td><img alt="<" src="icons/waypoint-left.png" title="-" onmousedown="formSetHighway('unclassified','-');">–/+<img alt=">" src="icons/waypoint-right.png" title="+" onmousedown="formSetHighway('unclassified','+');">
+<tr><td>Lakóövezeti út: <td><input name="highway-residential" type="text" size="3" onchange="formSetHighway('residential' ,'=');"><td>%<td><img alt="<" src="icons/waypoint-left.png" title="-" onmousedown="formSetHighway('residential' ,'-');">–/+<img alt=">" src="icons/waypoint-right.png" title="+" onmousedown="formSetHighway('residential' ,'+');">
+<tr><td>Szervízút: <td><input name="highway-service" type="text" size="3" onchange="formSetHighway('service' ,'=');"><td>%<td><img alt="<" src="icons/waypoint-left.png" title="-" onmousedown="formSetHighway('service' ,'-');">–/+<img alt=">" src="icons/waypoint-right.png" title="+" onmousedown="formSetHighway('service' ,'+');">
+<tr><td>Földút: <td><input name="highway-track" type="text" size="3" onchange="formSetHighway('track' ,'=');"><td>%<td><img alt="<" src="icons/waypoint-left.png" title="-" onmousedown="formSetHighway('track' ,'-');">–/+<img alt=">" src="icons/waypoint-right.png" title="+" onmousedown="formSetHighway('track' ,'+');">
+<tr><td>Kerékpárút: <td><input name="highway-cycleway" type="text" size="3" onchange="formSetHighway('cycleway' ,'=');"><td>%<td><img alt="<" src="icons/waypoint-left.png" title="-" onmousedown="formSetHighway('cycleway' ,'-');">–/+<img alt=">" src="icons/waypoint-right.png" title="+" onmousedown="formSetHighway('cycleway' ,'+');">
+<tr><td>Ösvény: <td><input name="highway-path" type="text" size="3" onchange="formSetHighway('path' ,'=');"><td>%<td><img alt="<" src="icons/waypoint-left.png" title="-" onmousedown="formSetHighway('path' ,'-');">–/+<img alt=">" src="icons/waypoint-right.png" title="+" onmousedown="formSetHighway('path' ,'+');">
+<tr><td>Lépcső: <td><input name="highway-steps" type="text" size="3" onchange="formSetHighway('steps' ,'=');"><td>%<td><img alt="<" src="icons/waypoint-left.png" title="-" onmousedown="formSetHighway('steps' ,'-');">–/+<img alt=">" src="icons/waypoint-right.png" title="+" onmousedown="formSetHighway('steps' ,'+');">
+<tr><td>Komp: <td><input name="highway-ferry" type="text" size="3" onchange="formSetHighway('ferry' ,'=');"><td>%<td><img alt="<" src="icons/waypoint-left.png" title="-" onmousedown="formSetHighway('ferry' ,'-');">–/+<img alt=">" src="icons/waypoint-right.png" title="+" onmousedown="formSetHighway('ferry' ,'+');">
+</table>
+</div>
+</div>
+
+<div class="hideshow_box">
+<span id="hideshow_speed_show" onclick="hideshow_show('speed');" class="hideshow_show">+</span>
+<span id="hideshow_speed_hide" onclick="hideshow_hide('speed');" class="hideshow_hide">-</span>
+<span class="hideshow_title">Sebességkorlát</span>
+<div id="hideshow_speed_div" style="display: none;">
+<table>
+<tr><td>Autópálya: <td><input name="speed-motorway" type="text" size="3" onchange="formSetSpeed('motorway' ,'=');"><td>km/hr<td><img alt="<" src="icons/waypoint-left.png" title="-" onmousedown="formSetSpeed('motorway' ,'-');">–/+<img alt=">" src="icons/waypoint-right.png" title="+" onmousedown="formSetSpeed('motorway' ,'+');">
+<tr><td>Autóút: <td><input name="speed-trunk" type="text" size="3" onchange="formSetSpeed('trunk' ,'=');"><td>km/hr<td><img alt="<" src="icons/waypoint-left.png" title="-" onmousedown="formSetSpeed('trunk' ,'-');">–/+<img alt=">" src="icons/waypoint-right.png" title="+" onmousedown="formSetSpeed('trunk' ,'+');">
+<tr><td>Főút: <td><input name="speed-primary" type="text" size="3" onchange="formSetSpeed('primary' ,'=');"><td>km/hr<td><img alt="<" src="icons/waypoint-left.png" title="-" onmousedown="formSetSpeed('primary' ,'-');">–/+<img alt=">" src="icons/waypoint-right.png" title="+" onmousedown="formSetSpeed('primary' ,'+');">
+<tr><td>Összekötőút: <td><input name="speed-secondary" type="text" size="3" onchange="formSetSpeed('secondary' ,'=');"><td>km/hr<td><img alt="<" src="icons/waypoint-left.png" title="-" onmousedown="formSetSpeed('secondary' ,'-');">–/+<img alt=">" src="icons/waypoint-right.png" title="+" onmousedown="formSetSpeed('secondary' ,'+');">
+<tr><td>Bekötőút: <td><input name="speed-tertiary" type="text" size="3" onchange="formSetSpeed('tertiary' ,'=');"><td>km/hr<td><img alt="<" src="icons/waypoint-left.png" title="-" onmousedown="formSetSpeed('tertiary' ,'-');">–/+<img alt=">" src="icons/waypoint-right.png" title="+" onmousedown="formSetSpeed('tertiary' ,'+');">
+<tr><td>Egyéb közút:<td><input name="speed-unclassified" type="text" size="3" onchange="formSetSpeed('unclassified','=');"><td>km/hr<td><img alt="<" src="icons/waypoint-left.png" title="-" onmousedown="formSetSpeed('unclassified','-');">–/+<img alt=">" src="icons/waypoint-right.png" title="+" onmousedown="formSetSpeed('unclassified','+');">
+<tr><td>Lakóövezeti út: <td><input name="speed-residential" type="text" size="3" onchange="formSetSpeed('residential' ,'=');"><td>km/hr<td><img alt="<" src="icons/waypoint-left.png" title="-" onmousedown="formSetSpeed('residential' ,'-');">–/+<img alt=">" src="icons/waypoint-right.png" title="+" onmousedown="formSetSpeed('residential' ,'+');">
+<tr><td>Szervízút: <td><input name="speed-service" type="text" size="3" onchange="formSetSpeed('service' ,'=');"><td>km/hr<td><img alt="<" src="icons/waypoint-left.png" title="-" onmousedown="formSetSpeed('service' ,'-');">–/+<img alt=">" src="icons/waypoint-right.png" title="+" onmousedown="formSetSpeed('service' ,'+');">
+<tr><td>Földút: <td><input name="speed-track" type="text" size="3" onchange="formSetSpeed('track' ,'=');"><td>km/hr<td><img alt="<" src="icons/waypoint-left.png" title="-" onmousedown="formSetSpeed('track' ,'-');">–/+<img alt=">" src="icons/waypoint-right.png" title="+" onmousedown="formSetSpeed('track' ,'+');">
+<tr><td>Kerékpárút: <td><input name="speed-cycleway" type="text" size="3" onchange="formSetSpeed('cycleway' ,'=');"><td>km/hr<td><img alt="<" src="icons/waypoint-left.png" title="-" onmousedown="formSetSpeed('cycleway' ,'-');">–/+<img alt=">" src="icons/waypoint-right.png" title="+" onmousedown="formSetSpeed('cycleway' ,'+');">
+<tr><td>Ösvény: <td><input name="speed-path" type="text" size="3" onchange="formSetSpeed('path' ,'=');"><td>km/hr<td><img alt="<" src="icons/waypoint-left.png" title="-" onmousedown="formSetSpeed('path' ,'-');">–/+<img alt=">" src="icons/waypoint-right.png" title="+" onmousedown="formSetSpeed('path' ,'+');">
+<tr><td>Lépcső: <td><input name="speed-steps" type="text" size="3" onchange="formSetSpeed('steps' ,'=');"><td>km/hr<td><img alt="<" src="icons/waypoint-left.png" title="-" onmousedown="formSetSpeed('steps' ,'-');">–/+<img alt=">" src="icons/waypoint-right.png" title="+" onmousedown="formSetSpeed('steps' ,'+');">
+<tr><td>Komp: <td><input name="speed-ferry" type="text" size="3" onchange="formSetSpeed('ferry' ,'=');"><td>km/hr<td><img alt="<" src="icons/waypoint-left.png" title="-" onmousedown="formSetSpeed('ferry' ,'-');">–/+<img alt=">" src="icons/waypoint-right.png" title="+" onmousedown="formSetSpeed('ferry' ,'+');">
+</table>
+</div>
+</div>
+
+<div class="hideshow_box">
+<span id="hideshow_property_show" onclick="hideshow_show('property');" class="hideshow_show">+</span>
+<span id="hideshow_property_hide" onclick="hideshow_hide('property');" class="hideshow_hide">-</span>
+<span class="hideshow_title">Út tulajdonságok</span>
+<div id="hideshow_property_div" style="display: none;">
+<table>
+<tr><td>Burkolt: <td><input name="property-paved" type="text" size="3" onchange="formSetProperty('paved' ,'=');"><td>%<td><img alt="<" src="icons/waypoint-left.png" title="-" onmousedown="formSetProperty('paved' ,'-');">–/+<img alt=">" src="icons/waypoint-right.png" title="+" onmousedown="formSetProperty('paved' ,'+');">
+<tr><td>Többsávos: <td><input name="property-multilane" type="text" size="3" onchange="formSetProperty('multilane' ,'=');"><td>%<td><img alt="<" src="icons/waypoint-left.png" title="-" onmousedown="formSetProperty('multilane' ,'-');">–/+<img alt=">" src="icons/waypoint-right.png" title="+" onmousedown="formSetProperty('multilane' ,'+');">
+<tr><td>Híd: <td><input name="property-bridge" type="text" size="3" onchange="formSetProperty('bridge' ,'=');"><td>%<td><img alt="<" src="icons/waypoint-left.png" title="-" onmousedown="formSetProperty('bridge' ,'-');">–/+<img alt=">" src="icons/waypoint-right.png" title="+" onmousedown="formSetProperty('bridge' ,'+');">
+<tr><td>Alagút: <td><input name="property-tunnel" type="text" size="3" onchange="formSetProperty('tunnel' ,'=');"><td>%<td><img alt="<" src="icons/waypoint-left.png" title="-" onmousedown="formSetProperty('tunnel' ,'-');">–/+<img alt=">" src="icons/waypoint-right.png" title="+" onmousedown="formSetProperty('tunnel' ,'+');">
+<tr><td>Gyalogút:<td><input name="property-footroute" type="text" size="3" onchange="formSetProperty('footroute' ,'=');"><td>%<td><img alt="<" src="icons/waypoint-left.png" title="-" onmousedown="formSetProperty('footroute' ,'-');">–/+<img alt=">" src="icons/waypoint-right.png" title="+" onmousedown="formSetProperty('footroute' ,'+');">
+<tr><td>Kijelölt kerékpárút:<td><input name="property-bicycleroute" type="text" size="3" onchange="formSetProperty('bicycleroute','=');"><td>%<td><img alt="<" src="icons/waypoint-left.png" title="-" onmousedown="formSetProperty('bicycleroute','-');">–/+<img alt=">" src="icons/waypoint-right.png" title="+" onmousedown="formSetProperty('bicycleroute','+');">
+</table>
+</div>
+</div>
+
+<div class="hideshow_box">
+<span id="hideshow_restriction_show" onclick="hideshow_show('restriction');" class="hideshow_show">+</span>
+<span id="hideshow_restriction_hide" onclick="hideshow_hide('restriction');" class="hideshow_hide">-</span>
+<span class="hideshow_title">Kizáró tényezők</span>
+<div id="hideshow_restriction_div" style="display: none;">
+<table>
+<tr><td>Egyirányúsítás mellőzése:<td><input name="restrict-oneway" type="checkbox" onchange="formSetRestriction('oneway');">
+<tr><td>Kanyarodási tilalmak mellőzése: <td><input name="restrict-turns" type="checkbox" onchange="formSetRestriction('turns' );">
+</table>
+<table>
+<tr><td>Súly:<td><input name="restrict-weight" type="text" size="3" onchange="formSetRestriction('weight','=');"><td>tonnes<td><img alt="<" src="icons/waypoint-left.png" title="-" onmousedown="formSetRestriction('weight','-');">–/+<img alt=">" src="icons/waypoint-right.png" title="+" onmousedown="formSetRestriction('weight','+');">
+<tr><td>Magasság:<td><input name="restrict-height" type="text" size="3" onchange="formSetRestriction('height','=');"><td>metres<td><img alt="<" src="icons/waypoint-left.png" title="-" onmousedown="formSetRestriction('height','-');">–/+<img alt=">" src="icons/waypoint-right.png" title="+" onmousedown="formSetRestriction('height','+');">
+<tr><td>Szélesség: <td><input name="restrict-width" type="text" size="3" onchange="formSetRestriction('width' ,'=');"><td>metres<td><img alt="<" src="icons/waypoint-left.png" title="-" onmousedown="formSetRestriction('width' ,'-');">–/+<img alt=">" src="icons/waypoint-right.png" title="+" onmousedown="formSetRestriction('width' ,'+');">
+<tr><td>Hosszúság:<td><input name="restrict-length" type="text" size="3" onchange="formSetRestriction('length','=');"><td>metres<td><img alt="<" src="icons/waypoint-left.png" title="-" onmousedown="formSetRestriction('length','-');">–/+<img alt=">" src="icons/waypoint-right.png" title="+" onmousedown="formSetRestriction('length','+');">
+</table>
+</div>
+</div>
+
+<div class="hideshow_box">
+<span class="hideshow_title">Find</span>
+<input type="button" title="A legrövidebb út keresése" id="shortest" value="Legrövidebb út" onclick="findRoute('shortest');" disabled="disabled">
+<input type="button" title="A leggyorsabb út keresése" id="quickest" value="Leggyorsabb út" onclick="findRoute('quickest');" disabled="disabled">
+</div>
+
+<div class="hideshow_box">
+<span class="hideshow_title">Linkek</span>
+<a id="permalink_url" href="router.html">Link erre a nézetre</a>
+<br>
+<a id="edit_url" target="edit" style="display: none;">OSM adatok szerkesztése</a>
+</div>
+
+<div class="hideshow_box">
+<span id="hideshow_help_options_show" onclick="hideshow_show('help_options');" class="hideshow_hide">+</span>
+<span id="hideshow_help_options_hide" onclick="hideshow_hide('help_options');" class="hideshow_show">-</span>
+<span class="hideshow_title">Súgó</span>
+<div id="hideshow_help_options_div">
+<div class="scrollable">
+<b>Quick Start</b>
+<br>
+Click on marker icons (above) to place them on the map (right). Then
+drag them to the correct position. Zooming the map before placing the
+markers is probably easiest. Alternatively type the latitude and
+longitude into the boxes above.
+<p>
+Select the transport type, allowed highway types, speed limits, highway
+properties and other restrictions from the options above.
+Select "Shortest" or "Quickest" to calculate the route and display it
+on the map.
+<p>
+<b>Waypoints</b>
+<br>
+Clicking on the marker icons will toggle the display of them on the map.
+When a route is calculated it will visit (as close as possible
+for the selected transport type) each of the waypoints that have
+markers on the map in the order given.
+<p>
+<b>Transport Type</b>
+<br>
+Selecting a transport type will restrict the chosen route to
+those on which it is allowed and set default values for the
+other parameters.
+<p>
+<b>Highway Preferences</b>
+<br>
+The highway preference is selected as a percentage and routes are chosen that
+try to follow the preferred highways.
+For example if a "Primary" road is given a "110%" preference and a "Secondary"
+road is given a "100%" preference then it means that a route on a Primary road
+can be up to 10% longer than on a secondary road and still be selected.
+<p>
+<b>Speed Limits</b>
+<br>
+The speed limits chosen here for the different types of highway apply if the
+highway has no other speed limit marked or it is higher than the chosen one.
+<p>
+<b>Property Preferences</b>
+<br>
+The property preference is selected as a percentage and routes are chosen that
+try to follow highways with the preferred property.
+For example if a "Paved" highway is given a "75%" preference then it means that
+an unpaved highway is automatically given a "25%" preference so that a route on
+a paved highway can be 3 times the length of an unpaved one and still be
+selected.
+<p>
+<b>Other Restrictions</b>
+<br>
+These allow a route to be found that avoids marked limits on
+weight, height, width or length. It is also possible to ignore
+one-way restrictions (e.g. if walking).
+</div>
+</div>
+</div>
+</form>
+</div>
+
+
+<div class="tab_content" id="tab_results_div" style="display: none;">
+
+<div class="hideshow_box">
+<span class="hideshow_title">Állapot</span>
+<div id="result_status">
+<div id="result_status_not_run">
+<b><i>Az útvonaltervező nem fut</i></b>
+</div>
+<div id="result_status_running" style="display: none;">
+<b>Az útvonaltervező számol ...</b>
+</div>
+<div id="result_status_complete" style="display: none;">
+<b>Az útvonaltervezés kész</b>
+<br>
+<a id="router_log_complete" target="router_log" href="#">Részletek</a>
+</div>
+<div id="result_status_error" style="display: none;">
+<b>Útvonaltervezési hiba</b>
+<br>
+<a id="router_log_error" target="router_log" href="#">Részletek</a>
+</div>
+<div id="result_status_failed" style="display: none;">
+<b>Az útvonaltervezőt nem sikerült futtatni</b>
+</div>
+</div>
+</div>
+
+<div class="hideshow_box">
+<span id="hideshow_shortest_show" onclick="hideshow_show('shortest');" class="hideshow_show">+</span>
+<span id="hideshow_shortest_hide" onclick="hideshow_hide('shortest');" class="hideshow_hide">-</span>
+<span class="hideshow_title">Legrövidebb út</span>
+<div id="shortest_status">
+<div id="shortest_status_no_info">
+<b><i>Nincs információ</i></b>
+</div>
+<div id="shortest_status_info" style="display: none;">
+</div>
+</div>
+<div id="hideshow_shortest_div" style="display: none;">
+<div id="shortest_links" style="display: none;">
+<table>
+<tr><td>HTML irányok: <td><a id="shortest_html" target="shortest_html" href="#">Új ablak</a>
+<tr><td>GPX file: <td><a id="shortest_gpx_track" target="shortest_gpx_track" href="#">Új ablak</a>
+<tr><td>GPX route file: <td><a id="shortest_gpx_route" target="shortest_gpx_route" href="#">Új ablak</a>
+<tr><td>Teljes szöveges file: <td><a id="shortest_text_all" target="shortest_text_all" href="#">Új ablak</a>
+<tr><td>Szöveges file: <td><a id="shortest_text" target="shortest_text" href="#">Új ablak</a>
+</table>
+<hr>
+</div>
+<div id="shortest_route">
+</div>
+</div>
+</div>
+
+<div class="hideshow_box">
+<span id="hideshow_quickest_show" onclick="hideshow_show('quickest');" class="hideshow_show">+</span>
+<span id="hideshow_quickest_hide" onclick="hideshow_hide('quickest');" class="hideshow_hide">-</span>
+<span class="hideshow_title">Leggyorsabb út</span>
+<div id="quickest_status">
+<div id="quickest_status_no_info">
+<b><i>Nincs információ</i></b>
+</div>
+<div id="quickest_status_info" style="display: none;">
+</div>
+</div>
+<div id="hideshow_quickest_div" style="display: none;">
+<div id="quickest_links" style="display: none;">
+<table>
+<tr><td>HTML irányok: <td><a id="quickest_html" target="quickest_html" href="#">Új ablak</a>
+<tr><td>GPX file: <td><a id="quickest_gpx_track" target="quickest_gpx_track" href="#">Új ablak</a>
+<tr><td>GPX route file: <td><a id="quickest_gpx_route" target="quickest_gpx_route" href="#">Új ablak</a>
+<tr><td>Teljes szöveges file: <td><a id="quickest_text_all" target="quickest_text_all" href="#">Új ablak</a>
+<tr><td>Szöveges file: <td><a id="quickest_text" target="quickest_text" href="#">Új ablak</a>
+</table>
+<hr>
+</div>
+<div id="quickest_route">
+</div>
+</div>
+</div>
+
+<div class="hideshow_box">
+<span id="hideshow_help_route_show" onclick="hideshow_show('help_route');" class="hideshow_hide">+</span>
+<span id="hideshow_help_route_hide" onclick="hideshow_hide('help_route');" class="hideshow_show">-</span>
+<span class="hideshow_title">Súgó</span>
+<div id="hideshow_help_route_div">
+<div class="scrollable">
+<b>Quick Start</b>
+<br>
+After calculating a route you can download the GPX file or plain
+text route description (summary or detailed version). Also you
+can view the route description and zoom in to selected parts.
+<p>
+<b>Problem Solving</b>
+<br>
+If the router completes with an error then the most likely cause is
+that it is not possible to find a route between the selected points.
+Moving one or more markers or changing the routing options should
+allow a route to be found.
+<p>
+<b>Output Formats</b>
+<br>
+<dl>
+<dt>HTML instructions
+<dd>A description of the route to take with directions at each
+important junction.
+<dt>GPX track file
+<dd>The same information that is displayed on the map with points
+for every node and lines for every segment.
+<dt>GPX route file
+<dd>The same information that is displayed in text for the route
+with a waypoint for each important junction in the route.
+<dt>Full text file
+<dd>A list of all of the nodes visited as well as the distance
+between them and the cumulative distance for each step of the
+route.
+<dt>Text file
+<dd>The same information that is displayed in text for the route.
+</dl>
+</div>
+</div>
+</div>
+</div>
+
+
+<div class="tab_content" id="tab_data_div" style="display: none;">
+<div class="hideshow_box">
+<span class="hideshow_title">Routino statisztika</span>
+<div id="statistics_data"></div>
+<a id="statistics_link" href="statistics.cgi" onclick="displayStatistics();return(false);">Statisztika mutatása</a>
+</div>
+
+<div class="hideshow_box">
+<span class="hideshow_title">Routino vizualizáció</span>
+To see Routino's view of the data there is a data visualiser that allows
+displaying of the underlying data in various ways.
+<br>
+<a id="visualiser_url" href="visualiser.html" target="visualiser">Link erre a nézetre</a>
+</div>
+</div>
+
+</div>
+
+<!-- Right hand side of window - map -->
+
+<div class="right_panel">
+<div class="map" id="map">
+<noscript>
+<p>
+Javascript is <em>required</em> to use this web page because of the interactive map.
+</noscript>
+</div>
+<div class="attribution">
+Útvonaltervező: <a href="http://www.routino.org/" target="routino">Routino</a>
+|
+Geo Data: <span id="attribution_data"></span>
+|
+Térképszeletek: <span id="attribution_tile"></span>
+</div>
+</div>
+
+</body>
+
+</html>
diff --git a/web/www/routino/router.html.nl b/web/www/routino/router.html.nl
index f5f1ff4..3e86102 100644
--- a/web/www/routino/router.html.nl
+++ b/web/www/routino/router.html.nl
@@ -13,7 +13,7 @@ Routino router web page.
 
 Part of the Routino routing software.
 
-This file Copyright 2008-2014 Andrew M. Bishop
+This file Copyright 2008-2015 Andrew M. Bishop
 
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU Affero General Public License as published by
@@ -94,10 +94,18 @@ icoon links, schuif het op map naar gewenste positie).
 <td>(FR)
 <td><input name="language" type="radio" value="fr" onchange="formSetLanguage();" >
 <tr>
+<td><a id="lang_hu_url" href="router.html.hu" title="Magyar weblap">Magyar</a>
+<td>(HU)
+<td><input name="language" type="radio" value="hu" onchange="formSetLanguage();" >
+<tr>
 <td><a id="lang_nl_url" href="router.html.nl" title="Nederlandse web pagina">Nederlands</a>
 <td>(NL)
 <td><input name="language" type="radio" value="nl" onchange="formSetLanguage();" checked>
 <tr>
+<td><a id="lang_pl_url" href="router.html.pl" title="Polski webpage">Polski</a>
+<td>(PL)
+<td><input name="language" type="radio" value="pl" onchange="formSetLanguage();" >
+<tr>
 <td><a id="lang_ru_url" href="router.html.ru" title="Русский">Русский</a>
 <td>(RU)
 <td><input name="language" type="radio" value="ru" onchange="formSetLanguage();" >
@@ -111,16 +119,9 @@ icoon links, schuif het op map naar gewenste positie).
 <span id="hideshow_waypoint_hide" onclick="hideshow_hide('waypoint');" class="hideshow_show">-</span>
 <span class="hideshow_title">Coordinaten</span>
 <div id="hideshow_waypoint_div">
-<table id="waypoints">
-<colgroup>
-<col style="width: 22px;">
-<col>
-<col style="width: 76px;">
-</colgroup>
-<tr id="waypointXXX" style="display: none;">
-<td>
-<img id="iconXXX" src="icons/marker-XXX-grey.png" title="Waypoint XXX Position - (click voor plaatsen/verwijderen op map)" alt="Waypoint XXX" onmousedown="markerToggleMap(XXX);">
-<td>
+<div id="waypoints">
+<div id="waypointXXX" class="waypoint" style="display: none;">
+<img id="iconXXX" class="waypoint-icon" src="icons/marker-XXX-grey.png" title="Waypoint XXX Position" alt="Waypoint XXX" onmouseup="markerToggleMap(XXX);" draggable="true">
 <span id="coordsXXX">
 <input name="lonXXX" type="text" size="7" title="Waypoint XXX Longitude" onchange="formSetCoords(XXX);">E
 <input name="latXXX" type="text" size="7" title="Waypoint XXX Latitude" onchange="formSetCoords(XXX);">N
@@ -128,7 +129,7 @@ icoon links, schuif het op map naar gewenste positie).
 <span id="searchXXX" style="display: none;">
 <input name="searchXXX" type="text" size="18" title="Waypoint XXX Location"> <!-- uses Javascript event for triggering -->
 </span>
-<td>
+<div class="waypoint-buttons" style="display: inline-block;">
 <img alt="?" src="icons/waypoint-search.png" title="Search for location" onmousedown="markerSearch(XXX);" >
 <img alt="G" src="icons/waypoint-locate.png" title="Get current location" onmousedown="markerLocate(XXX);" >
 <img alt="O" src="icons/waypoint-recentre.png" title="Centre map on this waypoint" onmousedown="markerRecentre(XXX);">
@@ -140,14 +141,15 @@ icoon links, schuif het op map naar gewenste positie).
 <img alt="o" src="icons/waypoint-centre.png" title="Centreer dit punt op map" onmousedown="markerCentre(XXX);" >
 <img alt="v" src="icons/waypoint-down.png" title="Beweeg dit punt naar beneden" onmousedown="markerMoveDown(XXX);">
 <img alt="-" src="icons/waypoint-remove.png" title="Verwijder dit punt" onmousedown="markerRemove(XXX);" >
-<tr id="searchresultsXXX" style="display: none;">
-<td colspan="3">
-<!-- The waypoints are inserted by the JavaScript, see the "maxmarkers" variable in router.js. -->
-<tr>
-<td colspan="3" class="center">
+</div>
+<div id="searchresultsXXX" style="display: none;">
+</div>
+</div>
+</div>
+<div id="waypoints-buttons" class="center">
 <input type="button" title="Keer volgorde punten om" value="Keer volgorde punten om" onmousedown="markersReverse();">
 <input type="button" title="Add a new waypoint to make a loop" value="Close loop" onmousedown="markersLoop();">
-</table>
+</div>
 </div>
 </div>
 
@@ -239,8 +241,8 @@ icoon links, schuif het op map naar gewenste positie).
 <span class="hideshow_title">Andere Beperkingen</span>
 <div id="hideshow_restriction_div" style="display: none;">
 <table>
-<tr><td>Volg Eenrichtingsverkeer: <td><input name="restrict-oneway" type="checkbox" onchange="formSetRestriction('oneway');">
-<tr><td>Obey turn restrictions:<td><input name="restrict-turns" type="checkbox" onchange="formSetRestriction('turns' );">
+<tr><td>Volg Eenrichtingsverkeer:<td><input name="restrict-oneway" type="checkbox" onchange="formSetRestriction('oneway');">
+<tr><td>Obey turn restrictions: <td><input name="restrict-turns" type="checkbox" onchange="formSetRestriction('turns' );">
 </table>
 <table>
 <tr><td>Gewicht:<td><input name="restrict-weight" type="text" size="3" onchange="formSetRestriction('weight','=');"><td>tonnes<td><img alt="<" src="icons/waypoint-left.png" title="-" onmousedown="formSetRestriction('weight','-');">–/+<img alt=">" src="icons/waypoint-right.png" title="+" onmousedown="formSetRestriction('weight','+');">
@@ -375,8 +377,8 @@ Het is ook mogelijk geen rekening te houden met eenrichtingsverkeer
 <tr><td>HTML directions: <td><a id="shortest_html" target="shortest_html" href="#">Open Popup</a>
 <tr><td>GPX track bestand: <td><a id="shortest_gpx_track" target="shortest_gpx_track" href="#">Open Popup</a>
 <tr><td>GPX route bestand: <td><a id="shortest_gpx_route" target="shortest_gpx_route" href="#">Open Popup</a>
-<tr><td>Full text bestand: <td><a id="shortest_text_all" target="shortest_text_all" href="#">Open Popup</a>
-<tr><td>Text bestand: <td><a id="shortest_text" target="shortest_text" href="#">Open Popup</a>
+<tr><td>Volledig tekst bestand: <td><a id="shortest_text_all" target="shortest_text_all" href="#">Open Popup</a>
+<tr><td>Tekst bestand: <td><a id="shortest_text" target="shortest_text" href="#">Open Popup</a>
 </table>
 <hr>
 </div>
@@ -402,8 +404,8 @@ Het is ook mogelijk geen rekening te houden met eenrichtingsverkeer
 <tr><td>HTML directions: <td><a id="quickest_html" target="quickest_html" href="#">Open Popup</a>
 <tr><td>GPX track bestand: <td><a id="quickest_gpx_track" target="quickest_gpx_track" href="#">Open Popup</a>
 <tr><td>GPX route bestand: <td><a id="quickest_gpx_route" target="quickest_gpx_route" href="#">Open Popup</a>
-<tr><td>Full text bestand: <td><a id="quickest_text_all" target="quickest_text_all" href="#">Open Popup</a>
-<tr><td>Text bestand: <td><a id="quickest_text" target="quickest_text" href="#">Open Popup</a>
+<tr><td>Volledig tekst bestand: <td><a id="quickest_text_all" target="quickest_text_all" href="#">Open Popup</a>
+<tr><td>Tekst bestand: <td><a id="quickest_text" target="quickest_text" href="#">Open Popup</a>
 </table>
 <hr>
 </div>
diff --git a/web/www/routino/router.html.en b/web/www/routino/router.html.pl
similarity index 56%
copy from web/www/routino/router.html.en
copy to web/www/routino/router.html.pl
index df52d8b..eb2bd1e 100644
--- a/web/www/routino/router.html.en
+++ b/web/www/routino/router.html.pl
@@ -6,14 +6,14 @@
 <meta name="keywords" content="openstreetmap routing route planner">
 <meta name="viewport" content="width=device-width, height=device-height, initial-scale=1, user-scalable=no">
 
-<title>Routino : Route Planner for OpenStreetMap Data</title>
+<title>Routino : Planowanie trasy dla Danych OpenStreetMap</title>
 
 <!--
 Routino router web page.
 
 Part of the Routino routing software.
 
-This file Copyright 2008-2014 Andrew M. Bishop
+This file Copyright 2008-2015 Andrew M. Bishop
 
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU Affero General Public License as published by
@@ -54,36 +54,36 @@ along with this program. If not, see http://www.gnu.org/licenses/.
 <div class="left_panel">
 
 <div class="tab_box">
-<span id="tab_options" onclick="tab_select('options');" class="tab_selected" title="Set routing options">Options</span>
-<span id="tab_results" onclick="tab_select('results');" class="tab_unselected" title="See routing results">Results</span>
-<span id="tab_data" onclick="tab_select('data');" class="tab_unselected" title="View database information">Data</span>
+<span id="tab_options" onclick="tab_select('options');" class="tab_selected" title="Ustaw punkty trasy">Opcje</span>
+<span id="tab_results" onclick="tab_select('results');" class="tab_unselected" title="Zobacz wyniki">Wyniki</span>
+<span id="tab_data" onclick="tab_select('data');" class="tab_unselected" title="Zobacz informacje bazy danych">Dane</span>
 </div>
 
 <div class="tab_content" id="tab_options_div">
 
 <form name="form" id="form" action="#" method="get" onsubmit="return false;">
 <div class="hideshow_box">
-<span class="hideshow_title">Routino OpenStreetMap Router</span>
+<span class="hideshow_title">Routino OpenStreetMap Planowanie Trasy</span>
 This web page allows routing within the data collected by OpenStreetMap.
 Select start and end points (click on the marker icons below), select routing preferences then find a route.
 <div class="center">
-<a target="other" href="http://www.routino.org/">Routino Website</a>
+<a target="other" href="http://www.routino.org/">Strona Routino</a>
 |
-<a target="other" href="documentation/">Documentation</a>
+<a target="other" href="documentation/">Dokumentacja</a>
 </div>
 </div>
 
 <div class="hideshow_box">
 <span id="hideshow_language_show" onclick="hideshow_show('language');" class="hideshow_show">+</span>
 <span id="hideshow_language_hide" onclick="hideshow_hide('language');" class="hideshow_hide">-</span>
-<span class="hideshow_title">Language</span>
+<span class="hideshow_title">Język</span>
 
 <div id="hideshow_language_div" style="display: none;">
 <table>
 <tr>
 <td><a id="lang_en_url" href="router.html.en" title="English language webpage">English</a>
 <td>(EN)
-<td><input name="language" type="radio" value="en" onchange="formSetLanguage();" checked>
+<td><input name="language" type="radio" value="en" onchange="formSetLanguage();" >
 <tr>
 <td><a id="lang_de_url" href="router.html.de" title="Deutsche Webseite">Deutsch</a>
 <td>(DE)
@@ -93,10 +93,18 @@ Select start and end points (click on the marker icons below), select routing pr
 <td>(FR)
 <td><input name="language" type="radio" value="fr" onchange="formSetLanguage();" >
 <tr>
+<td><a id="lang_hu_url" href="router.html.hu" title="Magyar weblap">Magyar</a>
+<td>(HU)
+<td><input name="language" type="radio" value="hu" onchange="formSetLanguage();" >
+<tr>
 <td><a id="lang_nl_url" href="router.html.nl" title="Nederlandse web pagina">Nederlands</a>
 <td>(NL)
 <td><input name="language" type="radio" value="nl" onchange="formSetLanguage();" >
 <tr>
+<td><a id="lang_pl_url" href="router.html.pl" title="Polski webpage">Polski</a>
+<td>(PL)
+<td><input name="language" type="radio" value="pl" onchange="formSetLanguage();" checked>
+<tr>
 <td><a id="lang_ru_url" href="router.html.ru" title="Русский">Русский</a>
 <td>(RU)
 <td><input name="language" type="radio" value="ru" onchange="formSetLanguage();" >
@@ -108,18 +116,11 @@ Select start and end points (click on the marker icons below), select routing pr
 <div class="hideshow_box">
 <span id="hideshow_waypoint_show" onclick="hideshow_show('waypoint');" class="hideshow_hide">+</span>
 <span id="hideshow_waypoint_hide" onclick="hideshow_hide('waypoint');" class="hideshow_show">-</span>
-<span class="hideshow_title">Waypoints</span>
+<span class="hideshow_title">Punkty</span>
 <div id="hideshow_waypoint_div">
-<table id="waypoints">
-<colgroup>
-<col style="width: 22px;">
-<col>
-<col style="width: 76px;">
-</colgroup>
-<tr id="waypointXXX" style="display: none;">
-<td>
-<img id="iconXXX" src="icons/marker-XXX-grey.png" title="Waypoint XXX Position - (click to add/remove on map)" alt="Waypoint XXX" onmousedown="markerToggleMap(XXX);">
-<td>
+<div id="waypoints">
+<div id="waypointXXX" class="waypoint" style="display: none;">
+<img id="iconXXX" class="waypoint-icon" src="icons/marker-XXX-grey.png" title="Waypoint XXX Position" alt="Waypoint XXX" onmouseup="markerToggleMap(XXX);" draggable="true">
 <span id="coordsXXX">
 <input name="lonXXX" type="text" size="7" title="Waypoint XXX Longitude" onchange="formSetCoords(XXX);">E
 <input name="latXXX" type="text" size="7" title="Waypoint XXX Latitude" onchange="formSetCoords(XXX);">N
@@ -127,45 +128,46 @@ Select start and end points (click on the marker icons below), select routing pr
 <span id="searchXXX" style="display: none;">
 <input name="searchXXX" type="text" size="18" title="Waypoint XXX Location"> <!-- uses Javascript event for triggering -->
 </span>
-<td>
-<img alt="?" src="icons/waypoint-search.png" title="Search for location" onmousedown="markerSearch(XXX);" >
-<img alt="G" src="icons/waypoint-locate.png" title="Get current location" onmousedown="markerLocate(XXX);" >
-<img alt="O" src="icons/waypoint-recentre.png" title="Centre map on this waypoint" onmousedown="markerRecentre(XXX);">
+<div class="waypoint-buttons" style="display: inline-block;">
+<img alt="?" src="icons/waypoint-search.png" title="Znajdź miejsce" onmousedown="markerSearch(XXX);" >
+<img alt="G" src="icons/waypoint-locate.png" title="Pobierz aktualna lokalizację" onmousedown="markerLocate(XXX);" >
+<img alt="O" src="icons/waypoint-recentre.png" title="Wycentruj mapę na tym punkcie" onmousedown="markerRecentre(XXX);">
 <img alt="^" src="icons/waypoint-up.png" title="Move this waypoint up" onmousedown="markerMoveUp(XXX);" >
 <img alt="+" src="icons/waypoint-add.png" title="Add waypoint after this one" onmousedown="markerAddAfter(XXX);">
 <br>
 <img alt="#" src="icons/waypoint-coords.png" title="Coordinates for location" onmousedown="markerCoords(XXX);" >
-<img alt="~" src="icons/waypoint-home.png" title="Toggle as home location" onmousedown="markerHome(XXX);" >
+<img alt="~" src="icons/waypoint-home.png" title="Współrzędne lokalizacji" onmousedown="markerHome(XXX);" >
 <img alt="o" src="icons/waypoint-centre.png" title="Centre this waypoint on map" onmousedown="markerCentre(XXX);" >
 <img alt="v" src="icons/waypoint-down.png" title="Move this waypoint down" onmousedown="markerMoveDown(XXX);">
 <img alt="-" src="icons/waypoint-remove.png" title="Remove this waypoint" onmousedown="markerRemove(XXX);" >
-<tr id="searchresultsXXX" style="display: none;">
-<td colspan="3">
-<!-- The waypoints are inserted by the JavaScript, see the "maxmarkers" variable in router.js. -->
-<tr>
-<td colspan="3" class="center">
+</div>
+<div id="searchresultsXXX" style="display: none;">
+</div>
+</div>
+</div>
+<div id="waypoints-buttons" class="center">
 <input type="button" title="Reverse order of waypoints" value="Reverse order" onmousedown="markersReverse();">
 <input type="button" title="Add a new waypoint to make a loop" value="Close loop" onmousedown="markersLoop();">
-</table>
+</div>
 </div>
 </div>
 
 <div class="hideshow_box">
 <span id="hideshow_transport_show" onclick="hideshow_show('transport');" class="hideshow_hide">+</span>
 <span id="hideshow_transport_hide" onclick="hideshow_hide('transport');" class="hideshow_show">-</span>
-<span class="hideshow_title">Transport Type</span>
+<span class="hideshow_title">Typ transportu</span>
 <div id="hideshow_transport_div">
 <table>
-<tr><td>Foot: <td><input name="transport" type="radio" value="foot" onchange="formSetTransport('foot' );">
-<tr><td>Horse: <td><input name="transport" type="radio" value="horse" onchange="formSetTransport('horse' );">
-<tr><td>Wheelchair:<td><input name="transport" type="radio" value="wheelchair" onchange="formSetTransport('wheelchair');">
-<tr><td>Bicycle: <td><input name="transport" type="radio" value="bicycle" onchange="formSetTransport('bicycle' );">
+<tr><td>Pieszo: <td><input name="transport" type="radio" value="foot" onchange="formSetTransport('foot' );">
+<tr><td>Konno: <td><input name="transport" type="radio" value="horse" onchange="formSetTransport('horse' );">
+<tr><td>Wózek inwalidzki:<td><input name="transport" type="radio" value="wheelchair" onchange="formSetTransport('wheelchair');">
+<tr><td>Rower: <td><input name="transport" type="radio" value="bicycle" onchange="formSetTransport('bicycle' );">
 <tr><td>Moped: <td><input name="transport" type="radio" value="moped" onchange="formSetTransport('moped' );">
-<tr><td>Motorcycle:<td><input name="transport" type="radio" value="motorcycle" onchange="formSetTransport('motorcycle');">
-<tr><td>Motorcar: <td><input name="transport" type="radio" value="motorcar" onchange="formSetTransport('motorcar' );">
+<tr><td>Motocykl:<td><input name="transport" type="radio" value="motorcycle" onchange="formSetTransport('motorcycle');">
+<tr><td>Samochód: <td><input name="transport" type="radio" value="motorcar" onchange="formSetTransport('motorcar' );">
 <tr><td>Goods: <td><input name="transport" type="radio" value="goods" onchange="formSetTransport('goods' );">
 <tr><td>HGV: <td><input name="transport" type="radio" value="hgv" onchange="formSetTransport('hgv' );">
-<tr><td>PSV: <td><input name="transport" type="radio" value="psv" onchange="formSetTransport('psv' );">
+<tr><td>Pojazd użyteczności publicznej: <td><input name="transport" type="radio" value="psv" onchange="formSetTransport('psv' );">
 </table>
 </div>
 </div>
@@ -173,22 +175,22 @@ Select start and end points (click on the marker icons below), select routing pr
 <div class="hideshow_box">
 <span id="hideshow_highway_show" onclick="hideshow_show('highway');" class="hideshow_show">+</span>
 <span id="hideshow_highway_hide" onclick="hideshow_hide('highway');" class="hideshow_hide">-</span>
-<span class="hideshow_title">Highway Preferences</span>
+<span class="hideshow_title">Preferowanie autostrad</span>
 <div id="hideshow_highway_div" style="display: none;">
 <table>
-<tr><td>Motorway: <td><input name="highway-motorway" type="text" size="3" onchange="formSetHighway('motorway' ,'=');"><td>%<td><img alt="<" src="icons/waypoint-left.png" title="-" onmousedown="formSetHighway('motorway' ,'-');">–/+<img alt=">" src="icons/waypoint-right.png" title="+" onmousedown="formSetHighway('motorway' ,'+');">
+<tr><td>Autostrada: <td><input name="highway-motorway" type="text" size="3" onchange="formSetHighway('motorway' ,'=');"><td>%<td><img alt="<" src="icons/waypoint-left.png" title="-" onmousedown="formSetHighway('motorway' ,'-');">–/+<img alt=">" src="icons/waypoint-right.png" title="+" onmousedown="formSetHighway('motorway' ,'+');">
 <tr><td>Trunk: <td><input name="highway-trunk" type="text" size="3" onchange="formSetHighway('trunk' ,'=');"><td>%<td><img alt="<" src="icons/waypoint-left.png" title="-" onmousedown="formSetHighway('trunk' ,'-');">–/+<img alt=">" src="icons/waypoint-right.png" title="+" onmousedown="formSetHighway('trunk' ,'+');">
-<tr><td>Primary: <td><input name="highway-primary" type="text" size="3" onchange="formSetHighway('primary' ,'=');"><td>%<td><img alt="<" src="icons/waypoint-left.png" title="-" onmousedown="formSetHighway('primary' ,'-');">–/+<img alt=">" src="icons/waypoint-right.png" title="+" onmousedown="formSetHighway('primary' ,'+');">
-<tr><td>Secondary: <td><input name="highway-secondary" type="text" size="3" onchange="formSetHighway('secondary' ,'=');"><td>%<td><img alt="<" src="icons/waypoint-left.png" title="-" onmousedown="formSetHighway('secondary' ,'-');">–/+<img alt=">" src="icons/waypoint-right.png" title="+" onmousedown="formSetHighway('secondary' ,'+');">
-<tr><td>Tertiary: <td><input name="highway-tertiary" type="text" size="3" onchange="formSetHighway('tertiary' ,'=');"><td>%<td><img alt="<" src="icons/waypoint-left.png" title="-" onmousedown="formSetHighway('tertiary' ,'-');">–/+<img alt=">" src="icons/waypoint-right.png" title="+" onmousedown="formSetHighway('tertiary' ,'+');">
-<tr><td>Unclassified:<td><input name="highway-unclassified" type="text" size="3" onchange="formSetHighway('unclassified','=');"><td>%<td><img alt="<" src="icons/waypoint-left.png" title="-" onmousedown="formSetHighway('unclassified','-');">–/+<img alt=">" src="icons/waypoint-right.png" title="+" onmousedown="formSetHighway('unclassified','+');">
-<tr><td>Residential: <td><input name="highway-residential" type="text" size="3" onchange="formSetHighway('residential' ,'=');"><td>%<td><img alt="<" src="icons/waypoint-left.png" title="-" onmousedown="formSetHighway('residential' ,'-');">–/+<img alt=">" src="icons/waypoint-right.png" title="+" onmousedown="formSetHighway('residential' ,'+');">
-<tr><td>Service: <td><input name="highway-service" type="text" size="3" onchange="formSetHighway('service' ,'=');"><td>%<td><img alt="<" src="icons/waypoint-left.png" title="-" onmousedown="formSetHighway('service' ,'-');">–/+<img alt=">" src="icons/waypoint-right.png" title="+" onmousedown="formSetHighway('service' ,'+');">
+<tr><td>Droga krajowa: <td><input name="highway-primary" type="text" size="3" onchange="formSetHighway('primary' ,'=');"><td>%<td><img alt="<" src="icons/waypoint-left.png" title="-" onmousedown="formSetHighway('primary' ,'-');">–/+<img alt=">" src="icons/waypoint-right.png" title="+" onmousedown="formSetHighway('primary' ,'+');">
+<tr><td>Droga wojewódzka: <td><input name="highway-secondary" type="text" size="3" onchange="formSetHighway('secondary' ,'=');"><td>%<td><img alt="<" src="icons/waypoint-left.png" title="-" onmousedown="formSetHighway('secondary' ,'-');">–/+<img alt=">" src="icons/waypoint-right.png" title="+" onmousedown="formSetHighway('secondary' ,'+');">
+<tr><td>Droga powiatowa: <td><input name="highway-tertiary" type="text" size="3" onchange="formSetHighway('tertiary' ,'=');"><td>%<td><img alt="<" src="icons/waypoint-left.png" title="-" onmousedown="formSetHighway('tertiary' ,'-');">–/+<img alt=">" src="icons/waypoint-right.png" title="+" onmousedown="formSetHighway('tertiary' ,'+');">
+<tr><td>Niesklasyfikowana:<td><input name="highway-unclassified" type="text" size="3" onchange="formSetHighway('unclassified','=');"><td>%<td><img alt="<" src="icons/waypoint-left.png" title="-" onmousedown="formSetHighway('unclassified','-');">–/+<img alt=">" src="icons/waypoint-right.png" title="+" onmousedown="formSetHighway('unclassified','+');">
+<tr><td>W obszarze zamieszkania: <td><input name="highway-residential" type="text" size="3" onchange="formSetHighway('residential' ,'=');"><td>%<td><img alt="<" src="icons/waypoint-left.png" title="-" onmousedown="formSetHighway('residential' ,'-');">–/+<img alt=">" src="icons/waypoint-right.png" title="+" onmousedown="formSetHighway('residential' ,'+');">
+<tr><td>Dojazdowa: <td><input name="highway-service" type="text" size="3" onchange="formSetHighway('service' ,'=');"><td>%<td><img alt="<" src="icons/waypoint-left.png" title="-" onmousedown="formSetHighway('service' ,'-');">–/+<img alt=">" src="icons/waypoint-right.png" title="+" onmousedown="formSetHighway('service' ,'+');">
 <tr><td>Track: <td><input name="highway-track" type="text" size="3" onchange="formSetHighway('track' ,'=');"><td>%<td><img alt="<" src="icons/waypoint-left.png" title="-" onmousedown="formSetHighway('track' ,'-');">–/+<img alt=">" src="icons/waypoint-right.png" title="+" onmousedown="formSetHighway('track' ,'+');">
-<tr><td>Cycleway: <td><input name="highway-cycleway" type="text" size="3" onchange="formSetHighway('cycleway' ,'=');"><td>%<td><img alt="<" src="icons/waypoint-left.png" title="-" onmousedown="formSetHighway('cycleway' ,'-');">–/+<img alt=">" src="icons/waypoint-right.png" title="+" onmousedown="formSetHighway('cycleway' ,'+');">
-<tr><td>Path: <td><input name="highway-path" type="text" size="3" onchange="formSetHighway('path' ,'=');"><td>%<td><img alt="<" src="icons/waypoint-left.png" title="-" onmousedown="formSetHighway('path' ,'-');">–/+<img alt=">" src="icons/waypoint-right.png" title="+" onmousedown="formSetHighway('path' ,'+');">
+<tr><td>Rowerowa: <td><input name="highway-cycleway" type="text" size="3" onchange="formSetHighway('cycleway' ,'=');"><td>%<td><img alt="<" src="icons/waypoint-left.png" title="-" onmousedown="formSetHighway('cycleway' ,'-');">–/+<img alt=">" src="icons/waypoint-right.png" title="+" onmousedown="formSetHighway('cycleway' ,'+');">
+<tr><td>Ścieżka: <td><input name="highway-path" type="text" size="3" onchange="formSetHighway('path' ,'=');"><td>%<td><img alt="<" src="icons/waypoint-left.png" title="-" onmousedown="formSetHighway('path' ,'-');">–/+<img alt=">" src="icons/waypoint-right.png" title="+" onmousedown="formSetHighway('path' ,'+');">
 <tr><td>Steps: <td><input name="highway-steps" type="text" size="3" onchange="formSetHighway('steps' ,'=');"><td>%<td><img alt="<" src="icons/waypoint-left.png" title="-" onmousedown="formSetHighway('steps' ,'-');">–/+<img alt=">" src="icons/waypoint-right.png" title="+" onmousedown="formSetHighway('steps' ,'+');">
-<tr><td>Ferry: <td><input name="highway-ferry" type="text" size="3" onchange="formSetHighway('ferry' ,'=');"><td>%<td><img alt="<" src="icons/waypoint-left.png" title="-" onmousedown="formSetHighway('ferry' ,'-');">–/+<img alt=">" src="icons/waypoint-right.png" title="+" onmousedown="formSetHighway('ferry' ,'+');">
+<tr><td>Przeprawa: <td><input name="highway-ferry" type="text" size="3" onchange="formSetHighway('ferry' ,'=');"><td>%<td><img alt="<" src="icons/waypoint-left.png" title="-" onmousedown="formSetHighway('ferry' ,'-');">–/+<img alt=">" src="icons/waypoint-right.png" title="+" onmousedown="formSetHighway('ferry' ,'+');">
 </table>
 </div>
 </div>
@@ -196,22 +198,22 @@ Select start and end points (click on the marker icons below), select routing pr
 <div class="hideshow_box">
 <span id="hideshow_speed_show" onclick="hideshow_show('speed');" class="hideshow_show">+</span>
 <span id="hideshow_speed_hide" onclick="hideshow_hide('speed');" class="hideshow_hide">-</span>
-<span class="hideshow_title">Speed Limits</span>
+<span class="hideshow_title">Ograniczenia prędkości</span>
 <div id="hideshow_speed_div" style="display: none;">
 <table>
-<tr><td>Motorway: <td><input name="speed-motorway" type="text" size="3" onchange="formSetSpeed('motorway' ,'=');"><td>km/hr<td><img alt="<" src="icons/waypoint-left.png" title="-" onmousedown="formSetSpeed('motorway' ,'-');">–/+<img alt=">" src="icons/waypoint-right.png" title="+" onmousedown="formSetSpeed('motorway' ,'+');">
+<tr><td>Autostrada: <td><input name="speed-motorway" type="text" size="3" onchange="formSetSpeed('motorway' ,'=');"><td>km/hr<td><img alt="<" src="icons/waypoint-left.png" title="-" onmousedown="formSetSpeed('motorway' ,'-');">–/+<img alt=">" src="icons/waypoint-right.png" title="+" onmousedown="formSetSpeed('motorway' ,'+');">
 <tr><td>Trunk: <td><input name="speed-trunk" type="text" size="3" onchange="formSetSpeed('trunk' ,'=');"><td>km/hr<td><img alt="<" src="icons/waypoint-left.png" title="-" onmousedown="formSetSpeed('trunk' ,'-');">–/+<img alt=">" src="icons/waypoint-right.png" title="+" onmousedown="formSetSpeed('trunk' ,'+');">
-<tr><td>Primary: <td><input name="speed-primary" type="text" size="3" onchange="formSetSpeed('primary' ,'=');"><td>km/hr<td><img alt="<" src="icons/waypoint-left.png" title="-" onmousedown="formSetSpeed('primary' ,'-');">–/+<img alt=">" src="icons/waypoint-right.png" title="+" onmousedown="formSetSpeed('primary' ,'+');">
-<tr><td>Secondary: <td><input name="speed-secondary" type="text" size="3" onchange="formSetSpeed('secondary' ,'=');"><td>km/hr<td><img alt="<" src="icons/waypoint-left.png" title="-" onmousedown="formSetSpeed('secondary' ,'-');">–/+<img alt=">" src="icons/waypoint-right.png" title="+" onmousedown="formSetSpeed('secondary' ,'+');">
-<tr><td>Tertiary: <td><input name="speed-tertiary" type="text" size="3" onchange="formSetSpeed('tertiary' ,'=');"><td>km/hr<td><img alt="<" src="icons/waypoint-left.png" title="-" onmousedown="formSetSpeed('tertiary' ,'-');">–/+<img alt=">" src="icons/waypoint-right.png" title="+" onmousedown="formSetSpeed('tertiary' ,'+');">
-<tr><td>Unclassified:<td><input name="speed-unclassified" type="text" size="3" onchange="formSetSpeed('unclassified','=');"><td>km/hr<td><img alt="<" src="icons/waypoint-left.png" title="-" onmousedown="formSetSpeed('unclassified','-');">–/+<img alt=">" src="icons/waypoint-right.png" title="+" onmousedown="formSetSpeed('unclassified','+');">
-<tr><td>Residential: <td><input name="speed-residential" type="text" size="3" onchange="formSetSpeed('residential' ,'=');"><td>km/hr<td><img alt="<" src="icons/waypoint-left.png" title="-" onmousedown="formSetSpeed('residential' ,'-');">–/+<img alt=">" src="icons/waypoint-right.png" title="+" onmousedown="formSetSpeed('residential' ,'+');">
-<tr><td>Service: <td><input name="speed-service" type="text" size="3" onchange="formSetSpeed('service' ,'=');"><td>km/hr<td><img alt="<" src="icons/waypoint-left.png" title="-" onmousedown="formSetSpeed('service' ,'-');">–/+<img alt=">" src="icons/waypoint-right.png" title="+" onmousedown="formSetSpeed('service' ,'+');">
+<tr><td>Droga krajowa: <td><input name="speed-primary" type="text" size="3" onchange="formSetSpeed('primary' ,'=');"><td>km/hr<td><img alt="<" src="icons/waypoint-left.png" title="-" onmousedown="formSetSpeed('primary' ,'-');">–/+<img alt=">" src="icons/waypoint-right.png" title="+" onmousedown="formSetSpeed('primary' ,'+');">
+<tr><td>Droga wojewódzka: <td><input name="speed-secondary" type="text" size="3" onchange="formSetSpeed('secondary' ,'=');"><td>km/hr<td><img alt="<" src="icons/waypoint-left.png" title="-" onmousedown="formSetSpeed('secondary' ,'-');">–/+<img alt=">" src="icons/waypoint-right.png" title="+" onmousedown="formSetSpeed('secondary' ,'+');">
+<tr><td>Droga powiatowa: <td><input name="speed-tertiary" type="text" size="3" onchange="formSetSpeed('tertiary' ,'=');"><td>km/hr<td><img alt="<" src="icons/waypoint-left.png" title="-" onmousedown="formSetSpeed('tertiary' ,'-');">–/+<img alt=">" src="icons/waypoint-right.png" title="+" onmousedown="formSetSpeed('tertiary' ,'+');">
+<tr><td>Niesklasyfikowana:<td><input name="speed-unclassified" type="text" size="3" onchange="formSetSpeed('unclassified','=');"><td>km/hr<td><img alt="<" src="icons/waypoint-left.png" title="-" onmousedown="formSetSpeed('unclassified','-');">–/+<img alt=">" src="icons/waypoint-right.png" title="+" onmousedown="formSetSpeed('unclassified','+');">
+<tr><td>W obszarze zamieszkania: <td><input name="speed-residential" type="text" size="3" onchange="formSetSpeed('residential' ,'=');"><td>km/hr<td><img alt="<" src="icons/waypoint-left.png" title="-" onmousedown="formSetSpeed('residential' ,'-');">–/+<img alt=">" src="icons/waypoint-right.png" title="+" onmousedown="formSetSpeed('residential' ,'+');">
+<tr><td>Dojazdowa: <td><input name="speed-service" type="text" size="3" onchange="formSetSpeed('service' ,'=');"><td>km/hr<td><img alt="<" src="icons/waypoint-left.png" title="-" onmousedown="formSetSpeed('service' ,'-');">–/+<img alt=">" src="icons/waypoint-right.png" title="+" onmousedown="formSetSpeed('service' ,'+');">
 <tr><td>Track: <td><input name="speed-track" type="text" size="3" onchange="formSetSpeed('track' ,'=');"><td>km/hr<td><img alt="<" src="icons/waypoint-left.png" title="-" onmousedown="formSetSpeed('track' ,'-');">–/+<img alt=">" src="icons/waypoint-right.png" title="+" onmousedown="formSetSpeed('track' ,'+');">
-<tr><td>Cycleway: <td><input name="speed-cycleway" type="text" size="3" onchange="formSetSpeed('cycleway' ,'=');"><td>km/hr<td><img alt="<" src="icons/waypoint-left.png" title="-" onmousedown="formSetSpeed('cycleway' ,'-');">–/+<img alt=">" src="icons/waypoint-right.png" title="+" onmousedown="formSetSpeed('cycleway' ,'+');">
-<tr><td>Path: <td><input name="speed-path" type="text" size="3" onchange="formSetSpeed('path' ,'=');"><td>km/hr<td><img alt="<" src="icons/waypoint-left.png" title="-" onmousedown="formSetSpeed('path' ,'-');">–/+<img alt=">" src="icons/waypoint-right.png" title="+" onmousedown="formSetSpeed('path' ,'+');">
+<tr><td>Rowerowa: <td><input name="speed-cycleway" type="text" size="3" onchange="formSetSpeed('cycleway' ,'=');"><td>km/hr<td><img alt="<" src="icons/waypoint-left.png" title="-" onmousedown="formSetSpeed('cycleway' ,'-');">–/+<img alt=">" src="icons/waypoint-right.png" title="+" onmousedown="formSetSpeed('cycleway' ,'+');">
+<tr><td>Ścieżka: <td><input name="speed-path" type="text" size="3" onchange="formSetSpeed('path' ,'=');"><td>km/hr<td><img alt="<" src="icons/waypoint-left.png" title="-" onmousedown="formSetSpeed('path' ,'-');">–/+<img alt=">" src="icons/waypoint-right.png" title="+" onmousedown="formSetSpeed('path' ,'+');">
 <tr><td>Steps: <td><input name="speed-steps" type="text" size="3" onchange="formSetSpeed('steps' ,'=');"><td>km/hr<td><img alt="<" src="icons/waypoint-left.png" title="-" onmousedown="formSetSpeed('steps' ,'-');">–/+<img alt=">" src="icons/waypoint-right.png" title="+" onmousedown="formSetSpeed('steps' ,'+');">
-<tr><td>Ferry: <td><input name="speed-ferry" type="text" size="3" onchange="formSetSpeed('ferry' ,'=');"><td>km/hr<td><img alt="<" src="icons/waypoint-left.png" title="-" onmousedown="formSetSpeed('ferry' ,'-');">–/+<img alt=">" src="icons/waypoint-right.png" title="+" onmousedown="formSetSpeed('ferry' ,'+');">
+<tr><td>Przeprawa: <td><input name="speed-ferry" type="text" size="3" onchange="formSetSpeed('ferry' ,'=');"><td>km/hr<td><img alt="<" src="icons/waypoint-left.png" title="-" onmousedown="formSetSpeed('ferry' ,'-');">–/+<img alt=">" src="icons/waypoint-right.png" title="+" onmousedown="formSetSpeed('ferry' ,'+');">
 </table>
 </div>
 </div>
@@ -223,11 +225,11 @@ Select start and end points (click on the marker icons below), select routing pr
 <div id="hideshow_property_div" style="display: none;">
 <table>
 <tr><td>Paved: <td><input name="property-paved" type="text" size="3" onchange="formSetProperty('paved' ,'=');"><td>%<td><img alt="<" src="icons/waypoint-left.png" title="-" onmousedown="formSetProperty('paved' ,'-');">–/+<img alt=">" src="icons/waypoint-right.png" title="+" onmousedown="formSetProperty('paved' ,'+');">
-<tr><td>Multiple Lanes: <td><input name="property-multilane" type="text" size="3" onchange="formSetProperty('multilane' ,'=');"><td>%<td><img alt="<" src="icons/waypoint-left.png" title="-" onmousedown="formSetProperty('multilane' ,'-');">–/+<img alt=">" src="icons/waypoint-right.png" title="+" onmousedown="formSetProperty('multilane' ,'+');">
-<tr><td>Bridge: <td><input name="property-bridge" type="text" size="3" onchange="formSetProperty('bridge' ,'=');"><td>%<td><img alt="<" src="icons/waypoint-left.png" title="-" onmousedown="formSetProperty('bridge' ,'-');">–/+<img alt=">" src="icons/waypoint-right.png" title="+" onmousedown="formSetProperty('bridge' ,'+');">
-<tr><td>Tunnel: <td><input name="property-tunnel" type="text" size="3" onchange="formSetProperty('tunnel' ,'=');"><td>%<td><img alt="<" src="icons/waypoint-left.png" title="-" onmousedown="formSetProperty('tunnel' ,'-');">–/+<img alt=">" src="icons/waypoint-right.png" title="+" onmousedown="formSetProperty('tunnel' ,'+');">
-<tr><td>Walking Route:<td><input name="property-footroute" type="text" size="3" onchange="formSetProperty('footroute' ,'=');"><td>%<td><img alt="<" src="icons/waypoint-left.png" title="-" onmousedown="formSetProperty('footroute' ,'-');">–/+<img alt=">" src="icons/waypoint-right.png" title="+" onmousedown="formSetProperty('footroute' ,'+');">
-<tr><td>Bicycle Route:<td><input name="property-bicycleroute" type="text" size="3" onchange="formSetProperty('bicycleroute','=');"><td>%<td><img alt="<" src="icons/waypoint-left.png" title="-" onmousedown="formSetProperty('bicycleroute','-');">–/+<img alt=">" src="icons/waypoint-right.png" title="+" onmousedown="formSetProperty('bicycleroute','+');">
+<tr><td>Wiele pasów: <td><input name="property-multilane" type="text" size="3" onchange="formSetProperty('multilane' ,'=');"><td>%<td><img alt="<" src="icons/waypoint-left.png" title="-" onmousedown="formSetProperty('multilane' ,'-');">–/+<img alt=">" src="icons/waypoint-right.png" title="+" onmousedown="formSetProperty('multilane' ,'+');">
+<tr><td>Most: <td><input name="property-bridge" type="text" size="3" onchange="formSetProperty('bridge' ,'=');"><td>%<td><img alt="<" src="icons/waypoint-left.png" title="-" onmousedown="formSetProperty('bridge' ,'-');">–/+<img alt=">" src="icons/waypoint-right.png" title="+" onmousedown="formSetProperty('bridge' ,'+');">
+<tr><td>Tunel: <td><input name="property-tunnel" type="text" size="3" onchange="formSetProperty('tunnel' ,'=');"><td>%<td><img alt="<" src="icons/waypoint-left.png" title="-" onmousedown="formSetProperty('tunnel' ,'-');">–/+<img alt=">" src="icons/waypoint-right.png" title="+" onmousedown="formSetProperty('tunnel' ,'+');">
+<tr><td>Trasa piesza:<td><input name="property-footroute" type="text" size="3" onchange="formSetProperty('footroute' ,'=');"><td>%<td><img alt="<" src="icons/waypoint-left.png" title="-" onmousedown="formSetProperty('footroute' ,'-');">–/+<img alt=">" src="icons/waypoint-right.png" title="+" onmousedown="formSetProperty('footroute' ,'+');">
+<tr><td>Trasa rowerowa:<td><input name="property-bicycleroute" type="text" size="3" onchange="formSetProperty('bicycleroute','=');"><td>%<td><img alt="<" src="icons/waypoint-left.png" title="-" onmousedown="formSetProperty('bicycleroute','-');">–/+<img alt=">" src="icons/waypoint-right.png" title="+" onmousedown="formSetProperty('bicycleroute','+');">
 </table>
 </div>
 </div>
@@ -235,29 +237,29 @@ Select start and end points (click on the marker icons below), select routing pr
 <div class="hideshow_box">
 <span id="hideshow_restriction_show" onclick="hideshow_show('restriction');" class="hideshow_show">+</span>
 <span id="hideshow_restriction_hide" onclick="hideshow_hide('restriction');" class="hideshow_hide">-</span>
-<span class="hideshow_title">Other Restrictions</span>
+<span class="hideshow_title">Inne ograniczenia</span>
 <div id="hideshow_restriction_div" style="display: none;">
 <table>
-<tr><td>Obey oneway streets: <td><input name="restrict-oneway" type="checkbox" onchange="formSetRestriction('oneway');">
-<tr><td>Obey turn restrictions:<td><input name="restrict-turns" type="checkbox" onchange="formSetRestriction('turns' );">
+<tr><td>Respektuj ulice jednokierunkowe:<td><input name="restrict-oneway" type="checkbox" onchange="formSetRestriction('oneway');">
+<tr><td>Respektuj ograniczenia skrętu: <td><input name="restrict-turns" type="checkbox" onchange="formSetRestriction('turns' );">
 </table>
 <table>
-<tr><td>Weight:<td><input name="restrict-weight" type="text" size="3" onchange="formSetRestriction('weight','=');"><td>tonnes<td><img alt="<" src="icons/waypoint-left.png" title="-" onmousedown="formSetRestriction('weight','-');">–/+<img alt=">" src="icons/waypoint-right.png" title="+" onmousedown="formSetRestriction('weight','+');">
-<tr><td>Height:<td><input name="restrict-height" type="text" size="3" onchange="formSetRestriction('height','=');"><td>metres<td><img alt="<" src="icons/waypoint-left.png" title="-" onmousedown="formSetRestriction('height','-');">–/+<img alt=">" src="icons/waypoint-right.png" title="+" onmousedown="formSetRestriction('height','+');">
-<tr><td>Width: <td><input name="restrict-width" type="text" size="3" onchange="formSetRestriction('width' ,'=');"><td>metres<td><img alt="<" src="icons/waypoint-left.png" title="-" onmousedown="formSetRestriction('width' ,'-');">–/+<img alt=">" src="icons/waypoint-right.png" title="+" onmousedown="formSetRestriction('width' ,'+');">
-<tr><td>Length:<td><input name="restrict-length" type="text" size="3" onchange="formSetRestriction('length','=');"><td>metres<td><img alt="<" src="icons/waypoint-left.png" title="-" onmousedown="formSetRestriction('length','-');">–/+<img alt=">" src="icons/waypoint-right.png" title="+" onmousedown="formSetRestriction('length','+');">
+<tr><td>Waga:<td><input name="restrict-weight" type="text" size="3" onchange="formSetRestriction('weight','=');"><td>tonnes<td><img alt="<" src="icons/waypoint-left.png" title="-" onmousedown="formSetRestriction('weight','-');">–/+<img alt=">" src="icons/waypoint-right.png" title="+" onmousedown="formSetRestriction('weight','+');">
+<tr><td>Wysokość:<td><input name="restrict-height" type="text" size="3" onchange="formSetRestriction('height','=');"><td>metres<td><img alt="<" src="icons/waypoint-left.png" title="-" onmousedown="formSetRestriction('height','-');">–/+<img alt=">" src="icons/waypoint-right.png" title="+" onmousedown="formSetRestriction('height','+');">
+<tr><td>Szerokość: <td><input name="restrict-width" type="text" size="3" onchange="formSetRestriction('width' ,'=');"><td>metres<td><img alt="<" src="icons/waypoint-left.png" title="-" onmousedown="formSetRestriction('width' ,'-');">–/+<img alt=">" src="icons/waypoint-right.png" title="+" onmousedown="formSetRestriction('width' ,'+');">
+<tr><td>Długość:<td><input name="restrict-length" type="text" size="3" onchange="formSetRestriction('length','=');"><td>metres<td><img alt="<" src="icons/waypoint-left.png" title="-" onmousedown="formSetRestriction('length','-');">–/+<img alt=">" src="icons/waypoint-right.png" title="+" onmousedown="formSetRestriction('length','+');">
 </table>
 </div>
 </div>
 
 <div class="hideshow_box">
-<span class="hideshow_title">Find</span>
-<input type="button" title="Find shortest route" id="shortest" value="Shortest Route" onclick="findRoute('shortest');" disabled="disabled">
-<input type="button" title="Find quickest route" id="quickest" value="Quickest Route" onclick="findRoute('quickest');" disabled="disabled">
+<span class="hideshow_title">Znajdź</span>
+<input type="button" title="Znajdź najkrótsza trasę" id="shortest" value="Najkrótsza trasa" onclick="findRoute('shortest');" disabled="disabled">
+<input type="button" title="Znajdź najdłuższą trasę" id="quickest" value="Najszybsza trasa" onclick="findRoute('quickest');" disabled="disabled">
 </div>
 
 <div class="hideshow_box">
-<span class="hideshow_title">Links</span>
+<span class="hideshow_title">Połączenia</span>
 <a id="permalink_url" href="router.html">Link to this map view</a>
 <br>
 <a id="edit_url" target="edit" style="display: none;">Edit this OSM data</a>
@@ -266,7 +268,7 @@ Select start and end points (click on the marker icons below), select routing pr
 <div class="hideshow_box">
 <span id="hideshow_help_options_show" onclick="hideshow_show('help_options');" class="hideshow_hide">+</span>
 <span id="hideshow_help_options_hide" onclick="hideshow_hide('help_options');" class="hideshow_show">-</span>
-<span class="hideshow_title">Help</span>
+<span class="hideshow_title">Pomoc</span>
 <div id="hideshow_help_options_div">
 <div class="scrollable">
 <b>Quick Start</b>
@@ -334,23 +336,23 @@ one-way restrictions (e.g. if walking).
 <span class="hideshow_title">Status</span>
 <div id="result_status">
 <div id="result_status_not_run">
-<b><i>Router not run</i></b>
+<b><i>Nie uruchomiono wyznaczania trasy</i></b>
 </div>
 <div id="result_status_running" style="display: none;">
-<b>Router running...</b>
+<b>Wyznaczanie trasy w trakcie...</b>
 </div>
 <div id="result_status_complete" style="display: none;">
-<b>Routing completed</b>
+<b>Trasa wyznaczona</b>
 <br>
-<a id="router_log_complete" target="router_log" href="#">View Details</a>
+<a id="router_log_complete" target="router_log" href="#">Zobacz szczegóły</a>
 </div>
 <div id="result_status_error" style="display: none;">
-<b>Router error</b>
+<b>Błąd wyznaczania trasy</b>
 <br>
-<a id="router_log_error" target="router_log" href="#">View Details</a>
+<a id="router_log_error" target="router_log" href="#">Zobacz szczegóły</a>
 </div>
 <div id="result_status_failed" style="display: none;">
-<b>Router failed to run</b>
+<b>Błąd uruchomienia wyznaczania trasy</b>
 </div>
 </div>
 </div>
@@ -358,10 +360,10 @@ one-way restrictions (e.g. if walking).
 <div class="hideshow_box">
 <span id="hideshow_shortest_show" onclick="hideshow_show('shortest');" class="hideshow_show">+</span>
 <span id="hideshow_shortest_hide" onclick="hideshow_hide('shortest');" class="hideshow_hide">-</span>
-<span class="hideshow_title">Shortest Route</span>
+<span class="hideshow_title">Najkrótsza trasa</span>
 <div id="shortest_status">
 <div id="shortest_status_no_info">
-<b><i>No Information</i></b>
+<b><i>Brak informacji</i></b>
 </div>
 <div id="shortest_status_info" style="display: none;">
 </div>
@@ -370,10 +372,10 @@ one-way restrictions (e.g. if walking).
 <div id="shortest_links" style="display: none;">
 <table>
 <tr><td>HTML directions: <td><a id="shortest_html" target="shortest_html" href="#">Open Popup</a>
-<tr><td>GPX track file: <td><a id="shortest_gpx_track" target="shortest_gpx_track" href="#">Open Popup</a>
-<tr><td>GPX route file: <td><a id="shortest_gpx_route" target="shortest_gpx_route" href="#">Open Popup</a>
+<tr><td>Plik trasy w formacie GPX: <td><a id="shortest_gpx_track" target="shortest_gpx_track" href="#">Open Popup</a>
+<tr><td>Plik nawigacji w formacie GPX: <td><a id="shortest_gpx_route" target="shortest_gpx_route" href="#">Open Popup</a>
 <tr><td>Full text file: <td><a id="shortest_text_all" target="shortest_text_all" href="#">Open Popup</a>
-<tr><td>Text file: <td><a id="shortest_text" target="shortest_text" href="#">Open Popup</a>
+<tr><td>Plik tekstowy: <td><a id="shortest_text" target="shortest_text" href="#">Open Popup</a>
 </table>
 <hr>
 </div>
@@ -385,10 +387,10 @@ one-way restrictions (e.g. if walking).
 <div class="hideshow_box">
 <span id="hideshow_quickest_show" onclick="hideshow_show('quickest');" class="hideshow_show">+</span>
 <span id="hideshow_quickest_hide" onclick="hideshow_hide('quickest');" class="hideshow_hide">-</span>
-<span class="hideshow_title">Quickest Route</span>
+<span class="hideshow_title">Najszybsza trasa</span>
 <div id="quickest_status">
 <div id="quickest_status_no_info">
-<b><i>No Information</i></b>
+<b><i>Brak informacji</i></b>
 </div>
 <div id="quickest_status_info" style="display: none;">
 </div>
@@ -397,10 +399,10 @@ one-way restrictions (e.g. if walking).
 <div id="quickest_links" style="display: none;">
 <table>
 <tr><td>HTML directions: <td><a id="quickest_html" target="quickest_html" href="#">Open Popup</a>
-<tr><td>GPX track file: <td><a id="quickest_gpx_track" target="quickest_gpx_track" href="#">Open Popup</a>
-<tr><td>GPX route file: <td><a id="quickest_gpx_route" target="quickest_gpx_route" href="#">Open Popup</a>
+<tr><td>Plik trasy w formacie GPX: <td><a id="quickest_gpx_track" target="quickest_gpx_track" href="#">Open Popup</a>
+<tr><td>Plik nawigacji w formacie GPX: <td><a id="quickest_gpx_route" target="quickest_gpx_route" href="#">Open Popup</a>
 <tr><td>Full text file: <td><a id="quickest_text_all" target="quickest_text_all" href="#">Open Popup</a>
-<tr><td>Text file: <td><a id="quickest_text" target="quickest_text" href="#">Open Popup</a>
+<tr><td>Plik tekstowy: <td><a id="quickest_text" target="quickest_text" href="#">Open Popup</a>
 </table>
 <hr>
 </div>
@@ -412,7 +414,7 @@ one-way restrictions (e.g. if walking).
 <div class="hideshow_box">
 <span id="hideshow_help_route_show" onclick="hideshow_show('help_route');" class="hideshow_hide">+</span>
 <span id="hideshow_help_route_hide" onclick="hideshow_hide('help_route');" class="hideshow_show">-</span>
-<span class="hideshow_title">Help</span>
+<span class="hideshow_title">Pomoc</span>
 <div id="hideshow_help_route_div">
 <div class="scrollable">
 <b>Quick Start</b>
@@ -455,13 +457,13 @@ route.
 
 <div class="tab_content" id="tab_data_div" style="display: none;">
 <div class="hideshow_box">
-<span class="hideshow_title">Routino Statistics</span>
+<span class="hideshow_title">Statystyki Routino</span>
 <div id="statistics_data"></div>
 <a id="statistics_link" href="statistics.cgi" onclick="displayStatistics();return(false);">Display data statistics</a>
 </div>
 
 <div class="hideshow_box">
-<span class="hideshow_title">Routino Visualiser</span>
+<span class="hideshow_title">Wizualizer Routino</span>
 To see Routino's view of the data there is a data visualiser that allows
 displaying of the underlying data in various ways.
 <br>
@@ -485,7 +487,7 @@ Router: <a href="http://www.routino.org/" target="routino">Routino</a>
 |
 Geo Data: <span id="attribution_data"></span>
 |
-Tiles: <span id="attribution_tile"></span>
+Kafelki: <span id="attribution_tile"></span>
 </div>
 </div>
 
diff --git a/web/www/routino/router.html.ru b/web/www/routino/router.html.ru
index 8da81b2..ebdc074 100644
--- a/web/www/routino/router.html.ru
+++ b/web/www/routino/router.html.ru
@@ -13,7 +13,7 @@ Routino router web page.
 
 Part of the Routino routing software.
 
-This file Copyright 2008-2014 Andrew M. Bishop
+This file Copyright 2008-2015 Andrew M. Bishop
 
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU Affero General Public License as published by
@@ -93,10 +93,18 @@ Select start and end points (click on the marker icons below), select routing pr
 <td>(FR)
 <td><input name="language" type="radio" value="fr" onchange="formSetLanguage();" >
 <tr>
+<td><a id="lang_hu_url" href="router.html.hu" title="Magyar weblap">Magyar</a>
+<td>(HU)
+<td><input name="language" type="radio" value="hu" onchange="formSetLanguage();" >
+<tr>
 <td><a id="lang_nl_url" href="router.html.nl" title="Nederlandse web pagina">Nederlands</a>
 <td>(NL)
 <td><input name="language" type="radio" value="nl" onchange="formSetLanguage();" >
 <tr>
+<td><a id="lang_pl_url" href="router.html.pl" title="Polski webpage">Polski</a>
+<td>(PL)
+<td><input name="language" type="radio" value="pl" onchange="formSetLanguage();" >
+<tr>
 <td><a id="lang_ru_url" href="router.html.ru" title="Русский">Русский</a>
 <td>(RU)
 <td><input name="language" type="radio" value="ru" onchange="formSetLanguage();" checked>
@@ -110,16 +118,9 @@ Select start and end points (click on the marker icons below), select routing pr
 <span id="hideshow_waypoint_hide" onclick="hideshow_hide('waypoint');" class="hideshow_show">-</span>
 <span class="hideshow_title">Waypoints</span>
 <div id="hideshow_waypoint_div">
-<table id="waypoints">
-<colgroup>
-<col style="width: 22px;">
-<col>
-<col style="width: 76px;">
-</colgroup>
-<tr id="waypointXXX" style="display: none;">
-<td>
-<img id="iconXXX" src="icons/marker-XXX-grey.png" title="Waypoint XXX Position - (click to add/remove on map)" alt="Waypoint XXX" onmousedown="markerToggleMap(XXX);">
-<td>
+<div id="waypoints">
+<div id="waypointXXX" class="waypoint" style="display: none;">
+<img id="iconXXX" class="waypoint-icon" src="icons/marker-XXX-grey.png" title="Waypoint XXX Position" alt="Waypoint XXX" onmouseup="markerToggleMap(XXX);" draggable="true">
 <span id="coordsXXX">
 <input name="lonXXX" type="text" size="7" title="Waypoint XXX Longitude" onchange="formSetCoords(XXX);">E
 <input name="latXXX" type="text" size="7" title="Waypoint XXX Latitude" onchange="formSetCoords(XXX);">N
@@ -127,7 +128,7 @@ Select start and end points (click on the marker icons below), select routing pr
 <span id="searchXXX" style="display: none;">
 <input name="searchXXX" type="text" size="18" title="Waypoint XXX Location"> <!-- uses Javascript event for triggering -->
 </span>
-<td>
+<div class="waypoint-buttons" style="display: inline-block;">
 <img alt="?" src="icons/waypoint-search.png" title="Search for location" onmousedown="markerSearch(XXX);" >
 <img alt="G" src="icons/waypoint-locate.png" title="Get current location" onmousedown="markerLocate(XXX);" >
 <img alt="O" src="icons/waypoint-recentre.png" title="Centre map on this waypoint" onmousedown="markerRecentre(XXX);">
@@ -139,14 +140,15 @@ Select start and end points (click on the marker icons below), select routing pr
 <img alt="o" src="icons/waypoint-centre.png" title="Centre this waypoint on map" onmousedown="markerCentre(XXX);" >
 <img alt="v" src="icons/waypoint-down.png" title="Move this waypoint down" onmousedown="markerMoveDown(XXX);">
 <img alt="-" src="icons/waypoint-remove.png" title="Remove this waypoint" onmousedown="markerRemove(XXX);" >
-<tr id="searchresultsXXX" style="display: none;">
-<td colspan="3">
-<!-- The waypoints are inserted by the JavaScript, see the "maxmarkers" variable in router.js. -->
-<tr>
-<td colspan="3" class="center">
+</div>
+<div id="searchresultsXXX" style="display: none;">
+</div>
+</div>
+</div>
+<div id="waypoints-buttons" class="center">
 <input type="button" title="Reverse order of waypoints" value="Reverse order" onmousedown="markersReverse();">
 <input type="button" title="Add a new waypoint to make a loop" value="Close loop" onmousedown="markersLoop();">
-</table>
+</div>
 </div>
 </div>
 
@@ -238,8 +240,8 @@ Select start and end points (click on the marker icons below), select routing pr
 <span class="hideshow_title">Другие ограничения</span>
 <div id="hideshow_restriction_div" style="display: none;">
 <table>
-<tr><td>Односторонняя улица: <td><input name="restrict-oneway" type="checkbox" onchange="formSetRestriction('oneway');">
-<tr><td>Obey turn restrictions:<td><input name="restrict-turns" type="checkbox" onchange="formSetRestriction('turns' );">
+<tr><td>Односторонняя улица:<td><input name="restrict-oneway" type="checkbox" onchange="formSetRestriction('oneway');">
+<tr><td>Obey turn restrictions: <td><input name="restrict-turns" type="checkbox" onchange="formSetRestriction('turns' );">
 </table>
 <table>
 <tr><td>Вес:<td><input name="restrict-weight" type="text" size="3" onchange="formSetRestriction('weight','=');"><td>tonnes<td><img alt="<" src="icons/waypoint-left.png" title="-" onmousedown="formSetRestriction('weight','-');">–/+<img alt=">" src="icons/waypoint-right.png" title="+" onmousedown="formSetRestriction('weight','+');">
diff --git a/web/www/routino/router.leaflet.js b/web/www/routino/router.leaflet.js
index a3b2328..9954ccd 100644
--- a/web/www/routino/router.leaflet.js
+++ b/web/www/routino/router.leaflet.js
@@ -3,7 +3,7 @@
 //
 // Part of the Routino routing software.
 //
-// This file Copyright 2008-2014 Andrew M. Bishop
+// This file Copyright 2008-2015 Andrew M. Bishop
 //
 // This program is free software: you can redistribute it and/or modify
 // it under the terms of the GNU Affero General Public License as published by
@@ -119,26 +119,33 @@ function html_init()            // called from router.html
 {
  var waypoints=document.getElementById("waypoints");
 
- var waypoint_html=waypoints.rows[0].innerHTML;
- waypoints.deleteRow(0);
+ var waypoint_html=waypoints.firstElementChild.outerHTML.split("XXX");
 
- var searchresults_html=waypoints.rows[0].innerHTML;
- waypoints.deleteRow(0);
+ waypoints.removeChild(waypoints.firstElementChild);
 
- for(var marker=mapprops.maxmarkers;marker>=1;marker--)
+ for(var marker=1;marker<=mapprops.maxmarkers;marker++)
    {
-    var searchresults=waypoints.insertRow(0);
+    var waypoint=document.createElement('div');
 
-    searchresults.style.display="none";
-    searchresults.id="searchresults" + marker;
-    searchresults.innerHTML=searchresults_html.split("XXX").join(marker);
+    waypoints.appendChild(waypoint);
 
-    var waypoint=waypoints.insertRow(0);
-
-    waypoint.style.display="none";
-    waypoint.id="waypoint" + marker;
-    waypoint.innerHTML=waypoint_html.split("XXX").join(marker);
+    waypoint.outerHTML=waypoint_html.join(marker);
    }
+
+ waypoints.addEventListener('dragstart',dragWaypointStart,false);
+ waypoints.addEventListener('dragend'  ,dragWaypointEnd  ,false);
+ waypoints.addEventListener('dragenter',dragWaypointEnter,false);
+ waypoints.addEventListener('dragover' ,dragWaypointOver ,false);
+ waypoints.addEventListener('dragleave',dragWaypointLeave,false);
+ waypoints.addEventListener('drop'     ,dragWaypointDrop ,false);
+
+
+ var map=document.getElementById("map");
+
+ map.addEventListener('dragenter',dragWaypointMapEnter,false);
+ map.addEventListener('dragover' ,dragWaypointMapOver ,false);
+ map.addEventListener('dragleave',dragWaypointMapLeave,false);
+ map.addEventListener('drop'     ,dragWaypointMapDrop ,false);
 }
 
 
@@ -645,8 +652,8 @@ function buildURLArguments(lang)
  for(var marker=1;marker<=vismarkers;marker++)
     if(routino.point[marker].active)
       {
-       url=url + ";lon" + marker + "=" + routino.point[marker].lon;
-       url=url + ";lat" + marker + "=" + routino.point[marker].lat;
+       url=url + ";lon" + marker + "=" + format5f(routino.point[marker].lon);
+       url=url + ";lat" + marker + "=" + format5f(routino.point[marker].lat);
        if(routino.point[marker].search !== "")
           url=url + ";search" + marker + "=" + encodeURIComponent(routino.point[marker].search);
       }
@@ -819,8 +826,8 @@ function map_init()             // called from router.html
 
     markers[marker]=L.marker(L.point(0,0), {clickable: true, draggable: true, icon: icons[marker]});
 
-    markers[marker].on("drag"   , (function(m) { return function(evt) { dragMove    (m,evt); }; }(marker)));
-    markers[marker].on("dragend", (function(m) { return function(evt) { dragComplete(m,evt); }; }(marker)));
+    markers[marker].on("drag"   , (function(m) { return function(evt) { dragMarkerMove    (m,evt); }; }(marker)));
+    markers[marker].on("dragend", (function(m) { return function(evt) { dragMarkerComplete(m,evt); }; }(marker)));
    }
 
  icons.home=L.icon({iconUrl: "icons/marker-home-red.png",
@@ -879,39 +886,204 @@ function map_init()             // called from router.html
 
 
 //
-// Callback for a drag occuring.
+// Callback for a marker drag occuring on the map.
 //
 
-function dragMove(marker,event)
+function dragMarkerMove(marker,event)
 {
- dragSetForm(marker);
+ dragMarkerSetForm(marker);
 }
 
 
 //
-// Callback for completing a drag.
+// Callback for completing a drag occuring on the map.
 //
 
-function dragComplete(marker,event)
+function dragMarkerComplete(marker,event)
 {
- dragSetForm(marker);
+ dragMarkerSetForm(marker);
 
  updateURLs();
 }
 
 
 //
-// Set the feature coordinates in the form after dragging.
+// Set the feature coordinates in the form after dragging it on the map.
 //
 
-function dragSetForm(marker)
+function dragMarkerSetForm(marker)
 {
  var lonlat = markers[marker].getLatLng();
 
- var lon=format5f(lonlat.lng);
- var lat=format5f(lonlat.lat);
+ formSetCoords(marker,lonlat.lng,lonlat.lat);
+}
+
+
+////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////// Marker dragging ////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
+
+var dragged_waypoint=null,dragged_marker=null;
+var dragged_waypoint_over=null,dragged_marker_over=null;
+ var dragged_icon_x,dragged_icon_y;
+
+//
+// Drag a waypoint up or down the list.
+//
+
+function dragWaypointStart(e)
+{
+ var w=e.target;
+
+ while(w!=null && w.className != "waypoint")
+    w=w.parentElement;
+
+ if(w===null)
+    return;
+
+ w.style.opacity = "0.5";
+
+ dragged_waypoint=w;
+ dragged_marker=Number.parseInt(dragged_waypoint.id.substring(8));
+
+ dragged_icon_x=e.clientX-e.target.offsetLeft;
+ dragged_icon_y=e.clientY-e.target.offsetTop;
+}
+
+function dragWaypointEnd(e)
+{
+ e.preventDefault();
+
+ if(dragged_waypoint===null)
+    return;
+
+ dragged_waypoint.style.opacity = "";
+
+ dragged_waypoint=null;
+ dragged_marker=null;
+
+ if(dragged_waypoint_over===null)
+    return;
+
+ dragged_waypoint_over.style.border = "";
+
+ dragged_waypoint_over=null;
+ dragged_marker_over=null;
+}
+
+
+//
+// Drag a waypoint over another one up or down the list.
+//
+
+function dragWaypointEnter(e)
+{
+ var w=e.target;
+
+ while(w!=null && w.className != "waypoint")
+    w=w.parentElement;
+
+ if(w===null)
+    return;
+
+ if(dragged_waypoint_over!==null)
+    dragged_waypoint_over.style.border = "";
+
+ if(w==dragged_waypoint)
+    return;
+
+ dragged_waypoint_over=w;
+ dragged_marker_over=Number.parseInt(dragged_waypoint_over.id.substring(8));
+
+ if(dragged_marker>dragged_marker_over)
+    w.style.borderTop = "3px solid black";
+ else
+    w.style.borderBottom = "3px solid black";
+}
+
+function dragWaypointOver(e)
+{
+ e.preventDefault();
+}
+
+function dragWaypointLeave(e)
+{
+ var w=e.target;
+
+ while(w!=null && w.className != "waypoint")
+    w=w.parentElement;
+
+ if(w===null)
+    return;
 
- formSetCoords(marker,lon,lat);
+ if(w==dragged_waypoint_over)
+    return;
+
+ w.style.border = "";
+}
+
+
+//
+// Drop the waypoint after dragging up or down the list.
+//
+
+function dragWaypointDrop(e)
+{
+ e.preventDefault();
+
+ if(dragged_marker_over===null)
+    return;
+
+ if(dragged_marker_over>dragged_marker)
+    for(var m=dragged_marker;m<dragged_marker_over;m++)
+       markerSwap(m,m+1);
+
+ if(dragged_marker_over<dragged_marker)
+    for(var m=dragged_marker;m>dragged_marker_over;m--)
+       markerSwap(m,m-1);
+}
+
+
+//
+// Drag a waypoint over the map.
+//
+
+function dragWaypointMapEnter(e)
+{
+ e.preventDefault();
+
+ if(dragged_waypoint_over!==null)
+    dragged_waypoint_over.style.border = "";
+}
+
+function dragWaypointMapOver(e)
+{
+ e.preventDefault();
+}
+
+function dragWaypointMapLeave(e)
+{
+ e.preventDefault();
+}
+
+
+//
+// Drop the waypoint after dragging it over the map.
+//
+
+function dragWaypointMapDrop(e)
+{
+ e.preventDefault();
+
+ var rect = document.getElementById("map").getBoundingClientRect();
+
+ var lonlat=map.containerPointToLatLng(L.point(e.clientX-rect.left-window.scrollX-dragged_icon_x+8,
+                                               e.clientY-rect.top -window.scrollY-dragged_icon_y+21));
+
+ formSetCoords(dragged_marker,lonlat.lng,lonlat.lat);
+
+ if(!routino.point[dragged_marker].active)
+    markerToggleMap(dragged_marker);
 }
 
 
@@ -919,7 +1091,6 @@ function dragSetForm(marker)
 /////////////////////////////// Marker handling ////////////////////////////////
 ////////////////////////////////////////////////////////////////////////////////
 
-
 //
 // Toggle a marker on the map.
 //
@@ -1030,7 +1201,7 @@ function markerCentre(marker)   // called from router.html
 
  var lonlat=map.getCenter();
 
- formSetCoords(marker,format5f(lonlat.lng),format5f(lonlat.lat));
+ formSetCoords(marker,lonlat.lng,lonlat.lat);
 }
 
 
@@ -1872,7 +2043,7 @@ function getRouteSuccess(response)
 
        if(rowtype=="c")
          {
-          thisline.match("<td class='r'> *([-0-9.]+) *([-0-9.]+)");
+          thisline.match(": *([-0-9.]+) *([-0-9.]+)");
           points[point]={lat: Number(RegExp.$1), lon: Number(RegExp.$2), html: "", highway: "", distance: "", total: ""};
 
           point++;
@@ -1900,14 +2071,11 @@ function getRouteSuccess(response)
          {
           points[point-1].html += thisline;
 
-          thisline.match("^(.*<td class='r'>)");
-          total_table = RegExp.$1;
-
-          thisline.match("<td class='l'>([^<]+)<");
-          total_word = RegExp.$1;
-
           thisline.match("<span class='j'>([^<]+)</span>");
           points[point-1].total = RegExp.$1;
+
+          thisline.match("<td>(.*)");
+          points[point-1].highway = RegExp.$1;
          }
       }
    }
@@ -1916,9 +2084,10 @@ function getRouteSuccess(response)
 
  var result="<table onmouseout='highlight(\"" + routing_type + "\",-1,\"clear\")'>";
 
- for(var p=0;p<point-1;p++)
+ for(var p=0;p<point;p++)
    {
-    points[p].html += total_table + points[p].total;
+    if(p!=point-1)
+       points[p].html += "<tr><td>" + points[p].total;
 
     result=result + "<tr onmouseover='highlight(\"" + routing_type + "\"," + p + ",\"show\")'>" +
                     "<td onclick='highlight(\"" + routing_type + "\"," + p + ",\"zoom\")'" +
@@ -1926,11 +2095,6 @@ function getRouteSuccess(response)
                     "<td class='highway'>" + points[p].highway;
    }
 
- result=result + "<tr onmouseover='highlight(\"" + routing_type + "\"," + p + ",\"show\")'>" +
-                 "<td onclick='highlight(\"" + routing_type + "\"," + p + ",\"zoom\")'" +
-                 " class='distance'>#" + (p+1) +
-                 "<td class='highway'>" + total_word + " " + points[p].total;
-
  result=result + "</table>";
 
  document.getElementById(routing_type + "_route").innerHTML=result;
diff --git a/web/www/routino/router.openlayers.js b/web/www/routino/router.openlayers.js
index 0ef7d88..62c8e8c 100644
--- a/web/www/routino/router.openlayers.js
+++ b/web/www/routino/router.openlayers.js
@@ -3,7 +3,7 @@
 //
 // Part of the Routino routing software.
 //
-// This file Copyright 2008-2014 Andrew M. Bishop
+// This file Copyright 2008-2015 Andrew M. Bishop
 //
 // This program is free software: you can redistribute it and/or modify
 // it under the terms of the GNU Affero General Public License as published by
@@ -119,26 +119,33 @@ function html_init()            // called from router.html
 {
  var waypoints=document.getElementById("waypoints");
 
- var waypoint_html=waypoints.rows[0].innerHTML;
- waypoints.deleteRow(0);
+ var waypoint_html=waypoints.firstElementChild.outerHTML.split("XXX");
 
- var searchresults_html=waypoints.rows[0].innerHTML;
- waypoints.deleteRow(0);
+ waypoints.removeChild(waypoints.firstElementChild);
 
- for(var marker=mapprops.maxmarkers;marker>=1;marker--)
+ for(var marker=1;marker<=mapprops.maxmarkers;marker++)
    {
-    var searchresults=waypoints.insertRow(0);
+    var waypoint=document.createElement('div');
 
-    searchresults.style.display="none";
-    searchresults.id="searchresults" + marker;
-    searchresults.innerHTML=searchresults_html.split("XXX").join(marker);
+    waypoints.appendChild(waypoint);
 
-    var waypoint=waypoints.insertRow(0);
-
-    waypoint.style.display="none";
-    waypoint.id="waypoint" + marker;
-    waypoint.innerHTML=waypoint_html.split("XXX").join(marker);
+    waypoint.outerHTML=waypoint_html.join(marker);
    }
+
+ waypoints.addEventListener('dragstart',dragWaypointStart,false);
+ waypoints.addEventListener('dragend'  ,dragWaypointEnd  ,false);
+ waypoints.addEventListener('dragenter',dragWaypointEnter,false);
+ waypoints.addEventListener('dragover' ,dragWaypointOver ,false);
+ waypoints.addEventListener('dragleave',dragWaypointLeave,false);
+ waypoints.addEventListener('drop'     ,dragWaypointDrop ,false);
+
+
+ var map=document.getElementById("map");
+
+ map.addEventListener('dragenter',dragWaypointMapEnter,false);
+ map.addEventListener('dragover' ,dragWaypointMapOver ,false);
+ map.addEventListener('dragleave',dragWaypointMapLeave,false);
+ map.addEventListener('drop'     ,dragWaypointMapDrop ,false);
 }
 
 
@@ -648,8 +655,8 @@ function buildURLArguments(lang)
  for(var marker=1;marker<=vismarkers;marker++)
     if(routino.point[marker].active)
       {
-       url=url + ";lon" + marker + "=" + routino.point[marker].lon;
-       url=url + ";lat" + marker + "=" + routino.point[marker].lat;
+       url=url + ";lon" + marker + "=" + format5f(routino.point[marker].lon);
+       url=url + ";lat" + marker + "=" + format5f(routino.point[marker].lat);
        if(routino.point[marker].search !== "")
           url=url + ";search" + marker + "=" + encodeURIComponent(routino.point[marker].search);
       }
@@ -871,8 +878,8 @@ function map_init()             // called from router.html
  // A function to drag the markers
 
  var drag = new OpenLayers.Control.DragFeature(layerVectors,
-                                               {onDrag:     dragMove,
-                                                onComplete: dragComplete });
+                                               {onDrag:     dragMarkerMove,
+                                                onComplete: dragMarkerComplete });
  map.addControl(drag);
  drag.activate();
 
@@ -941,44 +948,210 @@ function map_init()             // called from router.html
 
 
 //
-// Callback for a drag occuring.
+// Callback for a marker drag occuring on the map.
 //
 
-function dragMove(feature,pixel)
+function dragMarkerMove(feature,pixel)
 {
  for(var marker in markers)
     if(feature==markers[marker])
-       dragSetForm(marker);
+       dragMarkerSetForm(marker);
 }
 
 
 //
-// Callback for completing a drag.
+// Callback for completing a marker drag on the map.
 //
 
-function dragComplete(feature,pixel)
+function dragMarkerComplete(feature,pixel)
 {
  for(var marker in markers)
     if(feature==markers[marker])
-       dragSetForm(marker);
+       dragMarkerSetForm(marker);
 
  updateURLs();
 }
 
 
 //
-// Set the feature coordinates in the form after dragging.
+// Set the feature coordinates in the form after dragging it on the map.
 //
 
-function dragSetForm(marker)
+function dragMarkerSetForm(marker)
 {
  var lonlat = new OpenLayers.LonLat(markers[marker].geometry.x, markers[marker].geometry.y);
  lonlat.transform(epsg900913,epsg4326);
 
- var lon=format5f(lonlat.lon);
- var lat=format5f(lonlat.lat);
+ formSetCoords(marker,lonlat.lon,lonlat.lat);
+}
+
+
+////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////// Marker dragging ////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
+
+var dragged_waypoint=null,dragged_marker=null;
+var dragged_waypoint_over=null,dragged_marker_over=null;
+var dragged_icon_x,dragged_icon_y;
+
+//
+// Drag a waypoint up or down the list.
+//
+
+function dragWaypointStart(e)
+{
+ var w=e.target;
+
+ while(w!=null && w.className != "waypoint")
+    w=w.parentElement;
+
+ if(w===null)
+    return;
+
+ w.style.opacity = "0.5";
+
+ dragged_waypoint=w;
+ dragged_marker=Number.parseInt(dragged_waypoint.id.substring(8));
+
+ dragged_icon_x=e.clientX-e.target.offsetLeft;
+ dragged_icon_y=e.clientY-e.target.offsetTop;
+}
+
+function dragWaypointEnd(e)
+{
+ e.preventDefault();
+
+ if(dragged_waypoint===null)
+    return;
+
+ dragged_waypoint.style.opacity = "";
+
+ dragged_waypoint=null;
+ dragged_marker=null;
+
+ if(dragged_waypoint_over===null)
+    return;
+
+ dragged_waypoint_over.style.border = "";
 
- formSetCoords(marker,lon,lat);
+ dragged_waypoint_over=null;
+ dragged_marker_over=null;
+}
+
+
+//
+// Drag a waypoint over another one up or down the list.
+//
+
+function dragWaypointEnter(e)
+{
+ var w=e.target;
+
+ while(w!=null && w.className != "waypoint")
+    w=w.parentElement;
+
+ if(w===null)
+    return;
+
+ if(dragged_waypoint_over!==null)
+    dragged_waypoint_over.style.border = "";
+
+ if(w==dragged_waypoint)
+    return;
+
+ dragged_waypoint_over=w;
+ dragged_marker_over=Number.parseInt(dragged_waypoint_over.id.substring(8));
+
+ if(dragged_marker>dragged_marker_over)
+    w.style.borderTop = "3px solid black";
+ else
+    w.style.borderBottom = "3px solid black";
+}
+
+function dragWaypointOver(e)
+{
+ e.preventDefault();
+}
+
+function dragWaypointLeave(e)
+{
+ var w=e.target;
+
+ while(w!=null && w.className != "waypoint")
+    w=w.parentElement;
+
+ if(w===null)
+    return;
+
+ if(w==dragged_waypoint_over)
+    return;
+
+ w.style.border = "";
+}
+
+
+//
+// Drop the waypoint after dragging up or down the list.
+//
+
+function dragWaypointDrop(e)
+{
+ e.preventDefault();
+
+ if(dragged_marker_over===null)
+    return;
+
+ if(dragged_marker_over>dragged_marker)
+    for(var m=dragged_marker;m<dragged_marker_over;m++)
+       markerSwap(m,m+1);
+
+ if(dragged_marker_over<dragged_marker)
+    for(var m=dragged_marker;m>dragged_marker_over;m--)
+       markerSwap(m,m-1);
+}
+
+
+//
+// Drag a waypoint over the map.
+//
+
+function dragWaypointMapEnter(e)
+{
+ e.preventDefault();
+
+ if(dragged_waypoint_over!==null)
+    dragged_waypoint_over.style.border = "";
+}
+
+function dragWaypointMapOver(e)
+{
+ e.preventDefault();
+}
+
+function dragWaypointMapLeave(e)
+{
+ e.preventDefault();
+}
+
+
+//
+// Drop the waypoint after dragging it over the map.
+//
+
+function dragWaypointMapDrop(e)
+{
+ e.preventDefault();
+
+ var rect = document.getElementById("map").getBoundingClientRect();
+
+ var lonlat = map.getLonLatFromViewPortPx(new OpenLayers.Pixel(e.clientX-rect.left-window.scrollX-dragged_icon_x+8,
+                                                               e.clientY-rect.top -window.scrollY-dragged_icon_y+21));
+ lonlat.transform(epsg900913,epsg4326);
+
+ formSetCoords(dragged_marker,lonlat.lon,lonlat.lat);
+
+ if(!routino.point[dragged_marker].active)
+    markerToggleMap(dragged_marker);
 }
 
 
@@ -986,7 +1159,6 @@ function dragSetForm(marker)
 /////////////////////////////// Marker handling ////////////////////////////////
 ////////////////////////////////////////////////////////////////////////////////
 
-
 //
 // Toggle a marker on the map.
 //
@@ -1098,7 +1270,7 @@ function markerCentre(marker)   // called from router.html
  var lonlat=map.getCenter().clone();
  lonlat.transform(epsg900913,epsg4326);
 
- formSetCoords(marker,format5f(lonlat.lon),format5f(lonlat.lat));
+ formSetCoords(marker,lonlat.lon,lonlat.lat);
 }
 
 
@@ -1915,7 +2087,7 @@ function getRouteSuccess(response)
 
        if(rowtype=="c")
          {
-          thisline.match("<td class='r'> *([-0-9.]+) *([-0-9.]+)");
+          thisline.match(": *([-0-9.]+) *([-0-9.]+)");
           points[point]={lat: Number(RegExp.$1), lon: Number(RegExp.$2), html: "", highway: "", distance: "", total: ""};
 
           point++;
@@ -1943,14 +2115,11 @@ function getRouteSuccess(response)
          {
           points[point-1].html += thisline;
 
-          thisline.match("^(.*<td class='r'>)");
-          total_table = RegExp.$1;
-
-          thisline.match("<td class='l'>([^<]+)<");
-          total_word = RegExp.$1;
-
           thisline.match("<span class='j'>([^<]+)</span>");
           points[point-1].total = RegExp.$1;
+
+          thisline.match("<td>(.*)");
+          points[point-1].highway = RegExp.$1;
          }
       }
    }
@@ -1959,9 +2128,10 @@ function getRouteSuccess(response)
 
  var result="<table onmouseout='highlight(\"" + routing_type + "\",-1,\"clear\")'>";
 
- for(var p=0;p<point-1;p++)
+ for(var p=0;p<point;p++)
    {
-    points[p].html += total_table + points[p].total;
+    if(p!=point-1)
+       points[p].html += "<tr><td>" + points[p].total;
 
     result=result + "<tr onmouseover='highlight(\"" + routing_type + "\"," + p + ",\"show\")'>" +
                     "<td onclick='highlight(\"" + routing_type + "\"," + p + ",\"zoom\")'" +
@@ -1969,11 +2139,6 @@ function getRouteSuccess(response)
                     "<td class='highway'>" + points[p].highway;
    }
 
- result=result + "<tr onmouseover='highlight(\"" + routing_type + "\"," + p + ",\"show\")'>" +
-                 "<td onclick='highlight(\"" + routing_type + "\"," + p + ",\"zoom\")'" +
-                 " class='distance'>#" + (p+1) +
-                 "<td class='highway'>" + total_word + " " + points[p].total;
-
  result=result + "</table>";
 
  document.getElementById(routing_type + "_route").innerHTML=result;
diff --git a/web/www/routino/visualiser.html.de b/web/www/routino/visualiser.html.de
index b2aa6b6..53cfc96 100644
--- a/web/www/routino/visualiser.html.de
+++ b/web/www/routino/visualiser.html.de
@@ -89,9 +89,15 @@ Only data relevant for routing is displayed and some will therefore be excluded.
 <td><a id="lang_fr_url" href="visualiser.html.fr" title="Francais">Francais</a>
 <td>(FR)
 <tr>
+<td><a id="lang_hu_url" href="visualiser.html.hu" title="Magyar weblap">Magyar</a>
+<td>(HU)
+<tr>
 <td><a id="lang_nl_url" href="visualiser.html.nl" title="Nederlandse web pagina">Nederlands</a>
 <td>(NL)
 <tr>
+<td><a id="lang_pl_url" href="visualiser.html.pl" title="Polski webpage">Polski</a>
+<td>(PL)
+<tr>
 <td><a id="lang_ru_url" href="visualiser.html.ru" title="Русский">Русский</a>
 <td>(RU)
 </table>
@@ -138,7 +144,7 @@ server will only return data if the selected area is small enough.
 <b># Abbiegebeschrängkungen verarbeitet</b>
 </div>
 <div id="result_status_limit" style="display: none;">
-<b>Processed # limit changes</b>
+<b># Limit-Änderungen verarbeitet</b>
 </div>
 <div id="result_status_property" style="display: none;">
 <b># Segmente verarbeitet</b>
@@ -217,7 +223,7 @@ Each segment of the chosen type of highway is drawn.
 <tr><td>Feld-(Wald-)weg: <td><input name="highway" type="radio" value="track" onchange="displayData('highway');">
 <tr><td>Fahrradweg: <td><input name="highway" type="radio" value="cycleway" onchange="displayData('highway');">
 <tr><td>Weg: <td><input name="highway" type="radio" value="path" onchange="displayData('highway');">
-<tr><td>Fußweg: <td><input name="highway" type="radio" value="steps" onchange="displayData('highway');">
+<tr><td>Treppe: <td><input name="highway" type="radio" value="steps" onchange="displayData('highway');">
 <tr><td>Fähre: <td><input name="highway" type="radio" value="ferry" onchange="displayData('highway');">
 </table>
 </form>
@@ -240,8 +246,8 @@ Each segment allowed for the chosen type of transport is drawn.
 <tr><td>Motorrad:<td><input name="transport" type="radio" value="motorcycle" onchange="displayData('transport');">
 <tr><td>Auto: <td><input name="transport" type="radio" value="motorcar" onchange="displayData('transport');" checked>
 <tr><td>LKW: <td><input name="transport" type="radio" value="goods" onchange="displayData('transport');">
-<tr><td>Schwertransport: <td><input name="transport" type="radio" value="hgv" onchange="displayData('transport');">
-<tr><td>Personenverkehr: <td><input name="transport" type="radio" value="psv" onchange="displayData('transport');">
+<tr><td>Schwertransport/LKW: <td><input name="transport" type="radio" value="hgv" onchange="displayData('transport');">
+<tr><td>Öffentlicher Personenverkehr: <td><input name="transport" type="radio" value="psv" onchange="displayData('transport');">
 </table>
 </form>
 </div>
@@ -263,8 +269,8 @@ Each barrier blocking the chosen type of transport is drawn.
 <tr><td>Motorrad:<td><input name="barrier" type="radio" value="motorcycle" onchange="displayData('barrier');">
 <tr><td>Auto: <td><input name="barrier" type="radio" value="motorcar" onchange="displayData('barrier');" checked>
 <tr><td>LKW: <td><input name="barrier" type="radio" value="goods" onchange="displayData('barrier');">
-<tr><td>Schwertransport: <td><input name="barrier" type="radio" value="hgv" onchange="displayData('barrier');">
-<tr><td>Personenverkehr: <td><input name="barrier" type="radio" value="psv" onchange="displayData('barrier');">
+<tr><td>Schwertransport/LKW: <td><input name="barrier" type="radio" value="hgv" onchange="displayData('barrier');">
+<tr><td>Öffentlicher Personenverkehr: <td><input name="barrier" type="radio" value="psv" onchange="displayData('barrier');">
 </table>
 </form>
 </div>
@@ -273,7 +279,7 @@ Each barrier blocking the chosen type of transport is drawn.
 <div class="hideshow_box">
 <span id="hideshow_turns_show" onclick="hideshow_show('turns');" class="hideshow_show">+</span>
 <span id="hideshow_turns_hide" onclick="hideshow_hide('turns');" class="hideshow_hide">-</span>
-<input type="button" id="turns" onclick="displayData('turns');" value="Display Turn Restrictions">
+<input type="button" id="turns" onclick="displayData('turns');" value="Zeige Abbiegebeschränkungen">
 <div id="hideshow_turns_div" style="display: none;">
 Each turn restrictions is shown with a line indicating the disallowed turn.
 </div>
@@ -282,7 +288,7 @@ Each turn restrictions is shown with a line indicating the disallowed turn.
 <div class="hideshow_box">
 <span id="hideshow_speed_show" onclick="hideshow_show('speed');" class="hideshow_show">+</span>
 <span id="hideshow_speed_hide" onclick="hideshow_hide('speed');" class="hideshow_hide">-</span>
-<input type="button" id="speed" onclick="displayData('speed');" value="Display Speed Limits">
+<input type="button" id="speed" onclick="displayData('speed');" value="Zeige Geschwindigkeitsbeschränkungen">
 <div id="hideshow_speed_div" style="display: none;">
 Each node that joins segments with different speed limits is shown
 along with the speed limit on relevant segments.
@@ -290,7 +296,7 @@ along with the speed limit on relevant segments.
 <table>
 <tr><td><img src="icons/ball-1.png" alt="." ><td>Change of limit
 <tr><td><img src="icons/limit-no.png" alt="()" ><td>No specified limit
-<tr><td><img src="icons/limit-80.png" alt="(80)"><td>80 km/hour speed limit
+<tr><td><img src="icons/limit-80.png" alt="(80)"><td>80 km/Stunde Geschwindigkeitsbegrenzung
 </table>
 </div>
 </div>
@@ -298,7 +304,7 @@ along with the speed limit on relevant segments.
 <div class="hideshow_box">
 <span id="hideshow_weight_show" onclick="hideshow_show('weight');" class="hideshow_show">+</span>
 <span id="hideshow_weight_hide" onclick="hideshow_hide('weight');" class="hideshow_hide">-</span>
-<input type="button" id="weight" onclick="displayData('weight');" value="Display Weight Limits">
+<input type="button" id="weight" onclick="displayData('weight');" value="Gewichtswegbeschränkungen anzeigen">
 <div id="hideshow_weight_div" style="display: none;">
 Each node that joins segments with different weight limits is shown
 along with the weight limit on relevant segments.
@@ -322,7 +328,7 @@ along with the height limit on relevant segments.
 <table>
 <tr><td><img src="icons/ball-1.png" alt="." ><td>Change of limit
 <tr><td><img src="icons/limit-no.png" alt="()" ><td>No specified limit
-<tr><td><img src="icons/limit-4.0.png" alt="(4.0)"><td>4.0 m height limit
+<tr><td><img src="icons/limit-4.0.png" alt="(4.0)"><td>4.0 m Höhenbeschränkung
 </table>
 </div>
 </div>
diff --git a/web/www/routino/visualiser.html.en b/web/www/routino/visualiser.html.en
index 5401881..234be3a 100644
--- a/web/www/routino/visualiser.html.en
+++ b/web/www/routino/visualiser.html.en
@@ -89,9 +89,15 @@ Only data relevant for routing is displayed and some will therefore be excluded.
 <td><a id="lang_fr_url" href="visualiser.html.fr" title="Francais">Francais</a>
 <td>(FR)
 <tr>
+<td><a id="lang_hu_url" href="visualiser.html.hu" title="Magyar weblap">Magyar</a>
+<td>(HU)
+<tr>
 <td><a id="lang_nl_url" href="visualiser.html.nl" title="Nederlandse web pagina">Nederlands</a>
 <td>(NL)
 <tr>
+<td><a id="lang_pl_url" href="visualiser.html.pl" title="Polski webpage">Polski</a>
+<td>(PL)
+<tr>
 <td><a id="lang_ru_url" href="visualiser.html.ru" title="Русский">Русский</a>
 <td>(RU)
 </table>
diff --git a/web/www/routino/visualiser.html.fr b/web/www/routino/visualiser.html.fr
index 5372d87..e559ce1 100644
--- a/web/www/routino/visualiser.html.fr
+++ b/web/www/routino/visualiser.html.fr
@@ -89,9 +89,15 @@ Only data relevant for routing is displayed and some will therefore be excluded.
 <td><a id="lang_fr_url" href="visualiser.html.fr" title="Francais">Francais</a>
 <td>(FR)
 <tr>
+<td><a id="lang_hu_url" href="visualiser.html.hu" title="Magyar weblap">Magyar</a>
+<td>(HU)
+<tr>
 <td><a id="lang_nl_url" href="visualiser.html.nl" title="Nederlandse web pagina">Nederlands</a>
 <td>(NL)
 <tr>
+<td><a id="lang_pl_url" href="visualiser.html.pl" title="Polski webpage">Polski</a>
+<td>(PL)
+<tr>
 <td><a id="lang_ru_url" href="visualiser.html.ru" title="Русский">Русский</a>
 <td>(RU)
 </table>
diff --git a/web/www/routino/visualiser.html.nl b/web/www/routino/visualiser.html.hu
similarity index 63%
copy from web/www/routino/visualiser.html.nl
copy to web/www/routino/visualiser.html.hu
index e49ced8..82fa7ee 100644
--- a/web/www/routino/visualiser.html.nl
+++ b/web/www/routino/visualiser.html.hu
@@ -6,7 +6,7 @@
 <meta name="keywords" content="openstreetmap routino verifier">
 <meta name="viewport" content="width=device-width, height=device-height, initial-scale=1, user-scalable=no">
 
-<title>Routino : Data Visualiser for Routing Data</title>
+<title>Routino : Útvonaltervező adatok vizuálisan</title>
 
 <!--
 Routino data visualiser web page.
@@ -62,20 +62,20 @@ along with this program. If not, see http://www.gnu.org/licenses/.
 <div class="tab_content" id="tab_visualiser_div">
 
 <div class="hideshow_box">
-<span class="hideshow_title">Routino Visualiser</span>
+<span class="hideshow_title">Routino vizualizáció</span>
 This web page allows visualisation of the data that Routino uses for routing.
 Only data relevant for routing is displayed and some will therefore be excluded.
 <div class="center">
-<a target="other" href="http://www.routino.org/">Routino Website</a>
+<a target="other" href="http://www.routino.org/">Routino weboldal</a>
 |
-<a target="other" href="documentation/">Documentation</a>
+<a target="other" href="documentation/">Dokumentáció</a>
 </div>
 </div>
 
 <div class="hideshow_box">
 <span id="hideshow_language_show" onclick="hideshow_show('language');" class="hideshow_show">+</span>
 <span id="hideshow_language_hide" onclick="hideshow_hide('language');" class="hideshow_hide">-</span>
-<span class="hideshow_title">Taal</span>
+<span class="hideshow_title">Nyelv</span>
 
 <div id="hideshow_language_div" style="display: none;">
 <table>
@@ -89,9 +89,15 @@ Only data relevant for routing is displayed and some will therefore be excluded.
 <td><a id="lang_fr_url" href="visualiser.html.fr" title="Francais">Francais</a>
 <td>(FR)
 <tr>
+<td><a id="lang_hu_url" href="visualiser.html.hu" title="Magyar weblap">Magyar</a>
+<td>(HU)
+<tr>
 <td><a id="lang_nl_url" href="visualiser.html.nl" title="Nederlandse web pagina">Nederlands</a>
 <td>(NL)
 <tr>
+<td><a id="lang_pl_url" href="visualiser.html.pl" title="Polski webpage">Polski</a>
+<td>(PL)
+<tr>
 <td><a id="lang_ru_url" href="visualiser.html.ru" title="Русский">Русский</a>
 <td>(RU)
 </table>
@@ -100,48 +106,48 @@ Only data relevant for routing is displayed and some will therefore be excluded.
 </div>
 
 <div class="hideshow_box">
-<span class="hideshow_title">Instructions</span>
+<span class="hideshow_title">Útmutatók</span>
 Zoom in and then use the buttons below to download the data. The
 server will only return data if the selected area is small enough.
 </div>
 
 <div class="hideshow_box">
-<span class="hideshow_title">Status</span>
+<span class="hideshow_title">Állapot</span>
 <div id="result_status">
 <div id="result_status_no_data">
-<b><i>No data displayed</i></b>
+<b><i>Nincs megjelenítendő adat</i></b>
 </div>
 <div id="result_status_data" style="display: none;">
 </div>
 <div id="result_status_failed" style="display: none;">
-<b>Failed to get visualiser data!</b>
+<b>Sikertelen az adatok betöltése</b>
 </div>
 <div id="result_status_junctions" style="display: none;">
-<b>Processed # junctions</b>
+<b>Feldolgozva # kereszteződés</b>
 </div>
 <div id="result_status_super" style="display: none;">
-<b>Processed # super-nodes/segments</b>
+<b>Feldolgozva # szuper-pont/szegmens</b>
 </div>
 <div id="result_status_waytype" style="display: none;">
-<b>Processed # way type segments</b>
+<b>Feldolgozva # út típus szegmens</b>
 </div>
 <div id="result_status_highway" style="display: none;">
-<b>Processed # segments</b>
+<b>Feldolgozva # szegmens</b>
 </div>
 <div id="result_status_transport" style="display: none;">
-<b>Processed # segments</b>
+<b>Feldolgozva # szegmens</b>
 </div>
 <div id="result_status_barrier" style="display: none;">
-<b>Processed # nodes</b>
+<b>Feldolgozva # pont</b>
 </div>
 <div id="result_status_turns" style="display: none;">
-<b>Processed # turn restrictions</b>
+<b>Feldolgozva # kanyarodási korlátozás</b>
 </div>
 <div id="result_status_limit" style="display: none;">
 <b>Processed # limit changes</b>
 </div>
 <div id="result_status_property" style="display: none;">
-<b>Processed # segments</b>
+<b>Feldolgozva # szegmens</b>
 </div>
 <div id="result_status_errorlogs" style="display: none;">
 <b>Processed # error logs</b>
@@ -152,7 +158,7 @@ server will only return data if the selected area is small enough.
 <div class="hideshow_box">
 <span id="hideshow_junctions_show" onclick="hideshow_show('junctions');" class="hideshow_show">+</span>
 <span id="hideshow_junctions_hide" onclick="hideshow_hide('junctions');" class="hideshow_hide">-</span>
-<input type="button" id="junctions" onclick="displayData('junctions');" value="Display Junctions">
+<input type="button" id="junctions" onclick="displayData('junctions');" value="Kereszteződések mutatása">
 <div id="hideshow_junctions_div" style="display: none;">
 Each node that is a dead-end, a junction of two highways of different
 types (or different properties) or a junction where more than two segments
@@ -161,11 +167,11 @@ join are shown colour-coded.
 <table>
 <tr><td><img src="icons/ball-1.png" alt="1" ><td>only one highway - a dead-end.
 <tr><td><img src="icons/ball-2.png" alt="2" ><td>two highways of different types meet.
-<tr><td><img src="icons/ball-3.png" alt="3" ><td>three highways meet.
-<tr><td><img src="icons/ball-4.png" alt="4" ><td>four highways meet.
-<tr><td><img src="icons/ball-5.png" alt="5" ><td>five highways meet.
-<tr><td><img src="icons/ball-6.png" alt="6" ><td>six highways meet.
-<tr><td><img src="icons/ball-7.png" alt="7+"><td>seven (or more) highways meet.
+<tr><td><img src="icons/ball-3.png" alt="3" ><td>három út talákozása
+<tr><td><img src="icons/ball-4.png" alt="4" ><td>négy út találkozása
+<tr><td><img src="icons/ball-5.png" alt="5" ><td>öt út találkozása
+<tr><td><img src="icons/ball-6.png" alt="6" ><td>hat út találkozása
+<tr><td><img src="icons/ball-7.png" alt="7+"><td>hét, vagy több út találkozása
 </table>
 </div>
 </div>
@@ -173,7 +179,7 @@ join are shown colour-coded.
 <div class="hideshow_box">
 <span id="hideshow_super_show" onclick="hideshow_show('super');" class="hideshow_show">+</span>
 <span id="hideshow_super_hide" onclick="hideshow_hide('super');" class="hideshow_hide">-</span>
-<input type="button" id="super" onclick="displayData('super');" value="Display Super Segments">
+<input type="button" id="super" onclick="displayData('super');" value="Szuper szegmens mutatása">
 <div id="hideshow_super_div" style="display: none;">
 Each super-node and the associated super-segments are shown (see
 algorithm page for description).
@@ -183,16 +189,16 @@ algorithm page for description).
 <div class="hideshow_box">
 <span id="hideshow_waytype_show" onclick="hideshow_show('waytype');" class="hideshow_show">+</span>
 <span id="hideshow_waytype_hide" onclick="hideshow_hide('waytype');" class="hideshow_hide">-</span>
-<input type="button" id="waytype" onclick="displayData('waytype');" value="Display Way Type Segments">
+<input type="button" id="waytype" onclick="displayData('waytype');" value="Út típus szakaszok megjelenítese">
 <div id="hideshow_waytype_div" style="display: none;">
 Each highway segment of special types (one-way, cycle-both-ways and roundabout) are
 shown. For one-way segments a coloured triangle indicates the allowed direction.
 The colours of the triangles depend on the bearing of the highway segment.
 <form name="waytypes" id="waytypes" action="#" method="get" onsubmit="return false;">
 <table>
-<tr><td>One-way segments: <td><input name="waytype" type="radio" value="oneway" onchange="displayData('waytype');" checked>
+<tr><td>Egyirányú szakaszok: <td><input name="waytype" type="radio" value="oneway" onchange="displayData('waytype');" checked>
 <tr><td>Cycle-both-way segments:<td><input name="waytype" type="radio" value="cyclebothways" onchange="displayData('waytype');">
-<tr><td>Roundabout segments: <td><input name="waytype" type="radio" value="roundabout" onchange="displayData('waytype');">
+<tr><td>Körforgalmi szakaszok: <td><input name="waytype" type="radio" value="roundabout" onchange="displayData('waytype');">
 </table>
 </form>
 </div>
@@ -201,24 +207,24 @@ The colours of the triangles depend on the bearing of the highway segment.
 <div class="hideshow_box">
 <span id="hideshow_highway_show" onclick="hideshow_show('highway');" class="hideshow_show">+</span>
 <span id="hideshow_highway_hide" onclick="hideshow_hide('highway');" class="hideshow_hide">-</span>
-<input type="button" id="highway" onclick="displayData('highway');" value="Display Highway Segments">
+<input type="button" id="highway" onclick="displayData('highway');" value="Út szakaszok megjelenítése">
 <div id="hideshow_highway_div" style="display: none;">
 Each segment of the chosen type of highway is drawn.
 <form name="highways" id="highways" action="#" method="get" onsubmit="return false;">
 <table>
-<tr><td>Autostrade: <td><input name="highway" type="radio" value="motorway" onchange="displayData('highway');">
-<tr><td>Autoweg: <td><input name="highway" type="radio" value="trunk" onchange="displayData('highway');">
-<tr><td>Provinciale wegen: <td><input name="highway" type="radio" value="primary" onchange="displayData('highway');" checked>
-<tr><td>Nationale wegen: <td><input name="highway" type="radio" value="secondary" onchange="displayData('highway');">
-<tr><td>Doorgangsweg: <td><input name="highway" type="radio" value="tertiary" onchange="displayData('highway');">
-<tr><td>Niet geclassificeerd:<td><input name="highway" type="radio" value="unclassified" onchange="displayData('highway');">
-<tr><td>Woongebied: <td><input name="highway" type="radio" value="residential" onchange="displayData('highway');">
-<tr><td>Toegangsweg: <td><input name="highway" type="radio" value="service" onchange="displayData('highway');">
-<tr><td>Veldweg: <td><input name="highway" type="radio" value="track" onchange="displayData('highway');">
-<tr><td>Fietspad: <td><input name="highway" type="radio" value="cycleway" onchange="displayData('highway');">
-<tr><td>Pad: <td><input name="highway" type="radio" value="path" onchange="displayData('highway');">
-<tr><td>Trap: <td><input name="highway" type="radio" value="steps" onchange="displayData('highway');">
-<tr><td>Ferry: <td><input name="highway" type="radio" value="ferry" onchange="displayData('highway');">
+<tr><td>Autópálya: <td><input name="highway" type="radio" value="motorway" onchange="displayData('highway');">
+<tr><td>Autóút: <td><input name="highway" type="radio" value="trunk" onchange="displayData('highway');">
+<tr><td>Főút: <td><input name="highway" type="radio" value="primary" onchange="displayData('highway');" checked>
+<tr><td>Összekötőút: <td><input name="highway" type="radio" value="secondary" onchange="displayData('highway');">
+<tr><td>Bekötőút: <td><input name="highway" type="radio" value="tertiary" onchange="displayData('highway');">
+<tr><td>Egyéb közút:<td><input name="highway" type="radio" value="unclassified" onchange="displayData('highway');">
+<tr><td>Lakóövezeti út: <td><input name="highway" type="radio" value="residential" onchange="displayData('highway');">
+<tr><td>Szervízút: <td><input name="highway" type="radio" value="service" onchange="displayData('highway');">
+<tr><td>Földút: <td><input name="highway" type="radio" value="track" onchange="displayData('highway');">
+<tr><td>Kerékpárút: <td><input name="highway" type="radio" value="cycleway" onchange="displayData('highway');">
+<tr><td>Ösvény: <td><input name="highway" type="radio" value="path" onchange="displayData('highway');">
+<tr><td>Lépcső: <td><input name="highway" type="radio" value="steps" onchange="displayData('highway');">
+<tr><td>Komp: <td><input name="highway" type="radio" value="ferry" onchange="displayData('highway');">
 </table>
 </form>
 </div>
@@ -232,16 +238,16 @@ Each segment of the chosen type of highway is drawn.
 Each segment allowed for the chosen type of transport is drawn.
 <form name="transports" id="transports" action="#" method="get" onsubmit="return false;">
 <table>
-<tr><td>Te voet: <td><input name="transport" type="radio" value="foot" onchange="displayData('transport');">
-<tr><td>Paard: <td><input name="transport" type="radio" value="horse" onchange="displayData('transport');">
-<tr><td>Rolstoel:<td><input name="transport" type="radio" value="wheelchair" onchange="displayData('transport');">
-<tr><td>Fiets: <td><input name="transport" type="radio" value="bicycle" onchange="displayData('transport');">
-<tr><td>Brommer: <td><input name="transport" type="radio" value="moped" onchange="displayData('transport');">
-<tr><td>Motorfiets:<td><input name="transport" type="radio" value="motorcycle" onchange="displayData('transport');">
-<tr><td>Auto: <td><input name="transport" type="radio" value="motorcar" onchange="displayData('transport');" checked>
-<tr><td>Goederen: <td><input name="transport" type="radio" value="goods" onchange="displayData('transport');">
-<tr><td>Zwaar transport: <td><input name="transport" type="radio" value="hgv" onchange="displayData('transport');">
-<tr><td>Publiek transport: <td><input name="transport" type="radio" value="psv" onchange="displayData('transport');">
+<tr><td>Gyalog: <td><input name="transport" type="radio" value="foot" onchange="displayData('transport');">
+<tr><td>Lovas: <td><input name="transport" type="radio" value="horse" onchange="displayData('transport');">
+<tr><td>Kerekesszékes:<td><input name="transport" type="radio" value="wheelchair" onchange="displayData('transport');">
+<tr><td>Kerékpáros: <td><input name="transport" type="radio" value="bicycle" onchange="displayData('transport');">
+<tr><td>Robogós: <td><input name="transport" type="radio" value="moped" onchange="displayData('transport');">
+<tr><td>Motoros:<td><input name="transport" type="radio" value="motorcycle" onchange="displayData('transport');">
+<tr><td>Autós: <td><input name="transport" type="radio" value="motorcar" onchange="displayData('transport');" checked>
+<tr><td>Kisteherautós: <td><input name="transport" type="radio" value="goods" onchange="displayData('transport');">
+<tr><td>Kamionos: <td><input name="transport" type="radio" value="hgv" onchange="displayData('transport');">
+<tr><td>Buszos: <td><input name="transport" type="radio" value="psv" onchange="displayData('transport');">
 </table>
 </form>
 </div>
@@ -255,16 +261,16 @@ Each segment allowed for the chosen type of transport is drawn.
 Each barrier blocking the chosen type of transport is drawn.
 <form name="barriers" id="barriers" action="#" method="get" onsubmit="return false;">
 <table>
-<tr><td>Te voet: <td><input name="barrier" type="radio" value="foot" onchange="displayData('barrier');">
-<tr><td>Paard: <td><input name="barrier" type="radio" value="horse" onchange="displayData('barrier');">
-<tr><td>Rolstoel:<td><input name="barrier" type="radio" value="wheelchair" onchange="displayData('barrier');">
-<tr><td>Fiets: <td><input name="barrier" type="radio" value="bicycle" onchange="displayData('barrier');">
-<tr><td>Brommer: <td><input name="barrier" type="radio" value="moped" onchange="displayData('barrier');">
-<tr><td>Motorfiets:<td><input name="barrier" type="radio" value="motorcycle" onchange="displayData('barrier');">
-<tr><td>Auto: <td><input name="barrier" type="radio" value="motorcar" onchange="displayData('barrier');" checked>
-<tr><td>Goederen: <td><input name="barrier" type="radio" value="goods" onchange="displayData('barrier');">
-<tr><td>Zwaar transport: <td><input name="barrier" type="radio" value="hgv" onchange="displayData('barrier');">
-<tr><td>Publiek transport: <td><input name="barrier" type="radio" value="psv" onchange="displayData('barrier');">
+<tr><td>Gyalog: <td><input name="barrier" type="radio" value="foot" onchange="displayData('barrier');">
+<tr><td>Lovas: <td><input name="barrier" type="radio" value="horse" onchange="displayData('barrier');">
+<tr><td>Kerekesszékes:<td><input name="barrier" type="radio" value="wheelchair" onchange="displayData('barrier');">
+<tr><td>Kerékpáros: <td><input name="barrier" type="radio" value="bicycle" onchange="displayData('barrier');">
+<tr><td>Robogós: <td><input name="barrier" type="radio" value="moped" onchange="displayData('barrier');">
+<tr><td>Motoros:<td><input name="barrier" type="radio" value="motorcycle" onchange="displayData('barrier');">
+<tr><td>Autós: <td><input name="barrier" type="radio" value="motorcar" onchange="displayData('barrier');" checked>
+<tr><td>Kisteherautós: <td><input name="barrier" type="radio" value="goods" onchange="displayData('barrier');">
+<tr><td>Kamionos: <td><input name="barrier" type="radio" value="hgv" onchange="displayData('barrier');">
+<tr><td>Buszos: <td><input name="barrier" type="radio" value="psv" onchange="displayData('barrier');">
 </table>
 </form>
 </div>
@@ -273,7 +279,7 @@ Each barrier blocking the chosen type of transport is drawn.
 <div class="hideshow_box">
 <span id="hideshow_turns_show" onclick="hideshow_show('turns');" class="hideshow_show">+</span>
 <span id="hideshow_turns_hide" onclick="hideshow_hide('turns');" class="hideshow_hide">-</span>
-<input type="button" id="turns" onclick="displayData('turns');" value="Display Turn Restrictions">
+<input type="button" id="turns" onclick="displayData('turns');" value="Kanyarodási korlátozások">
 <div id="hideshow_turns_div" style="display: none;">
 Each turn restrictions is shown with a line indicating the disallowed turn.
 </div>
@@ -282,15 +288,15 @@ Each turn restrictions is shown with a line indicating the disallowed turn.
 <div class="hideshow_box">
 <span id="hideshow_speed_show" onclick="hideshow_show('speed');" class="hideshow_show">+</span>
 <span id="hideshow_speed_hide" onclick="hideshow_hide('speed');" class="hideshow_hide">-</span>
-<input type="button" id="speed" onclick="displayData('speed');" value="Display Speed Limits">
+<input type="button" id="speed" onclick="displayData('speed');" value="Sebességhatárok">
 <div id="hideshow_speed_div" style="display: none;">
 Each node that joins segments with different speed limits is shown
 along with the speed limit on relevant segments.
 <br>
 <table>
-<tr><td><img src="icons/ball-1.png" alt="." ><td>Change of limit
-<tr><td><img src="icons/limit-no.png" alt="()" ><td>No specified limit
-<tr><td><img src="icons/limit-80.png" alt="(80)"><td>80 km/hour speed limit
+<tr><td><img src="icons/ball-1.png" alt="." ><td>Korlátozás változása
+<tr><td><img src="icons/limit-no.png" alt="()" ><td>Nincs korlátozás
+<tr><td><img src="icons/limit-80.png" alt="(80)"><td>80 km/óra sebességkorlátozás
 </table>
 </div>
 </div>
@@ -298,15 +304,15 @@ along with the speed limit on relevant segments.
 <div class="hideshow_box">
 <span id="hideshow_weight_show" onclick="hideshow_show('weight');" class="hideshow_show">+</span>
 <span id="hideshow_weight_hide" onclick="hideshow_hide('weight');" class="hideshow_hide">-</span>
-<input type="button" id="weight" onclick="displayData('weight');" value="Display Weight Limits">
+<input type="button" id="weight" onclick="displayData('weight');" value="Súlykorlátozások">
 <div id="hideshow_weight_div" style="display: none;">
 Each node that joins segments with different weight limits is shown
 along with the weight limit on relevant segments.
 <br>
 <table>
-<tr><td><img src="icons/ball-1.png" alt="." ><td>Change of limit
-<tr><td><img src="icons/limit-no.png" alt="()" ><td>No specified limit
-<tr><td><img src="icons/limit-8.0.png" alt="(8.0)"><td>8.0 tonnes weight limit
+<tr><td><img src="icons/ball-1.png" alt="." ><td>Korlátozás változása
+<tr><td><img src="icons/limit-no.png" alt="()" ><td>Nincs korlátozás
+<tr><td><img src="icons/limit-8.0.png" alt="(8.0)"><td>8 tonnás súlykorlátozás
 </table>
 </div>
 </div>
@@ -314,15 +320,15 @@ along with the weight limit on relevant segments.
 <div class="hideshow_box">
 <span id="hideshow_height_show" onclick="hideshow_show('height');" class="hideshow_show">+</span>
 <span id="hideshow_height_hide" onclick="hideshow_hide('height');" class="hideshow_hide">-</span>
-<input type="button" id="height" onclick="displayData('height');" value="Display Height Limits">
+<input type="button" id="height" onclick="displayData('height');" value="Magasságkorlátozások">
 <div id="hideshow_height_div" style="display: none;">
 Each node that joins segments with different height limits is shown
 along with the height limit on relevant segments.
 <br>
 <table>
-<tr><td><img src="icons/ball-1.png" alt="." ><td>Change of limit
-<tr><td><img src="icons/limit-no.png" alt="()" ><td>No specified limit
-<tr><td><img src="icons/limit-4.0.png" alt="(4.0)"><td>4.0 m height limit
+<tr><td><img src="icons/ball-1.png" alt="." ><td>Korlátozás változása
+<tr><td><img src="icons/limit-no.png" alt="()" ><td>Nincs korlátozás
+<tr><td><img src="icons/limit-4.0.png" alt="(4.0)"><td>4 méter magasságkorlátozás
 </table>
 </div>
 </div>
@@ -330,15 +336,15 @@ along with the height limit on relevant segments.
 <div class="hideshow_box">
 <span id="hideshow_width_show" onclick="hideshow_show('width');" class="hideshow_show">+</span>
 <span id="hideshow_width_hide" onclick="hideshow_hide('width');" class="hideshow_hide">-</span>
-<input type="button" id="width" onclick="displayData('width');" value="Display Width Limits">
+<input type="button" id="width" onclick="displayData('width');" value="Szélességkorlátozások">
 <div id="hideshow_width_div" style="display: none;">
 Each node that joins segments with different width limits is shown
 along with the width limit on relevant segments.
 <br>
 <table>
-<tr><td><img src="icons/ball-1.png" alt="." ><td>Change of limit
-<tr><td><img src="icons/limit-no.png" alt="()" ><td>No specified limit
-<tr><td><img src="icons/limit-3.0.png" alt="(3.0)"><td>3.0 m width limit
+<tr><td><img src="icons/ball-1.png" alt="." ><td>Korlátozás változása
+<tr><td><img src="icons/limit-no.png" alt="()" ><td>Nincs korlátozás
+<tr><td><img src="icons/limit-3.0.png" alt="(3.0)"><td>3 méter szélességkorlátozás
 </table>
 </div>
 </div>
@@ -346,15 +352,15 @@ along with the width limit on relevant segments.
 <div class="hideshow_box">
 <span id="hideshow_length_show" onclick="hideshow_show('length');" class="hideshow_show">+</span>
 <span id="hideshow_length_hide" onclick="hideshow_hide('length');" class="hideshow_hide">-</span>
-<input type="button" id="length" onclick="displayData('length');" value="Display Length Limits">
+<input type="button" id="length" onclick="displayData('length');" value="Hosszúságkorlátozások">
 <div id="hideshow_length_div" style="display: none;">
 Each node that joins segments with different length limits is shown
 along with the length limit on relevant segments.
 <br>
 <table>
-<tr><td><img src="icons/ball-1.png" alt="." ><td>Change of limit
-<tr><td><img src="icons/limit-no.png" alt="()" ><td>No specified limit
-<tr><td><img src="icons/limit-9.0.png" alt="(9.0)"><td>9.0 m length limit
+<tr><td><img src="icons/ball-1.png" alt="." ><td>Korlátozás változása
+<tr><td><img src="icons/limit-no.png" alt="()" ><td>Nincs korlátozás
+<tr><td><img src="icons/limit-9.0.png" alt="(9.0)"><td>9 méter hosszúságkorlátozás
 </table>
 </div>
 </div>
@@ -362,17 +368,17 @@ along with the length limit on relevant segments.
 <div class="hideshow_box">
 <span id="hideshow_property_show" onclick="hideshow_show('property');" class="hideshow_show">+</span>
 <span id="hideshow_property_hide" onclick="hideshow_hide('property');" class="hideshow_hide">-</span>
-<input type="button" id="property" onclick="displayData('property');" value="Display Highway Properties">
+<input type="button" id="property" onclick="displayData('property');" value="Út tulajdonságok megjelenítése">
 <div id="hideshow_property_div" style="display: none;">
 Each segment of the highways with a particular property is drawn.
 <form name="properties" id="properties" action="#" method="get" onsubmit="return false;">
 <table>
-<tr><td>Verhard: <td><input name="property" type="radio" value="paved" onchange="displayData('property');" checked>
-<tr><td>Meerdere Stroken: <td><input name="property" type="radio" value="multilane" onchange="displayData('property');">
-<tr><td>Brug: <td><input name="property" type="radio" value="bridge" onchange="displayData('property');">
-<tr><td>Tunnel: <td><input name="property" type="radio" value="tunnel" onchange="displayData('property');">
-<tr><td>Walking Route: <td><input name="property" type="radio" value="footroute" onchange="displayData('property');">
-<tr><td>Bicycle Route: <td><input name="property" type="radio" value="bicycleroute" onchange="displayData('property');">
+<tr><td>Burkolt: <td><input name="property" type="radio" value="paved" onchange="displayData('property');" checked>
+<tr><td>Többsávos: <td><input name="property" type="radio" value="multilane" onchange="displayData('property');">
+<tr><td>Híd: <td><input name="property" type="radio" value="bridge" onchange="displayData('property');">
+<tr><td>Alagút: <td><input name="property" type="radio" value="tunnel" onchange="displayData('property');">
+<tr><td>Gyalogút: <td><input name="property" type="radio" value="footroute" onchange="displayData('property');">
+<tr><td>Kijelölt kerékpárút: <td><input name="property" type="radio" value="bicycleroute" onchange="displayData('property');">
 </table>
 </form>
 </div>
@@ -381,27 +387,27 @@ Each segment of the highways with a particular property is drawn.
 <div class="hideshow_box">
 <span id="hideshow_errorlogs_show" onclick="hideshow_show('errorlogs');" class="hideshow_show">+</span>
 <span id="hideshow_errorlogs_hide" onclick="hideshow_hide('errorlogs');" class="hideshow_hide">-</span>
-<input type="button" id="errorlogs" onclick="displayData('errorlogs');" value="Display Error Logs">
+<input type="button" id="errorlogs" onclick="displayData('errorlogs');" value="Hiba logok megmutatása">
 <div id="hideshow_errorlogs_div" style="display: none;">
-Potential problems found by Routino when processing the input data.
+Lehetséges hibák fordultak elő az adatok feldolgozása során
 </div>
 </div>
 
 <div class="hideshow_box">
-<input type="button" id="clear" onclick="displayData('');" value="Clear data">
+<input type="button" id="clear" onclick="displayData('');" value="Adatok törlése">
 </div>
 
 <div class="hideshow_box">
-<span class="hideshow_title">Links</span>
-<a id="permalink_url" href="visualiser.html">Link to this map view</a>
+<span class="hideshow_title">Linkek</span>
+<a id="permalink_url" href="visualiser.html">Link erre a nézetre</a>
 <br>
-<a id="edit_url" target="edit" style="display: none;">Lees hoe je OSM data kan inbrengen</a>
+<a id="edit_url" target="edit" style="display: none;">OSM adatok szerkesztése</a>
 </div>
 
 <div class="hideshow_box">
 <span id="hideshow_help_options_show" onclick="hideshow_show('help_options');" class="hideshow_hide">+</span>
 <span id="hideshow_help_options_hide" onclick="hideshow_hide('help_options');" class="hideshow_show">-</span>
-<span class="hideshow_title">Help</span>
+<span class="hideshow_title">Súgó</span>
 <div id="hideshow_help_options_div">
 <div class="scrollable">
 <b>Quick Start</b>
@@ -424,18 +430,18 @@ again.
 
 <div class="tab_content" id="tab_router_div" style="display: none;">
 <div class="hideshow_box">
-<span class="hideshow_title">Routino Router</span>
+<span class="hideshow_title">Routino Útvonaltervező</span>
 To perform routing on the map use the link below.
 <br>
-<a id="router_url" href="router.html" target="router">Link to this map view</a>
+<a id="router_url" href="router.html" target="router">Link erre a nézetre</a>
 </div>
 </div>
 
 <div class="tab_content" id="tab_data_div" style="display: none;">
 <div class="hideshow_box">
-<span class="hideshow_title">Routino Statistics</span>
+<span class="hideshow_title">Routino statisztika</span>
 <div id="statistics_data"></div>
-<a id="statistics_link" href="statistics.cgi" onclick="displayStatistics();return(false);">Display data statistics</a>
+<a id="statistics_link" href="statistics.cgi" onclick="displayStatistics();return(false);">Statisztika mutatása</a>
 </div>
 </div>
 
@@ -451,11 +457,11 @@ Javascript is <em>required</em> to use this web page because of the interactive
 </noscript>
 </div>
 <div class="attribution">
-Router: <a href="http://www.routino.org/" target="routino">Routino</a>
+Útvonaltervező: <a href="http://www.routino.org/" target="routino">Routino</a>
 |
 Geo Data: <span id="attribution_data"></span>
 |
-Tiles: <span id="attribution_tile"></span>
+Térképszeletek: <span id="attribution_tile"></span>
 </div>
 </div>
 
diff --git a/web/www/routino/visualiser.html.nl b/web/www/routino/visualiser.html.nl
index e49ced8..dc5c550 100644
--- a/web/www/routino/visualiser.html.nl
+++ b/web/www/routino/visualiser.html.nl
@@ -89,9 +89,15 @@ Only data relevant for routing is displayed and some will therefore be excluded.
 <td><a id="lang_fr_url" href="visualiser.html.fr" title="Francais">Francais</a>
 <td>(FR)
 <tr>
+<td><a id="lang_hu_url" href="visualiser.html.hu" title="Magyar weblap">Magyar</a>
+<td>(HU)
+<tr>
 <td><a id="lang_nl_url" href="visualiser.html.nl" title="Nederlandse web pagina">Nederlands</a>
 <td>(NL)
 <tr>
+<td><a id="lang_pl_url" href="visualiser.html.pl" title="Polski webpage">Polski</a>
+<td>(PL)
+<tr>
 <td><a id="lang_ru_url" href="visualiser.html.ru" title="Русский">Русский</a>
 <td>(RU)
 </table>
@@ -100,7 +106,7 @@ Only data relevant for routing is displayed and some will therefore be excluded.
 </div>
 
 <div class="hideshow_box">
-<span class="hideshow_title">Instructions</span>
+<span class="hideshow_title">Instructies</span>
 Zoom in and then use the buttons below to download the data. The
 server will only return data if the selected area is small enough.
 </div>
@@ -109,7 +115,7 @@ server will only return data if the selected area is small enough.
 <span class="hideshow_title">Status</span>
 <div id="result_status">
 <div id="result_status_no_data">
-<b><i>No data displayed</i></b>
+<b><i>Geen data getoond</i></b>
 </div>
 <div id="result_status_data" style="display: none;">
 </div>
@@ -282,7 +288,7 @@ Each turn restrictions is shown with a line indicating the disallowed turn.
 <div class="hideshow_box">
 <span id="hideshow_speed_show" onclick="hideshow_show('speed');" class="hideshow_show">+</span>
 <span id="hideshow_speed_hide" onclick="hideshow_hide('speed');" class="hideshow_hide">-</span>
-<input type="button" id="speed" onclick="displayData('speed');" value="Display Speed Limits">
+<input type="button" id="speed" onclick="displayData('speed');" value="Toon snelheidslimieten">
 <div id="hideshow_speed_div" style="display: none;">
 Each node that joins segments with different speed limits is shown
 along with the speed limit on relevant segments.
@@ -298,7 +304,7 @@ along with the speed limit on relevant segments.
 <div class="hideshow_box">
 <span id="hideshow_weight_show" onclick="hideshow_show('weight');" class="hideshow_show">+</span>
 <span id="hideshow_weight_hide" onclick="hideshow_hide('weight');" class="hideshow_hide">-</span>
-<input type="button" id="weight" onclick="displayData('weight');" value="Display Weight Limits">
+<input type="button" id="weight" onclick="displayData('weight');" value="Toon massa limieten">
 <div id="hideshow_weight_div" style="display: none;">
 Each node that joins segments with different weight limits is shown
 along with the weight limit on relevant segments.
@@ -306,7 +312,7 @@ along with the weight limit on relevant segments.
 <table>
 <tr><td><img src="icons/ball-1.png" alt="." ><td>Change of limit
 <tr><td><img src="icons/limit-no.png" alt="()" ><td>No specified limit
-<tr><td><img src="icons/limit-8.0.png" alt="(8.0)"><td>8.0 tonnes weight limit
+<tr><td><img src="icons/limit-8.0.png" alt="(8.0)"><td>8.0 ton massa limiet
 </table>
 </div>
 </div>
@@ -314,7 +320,7 @@ along with the weight limit on relevant segments.
 <div class="hideshow_box">
 <span id="hideshow_height_show" onclick="hideshow_show('height');" class="hideshow_show">+</span>
 <span id="hideshow_height_hide" onclick="hideshow_hide('height');" class="hideshow_hide">-</span>
-<input type="button" id="height" onclick="displayData('height');" value="Display Height Limits">
+<input type="button" id="height" onclick="displayData('height');" value="Toon hoogte limieten">
 <div id="hideshow_height_div" style="display: none;">
 Each node that joins segments with different height limits is shown
 along with the height limit on relevant segments.
@@ -322,7 +328,7 @@ along with the height limit on relevant segments.
 <table>
 <tr><td><img src="icons/ball-1.png" alt="." ><td>Change of limit
 <tr><td><img src="icons/limit-no.png" alt="()" ><td>No specified limit
-<tr><td><img src="icons/limit-4.0.png" alt="(4.0)"><td>4.0 m height limit
+<tr><td><img src="icons/limit-4.0.png" alt="(4.0)"><td>4.0 m hoogte limiet
 </table>
 </div>
 </div>
@@ -330,7 +336,7 @@ along with the height limit on relevant segments.
 <div class="hideshow_box">
 <span id="hideshow_width_show" onclick="hideshow_show('width');" class="hideshow_show">+</span>
 <span id="hideshow_width_hide" onclick="hideshow_hide('width');" class="hideshow_hide">-</span>
-<input type="button" id="width" onclick="displayData('width');" value="Display Width Limits">
+<input type="button" id="width" onclick="displayData('width');" value="Toon breedte limieten">
 <div id="hideshow_width_div" style="display: none;">
 Each node that joins segments with different width limits is shown
 along with the width limit on relevant segments.
@@ -338,7 +344,7 @@ along with the width limit on relevant segments.
 <table>
 <tr><td><img src="icons/ball-1.png" alt="." ><td>Change of limit
 <tr><td><img src="icons/limit-no.png" alt="()" ><td>No specified limit
-<tr><td><img src="icons/limit-3.0.png" alt="(3.0)"><td>3.0 m width limit
+<tr><td><img src="icons/limit-3.0.png" alt="(3.0)"><td>3.0 m breedte limiet
 </table>
 </div>
 </div>
diff --git a/web/www/routino/visualiser.html.en b/web/www/routino/visualiser.html.pl
similarity index 78%
copy from web/www/routino/visualiser.html.en
copy to web/www/routino/visualiser.html.pl
index 5401881..c44f8f3 100644
--- a/web/www/routino/visualiser.html.en
+++ b/web/www/routino/visualiser.html.pl
@@ -62,20 +62,20 @@ along with this program. If not, see http://www.gnu.org/licenses/.
 <div class="tab_content" id="tab_visualiser_div">
 
 <div class="hideshow_box">
-<span class="hideshow_title">Routino Visualiser</span>
+<span class="hideshow_title">Wizualizer Routino</span>
 This web page allows visualisation of the data that Routino uses for routing.
 Only data relevant for routing is displayed and some will therefore be excluded.
 <div class="center">
-<a target="other" href="http://www.routino.org/">Routino Website</a>
+<a target="other" href="http://www.routino.org/">Strona Routino</a>
 |
-<a target="other" href="documentation/">Documentation</a>
+<a target="other" href="documentation/">Dokumentacja</a>
 </div>
 </div>
 
 <div class="hideshow_box">
 <span id="hideshow_language_show" onclick="hideshow_show('language');" class="hideshow_show">+</span>
 <span id="hideshow_language_hide" onclick="hideshow_hide('language');" class="hideshow_hide">-</span>
-<span class="hideshow_title">Language</span>
+<span class="hideshow_title">Język</span>
 
 <div id="hideshow_language_div" style="display: none;">
 <table>
@@ -89,9 +89,15 @@ Only data relevant for routing is displayed and some will therefore be excluded.
 <td><a id="lang_fr_url" href="visualiser.html.fr" title="Francais">Francais</a>
 <td>(FR)
 <tr>
+<td><a id="lang_hu_url" href="visualiser.html.hu" title="Magyar weblap">Magyar</a>
+<td>(HU)
+<tr>
 <td><a id="lang_nl_url" href="visualiser.html.nl" title="Nederlandse web pagina">Nederlands</a>
 <td>(NL)
 <tr>
+<td><a id="lang_pl_url" href="visualiser.html.pl" title="Polski webpage">Polski</a>
+<td>(PL)
+<tr>
 <td><a id="lang_ru_url" href="visualiser.html.ru" title="Русский">Русский</a>
 <td>(RU)
 </table>
@@ -100,7 +106,7 @@ Only data relevant for routing is displayed and some will therefore be excluded.
 </div>
 
 <div class="hideshow_box">
-<span class="hideshow_title">Instructions</span>
+<span class="hideshow_title">Instrukcje</span>
 Zoom in and then use the buttons below to download the data. The
 server will only return data if the selected area is small enough.
 </div>
@@ -109,7 +115,7 @@ server will only return data if the selected area is small enough.
 <span class="hideshow_title">Status</span>
 <div id="result_status">
 <div id="result_status_no_data">
-<b><i>No data displayed</i></b>
+<b><i>Brak danych do wyświetlenia</i></b>
 </div>
 <div id="result_status_data" style="display: none;">
 </div>
@@ -206,19 +212,19 @@ The colours of the triangles depend on the bearing of the highway segment.
 Each segment of the chosen type of highway is drawn.
 <form name="highways" id="highways" action="#" method="get" onsubmit="return false;">
 <table>
-<tr><td>Motorway: <td><input name="highway" type="radio" value="motorway" onchange="displayData('highway');">
+<tr><td>Autostrada: <td><input name="highway" type="radio" value="motorway" onchange="displayData('highway');">
 <tr><td>Trunk: <td><input name="highway" type="radio" value="trunk" onchange="displayData('highway');">
-<tr><td>Primary: <td><input name="highway" type="radio" value="primary" onchange="displayData('highway');" checked>
-<tr><td>Secondary: <td><input name="highway" type="radio" value="secondary" onchange="displayData('highway');">
-<tr><td>Tertiary: <td><input name="highway" type="radio" value="tertiary" onchange="displayData('highway');">
-<tr><td>Unclassified:<td><input name="highway" type="radio" value="unclassified" onchange="displayData('highway');">
-<tr><td>Residential: <td><input name="highway" type="radio" value="residential" onchange="displayData('highway');">
-<tr><td>Service: <td><input name="highway" type="radio" value="service" onchange="displayData('highway');">
+<tr><td>Droga krajowa: <td><input name="highway" type="radio" value="primary" onchange="displayData('highway');" checked>
+<tr><td>Droga wojewódzka: <td><input name="highway" type="radio" value="secondary" onchange="displayData('highway');">
+<tr><td>Droga powiatowa: <td><input name="highway" type="radio" value="tertiary" onchange="displayData('highway');">
+<tr><td>Niesklasyfikowana:<td><input name="highway" type="radio" value="unclassified" onchange="displayData('highway');">
+<tr><td>W obszarze zamieszkania: <td><input name="highway" type="radio" value="residential" onchange="displayData('highway');">
+<tr><td>Dojazdowa: <td><input name="highway" type="radio" value="service" onchange="displayData('highway');">
 <tr><td>Track: <td><input name="highway" type="radio" value="track" onchange="displayData('highway');">
-<tr><td>Cycleway: <td><input name="highway" type="radio" value="cycleway" onchange="displayData('highway');">
-<tr><td>Path: <td><input name="highway" type="radio" value="path" onchange="displayData('highway');">
+<tr><td>Rowerowa: <td><input name="highway" type="radio" value="cycleway" onchange="displayData('highway');">
+<tr><td>Ścieżka: <td><input name="highway" type="radio" value="path" onchange="displayData('highway');">
 <tr><td>Steps: <td><input name="highway" type="radio" value="steps" onchange="displayData('highway');">
-<tr><td>Ferry: <td><input name="highway" type="radio" value="ferry" onchange="displayData('highway');">
+<tr><td>Przeprawa: <td><input name="highway" type="radio" value="ferry" onchange="displayData('highway');">
 </table>
 </form>
 </div>
@@ -232,16 +238,16 @@ Each segment of the chosen type of highway is drawn.
 Each segment allowed for the chosen type of transport is drawn.
 <form name="transports" id="transports" action="#" method="get" onsubmit="return false;">
 <table>
-<tr><td>Foot: <td><input name="transport" type="radio" value="foot" onchange="displayData('transport');">
-<tr><td>Horse: <td><input name="transport" type="radio" value="horse" onchange="displayData('transport');">
-<tr><td>Wheelchair:<td><input name="transport" type="radio" value="wheelchair" onchange="displayData('transport');">
-<tr><td>Bicycle: <td><input name="transport" type="radio" value="bicycle" onchange="displayData('transport');">
+<tr><td>Pieszo: <td><input name="transport" type="radio" value="foot" onchange="displayData('transport');">
+<tr><td>Konno: <td><input name="transport" type="radio" value="horse" onchange="displayData('transport');">
+<tr><td>Wózek inwalidzki:<td><input name="transport" type="radio" value="wheelchair" onchange="displayData('transport');">
+<tr><td>Rower: <td><input name="transport" type="radio" value="bicycle" onchange="displayData('transport');">
 <tr><td>Moped: <td><input name="transport" type="radio" value="moped" onchange="displayData('transport');">
-<tr><td>Motorcycle:<td><input name="transport" type="radio" value="motorcycle" onchange="displayData('transport');">
-<tr><td>Motorcar: <td><input name="transport" type="radio" value="motorcar" onchange="displayData('transport');" checked>
+<tr><td>Motocykl:<td><input name="transport" type="radio" value="motorcycle" onchange="displayData('transport');">
+<tr><td>Samochód: <td><input name="transport" type="radio" value="motorcar" onchange="displayData('transport');" checked>
 <tr><td>Goods: <td><input name="transport" type="radio" value="goods" onchange="displayData('transport');">
 <tr><td>HGV: <td><input name="transport" type="radio" value="hgv" onchange="displayData('transport');">
-<tr><td>PSV: <td><input name="transport" type="radio" value="psv" onchange="displayData('transport');">
+<tr><td>Pojazd użyteczności publicznej: <td><input name="transport" type="radio" value="psv" onchange="displayData('transport');">
 </table>
 </form>
 </div>
@@ -255,16 +261,16 @@ Each segment allowed for the chosen type of transport is drawn.
 Each barrier blocking the chosen type of transport is drawn.
 <form name="barriers" id="barriers" action="#" method="get" onsubmit="return false;">
 <table>
-<tr><td>Foot: <td><input name="barrier" type="radio" value="foot" onchange="displayData('barrier');">
-<tr><td>Horse: <td><input name="barrier" type="radio" value="horse" onchange="displayData('barrier');">
-<tr><td>Wheelchair:<td><input name="barrier" type="radio" value="wheelchair" onchange="displayData('barrier');">
-<tr><td>Bicycle: <td><input name="barrier" type="radio" value="bicycle" onchange="displayData('barrier');">
+<tr><td>Pieszo: <td><input name="barrier" type="radio" value="foot" onchange="displayData('barrier');">
+<tr><td>Konno: <td><input name="barrier" type="radio" value="horse" onchange="displayData('barrier');">
+<tr><td>Wózek inwalidzki:<td><input name="barrier" type="radio" value="wheelchair" onchange="displayData('barrier');">
+<tr><td>Rower: <td><input name="barrier" type="radio" value="bicycle" onchange="displayData('barrier');">
 <tr><td>Moped: <td><input name="barrier" type="radio" value="moped" onchange="displayData('barrier');">
-<tr><td>Motorcycle:<td><input name="barrier" type="radio" value="motorcycle" onchange="displayData('barrier');">
-<tr><td>Motorcar: <td><input name="barrier" type="radio" value="motorcar" onchange="displayData('barrier');" checked>
+<tr><td>Motocykl:<td><input name="barrier" type="radio" value="motorcycle" onchange="displayData('barrier');">
+<tr><td>Samochód: <td><input name="barrier" type="radio" value="motorcar" onchange="displayData('barrier');" checked>
 <tr><td>Goods: <td><input name="barrier" type="radio" value="goods" onchange="displayData('barrier');">
 <tr><td>HGV: <td><input name="barrier" type="radio" value="hgv" onchange="displayData('barrier');">
-<tr><td>PSV: <td><input name="barrier" type="radio" value="psv" onchange="displayData('barrier');">
+<tr><td>Pojazd użyteczności publicznej: <td><input name="barrier" type="radio" value="psv" onchange="displayData('barrier');">
 </table>
 </form>
 </div>
@@ -273,7 +279,7 @@ Each barrier blocking the chosen type of transport is drawn.
 <div class="hideshow_box">
 <span id="hideshow_turns_show" onclick="hideshow_show('turns');" class="hideshow_show">+</span>
 <span id="hideshow_turns_hide" onclick="hideshow_hide('turns');" class="hideshow_hide">-</span>
-<input type="button" id="turns" onclick="displayData('turns');" value="Display Turn Restrictions">
+<input type="button" id="turns" onclick="displayData('turns');" value="Wyświetlaj zakazy skrętu">
 <div id="hideshow_turns_div" style="display: none;">
 Each turn restrictions is shown with a line indicating the disallowed turn.
 </div>
@@ -282,7 +288,7 @@ Each turn restrictions is shown with a line indicating the disallowed turn.
 <div class="hideshow_box">
 <span id="hideshow_speed_show" onclick="hideshow_show('speed');" class="hideshow_show">+</span>
 <span id="hideshow_speed_hide" onclick="hideshow_hide('speed');" class="hideshow_hide">-</span>
-<input type="button" id="speed" onclick="displayData('speed');" value="Display Speed Limits">
+<input type="button" id="speed" onclick="displayData('speed');" value="Wyświetlaj ograniczenia prędkości">
 <div id="hideshow_speed_div" style="display: none;">
 Each node that joins segments with different speed limits is shown
 along with the speed limit on relevant segments.
@@ -290,7 +296,7 @@ along with the speed limit on relevant segments.
 <table>
 <tr><td><img src="icons/ball-1.png" alt="." ><td>Change of limit
 <tr><td><img src="icons/limit-no.png" alt="()" ><td>No specified limit
-<tr><td><img src="icons/limit-80.png" alt="(80)"><td>80 km/hour speed limit
+<tr><td><img src="icons/limit-80.png" alt="(80)"><td>Ograniczenie prędkości do 80 km/h
 </table>
 </div>
 </div>
@@ -298,7 +304,7 @@ along with the speed limit on relevant segments.
 <div class="hideshow_box">
 <span id="hideshow_weight_show" onclick="hideshow_show('weight');" class="hideshow_show">+</span>
 <span id="hideshow_weight_hide" onclick="hideshow_hide('weight');" class="hideshow_hide">-</span>
-<input type="button" id="weight" onclick="displayData('weight');" value="Display Weight Limits">
+<input type="button" id="weight" onclick="displayData('weight');" value="Wyświetlaj ograniczenia ciężaru">
 <div id="hideshow_weight_div" style="display: none;">
 Each node that joins segments with different weight limits is shown
 along with the weight limit on relevant segments.
@@ -306,7 +312,7 @@ along with the weight limit on relevant segments.
 <table>
 <tr><td><img src="icons/ball-1.png" alt="." ><td>Change of limit
 <tr><td><img src="icons/limit-no.png" alt="()" ><td>No specified limit
-<tr><td><img src="icons/limit-8.0.png" alt="(8.0)"><td>8.0 tonnes weight limit
+<tr><td><img src="icons/limit-8.0.png" alt="(8.0)"><td>Ograniczenie ciężaru do 8.0 ton
 </table>
 </div>
 </div>
@@ -314,7 +320,7 @@ along with the weight limit on relevant segments.
 <div class="hideshow_box">
 <span id="hideshow_height_show" onclick="hideshow_show('height');" class="hideshow_show">+</span>
 <span id="hideshow_height_hide" onclick="hideshow_hide('height');" class="hideshow_hide">-</span>
-<input type="button" id="height" onclick="displayData('height');" value="Display Height Limits">
+<input type="button" id="height" onclick="displayData('height');" value="Wyświetlaj ograniczenia wysokości">
 <div id="hideshow_height_div" style="display: none;">
 Each node that joins segments with different height limits is shown
 along with the height limit on relevant segments.
@@ -322,7 +328,7 @@ along with the height limit on relevant segments.
 <table>
 <tr><td><img src="icons/ball-1.png" alt="." ><td>Change of limit
 <tr><td><img src="icons/limit-no.png" alt="()" ><td>No specified limit
-<tr><td><img src="icons/limit-4.0.png" alt="(4.0)"><td>4.0 m height limit
+<tr><td><img src="icons/limit-4.0.png" alt="(4.0)"><td>Ograniczenie wysokości do 4.0 m
 </table>
 </div>
 </div>
@@ -330,7 +336,7 @@ along with the height limit on relevant segments.
 <div class="hideshow_box">
 <span id="hideshow_width_show" onclick="hideshow_show('width');" class="hideshow_show">+</span>
 <span id="hideshow_width_hide" onclick="hideshow_hide('width');" class="hideshow_hide">-</span>
-<input type="button" id="width" onclick="displayData('width');" value="Display Width Limits">
+<input type="button" id="width" onclick="displayData('width');" value="Wyświetlaj ograniczenia szerokości">
 <div id="hideshow_width_div" style="display: none;">
 Each node that joins segments with different width limits is shown
 along with the width limit on relevant segments.
@@ -338,7 +344,7 @@ along with the width limit on relevant segments.
 <table>
 <tr><td><img src="icons/ball-1.png" alt="." ><td>Change of limit
 <tr><td><img src="icons/limit-no.png" alt="()" ><td>No specified limit
-<tr><td><img src="icons/limit-3.0.png" alt="(3.0)"><td>3.0 m width limit
+<tr><td><img src="icons/limit-3.0.png" alt="(3.0)"><td>Ograniczenie szerokości do 3.0 m
 </table>
 </div>
 </div>
@@ -346,7 +352,7 @@ along with the width limit on relevant segments.
 <div class="hideshow_box">
 <span id="hideshow_length_show" onclick="hideshow_show('length');" class="hideshow_show">+</span>
 <span id="hideshow_length_hide" onclick="hideshow_hide('length');" class="hideshow_hide">-</span>
-<input type="button" id="length" onclick="displayData('length');" value="Display Length Limits">
+<input type="button" id="length" onclick="displayData('length');" value="Wyświetlaj ograniczenia długości">
 <div id="hideshow_length_div" style="display: none;">
 Each node that joins segments with different length limits is shown
 along with the length limit on relevant segments.
@@ -354,7 +360,7 @@ along with the length limit on relevant segments.
 <table>
 <tr><td><img src="icons/ball-1.png" alt="." ><td>Change of limit
 <tr><td><img src="icons/limit-no.png" alt="()" ><td>No specified limit
-<tr><td><img src="icons/limit-9.0.png" alt="(9.0)"><td>9.0 m length limit
+<tr><td><img src="icons/limit-9.0.png" alt="(9.0)"><td>Ograniczenie długości do 9.0 m
 </table>
 </div>
 </div>
@@ -368,11 +374,11 @@ Each segment of the highways with a particular property is drawn.
 <form name="properties" id="properties" action="#" method="get" onsubmit="return false;">
 <table>
 <tr><td>Paved: <td><input name="property" type="radio" value="paved" onchange="displayData('property');" checked>
-<tr><td>Multiple Lanes: <td><input name="property" type="radio" value="multilane" onchange="displayData('property');">
-<tr><td>Bridge: <td><input name="property" type="radio" value="bridge" onchange="displayData('property');">
-<tr><td>Tunnel: <td><input name="property" type="radio" value="tunnel" onchange="displayData('property');">
-<tr><td>Walking Route: <td><input name="property" type="radio" value="footroute" onchange="displayData('property');">
-<tr><td>Bicycle Route: <td><input name="property" type="radio" value="bicycleroute" onchange="displayData('property');">
+<tr><td>Wiele pasów: <td><input name="property" type="radio" value="multilane" onchange="displayData('property');">
+<tr><td>Most: <td><input name="property" type="radio" value="bridge" onchange="displayData('property');">
+<tr><td>Tunel: <td><input name="property" type="radio" value="tunnel" onchange="displayData('property');">
+<tr><td>Trasa piesza: <td><input name="property" type="radio" value="footroute" onchange="displayData('property');">
+<tr><td>Trasa rowerowa: <td><input name="property" type="radio" value="bicycleroute" onchange="displayData('property');">
 </table>
 </form>
 </div>
@@ -388,11 +394,11 @@ Potential problems found by Routino when processing the input data.
 </div>
 
 <div class="hideshow_box">
-<input type="button" id="clear" onclick="displayData('');" value="Clear data">
+<input type="button" id="clear" onclick="displayData('');" value="Wyczyść">
 </div>
 
 <div class="hideshow_box">
-<span class="hideshow_title">Links</span>
+<span class="hideshow_title">Połączenia</span>
 <a id="permalink_url" href="visualiser.html">Link to this map view</a>
 <br>
 <a id="edit_url" target="edit" style="display: none;">Edit this OSM data</a>
@@ -401,7 +407,7 @@ Potential problems found by Routino when processing the input data.
 <div class="hideshow_box">
 <span id="hideshow_help_options_show" onclick="hideshow_show('help_options');" class="hideshow_hide">+</span>
 <span id="hideshow_help_options_hide" onclick="hideshow_hide('help_options');" class="hideshow_show">-</span>
-<span class="hideshow_title">Help</span>
+<span class="hideshow_title">Pomoc</span>
 <div id="hideshow_help_options_div">
 <div class="scrollable">
 <b>Quick Start</b>
@@ -425,7 +431,7 @@ again.
 <div class="tab_content" id="tab_router_div" style="display: none;">
 <div class="hideshow_box">
 <span class="hideshow_title">Routino Router</span>
-To perform routing on the map use the link below.
+Aby wyznaczyć trasę na mapie użyj linku poniżej
 <br>
 <a id="router_url" href="router.html" target="router">Link to this map view</a>
 </div>
@@ -433,7 +439,7 @@ To perform routing on the map use the link below.
 
 <div class="tab_content" id="tab_data_div" style="display: none;">
 <div class="hideshow_box">
-<span class="hideshow_title">Routino Statistics</span>
+<span class="hideshow_title">Statystyki Routino</span>
 <div id="statistics_data"></div>
 <a id="statistics_link" href="statistics.cgi" onclick="displayStatistics();return(false);">Display data statistics</a>
 </div>
@@ -455,7 +461,7 @@ Router: <a href="http://www.routino.org/" target="routino">Routino</a>
 |
 Geo Data: <span id="attribution_data"></span>
 |
-Tiles: <span id="attribution_tile"></span>
+Kafelki: <span id="attribution_tile"></span>
 </div>
 </div>
 
diff --git a/web/www/routino/visualiser.html.ru b/web/www/routino/visualiser.html.ru
index d3e7d41..659158e 100644
--- a/web/www/routino/visualiser.html.ru
+++ b/web/www/routino/visualiser.html.ru
@@ -89,9 +89,15 @@ Only data relevant for routing is displayed and some will therefore be excluded.
 <td><a id="lang_fr_url" href="visualiser.html.fr" title="Francais">Francais</a>
 <td>(FR)
 <tr>
+<td><a id="lang_hu_url" href="visualiser.html.hu" title="Magyar weblap">Magyar</a>
+<td>(HU)
+<tr>
 <td><a id="lang_nl_url" href="visualiser.html.nl" title="Nederlandse web pagina">Nederlands</a>
 <td>(NL)
 <tr>
+<td><a id="lang_pl_url" href="visualiser.html.pl" title="Polski webpage">Polski</a>
+<td>(PL)
+<tr>
 <td><a id="lang_ru_url" href="visualiser.html.ru" title="Русский">Русский</a>
 <td>(RU)
 </table>
diff --git a/xml/Makefile b/xml/Makefile
index 841acfc..0e1d324 100644
--- a/xml/Makefile
+++ b/xml/Makefile
@@ -2,7 +2,7 @@
 #
 # Part of the Routino routing software.
 #
-# This file Copyright 2010-2014 Andrew M. Bishop
+# This file Copyright 2010-2015 Andrew M. Bishop
 #
 # This program is free software: you can redistribute it and/or modify
 # it under the terms of the GNU Affero General Public License as published by
@@ -68,11 +68,11 @@ install: all
 
 clean:
 	rm -f *~
+	rm -f $(SPECIAL_FILES)
 
 ########
 
 distclean: clean
-	rm -f $(SPECIAL_FILES)
 
 ########
 
diff --git a/xml/routino-tagging.xml b/xml/routino-tagging.xml
index 96153a5..e2c4321 100644
--- a/xml/routino-tagging.xml
+++ b/xml/routino-tagging.xml
@@ -5,7 +5,7 @@
 
      Part of the Routino routing software.
      ============================================================
-     This file Copyright 2010-2014 Andrew M. Bishop
+     This file Copyright 2010-2015 Andrew M. Bishop
 
      This program is free software: you can redistribute it and/or modify
      it under the terms of the GNU Affero General Public License as published by
@@ -67,14 +67,6 @@
         <set v="foot_only"/>
       </if>
 
-      <if k="barrier" v="cycle_barrier">
-        <set v="foot_only"/>
-      </if>
-
-      <if k="barrier" v="bicycle_barrier">
-        <set v="foot_only"/>
-      </if>
-
       <if k="barrier" v="foot_only">
         <output k="horse"      v="no"/>
         <output k="wheelchair" v="no"/>
diff --git a/xml/routino-translations.xml b/xml/routino-translations.xml
index b280e6c..e1f2b35 100644
--- a/xml/routino-translations.xml
+++ b/xml/routino-translations.xml
@@ -5,7 +5,7 @@
 
      Part of the Routino routing software.
      ============================================================
-     This file Copyright 2010-2014 Andrew M. Bishop
+     This file Copyright 2010-2015 Andrew M. Bishop
 
      This program is free software: you can redistribute it and/or modify
      it under the terms of the GNU Affero General Public License as published by
@@ -16,7 +16,7 @@
 <routino-translations xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                       xsi:noNamespaceSchemaLocation="http://www.routino.org/xml/routino-translations.xsd">
 
-  <language lang="en">
+  <language lang="en" language="English">
 
     <!-- Copyright of the data being routed, not of this file  -->
     <copyright>
@@ -86,12 +86,13 @@
 
       <title text="%s Route" /> <!-- %s = [shortest|quickest] -->
 
-      <start   string="Start" text="At %s, head %s" /> <!-- 1st %s = [waypoint|junction], 2nd %s = [heading] -->
-      <node    string="At" text="%s, go %s heading %s" /> <!-- 1st %s = [waypoint|junction], 2nd %s = [turn], 3rd %s = [heading] -->
-      <rbnode  string="Leave" text="%s, take the %s exit heading %s" /> <!-- 1st %s = [roundabout], 2nd %s = [first|second|...], 3rd %s = [heading] -->
-      <segment string="Follow" text="%s for %.3f km, %.1f min" /> <!-- 1st %s = street name -->
-      <stop    string="Stop" text="At %s" /> <!-- 1st %s = [waypoint|junction] -->
-      <total   string="Total" text="%.1f km, %.0f minutes" />
+      <start    text="Start at %s, head %s" /> <!-- 1st %s = [waypoint|junction], 2nd %s = [heading] -->
+      <node     text="At %s, go %s heading %s" /> <!-- 1st %s = [waypoint|junction], 2nd %s = [turn], 3rd %s = [heading] -->
+      <rbnode   text="Leave %s, take the %s exit heading %s" /> <!-- 1st %s = [roundabout], 2nd %s = [first|second|...], 3rd %s = [heading] -->
+      <segment  text="Follow %s for %.3f km, %.1f min" /> <!-- 1st %s = street name -->
+      <stop     text="Stop at %s" /> <!-- 1st %s = [waypoint|junction] -->
+      <total    text="Total %.1f km, %.0f minutes" />
+      <subtotal text="%.1f km, %.0f minutes" />
     </output-html>
 
     <!-- GPX output -->
@@ -109,7 +110,7 @@
 
   </language>
 
-  <language lang="de">
+  <language lang="de" language="Deutsch">
 
     <!-- Copyright of the data being routed, not of this file  -->
     <copyright>
@@ -119,7 +120,7 @@
     </copyright>
 
     <!-- Turn directions, 0 = ahead, -2 = left, +/-4 = behind, +2 = right -->
-    <turn direction="-4" string="Spitzkehre nach links" />
+    <turn direction="-4" string="Sehr scharf links" />
     <turn direction="-3" string="Scharf links" />
     <turn direction="-2" string="Links" />
     <turn direction="-1" string="Halb links" />
@@ -127,7 +128,7 @@
     <turn direction="1"  string="Halb rechts" />
     <turn direction="2"  string="Rechts" />
     <turn direction="3"  string="Scharf rechts" />
-    <turn direction="4"  string="Spitzkehre nach rechts" />
+    <turn direction="4"  string="Sehr scharf rechts" />
 
     <!-- Heading directions, 0 = North, -2 = West, +/-4 = South, +2 = East -->
     <heading direction="-4" string="Süd" />
@@ -156,14 +157,14 @@
     <highway type="motorway"     string="Autobahn" />
     <highway type="trunk"        string="Schnellstraße" />
     <highway type="primary"      string="Bundesstraße" />
-    <highway type="secondary"    string="Landstraße" />
+    <highway type="secondary"    string="Landesstraße" />
     <highway type="tertiary"     string="Kreisstraße" />
     <highway type="unclassified" string="Nebenstraße" />
     <highway type="residential"  string="Wohngebietsstraße" />
     <highway type="service"      string="Erschließungsweg" />
-    <highway type="track"        string="Wirtschaftsweg" />
+    <highway type="track"        string="Feld-/Waldweg" />
     <highway type="cycleway"     string="Radweg" />
-    <highway type="path"         string="Weg" />
+    <highway type="path"         string="Weg/Pfad" />
     <highway type="steps"        string="Treppe" />
     <highway type="ferry"        string="Fähre" />
 
@@ -179,12 +180,13 @@
 
       <title text="%s Route" /> <!-- %s = [shortest|quickest] -->
 
-      <start   string="Start" text="Bei %s halten Sie sich Richtung %s" /> <!-- 1st %s = [waypoint|junction], 2nd %s = [heading] -->
-      <node    string="Bei" text="Bei %s wenden Sie sich nach %s Richtung %s" /> <!-- 1st %s = [waypoint|junction], 2nd %s = [turn], 3rd %s = [heading] -->
-      <rbnode  string="Verlassen Sie" text="%s, nehmen Sie die %s Ausfahrt Richtung %s" /> <!-- 1st %s = [roundabout], 2nd %s = [first|second|...], 3rd %s = [heading] -->
-      <segment string="Folgen" text="Folgen Sie der %s für %.3f km bzw. %.1f min" /> <!-- 1st %s = street name -->
-      <stop    string="Stop" text="Sie sind bei %s angekommen" /> <!-- 1st %s = [waypoint|junction] -->
-      <total   string="Gesamt" text="%.1f km, %.0f minuten" />
+      <start    text="Start bei %s halten Sie sich Richtung %s" /> <!-- 1st %s = [waypoint|junction], 2nd %s = [heading] -->
+      <node     text="Bei %s wenden Sie sich nach %s Richtung %s" /> <!-- 1st %s = [waypoint|junction], 2nd %s = [turn], 3rd %s = [heading] -->
+      <rbnode   text="Verlassen Sie %s, nehmen Sie die %s Ausfahrt Richtung %s" /> <!-- 1st %s = [roundabout], 2nd %s = [first|second|...], 3rd %s = [heading] -->
+      <segment  text="Folgen Sie der %s für %.3f km bzw. %.1f min" /> <!-- 1st %s = street name -->
+      <stop     text="Stop Sie sind bei %s angekommen" /> <!-- 1st %s = [waypoint|junction] -->
+      <total    text="Gesamt %.1f km, %.0f minuten" />
+      <subtotal text="%.1f km, %.0f minuten" />
     </output-html>
 
     <!-- GPX output -->
@@ -202,7 +204,7 @@
 
   </language>
 
-  <language lang="fr">
+  <language lang="fr" language="Francais">
 
     <!-- Copyright of the data being routed, not of this file  -->
     <copyright>
@@ -272,12 +274,13 @@
 
       <title text="Itinéraire %s" /> <!-- %s = [shortest|quickest] -->
 
-      <start   string="Débute" text="à %s, direction %s" /> <!-- 1st %s = [waypoint|junction], 2nd %s = [heading] -->
-      <node    string="à" text="%s, aller %s direction %s" /> <!-- 1st %s = [waypoint|junction], 2nd %s = [turn], 3rd %s = [heading] -->
-      <rbnode  string="Quitter" text="%s, prendre le %s sortir direction %s" /> <!-- 1st %s = [roundabout], 2nd %s = [first|second|...], 3rd %s = [heading] -->
-      <segment string="Suivre" text="%s pendant %.3f km, %.1f min" /> <!-- 1st %s = street name -->
-      <stop    string="S'arrêter" text="à %s" /> <!-- 1st %s = [waypoint|junction] -->
-      <total   string="Total" text="%.1f km, %.0f minutes" />
+      <start    text="Débute à %s, direction %s" /> <!-- 1st %s = [waypoint|junction], 2nd %s = [heading] -->
+      <node     text="à %s, aller %s direction %s" /> <!-- 1st %s = [waypoint|junction], 2nd %s = [turn], 3rd %s = [heading] -->
+      <rbnode   text="Quitter %s, prendre le %s sortir direction %s" /> <!-- 1st %s = [roundabout], 2nd %s = [first|second|...], 3rd %s = [heading] -->
+      <segment  text="Suivre %s pendant %.3f km, %.1f min" /> <!-- 1st %s = street name -->
+      <stop     text="S'arrêter à %s" /> <!-- 1st %s = [waypoint|junction] -->
+      <total    text="Total %.1f km, %.0f minutes" />
+      <subtotal text="%.1f km, %.0f minutes" />
     </output-html>
 
     <!-- GPX output -->
@@ -295,7 +298,101 @@
 
   </language>
 
-  <language lang="nl">
+  <language lang="hu" language="Magyar">
+
+    <!-- Copyright of the data being routed, not of this file  -->
+    <copyright>
+      <creator string="Készítő" text="Routino - http://www.routino.org/" />
+      <source  string="Forrás" text="Openstreetmap adatok alapján http://www.openstreetmap.org/" />
+      <license string="Liszenc" text="http://www.openstreetmap.org/copyright" />
+    </copyright>
+
+    <!-- Turn directions, 0 = ahead, -2 = left, +/-4 = behind, +2 = right -->
+    <turn direction="-4" string="Nagyon élesen balra" />
+    <turn direction="-3" string="Élesen balra" />
+    <turn direction="-2" string="Balra" />
+    <turn direction="-1" string="Balra tarts" />
+    <turn direction="0"  string="Egyenesen" />
+    <turn direction="1"  string="Jobbra tarts" />
+    <turn direction="2"  string="Jobbra" />
+    <turn direction="3"  string="Élesen jobbra" />
+    <turn direction="4"  string="Nagyon élesen jobbra" />
+
+    <!-- Heading directions, 0 = North, -2 = West, +/-4 = South, +2 = East -->
+    <heading direction="-4" string="dél" />
+    <heading direction="-3" string="délnyugat" />
+    <heading direction="-2" string="nyugat" />
+    <heading direction="-1" string="északnyugat" />
+    <heading direction="0"  string="észak" />
+    <heading direction="1"  string="északkelet" />
+    <heading direction="2"  string="kelet" />
+    <heading direction="3"  string="délkelet" />
+    <heading direction="4"  string="dél" />
+
+    <!-- Ordinals, 1 = first, 2 = second ... -->
+    <ordinal number="1"  string="első" />
+    <ordinal number="2"  string="második" />
+    <ordinal number="3"  string="harmadik" />
+    <ordinal number="4"  string="negyedik" />
+    <ordinal number="5"  string="ötödik" />
+    <ordinal number="6"  string="hatodik" />
+    <ordinal number="7"  string="hetedik" />
+    <ordinal number="8"  string="nyolcadik" />
+    <ordinal number="9"  string="kilencedik" />
+    <ordinal number="10" string="tizedik" />
+
+    <!-- Highway names -->
+    <highway type="motorway"     string="autópálya" />
+    <highway type="trunk"        string="autóút" />
+    <highway type="primary"      string="főút" />
+    <highway type="secondary"    string="összekötőút" />
+    <highway type="tertiary"     string="bekötőút" />
+    <highway type="unclassified" string="egyéb közút" />
+    <highway type="residential"  string="lakóút" />
+    <highway type="service"      string="szervízút" />
+    <highway type="track"        string="földút" />
+    <highway type="cycleway"     string="kerékpárút" />
+    <highway type="path"         string="ösvény" />
+    <highway type="steps"        string="lépcső" />
+    <highway type="ferry"        string="komp" />
+
+    <!-- The type of route -->
+    <route type="shortest" string="Legrövidebb" /> <!-- For the description and route name -->
+    <route type="quickest" string="Leggyorsabb" /> <!-- For the description and route name -->
+
+    <!-- HTML output -->
+    <output-html>
+      <waypoint type="waypoint"   string="Útpont" /> <!-- For the chosen waypoints -->
+      <waypoint type="junction"   string="Kereszteződés" /> <!-- For the interesting junctions -->
+      <waypoint type="roundabout" string="Körforgalom" /> <!-- For roundabouts -->
+
+      <title text="%s útvonal" /> <!-- %s = [shortest|quickest] -->
+
+      <start    text="Indulás %s, %s felé" /> <!-- 1st %s = [waypoint|junction], 2nd %s = [heading] -->
+      <node     text="Itt %s, menj %s %s felé" /> <!-- 1st %s = [waypoint|junction], 2nd %s = [turn], 3rd %s = [heading] -->
+      <rbnode   text="Kijárat %s, %s kijárat %s felé" /> <!-- 1st %s = [roundabout], 2nd %s = [first|second|...], 3rd %s = [heading] -->
+      <segment  text="Erre %s, %.3f km, %.1f perc" /> <!-- 1st %s = street name -->
+      <!-- TRANSLATION REQUIRED: stop     text="Stop at %s" / --> <!-- 1st %s = [waypoint|junction] -->
+      <total    text="Összesen %.1f km, %.0f perc" />
+      <subtotal text="%.1f km, %.0f perc" />
+    </output-html>
+
+    <!-- GPX output -->
+    <output-gpx>
+      <waypoint type="start" string="Indulás" /> <!-- For the first route waypoint -->
+      <!-- TRANSLATION REQUIRED: waypoint type="inter" string="INTER" / --> <!-- For the intermediate route waypoints -->
+      <waypoint type="trip" string="Utazás" /> <!-- For the other route points -->
+      <!-- TRANSLATION REQUIRED: waypoint type="finish" string="FINISH"/ --> <!-- For the last route waypoint -->
+
+      <desc  text="%s útvonal a kezdő és utolsó pont között" /> <!-- %s = [shortest|quickest] -->
+      <!-- TRANSLATION REQUIRED: name  text="%s route" / --> <!-- %s = [shortest|quickest] -->
+      <!-- TRANSLATION REQUIRED: step  text="%s on '%s' for %.3f km, %.1f min" / --> <!-- 1st %s = [turn], 2nd %s = street name -->
+      <final text="Az egész út %.1f km, %.0f perc" />
+    </output-gpx>
+
+  </language>
+
+  <language lang="nl" language="Nederlands">
 
     <!-- Copyright of the data being routed, not of this file  -->
     <copyright>
@@ -365,12 +462,13 @@
 
       <title text="%s Route" /> <!-- %s = [shortest|quickest] -->
 
-      <start   string="Start" text="Bij %s neemt u de richting %s" /> <!-- 1st %s = [waypoint|junction], 2nd %s = [heading] -->
-      <node    string="Bij" text="Bij %s gaat u %s richting %s" /> <!-- 1st %s = [waypoint|junction], 2nd %s = [turn], 3rd %s = [heading] -->
-      <rbnode  string="Leave" text="Aan de %s, neem de %s afslag richting %s" /> <!-- 1st %s = [roundabout], 2nd %s = [first|second|...], 3rd %s = [heading] -->
-      <segment string="Volg" text="Volgt u de %s voor %.3f km %.1f min" /> <!-- 1st %s = street name -->
-      <stop    string="Stop" text="U bent bij  %s aangekomen" /> <!-- 1st %s = [waypoint|junction] -->
-      <total   string="Totaal" text="%.1f km, %.0f minuten" />
+      <start    text="Start bij %s neemt u de richting %s" /> <!-- 1st %s = [waypoint|junction], 2nd %s = [heading] -->
+      <node     text="Bij %s gaat u %s richting %s" /> <!-- 1st %s = [waypoint|junction], 2nd %s = [turn], 3rd %s = [heading] -->
+      <rbnode   text="Leave aan de %s, neem de %s afslag richting %s" /> <!-- 1st %s = [roundabout], 2nd %s = [first|second|...], 3rd %s = [heading] -->
+      <segment  text="Volg u de %s voor %.3f km %.1f min" /> <!-- 1st %s = street name -->
+      <stop     text="Stop U bent bij %s aangekomen" /> <!-- 1st %s = [waypoint|junction] -->
+      <total    text="Totaal %.1f km, %.0f minuten" />
+      <subtotal text="%.1f km, %.0f minuten" />
     </output-html>
 
     <!-- GPX output -->
@@ -383,12 +481,106 @@
       <desc  text="%s Route tussen 'Start' und 'Finish'" /> <!-- %s = [shortest|quickest] -->
       <name  text="%s Route" /> <!-- %s = [shortest|quickest] -->
       <step  text="%s op '%s' voor %.3f km, %.1f min" /> <!-- 1st %s = [turn], 2nd %s = street name -->
-      <final text="Totaal trip  %.1f km, %.0f minuten" />
+      <final text="Totaal trip %.1f km, %.0f minuten" />
+    </output-gpx>
+
+  </language>
+
+  <language lang="pl" language="Polski">
+
+    <!-- Copyright of the data being routed, not of this file  -->
+    <copyright>
+      <creator string="Twórca" text="Routino - http://www.routino.org/" />
+      <source  string="Źródło" text="Oparte na danych OpenStreetMap ze strony http://www.openstreetmap.org/" />
+      <license string="Licencja" text="http://www.openstreetmap.org/copyright" />
+    </copyright>
+
+    <!-- Turn directions, 0 = ahead, -2 = left, +/-4 = behind, +2 = right -->
+    <turn direction="-4" string="Bardzo ostro w lewo" />
+    <turn direction="-3" string="Ostro w lewo" />
+    <turn direction="-2" string="W lewo" />
+    <turn direction="-1" string="Lekko w lewo" />
+    <turn direction="0"  string="Prosto" />
+    <turn direction="1"  string="Lekko w prawo" />
+    <turn direction="2"  string="W prawo" />
+    <turn direction="3"  string="Ostro w prawo" />
+    <turn direction="4"  string="Bardzo ostro w prawo" />
+
+    <!-- Heading directions, 0 = North, -2 = West, +/-4 = South, +2 = East -->
+    <heading direction="-4" string="Na południe" />
+    <heading direction="-3" string="Na południowy zachód" />
+    <heading direction="-2" string="Na zachód" />
+    <heading direction="-1" string="Na północny zachód" />
+    <heading direction="0"  string="Na północ" />
+    <heading direction="1"  string="Na północny wschód" />
+    <heading direction="2"  string="Na wschód" />
+    <heading direction="3"  string="Na południowy wschód" />
+    <heading direction="4"  string="Na południe" />
+
+    <!-- Ordinals, 1 = first, 2 = second ... -->
+    <ordinal number="1"  string="Pierwszy" />
+    <ordinal number="2"  string="Drugi" />
+    <ordinal number="3"  string="Trzeci" />
+    <ordinal number="4"  string="Czwarty" />
+    <ordinal number="5"  string="Piąty" />
+    <ordinal number="6"  string="Szósty" />
+    <ordinal number="7"  string="Siódmy" />
+    <ordinal number="8"  string="Ósmy" />
+    <ordinal number="9"  string="Dziewiąty" />
+    <ordinal number="10" string="Dziesiąty" />
+
+    <!-- Highway names -->
+    <highway type="motorway"     string="Autostrada" />
+    <highway type="trunk"        string="Droga ekspresowa" />
+    <highway type="primary"      string="Droga krajowa" />
+    <highway type="secondary"    string="Droga powiatowa" />
+    <highway type="tertiary"     string="Droga lokalna" />
+    <highway type="unclassified" string="Droga nieznanego typu" />
+    <highway type="residential"  string="Droga osiedlowa" />
+    <highway type="service"      string="Droga dojazdowa" />
+    <highway type="track"        string="Droga polna" />
+    <highway type="cycleway"     string="Droga rowerowa" />
+    <highway type="path"         string="Ścieżka" />
+    <highway type="steps"        string="Pieszo" />
+    <highway type="ferry"        string="Prom" />
+
+    <!-- The type of route -->
+    <route type="shortest" string="Najkrótsza" /> <!-- For the description and route name -->
+    <route type="quickest" string="Najszybsza" /> <!-- For the description and route name -->
+
+    <!-- HTML output -->
+    <output-html>
+      <waypoint type="waypoint"   string="Punkt" /> <!-- For the chosen waypoints -->
+      <!-- TRANSLATION REQUIRED: waypoint type="junction"   string="Junction" / --> <!-- For the interesting junctions -->
+      <waypoint type="roundabout" string="Rondo" /> <!-- For roundabouts -->
+
+      <title text="%s Trasa" /> <!-- %s = [shortest|quickest] -->
+
+      <start    text="Start %s kieruj się na %s" /> <!-- 1st %s = [waypoint|junction], 2nd %s = [heading] -->
+      <!-- TRANSLATION REQUIRED: node     text="At %s, go %s heading %s" / --> <!-- 1st %s = [waypoint|junction], 2nd %s = [turn], 3rd %s = [heading] -->
+      <!-- TRANSLATION REQUIRED: rbnode   text="Leave %s, take the %s exit heading %s" / --> <!-- 1st %s = [roundabout], 2nd %s = [first|second|...], 3rd %s = [heading] -->
+      <segment  text="Podążaj %s przez %.3f km, %.1f min." /> <!-- 1st %s = street name -->
+      <stop     text="Stop Na %s" /> <!-- 1st %s = [waypoint|junction] -->
+      <total    text="Całkowity %.1f km, %.0f min." />
+      <subtotal text="%.1f km, %.0f min." />
+    </output-html>
+
+    <!-- GPX output -->
+    <output-gpx>
+      <waypoint type="start" string="START" /> <!-- For the first route waypoint -->
+      <waypoint type="inter" string="INTER" /> <!-- For the intermediate route waypoints -->
+      <waypoint type="trip" string="TRIP" /> <!-- For the other route points -->
+      <waypoint type="finish" string="KONIEC"/> <!-- For the last route waypoint -->
+
+      <desc  text="%s trasa pomiędzy 'start' a 'koniec'" /> <!-- %s = [shortest|quickest] -->
+      <name  text="%s trasa" /> <!-- %s = [shortest|quickest] -->
+      <step  text="%s na %s przez %.3f km, %.1f min." /> <!-- 1st %s = [turn], 2nd %s = street name -->
+      <final text="Całkowita podróż %.1f km, %.0f min." />
     </output-gpx>
 
   </language>
 
-  <language lang="ru">
+  <language lang="ru" language="Русский">
 
     <!-- Copyright of the data being routed, not of this file  -->
     <copyright>
@@ -458,12 +650,13 @@
 
       <title text="%s маршрут" /> <!-- %s = [shortest|quickest] -->
 
-      <start   string="Старт" text=" %s, на %s" /> <!-- 1st %s = [waypoint|junction], 2nd %s = [heading] -->
-      <node    string="на" text="%s, %s,  на %s" /> <!-- 1st %s = [waypoint|junction], 2nd %s = [turn], 3rd %s = [heading] -->
-      <!-- TRANSLATION REQUIRED: rbnode  string="Покинуть" text="%s, take the %s exit heading %s" / --> <!-- 1st %s = [roundabout], 2nd %s = [first|second|...], 3rd %s = [heading] -->
-      <segment string="Следуйте" text="по %s %.3f км, %.1f мин" /> <!-- 1st %s = street name -->
-      <stop    string="Стоп" text=" %s" /> <!-- 1st %s = [waypoint|junction] -->
-      <total   string="Всего" text="%.1f км, %.0f минут" />
+      <start    text="Старт  %s, на %s" /> <!-- 1st %s = [waypoint|junction], 2nd %s = [heading] -->
+      <node     text="на %s, %s, на %s" /> <!-- 1st %s = [waypoint|junction], 2nd %s = [turn], 3rd %s = [heading] -->
+      <!-- TRANSLATION REQUIRED: rbnode   text="Leave %s, take the %s exit heading %s" / --> <!-- 1st %s = [roundabout], 2nd %s = [first|second|...], 3rd %s = [heading] -->
+      <segment  text="Следуйте по %s %.3f км, %.1f мин" /> <!-- 1st %s = street name -->
+      <stop     text="Стоп  %s" /> <!-- 1st %s = [waypoint|junction] -->
+      <total    text="Всего %.1f км, %.0f минут" />
+      <subtotal text="%.1f км, %.0f минут" />
     </output-html>
 
     <!-- GPX output -->
diff --git a/xml/routino-translations.xsd b/xml/routino-translations.xsd
index 1c5646e..8519e4c 100644
--- a/xml/routino-translations.xsd
+++ b/xml/routino-translations.xsd
@@ -5,7 +5,7 @@
 
      Part of the Routino routing software.
      ============================================================
-     This file Copyright 2010-2012 Andrew M. Bishop
+     This file Copyright 2010-2015 Andrew M. Bishop
 
      This program is free software: you can redistribute it and/or modify
      it under the terms of the GNU Affero General Public License as published by
@@ -37,6 +37,7 @@
       <xsd:element name="output-gpx"  type="GPXType"       minOccurs="0"/>
     </xsd:sequence>
     <xsd:attribute name="lang"        type="xsd:string"/>
+    <xsd:attribute name="language"    type="xsd:string"/>
   </xsd:complexType>
 
   <!-- The copyright information (of the generated output, not of this file) -->
@@ -103,6 +104,7 @@
       <xsd:element name="segment"  type="HTMLSegmentType"/>
       <xsd:element name="stop"     type="HTMLStopType"/>
       <xsd:element name="total"    type="HTMLTotalType"/>
+      <xsd:element name="subtotal" type="HTMLSubtotalType"/>
     </xsd:sequence>
   </xsd:complexType>
 
@@ -116,32 +118,30 @@
   </xsd:complexType>
 
   <xsd:complexType name="HTMLStartType">
-    <xsd:attribute name="string" type="xsd:string"/>
     <xsd:attribute name="text"   type="xsd:string"/>
   </xsd:complexType>
 
   <xsd:complexType name="HTMLNodeType">
-    <xsd:attribute name="string" type="xsd:string"/>
     <xsd:attribute name="text"   type="xsd:string"/>
   </xsd:complexType>
 
   <xsd:complexType name="HTMLRBNodeType">
-    <xsd:attribute name="string" type="xsd:string"/>
     <xsd:attribute name="text"   type="xsd:string"/>
   </xsd:complexType>
 
   <xsd:complexType name="HTMLSegmentType">
-    <xsd:attribute name="string" type="xsd:string"/>
     <xsd:attribute name="text"   type="xsd:string"/>
   </xsd:complexType>
 
   <xsd:complexType name="HTMLStopType">
-    <xsd:attribute name="string" type="xsd:string"/>
     <xsd:attribute name="text"   type="xsd:string"/>
   </xsd:complexType>
 
   <xsd:complexType name="HTMLTotalType">
-    <xsd:attribute name="string" type="xsd:string"/>
+    <xsd:attribute name="text"   type="xsd:string"/>
+  </xsd:complexType>
+
+  <xsd:complexType name="HTMLSubtotalType">
     <xsd:attribute name="text"   type="xsd:string"/>
   </xsd:complexType>
 

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-grass/routino.git



More information about the Pkg-grass-devel mailing list