Index: /applications/editors/josm/plugins/smed2/src/render/Renderer.java
===================================================================
--- /applications/editors/josm/plugins/smed2/src/render/Renderer.java	(revision 30338)
+++ /applications/editors/josm/plugins/smed2/src/render/Renderer.java	(revision 30339)
@@ -18,4 +18,5 @@
 import s57.S57val.*;
 import s57.S57map;
+import s57.S57att.Att;
 import s57.S57map.*;
 import symbols.Areas;
@@ -346,5 +347,5 @@
 		}
 	}
-
+	
 	public static void labelText(Feature feature, String str, Font font, Color tc) {
 		labelText(feature, str, font, tc, LabelStyle.NONE, null, null, null);
Index: /applications/editors/josm/plugins/smed2/src/render/Rules.java
===================================================================
--- /applications/editors/josm/plugins/smed2/src/render/Rules.java	(revision 30338)
+++ /applications/editors/josm/plugins/smed2/src/render/Rules.java	(revision 30339)
@@ -74,4 +74,22 @@
 	}
 
+	public static void addName(Feature feature, int z, Font font) {
+		addName(feature, z, font, Color.black, new Delta(Handle.CC, new AffineTransform()));
+	}
+	public static void addName(Feature feature, int z, Font font, Color colour) {
+		addName(feature, z, font, colour, new Delta(Handle.CC, new AffineTransform()));
+	}
+	public static void addName(Feature feature, int z, Font font, Delta delta) {
+		addName(feature, z, font, Color.black, delta);
+	}
+	public static void addName(Feature feature, int z, Font font, Color colour, Delta delta) {
+		if (Renderer.zoom >= z) {
+			String name = getName(feature);
+			if (name != null) {
+				Renderer.labelText(feature, name, font,  colour, delta);
+			}
+		}
+	}
+
 	static AttMap getAtts(Feature feature, Obj obj, int idx) {
 		HashMap<Integer, AttMap> objs = feature.objs.get(obj);
@@ -109,15 +127,6 @@
 	}
 	
