Index: src/uk/me/parabola/mkgmap/osmstyle/StyledConverter.java
===================================================================
--- src/uk/me/parabola/mkgmap/osmstyle/StyledConverter.java	(revision 2644)
+++ src/uk/me/parabola/mkgmap/osmstyle/StyledConverter.java	(working copy)
@@ -228,9 +228,6 @@
 					// If not already copied, do so now
 					if (el == way)
 						el = way.copy();
-
-					// Not sure if this is needed as this really is a completely new way.
-					// originalWay.put(el, way);
 				}
 				postConvertRules(el, type);
 				addConvertedWay((Way) el, type);
@@ -276,9 +273,6 @@
 					// If not already copied, do so now
 					if (el == node)
 						el = node.copy();
-
-					// Not sure if this is needed as this really is a completely new way.
-					// originalWay.put(el, way);
 				}
 				postConvertRules(el, type);
 				addPoint((Node) el, type);
@@ -698,7 +692,10 @@
 	}
 
 	void addRoad(Way way, GType gt) {
-
+		if (way.getPoints().size() < 2){
+			log.warn("road has < 2 points ",way.getId(),"(discarding)");
+			return;
+		}
 		String oneWay = way.getTag("oneway");
 		if("-1".equals(oneWay) || "reverse".equals(oneWay)) {
 			// it's a oneway street in the reverse direction
@@ -890,15 +887,15 @@
 								// insert a new point after the POI to
 								// make a short stub segment
 								p1 = p.makeBetweenPoint(p1, stubSegmentLength / dist);
+								p1.incHighwayCount();
 								points.add(i + 1, p1);
 							}
 
 							// now split the way at the next point to
 							// limit the region that has restricted
 							// access
-							if(!p.equals(p1) &&
-							   ((i + 2) == points.size() ||
-								!p1.equals(points.get(i + 2)))) {
+							if((i+2 < points.size() && 
+									safeToSplitWay(points, i+1, 0, points.size()-1))) {
 								Way tail = splitWayAt(way, i + 1);
 								// recursively process tail of way
 								addRoad(tail, gt);
@@ -918,8 +915,14 @@
 						// across the POI when both the start and end
 						// points are either side of the POI and both
 						// are in the restricted region
-						p.incHighwayCount();
-
+						if (p.getHighwayCount() < 2){
+							if (i == 0|| i == points.size()-1 ||
+									safeToSplitWay(points, i, 0, points.size()-1))
+								p.incHighwayCount();
+							else {
+								points.set(i,new Coord(p.getLatitude(),p.getLongitude()));
+							}
+						}
 						// copy all of the POI's access restrictions
 						// to the way segment
 						for (AccessMapping anAccessMap : accessMap) {
@@ -948,19 +951,15 @@
 								// insert a new point to make a short
 								// stub segment
 								p1 = p1.makeBetweenPoint(p, stubSegmentLength / dist);
+								p1.incHighwayCount();
 								points.add(i + 1, p1);
-								// as p1 is now no longer a CoordPOI,
-								// the split below will be deferred
-								// until the next iteration of the
-								// loop (which is what we want!)
+								continue;
 							}
 
 							// now split the way here if it is not the
 							// first point in the way
-							if(p1 instanceof CoordPOI &&
-							   i > 0 &&
-							   !p.equals(points.get(i - 1)) &&
-							   !p.equals(p1)) {
+							if(i > 0 &&
+							   safeToSplitWay(points, i, 0, points.size() - 1)) {
 								Way tail = splitWayAt(way, i);
 								// recursively process tail of road
 								addRoad(tail, gt);
@@ -1034,6 +1033,8 @@
 			// same object not just the same coordinates)
 			for(int p1I = 0; !wayWasSplit && p1I < (numPointsInWay - 1); p1I++) {
 				Coord p1 = wayPoints.get(p1I);
+				if (p1.getHighwayCount() < 2)
+					continue;
 				for(int p2I = p1I + 1; !wayWasSplit && p2I < numPointsInWay; p2I++) {
 					if(p1 == wayPoints.get(p2I)) {
 						// way is a loop or intersects itself 
@@ -1059,7 +1060,8 @@
 								--p2I;
 								// but number of points has reduced
 								--numPointsInWay;
-
+								if (p2I + 1 == numPointsInWay) 
+									wayPoints.get(p2I).incHighwayCount();
 								// if wayPoints[p2I] is the last point
 								// in the way and it is so close to p1
 								// that a short arc would be produced,
@@ -1107,9 +1109,12 @@
 			floor = 0;
 		if(ceiling >= points.size())
 			ceiling = points.size() - 1;
+		double arcLength = 0;
+		Coord prev = candidate;
 		// test points after pos
 		for(int i = pos + 1; i <= ceiling; ++i) {
 			Coord p = points.get(i);
+			arcLength += p.distance(prev);
 			if(i == ceiling || p.getHighwayCount() > 1) {
 				// point is going to be a node
 				if(candidate.equals(p)) {
@@ -1119,14 +1124,16 @@
 				// no need to test further
 				break;
 			}
-			else if(!candidate.equals(p)) {
-				// no need to test further
-				break;
-			}
+			prev = p;
 		}
+		if (arcLength < minimumArcLength)
+			return false;
+		prev = candidate;
+		arcLength = 0;
 		// test points before pos
 		for(int i = pos - 1; i >= floor; --i) {
 			Coord p = points.get(i);
+			arcLength += p.distance(prev);
 			if(i == floor || p.getHighwayCount() > 1) {
 				// point is going to be a node
 				if(candidate.equals(p)) {
@@ -1136,13 +1143,9 @@
 				// no need to test further
 				break;
 			}
-			else if(!candidate.equals(p)) {
-				// no need to test further
-				break;
-			}
 		}
 
-		return true;
+		return arcLength >= minimumArcLength;
 	}
 
 	String getDebugName(Way way) {
@@ -1901,7 +1904,8 @@
 				points.get(numPoints - 1).setTreatAsNode(true);
 				// non-end points have 2 arcs but ignore points that
 				// are only in a single way
-				for (int i = numPoints - 2; i >= 1; --i) {
+				Coord prev = points.get(numPoints - 1);
+				for (int i = numPoints - 2; i >= 0; --i) {
 					Coord p = points.get(i);
 					// if this point is a CoordPOI it may become a
 					// node later even if it isn't actually a connection
@@ -1910,6 +1914,25 @@
 					// if it is on a boundary it will become a node later
 					if (p.getHighwayCount() > 1 || p instanceof CoordPOI || p.getOnBoundary())
 						p.setTreatAsNode(true);
+					// remove equal points
+					if (p.equals(prev)) {
+						int removePos = -1;
+						if (prev.isTreatAsNode() == false){
+							removePos = i+1;
+							prev = p;
+						}
+						else if (p.isTreatAsNode() == false){
+							removePos = i;
+						}
+						if (removePos >= 0){
+							points.remove(removePos);
+							if (log.isInfoEnabled())
+								log.info("Way", way.toBrowseURL(), "has consecutive equal points at node numbers",i+1, "and",i+2,"(discarding",removePos+1,")");						
+							modifiedRoads.put(way.getId(), way);
+						}
+					} else {
+						prev = p;
+					}
 				}
 			}
 		}
@@ -1960,7 +1983,16 @@
 
 						if (replacement != null) {
 							assert !p.getOnBoundary() : "Boundary node replaced";
+							if ((p instanceof CoordPOI || replacement instanceof CoordPOI) &&"true".equals(way.getTag("mkgmap:way-has-pois"))){
+								if (p instanceof CoordPOI && replacement instanceof CoordPOI)
+									log.warn("CoordPOI", ((CoordPOI)p).getNode().getId(), "replaced by other CoordPOI",((CoordPOI) replacement).getNode().getId(), "in way",  way.toBrowseURL());
+								else if (p instanceof CoordPOI)
+									log.warn("CoordPOI", ((CoordPOI)p).getNode().getId(),"replaced by simple coord in way", way.toBrowseURL());
+								else 
+									log.warn("CoordPOI", ((CoordPOI) replacement).getNode().getId(), "replaces Coord in way with other CoordPOI in way", way.toBrowseURL());
+							}
 							p = replacement;
+							p.incHighwayCount();
 							// replace point in way
 							points.set(i, p);
 							if (i == 0)
@@ -2067,32 +2099,46 @@
 							break; // give up with this way
 						}
 					}
-
 					// reset arc length
 					arcLength = 0;
 
 					// do the merge
 					++numNodesMerged;
 					if (p.getOnBoundary()) {
+						Coord replacement = p;
+						if (replacement instanceof CoordPOI && previousNode.getHighwayCount() >= 2){
+							log.warn("exchanging CoordPOI " + ((CoordPOI)replacement).getNode().getId() + " by normal Coord because it would be on a short arc.");
+							replacement = new Coord(p.getLatitude(),p.getLongitude());
+							replacement.setOnBoundary(true);
+							replacement.incHighwayCount();
+							points.set(i, replacement);
+						}
 						// current point is a boundary node so we need
 						// to merge the previous node into this node
-						replacements.put(previousNode, p);
+						replacements.put(previousNode, replacement);
 						previousNode.setReplaced(true);
-						p.setTreatAsNode(true);
+						replacement.setTreatAsNode(true);
 						// remove the preceding point(s) back to and
 						// including the previous node
 						for(int j = i - 1; j >= previousNodeIndex; --j) {
 							points.remove(j);
 						}
 					} else {
+						Coord replacement = previousNode;
+						if (replacement instanceof CoordPOI && p.getHighwayCount() >= 2){
+							log.warn("exchanging CoordPOI " + ((CoordPOI)replacement).getNode().getId() + " by normal Coord because it would be on a short arc.");
+							replacement = new Coord(p.getLatitude(),p.getLongitude());
+							replacement.setOnBoundary(previousNode.getOnBoundary());
+							replacement.incHighwayCount();
+							points.set(previousNodeIndex, replacement);
+						}
+
 						// current point is not on a boundary so merge
 						// this node into the previous one
-						replacements.put(p, previousNode);
+						replacements.put(p, replacement);
 						p.setReplaced(true);
-						previousNode.setTreatAsNode(true);
-						// reset previous point to be the previous
-						// node
-						previousPoint = previousNode;
+						replacement.setTreatAsNode(true);
+						previousPoint = replacement;
 						// remove the point(s) back to the previous
 						// node
 						for (int j = i; j > previousNodeIndex; --j) {
