Index: src/uk/me/parabola/mkgmap/build/MapBuilder.java
===================================================================
--- src/uk/me/parabola/mkgmap/build/MapBuilder.java	(revision 2330)
+++ src/uk/me/parabola/mkgmap/build/MapBuilder.java	(working copy)
@@ -26,6 +26,7 @@
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
+import java.util.Set;
 
 import uk.me.parabola.imgfmt.ExitException;
 import uk.me.parabola.imgfmt.app.Coord;
@@ -110,12 +111,16 @@
 
 	private final java.util.Map<String, Highway> highways = new HashMap<String, Highway>();
 
-	private Country defaultCountry;
+	/** name that is used for cities which name are unknown */
+	private final static String UNKNOWN_CITY_NAME = "";
 
+	private Country defaultCountry;
 	private String countryName = "COUNTRY";
 	private String countryAbbr = "ABC";
 	private String regionName;
 	private String regionAbbr;
+	
+	private Set<String> locationAutofill;
 
 	private int minSizePolygon;
 	private double reducePointError;
@@ -134,6 +139,7 @@
 
 	public MapBuilder() {
 		regionName = null;
+		locationAutofill = Collections.emptySet();
 		locator = new Locator();
 	}
 
@@ -159,7 +165,10 @@
 
 		licenseFileName = props.getProperty("license-file", null);
 		
+		locationAutofill = LocatorUtil.parseAutofillOption(props);
+		
 		locator = new Locator(props);
