Index: data/defaultpresets.xml
===================================================================
--- data/defaultpresets.xml	(revision 4181)
+++ data/defaultpresets.xml	(working copy)
@@ -4122,6 +4122,8 @@
             <roles>
                 <role key="outer" text="outer segment" requisite="required" type="way" />
                 <role key="inner" text="inner segment" requisite="optional" type="way" />
+                <role key="enclave" text="enclave segment" requisite="optional" type="way" />
+                <role key="exclave" text="exclave segment" requisite="optional" type="way" />
                 <role key="subarea" text="Sub area" requisite="optional" type="relation" />
                 <role key="admin_centre" text="Administration centre" requisite="optional" type="node" />
             </roles>
Index: src/org/openstreetmap/josm/data/osm/Relation.java
===================================================================
--- src/org/openstreetmap/josm/data/osm/Relation.java	(revision 4181)
+++ src/org/openstreetmap/josm/data/osm/Relation.java	(working copy)
@@ -409,6 +409,10 @@
         return "multipolygon".equals(get("type"));
     }
 
+    public boolean isBoundary() {
+        return "boundary".equals(get("type"));
+    }
+
     @Override
     public BBox getBBox() {
         RelationMember[] members = this.members;
Index: src/org/openstreetmap/josm/data/osm/visitor/paint/MapPainter.java
===================================================================
--- src/org/openstreetmap/josm/data/osm/visitor/paint/MapPainter.java	(revision 4181)
+++ src/org/openstreetmap/josm/data/osm/visitor/paint/MapPainter.java	(working copy)
@@ -33,6 +33,7 @@
 import org.openstreetmap.josm.data.osm.Relation;
 import org.openstreetmap.josm.data.osm.RelationMember;
 import org.openstreetmap.josm.data.osm.Way;
+import org.openstreetmap.josm.data.osm.visitor.paint.relations.Boundary;
 import org.openstreetmap.josm.data.osm.visitor.paint.relations.Multipolygon;
 import org.openstreetmap.josm.data.osm.visitor.paint.relations.Multipolygon.PolyData;
 import org.openstreetmap.josm.gui.NavigatableComponent;
@@ -688,7 +689,7 @@
     }
 
     public void drawArea(Relation r, Color color, BufferedImage fillImage, float fillImageAlpha, TextElement text) {
-        Multipolygon multipolygon = new Multipolygon(nc);
+        Multipolygon multipolygon = r.isBoundary() ? new Boundary(nc) : new Multipolygon(nc);
         multipolygon.load(r);
         if(!r.isDisabled() && !multipolygon.getOuterWays().isEmpty()) {
             for (PolyData pd : multipolygon.getCombinedPolygons()) {
Index: src/org/openstreetmap/josm/data/osm/visitor/paint/relations/Boundary.java
===================================================================
--- src/org/openstreetmap/josm/data/osm/visitor/paint/relations/Boundary.java	(revision 0)
+++ src/org/openstreetmap/josm/data/osm/visitor/paint/relations/Boundary.java	(revision 0)
@@ -0,0 +1,45 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.data.osm.visitor.paint.relations;
+
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.data.osm.Relation;
+import org.openstreetmap.josm.gui.NavigatableComponent;
+
+public class Boundary extends Multipolygon {
+
+    public Boundary(NavigatableComponent nc) {
+        super(nc);
+    }
+
+    protected static class BoundaryRoleMatcher extends MultipolygonRoleMatcher {
+
+        @Override
+        protected void initDefaults() {
+            super.initDefaults();
+            outerExactRoles.add("exclave");
+            innerExactRoles.add("enclave");
+        }
+    }
+
+    @Override
+    public void load(Relation r) {
+        load(r, getBoundaryRoleMatcher());
+    }
+
+    /*
+     * Init a private global matcher object which will listen to preference
+     * changes.
+     */
+    private static BoundaryRoleMatcher roleMatcher;
+    private static BoundaryRoleMatcher getBoundaryRoleMatcher() {
+        if (roleMatcher == null) {
+            roleMatcher = new BoundaryRoleMatcher();
+            if (Main.pref != null){
+                roleMatcher.initFromPreferences();
+                Main.pref.addPreferenceChangeListener(roleMatcher);
+            }
+        }
+        return roleMatcher;
+    }
+
+}
Index: src/org/openstreetmap/josm/data/osm/visitor/paint/relations/Multipolygon.java
===================================================================
--- src/org/openstreetmap/josm/data/osm/visitor/paint/relations/Multipolygon.java	(revision 4181)
+++ src/org/openstreetmap/josm/data/osm/visitor/paint/relations/Multipolygon.java	(working copy)
@@ -48,13 +48,13 @@
      * above.</p>
      * 
      */
-    private static class MultipolygonRoleMatcher implements PreferenceChangedListener{
-        private final List<String> outerExactRoles = new ArrayList<String>();
-        private final List<String> outerRolePrefixes = new ArrayList<String>();
-        private final List<String> innerExactRoles = new ArrayList<String>();
-        private final List<String> innerRolePrefixes = new ArrayList<String>();
+    protected static class MultipolygonRoleMatcher implements PreferenceChangedListener{
+        protected final List<String> outerExactRoles = new ArrayList<String>();
+        protected final List<String> outerRolePrefixes = new ArrayList<String>();
+        protected final List<String> innerExactRoles = new ArrayList<String>();
+        protected final List<String> innerRolePrefixes = new ArrayList<String>();
 
-        private void initDefaults() {
+        protected void initDefaults() {
             outerExactRoles.clear();
             outerRolePrefixes.clear();
             innerExactRoles.clear();
@@ -76,7 +76,7 @@
             }
         }
 
-        private void initFromPreferences() {
+        protected void initFromPreferences() {
             initDefaults();
             if (Main.pref == null) return;
             Collection<String> literals;
@@ -136,7 +136,7 @@
      * changes.
      */
     private static MultipolygonRoleMatcher roleMatcher;
-    private static MultipolygonRoleMatcher getMultipoloygonRoleMatcher() {
+    private static MultipolygonRoleMatcher getMultipolygonRoleMatcher() {
         if (roleMatcher == null) {
             roleMatcher = new MultipolygonRoleMatcher();
             if (Main.pref != null){
@@ -252,7 +252,10 @@
     }
 
     public void load(Relation r) {
-        MultipolygonRoleMatcher matcher = getMultipoloygonRoleMatcher();
+        load(r, getMultipolygonRoleMatcher());
+    }
+
+    protected void load(Relation r, MultipolygonRoleMatcher matcher) {
 
         // Fill inner and outer list with valid ways
         for (RelationMember m : r.getMembers()) {
Index: src/org/openstreetmap/josm/data/validation/tests/MultipolygonTest.java
===================================================================
--- src/org/openstreetmap/josm/data/validation/tests/MultipolygonTest.java	(revision 4181)
+++ src/org/openstreetmap/josm/data/validation/tests/MultipolygonTest.java	(working copy)
@@ -15,6 +15,7 @@
 import org.openstreetmap.josm.data.osm.Relation;
 import org.openstreetmap.josm.data.osm.RelationMember;
 import org.openstreetmap.josm.data.osm.Way;
+import org.openstreetmap.josm.data.osm.visitor.paint.relations.Boundary;
 import org.openstreetmap.josm.data.osm.visitor.paint.relations.Multipolygon;
 import org.openstreetmap.josm.data.osm.visitor.paint.relations.Multipolygon.JoinedWay;
 import org.openstreetmap.josm.data.osm.visitor.paint.relations.Multipolygon.PolyData.Intersection;
@@ -127,10 +128,10 @@
     @Override
     public void visit(Relation r) {
         nonClosedWays.clear();
-        if (r.isMultipolygon()) {
+        if (r.isMultipolygon() || r.isBoundary()) {
             checkMembersAndRoles(r);
 
-            Multipolygon polygon = new Multipolygon(Main.map.mapView);
+            Multipolygon polygon = r.isBoundary() ? new Boundary(Main.map.mapView) : new Multipolygon(Main.map.mapView);
             polygon.load(r);
 
             if (polygon.getOuterWays().isEmpty()) {
@@ -252,9 +253,11 @@
         for (RelationMember rm : r.getMembers()) {
             if (rm.isWay()) {
                 if (!("inner".equals(rm.getRole()) || "outer".equals(rm.getRole()) || !rm.hasRole())) {
-                    errors.add(new TestError(this, Severity.WARNING, tr("No useful role for multipolygon member"), WRONG_MEMBER_ROLE, rm.getMember()));
+                    if (!(r.isBoundary() && ("enclave".equals(rm.getRole()) || "exclave".equals(rm.getRole())))) {
+                        errors.add(new TestError(this, Severity.WARNING, tr("No useful role for multipolygon member"), WRONG_MEMBER_ROLE, rm.getMember()));
+                    }
                 }
-            } else {
+            } else if (r.isMultipolygon()) {
                 errors.add(new TestError(this, Severity.WARNING, tr("Non-Way in multipolygon"), WRONG_MEMBER_TYPE, rm.getMember()));
             }
         }
Index: src/org/openstreetmap/josm/gui/mappaint/ElemStyles.java
===================================================================
--- src/org/openstreetmap/josm/gui/mappaint/ElemStyles.java	(revision 4181)
+++ src/org/openstreetmap/josm/gui/mappaint/ElemStyles.java	(working copy)
@@ -13,6 +13,7 @@
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
 import org.openstreetmap.josm.data.osm.Relation;
 import org.openstreetmap.josm.data.osm.Way;
+import org.openstreetmap.josm.data.osm.visitor.paint.relations.Boundary;
 import org.openstreetmap.josm.data.osm.visitor.paint.relations.Multipolygon;
 import org.openstreetmap.josm.gui.NavigatableComponent;
 import org.openstreetmap.josm.gui.mappaint.StyleCache.StyleList;
@@ -93,10 +94,10 @@
 
             for (OsmPrimitive referrer : osm.getReferrers()) {
                 Relation r = (Relation) referrer;
-                if (!drawMultipolygon || !r.isMultipolygon()  || !r.isUsable()) {
+                if (!drawMultipolygon || !r.isMultipolygon() || !r.isBoundary() || !r.isUsable()) {
                     continue;
                 }
-                Multipolygon multipolygon = new Multipolygon(nc);
+                Multipolygon multipolygon = r.isBoundary() ? new Boundary(nc) : new Multipolygon(nc);
                 multipolygon.load(r);
 
                 if (multipolygon.getOuterWays().contains(osm)) {
@@ -246,7 +247,7 @@
             } else if (osm instanceof Node) {
                 addIfNotNull(sl, NodeElemStyle.create(env));
             } else if (osm instanceof Relation) {
-                if (((Relation)osm).isMultipolygon()) {
+                if (((Relation)osm).isMultipolygon() || ((Relation)osm).isBoundary()) {
                     addIfNotNull(sl, AreaElemStyle.create(c));
                     addIfNotNull(sl, LinePatternElemStyle.create(env));
                     addIfNotNull(sl, LineElemStyle.createLine(env));
Index: src/org/openstreetmap/josm/gui/mappaint/mapcss/Condition.java
===================================================================
--- src/org/openstreetmap/josm/gui/mappaint/mapcss/Condition.java	(revision 4181)
+++ src/org/openstreetmap/josm/gui/mappaint/mapcss/Condition.java	(working copy)
@@ -274,7 +274,7 @@
             if (equal(id, "closed")) {
                 if (e.osm instanceof Way && ((Way) e.osm).isClosed())
                     return true;
-                if (e.osm instanceof Relation && ((Relation) e.osm).isMultipolygon())
+                if (e.osm instanceof Relation && (((Relation) e.osm).isMultipolygon() || ((Relation) e.osm).isBoundary()))
                     return true;
                 return false;
             } else if (equal(id, "modified"))
Index: src/org/openstreetmap/josm/gui/mappaint/mapcss/Selector.java
===================================================================
--- src/org/openstreetmap/josm/gui/mappaint/mapcss/Selector.java	(revision 4181)
+++ src/org/openstreetmap/josm/gui/mappaint/mapcss/Selector.java	(working copy)
@@ -270,7 +270,7 @@
             if (base.equals("area")) {
                 if (e.osm instanceof Way)
                     return true;
-                if (e.osm instanceof Relation && ((Relation) e.osm).isMultipolygon())
+                if (e.osm instanceof Relation && (((Relation) e.osm).isMultipolygon() || ((Relation) e.osm).isBoundary()))
                     return true;
             }
             if (base.equals(OsmPrimitiveType.from(e.osm).getAPIName()))
Index: src/org/openstreetmap/josm/gui/mappaint/xml/XmlStyleSource.java
===================================================================
--- src/org/openstreetmap/josm/gui/mappaint/xml/XmlStyleSource.java	(revision 4181)
+++ src/org/openstreetmap/josm/gui/mappaint/xml/XmlStyleSource.java	(working copy)
@@ -49,6 +49,7 @@
         super(entry);
     }
 
+    @Override
     protected void init() {
         super.init();
         icons.clear();
@@ -88,6 +89,7 @@
         }
     }
 
+    @Override
     public InputStream getSourceInputStream() throws IOException {
         MirroredInputStream in = new MirroredInputStream(url);
         InputStream zip = in.getZipEntry("xml", "style");
@@ -295,7 +297,7 @@
                     }
                 }
             }
-        } else if (osm instanceof Way || (osm instanceof Relation && ((Relation)osm).isMultipolygon())) {
+        } else if (osm instanceof Way || (osm instanceof Relation && (((Relation)osm).isMultipolygon()) || ((Relation)osm).isBoundary())) {
             WayPrototypesRecord p = new WayPrototypesRecord();
             get(osm, pretendWayIsClosed || !(osm instanceof Way) || ((Way) osm).isClosed(), p, (useMinMaxScale ? scale : null), mc);
             if (p.line != null) {
