Index: trunk/src/org/openstreetmap/josm/actions/ReverseWayAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/ReverseWayAction.java	(revision 2347)
+++ trunk/src/org/openstreetmap/josm/actions/ReverseWayAction.java	(revision 2348)
@@ -81,5 +81,5 @@
         Main.main.undoRedo.add(new SequenceCommand(tr("Reverse ways"), c));
         if (propertiesUpdated) {
-            DataSet.fireSelectionChanged(getCurrentDataSet().getSelected());
+            getCurrentDataSet().fireSelectionChanged();
         }
         Main.map.repaint();
Index: trunk/src/org/openstreetmap/josm/actions/UploadAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/UploadAction.java	(revision 2347)
+++ trunk/src/org/openstreetmap/josm/actions/UploadAction.java	(revision 2348)
@@ -688,5 +688,5 @@
             //
             layer.cleanupAfterUpload(processedPrimitives);
-            DataSet.fireSelectionChanged(layer.data.getSelected());
+            layer.data.fireSelectionChanged();
             layer.fireDataChange();
             if (lastException != null) {
Index: trunk/src/org/openstreetmap/josm/actions/mapmode/DrawAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/mapmode/DrawAction.java	(revision 2347)
+++ trunk/src/org/openstreetmap/josm/actions/mapmode/DrawAction.java	(revision 2348)
@@ -245,5 +245,5 @@
         // primitives
         //
-        DataSet.fireSelectionChanged(getCurrentDataSet().getSelected());
+        getCurrentDataSet().fireSelectionChanged();
     }
 
@@ -272,5 +272,5 @@
     private void tryAgain(MouseEvent e) {
         getCurrentDataSet().setSelected();
-        DataSet.fireSelectionChanged(getCurrentDataSet().getSelected());
+        Main.main.getCurrentDataSet().fireSelectionChanged();
         mouseClicked(e);
     }
@@ -284,5 +284,5 @@
         // let everybody else know about the current selection
         //
-        DataSet.fireSelectionChanged(getCurrentDataSet().getSelected());
+        Main.main.getCurrentDataSet().fireSelectionChanged();
         lastUsedNode = null;
         wayIsFinished = true;
@@ -345,6 +345,6 @@
                 // (this is just a convenience option so that people don't
                 // have to switch modes)
-                newSelection.clear();
-                newSelection.add(n);
+                getCurrentDataSet().setSelected(n);
+                selection = getCurrentDataSet().getSelected();
                 // The user explicitly selected a node, so let him continue drawing
                 wayIsFinished = false;
@@ -523,6 +523,6 @@
 
                 extendedWay = true;
-                newSelection.clear();
-                newSelection.add(wayToSelect);
+                ds.setSelected(way);
+                ds.fireSelectionChanged();
             }
         }
@@ -540,5 +540,7 @@
                 }
             }
-            newSelection.add(n);
+
+            ds.setSelected(n);
+            ds.fireSelectionChanged();
         } else if (!newNode) {
             title = tr("Connect existing way to node");
@@ -585,5 +587,5 @@
                     (posn0 < selectedWay.getNodesCount()-1) && targetNode.equals(selectedWay.getNode(posn0+1))) {  // next node
                 getCurrentDataSet().setSelected(targetNode);
-                DataSet.fireSelectionChanged(getCurrentDataSet().getSelected());
+                getCurrentDataSet().fireSelectionChanged();
                 lastUsedNode = targetNode;
                 return true;
Index: trunk/src/org/openstreetmap/josm/actions/mapmode/SelectAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/mapmode/SelectAction.java	(revision 2347)
+++ trunk/src/org/openstreetmap/josm/actions/mapmode/SelectAction.java	(revision 2348)
@@ -499,5 +499,5 @@
                     }
                 }
-                DataSet.fireSelectionChanged(selection);
+                getCurrentDataSet().fireSelectionChanged();
             }
         }