+		locator.setDefaultCountry(countryName, countryAbbr);
 	}
 
 	/**
@@ -184,6 +193,8 @@
 			}
 		}
 
+		normalizeCountries(src);
+		
 		processCities(map, src);
 		processRoads(map,src);
 		processPOIs(map, src);
@@ -244,6 +255,41 @@
 	}
 
 	/**
+	 * Process the country names of all elements and normalize them
+	 * so that one consistent country name is used for the same country 
+	 * instead of different spellings.
+	 * @param src the source of elements
+	 */
+	private void normalizeCountries(MapDataSource src) {
+		for (MapPoint p : src.getPoints()) {
+			String countryStr = p.getCountry();
+			if (countryStr != null) {
+				countryStr = locator.normalizeCountry(countryStr);
+				p.setCountry(countryStr);
+			}			
+		}
+		
+		for (MapLine l : src.getLines()) {
+			String countryStr = l.getCountry();
+			if (countryStr != null) {
+				countryStr = locator.normalizeCountry(countryStr);
+				l.setCountry(countryStr);
+			}			
+		}		
+
+		// shapes do not have address information
+		// untag the following lines if this is wrong
+//		for (MapShape s : src.getShapes()) {
+//			String countryStr = s.getCountry();
+//			if (countryStr != null) {
+//				countryStr = locator.normalizeCountry(countryStr);
+//				s.setCountry(countryStr);
+//			}			
+//		}		
+
+	}
+	
+	/**
 	 * Processing of Cities
 	 *
 	 * Fills the city list in lbl block that is required for find by name
@@ -255,28 +301,22 @@
 	 */
 	private void processCities(Map map, MapDataSource src) {
 		LBLFile lbl = map.getLblFile();
-
-		locator.setDefaultCountry(countryName, countryAbbr);
 		
-		// collect the names of the cities
-		for (MapPoint p : src.getPoints()) {
-			if(p.isCity() && p.getName() != null)
-				locator.addCityOrPlace(p); // Put the city info the map for missing info 
-		}
-
-		locator.autofillCities(); // Try to fill missing information that include search of next city
+		if (locationAutofill.isEmpty() == false) {
+			// collect the names of the cities
+			for (MapPoint p : src.getPoints()) {
+				if(p.isCity() && p.getName() != null)
+					locator.addCityOrPlace(p); // Put the city info the map for missing info 
+			}
 
+			locator.autofillCities(); // Try to fill missing information that include search of next city
+		}
+		
 		for (MapPoint p : src.getPoints()) 
 		{
 			if(p.isCity() && p.getName() != null)
 			{
-
 				String countryStr = p.getCountry();
-				if (countryStr != null) {
-					countryStr = locator.normalizeCountry(countryStr);
-					p.setCountry(countryStr);
-				}
-
 				Country thisCountry;
 				if(countryStr != null) {
 					thisCountry = lbl.createCountry(countryStr, locator.getCountryISOCode(countryStr));
@@ -311,14 +351,10 @@
 			if(line.isRoad()) {
 				String cityName = line.getCity();
 				String cityCountryName = line.getCountry();
-				if (cityCountryName != null) {
-					cityCountryName = locator.normalizeCountry(cityCountryName);
-					line.setCountry(cityCountryName);
-				}
 				String cityRegionName  = line.getRegion();
 				String zipStr = line.getZip();
 
-				if(cityName == null) {
+				if(cityName == null && locationAutofill.contains("nearest")) {
 					// Get name of next city if untagged
 
 					searchPoint.setLocation(line.getLocation());
@@ -336,6 +372,12 @@
 					}
 				}
 
+				if (cityName == null && (cityCountryName != null || cityRegionName != null)) {
+					// if city name is unknown and region and/or country is known 
+					// use empty name for the city
+					cityName = UNKNOWN_CITY_NAME;
+				}
+				
 				if(cityName != null) {
 
 					Country cc = (cityCountryName == null)? getDefaultCountry() : lbl.createCountry(cityCountryName, locator.getCountryISOCode(cityCountryName));
@@ -380,10 +422,7 @@
 				String zipStr     = p.getZip();
 				String cityStr    = p.getCity();
 
-				if(countryStr != null)
-					countryStr = locator.normalizeCountry(countryStr);
-
-				if(countryStr == null || regionStr == null || (zipStr == null && cityStr == null))
+				if(locationAutofill.contains("nearest") && (countryStr == null || regionStr == null || (zipStr == null && cityStr == null)))
 				{
 					MapPoint nextCity = locator.findNearbyCityByName(p);
 						
@@ -429,6 +468,12 @@
 
 				POIRecord r = lbl.createPOI(p.getName());	
 
+				if (cityStr == null && (countryStr != null || regionStr != null)) {
+					// if city name is unknown and region and/or country is known 
+					// use empty name for the city
+					cityStr = UNKNOWN_CITY_NAME;
+				}
+				
 				if(cityStr != null)
 				{
 					Country thisCountry;
@@ -500,14 +545,14 @@
 			if(hw == null)
 				hw = makeHighway(map, ref);
 			if(hw == null) {
-			    log.warn("Can't create exit " + mep.getName() + " (OSM id " + OSMId + ") on unknown highway " + ref);
+			    log.warn("Can't create exit", mep.getName(), "(OSM id", OSMId, ") on unknown highway", ref);
 			    return;
 			}
 			String exitName = mep.getName();
 			String exitTo = mep.getTo();
 			Exit exit = new Exit(hw);
 			String facilityDescription = mep.getFacilityDescription();
-			log.info("Creating " + ref + " exit " + exitName + " (OSM id " + OSMId +") to " + exitTo + " with facility " + ((facilityDescription == null)? "(none)" : facilityDescription));
+			log.info("Creating", ref, "exit", exitName, "(OSM id", OSMId +") to", exitTo, "with facility", ((facilityDescription == null)? "(none)" : facilityDescription));
 			if(facilityDescription != null) {
 				// description is TYPE,DIR,FACILITIES,LABEL
 				// (same as Polish Format)
@@ -597,7 +642,7 @@
 
 				MapSplitter splitter = new MapSplitter(srcDivPair.getSource(), zoom);
 				MapArea[] areas = splitter.split();
-				log.info("Map region " + srcDivPair.getSource().getBounds() + " split into " + areas.length + " areas at resolution " + zoom.getResolution());
+				log.info("Map region", srcDivPair.getSource().getBounds(), "split into", areas.length, "areas at resolution", zoom.getResolution());
 
 				for (MapArea area : areas) {
 					Subdivision parent = srcDivPair.getSubdiv();
Index: src/uk/me/parabola/mkgmap/build/LocatorUtil.java
===================================================================
--- src/uk/me/parabola/mkgmap/build/LocatorUtil.java	(revision 2330)
+++ src/uk/me/parabola/mkgmap/build/LocatorUtil.java	(working copy)
@@ -38,7 +38,7 @@
 	 * @return the options
 	 */
 	public static Set<String> parseAutofillOption(EnhancedProperties props) {
-		String optionStr = props.getProperty("location-autofill", "bounds");
+		String optionStr = props.getProperty("location-autofill", null);
 		if (optionStr == null) {
 			return Collections.emptySet();
 		}
Index: src/uk/me/parabola/mkgmap/reader/osm/LocationHook.java
===================================================================
--- src/uk/me/parabola/mkgmap/reader/osm/LocationHook.java	(revision 2330)
+++ src/uk/me/parabola/mkgmap/reader/osm/LocationHook.java	(working copy)
@@ -15,11 +15,11 @@
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
-import java.util.Set;
 import java.util.Map.Entry;
+import java.util.Set;
+
 import uk.me.parabola.imgfmt.app.Coord;
 import uk.me.parabola.log.Logger;
-import uk.me.parabola.mkgmap.build.LocatorUtil;
 import uk.me.parabola.mkgmap.reader.osm.boundary.BoundaryGrid;
 import uk.me.parabola.mkgmap.reader.osm.boundary.BoundaryQuadTree;
 import uk.me.parabola.mkgmap.reader.osm.boundary.BoundaryUtil;
@@ -44,7 +44,6 @@
 	private String boundaryDirName;
 
 	
-	public static final String BOUNDS_OPTION = "bounds";
 	/** this static object is used to synchronize the check if the bounds directory contains any bounds */
 	private static final Object BOUNDS_CHECK_LOCK = new Object();
 	
@@ -56,51 +55,41 @@
 	private EnhancedProperties props;
 
 	public boolean init(ElementSaver saver, EnhancedProperties props) {
-		if (props.containsKey("index") == false) {
-			log.info("Disable LocationHook because index option is not set.");
+		boundaryDirName = props.getProperty("bounds");
+		
+		if (boundaryDirName == null) {
+			// bounds property not set
 			return false;
 		}
-
+		
 		this.props = props;
 		this.saver = saver;
 
-		autofillOptions.addAll(LocatorUtil.parseAutofillOption(props));
-
-		if (autofillOptions.isEmpty()) {
-			log.info("Disable LocationHook because no location-autofill option set.");
-			return false;
-		}
-
-		if (autofillOptions.contains(BOUNDS_OPTION)) {
-			boundaryDirName = props.getProperty("bounds", "bounds");
-			long t1 = System.currentTimeMillis();
-
-			synchronized (BOUNDS_CHECK_LOCK) {
-				// checking of the boundary dir is expensive
-				// check once only and reuse the result
-				if (boundaryDirName.equals(checkedBoundaryDirName)) {
-					if (checkBoundaryDirOk == false) {
-						log.error("Disable LocationHook because boundary directory is unusable. Dir: "+boundaryDirName);
-						return false;
-					}
-				} else {
-					checkedBoundaryDirName = boundaryDirName;
-					checkBoundaryDirOk = false;
+		long t1 = System.currentTimeMillis();
 
-					// boundaryDir.list() is much quicker than boundaryDir.listFiles(FileFilter)
-					List<String> boundaryFiles = BoundaryUtil.getBoundaryDirContent(boundaryDirName);
-					if (boundaryFiles == null || boundaryFiles.size() == 0) {
-						log.error("LocationHook is disabled because no boundary files are available. Dir: "
-								+ boundaryDirName);
-						return false;
-					}
+		synchronized (BOUNDS_CHECK_LOCK) {
+			// checking of the boundary dir is expensive
+			// check once only and reuse the result
+			if (boundaryDirName.equals(checkedBoundaryDirName)) {
+				if (checkBoundaryDirOk == false) {
+					log.error("Disable LocationHook because bounds directory is unusable. Dir: "+boundaryDirName);
+					return false;
+				}
+			} else {
+				checkedBoundaryDirName = boundaryDirName;
+				checkBoundaryDirOk = false;
 
-					// passed all checks => boundaries are okay
-					checkBoundaryDirOk = true;
+				List<String> boundaryFiles = BoundaryUtil.getBoundaryDirContent(boundaryDirName);
+				if (boundaryFiles == null || boundaryFiles.size() == 0) {
+					log.error("LocationHook is disabled because no bounds files are available. Dir: "
+							+ boundaryDirName);
+					return false;
 				}
+					// passed all checks => boundaries are okay
+				checkBoundaryDirOk = true;
 			}
-			log.info("Checking bounds dir took", (System.currentTimeMillis() - t1), "ms");
 		}
+		log.info("Checking bounds dir took", (System.currentTimeMillis() - t1), "ms");
 		return true;
 	}
 
@@ -108,10 +97,8 @@
 		long t1 = System.currentTimeMillis();
 		log.info("Starting with location hook");
 
-		if (autofillOptions.contains(BOUNDS_OPTION)) {
-			boundaryGrid = new BoundaryGrid(boundaryDirName, saver.getBoundingBox(), props);
-			processLocationRelevantElements();
-		}
+		boundaryGrid = new BoundaryGrid(boundaryDirName, saver.getBoundingBox(), props);
+		processLocationRelevantElements();
 
 		long dt = (System.currentTimeMillis() - t1);
 		log.info("======= LocationHook Stats =====");             
Index: src/uk/me/parabola/mkgmap/reader/osm/boundary/BoundaryPreparer.java
===================================================================
--- src/uk/me/parabola/mkgmap/reader/osm/boundary/BoundaryPreparer.java	(revision 2330)
+++ src/uk/me/parabola/mkgmap/reader/osm/boundary/BoundaryPreparer.java	(working copy)
@@ -109,9 +109,9 @@
 		if (workoutOnly)
 			return true;
 		this.boundaryFilename = props.getProperty("createboundsfile", null);
-		this.inDir = props.getProperty("bounds", "bounds");
-		this.outDir = props.getProperty("bounds", "bounds");
-		return boundaryFilename != null;
+		this.inDir = props.getProperty("bounds", null);
+		this.outDir = props.getProperty("bounds", null);
+		return boundaryFilename != null && this.inDir != null && this.outDir != null;
 	}
 
 	public void run() {
Index: src/uk/me/parabola/mkgmap/reader/osm/boundary/BoundaryUtil.java
===================================================================
--- src/uk/me/parabola/mkgmap/reader/osm/boundary/BoundaryUtil.java	(revision 2330)
+++ src/uk/me/parabola/mkgmap/reader/osm/boundary/BoundaryUtil.java	(working copy)
@@ -440,6 +440,7 @@
 			log.error("boundary directory/zip does not exist: " + dirName);
 		else{		
 			if (boundaryDir.isDirectory()){
+				// boundaryDir.list() is much quicker than boundaryDir.listFiles(FileFilter)
 				String[] allNames = boundaryDir.list();
 				for (String name: allNames){
 					if (name.endsWith(".bnd"))
