Index: trunk/src/org/openstreetmap/josm/actions/CreateMultipolygonAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/CreateMultipolygonAction.java	(revision 13955)
+++ trunk/src/org/openstreetmap/josm/actions/CreateMultipolygonAction.java	(revision 13957)
@@ -168,5 +168,7 @@
             } else if (multipolygonRelation.hasIncompleteMembers()) {
                 MainApplication.worker.submit(new DownloadRelationMemberTask(multipolygonRelation,
-                        DownloadSelectedIncompleteMembersAction.buildSetOfIncompleteMembers(Collections.singleton(multipolygonRelation)),
+                        Utils.filteredCollection(
+                            DownloadSelectedIncompleteMembersAction.buildSetOfIncompleteMembers(
+                                    Collections.singleton(multipolygonRelation)), OsmPrimitive.class),
                         editLayer));
             }
Index: trunk/src/org/openstreetmap/josm/actions/IPrimitiveAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/IPrimitiveAction.java	(revision 13957)
+++ trunk/src/org/openstreetmap/josm/actions/IPrimitiveAction.java	(revision 13957)
@@ -0,0 +1,21 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.actions;
+
+import java.util.Collection;
+
+import javax.swing.Action;
+
+import org.openstreetmap.josm.data.osm.IPrimitive;
+
+/**
+ * Interface used to enable/disable all primitive-related actions, even those registered by plugins.
+ * @since 13957
+ */
+public interface IPrimitiveAction extends Action {
+
+    /**
+     * Specifies the working set of primitives.
+     * @param primitives The new working set of primitives. Can be null or empty
+     */
+    void setPrimitives(Collection<? extends IPrimitive> primitives);
+}
Index: trunk/src/org/openstreetmap/josm/actions/OsmPrimitiveAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/OsmPrimitiveAction.java	(revision 13955)
+++ trunk/src/org/openstreetmap/josm/actions/OsmPrimitiveAction.java	(revision 13957)
@@ -11,5 +11,7 @@
  * Interface used to enable/disable all primitive-related actions, even those registered by plugins.
  * @since 5821
+ * @deprecated Use {@link IPrimitiveAction} instead
  */