@@ -515,28 +515,28 @@
     public void selectPrims(Collection<OsmPrimitive> selectionList, boolean shift,
             boolean ctrl, boolean released, boolean area) {
+        DataSet ds = getCurrentDataSet();
         if ((shift && ctrl) || (ctrl && !released))
             return; // not allowed together
 
-        Collection<OsmPrimitive> curSel;
-        if (!ctrl && !shift) {
-            curSel = new LinkedList<OsmPrimitive>(); // new selection will replace the old.
+        // plain clicks with no modifiers clear the selection
+        if (!ctrl && !shift)
+            ds.clearSelection();
+
+        if (ctrl) {
+            // Ctrl on an item toggles its selection status,
+            // but Ctrl on an *area* just clears those items
+            // out of the selection.
+            if (area)
+                ds.clearSelection(selectionList);
+            else
+                ds.toggleSelected(selectionList);
         } else {
-            curSel = getCurrentDataSet().getSelected();
-        }
-
-        for (OsmPrimitive osm : selectionList)
-        {
-            if (ctrl)
-            {
-                if(curSel.contains(osm)) {
-                    curSel.remove(osm);
-                } else if(!area) {
-                    curSel.add(osm);
-                }
-            } else {
-                curSel.add(osm);
-            }
-        }
-        getCurrentDataSet().setSelected(curSel);
+            // This is either a plain click (which means we
+            // previously cleared the selection), or a
+            // shift-click where we are adding things to an
+            // existing selection.
+            ds.addSelected(selectionList);
+        }
+        ds.fireSelectionChanged();
         Main.map.mapView.repaint();
     }
Index: trunk/src/org/openstreetmap/josm/data/UndoRedoHandler.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/UndoRedoHandler.java	(revision 2347)
+++ trunk/src/org/openstreetmap/josm/data/UndoRedoHandler.java	(revision 2348)
@@ -50,5 +50,5 @@
 
         // the command may have changed the selection so tell the listeners about the current situation
-        DataSet.fireSelectionChanged(Main.main.getCurrentDataSet().getSelected());
+        Main.main.getCurrentDataSet().fireSelectionChanged();
     }
 
