Index: trunk/doc/options.txt
===================================================================
--- trunk/doc/options.txt	(revision 3746)
+++ trunk/doc/options.txt	(working copy)
@@ -309,10 +309,17 @@
 ;--copyright-file=file
 : 	Specify copyright messages from a file.
 Note that the first copyright message is not displayed on a device, but is 
-shown in BaseCamp. The copyright file must include at least two lines.
-<p>
-;--license-file=file
-: 	Specify a file which content will be added as license. 
+shown in BaseCamp. The copyright file must include at least two lines and
+be UTF-8 encoded. The following symbols will be substituted by mkgmap:
+$MKGMAP_VERSION$, $JAVA_VERSION$, $YEAR$, $LONG_DATE$, $SHORT_DATE$ and $TIME$.
+Time and date substitutions use the local date and time formats.
+<p>
+;--license-file=file
+: 	Specify a file which content will be added as license.
+The license file must be UTF-8 encoded.
+The following symbols will be substituted by mkgmap:
+$MKGMAP_VERSION$, $JAVA_VERSION$, $YEAR$, $LONG_DATE$, $SHORT_DATE$ and $TIME$.
+Time and date substitutions use the local date and time formats.
 All entries of all maps will be merged in the overview map.
 <p>
 === Optimization options ===
Index: trunk/resources/help/en/options
===================================================================
--- trunk/resources/help/en/options	(revision 3746)
+++ trunk/resources/help/en/options	(working copy)
@@ -306,10 +306,17 @@
 --copyright-file=file
 	Specify copyright messages from a file.
 	Note that the first copyright message is not displayed on a device, but is 
-	shown in BaseCamp. The copyright file must include at least two lines.
-
---license-file=file
-	Specify a file which content will be added as license. 
+	shown in BaseCamp. The copyright file must include at least two lines and
+	be UTF-8 encoded. The following symbols will be substituted by mkgmap:
+	$MKGMAP_VERSION$, $JAVA_VERSION$, $YEAR$, $LONG_DATE$, $SHORT_DATE$ and $TIME$.
+	Time and date substitutions use the local date and time formats.
+
+--license-file=file
+	Specify a file which content will be added as license.
+	The license file must be UTF-8 encoded.
+	The following symbols will be substituted by mkgmap:
+	$MKGMAP_VERSION$, $JAVA_VERSION$, $YEAR$, $LONG_DATE$, $SHORT_DATE$ and $TIME$.
+	Time and date substitutions use the local date and time formats.
 	All entries of all maps will be merged in the overview map.
 
 Optimization options:
Index: trunk/src/uk/me/parabola/mkgmap/build/MapBuilder.java
===================================================================
--- trunk/src/uk/me/parabola/mkgmap/build/MapBuilder.java	(revision 3746)
+++ trunk/src/uk/me/parabola/mkgmap/build/MapBuilder.java	(working copy)
@@ -13,12 +13,12 @@
 
 package uk.me.parabola.mkgmap.build;
 
-import java.io.BufferedReader;
 import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
 import java.nio.file.Files;
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+import java.time.format.FormatStyle;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
@@ -27,6 +27,7 @@
 import java.util.IdentityHashMap;
 import java.util.List;
 import java.util.Set;
+import java.util.function.UnaryOperator;
 
 import uk.me.parabola.imgfmt.ExitException;
 import uk.me.parabola.imgfmt.Utils;
