diff --git a/src/uk/me/parabola/mkgmap/reader/osm/Way.java b/src/uk/me/parabola/mkgmap/reader/osm/Way.java
index a8812bf..a4d8680 100644
--- a/src/uk/me/parabola/mkgmap/reader/osm/Way.java
+++ b/src/uk/me/parabola/mkgmap/reader/osm/Way.java
@@ -16,6 +16,7 @@
  */
 package uk.me.parabola.mkgmap.reader.osm;
 
+import java.awt.Polygon;
 import java.util.ArrayList;
 import java.util.List;
 
@@ -141,4 +142,37 @@ public class Way extends Element {
 	public String kind() {
 		return "way";
 	}
+
+	// returns true if the way is a closed polygon with a clockwise
+	// direction
+	public boolean clockwise() {
+
+		if(points.size() < 3 || !points.get(0).equals(points.get(points.size() - 1)))
+			return false;
+
+		long area = 0;
+		Coord p1 = points.get(0);
+		for(int i = 1; i < points.size(); ++i) {
+			Coord p2 = points.get(i);
+			area += ((long)p1.getLongitude() * p2.getLatitude() - 
+					 (long)p2.getLongitude() * p1.getLatitude());
+			p1 = p2;
+		}
+
+		// this test looks to be inverted but gives the expected result!
+		return area < 0;
+	}
+
+	// simplistic check to see if this way "contains" another - for
+	// speed, all we do is check that all of the other way's points
+	// are inside this way's polygon
+	public boolean containsPointsOf(Way other) {
+		Polygon thisPoly = new Polygon();
+		for(Coord p : points)
+			thisPoly.addPoint(p.getLongitude(), p.getLatitude());
+		for(Coord p : other.points)
+			if(!thisPoly.contains(p.getLongitude(), p.getLatitude()))
+				return false;
+		return true;
+	}
 }