-	static boolean hasObject(Feature feature, Obj obj) {
-		return (feature.objs.containsKey(obj));
-	}
-	
-	static boolean hasAttribute(Feature feature, Obj obj, Att att) {
-		AttMap atts = getAtts(feature, obj, 0);
-		return ((atts != null) && (atts.containsKey(att)));
-	}
-	
-	static boolean testAttribute(Feature feature, Obj obj, Att att, Object val) {
-		AttMap atts = getAtts(feature, obj, 0);
+	static boolean testAttribute(Feature feature, Obj obj, int idx, Att att, Object val) {
+		AttMap atts = getAtts(feature, obj, idx);
 		if (atts != null) {
 			AttVal item = atts.get(att);
@@ -221,6 +230,5 @@
 			else
 				Renderer.lineVector(feature, new LineStyle(Color.black, 8, new float[] { 25, 25 }));
-			if ((Renderer.zoom >= 12) && (name != null))
-				Renderer.labelText(feature, name, new Font("Arial", Font.PLAIN, 100), Color.black);
+			addName(feature, 12, new Font("Arial", Font.PLAIN, 100), new Delta(Handle.CC, new AffineTransform()));
 			break;
 		case FAIRWY:
@@ -246,15 +254,15 @@
 			break;
 		case OSPARE:
-			if (testAttribute(feature, feature.type, Att.CATPRA, CatPRA.PRA_WFRM)) {
+			if (testAttribute(feature, feature.type, 0, Att.CATPRA, CatPRA.PRA_WFRM)) {
 				Renderer.symbol(feature, Areas.WindFarm);
 				Renderer.lineVector(feature, new LineStyle(Color.black, 20, new float[] { 40, 40 }));
-				if ((Renderer.zoom >= 15) && (name != null))
-					Renderer.labelText(feature, name, new Font("Arial", Font.BOLD, 80), Color.black, new Delta(Handle.TC, AffineTransform.getTranslateInstance(0, 10)));
+				addName(feature, 15, new Font("Arial", Font.BOLD, 80), new Delta(Handle.TC, AffineTransform.getTranslateInstance(0, 10)));
 			}
 			break;
 		case RESARE:
+		case MIPARE:
 			if (Renderer.zoom >= 12) {
 				Renderer.lineSymbols(feature, Areas.Restricted, 1.0, null, null, 0, Mline);
-				if (testAttribute(feature, feature.type, Att.CATREA, CatREA.REA_NWAK)) {
+				if (testAttribute(feature, feature.type, 0, Att.CATREA, CatREA.REA_NWAK)) {
 					Renderer.symbol(feature, Areas.NoWake);
 				}
@@ -302,6 +310,5 @@
 			case SEA_GAT:
 			case SEA_NRRW:
-				if ((Renderer.zoom >= 12) && (name != null))
-					Renderer.labelText(feature, name, new Font("Arial", Font.PLAIN, 100), Color.black);
+				addName(feature, 12, new Font("Arial", Font.PLAIN, 100));
 				break;
 			default:
@@ -317,6 +324,5 @@
 				Renderer.lineSymbols(feature, Areas.Restricted, 0.5, Areas.LinePlane, null, 10, Mline);
 			}
-			if ((Renderer.zoom >= 15) && (name != null))
-				Renderer.labelText(feature, name, new Font("Arial", Font.BOLD, 80), Color.black, new Delta(Handle.BC, AffineTransform.getTranslateInstance(0, -90)));
+			addName(feature, 15, new Font("Arial", Font.BOLD, 80), new Delta(Handle.BC, AffineTransform.getTranslateInstance(0, -90)));
 			break;
 		default:
@@ -352,9 +358,9 @@
 			} else {
 				Renderer.symbol(feature, Beacons.Shapes.get(shape), getScheme(feature, feature.type));
-				if (hasObject(feature, Obj.TOPMAR)) {
+				if (feature.objs.containsKey(Obj.TOPMAR)) {
 					Symbol topmark = Topmarks.Shapes.get(feature.objs.get(Obj.TOPMAR).get(0).get(Att.TOPSHP).val);
 					if (topmark != null)
 						Renderer.symbol(feature, Topmarks.Shapes.get(feature.objs.get(Obj.TOPMAR).get(0).get(Att.TOPSHP).val), getScheme(feature, Obj.TOPMAR), Topmarks.BeaconDelta);
-				} else	if (hasObject(feature, Obj.DAYMAR)) {
+				} else	if (feature.objs.containsKey(Obj.DAYMAR)) {
 					Symbol topmark = Topmarks.Shapes.get(feature.objs.get(Obj.DAYMAR).get(0).get(Att.TOPSHP).val);
 					if (topmark != null)
@@ -370,9 +376,9 @@
 			BoySHP shape = (BoySHP) getAttVal(feature, feature.type, 0, Att.BOYSHP);
 			Renderer.symbol(feature, Buoys.Shapes.get(shape), getScheme(feature, feature.type));
-			if (hasObject(feature, Obj.TOPMAR)) {
+			if (feature.objs.containsKey(Obj.TOPMAR)) {
 				Symbol topmark = Topmarks.Shapes.get(feature.objs.get(Obj.TOPMAR).get(0).get(Att.TOPSHP).val);
 				if (topmark != null)
 					Renderer.symbol(feature, topmark, getScheme(feature, Obj.TOPMAR), Topmarks.BuoyDeltas.get(shape));
-			} else if (hasObject(feature, Obj.DAYMAR)) {
+			} else if (feature.objs.containsKey(Obj.DAYMAR)) {
 				Symbol topmark = Topmarks.Shapes.get(feature.objs.get(Obj.DAYMAR).get(0).get(Att.TOPSHP).val);
 				if (topmark != null)
@@ -446,39 +452,41 @@
 	private static void distances(Feature feature) {
 		if (Renderer.zoom >= 14) {
-			if (!testAttribute(feature, Obj.DISMAR, Att.CATDIS, CatDIS.DIS_NONI)) {
+			if (!testAttribute(feature, Obj.DISMAR, 0, Att.CATDIS, CatDIS.DIS_NONI)) {
 				Renderer.symbol(feature, Harbours.DistanceI);
 			} else {
 				Renderer.symbol(feature, Harbours.DistanceU);
 			}
-			if ((Renderer.zoom >=15) && hasAttribute(feature, Obj.DISMAR, Att.WTWDIS)) {
-				AttMap atts = feature.objs.get(Obj.DISMAR).get(0);
-				Double dist = (Double) atts.get(Att.WTWDIS).val;
-				String str = "";
-				if (atts.containsKey(Att.HUNITS)) {
-					switch ((UniHLU) atts.get(Att.HUNITS).val) {
-					case HLU_METR:
-						str += "m ";
-						break;
-					case HLU_FEET:
-						str += "ft ";
-						break;
-					case HLU_HMTR:
-						str += "hm ";
-						break;
-					case HLU_KMTR:
-						str += "km ";
-						break;
-					case HLU_SMIL:
-						str += "M ";
-						break;
-					case HLU_NMIL:
-						str += "NM ";
-						break;
-					default:
-						break;
+			if (Renderer.zoom >= 15) {
+				AttMap atts = getAtts(feature, Obj.DISMAR, 0);
+				if ((atts != null) && (atts.containsKey(Att.WTWDIS))) {
+					Double dist = (Double) atts.get(Att.WTWDIS).val;
+					String str = "";
+					if (atts.containsKey(Att.HUNITS)) {
+						switch ((UniHLU) atts.get(Att.HUNITS).val) {
+						case HLU_METR:
+							str += "m ";
+							break;
+						case HLU_FEET:
+							str += "ft ";
+							break;
+						case HLU_HMTR:
+							str += "hm ";
+							break;
+						case HLU_KMTR:
+							str += "km ";
+							break;
+						case HLU_SMIL:
+							str += "M ";
+							break;
+						case HLU_NMIL:
+							str += "NM ";
+							break;
+						default:
+							break;
+						}
 					}
-				}
-				str += String.format("%1.0f", dist);
-				Renderer.labelText(feature, str, new Font("Arial", Font.PLAIN, 40), Color.black, new Delta(Handle.CC, AffineTransform.getTranslateInstance(0, 45)));
+					str += String.format("%1.0f", dist);
+					Renderer.labelText(feature, str, new Font("Arial", Font.PLAIN, 40), Color.black, new Delta(Handle.CC, AffineTransform.getTranslateInstance(0, 45)));
+				}
 			}
 		}
@@ -535,7 +543,5 @@
 					Renderer.lineSymbols(feature, Areas.Restricted, 1.0, Areas.LineAnchor, null, 10, Mline);
 				}
-				if ((Renderer.zoom >= 15) && ((name) != null)) {
-					Renderer.labelText(feature, name, new Font("Arial", Font.BOLD, 60), Mline, new Delta(Handle.LC, AffineTransform.getTranslateInstance(70, 0)));
-				}
+				addName(feature, 15, new Font("Arial", Font.BOLD, 60), Mline, new Delta(Handle.LC, AffineTransform.getTranslateInstance(70, 0)));
 				ArrayList<StsSTS> sts = (ArrayList<StsSTS>)getAttVal(feature, Obj.ACHARE, 0, Att.STATUS);
 				if ((Renderer.zoom >= 15) && (sts != null) && (sts.contains(StsSTS.STS_RESV))) {
@@ -638,18 +644,6 @@
 		Renderer.symbol(feature, catSym);
 		Renderer.symbol(feature, fncSym);
-/*  if (!has_attribute("function") && !has_attribute("category") && has_object("light")) {
-    symbol("lighthouse");
-    if ((zoom >= 15) && has_item_attribute("name"))
-      text(item_attribute("name"), "font-family:Arial; font-weight:bold; font-size:80; text-anchor:middle", 0, -70);
-  } else {
-    if ((zoom >= 15) && has_item_attribute("name"))
-      text(item_attribute("name"), "font-family:Arial; font-weight:bold; font-size:80; text-anchor:start", 60, -50);
-  }
-}
-*/
+		addName(feature, 15, new Font("Arial", Font.BOLD, 80), new Delta(Handle.BL, AffineTransform.getTranslateInstance(60, -50)));
 		Signals.addSignals(feature);
-	}
-	
-	private static void buildings(Feature feature) {
 	}
 	
@@ -664,5 +658,5 @@
 			break;
 		case PILPNT:
-			if (hasObject(feature, Obj.LIGHTS))
+			if (feature.objs.containsKey(Obj.LIGHTS))
 				Renderer.symbol(feature, Beacons.LightMinor);
 			else
@@ -680,7 +674,13 @@
 	private static void marinas(Feature feature) {
 		if (Renderer.zoom >= 16) {
-			
-		}
-	}
+	  	ArrayList<Symbol> symbols = new ArrayList<Symbol>();
+	  	ArrayList<CatSCF> scfs = (ArrayList<CatSCF>) getAttVal(feature, Obj.SMCFAC, 0, Att.CATSCF);
+	  	for (CatSCF scf : scfs) {
+	  		symbols.add(Facilities.Cats.get(scf));
+	  	}
+		  Renderer.cluster(feature, symbols);
+	  }
+	}
+	
 	private static void moorings(Feature feature) {
 		switch ((CatMOR) getAttVal(feature, feature.type, 0, Att.CATMOR)) {
@@ -700,4 +700,5 @@
 				shape = BoySHP.BOY_SPHR;
 			Renderer.symbol(feature, Buoys.Shapes.get(shape), getScheme(feature, feature.type));
+			Renderer.symbol(feature, Topmarks.TopMooring, Topmarks.BuoyDeltas.get(shape));
 			break;
 		}
@@ -923,4 +924,11 @@
 
 	private static void obstructions(Feature feature) {
+		if ((Renderer.zoom >= 12) && (feature.type == Obj.OBSTRN)) {
+			switch ((CatOBS) getAttVal(feature, feature.type, 0, Att.CATOBS)) {
+			case OBS_BOOM:
+				Renderer.lineVector(feature, new LineStyle(Color.black, 5, new float[] { 20, 20 }, null));
+				if (Renderer.zoom >= 15) Renderer.lineText(feature, "Boom", new Font("Arial", Font.PLAIN, 80), Color.black, 0.5, -20);
+	      }
+	    }
 		if ((Renderer.zoom >= 14) && (feature.type == Obj.UWTROC)) {
 			WatLEV lvl = (WatLEV) getAttVal(feature, feature.type, 0, Att.WATLEV);
@@ -968,7 +976,5 @@
 		else
 			Renderer.symbol(feature, Landmarks.Platform);
-		String name = getName(feature);
-		if ((Renderer.zoom >= 15) && (name != null))
-			Renderer.labelText(feature, name, new Font("Arial", Font.BOLD, 40), Color.black, new Delta(Handle.BL, AffineTransform.getTranslateInstance(20, -50)));
+		addName(feature, 15, new Font("Arial", Font.BOLD, 40), new Delta(Handle.BL, AffineTransform.getTranslateInstance(20, -50)));
 		Signals.addSignals(feature);
 	}
@@ -983,7 +989,5 @@
 			} else if (feature.type == Obj.HULKES) {
 				Renderer.lineVector(feature, new LineStyle(Color.black, 4, null, new Color(0xffe000)));
-				String name = getName(feature);
-				if ((Renderer.zoom >= 15) && (name != null))
-					Renderer.labelText(feature, name, new Font("Arial", Font.BOLD, 80), Color.black);
+				addName(feature, 15, new Font("Arial", Font.BOLD, 80));
 			}
 		}
@@ -999,7 +1003,5 @@
 			else
 				Renderer.lineVector(feature, new LineStyle(new Color(0x80c48080, true), 20, null, null));
-			String name = getName(feature);
-			if ((Renderer.zoom >= 10) && (name != null))
-				Renderer.labelText(feature, name, new Font("Arial", Font.BOLD, 150), new Color(0x80c48080, true));
+			addName(feature, 10, new Font("Arial", Font.BOLD, 150), new Color(0x80c48080, true));
 			break;
 		case TSELNE:
@@ -1032,4 +1034,16 @@
 				if (Renderer.zoom >= 15)
 					Renderer.lineText(feature, "Training Wall", new Font("Arial", Font.PLAIN, 80), Color.black, 0.5, -30);
+				break;
+			case SLC_SWAY:
+				Renderer.lineVector(feature, new LineStyle(Color.black, 2, null, new Color(0xffe000)));
+			  if ((Renderer.zoom >= 16) && feature.objs.containsKey(Obj.SMCFAC))  {
+			  	ArrayList<Symbol> symbols = new ArrayList<Symbol>();
+			  	ArrayList<CatSCF> scfs = (ArrayList<CatSCF>) getAttVal(feature, Obj.SMCFAC, 0, Att.CATSCF);
+			  	for (CatSCF scf : scfs) {
+			  		symbols.add(Facilities.Cats.get(scf));
+			  	}
+				  Renderer.cluster(feature, symbols);
+			  }
+				break;
 			}
 		}
Index: /applications/editors/josm/plugins/smed2/src/symbols/Symbols.java
===================================================================
--- /applications/editors/josm/plugins/smed2/src/symbols/Symbols.java	(revision 30338)
+++ /applications/editors/josm/plugins/smed2/src/symbols/Symbols.java	(revision 30339)
@@ -18,8 +18,10 @@
 import java.util.ArrayList;
 
+import s57.S57val.ColPAT;
+
 public class Symbols {
 
 	public enum Form {
-		BBOX, STRK, COLR, FILL, LINE, RECT, RRCT, ELPS, EARC, PLIN, PGON, RSHP, TEXT, SYMB, P1, P2, H2, H3, H4, H5, V2, V3, D2, D3, D4, B2, S2, S3, S4, C2, X2
+		BBOX, STRK, COLR, FILL, LINE, RECT, RRCT, ELPS, EARC, PLIN, PGON, RSHP, TEXT, SYMB, P1, P2, H2, H3, H4, H5, V2, V3, D2, D3, D4, B1, S2, S3, S4, C2, X2
 	}
 
@@ -149,6 +151,12 @@
 		int pn = 0;
 		int cn = 0;
+		Patt bpat = Patt.Z;
+		Color bcol = null;
 		g2.setPaint(Color.black);
 		if (cs != null) {
+			if ((cs.pat.size() > 0) && (cs.col.size() > 0) && (cs.pat.get(0) == Patt.B)) {
+				bpat = (cs.pat.remove(0));
+				bcol = (cs.col.remove(0));
+			}
 			pn = cs.pat.size();
 			cn = cs.col.size() - ((pn != 0) ? pn - 1 : 0);
@@ -231,5 +239,5 @@
 								break;
 							case H2:
-								if ((cn > 1) && (cs.pat.get(0) == Patt.H)) {
+								if ((cn > 1) && (pn > 0) && (cs.pat.get(0) == Patt.H)) {
 									g2.setPaint(cs.col.get(cs.col.size() - pn));
 									g2.fill((Path2D.Double) patch.params);
@@ -237,5 +245,5 @@
 								break;
 							case H3:
-								if ((cn == 3) && (cs.pat.get(0) == Patt.H)) {
+								if ((cn == 3) && (pn > 0) && (cs.pat.get(0) == Patt.H)) {
 									g2.setPaint(cs.col.get(1));
 									g2.fill((Path2D.Double) patch.params);
@@ -243,5 +251,5 @@
 								break;
 							case H4:
-								if ((cn == 4) && (cs.pat.get(0) == Patt.H)) {
+								if ((cn == 4) && (pn > 0) && (cs.pat.get(0) == Patt.H)) {
 									g2.setPaint(cs.col.get(1));
 									g2.fill((Path2D.Double) patch.params);
@@ -249,5 +257,5 @@
 								break;
 							case H5:
-								if ((cn == 4) && (cs.pat.get(0) == Patt.H)) {
+								if ((cn == 4) && (pn > 0) && (cs.pat.get(0) == Patt.H)) {
 									g2.setPaint(cs.col.get(2));
 									g2.fill((Path2D.Double) patch.params);
@@ -255,5 +263,5 @@
 								break;
 							case V2:
-								if ((cn > 1) && (cs.pat.get(0) == Patt.V)) {
+								if ((cn > 1) && (pn > 0) && (cs.pat.get(0) == Patt.V)) {
 									g2.setPaint(cs.col.get(cs.col.size() - pn));
 									g2.fill((Path2D.Double) patch.params);
@@ -261,6 +269,12 @@
 								break;
 							case V3:
-								if ((cn == 3) && (cs.pat.get(0) == Patt.V)) {
+								if ((cn == 3) && (pn > 0) && (cs.pat.get(0) == Patt.V)) {
 									g2.setPaint(cs.col.get(1));
+									g2.fill((Path2D.Double) patch.params);
+								}
+								break;
+							case B1:
+								if (bpat == Patt.B) {
+									g2.setPaint(bcol);
 									g2.fill((Path2D.Double) patch.params);
 								}
Index: /applications/editors/josm/plugins/smed2/src/symbols/Topmarks.java
===================================================================
--- /applications/editors/josm/plugins/smed2/src/symbols/Topmarks.java	(revision 30338)
+++ /applications/editors/josm/plugins/smed2/src/symbols/Topmarks.java	(revision 30339)
@@ -190,4 +190,8 @@
 		p = new Path2D.Double(); p.moveTo(-4.3,-1.0); p.lineTo(-4.3,-27.0); p.lineTo(4.3,-27.0); p.lineTo(4.3,-1.0); p.closePath();
 		colours.add(new Instr(Form.V3, p));
+		p = new Path2D.Double(); p.setWindingRule(GeneralPath.WIND_EVEN_ODD);
+		p.moveTo(-13.0,-1.0); p.lineTo(-13.0,-27.0); p.lineTo(13.0,-27.0); p.lineTo(13.0,-1.0); p.closePath();
+		p.moveTo(-8.0,-6.0); p.lineTo(-8.0,-22.0); p.lineTo(8.0,-22.0); p.lineTo(8.0,-6.0); p.closePath();
+		colours.add(new Instr(Form.B1, p));
 		TopSquare.add(new Instr(Form.COLR, colours));
 		TopSquare.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
@@ -206,4 +210,12 @@
 		p = new Path2D.Double(); p.moveTo(-10.0,-19.7); p.lineTo(-15.0,-15.0); p.lineTo(-10.0,-10.3); p.lineTo(10.0,-10.3); p.lineTo(15.0,-15.0); p.lineTo(10.0,-19.7); p.closePath();
 		colours.add(new Instr(Form.H3, p));
+		p = new Path2D.Double();  p.moveTo(0.0,-29.0); p.lineTo(0.0,-1.0); p.lineTo(15.0,-15.0); p.closePath();
+		colours.add(new Instr(Form.V2, p));
+		p = new Path2D.Double(); p.moveTo(0.0,-29.0); p.lineTo(-5.0,-24.3); p.lineTo(-5.0,-5.7); p.lineTo(0.0,-1.0); p.lineTo(5.0,-5.7); p.lineTo(5.0,-24.3); p.closePath();
+		colours.add(new Instr(Form.V3, p));
+		p = new Path2D.Double(); p.setWindingRule(GeneralPath.WIND_EVEN_ODD);
+		p.moveTo(0.0,-29.0); p.lineTo(-15.0,-15.0); p.lineTo(0.0,-1.0); p.lineTo(15.0,-15.0); p.closePath();
+		p.moveTo(0.0,-23.0); p.lineTo(-9.0,-15.0); p.lineTo(0.0,-7.0); p.lineTo(9.0,-15.0); p.closePath();
+		colours.add(new Instr(Form.B1, p));
 		TopRhombus.add(new Instr(Form.COLR, colours));
 		TopRhombus.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
