Index: src/uk/me/parabola/imgfmt/app/net/RoadDef.java
===================================================================
--- src/uk/me/parabola/imgfmt/app/net/RoadDef.java	(revision 2942)
+++ src/uk/me/parabola/imgfmt/app/net/RoadDef.java	(working copy)
@@ -118,7 +118,6 @@
 	private boolean linkRoad;
 	private boolean synthesised;
 	private boolean flareCheck;
-	private boolean deadEndCheck;
 	private Set<String> messageIssued;
 
 	private final List<Offset> rgnOffsets = new ArrayList<Offset>(4);
@@ -723,14 +722,6 @@
 		return flareCheck;
 	}
 
-	public void doDeadEndCheck(boolean dec) {
-		deadEndCheck = dec;
-	}
-
-	public boolean doDeadEndCheck() {
-		return deadEndCheck;
-	}
-
 	public boolean messagePreviouslyIssued(String key) {
 		if(messageIssued == null)
 			messageIssued = new HashSet<String>();
Index: src/uk/me/parabola/imgfmt/app/net/RouteNode.java
===================================================================
--- src/uk/me/parabola/imgfmt/app/net/RouteNode.java	(revision 2942)
+++ src/uk/me/parabola/imgfmt/app/net/RouteNode.java	(working copy)
@@ -826,83 +826,6 @@
 		}
 	}
 
-	public void reportDeadEnds(int level) {
-
-		if(level > 0) {
-			boolean noWayOut = true;
-			boolean noWayIn = true;
-			List<RouteArc> maybeDeadEndArcs = new ArrayList<RouteArc>();
-
-			for(RouteArc a : arcs) {
-
-				if(!a.getRoadDef().isSynthesised()) {
-
-					if(a.getRoadDef().isOneway() ||
-					   a.getRoadDef().isRoundabout()) {
-						// it's a oneway road
-						if(a.getRoadDef().doDeadEndCheck()) {
-							// it's not been excluded from the check
-							maybeDeadEndArcs.add(a);
-						}
-					}
-					else {
-						// it's not a oneway road so traffic can both
-						// leave this node and arrive at this node
-						noWayOut = noWayIn = false;
-					}
-
-					if(a.isForward()) {
-						// traffic can leave this node
-						noWayOut = false;
-					}
-					else {
-						// traffic can arrive at this node
-						noWayIn = false;
-					}
-				}
-			}
-
-			if(maybeDeadEndArcs.isEmpty()) {
-				// nothing to complain about
-				return;
-			}
-
-			if(noWayIn) {
-				if(maybeDeadEndArcs.size() == 1) {
-					if(level > 1)
-						log.warn("Oneway road " + maybeDeadEndArcs.get(0).getRoadDef() + " comes from nowhere at " + coord.toOSMURL());
-				}
-				else {
-					String roads = null;
-					for(RouteArc a : maybeDeadEndArcs) {
-						if(roads == null)
-							roads = "" + a.getRoadDef();
-						else
-							roads += ", " + a.getRoadDef();
-					}
-					log.warn("Oneway roads " + roads + " come from nowhere at " + coord.toOSMURL());
-				}
-			}
-
-			if(noWayOut) {
-				if(maybeDeadEndArcs.size() == 1) {
-					if(level > 1)
-						log.warn("Oneway road " + maybeDeadEndArcs.get(0).getRoadDef() + " goes nowhere at " + coord.toOSMURL());
-				}
-				else {
-					String roads = null;
-					for(RouteArc a : maybeDeadEndArcs) {
-						if(roads == null)
-							roads = "" + a.getRoadDef();
-						else
-							roads += ", " + a.getRoadDef();
-					}
-					log.warn("Oneway roads " + roads + " go nowhere at " + coord.toOSMURL());
-				}
-			}
-		}
-	}
-
 	public void addThroughRoute(long roadIdA, long roadIdB) {
 		if(throughRoutes == null)
 			throughRoutes = new ArrayList<RouteArc[]>();
Index: src/uk/me/parabola/mkgmap/general/MapRoad.java
===================================================================
--- src/uk/me/parabola/mkgmap/general/MapRoad.java	(revision 2942)
+++ src/uk/me/parabola/mkgmap/general/MapRoad.java	(working copy)
@@ -136,10 +136,6 @@
 		roadDef.doFlareCheck(fc);
 	}
 
-	public void doDeadEndCheck(boolean dec) {
-		roadDef.doDeadEndCheck(dec);
-	}
-
 	public void setLinkRoad(boolean lr) {
 		roadDef.setLinkRoad(lr);
 	}
Index: src/uk/me/parabola/mkgmap/general/RoadNetwork.java
===================================================================
--- src/uk/me/parabola/mkgmap/general/RoadNetwork.java	(revision 2942)
+++ src/uk/me/parabola/mkgmap/general/RoadNetwork.java	(working copy)
@@ -67,7 +67,6 @@
 	private int maxFlareLengthRatio ;
 	private boolean reportSimilarArcs;
 	private boolean outputCurveData;