Index: trunk/src/org/openstreetmap/josm/data/osm/DataSet.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/osm/DataSet.java	(revision 2347)
+++ trunk/src/org/openstreetmap/josm/data/osm/DataSet.java	(revision 2348)
@@ -26,33 +26,5 @@
  */
 public class DataSet implements Cloneable {
-
-    /**
-     * The API version that created this data set, if any.
-     */
-    public String version;
-
-    /**
-     * All nodes goes here, even when included in other data (ways etc). This enables the instant
-     * conversion of the whole DataSet by iterating over this data structure.
-     */
-    public QuadBuckets<Node> nodes = new QuadBuckets<Node>();
-
-    /**
-     * All ways (Streets etc.) in the DataSet.
-     *
-     * The way nodes are stored only in the way list.
-     */
-    public QuadBuckets<Way> ways = new QuadBuckets<Way>();
-
-    /**
-     * All relations/relationships
-     */
-    public Collection<Relation> relations = new LinkedList<Relation>();
-
-    /**
-     * All data sources of this DataSet.
-     */
-    public Collection<DataSource> dataSources = new LinkedList<DataSource>();
-
+    
     /**
      * A list of listeners to selection changed events. The list is static, as listeners register
@@ -61,5 +33,45 @@
      */
     public static Collection<SelectionChangedListener> selListeners = new LinkedList<SelectionChangedListener>();
-
+    
+    /**
+     * notifies all registered selection change listeners about the current selection of
+     * primitives
+     * 
+     * @param sel the current selection
+     */
+    private static void notifySelectionChangeListeners(Collection<? extends OsmPrimitive> sel) {
+        for (SelectionChangedListener l : selListeners) {
+            l.selectionChanged(sel);
+        }
+    }
+
+    /**
+     * The API version that created this data set, if any.
+     */
+    public String version;
+
+    /**
+     * All nodes goes here, even when included in other data (ways etc). This enables the instant
+     * conversion of the whole DataSet by iterating over this data structure.
+     */
+    public QuadBuckets<Node> nodes = new QuadBuckets<Node>();
+
+    /**
+     * All ways (Streets etc.) in the DataSet.
+     *
+     * The way nodes are stored only in the way list.
+     */
+    public QuadBuckets<Way> ways = new QuadBuckets<Way>();
+
+    /**
+     * All relations/relationships
+     */
+    public Collection<Relation> relations = new LinkedList<Relation>();
+
+    /**
+     * All data sources of this DataSet.
+     */
+    public Collection<DataSource> dataSources = new LinkedList<DataSource>();
+    
     /**
      * @return A collection containing all primitives of the dataset. The data is ordered after:
@@ -242,5 +254,14 @@
     LinkedHashSet<OsmPrimitive> selectedPrimitives = new LinkedHashSet<OsmPrimitive>();
 
-    public boolean toggleSelected(OsmPrimitive osm) {
+    public boolean toggleSelected(Collection<OsmPrimitive> osm) {
+        for (OsmPrimitive o : osm)
+            this.__toggleSelected(o);
+        fireSelectionChanged();
+        return true;
+    }
+    public boolean toggleSelected(OsmPrimitive... osm) {
+        return this.toggleSelected(Arrays.asList(osm));
+    }
+    private boolean __toggleSelected(OsmPrimitive osm) {
         if (!selectedPrimitives.remove(osm)) {
             selectedPrimitives.add(osm);
@@ -276,5 +297,5 @@
         selectedPrimitives = new LinkedHashSet<OsmPrimitive>(selection);
         if (fireSelectionChangeEvent) {
-            fireSelectionChanged(selection);
+            fireSelectionChanged();
         }
     }
@@ -314,5 +335,5 @@
         selectedPrimitives.addAll(selection);
         if (fireSelectionChangeEvent) {
-            fireSelectionChanged(selection);
+            fireSelectionChanged();
         }
     }
@@ -326,5 +347,5 @@
         List<OsmPrimitive> list = Arrays.asList(osm);
         setSelected(list);
-        fireSelectionChanged(list);
+        fireSelectionChanged();
     }
 
@@ -359,8 +380,11 @@
         clearSelection(Arrays.asList(osm));
     }
-    private void clearSelection(Collection<? extends OsmPrimitive> list) {
+    public void clearSelection(Collection<? extends OsmPrimitive> list) {
         if (list == null)
             return;
         selectedPrimitives.removeAll(list);
+    }
+    public void clearSelection() {
+        selectedPrimitives.clear();
     }
 
@@ -381,13 +405,12 @@
 
     /**
-     * Remember to fire an selection changed event. A call to this will not fire the event
-     * immediately. For more,
-     * @see SelectionChangedListener
-     */
-    public static void fireSelectionChanged(Collection<? extends OsmPrimitive> sel) {
-        for (SelectionChangedListener l : selListeners) {
-            l.selectionChanged(sel);
-        }
-    }
+     * Notifies all registered {@see SelectionChangedListener} about the current selection in 
+     * this dataset.
+     * 
+     */
+    public void fireSelectionChanged(){
+        notifySelectionChangeListeners(selectedPrimitives);
+    }
+
 
     @Override public DataSet clone() {
Index: trunk/src/org/openstreetmap/josm/gui/MapStatus.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/MapStatus.java	(revision 2347)
+++ trunk/src/org/openstreetmap/josm/gui/MapStatus.java	(revision 2348)
@@ -333,5 +333,5 @@
                 }
             }
-            DataSet.fireSelectionChanged(ds.getSelected());
+            ds.fireSelectionChanged();
         }
 
@@ -463,5 +463,4 @@
                     // Let the user toggle the selection
                     ds.toggleSelected(osm);
-                    DataSet.fireSelectionChanged(ds.getSelected());
                     l.validate();
                 }
Index: trunk/src/org/openstreetmap/josm/gui/MapView.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/MapView.java	(revision 2347)
+++ trunk/src/org/openstreetmap/josm/gui/MapView.java	(revision 2348)
@@ -503,5 +503,5 @@
             if (getCurrentDataSet() != null) {
                 getCurrentDataSet().setSelected();
-                DataSet.fireSelectionChanged(getCurrentDataSet().getSelected());
+                getCurrentDataSet().fireSelectionChanged();
             }
         }
Index: trunk/src/org/openstreetmap/josm/gui/dialogs/PropertiesDialog.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/dialogs/PropertiesDialog.java	(revision 2347)
+++ trunk/src/org/openstreetmap/josm/gui/dialogs/PropertiesDialog.java	(revision 2348)
@@ -267,5 +267,5 @@
         }
 
-        DataSet.fireSelectionChanged(sel);
+        Main.main.getCurrentDataSet().fireSelectionChanged();
         selectionChanged(sel); // update whole table
         Main.parent.repaint(); // repaint all - drawing could have been changed
