Index: src/uk/me/parabola/mkgmap/osmstyle/ConvertedWay.java
===================================================================
--- src/uk/me/parabola/mkgmap/osmstyle/ConvertedWay.java	(revision 4696)
+++ src/uk/me/parabola/mkgmap/osmstyle/ConvertedWay.java	(working copy)
@@ -37,6 +37,7 @@
 	private final Way way;				// with tags after Style processing
 	private final GType gt;
 	private final boolean isRoad;
+	private boolean hasDirection;    // if true way should not be reversed in RoadMerger
 
 	private byte roadClass;			// 0-4
 	private byte roadSpeed;			// 0-7
@@ -79,6 +80,7 @@
 		this.mkgmapAccess = other.mkgmapAccess;
 		this.routeFlags = other.routeFlags;
 		this.overlay = other.overlay;
+		this.hasDirection = other.hasDirection;
 	}
 	
 	public int getIndex(){
@@ -282,4 +284,11 @@
 	public boolean isOverlay() {
 		return overlay;
 	}
+
+	public void setHasDirection(boolean b) {
+		hasDirection = b;
+	}
+	public boolean hasDirection() {
+		return hasDirection;
+	}
 }
Index: src/uk/me/parabola/mkgmap/osmstyle/RoadMerger.java
===================================================================
--- src/uk/me/parabola/mkgmap/osmstyle/RoadMerger.java	(revision 4696)
+++ src/uk/me/parabola/mkgmap/osmstyle/RoadMerger.java	(working copy)
@@ -21,7 +21,9 @@
 import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
+import java.util.Objects;
 import java.util.Set;
+import java.util.stream.Collectors;
 
 import uk.me.parabola.imgfmt.Utils;
 import uk.me.parabola.imgfmt.app.Coord;
@@ -34,7 +36,7 @@
 
 /**
  * Merges connected roads with identical road relevant tags based on the OSM elements 
- * and the GType class.
+ * and the GType class. 
  * 
  * @author WanMil
  */