@@ -109,6 +110,7 @@
 public class MapBuilder implements Configurable {
 	private static final Logger log = Logger.getLogger(MapBuilder.class);
 	private static final int CLEAR_TOP_BITS = (32 - 15);
+	private static final LocalDateTime now = LocalDateTime.now();
 	
 	private static final int MIN_SIZE_LINE = 1;
 
@@ -825,25 +827,19 @@
 	 */
 	private void getMapInfo() {
 		if (licenseFileName != null) {
-			File file = new File(licenseFileName);
-
+			List<String> licenseArray = new ArrayList<>();
 			try {
-				BufferedReader reader = Files.newBufferedReader(file.toPath(), Charset.forName("utf-8"));
-				String text;
-
-				// repeat until all lines is read
-				while ((text = reader.readLine()) != null) {
-					if (!text.isEmpty()) {
-						mapInfo.add(text);
-					}
-				}
-
-				reader.close();
-			} catch (FileNotFoundException e) {
-				throw new ExitException("Could not open license file " + licenseFileName);
-			} catch (IOException e) {
-				throw new ExitException("Error reading license file " + licenseFileName);
+				File file = new File(licenseFileName);
+				licenseArray = Files.readAllLines(file.toPath(), StandardCharsets.UTF_8);
 			}
+			catch (Exception e) {
+				throw new ExitException("Error reading license file " + licenseFileName, e);
+			}
+			if ((licenseArray.size() > 0) && licenseArray.get(0).startsWith("\ufeff"))
+				licenseArray.set(0, licenseArray.get(0).substring(1));
+			UnaryOperator<String> replaceVariables = s->s.replace("$MKGMAP_VERSION$", Version.VERSION).replace("$JAVA_VERSION$", System.getProperty("java.version")).replace("$YEAR$", Integer.toString(now.getYear())).replace("$LONGDATE$", now.format(DateTimeFormatter.ofLocalizedDate(FormatStyle.LONG))).replace("$SHORTDATE$", now.format(DateTimeFormatter.ofLocalizedDate(FormatStyle.SHORT))).replace("$TIME$", now.toLocalTime().toString().substring(0, 5));
+			licenseArray.replaceAll(replaceVariables);
+			mapInfo.addAll(licenseArray);
 		} else {
 			mapInfo.add("Map data (c) OpenStreetMap and its contributors");
 			mapInfo.add("http://www.openstreetmap.org/copyright");
Index: trunk/src/uk/me/parabola/mkgmap/main/Main.java
===================================================================
--- trunk/src/uk/me/parabola/mkgmap/main/Main.java	(revision 3746)
+++ trunk/src/uk/me/parabola/mkgmap/main/Main.java	(working copy)
@@ -142,7 +142,13 @@
 			++numExitExceptions;
 		} catch (ExitException e) {
 			++numExitExceptions;
-			System.err.println(e.getMessage());
+			String message = e.getMessage();
+			Throwable cause = e.getCause();
+			while (cause != null) {
+				message += "\r\n" + cause.toString();
+				cause = cause.getCause();
+			}
+			System.err.println(message);
 		}
 		
 		System.out.println("Number of ExitExceptions: " + numExitExceptions);
Index: trunk/src/uk/me/parabola/mkgmap/reader/osm/OsmMapDataSource.java
===================================================================
--- trunk/src/uk/me/parabola/mkgmap/reader/osm/OsmMapDataSource.java	(revision 3746)
+++ trunk/src/uk/me/parabola/mkgmap/reader/osm/OsmMapDataSource.java	(working copy)
@@ -22,8 +22,11 @@
 import java.io.FileReader;
 import java.io.IOException;
 import java.io.InputStream;
-import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
 import java.nio.file.Files;
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+import java.time.format.FormatStyle;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.HashSet;
@@ -30,11 +33,13 @@
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.util.function.UnaryOperator;
 
 import uk.me.parabola.imgfmt.ExitException;
 import uk.me.parabola.imgfmt.FormatException;
 import uk.me.parabola.imgfmt.Utils;
 import uk.me.parabola.log.Logger;
+import uk.me.parabola.mkgmap.Version;
 import uk.me.parabola.mkgmap.general.LevelInfo;
 import uk.me.parabola.mkgmap.general.LoadableMapDataSource;
 import uk.me.parabola.mkgmap.osmstyle.StyleImpl;
@@ -70,6 +75,7 @@
 	private final Set<String> usedTags = new HashSet<>();
 	protected ElementSaver elementSaver;
 	protected OsmReadingHooks osmReadingHooks;
+	private static final LocalDateTime now = LocalDateTime.now();
 
 	/**
 	 * Get the maps levels to be used for the current map.  This can be
@@ -145,19 +151,15 @@
 			List<String> copyrightArray = new ArrayList<>();
 			try {
 				File file = new File(copyrightFileName);
-				BufferedReader reader = Files.newBufferedReader(file.toPath(), Charset.forName("utf-8"));
-
-				String text;
-				while ((text = reader.readLine()) != null) {
-					copyrightArray.add(text);
-				}
-
-				reader.close();
-			} catch (FileNotFoundException e) {
-				throw new ExitException("Could not open copyright file " + copyrightFileName);
-			} catch (IOException e) {
-				throw new ExitException("Error reading copyright file " + copyrightFileName);
+				copyrightArray = Files.readAllLines(file.toPath(), StandardCharsets.UTF_8);
 			}
+			catch (Exception e) {
+				throw new ExitException("Error reading copyright file " + copyrightFileName, e);
+			}
+			if ((copyrightArray.size() > 0) && copyrightArray.get(0).startsWith("\ufeff"))
+				copyrightArray.set(0, copyrightArray.get(0).substring(1));
+			UnaryOperator<String> replaceVariables = s->s.replace("$MKGMAP_VERSION$", Version.VERSION).replace("$JAVA_VERSION$", System.getProperty("java.version")).replace("$YEAR$", Integer.toString(now.getYear())).replace("$LONGDATE$", now.format(DateTimeFormatter.ofLocalizedDate(FormatStyle.LONG))).replace("$SHORTDATE$", now.format(DateTimeFormatter.ofLocalizedDate(FormatStyle.SHORT))).replace("$TIME$", now.toLocalTime().toString().substring(0, 5));
+			copyrightArray.replaceAll(replaceVariables);
 			String[] copyright = new String[copyrightArray.size()];
 			copyrightArray.toArray(copyright);
 			return copyright;
