Index: /trunk/src/org/openstreetmap/josm/actions/search/SearchCompiler.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/actions/search/SearchCompiler.java	(revision 6673)
+++ /trunk/src/org/openstreetmap/josm/actions/search/SearchCompiler.java	(revision 6674)
@@ -22,4 +22,5 @@
 import org.openstreetmap.josm.data.osm.Node;
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
+import org.openstreetmap.josm.data.osm.OsmPrimitiveType;
 import org.openstreetmap.josm.data.osm.OsmUtils;
 import org.openstreetmap.josm.data.osm.Relation;
@@ -746,20 +747,14 @@
     }
 
-    // TODO: change how we handle this
     private static class ExactType extends Match {
-        private final Class<?> type;
+        private final OsmPrimitiveType type;
         public ExactType(String type) throws ParseError {
-            if ("node".equals(type)) {
-                this.type = Node.class;
-            } else if ("way".equals(type)) {
-                this.type = Way.class;
-            } else if ("relation".equals(type)) {
-                this.type = Relation.class;
-            } else
+            this.type = OsmPrimitiveType.from(type);
+            if (this.type == null)
                 throw new ParseError(tr("Unknown primitive type: {0}. Allowed values are node, way or relation",
                         type));
         }
         @Override public boolean match(OsmPrimitive osm) {
-            return osm.getClass() == type;
+            return type.equals(osm.getType());
         }
         @Override public String toString() {return "type="+type;}
Index: /trunk/src/org/openstreetmap/josm/data/osm/SimplePrimitiveId.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/data/osm/SimplePrimitiveId.java	(revision 6673)
+++ /trunk/src/org/openstreetmap/josm/data/osm/SimplePrimitiveId.java	(revision 6674)
@@ -3,4 +3,6 @@
 
 import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
@@ -9,4 +11,6 @@
     private final long id;
     private final OsmPrimitiveType type;
+
+    public static final Pattern ID_PATTERN = Pattern.compile("((n(ode)?|w(ay)?|r(el(ation)?)?)/?)(\\d+)");
 
     public SimplePrimitiveId(long id, OsmPrimitiveType type) {
@@ -64,21 +68,42 @@
 
     /**
-     * Parses a {@code OsmPrimitiveType} from the string {@code s}.
+     * Parses a {@code SimplePrimitiveId} from the string {@code s}.
      * @param s the string to be parsed, e.g., {@code n1}, {@code node1},
      * {@code w1}, {@code way1}, {@code r1}, {@code rel1}, {@code relation1}.
-     * @return the parsed {@code OsmPrimitiveType}
+     * @return the parsed {@code SimplePrimitiveId}
      * @throws IllegalArgumentException if the string does not match the pattern
      */
     public static SimplePrimitiveId fromString(String s) {
-        final Pattern p = Pattern.compile("((n(ode)?|w(ay)?|r(el(ation)?)?)/?)(\\d+)");
-        final Matcher m = p.matcher(s);
+        final Matcher m = ID_PATTERN.matcher(s);
         if (m.matches()) {
             return new SimplePrimitiveId(Long.parseLong(m.group(m.groupCount())),
-                    s.charAt(0) == 'n' ? OsmPrimitiveType.NODE
-                    : s.charAt(0) == 'w' ? OsmPrimitiveType.WAY
-                    : OsmPrimitiveType.RELATION);
+                    s.charAt(0) == 'n'
+                            ? OsmPrimitiveType.NODE
+                            : s.charAt(0) == 'w'
+                            ? OsmPrimitiveType.WAY
+                            : OsmPrimitiveType.RELATION);
         } else {
-            throw new IllegalArgumentException("The string " + s + " does not match the pattern " + p);
+            throw new IllegalArgumentException("The string " + s + " does not match the pattern " + ID_PATTERN);
         }
     }
+
+    /**
+     * Attempts to parse extract any primitive id from the string {@code s}.
+     * @param s the string to be parsed, e.g., {@code n1, w1}, {@code node1 and rel2}.
+     * @return the parsed list of {@code OsmPrimitiveType}s.
+     */
+    public static List<SimplePrimitiveId> fuzzyParse(String s) {
+        final ArrayList<SimplePrimitiveId> ids = new ArrayList<SimplePrimitiveId>();
+        final Matcher m = ID_PATTERN.matcher(s);
+        while (m.find()) {
+            final char firstChar = s.charAt(m.start());
+            ids.add(new SimplePrimitiveId(Long.parseLong(m.group(m.groupCount())),
+                    firstChar == 'n'
+                            ? OsmPrimitiveType.NODE
+                            : firstChar == 'w'
+                            ? OsmPrimitiveType.WAY
+                            : OsmPrimitiveType.RELATION));
+        }
+        return ids;
+    }
 }