@@ -41,15 +43,15 @@
 public class RoadMerger {
 	private static final Logger log = Logger.getLogger(RoadMerger.class);
 
-	private static final double MAX_MERGE_ANGLE = 130d;
+	private static final double MAX_MERGE_ANGLE = 130.0;
+
+	private final boolean reverseAllowed;
 	
 	/** maps which coord of a way(id) are restricted - they should not be merged */
 	private final MultiIdentityHashMap<Coord, Long> restrictions = new MultiIdentityHashMap<>();
 
-	/** maps the start point of a road to its road definition */
-	private final MultiIdentityHashMap<Coord, ConvertedWay> startPoints = new MultiIdentityHashMap<>();
-	/** maps the end point of a road to its road definition */
-	private final MultiIdentityHashMap<Coord, ConvertedWay> endPoints = new MultiIdentityHashMap<>();
+	/** maps the start and end points of a road to its road definition */
+	private final MultiIdentityHashMap<Coord, ConvertedWay> sharedPoints = new MultiIdentityHashMap<>();
 
 	/** 
 	 * For these tags two ways need to have an equal value so that their roads can be merged.
@@ -71,20 +73,17 @@
 			"mkgmap:numbers"
 			));
 
-
+	
 	/**
-	 * Checks if two strings are equal ({@code null} supported).
-	 * @param s1 first string ({@code null} allowed)
-	 * @param s2 second string ({@code null} allowed)
-	 * @return {@code true} both strings are equal or both {@code null}; {@code false} both strings are not equal
+	 * Create new road merger.
+	 * 
+	 * @param reverseAllowed set to true if ways can be reversed for merging. Not
+	 *                       that the reversed flag will not be set for them.
 	 */
-	private static boolean stringEquals(String s1, String s2) {
-		if (s1 == null) 
-			return s2 == null;
-		return s1.equals(s2);
+	public RoadMerger(boolean reverseAllowed) {
+		this.reverseAllowed = reverseAllowed;
 	}
 
-
 	/**
 	 * We must not merge roads at via points of restriction relations
 	 * if the way is referenced in the restriction.
@@ -94,10 +93,8 @@
 		for (RestrictionRelation rel : restrictionRels) {
 			Set<Long> restrictionWayIds = rel.getWayIds();
 			for (Coord via: rel.getViaCoords()){
-				HashSet<ConvertedWay> roadAtVia = new HashSet<>();
-				roadAtVia.addAll(startPoints.get(via));
-				roadAtVia.addAll(endPoints.get(via));
-				for (ConvertedWay r: roadAtVia){
+				HashSet<ConvertedWay> roadAtVia = new HashSet<>(sharedPoints.get(via));
+				for (ConvertedWay r : roadAtVia) {
 					long wayId = r.getWay().getId();
 					if (restrictionWayIds.contains(wayId))
 						restrictions.add(via, wayId);
@@ -107,10 +104,7 @@
 	}
 	
 	private boolean hasRestriction(Coord c, Way w) {
-		if (w.isViaWay())
-			return true;
-		List<Long> wayRestrictions = restrictions.get(c);
-		return wayRestrictions.contains(w.getId());
+		return w.isViaWay() || restrictions.get(c).contains(w.getId());
 	}
 
 	/**
@@ -119,23 +113,38 @@
 	 * For the tag it should not matter because all tags used after the
 	 * RoadMerger are compared to be the same.
 	 * 
+	 * @param mergePoint the end point where the two roads are connected
 	 * @param road1 first road (will keep the merged road)
 	 * @param road2 second road
 	 */
-	private void mergeRoads(ConvertedWay road1, ConvertedWay road2) {
+	private void mergeRoads(Coord mergePoint, ConvertedWay road1, ConvertedWay road2) {
 		// Removes the second line,
 		// Merges the points in the first one
-		List<Coord> points2 = road2.getWay().getPoints();
-		Coord mergePoint = points2.get(0);
-		Coord endPoint= points2.get(points2.size()-1);
+		Way way1 = road1.getWay();
+		Way way2 = road2.getWay();
+		if (way1.getFirstPoint() == mergePoint) {
+			assert reverseAllowed : "bad reverse at " + mergePoint.toDegreeString();
+			Collections.reverse(way1.getPoints());
+			
+		}
+		assert way1.getLastPoint() == mergePoint;
 		
-		startPoints.removeMapping(mergePoint, road2);
-		endPoints.removeMapping(endPoint, road2);
-		endPoints.removeMapping(mergePoint, road1);
+		List<Coord> points2 = way2.getPoints();
+		sharedPoints.removeMapping(way2.getFirstPoint(), road2);
+		sharedPoints.removeMapping(way2.getLastPoint(), road2);
+		sharedPoints.removeMapping(mergePoint, road1);
+		Coord endPoint= way2.getLastPoint();
+		if (endPoint == mergePoint) {
+			assert reverseAllowed;
+			Collections.reverse(points2);
+			endPoint = way2.getLastPoint();
+		}
 
 		road1.getPoints().addAll(points2.subList(1, points2.size()));
-		endPoints.add(endPoint, road1);
 		
+		points2.clear(); // makes road2 invalid
+		sharedPoints.add(endPoint, road1);
+		
 		// merge the POI info
 		String wayPOI2 = road2.getWay().getTag(StyledConverter.WAY_POI_NODE_IDS);
 		if (wayPOI2 != null){
@@ -151,48 +160,46 @@
 		
 		// the mergePoint is now used by one highway less
 		mergePoint.decHighwayCount();
-		
-		// road2 is removed - it must not be part of a restriction
-		assert !restrictions.get(endPoint).contains(road2.getWay().getId());
-		
+
 	}
 
 	/**
-	 * Merge the roads and copy the results to the given lists.
-	 * @param resultingWays list for the merged (and not mergeable) ways
-	 * @param resultingGTypes list for the merged (and not mergeable) GTypes
+	 * Merge the roads and copy the results to the given lists. 
+	 * Note that the points of roads are modified!
+	 * @param roads list of roads  
+	 * @param restrictions list of restriction relations
 	 */
-	public List<ConvertedWay>  merge(List<ConvertedWay> convertedWays,
-			List<RestrictionRelation> restrictions) {
-		List<ConvertedWay> result = new ArrayList<>();
-		List<ConvertedWay> roadsToMerge = new ArrayList<>(convertedWays.size());
-		for (int i = 0; i < convertedWays.size(); i++) {
-			ConvertedWay cw = convertedWays.get(i);
-			if (cw.isValid() && cw.isRoad())
-				roadsToMerge.add(cw);
-		}
+	public List<ConvertedWay> merge(List<ConvertedWay> roads, List<RestrictionRelation> restrictions) {
 
+		List<ConvertedWay> roadsToMerge = roads.stream()
+				.filter(cw -> cw.isValid() && cw.isRoad())
+				.collect(Collectors.toList());
+		
 		int noRoadsBeforeMerge = roadsToMerge.size();
 		int numMerges = 0;
 		
 		List<Coord> mergePoints = new ArrayList<>();
-
+		Set<Coord> ignoreAnglePoints = Collections.newSetFromMap(new IdentityHashMap<Coord, Boolean>());
 		// first add all roads with their start and end points to the
 		// start/endpoint lists
+		
 		for (ConvertedWay road : roadsToMerge) {
 			Coord start = road.getWay().getFirstPoint();
 			Coord end = road.getWay().getLastPoint();
 
 			if (start == end) {
-				// do not merge closed roads
-				result.add(road);
+				// do not merge closed roads 
 				continue;
 			}
-
-			mergePoints.add(start);
-			mergePoints.add(end);
-			startPoints.add(start, road);
-			endPoints.add(end, road);
+			for (Coord p : Arrays.asList(start, end)) {
+				if (p.getHighwayCount() >= 2) {
+					if (p.getHighwayCount() == 2) {
+						ignoreAnglePoints.add(p);
+					}
+					mergePoints.add(p);
+					sharedPoints.add(p, road);
+				}
+			}
 		}
 		workoutRestrictionRelations(restrictions);
 
@@ -207,91 +214,85 @@
 				continue;
 			}
 			
-			// get all road that start with the merge point
-			List<ConvertedWay> startRoads = startPoints.get(mergePoint);
-			// get all roads that end with the merge point
-			List<ConvertedWay> endRoads = endPoints.get(mergePoint);
-			
-			if (endRoads.isEmpty() || startRoads.isEmpty()) {
-				// this might happen if another merge operation changed endPoints and/or startPoints
-				mergeCompletedPoints.add(mergePoint);
-				continue;
-			}
-			
+			List<ConvertedWay> roadsAtPoint = sharedPoints.get(mergePoint);
 			// go through all combinations and test which combination is the best
 			double bestAngle = Double.MAX_VALUE;
 			ConvertedWay mergeRoad1 = null;
 			ConvertedWay mergeRoad2 = null;
 			
-			for (ConvertedWay road1 : endRoads) {
+			// go through all possible combinations of the roads at this point
+			for (ConvertedWay road1 : roadsAtPoint) {
+				// check if we can only merge at road end and  
 				// check if the road has a restriction at the merge point
 				// which does not allow us to merge the road at this point
-				if (hasRestriction(mergePoint, road1.getWay())) {
+				if ((!reverseAllowed && road1.getWay().getLastPoint() != mergePoint)
+						|| (hasRestriction(mergePoint, road1.getWay()))) {
 					continue;
 				}
-				
-				List<Coord> points1 = road1.getPoints();
-				
-				// go through all candidates to merge
-				for (ConvertedWay road2 : startRoads) {
-					
-					// the second road is merged into the first road
+				for (ConvertedWay road2 : roadsAtPoint) {
+					// make sure roads are different and meat reverse criteria
+					// The second road is merged into the first road
 					// so only the id of the first road is kept
 					// This also means that the second road must not have a restriction on 
 					// both start and end point
-					if (hasRestriction(mergePoint, road2.getWay())
+					if ((road1 == road2 || !reverseAllowed && road2.getWay().getFirstPoint() != mergePoint)
+							|| (hasRestriction(road2.getWay().getFirstPoint(), road2.getWay()))
 							|| hasRestriction(road2.getWay().getLastPoint(), road2.getWay())) {
 						continue;
 					}
-					
-					// check if both roads can be merged
-					if (isMergeable(mergePoint, road1, road2)){
-						// yes they might be merged
-						// calculate the angle between them 
-						// if there is more then one road to merge the one with the lowest angle is merged 
-						double angle = Math.abs(Utils.getAngle(points1.get(points1.size()-2), mergePoint, road2.getPoints().get(1)));
-						log.debug("Road",road1.getWay().getId(),"and road",road2.getWay().getId(),"are mergeable with angle",angle);
+
+					if (isMergeable(mergePoint, road1, road2)) {
+						// calculate the angle between the roads 
+						// if there is more then one road to merge the pair with the lowest angle is preferred 
+						double angle = getAngle(mergePoint, road1.getWay(), road2.getWay());
+						log.debug("Road", road1.getWay().getId(), "and road", road2.getWay().getId(),
+								"are mergeable with angle", angle);
 						if (angle < bestAngle) {
 							mergeRoad1 = road1;
 							mergeRoad2 = road2;
 							bestAngle = angle;
-						} 
+						}
 					}
 				}
 			}
 			
+			boolean merged = false;
 			// is there a pair of roads that can be merged?
 			if (mergeRoad1 != null && mergeRoad2 != null) {
-				// yes!! => merge them
-				log.debug("Merge",mergeRoad1.getWay().getId(),"and",mergeRoad2.getWay().getId(),"with angle",bestAngle);
-				mergeRoads(mergeRoad1, mergeRoad2);
-				numMerges++;
-			} else {
+				if (bestAngle > MAX_MERGE_ANGLE && !ignoreAnglePoints.contains(mergePoint)) {
+					// The angle exceeds the limit => do not merge
+					// See http://www.mkgmap.org.uk/pipermail/mkgmap-dev/2013q3/018649.html
+					log.info("Do not merge ways", mergeRoad1.getWay().getId(), "and", mergeRoad2.getWay().getId(), "at",
+							mergePoint, "because they span a too big angle", bestAngle);
+				} else {
+					// yes!! => merge them
+					log.debug("Merging", mergeRoad1.getWay().getId(), "and", mergeRoad2.getWay().getId(), "at",
+							mergePoint, "with angle", bestAngle);
+					mergeRoads(mergePoint, mergeRoad1, mergeRoad2);
+					numMerges++;
+					merged = true;
+				}
+			}
+			if (!merged) {
 				// no => do not check this point again
 				mergeCompletedPoints.add(mergePoint);
 			}
 		}
 
-		// copy all merged roads to the roads list
-		for (List<ConvertedWay> mergedRoads : endPoints.values()) {
-			result.addAll(mergedRoads);
-		}
-
-		// sort the roads to ensure that the order of roads is constant for two runs
-		result.sort((o1, o2) -> Integer.compare(o1.getIndex(), o2.getIndex()));
+		List<ConvertedWay> result = roadsToMerge.stream()
+				.filter(ConvertedWay::isValid)
+				.collect(Collectors.toList());
 		
 		// print out some statistics
 		int noRoadsAfterMerge = result.size();
-		log.info("Roads before/after merge:", noRoadsBeforeMerge, "/",
-				noRoadsAfterMerge);
-		int percentage = (int) Math.round((noRoadsBeforeMerge - noRoadsAfterMerge) * 100.0d
-						/ noRoadsBeforeMerge);
-		log.info("Road network reduced by", percentage, "%",numMerges,"merges");
+		log.info("Roads before/after merge:", noRoadsBeforeMerge, "/", noRoadsAfterMerge);
+		int percentage = (int) Math.round((noRoadsBeforeMerge-noRoadsAfterMerge) * 100.0d / noRoadsBeforeMerge);
+		log.info("Road network reduced by", percentage, "%", numMerges, "merges");
 		return result;
 	}
 
 	/**
-	 * Checks if the given {@code otherRoad} can be merged with this road at 
+	 * Checks if the first road can be merged with the 2nd road at 
 	 * the given {@code mergePoint}.
 	 * @param mergePoint the coord where this road and otherRoad might be merged
 	 * @param road1 1st road instance
@@ -299,7 +300,9 @@
 	 * @return {@code true} road1 can be merged with {@code road2};
 	 * 	{@code false} the roads cannot be merged at {@code mergePoint}
 	 */
-	private static boolean isMergeable(Coord mergePoint, ConvertedWay road1, ConvertedWay road2) {
+	private boolean isMergeable(Coord mergePoint, ConvertedWay road1, ConvertedWay road2) {
+		if(road1 == road2)
+			return false;
 		// check if basic road attributes match
 		if (road1.getRoadClass() != road2.getRoadClass() || road1.getRoadSpeed() != road2.getRoadSpeed()) {
 			return false;
@@ -329,10 +332,7 @@
 			return false;
 		}
 
-		if (!isWayTagsMergeable(way1, way2)) 
-			return false;
-		
-		return isAngleOK(mergePoint, way1, way2); 
+		return isWayTagsMergeable(way1, way2);
 	}
 
 
@@ -343,7 +343,7 @@
 	 * @param road2 second road
 	 * @return true if roads can be merged, else false
 	 */
-	private static boolean checkGeometry(Coord mergePoint, ConvertedWay road1, ConvertedWay road2) {
+	private boolean checkGeometry(Coord mergePoint, ConvertedWay road1, ConvertedWay road2) {
 		Way way1 = road1.getWay();
 		Way way2 = road2.getWay();
 		// now check if this road starts or stops at the mergePoint
@@ -362,6 +362,9 @@
 			// roads not mergeable at mergePoint
 			return false;
 		}
+		if (!reverseAllowed && (mergePoint != cEnd || mergePoint != cOtherStart)) {
+			 return false;
+		}
 
 		// check if merging would create a closed way - which should not
 		// be done (why? WanMil)
@@ -369,17 +372,18 @@
 			return false;
 		}
 
-		if (road1.isOneway()){
+		boolean differentDir = (cStart == mergePoint) == (cOtherStart == mergePoint);
+		if (!differentDir)
+			return true;
+		if (road1.isOneway()) {
 			assert road2.isOneway();
 			// oneway must not only be checked for equality
 			// but also for correct direction of both ways
-			if ((cStart == mergePoint) == (cOtherStart == mergePoint)) {
-				// both ways are oneway but they have a different direction
-				log.warn("oneway with different direction", way1.getId(),way2.getId());
-				return false;
-			}
+			// both ways are oneway but they have a different direction
+			log.warn("oneway with different direction", way1.getId(), way2.getId());
+			return false;
 		}
-		return true;
+		return reverseAllowed && !(road1.hasDirection() || road2.hasDirection()); 
 	}
 
 
@@ -435,7 +439,7 @@
 		for (String tagname : mergeTagsEqualValue) {
 			String tag1 = way1.getTag(tagname);
 			String tag2 = way2.getTag(tagname);
-			if (!stringEquals(tag1, tag2)) {
+			if (!Objects.equals(tag1, tag2)) {
 				if (log.isDebugEnabled()){
 					log.debug(tagname, "does not match", way1.getId(), "("
 							+ tag1 + ")", way2.getId(), "(" + tag2
@@ -448,15 +452,13 @@
 	}
 
 	/**
-	 * Checks if the angle between the two {@link Way} objects of both roads 
-	 * is not too sharp so that both roads can be merged. 
+	 * Calculate the angle between the two {@link Way} objects of both roads 
 	 * @param mergePoint the coord where both roads should be merged
 	 * @param way1 1st way
 	 * @param way2 2nd way
-	 * @return {@code true} angle is okay, roads might be merged;
-	 *  {@code false} angle is so sharp that roads must not be merged
+	 * 
 	 */
-	private static boolean isAngleOK(Coord mergePoint, Way way1, Way way2) {
+	private static double getAngle(Coord mergePoint, Way way1, Way way2) {
 		// Check the angle of the two ways
 		Coord cOnWay1;
 		if (way1.getFirstPoint() == mergePoint) {
@@ -471,18 +473,6 @@
 			cOnWay2 = way2.getPoints().get(way2.getPoints().size() - 2);
 		}
 
-		double angle = Math.abs(Utils.getAngle(cOnWay1, mergePoint, cOnWay2));
-		if (angle > MAX_MERGE_ANGLE) {
-			// The angle exceeds the limit => do not merge
-			// Don't know if this is really required or not. 
-			// But the number of merges which do not succeed due to this
-			// restriction is quite low and there have been requests
-			// for this: http://www.mkgmap.org.uk/pipermail/mkgmap-dev/2013q3/018649.html
-
-			log.info("Do not merge ways",way1.getId(),"and",way2.getId(),"because they span a too big angle",angle,"°");
-			return false;
-		}
-
-		return true;
+		return Math.abs(Utils.getAngle(cOnWay1, mergePoint, cOnWay2));
 	}
 }
Index: src/uk/me/parabola/mkgmap/osmstyle/StyledConverter.java
===================================================================
--- src/uk/me/parabola/mkgmap/osmstyle/StyledConverter.java	(revision 4696)
+++ src/uk/me/parabola/mkgmap/osmstyle/StyledConverter.java	(working copy)
@@ -125,6 +125,7 @@
 	private IdentityHashMap<Coord, CoordNode> nodeIdMap = new IdentityHashMap<>();
 
 	public static final String WAY_POI_NODE_IDS = "mkgmap:way-poi-node-ids";
+	private static final short TKM_HAS_DIRECTION = TagDict.getInstance().xlate("mkgmap:has-direction");
 	
 	/** boundary ways with admin_level=2 */
 	private final Set<Way> borders = new LinkedHashSet<>();
@@ -157,6 +158,7 @@
 	private int reportDeadEnds; 
 	private final boolean linkPOIsToWays;
 	private final boolean mergeRoads;
+	private final boolean forceReverseMerge;
 	private final boolean routable;
 	private boolean forceEndNodesRoutingNodes; 
 	private final Tags styleOptionTags;
@@ -166,6 +168,7 @@
 	
 	private LineAdder lineAdder;
 	private NearbyPoiHandler nearbyPoiHandler;
+	private boolean styleSetsDirection;
 
 	static List<String> unusedStyleOptions = new ArrayList<>();
 	static List<String> duplicateKeys = new ArrayList<>();
@@ -185,6 +188,7 @@
 		if (lineRules.containsExpression("$mkgmap:dest_hint='true'")){
 			log.error("At least one 'lines' rule in the style contains the expression mkgmap:dest_hint=true, it should be changed to mkgmap:dest_hint=*");
 		}
+		styleSetsDirection = lineRules.containsExpression("$mkgmap:has-direction='true'");
 		housenumberGenerator = new HousenumberGenerator(props);
 		
 		driveOn = props.getProperty("drive-on", null);
@@ -228,6 +232,7 @@
 		
 		// undocumented option - usually used for debugging only
 		mergeRoads = !props.getProperty("no-mergeroads", false);
+		forceReverseMerge = props.getProperty("force-reverse-merge", false);
 		routable = props.containsKey("route");
 		String styleOption= props.getProperty("style-option",null);
 		styleOptionTags = parseStyleOption(styleOption);
@@ -344,6 +349,7 @@
 				}
 			}
 			ConvertedWay cw = new ConvertedWay(lineIndex++, way, foundType);
+			cw.setHasDirection(way.tagIsLikeYes(TKM_HAS_DIRECTION));
 			cw.setReversed(wasReversed);
 			if (cw.isRoad()){
 				roads.add(cw);
@@ -872,7 +878,19 @@
 	 */
 	private void mergeRoads() {
 		if (mergeRoads) {
-			RoadMerger merger = new RoadMerger();
+			// transfer any hasDirection flag to all lines concerning the same way
+			Set<Long> waysWithDirection = new HashSet<>();
+			if (styleSetsDirection) {
+				for (List<ConvertedWay> list : Arrays.asList(lines, roads)) {
+					list.stream().filter(cw -> cw.hasDirection() && cw.isValid())
+					.forEach(cw -> waysWithDirection.add(cw.getWay().getId()));
+				}
+			}
+			// set direction flag for roads which have overlay lines with direction
+			roads.stream().filter(cw -> waysWithDirection.contains(cw.getWay().getId()))
+					.forEach(cw -> cw.setHasDirection(true));
+					
+			RoadMerger merger = new RoadMerger(styleSetsDirection || forceReverseMerge);
 			roads = merger.merge(roads, restrictions);
 		} else {
 			log.info("Merging roads is disabled");
@@ -1241,7 +1259,7 @@
 			line.setType(replType);
 		line.setPoints(points);
 
-		if (way.tagIsLikeYes(TK_ONEWAY))
+		if (way.tagIsLikeYes(TK_ONEWAY) || way.tagIsLikeYes(TKM_HAS_DIRECTION))
 			line.setDirection(true);
 
 		clipper.clipLine(line, lineAdder);
@@ -1847,9 +1865,9 @@
 		road.setSpeed(cw.getRoadSpeed());
 		
 		if (cw.isOneway()) {
-			road.setDirection(true);
 			road.setOneway();
 		}
+		road.setDirection(cw.isOneway() || way.tagIsLikeYes(TKM_HAS_DIRECTION));
 
 		road.setAccess(cw.getAccess());
 		
@@ -1976,10 +1994,7 @@
 				continue;
 			}
 			lastId = way.getId();
-			List<Coord> points = way.getPoints();
-			for (Coord p:points){
-				p.incHighwayCount();
-			}
+			way.getPoints().forEach(Coord::incHighwayCount);
 		}
 		
 		// go through all duplicated highways and increase the highway counter of all crossroads
@@ -2010,17 +2025,12 @@
 		log.debug("Resetting highway counters");
 		long lastId = 0;
 		for (ConvertedWay cw :roads){
-			if (!cw.isValid())
-				continue;
 			Way way = cw.getWay();
-			if (way.getId() == lastId) {
+			if (!cw.isValid() || way.getId() == lastId) 
 				continue;
-			}
+			
 			lastId = way.getId();
-			List<Coord> points = way.getPoints();
-			for (Coord p:points){
-				p.resetHighwayCount();
-			}
+			way.getPoints().forEach(Coord::resetHighwayCount);
 		}
 	}
 
