Index: trunk/src/org/openstreetmap/josm/data/osm/DefaultNameFormatter.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/osm/DefaultNameFormatter.java	(revision 13765)
+++ trunk/src/org/openstreetmap/josm/data/osm/DefaultNameFormatter.java	(revision 13766)
@@ -140,8 +140,8 @@
         if (osm instanceof INode) {
             return format((INode) osm);
-        } else if (osm instanceof IWay<?>) {
+        } else if (osm instanceof IWay) {
             return format((IWay<?>) osm);
         } else if (osm instanceof IRelation) {
-            return format((IRelation) osm);
+            return format((IRelation<?>) osm);
         }
         return null;
@@ -306,5 +306,5 @@
 
     @Override
-    public String format(IRelation relation) {
+    public String format(IRelation<?> relation) {
         StringBuilder name = new StringBuilder();
         if (relation.isIncomplete()) {
@@ -336,5 +336,5 @@
     }
 
-    private static StringBuilder formatRelationNameAndType(IRelation relation, StringBuilder result, TaggingPreset preset) {
+    private static StringBuilder formatRelationNameAndType(IRelation<?> relation, StringBuilder result, TaggingPreset preset) {
         if (preset == null || !(relation instanceof TemplateEngineDataProvider)) {
             result.append(getRelationTypeName(relation));
@@ -353,5 +353,5 @@
     }
 
-    private final Comparator<IRelation> relationComparator = (r1, r2) -> {
+    private final Comparator<IRelation<?>> relationComparator = (r1, r2) -> {
         //TODO This doesn't work correctly with formatHooks
 
@@ -396,9 +396,9 @@
 
     @Override
-    public Comparator<IRelation> getRelationComparator() {
+    public Comparator<IRelation<?>> getRelationComparator() {
         return relationComparator;
     }
 
-    private static String getRelationTypeName(IRelation relation) {
+    private static String getRelationTypeName(IRelation<?> relation) {
         String name = trc("Relation type", relation.get("type"));
         if (name == null) {
@@ -433,5 +433,5 @@
     }
 
-    private static String getNameTagValue(IRelation relation, String nameTag) {
+    private static String getNameTagValue(IRelation<?> relation, String nameTag) {
         if ("name".equals(nameTag)) {
             if (Config.getPref().getBoolean("osm-primitives.localize-name", true))
@@ -456,5 +456,5 @@
     }
 
-    private static String getRelationName(IRelation relation) {
+    private static String getRelationName(IRelation<?> relation) {
         String nameTag;
         for (String n : getNamingtagsForRelations()) {
Index: trunk/src/org/openstreetmap/josm/data/osm/IRelation.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/osm/IRelation.java	(revision 13765)
+++ trunk/src/org/openstreetmap/josm/data/osm/IRelation.java	(revision 13766)
@@ -2,9 +2,12 @@
 package org.openstreetmap.josm.data.osm;
 
+import java.util.List;
+
 /**
  * IRelation captures the common functions of {@link Relation} and {@link RelationData}.
+ * @param <M> Type of OSM relation member
  * @since 4098
  */
-public interface IRelation extends IPrimitive {
+public interface IRelation<M extends IRelationMember<?>> extends IPrimitive {
 
     /**
@@ -13,4 +16,21 @@
      */
     int getMembersCount();
+
+    /**
+     * Returns the relation member at the specified index.
+     * @param index the index of the relation member
+     * @return relation member at the specified index
+     * @since 13766 (IRelation)
+     */
+    M getMember(int index);
+
+    /**
+     * Returns members of the relation.
+     * @return Members of the relation. Changes made in returned list are not mapped
+     * back to the primitive, use setMembers() to modify the members
+     * @since 1925
+     * @since 13766 (IRelation)
+     */
+    List<M> getMembers();
 
     /**
Index: trunk/src/org/openstreetmap/josm/data/osm/IRelationMember.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/osm/IRelationMember.java	(revision 13765)
+++ trunk/src/org/openstreetmap/josm/data/osm/IRelationMember.java	(revision 13766)
@@ -6,7 +6,8 @@
 /**
  * IRelationMember captures the common functions of {@link RelationMember} and {@link RelationMemberData}.
+ * @param <P> the base type of OSM primitives
  * @since 13677
  */
-public interface IRelationMember extends PrimitiveId {
+public interface IRelationMember<P extends IPrimitive> extends PrimitiveId {
 
     /**
@@ -50,3 +51,19 @@
      */
     boolean isRelation();
+
+    /**
+     * Returns type of member for icon display.
+     * @return type of member for icon display
+     * @since 13766 (IRelationMember)
+     */
+    default OsmPrimitiveType getDisplayType() {
+        return getMember().getDisplayType();
+    }
+
+    /**
+     * Returns the relation member.
+     * @return Member. Returned value is never null.
+     * @since 13766 (IRelationMember)
+     */
+    P getMember();
 }
Index: trunk/src/org/openstreetmap/josm/data/osm/IWay.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/osm/IWay.java	(revision 13765)
+++ trunk/src/org/openstreetmap/josm/data/osm/IWay.java	(revision 13766)
@@ -77,5 +77,5 @@
         if (o instanceof IRelation)
             return 1;
-        return o instanceof IWay<?> ? Long.compare(getUniqueId(), o.getUniqueId()) : -1;
+        return o instanceof IWay ? Long.compare(getUniqueId(), o.getUniqueId()) : -1;
     }
 
Index: trunk/src/org/openstreetmap/josm/data/osm/NameFormatter.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/osm/NameFormatter.java	(revision 13765)
+++ trunk/src/org/openstreetmap/josm/data/osm/NameFormatter.java	(revision 13766)
@@ -35,5 +35,5 @@
      * @since 13564 (signature)
      */
-    String format(IRelation relation);
+    String format(IRelation<?> relation);
 
     /**
@@ -64,4 +64,4 @@
      * @since 13564 (signature)
      */
-    Comparator<IRelation> getRelationComparator();
+    Comparator<IRelation<?>> getRelationComparator();
 }
Index: trunk/src/org/openstreetmap/josm/data/osm/NameFormatterHook.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/osm/NameFormatterHook.java	(revision 13765)
+++ trunk/src/org/openstreetmap/josm/data/osm/NameFormatterHook.java	(revision 13766)
@@ -15,5 +15,5 @@
      * @return The corrected type name if needed, null otherwise.
      */
-    String checkRelationTypeName(IRelation relation, String defaultName);
+    String checkRelationTypeName(IRelation<?> relation, String defaultName);
 
     /**
@@ -39,4 +39,4 @@
      * @return The corrected format if needed, null otherwise.
      */
-    String checkFormat(IRelation relation, String defaultName);
+    String checkFormat(IRelation<?> relation, String defaultName);
 }
Index: trunk/src/org/openstreetmap/josm/data/osm/OsmData.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/osm/OsmData.java	(revision 13765)
+++ trunk/src/org/openstreetmap/josm/data/osm/OsmData.java	(revision 13766)
@@ -24,5 +24,5 @@
  * @since 13764
  */
-public interface OsmData<O extends IPrimitive, N extends INode, W extends IWay<N>, R extends IRelation> extends Data, Lockable {
+public interface OsmData<O extends IPrimitive, N extends INode, W extends IWay<N>, R extends IRelation<?>> extends Data, Lockable {
 
     // --------------
Index: trunk/src/org/openstreetmap/josm/data/osm/OsmPrimitiveType.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/osm/OsmPrimitiveType.java	(revision 13765)
+++ trunk/src/org/openstreetmap/josm/data/osm/OsmPrimitiveType.java	(revision 13766)
@@ -86,5 +86,5 @@
     public static OsmPrimitiveType from(IPrimitive obj) {
         if (obj instanceof INode) return NODE;
-        if (obj instanceof IWay<?>) return WAY;
+        if (obj instanceof IWay) return WAY;
         if (obj instanceof IRelation) return RELATION;
         throw new IllegalArgumentException("Unknown type: "+obj);
Index: trunk/src/org/openstreetmap/josm/data/osm/QuadBucketPrimitiveStore.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/osm/QuadBucketPrimitiveStore.java	(revision 13765)
+++ trunk/src/org/openstreetmap/josm/data/osm/QuadBucketPrimitiveStore.java	(revision 13766)
@@ -20,5 +20,5 @@
  * @since 12048
  */
-public class QuadBucketPrimitiveStore<N extends INode, W extends IWay<N>, R extends IRelation> {
+public class QuadBucketPrimitiveStore<N extends INode, W extends IWay<N>, R extends IRelation<?>> {
     /**
      * All nodes goes here, even when included in other data (ways etc). This enables the instant
Index: trunk/src/org/openstreetmap/josm/data/osm/Relation.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/osm/Relation.java	(revision 13765)
+++ trunk/src/org/openstreetmap/josm/data/osm/Relation.java	(revision 13766)
@@ -24,6 +24,7 @@
  *
  * @author Frederik Ramm
+ * @since 343
  */
-public final class Relation extends OsmPrimitive implements IRelation {
+public final class Relation extends OsmPrimitive implements IRelation<RelationMember> {
 
     private RelationMember[] members = new RelationMember[0];
@@ -31,9 +32,5 @@
     private BBox bbox;
 
-    /**
-     * @return Members of the relation. Changes made in returned list are not mapped
-     * back to the primitive, use setMembers() to modify the members
-     * @since 1925
-     */
+    @Override
     public List<RelationMember> getMembers() {
         return new CopyList<>(members);
@@ -75,9 +72,5 @@
     }
 
-    /**
-     * Returns the relation member at the specified index.
-     * @param index the index of the relation member
-     * @return relation member at the specified index
-     */
+    @Override
     public RelationMember getMember(int index) {
         return members[index];
Index: trunk/src/org/openstreetmap/josm/data/osm/RelationData.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/osm/RelationData.java	(revision 13765)
+++ trunk/src/org/openstreetmap/josm/data/osm/RelationData.java	(revision 13766)
@@ -11,5 +11,5 @@
  * @since 2284
  */
-public class RelationData extends PrimitiveData implements IRelation {
+public class RelationData extends PrimitiveData implements IRelation<RelationMemberData> {
 
     private static final long serialVersionUID = 1163664954890478565L;
@@ -41,8 +41,5 @@
     }
 
-    /**
-     * Returns relation members.
-     * @return relation members
-     */
+    @Override
     public List<RelationMemberData> getMembers() {
         return members;
@@ -63,16 +60,21 @@
 
     @Override
+    public RelationMemberData getMember(int index) {
+        return members.get(index);
+    }
+
+    @Override
     public long getMemberId(int idx) {
-        return members.get(idx).getMemberId();
+        return getMember(idx).getMemberId();
     }
 
     @Override
     public String getRole(int idx) {
-        return members.get(idx).getRole();
+        return getMember(idx).getRole();
     }
 
     @Override
     public OsmPrimitiveType getMemberType(int idx) {
-        return members.get(idx).getMemberType();
+        return getMember(idx).getMemberType();
     }
 
Index: trunk/src/org/openstreetmap/josm/data/osm/RelationMember.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/osm/RelationMember.java	(revision 13765)
+++ trunk/src/org/openstreetmap/josm/data/osm/RelationMember.java	(revision 13766)
@@ -12,5 +12,5 @@
  * @since 343
  */
-public class RelationMember implements IRelationMember {
+public class RelationMember implements IRelationMember<OsmPrimitive> {
 
     /**
@@ -37,13 +37,4 @@
     public boolean isWay() {
         return member instanceof Way;
-    }
-
-    /**
-     * Returns type of member for icon display.
-     * @return type of member for icon display
-     * @since 3844
-     */
-    public OsmPrimitiveType getDisplayType() {
-        return member.getDisplayType();
     }
 
@@ -80,9 +71,5 @@
     }
 
-    /**
-     * Returns the relation member.
-     * @return Member. Returned value is never null.
-     * @since 1937
-     */
+    @Override
     public OsmPrimitive getMember() {
         return member;
Index: trunk/src/org/openstreetmap/josm/data/osm/RelationMemberData.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/osm/RelationMemberData.java	(revision 13765)
+++ trunk/src/org/openstreetmap/josm/data/osm/RelationMemberData.java	(revision 13766)
@@ -11,5 +11,5 @@
  * @since 2284
  */
-public class RelationMemberData implements IRelationMember, Serializable {
+public class RelationMemberData implements IRelationMember<PrimitiveData>, Serializable {
 
     private static final long serialVersionUID = 381392198209333319L;
@@ -64,4 +64,9 @@
 
     @Override
+    public OsmPrimitiveType getDisplayType() {
+        return memberType;
+    }
+
+    @Override
     public boolean isNode() {
         return OsmPrimitiveType.NODE == memberType;
@@ -76,4 +81,9 @@
     public boolean isRelation() {
         return OsmPrimitiveType.RELATION == memberType;
+    }
+
+    @Override
+    public PrimitiveData getMember() {
+        throw new UnsupportedOperationException();
     }
 
Index: trunk/src/org/openstreetmap/josm/data/osm/visitor/PrimitiveVisitor.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/osm/visitor/PrimitiveVisitor.java	(revision 13765)
+++ trunk/src/org/openstreetmap/josm/data/osm/visitor/PrimitiveVisitor.java	(revision 13766)
@@ -28,4 +28,4 @@
      * @param r The relation to inspect.
      */
-    void visit(IRelation r);
+    void visit(IRelation<?> r);
 }
Index: trunk/src/org/openstreetmap/josm/gui/dialogs/properties/PropertiesDialog.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/dialogs/properties/PropertiesDialog.java	(revision 13765)
+++ trunk/src/org/openstreetmap/josm/gui/dialogs/properties/PropertiesDialog.java	(revision 13766)
@@ -730,7 +730,7 @@
      * @return The current selected relation membership
      */
-    public IRelation getSelectedMembershipRelation() {
+    public IRelation<?> getSelectedMembershipRelation() {
         int row = membershipTable.getSelectedRow();
-        return row > -1 ? (IRelation) membershipData.getValueAt(row, 0) : null;
+        return row > -1 ? (IRelation<?>) membershipData.getValueAt(row, 0) : null;
     }
 
Index: trunk/src/org/openstreetmap/josm/io/OsmWriter.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/OsmWriter.java	(revision 13765)
+++ trunk/src/org/openstreetmap/josm/io/OsmWriter.java	(revision 13766)
@@ -282,5 +282,5 @@
 
     @Override
-    public void visit(IRelation e) {
+    public void visit(IRelation<?> e) {
         if (e.isIncomplete()) return;
         addCommon(e, "relation");
Index: trunk/test/unit/org/openstreetmap/josm/data/osm/DefaultNameFormatterTest.java
===================================================================
--- trunk/test/unit/org/openstreetmap/josm/data/osm/DefaultNameFormatterTest.java	(revision 13765)
+++ trunk/test/unit/org/openstreetmap/josm/data/osm/DefaultNameFormatterTest.java	(revision 13766)
@@ -63,5 +63,5 @@
         TaggingPresets.addTaggingPresets(TaggingPresetReader.readAll("http://localhost:" + wireMockRule.port() + "/" + source, true));
 
-        Comparator<IRelation> comparator = DefaultNameFormatter.getInstance().getRelationComparator();
+        Comparator<IRelation<?>> comparator = DefaultNameFormatter.getInstance().getRelationComparator();
 
         try (InputStream is = TestUtils.getRegressionDataStream(9632, "data.osm.zip")) {
