Index: trunk/src/org/openstreetmap/josm/data/osm/DataSet.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/osm/DataSet.java	(revision 2308)
+++ trunk/src/org/openstreetmap/josm/data/osm/DataSet.java	(revision 2309)
@@ -5,6 +5,8 @@
 import java.util.Arrays;
 import java.util.Collection;
+import java.util.Collections;
 import java.util.Comparator;
 import java.util.HashMap;
+import java.util.LinkedHashSet;
 import java.util.HashSet;
 import java.util.Iterator;
@@ -14,4 +16,5 @@
 
 import org.openstreetmap.josm.data.SelectionChangedListener;
+import org.openstreetmap.josm.data.osm.OsmPrimitive;
 
 /**
@@ -156,4 +159,5 @@
             relations.remove(primitive);
         }
+        selectedPrimitives.remove(primitive);
     }
 
@@ -163,6 +167,10 @@
 
     public Collection<OsmPrimitive> getSelectedNodesAndWays() {
-        Collection<OsmPrimitive> sel = getSelected(nodes);
-        sel.addAll(getSelected(ways));
+        Collection<OsmPrimitive> sel = new LinkedList<OsmPrimitive>();
+        for (OsmPrimitive osm : selectedPrimitives) {
+            if (osm instanceof Way ||
+                osm instanceof Node)
+                sel.add(osm);
+        }
         return sel;
     }
@@ -174,8 +182,9 @@
      */
     public Collection<OsmPrimitive> getSelected() {
-        Collection<OsmPrimitive> sel = getSelected(nodes);
-        sel.addAll(getSelected(ways));
-        sel.addAll(getSelected(relations));
-        return sel;
+        // It would be nice to have this be a copy-on-write list
+        // or an Collections.unmodifiableList().  It would be
+        // much faster for large selections.  May users just
+        // call this, and only check the .size().
+        return new ArrayList<OsmPrimitive>(selectedPrimitives);
     }
 
@@ -233,15 +242,13 @@
     }
 