Index: /trunk/src/org/openstreetmap/josm/gui/dialogs/OsmIdSelectionDialog.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/dialogs/OsmIdSelectionDialog.java	(revision 6673)
+++ /trunk/src/org/openstreetmap/josm/gui/dialogs/OsmIdSelectionDialog.java	(revision 6674)
@@ -3,5 +3,7 @@
 
 import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.data.osm.OsmPrimitiveType;
 import org.openstreetmap.josm.data.osm.PrimitiveId;
+import org.openstreetmap.josm.data.osm.SimplePrimitiveId;
 import org.openstreetmap.josm.gui.ExtendedDialog;
 import org.openstreetmap.josm.gui.widgets.HistoryComboBox;
@@ -29,6 +31,8 @@
 import java.util.Collection;
 import java.util.Collections;
+import java.util.HashSet;
 import java.util.LinkedList;
 import java.util.List;
+import java.util.Set;
 
 import static org.openstreetmap.josm.tools.I18n.tr;
@@ -187,17 +191,36 @@
         String buf = Utils.getClipboardContent();
         if (buf != null) {
-            if (buf.contains("node")) cbType.setSelectedIndex(0);
-            if (buf.contains("way")) cbType.setSelectedIndex(1);
-            if (buf.contains("relation")) cbType.setSelectedIndex(2);
-            String[] res = buf.split("/");
-            String txt;
-            if (res.length > 0) {
-                txt = res[res.length - 1];
-                if (txt.isEmpty() && txt.length() > 1) txt = res[res.length - 2];
+            if (buf.length() <= Main.pref.getInteger("downloadprimitive.max-autopaste-length", 2000)) {
+                final List<SimplePrimitiveId> ids = SimplePrimitiveId.fuzzyParse(buf);
+                final String parsedText = Utils.join(", ", Utils.transform(ids, new Utils.Function<SimplePrimitiveId, String>() {
+                    @Override
+                    public String apply(SimplePrimitiveId x) {
+                        return x.getType().getAPIName().charAt(0) + String.valueOf(x.getUniqueId());
+                    }
+                }));
+                tfId.tryToPasteFrom(parsedText);
+                final Set<OsmPrimitiveType> types = new HashSet<OsmPrimitiveType>(Utils.transform(ids, new Utils.Function<SimplePrimitiveId, OsmPrimitiveType>() {
+                    @Override
+                    public OsmPrimitiveType apply(SimplePrimitiveId x) {
+                        return x.getType();
+                    }
+                }));
+                if (types.size() == 1) {
+                    // select corresponding type
+                    cbType.setSelectedItem(types.iterator().next());
+                } else {
+                    // select "mixed"
+                    cbType.setSelectedIndex(3);
+                }
             } else {
-                txt = buf;
-            }
-            if (buf.length() <= Main.pref.getInteger("downloadprimitive.max-autopaste-length", 2000)) {
-                tfId.tryToPasteFrom(txt.replaceAll("[^0-9]+", " ").replaceAll("\\s\\s+", " "));
+                if (buf.contains("node")) cbType.setSelectedIndex(0);
+                if (buf.contains("way")) cbType.setSelectedIndex(1);
+                if (buf.contains("relation")) cbType.setSelectedIndex(2);
+                String[] res = buf.split("/");
+                String txt;
+                if (res.length > 0) {
+                    txt = res[res.length - 1];
+                    if (txt.isEmpty() && txt.length() > 1) txt = res[res.length - 2];
+                }
             }
         }
Index: /trunk/src/org/openstreetmap/josm/io/remotecontrol/handler/LoadAndZoomHandler.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/io/remotecontrol/handler/LoadAndZoomHandler.java	(revision 6673)
+++ /trunk/src/org/openstreetmap/josm/io/remotecontrol/handler/LoadAndZoomHandler.java	(revision 6674)
@@ -22,4 +22,5 @@
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
 import org.openstreetmap.josm.data.osm.Relation;
+import org.openstreetmap.josm.data.osm.SimplePrimitiveId;
 import org.openstreetmap.josm.data.osm.Way;
 import org.openstreetmap.josm.data.osm.visitor.BoundingXYVisitor;
@@ -52,7 +53,5 @@
 
     // Optional argument 'select'
-    private final Set<Long> ways = new HashSet<Long>();
-    private final Set<Long> nodes = new HashSet<Long>();
-    private final Set<Long> relations = new HashSet<Long>();
+    private final HashSet<SimplePrimitiveId> toSelect = new HashSet<SimplePrimitiveId>();
 
     @Override
@@ -60,6 +59,6 @@
         String msg = tr("Remote Control has been asked to load data from the API.") +
                 "<br>" + tr("Bounding box: ") + new BBox(minlon, minlat, maxlon, maxlat).toStringCSV(", ");
-        if (args.containsKey("select") && ways.size()+nodes.size()+relations.size() > 0) {
-            msg += "<br>" + tr("Sel.: Rel.:{0} / Ways:{1} / Nodes:{2}", relations.size(), ways.size(), nodes.size());
+        if (args.containsKey("select") && toSelect.size() > 0) {
+            msg += "<br>" + tr("Selection: {0}", toSelect.size());
         }
         return msg;
@@ -168,22 +167,11 @@
                     if(ds == null) // e.g. download failed
                         return;
-                    for (Way w : ds.getWays()) {
-                        if (ways.contains(w.getId())) {
-                            newSel.add(w);
-                        }
-                    }
-                    ways.clear();
-                    for (Node n : ds.getNodes()) {
-                        if (nodes.contains(n.getId())) {
-                            newSel.add(n);
-                        }
-                    }
-                    nodes.clear();
-                    for (Relation r : ds.getRelations()) {
-                        if (relations.contains(r.getId())) {
-                            newSel.add(r);
-                        }
-                    }
-                    relations.clear();
+                    for (SimplePrimitiveId id : toSelect) {
+                        final OsmPrimitive p = ds.getPrimitiveById(id);
+                        if (p != null) {
+                            newSel.add(p);
+                        }
+                    }
+                    toSelect.clear();
                     ds.setSelected(newSel);
                     if (PermissionPrefWithDefault.CHANGE_VIEWPORT.isAllowed()) {
@@ -277,22 +265,10 @@
         // Process optional argument 'select'
         if (args.containsKey("select")) {
-            ways.clear();
-            nodes.clear();
-            relations.clear();
+            toSelect.clear();
             for (String item : args.get("select").split(",")) {
                 try {
-                    if (item.startsWith("way")) {
-                        ways.add(Long.parseLong(item.substring(3)));
-                    } else if (item.startsWith("node")) {
-                        nodes.add(Long.parseLong(item.substring(4)));
-                    } else if (item.startsWith("relation")) {
-                        relations.add(Long.parseLong(item.substring(8)));
-                    } else if (item.startsWith("rel")) {
-                        relations.add(Long.parseLong(item.substring(3)));
-                    } else {
-                        Main.warn("RemoteControl: invalid selection '"+item+"' ignored");
-                    }
-                } catch (NumberFormatException e) {
-                    Main.warn("RemoteControl: invalid selection '"+item+"' ignored");
+                    toSelect.add(SimplePrimitiveId.fromString(item));
+                } catch (IllegalArgumentException ex) {
+                    Main.warn("RemoteControl: invalid selection '" + item + "' ignored");
                 }
             }
Index: /trunk/test/unit/org/openstreetmap/josm/data/osm/SimplePrimitiveIdTest.groovy
===================================================================
--- /trunk/test/unit/org/openstreetmap/josm/data/osm/SimplePrimitiveIdTest.groovy	(revision 6674)
+++ /trunk/test/unit/org/openstreetmap/josm/data/osm/SimplePrimitiveIdTest.groovy	(revision 6674)
@@ -0,0 +1,30 @@
+package org.openstreetmap.josm.data.osm
+
+class SimplePrimitiveIdTest extends GroovyTestCase {
+
+    void testNode() {
+        assert SimplePrimitiveId.fromString("node/123") == new SimplePrimitiveId(123, OsmPrimitiveType.NODE)
+        assert SimplePrimitiveId.fromString("n123") == new SimplePrimitiveId(123, OsmPrimitiveType.NODE)
+        assert SimplePrimitiveId.fromString("node123") == new SimplePrimitiveId(123, OsmPrimitiveType.NODE)
+        assert SimplePrimitiveId.fromString("n123456789123456789") == new SimplePrimitiveId(123456789123456789, OsmPrimitiveType.NODE)
+    }
+
+    void testWay() {
+        assert SimplePrimitiveId.fromString("way/123") == new SimplePrimitiveId(123, OsmPrimitiveType.WAY)
+        assert SimplePrimitiveId.fromString("w123") == new SimplePrimitiveId(123, OsmPrimitiveType.WAY)
+        assert SimplePrimitiveId.fromString("way123") == new SimplePrimitiveId(123, OsmPrimitiveType.WAY)
+        assert SimplePrimitiveId.fromString("w123456789123456789") == new SimplePrimitiveId(123456789123456789, OsmPrimitiveType.WAY)
+    }
+
+    void testRelation() {
+        assert SimplePrimitiveId.fromString("relation/123") == new SimplePrimitiveId(123, OsmPrimitiveType.RELATION)
+        assert SimplePrimitiveId.fromString("r123") == new SimplePrimitiveId(123, OsmPrimitiveType.RELATION)
+        assert SimplePrimitiveId.fromString("rel123") == new SimplePrimitiveId(123, OsmPrimitiveType.RELATION)
+        assert SimplePrimitiveId.fromString("relation123") == new SimplePrimitiveId(123, OsmPrimitiveType.RELATION)
+    }
+
+    void testFuzzy() {
+        assert SimplePrimitiveId.fuzzyParse("foo relation/123 bar").toString() == "[relation 123]"
+        assert SimplePrimitiveId.fuzzyParse("foo relation/123 and way/345 but also node/789").toString() == "[relation 123, way 345, node 789]"
+    }
+}