+@Deprecated
 public interface OsmPrimitiveAction extends Action {
 
Index: trunk/src/org/openstreetmap/josm/actions/relation/AbstractRelationAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/relation/AbstractRelationAction.java	(revision 13955)
+++ trunk/src/org/openstreetmap/josm/actions/relation/AbstractRelationAction.java	(revision 13957)
@@ -8,9 +8,9 @@
 
 import org.openstreetmap.josm.Main;
-import org.openstreetmap.josm.actions.OsmPrimitiveAction;
-import org.openstreetmap.josm.data.osm.DataSet;
+import org.openstreetmap.josm.actions.IPrimitiveAction;
 import org.openstreetmap.josm.data.osm.DownloadPolicy;
-import org.openstreetmap.josm.data.osm.OsmPrimitive;
-import org.openstreetmap.josm.data.osm.Relation;
+import org.openstreetmap.josm.data.osm.IPrimitive;
+import org.openstreetmap.josm.data.osm.IRelation;
+import org.openstreetmap.josm.data.osm.OsmData;
 import org.openstreetmap.josm.io.OnlineResource;
 import org.openstreetmap.josm.tools.SubclassFilteredCollection;
@@ -20,8 +20,9 @@
  * to be disabled if the collection is empty
  * @since 5793
+ * @since 13957 (signature)
  */
-public abstract class AbstractRelationAction extends AbstractAction implements OsmPrimitiveAction {
+public abstract class AbstractRelationAction extends AbstractAction implements IPrimitiveAction {
     /** relation collection */
-    protected transient Collection<Relation> relations = Collections.<Relation>emptySet();
+    protected transient Collection<IRelation<?>> relations = Collections.<IRelation<?>>emptySet();
 
     /**
@@ -30,14 +31,14 @@
      * @return the relation contained in {@code primitives}
      */
-    protected static final Collection<Relation> getRelations(Collection<? extends OsmPrimitive> primitives) {
+    protected static final Collection<IRelation<?>> getRelations(Collection<? extends IPrimitive> primitives) {
         if (primitives == null || primitives.isEmpty()) {
-            return Collections.<Relation>emptySet();
+            return Collections.<IRelation<?>>emptySet();
         } else {
-            return new SubclassFilteredCollection<>(primitives, Relation.class::isInstance);
+            return new SubclassFilteredCollection<>(primitives, IRelation.class::isInstance);
         }
     }
 
     @Override
-    public void setPrimitives(Collection<? extends OsmPrimitive> primitives) {
+    public void setPrimitives(Collection<? extends IPrimitive> primitives) {
         this.relations = getRelations(primitives);
         updateEnabledState();
@@ -55,5 +56,5 @@
             return false;
         }
-        DataSet ds = relations.iterator().next().getDataSet();
+        OsmData<?, ?, ?, ?> ds = relations.iterator().next().getDataSet();
         return !Main.isOffline(OnlineResource.OSM_API)
             && ds != null && !ds.isLocked() && !DownloadPolicy.BLOCKED.equals(ds.getDownloadPolicy());
Index: trunk/src/org/openstreetmap/josm/actions/relation/AddSelectionToRelations.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/relation/AddSelectionToRelations.java	(revision 13955)
+++ trunk/src/org/openstreetmap/josm/actions/relation/AddSelectionToRelations.java	(revision 13957)
@@ -14,6 +14,6 @@
 import org.openstreetmap.josm.command.SequenceCommand;
 import org.openstreetmap.josm.data.osm.DataSelectionListener;
-import org.openstreetmap.josm.data.osm.DataSet;
-import org.openstreetmap.josm.data.osm.OsmPrimitive;
+import org.openstreetmap.josm.data.osm.IPrimitive;
+import org.openstreetmap.josm.data.osm.OsmData;
 import org.openstreetmap.josm.data.osm.OsmUtils;
 import org.openstreetmap.josm.data.osm.Relation;
@@ -23,4 +23,5 @@
 import org.openstreetmap.josm.gui.util.GuiHelper;
 import org.openstreetmap.josm.tools.ImageProvider;
+import org.openstreetmap.josm.tools.Utils;
 
 /**
@@ -40,5 +41,5 @@
     public void actionPerformed(ActionEvent e) {
         Collection<Command> cmds = new LinkedList<>();
-        for (Relation orig : relations) {
+        for (Relation orig : Utils.filteredCollection(relations, Relation.class)) {
             Command c = GenericRelationEditor.addPrimitivesToRelation(orig, MainApplication.getLayerManager().getActiveDataSet().getSelected());
             if (c != null) {
@@ -61,5 +62,5 @@
         int size = relations.size();
         putValue(NAME, trn("Add selection to {0} relation", "Add selection to {0} relations", size, size));
-        DataSet ds = MainApplication.getLayerManager().getActiveDataSet();
+        OsmData<?, ?, ?, ?> ds = MainApplication.getLayerManager().getActiveData();
         if (ds != null) {
             selectionChanged(ds.getSelected());
@@ -69,5 +70,5 @@
     }
 
-    private void selectionChanged(final Collection<? extends OsmPrimitive> newSelection) {
+    private void selectionChanged(final Collection<? extends IPrimitive> newSelection) {
         GuiHelper.runInEDT(() -> setEnabled(newSelection != null && !newSelection.isEmpty()
                 && OsmUtils.isOsmCollectionEditable(relations)));
Index: trunk/src/org/openstreetmap/josm/actions/relation/DeleteRelationsAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/relation/DeleteRelationsAction.java	(revision 13955)
+++ trunk/src/org/openstreetmap/josm/actions/relation/DeleteRelationsAction.java	(revision 13957)
@@ -14,4 +14,5 @@
 import org.openstreetmap.josm.gui.layer.OsmDataLayer;
 import org.openstreetmap.josm.tools.ImageProvider;
+import org.openstreetmap.josm.tools.Utils;
 
 /**
@@ -46,5 +47,5 @@
         if (!isEnabled())
             return;
-        deleteRelation(relations);
+        deleteRelation(Utils.filteredCollection(relations, Relation.class));
     }
 
Index: trunk/src/org/openstreetmap/josm/actions/relation/DownloadMembersAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/relation/DownloadMembersAction.java	(revision 13955)
+++ trunk/src/org/openstreetmap/josm/actions/relation/DownloadMembersAction.java	(revision 13957)
@@ -8,9 +8,11 @@
 import java.util.Collection;
 
-import org.openstreetmap.josm.data.osm.OsmPrimitive;
+import org.openstreetmap.josm.data.osm.IPrimitive;
+import org.openstreetmap.josm.data.osm.Relation;
 import org.openstreetmap.josm.gui.MainApplication;
 import org.openstreetmap.josm.gui.dialogs.relation.DownloadRelationTask;
 import org.openstreetmap.josm.tools.ImageProvider;
 import org.openstreetmap.josm.tools.SubclassFilteredCollection;
+import org.openstreetmap.josm.tools.Utils;
 
 /**
@@ -33,9 +35,10 @@
     public void actionPerformed(ActionEvent e) {
         if (!isEnabled() || relations.isEmpty() || !MainApplication.isDisplayingMapView()) return;
-        MainApplication.worker.submit(new DownloadRelationTask(relations, MainApplication.getLayerManager().getEditLayer()));
+        MainApplication.worker.submit(new DownloadRelationTask(
+                Utils.filteredCollection(relations, Relation.class), MainApplication.getLayerManager().getEditLayer()));
     }
 
     @Override
-    public void setPrimitives(Collection<? extends OsmPrimitive> primitives) {
+    public void setPrimitives(Collection<? extends IPrimitive> primitives) {
         // selected non-new relations
         this.relations = SubclassFilteredCollection.filter(getRelations(primitives), r -> !r.isNew());
Index: trunk/src/org/openstreetmap/josm/actions/relation/DownloadSelectedIncompleteMembersAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/relation/DownloadSelectedIncompleteMembersAction.java	(revision 13955)
+++ trunk/src/org/openstreetmap/josm/actions/relation/DownloadSelectedIncompleteMembersAction.java	(revision 13957)
@@ -9,4 +9,6 @@
 import java.util.Set;
 
+import org.openstreetmap.josm.data.osm.IPrimitive;
+import org.openstreetmap.josm.data.osm.IRelation;
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
 import org.openstreetmap.josm.data.osm.Relation;
@@ -15,4 +17,5 @@
 import org.openstreetmap.josm.tools.ImageProvider;
 import org.openstreetmap.josm.tools.SubclassFilteredCollection;
+import org.openstreetmap.josm.tools.Utils;
 
 /**
@@ -22,5 +25,5 @@
 public class DownloadSelectedIncompleteMembersAction extends AbstractRelationAction {
 
-    private transient Collection<OsmPrimitive> incompleteMembers;
+    private transient Collection<IPrimitive> incompleteMembers;
 
     /**
@@ -38,7 +41,7 @@
      * @return The set of incomplete members of the given relations.
      */
-    public static Set<OsmPrimitive> buildSetOfIncompleteMembers(Collection<Relation> rels) {
-        Set<OsmPrimitive> ret = new HashSet<>();
-        for (Relation r : rels) {
+    public static Set<IPrimitive> buildSetOfIncompleteMembers(Collection<IRelation<?>> rels) {
+        Set<IPrimitive> ret = new HashSet<>();
+        for (IRelation<?> r : rels) {
             ret.addAll(SubclassFilteredCollection.filter(r.getIncompleteMembers(), osm -> !osm.isNew()));
         }
@@ -50,13 +53,13 @@
         if (!isEnabled() || relations.isEmpty() || !MainApplication.isDisplayingMapView()) return;
         MainApplication.worker.submit(new DownloadRelationMemberTask(
-                relations,
-                incompleteMembers,
+                Utils.filteredCollection(relations, Relation.class),
+                Utils.filteredCollection(incompleteMembers, OsmPrimitive.class),
                 MainApplication.getLayerManager().getEditLayer()));
     }
 
     @Override
-    public void setPrimitives(Collection<? extends OsmPrimitive> primitives) {
+    public void setPrimitives(Collection<? extends IPrimitive> primitives) {
         // selected relations with incomplete members
-        this.relations = SubclassFilteredCollection.filter(getRelations(primitives), Relation::hasIncompleteMembers);
+        this.relations = SubclassFilteredCollection.filter(getRelations(primitives), IRelation::hasIncompleteMembers);
         this.incompleteMembers = buildSetOfIncompleteMembers(relations);
         updateEnabledState();
Index: trunk/src/org/openstreetmap/josm/actions/relation/DuplicateRelationAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/relation/DuplicateRelationAction.java	(revision 13955)
+++ trunk/src/org/openstreetmap/josm/actions/relation/DuplicateRelationAction.java	(revision 13957)
@@ -6,4 +6,5 @@
 import java.awt.event.ActionEvent;
 
+import org.openstreetmap.josm.data.osm.IRelation;
 import org.openstreetmap.josm.data.osm.Relation;
 import org.openstreetmap.josm.gui.MainApplication;
@@ -45,6 +46,8 @@
         if (!isEnabled() || relations.isEmpty())
             return;
-        Relation r = relations.iterator().next();
-        duplicateRelationAndLaunchEditor(r);
+        IRelation<?> r = relations.iterator().next();
+        if (r instanceof Relation) {
+            duplicateRelationAndLaunchEditor((Relation) r);
+        }
     }
 
@@ -52,5 +55,7 @@
     protected void updateEnabledState() {
         // only one selected relation can be edited
-        setEnabled(relations.size() == 1 && !relations.iterator().next().getDataSet().isLocked());
+        setEnabled(relations.size() == 1
+                && relations.iterator().next() instanceof Relation
+                && !relations.iterator().next().getDataSet().isLocked());
     }
 }
Index: trunk/src/org/openstreetmap/josm/actions/relation/EditRelationAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/relation/EditRelationAction.java	(revision 13955)
+++ trunk/src/org/openstreetmap/josm/actions/relation/EditRelationAction.java	(revision 13957)
@@ -13,4 +13,5 @@
 
 import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.data.osm.IRelation;
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
 import org.openstreetmap.josm.data.osm.OsmUtils;
@@ -22,4 +23,6 @@
 import org.openstreetmap.josm.spi.preferences.Config;
 import org.openstreetmap.josm.tools.ImageProvider;
+import org.openstreetmap.josm.tools.SubclassFilteredCollection;
+import org.openstreetmap.josm.tools.Utils;
 
 /**
@@ -71,15 +74,16 @@
     @Override
     public void actionPerformed(ActionEvent e) {
-        if (!isEnabled() || relations.isEmpty()) return;
-        if (relations.size() > Config.getPref().getInt("warn.open.maxrelations", 5) &&
+        SubclassFilteredCollection<IRelation<?>, Relation> filteredRelations = Utils.filteredCollection(relations, Relation.class);
+        if (!isEnabled() || filteredRelations.isEmpty()) return;
+        if (filteredRelations.size() > Config.getPref().getInt("warn.open.maxrelations", 5) &&
             /* I18N english text for value 1 makes no real sense, never called for values <= maxrel (usually 5) */
             JOptionPane.OK_OPTION != JOptionPane.showConfirmDialog(Main.parent,
                     "<html>"+trn("You are about to open <b>{0}</b> different relation editor simultaneously.<br/>Do you want to continue?",
                             "You are about to open <b>{0}</b> different relation editors simultaneously.<br/>Do you want to continue?",
-                            relations.size(), relations.size())+"</html>",
+                            filteredRelations.size(), filteredRelations.size())+"</html>",
                     tr("Confirmation"), JOptionPane.OK_CANCEL_OPTION, JOptionPane.WARNING_MESSAGE)) {
             return;
         }
-        for (Relation r : relations) {
+        for (Relation r : filteredRelations) {
             launchEditor(r);
         }
@@ -89,6 +93,7 @@
     protected void updateEnabledState() {
         boolean enabled = false;
-        if (OsmUtils.isOsmCollectionEditable(relations)) {
-            for (Relation r : relations) {
+        SubclassFilteredCollection<IRelation<?>, Relation> filteredRelations = Utils.filteredCollection(relations, Relation.class);
+        if (OsmUtils.isOsmCollectionEditable(filteredRelations)) {
+            for (Relation r : filteredRelations) {
                 if (!r.isDeleted()) {
                     enabled = true;
Index: trunk/src/org/openstreetmap/josm/actions/relation/ExportRelationToGpxAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/relation/ExportRelationToGpxAction.java	(revision 13955)
+++ trunk/src/org/openstreetmap/josm/actions/relation/ExportRelationToGpxAction.java	(revision 13957)
@@ -23,10 +23,10 @@
 
 import org.openstreetmap.josm.actions.GpxExportAction;
-import org.openstreetmap.josm.actions.OsmPrimitiveAction;
+import org.openstreetmap.josm.actions.IPrimitiveAction;
 import org.openstreetmap.josm.data.gpx.GpxData;
 import org.openstreetmap.josm.data.gpx.ImmutableGpxTrack;
 import org.openstreetmap.josm.data.gpx.WayPoint;
+import org.openstreetmap.josm.data.osm.IPrimitive;
 import org.openstreetmap.josm.data.osm.Node;
-import org.openstreetmap.josm.data.osm.OsmPrimitive;
 import org.openstreetmap.josm.data.osm.Relation;
 import org.openstreetmap.josm.data.osm.RelationMember;
@@ -47,5 +47,5 @@
  */
 public class ExportRelationToGpxAction extends GpxExportAction
-    implements OsmPrimitiveAction {
+    implements IPrimitiveAction {
 
     /** Enumeration of export variants */
@@ -235,5 +235,5 @@
 
     @Override
-    public void setPrimitives(Collection<? extends OsmPrimitive> primitives) {
+    public void setPrimitives(Collection<? extends IPrimitive> primitives) {
         relations = Collections.<Relation>emptySet();
         if (primitives != null && !primitives.isEmpty()) {
Index: trunk/src/org/openstreetmap/josm/actions/relation/SelectMembersAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/relation/SelectMembersAction.java	(revision 13955)
+++ trunk/src/org/openstreetmap/josm/actions/relation/SelectMembersAction.java	(revision 13957)
@@ -8,6 +8,6 @@
 import java.util.Set;
 
-import org.openstreetmap.josm.data.osm.OsmPrimitive;
-import org.openstreetmap.josm.data.osm.Relation;
+import org.openstreetmap.josm.data.osm.IPrimitive;
+import org.openstreetmap.josm.data.osm.IRelation;
 import org.openstreetmap.josm.gui.MainApplication;
 import org.openstreetmap.josm.tools.ImageProvider;
@@ -38,12 +38,12 @@
         if (!isEnabled() || relations.isEmpty() || !MainApplication.isDisplayingMapView()) return;
 
-        Set<OsmPrimitive> members = new HashSet<>();
-        for (Relation r: relations) {
+        Set<IPrimitive> members = new HashSet<>();
+        for (IRelation<?> r: relations) {
             members.addAll(r.getMemberPrimitivesList());
         }
         if (add) {
-            MainApplication.getLayerManager().getActiveDataSet().addSelected(members);
+            MainApplication.getLayerManager().getActiveData().addSelected(members);
         } else {
-            MainApplication.getLayerManager().getActiveDataSet().setSelected(members);
+            MainApplication.getLayerManager().getActiveData().setSelected(members);
         }
     }
Index: trunk/src/org/openstreetmap/josm/actions/relation/SelectRelationAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/relation/SelectRelationAction.java	(revision 13955)
+++ trunk/src/org/openstreetmap/josm/actions/relation/SelectRelationAction.java	(revision 13957)
@@ -6,5 +6,5 @@
 import java.awt.event.ActionEvent;
 
-import org.openstreetmap.josm.data.osm.DataSet;
+import org.openstreetmap.josm.data.osm.OsmData;
 import org.openstreetmap.josm.gui.MainApplication;
 import org.openstreetmap.josm.tools.ImageProvider;
@@ -34,5 +34,5 @@
     public void actionPerformed(ActionEvent e) {
         if (!isEnabled() || relations.isEmpty()) return;
-        DataSet ds = MainApplication.getLayerManager().getActiveDataSet();
+        OsmData<?, ?, ?, ?> ds = MainApplication.getLayerManager().getActiveData();
         if (ds == null) return;
         if (add) {