diff --git a/src/uk/me/parabola/mkgmap/reader/osm/xml/Osm5XmlHandler.java b/src/uk/me/parabola/mkgmap/reader/osm/xml/Osm5XmlHandler.java
index 7cffaed..6a85d5a 100644
--- a/src/uk/me/parabola/mkgmap/reader/osm/xml/Osm5XmlHandler.java
+++ b/src/uk/me/parabola/mkgmap/reader/osm/xml/Osm5XmlHandler.java
@@ -1152,6 +1152,7 @@ class Osm5XmlHandler extends DefaultHandler {
 		while (it.hasNext()) {
 			Way w = it.next();
 			if (w.isClosed()) {
+				log.info("adding island " + w);
 				islands.add(w);
 				it.remove();
 			}
@@ -1168,27 +1169,8 @@ class Osm5XmlHandler extends DefaultHandler {
 			}
 		}
 
-		// create a "inner" way for each island
-		for (Way w : islands) {
-			log.info("adding island " + w);
-			if(generateSeaUsingMP)
-				seaRelation.addElement("inner", w);
-			else {
-				if(!FakeIdGenerator.isFakeId(w.getId())) {
-					Way w1 = new Way(FakeIdGenerator.makeFakeId());
-					w1.getPoints().addAll(w.getPoints());
-					// only copy the name tags
-					for(String tag : w)
-						if(tag.equals("name") || tag.endsWith(":name"))
-							w1.addTag(tag, w.getTag(tag));
-					w = w1;
-				}
-				w.addTag(landTag[0], landTag[1]);
-				wayMap.put(w.getId(), w);
-			}
-		}
-
 		boolean generateSeaBackground = true;
+		boolean coastlineIntersectsBoundary = false;
 
 		// the remaining shoreline segments should intersect the boundary
 		// find the intersection points and store them in a SortedMap
@@ -1273,6 +1255,7 @@ class Osm5XmlHandler extends DefaultHandler {
 					log.debug("hits (second try): ", hStart, hEnd);
 					hitMap.put(hStart, w);
 					hitMap.put(hEnd, null);
+					coastlineIntersectsBoundary = true;
 				}
 				else {
 					// show the coastline even though we can't produce
@@ -1285,40 +1268,9 @@ class Osm5XmlHandler extends DefaultHandler {
 				log.debug("hits: ", hStart, hEnd);
 				hitMap.put(hStart, w);
 				hitMap.put(hEnd, null);
+				coastlineIntersectsBoundary = true;
 			}
 		}
-		if (generateSeaBackground) {
-			seaId = FakeIdGenerator.makeFakeId();
-			sea = new Way(seaId);
-			if (generateSeaUsingMP) {
-				// the sea background area must be a little bigger than all
-				// inner land areas. this is a workaround for a mp shortcoming:
-				// mp is not able to combine outer and inner if they intersect
-				// or have overlaying lines
-				// the added area will be clipped later by the style generator
-				sea.addPoint(new Coord(nw.getLatitude() - 1,
-						nw.getLongitude() - 1));
-				sea.addPoint(new Coord(sw.getLatitude() + 1,
-						sw.getLongitude() - 1));
-				sea.addPoint(new Coord(se.getLatitude() + 1,
-						se.getLongitude() + 1));
-				sea.addPoint(new Coord(ne.getLatitude() - 1,
-						ne.getLongitude() + 1));
-				sea.addPoint(new Coord(nw.getLatitude() - 1,
-						nw.getLongitude() - 1));
-			} else {
-				sea.addPoint(nw);
-				sea.addPoint(sw);
-				sea.addPoint(se);
-				sea.addPoint(ne);
-				sea.addPoint(nw);
-			}
-			sea.addTag("natural", "sea");
-			log.info("sea: ", sea);
-			wayMap.put(seaId, sea);
-			if(generateSeaUsingMP)
-				seaRelation.addElement("outer", sea);
-		}
 
 		// now construct inner ways from these segments
 		NavigableSet<EdgeHit> hits = (NavigableSet<EdgeHit>) hitMap.keySet();
@@ -1379,23 +1331,108 @@ class Osm5XmlHandler extends DefaultHandler {
 			if (!w.isClosed())
 				w.getPoints().add(w.getPoints().get(0));
 			log.info("adding non-island landmass, hits.size()=" + hits.size());
-			//w.addTag("highway", "motorway");
-			if(generateSeaUsingMP)
+			islands.add(w);
+		}
+
+		List<Way> antiIslands = new ArrayList<Way>();
+
+		for (Way w : islands) {
+
+			if(generateSeaUsingMP) {
+				// create a "inner" way for each island
 				seaRelation.addElement("inner", w);
+			}
 			else {
 				if(!FakeIdGenerator.isFakeId(w.getId())) {
 					Way w1 = new Way(FakeIdGenerator.makeFakeId());
 					w1.getPoints().addAll(w.getPoints());
+					// only copy the name tags
 					for(String tag : w)
 						if(tag.equals("name") || tag.endsWith(":name"))
 							w1.addTag(tag, w.getTag(tag));
 					w = w1;
 				}
-				w.addTag(landTag[0], landTag[1]);
+				// determine where the water is
+				if(w.clockwise()) {
+					// water on the inside of the poly, it's an
+					// "anti-island" so tag with natural=water (to
+					// make it visible above the land)
+					w.addTag("natural", "water");
+					antiIslands.add(w);
+				}
+				else {
+					// water on the outside of the poly, it's an
+					// island so tag it as land
+					w.addTag(landTag[0], landTag[1]);
+				}
+
 				wayMap.put(w.getId(), w);
 			}
 		}
 
+		islands.removeAll(antiIslands);
+
+		if(!coastlineIntersectsBoundary && antiIslands.size() > 0) {
+			// the coast doesn't reach the boundary and the tile
+			// contains "anti-islands" so assume what we have is land
+			// with a sea in the middle
+			generateSeaBackground = false;
+		}
+
+		if (generateSeaBackground) {
+
+			// the background is sea so all anti-islands should be
+			// contained by land otherwise they won't be visible
+
+			for(Way ai : antiIslands) {
+				boolean containedByLand = false;
+				for(Way i : islands) {
+					if(i.containsPointsOf(ai)) {
+						containedByLand = true;
+						break;
+					}
+				}
+				if(!containedByLand) {
+					// found an anti-island that is not contained by
+					// land so convert it back into an island
+					ai.deleteTag("natural");
+					ai.addTag(landTag[0], landTag[1]);
+					log.warn("Converting anti-island starting at " + ai.getPoints().get(0).toOSMURL() + " into an island as it is surrounded by water");
+				}
+			}
+
+			seaId = FakeIdGenerator.makeFakeId();
+			sea = new Way(seaId);
+			if (generateSeaUsingMP) {
+				// the sea background area must be a little bigger than all
+				// inner land areas. this is a workaround for a mp shortcoming:
+				// mp is not able to combine outer and inner if they intersect
+				// or have overlaying lines
+				// the added area will be clipped later by the style generator
+				sea.addPoint(new Coord(nw.getLatitude() - 1,
+						nw.getLongitude() - 1));
+				sea.addPoint(new Coord(sw.getLatitude() + 1,
+						sw.getLongitude() - 1));
+				sea.addPoint(new Coord(se.getLatitude() + 1,
+						se.getLongitude() + 1));
+				sea.addPoint(new Coord(ne.getLatitude() - 1,
+						ne.getLongitude() + 1));
+				sea.addPoint(new Coord(nw.getLatitude() - 1,
+						nw.getLongitude() - 1));
+			} else {
+				sea.addPoint(nw);
+				sea.addPoint(sw);
+				sea.addPoint(se);
+				sea.addPoint(ne);
+				sea.addPoint(nw);
+			}
+			sea.addTag("natural", "sea");
+			log.info("sea: ", sea);
+			wayMap.put(seaId, sea);
+			if(generateSeaUsingMP)
+				seaRelation.addElement("outer", sea);
+		}
+
 		if(generateSeaUsingMP) {
 			seaRelation = new MultiPolygonRelation(seaRelation, wayMap);
 			relationMap.put(multiId, seaRelation);