-    public boolean addSelected(OsmPrimitive osm) {
-        osm.setSelected(true);
+    LinkedHashSet<OsmPrimitive> selectedPrimitives = new LinkedHashSet<OsmPrimitive>();
+
+    public boolean toggleSelected(OsmPrimitive osm) {
+        if (!selectedPrimitives.remove(osm))
+            selectedPrimitives.add(osm);
         return true;
     }
-
-    public boolean toggleSelected(OsmPrimitive osm) {
-        osm.setSelected(!osm.isSelected());
-        return true;
-    }
     public boolean isSelected(OsmPrimitive osm) {
-        return osm.isSelected();
+        return selectedPrimitives.contains(osm);
     }
 
@@ -268,10 +275,5 @@
      */
     public void setSelected(Collection<? extends OsmPrimitive> selection, boolean fireSelectionChangeEvent) {
-        clearSelection(nodes);
-        clearSelection(ways);
-        clearSelection(relations);
-        for (OsmPrimitive osm : selection) {
-            osm.setSelected(true);
-        }
+        selectedPrimitives = new LinkedHashSet<OsmPrimitive>(selection);
         if (fireSelectionChangeEvent) {
             fireSelectionChanged(selection);
@@ -299,4 +301,8 @@
     }
 
+    public void addSelected(OsmPrimitive... osm) {
+        addSelected(Arrays.asList(osm));
+    }
+
     /**
      * Adds the primitives in <code>selection</code> to the current selection.
@@ -307,7 +313,5 @@
      */
     public void addSelected(Collection<? extends OsmPrimitive> selection, boolean fireSelectionChangeEvent) {
-        for (OsmPrimitive osm : selection) {
-            osm.setSelected(true);
-        }
+        selectedPrimitives.addAll(selection);
         if (fireSelectionChangeEvent) {
             fireSelectionChanged(selection);
@@ -321,12 +325,7 @@
             return;
         }
-        clearSelection(nodes);
-        clearSelection(ways);
-        clearSelection(relations);
-        for (OsmPrimitive o : osm)
-            if (o != null) {
-                o.setSelected(true);
-            }
-        fireSelectionChanged(Arrays.asList(osm));
+        List<OsmPrimitive> list = Arrays.asList(osm);
+        setSelected(list);
+        fireSelectionChanged(list);
     }
 
@@ -364,7 +363,5 @@
         if (list == null)
             return;
-        for (OsmPrimitive osm : list) {
-            osm.setSelected(false);
-        }
+        selectedPrimitives.removeAll(list);
     }
 
@@ -374,11 +371,11 @@
      */
     private Collection<OsmPrimitive> getSelected(Collection<? extends OsmPrimitive> list) {
-        Collection<OsmPrimitive> sel = new HashSet<OsmPrimitive>();
         if (list == null)
-            return sel;
-        for (OsmPrimitive osm : list)
-            if (osm.isSelected() && !osm.isDeleted()) {
-                sel.add(osm);
-            }
+            return new LinkedList<OsmPrimitive>();
+        // getSelected() is called with large lists, so
+        // creating the return list from the selection
+        // should be faster most of the time.
+        Collection<OsmPrimitive> sel = new LinkedHashSet<OsmPrimitive>(selectedPrimitives);
+        sel.retainAll(list);
         return sel;
     }
Index: trunk/src/org/openstreetmap/josm/data/osm/OsmPrimitive.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/osm/OsmPrimitive.java	(revision 2308)
+++ trunk/src/org/openstreetmap/josm/data/osm/OsmPrimitive.java	(revision 2309)
@@ -47,7 +47,6 @@
     private static final int FLAG_DELETED  = 1 << 3;
     private static final int FLAG_FILTERED = 1 << 4;
-    private static final int FLAG_SELECTED = 1 << 5;
-    private static final int FLAG_HAS_DIRECTIONS = 1 << 6;
-    private static final int FLAG_TAGGED = 1 << 7;
+    private static final int FLAG_HAS_DIRECTIONS = 1 << 5;
+    private static final int FLAG_TAGGED = 1 << 6;
 
     /**
@@ -189,5 +188,5 @@
      * Sets whether this primitive is disabled or not.
      *
-     * @param selected  true, if this primitive is disabled; false, otherwise
+     * @param disabled true, if this primitive is disabled; false, otherwise
      */
     public void setDisabled(boolean disabled) {
@@ -211,5 +210,5 @@
      * Sets whether this primitive is filtered out or not.
      *
-     * @param selected  true, if this primitive is filtered out; false, otherwise
+     * @param filtered true, if this primitive is filtered out; false, otherwise
      */
     public void setFiltered(boolean filtered) {
@@ -227,27 +226,4 @@
     public boolean isFiltered() {
         return (flags & FLAG_FILTERED) != 0;
-    }
-
-    /**
-     * Sets whether this primitive is selected or not.
-     *
-     * @param selected  true, if this primitive is selected; false, otherwise
-     * @since 1899
-     */
-    @Deprecated public void setSelected(boolean selected) {
-        if (selected) {
-            flags |= FLAG_SELECTED;
-        } else {
-            flags &= ~FLAG_SELECTED;
-        }
-    }
-    /**
-     * Replies true, if this primitive is selected.
-     *
-     * @return true, if this primitive is selected
-     * @since 1899
-     */
-    @Deprecated public boolean isSelected() {
-        return (flags & FLAG_SELECTED) != 0;
     }
 
@@ -475,5 +451,5 @@
      * Sets whether this primitive is deleted or not.
      *
-     * Also marks this primitive as modified if deleted is true and sets selected to false.
+     * Also marks this primitive as modified if deleted is true.
      *
      * @param deleted  true, if this primitive is deleted; false, otherwise
@@ -486,5 +462,4 @@
         }
         setModified(deleted);
-        setSelected(false);
     }
 