-	private int reportDeadEnds ;
 
 	public void config(EnhancedProperties props) {
 		String ath = props.getProperty("adjust-turn-headings");
@@ -81,8 +80,6 @@
 		checkRoundaboutFlares = props.getProperty("check-roundabout-flares", false);
 		maxFlareLengthRatio = props.getProperty("max-flare-length-ratio", 0);
 
-		reportDeadEnds = props.getProperty("report-dead-ends", 1);
-
 		reportSimilarArcs = props.getProperty("report-similar-arcs", false);
 
 		outputCurveData = !props.getProperty("no-arc-curves", false);
@@ -238,8 +235,6 @@
 					node.checkRoundaboutFlares(maxFlareLengthRatio);
 				if(reportSimilarArcs)
 					node.reportSimilarArcs();
-				if(reportDeadEnds != 0)
-					node.reportDeadEnds(reportDeadEnds);
 			}
 			if(adjustTurnHeadings != 0)
 				node.tweezeArcs(adjustTurnHeadings);
Index: src/uk/me/parabola/mkgmap/osmstyle/StyledConverter.java
===================================================================
--- src/uk/me/parabola/mkgmap/osmstyle/StyledConverter.java	(revision 2942)
+++ src/uk/me/parabola/mkgmap/osmstyle/StyledConverter.java	(working copy)
@@ -80,7 +80,7 @@
 	private final MapCollector collector;
 
 	private Clipper clipper = Clipper.NULL_CLIPPER;
-	private Area bbox;
+	private Area bbox = new Area(-90.0d, -180.0d, 90.0d, 180.0d); // default is planet
 
 	// restrictions associates lists of turn restrictions with the
 	// Coord corresponding to the restrictions' 'via' node
@@ -134,6 +134,7 @@
 	private boolean driveOnLeft;
 	private boolean driveOnRight;
 	private final boolean checkRoundabouts;
+	private int reportDeadEnds; 
 	private final boolean linkPOIsToWays;
 	private final boolean mergeRoads;
 
@@ -166,7 +167,8 @@
 			NODHeader.setDriveOnLeft(driveOnLeft);
 		driveOnRight = props.getProperty("drive-on-right") != null;
 		checkRoundabouts = props.getProperty("check-roundabouts") != null;
-
+		reportDeadEnds = props.getProperty("report-dead-ends", 1);  
+		
 		LineAdder overlayAdder = style.getOverlays(lineAdder);
 		if (overlayAdder != null)
 			lineAdder = overlayAdder;
