Index: /trunk/src/org/openstreetmap/josm/data/osm/DataSet.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/data/osm/DataSet.java	(revision 3146)
+++ /trunk/src/org/openstreetmap/josm/data/osm/DataSet.java	(revision 3147)
@@ -163,14 +163,8 @@
 
     /**
-     * @return A collection containing all primitives of the dataset. The data is ordered after:
-     * first come nodes, then ways, then relations. Ordering in between the categories is not
-     * guaranteed.
-     */
-    public List<OsmPrimitive> allPrimitives() {
-        List<OsmPrimitive> o = new LinkedList<OsmPrimitive>();
-        o.addAll(nodes);
-        o.addAll(ways);
-        o.addAll(relations);
-        return o;
+     * @return A collection containing all primitives of the dataset. Data are not ordered
+     */
+    public Collection<OsmPrimitive> allPrimitives() {
+        return Collections.unmodifiableCollection(allPrimitives);
     }
 
@@ -179,28 +173,13 @@
      */
     public Collection<OsmPrimitive> allNonDeletedPrimitives() {
-        Collection<OsmPrimitive> o = new LinkedList<OsmPrimitive>();
-        for (OsmPrimitive osm : allPrimitives())
-            if (osm.isVisible() && !osm.isDeleted()) {
-                o.add(osm);
-            }
-        return o;
+        return new DatasetCollection.AllNonDeleted(allPrimitives);
     }
 
     public Collection<OsmPrimitive> allNonDeletedCompletePrimitives() {
-        Collection<OsmPrimitive> o = new LinkedList<OsmPrimitive>();
-        for (OsmPrimitive osm : allPrimitives())
-            if (osm.isVisible() && !osm.isDeleted() && !osm.isIncomplete()) {
-                o.add(osm);
-            }
-        return o;
+        return new DatasetCollection.AllNonDeletedComplete(allPrimitives);
     }
 
     public Collection<OsmPrimitive> allNonDeletedPhysicalPrimitives() {
-        Collection<OsmPrimitive> o = new LinkedList<OsmPrimitive>();
-        for (OsmPrimitive osm : allPrimitives())
-            if (osm.isVisible() && !osm.isDeleted() && !osm.isIncomplete() && !(osm instanceof Relation)) {
-                o.add(osm);
-            }
-        return o;
+        return new DatasetCollection.AllNonDeletedPhysical(allPrimitives);
     }
 
@@ -209,11 +188,5 @@
      */
     public Collection<OsmPrimitive> allModifiedPrimitives() {
-        Collection<OsmPrimitive> o = new LinkedList<OsmPrimitive>();
-        for (OsmPrimitive osm : allPrimitives()) {
-            if (osm.isVisible() && osm.isModified()) {
-                o.add(osm);
-            }
-        }
-        return o;
+        return new DatasetCollection.AllModified(allPrimitives);
     }
 
Index: /trunk/src/org/openstreetmap/josm/data/osm/DatasetCollection.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/data/osm/DatasetCollection.java	(revision 3147)
+++ /trunk/src/org/openstreetmap/josm/data/osm/DatasetCollection.java	(revision 3147)
@@ -0,0 +1,128 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.data.osm;
+
+import java.util.AbstractCollection;
+import java.util.Collection;
+import java.util.Iterator;
+
+abstract class DatasetCollection extends AbstractCollection<OsmPrimitive> {
+
+    private class FilterIterator implements Iterator<OsmPrimitive> {
+
+        private final Iterator<OsmPrimitive> iterator;
+        private OsmPrimitive current;
+
+        public FilterIterator(Iterator<OsmPrimitive> iterator) {
+            this.iterator = iterator;
+        }
+
+        private void findNext() {
+            if (current == null) {
+                while (iterator.hasNext()) {
+                    current = iterator.next();
+                    if (filter(current))
+                        return;
+                }
+                current = null;
+            }
+        }
+
+        public boolean hasNext() {
+            findNext();
+            return current != null;
+        }
+
+        public OsmPrimitive next() {
+            findNext();
+            OsmPrimitive old = current;
+            current = null;
+            return old;
+        }
+
+        public void remove() {
+            throw new UnsupportedOperationException();
+        }
+    }
+
+    private final Collection<OsmPrimitive> primitives;
+
+    public DatasetCollection(Collection<OsmPrimitive> primitives) {
+        this.primitives = primitives;
+    }
+
+    protected abstract boolean filter(OsmPrimitive primitive);
+
+    @Override
+    public Iterator<OsmPrimitive> iterator() {
+        return new FilterIterator(primitives.iterator());
+    }
+
+    @Override
+    public int size() {
+        int size = 0;
+        Iterator<OsmPrimitive> it = iterator();
+        while (it.hasNext()) {
+            size++;
+            it.next();
+        }
+        return size;
+    }
+
+    @Override
+    public boolean isEmpty() {
+        return !iterator().hasNext();
+    }
+
+    public static class AllNonDeleted extends DatasetCollection {
+
+        public AllNonDeleted(Collection<OsmPrimitive> primitives) {
+            super(primitives);
+        }
+
+        @Override
+        protected boolean filter(OsmPrimitive primitive) {
+            return primitive.isVisible() && !primitive.isDeleted();
+        }
+
+    }
+
+    public static class AllNonDeletedComplete extends DatasetCollection {
+
+        public AllNonDeletedComplete(Collection<OsmPrimitive> primitives) {
+            super(primitives);
+        }
+
+        @Override
+        protected boolean filter(OsmPrimitive primitive) {
+            return primitive.isVisible() && !primitive.isDeleted() && !primitive.isIncomplete();
+        }
+
+    }
+
+    public static class AllNonDeletedPhysical extends DatasetCollection {
+
+        public AllNonDeletedPhysical(Collection<OsmPrimitive> primitives) {
+            super(primitives);
+        }
+
+        @Override
+        protected boolean filter(OsmPrimitive primitive) {
+            return primitive.isVisible() && !primitive.isDeleted() && !primitive.isIncomplete() && !(primitive instanceof Relation);
+        }
+
+    }
+
+    public static class AllModified extends DatasetCollection {
+
+        public AllModified(Collection<OsmPrimitive> primitives) {
+            super(primitives);
+        }
+
+        @Override
+        protected boolean filter(OsmPrimitive primitive) {
+            return primitive.isVisible() && primitive.isModified();
+        }
+
+    }
+
+}
