Index: trunk/src/org/openstreetmap/josm/actions/JosmAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/JosmAction.java	(revision 3415)
+++ trunk/src/org/openstreetmap/josm/actions/JosmAction.java	(revision 3416)
@@ -96,5 +96,5 @@
         }
         MapView.removeLayerChangeListener(layerChangeAdapter);
-        DataSet.selListeners.remove(selectionChangeAdapter);
+        DataSet.removeSelectionListener(selectionChangeAdapter);
     }
 
@@ -131,5 +131,5 @@
         selectionChangeAdapter = new SelectionChangeAdapter();
         MapView.addLayerChangeListener(layerChangeAdapter);
-        DataSet.selListeners.add(selectionChangeAdapter);
+        DataSet.addSelectionListener(selectionChangeAdapter);
         initEnabledState();
     }
Index: trunk/src/org/openstreetmap/josm/actions/mapmode/DrawAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/mapmode/DrawAction.java	(revision 3415)
+++ trunk/src/org/openstreetmap/josm/actions/mapmode/DrawAction.java	(revision 3416)
@@ -218,5 +218,5 @@
         Main.map.mapView.addMouseMotionListener(this);
         Main.map.mapView.addTemporaryLayer(this);
-        DataSet.selListeners.add(this);
+        DataSet.addSelectionListener(this);
 
         try {
@@ -233,5 +233,5 @@
         Main.map.mapView.removeMouseMotionListener(this);
         Main.map.mapView.removeTemporaryLayer(this);
-        DataSet.selListeners.remove(this);
+        DataSet.removeSelectionListener(this);
         removeHighlighting();
         try {
Index: trunk/src/org/openstreetmap/josm/data/osm/DataSet.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/osm/DataSet.java	(revision 3415)
+++ trunk/src/org/openstreetmap/josm/data/osm/DataSet.java	(revision 3416)
@@ -322,7 +322,16 @@
      * themselves for any dataset selection changes that occur, regardless of the current active
      * dataset. (However, the selection does only change in the active layer)
-     */
-    public static final Collection<SelectionChangedListener> selListeners =
-        Collections.synchronizedList(new LinkedList<SelectionChangedListener>());
+     * @deprecated Use addSelectionListener/removeSelectionListener instead
+     */
+    @Deprecated
+    public static final Collection<SelectionChangedListener> selListeners = new CopyOnWriteArrayList<SelectionChangedListener>();
+
+    public static void addSelectionListener(SelectionChangedListener listener) {
+        ((CopyOnWriteArrayList<SelectionChangedListener>)selListeners).addIfAbsent(listener);
+    }
+
+    public static void removeSelectionListener(SelectionChangedListener listener) {
+        selListeners.remove(listener);
+    }
 
     /**
Index: trunk/src/org/openstreetmap/josm/data/osm/DatasetCollection.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/osm/DatasetCollection.java	(revision 3415)
+++ trunk/src/org/openstreetmap/josm/data/osm/DatasetCollection.java	(revision 3416)
@@ -50,4 +50,5 @@
     private final Collection<? extends OsmPrimitive> primitives;
     private final Predicate<OsmPrimitive> predicate;
+    int size = -1;
 
     public DatasetCollection(Collection<? extends OsmPrimitive> primitives, Predicate<OsmPrimitive> predicate) {
@@ -63,9 +64,11 @@
     @Override
     public int size() {
-        int size = 0;
-        Iterator<T> it = iterator();
-        while (it.hasNext()) {
-            size++;
-            it.next();
+        if (size == -1) {
+            size = 0;
+            Iterator<T> it = iterator();
+            while (it.hasNext()) {
+                size++;
+                it.next();
+            }
         }
         return size;
Index: trunk/src/org/openstreetmap/josm/data/osm/event/SelectionEventManager.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/osm/event/SelectionEventManager.java	(revision 3415)
+++ trunk/src/org/openstreetmap/josm/data/osm/event/SelectionEventManager.java	(revision 3416)
@@ -49,5 +49,5 @@
 
     public SelectionEventManager() {
-        DataSet.selListeners.add(this);
+        DataSet.addSelectionListener(this);
     }
 
Index: trunk/src/org/openstreetmap/josm/gui/MapView.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/MapView.java	(revision 3415)
+++ trunk/src/org/openstreetmap/josm/gui/MapView.java	(revision 3416)
@@ -222,5 +222,5 @@
 
         // listend to selection changes to redraw the map
-        DataSet.selListeners.add(new SelectionChangedListener(){
+        DataSet.addSelectionListener(new SelectionChangedListener(){
             public void selectionChanged(Collection<? extends OsmPrimitive> newSelection) {
                 repaint();
Index: trunk/src/org/openstreetmap/josm/gui/dialogs/ChangesetDialog.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/dialogs/ChangesetDialog.java	(revision 3415)
+++ trunk/src/org/openstreetmap/josm/gui/dialogs/ChangesetDialog.java	(revision 3416)
@@ -115,5 +115,5 @@
         ChangesetCache.getInstance().addChangesetCacheListener(inSelectionModel);
         MapView.addEditLayerChangeListener(inSelectionModel);
-        DataSet.selListeners.add(inSelectionModel);
+        DataSet.addSelectionListener(inSelectionModel);
 
         // let the model for changesets in the current layer listen to various
@@ -141,5 +141,5 @@
         //
         MapView.removeEditLayerChangeListener(inSelectionModel);
-        DataSet.selListeners.remove(inSelectionModel);
+        DataSet.removeSelectionListener(inSelectionModel);
     }
 
Index: trunk/src/org/openstreetmap/josm/gui/dialogs/ConflictDialog.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/dialogs/ConflictDialog.java	(revision 3415)
+++ trunk/src/org/openstreetmap/josm/gui/dialogs/ConflictDialog.java	(revision 3416)
@@ -121,5 +121,5 @@
     @Override
     public void showNotify() {
-        DataSet.selListeners.add(this);
+        DataSet.addSelectionListener(this);
         MapView.addEditLayerChangeListener(this, true);
         refreshView();
@@ -129,5 +129,5 @@
     public void hideNotify() {
         MapView.removeEditLayerChangeListener(this);
-        DataSet.selListeners.remove(this);
+        DataSet.removeSelectionListener(this);
     }
 
Index: trunk/src/org/openstreetmap/josm/gui/dialogs/HistoryDialog.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/dialogs/HistoryDialog.java	(revision 3415)
+++ trunk/src/org/openstreetmap/josm/gui/dialogs/HistoryDialog.java	(revision 3416)
@@ -71,5 +71,5 @@
                         Shortcut.GROUP_LAYER, Shortcut.SHIFT_DEFAULT), 150);
         build();
-        DataSet.selListeners.add(model);
+        DataSet.addSelectionListener(model);
 
         HelpUtil.setHelpContext(this, HelpUtil.ht("/Dialog/HistoryDialog"));
Index: trunk/src/org/openstreetmap/josm/gui/dialogs/UserListDialog.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/dialogs/UserListDialog.java	(revision 3415)
+++ trunk/src/org/openstreetmap/josm/gui/dialogs/UserListDialog.java	(revision 3416)
@@ -71,5 +71,5 @@
     @Override
     public void showNotify() {
-        DataSet.selListeners.add(this);
+        DataSet.addSelectionListener(this);
         MapView.addLayerChangeListener(this);
     }
@@ -78,5 +78,5 @@
     public void hideNotify() {
         MapView.removeLayerChangeListener(this);
-        DataSet.selListeners.remove(this);
+        DataSet.removeSelectionListener(this);
     }
 
Index: trunk/src/org/openstreetmap/josm/gui/dialogs/relation/MemberTableModel.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/dialogs/relation/MemberTableModel.java	(revision 3415)
+++ trunk/src/org/openstreetmap/josm/gui/dialogs/relation/MemberTableModel.java	(revision 3416)
@@ -73,10 +73,10 @@
 
     public void register() {
-        DataSet.selListeners.add(this);
+        DataSet.addSelectionListener(this);
         getLayer().data.addDataSetListener(this);
     }
 
     public void unregister() {
-        DataSet.selListeners.remove(this);
+        DataSet.removeSelectionListener(this);
         getLayer().data.removeDataSetListener(this);
     }
Index: trunk/src/org/openstreetmap/josm/gui/dialogs/relation/SelectionTableModel.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/dialogs/relation/SelectionTableModel.java	(revision 3415)
+++ trunk/src/org/openstreetmap/josm/gui/dialogs/relation/SelectionTableModel.java	(revision 3416)
@@ -36,10 +36,10 @@
 
     public void register() {
-        DataSet.selListeners.add(this);
+        DataSet.addSelectionListener(this);
         MapView.addLayerChangeListener(this);
     }
 
     public void unregister() {
-        DataSet.selListeners.remove(this);
+        DataSet.removeSelectionListener(this);
         MapView.removeLayerChangeListener(this);
     }
Index: trunk/src/org/openstreetmap/josm/gui/layer/OsmDataLayer.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/layer/OsmDataLayer.java	(revision 3415)
+++ trunk/src/org/openstreetmap/josm/gui/layer/OsmDataLayer.java	(revision 3416)
@@ -202,5 +202,5 @@
         conflicts = new ConflictCollection();
         data.addDataSetListener(new DataSetListenerAdapter(this));
-        DataSet.selListeners.add(this);
+        DataSet.addSelectionListener(this);
     }
 
@@ -653,5 +653,5 @@
     @Override
     public void destroy() {
-        DataSet.selListeners.remove(this);
+        DataSet.removeSelectionListener(this);
     }
 