@@ -241,11 +243,6 @@
 		if (foundType.getFeatureKind() == FeatureKind.POLYLINE) {
 		    if(foundType.isRoad() &&
 			   !MapObject.hasExtendedType(foundType.getType())){
-				if (way.isBoolTag("oneway")) {
-					if (checkFixmeCoords(way))
-						way.addTag("mkgmap:dead-end-check", "false");
-				}
-		    	
 		    	roads.add(way);
 		    	roadTypes.add(new GType(foundType));
 		    }
@@ -453,7 +450,26 @@
 		
 		if (el instanceof Way && type.isRoad()) {
 			Way way = (Way) el;
+
+			String oneWay = way.getTag("oneway");
+			if("-1".equals(oneWay) || "reverse".equals(oneWay)) {
+				// it's a oneway street in the reverse direction
+				// so reverse the order of the nodes and change
+				// the oneway tag to "yes"
+				way.reverse();
+				way.addTag("oneway", "yes");
+				if("roundabout".equals(way.getTag("junction")))
+					log.warn("Roundabout", way.getId(), "has reverse oneway tag (" + way.getPoints().get(0).toOSMURL() + ")");
+			}
+
+			if (way.isBoolTag("oneway")) {
+				way.addTag("oneway", "yes");
+				if (checkFixmeCoords(way))
+					way.addTag("mkgmap:dead-end-check", "false");
+			} else 
+				way.deleteTag("oneway");
 			
+			
 			recalcRoadClass(way, type);
 			recalcRoadSpeed(way, type);
 		}
@@ -503,7 +519,7 @@
 		findUnconnectedRoads();
 		filterCoordPOI();
 		removeShortArcsByMergingNodes();
-		// make sure that copies of modified roads are have equal points 
+		// make sure that copies of modified roads have equal points 
 		for (int i = 0; i < lines.size(); i++){
 			Way line = lines.get(i);
 			if (deletedRoads.contains(line.getId())){
@@ -823,17 +839,6 @@
 			return;
 		}
 
-		String oneWay = way.getTag("oneway");
-		if("-1".equals(oneWay) || "reverse".equals(oneWay)) {
-			// it's a oneway street in the reverse direction
-			// so reverse the order of the nodes and change
-			// the oneway tag to "yes"
-			way.reverse();
-			way.addTag("oneway", "yes");
-			if("roundabout".equals(way.getTag("junction")))
-				log.warn("Roundabout", way.getId(), "has reverse oneway tag (" + way.getPoints().get(0).toOSMURL() + ")");
-		}
-
 		if("roundabout".equals(way.getTag("junction"))) {
 			List<Coord> points = way.getPoints();
 			// if roundabout checking is enabled and roundabout has at
@@ -1429,7 +1434,6 @@
 		if (way.isBoolTag("oneway")) {
 			road.setDirection(true);
 			road.setOneway();
-			road.doDeadEndCheck(!way.isNotBoolTag("mkgmap:dead-end-check"));
 		}
 
 		boolean[] noAccess = new boolean[RoadNetwork.NO_MAX];
@@ -1687,8 +1691,11 @@
 	 * If such a road has the mkgmap:set_unconnected_type tag, add it as line, not as a road. 
 	 */
 	private void findUnconnectedRoads(){
+		Map<Coord, HashSet<Way>> connectors = new IdentityHashMap<Coord, HashSet<Way>>(roads.size()*2);
 		
-		Map<Coord, HashSet<Way>> connectors = new IdentityHashMap<Coord, HashSet<Way>>(roads.size()*2);
+		// for dead-end-check only: will contain ways with loops (also simply closed ways)
+		HashSet<Way> selfConnectors = new HashSet<Way>();
+		
 		// collect nodes that might connect roads
 		long lastId = 0;
 		for (Way way :roads){
@@ -1702,7 +1709,9 @@
 						ways = new HashSet<Way>(4);
 						connectors.put(p, ways);
 					}
-					ways.add(way);
+					boolean wasNew = ways.add(way);
+					if (!wasNew && reportDeadEnds > 0)
+						selfConnectors.add(way);
 				}
 			}
 		}
@@ -1710,7 +1719,83 @@
 		// find roads that are not connected
 		for (int i = 0; i < roads.size(); i++){
 			Way way = roads.get(i);
-			String check_type = way.getTag("mkgmap:set_unconnected_type");
+			if(reportDeadEnds > 0){
+				// report dead ends of oneway roads 
+				if (way.isBoolTag("oneway") && !way.isNotBoolTag("mkgmap:dead-end-check")) {
+					List<Coord> points = way.getPoints();
+					int[] pointsToCheck = {0, points.size()-1};
+					if (points.get(pointsToCheck[0]) == points.get(pointsToCheck[1]))
+						continue; // skip closed way
+					for (int pos: pointsToCheck ){
+						boolean isDeadEnd = true;
+						boolean isDeadEndOfMultipleWays = true;
+						Coord p = points.get(pos);
+						if (bbox.contains(p) == false || p.getOnBoundary())
+							isDeadEnd = false;  // we don't know enough about possible connections 
+						else if (p.getHighwayCount() < 2){
+							isDeadEndOfMultipleWays = false;
+						} else {
+							HashSet<Way> ways = connectors.get(p);
+							if (ways.size() <= 1)
+								isDeadEndOfMultipleWays = false;
+							for (Way connectedWay: ways){
+								if (!isDeadEnd)
+									break;
+								if (way == connectedWay){
+									if (selfConnectors.contains(way)){
+										// this might be a P-shaped oneway,
+										// check if it has other exists in the loop part
+										if (pos == 0){
+											for (int k = pos+1; k < points.size()-1; k++){
+												Coord pTest = points.get(k);
+												if (pTest == p)
+													break; // found no other exit
+												if (pTest.getHighwayCount() > 1){
+													isDeadEnd = false;
+													break;
+												}
+											} 
+
+										}else {
+											for (int k = pos-1; k >= 0; k--){
+												Coord pTest = points.get(k);
+												if (pTest == p)
+													break; // found no other exit
+												if (pTest.getHighwayCount() > 1){
+													isDeadEnd = false;
+													break;
+												}
+											} 
+										}
+									}
+									continue;
+								}
+								List<Coord> otherPoints = connectedWay.getPoints();
+								Coord otherFirst = otherPoints.get(0);
+								Coord otherLast = otherPoints.get(otherPoints.size()-1);
+								if (otherFirst == otherLast || connectedWay.isBoolTag("oneway") == false)
+									isDeadEnd = false;  
+								else {
+									Coord pOther;
+									if (pos != 0)
+										pOther = otherLast;
+									else
+										pOther = otherFirst;
+									if (p != pOther){
+										// way is connected to a point on a oneway which allows going on
+										isDeadEnd = false;
+									}
+								}
+							}
+						}
+						
+						if (isDeadEnd && (isDeadEndOfMultipleWays || reportDeadEnds > 1)){
+							log.warn("Oneway road " + way.getId() + " with tags " + way.toTagString() + ((pos==0) ? " comes from":" goes to") + " nowhere at " + p.toOSMURL());
+						}
+					}
+				}
+			}
+  			String check_type = way.getTag("mkgmap:set_unconnected_type");
 			if (check_type != null){
 				boolean isConnected = false;
 				boolean onBoundary = false;