@@ -355,5 +355,5 @@
             return;
         Main.main.undoRedo.add(new ChangePropertyCommand(sel, key, value));
-        DataSet.fireSelectionChanged(sel);
+        Main.main.getCurrentDataSet().fireSelectionChanged();
         selectionChanged(sel); // update table
         Main.parent.repaint(); // repaint all - drawing could have been changed
@@ -826,5 +826,5 @@
             Collection<OsmPrimitive> sel = Main.main.getCurrentDataSet().getSelected();
             Main.main.undoRedo.add(new ChangePropertyCommand(sel, key, null));
-            DataSet.fireSelectionChanged(sel);
+            Main.main.getCurrentDataSet().fireSelectionChanged();
             selectionChanged(sel); // update table
 
@@ -852,5 +852,5 @@
             }
             Main.main.undoRedo.add(new ChangeCommand(cur, rel));
-            DataSet.fireSelectionChanged(sel);
+            Main.main.getCurrentDataSet().fireSelectionChanged();
             selectionChanged(sel); // update whole table
         }
Index: trunk/src/org/openstreetmap/josm/gui/dialogs/RelationListDialog.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/dialogs/RelationListDialog.java	(revision 2347)
+++ trunk/src/org/openstreetmap/josm/gui/dialogs/RelationListDialog.java	(revision 2348)
@@ -517,5 +517,5 @@
             }
             Main.map.mapView.getEditLayer().data.setSelected(selection);
-            DataSet.fireSelectionChanged(selection);
+            Main.map.mapView.getEditLayer().data.fireSelectionChanged();
         }
 
@@ -545,5 +545,4 @@
             }
             Main.map.mapView.getEditLayer().data.setSelected(members);
-            DataSet.fireSelectionChanged(members);
         }
 
Index: trunk/src/org/openstreetmap/josm/gui/dialogs/relation/GenericRelationEditor.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/dialogs/relation/GenericRelationEditor.java	(revision 2347)
+++ trunk/src/org/openstreetmap/josm/gui/dialogs/relation/GenericRelationEditor.java	(revision 2348)
@@ -883,5 +883,4 @@
         public void actionPerformed(ActionEvent e) {
             getLayer().data.setSelected(memberTableModel.getSelectedChildPrimitives());
-            DataSet.fireSelectionChanged(getLayer().data.getSelected());
         }
 
@@ -1006,5 +1005,5 @@
             // make sure everybody is notified about the changes
             //
-            DataSet.fireSelectionChanged(getLayer().data.getSelected());
+            getLayer().data.fireSelectionChanged();
             getLayer().fireDataChange();
             GenericRelationEditor.this.setRelation(newRelation);
@@ -1039,5 +1038,5 @@
             memberTableModel.applyToRelation(editedRelation);
             Main.main.undoRedo.add(new ChangeCommand(getRelation(), editedRelation));
-            DataSet.fireSelectionChanged(getLayer().data.getSelected());
+            getLayer().data.fireSelectionChanged();
             getLayer().fireDataChange();
             // this will refresh the snapshot and update the dialog title
Index: trunk/src/org/openstreetmap/josm/gui/dialogs/relation/MemberTable.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/dialogs/relation/MemberTable.java	(revision 2347)
+++ trunk/src/org/openstreetmap/josm/gui/dialogs/relation/MemberTable.java	(revision 2348)
@@ -204,5 +204,4 @@
             OsmPrimitive primitive = getMemberTableModel().getReferredPrimitive(row);
             layer.data.setSelected(primitive);
-            DataSet.fireSelectionChanged(layer.data.getSelected());
             AutoScaleAction action = new AutoScaleAction("selection");
             action.autoScale();
Index: trunk/src/org/openstreetmap/josm/gui/io/UploadLayerTask.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/io/UploadLayerTask.java	(revision 2347)
+++ trunk/src/org/openstreetmap/josm/gui/io/UploadLayerTask.java	(revision 2348)
@@ -144,5 +144,5 @@
             return;
         layer.cleanupAfterUpload(processedPrimitives);
-        DataSet.fireSelectionChanged(layer.data.getSelected());
+        layer.data.fireSelectionChanged();;
         layer.fireDataChange();
         layer.onPostUploadToServer();
