Index: /trunk/src/org/openstreetmap/josm/actions/search/PushbackTokenizer.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/actions/search/PushbackTokenizer.java	(revision 5847)
+++ /trunk/src/org/openstreetmap/josm/actions/search/PushbackTokenizer.java	(revision 5848)
@@ -30,4 +30,12 @@
         public long getEnd() {
             return end;
+        }
+
+        /* (non-Javadoc)
+         * @see java.lang.Object#toString()
+         */
+        @Override
+        public String toString() {
+            return "Range [start=" + start + ", end=" + end + "]";
         }
     }
Index: /trunk/src/org/openstreetmap/josm/actions/search/SearchCompiler.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/actions/search/SearchCompiler.java	(revision 5847)
+++ /trunk/src/org/openstreetmap/josm/actions/search/SearchCompiler.java	(revision 5848)
@@ -374,48 +374,49 @@
 
     /**
-     * Matches objects with the given object ID.
-     */
-    private static class Id extends Match {
-        private long id;
-        public Id(long id) {
-            this.id = id;
-        }
+     * Matches objects with ID in the given range.
+     */
+    private static class Id extends RangeMatch {
+        public Id(Range range) {super(range);}
         public Id(PushbackTokenizer tokenizer) throws ParseError {
-            this(tokenizer.readNumber(tr("Primitive id expected")));
-        }
-        @Override public boolean match(OsmPrimitive osm) {
-            return id == 0?osm.isNew():osm.getUniqueId() == id;
-        }
-        @Override public String toString() {return "id="+id;}
-    }
-
-    /**
-     * Matches objects with the given changeset ID.
-     */
-    private static class ChangesetId extends Match {
-        private long changesetid;
-        public ChangesetId(long changesetid) {this.changesetid = changesetid;}
+            this(tokenizer.readRange(tr("Range of primitive ids expected")));
+        }
+        @Override protected Long getNumber(OsmPrimitive osm) {
+            return osm.isNew() ? 0 : osm.getUniqueId();
+        }
+        @Override protected String getString() {
+            return "id";
+        }
+    }
+
+    /**
+     * Matches objects with a changeset ID in the given range.
+     */
+    private static class ChangesetId extends RangeMatch {
+        public ChangesetId(Range range) {super(range);}
         public ChangesetId(PushbackTokenizer tokenizer) throws ParseError {
-            this(tokenizer.readNumber(tr("Changeset id expected")));
-        }
-        @Override public boolean match(OsmPrimitive osm) {
-            return osm.getChangesetId() == changesetid;
-        }
-        @Override public String toString() {return "changeset="+changesetid;}
-    }
-
-    /**
-     * Matches objects with the given version number.
-     */
-    private static class Version extends Match {
-        private long version;
-        public Version(long version) {this.version = version;}
+            this(tokenizer.readRange(tr("Range of changeset ids expected")));
+        }
+        @Override protected Long getNumber(OsmPrimitive osm) {
+            return (long) osm.getChangesetId();
+        }
+        @Override protected String getString() {
+            return "changeset";
+        }
+    }
+
+    /**
+     * Matches objects with a version number in the given range.
+     */
+    private static class Version extends RangeMatch {
+        public Version(Range range) {super(range);}
         public Version(PushbackTokenizer tokenizer) throws ParseError {
-            this(tokenizer.readNumber(tr("Version expected")));
-        }
-        @Override public boolean match(OsmPrimitive osm) {
-            return osm.getVersion() == version;
-        }
-        @Override public String toString() {return "version="+version;}
+            this(tokenizer.readRange(tr("Range of versions expected")));
+        }
+        @Override protected Long getNumber(OsmPrimitive osm) {
+            return (long) osm.getVersion();
+        }
+        @Override protected String getString() {
+            return "version";
+        }
     }
 
@@ -833,34 +834,34 @@
      * Matches objects with properties in a certain range.
      */
-    private abstract static class CountRange extends Match {
-
-        private long minCount;
-        private long maxCount;
-
-        public CountRange(long minCount, long maxCount) {
-            this.minCount = Math.min(minCount, maxCount);
-            this.maxCount = Math.max(minCount, maxCount);
-        }
-
-        public CountRange(Range range) {
+    private abstract static class RangeMatch extends Match {
+
+        private final long min;
+        private final long max;
+
+        public RangeMatch(long min, long max) {
+            this.min = Math.min(min, max);
+            this.max = Math.max(min, max);
+        }
+
+        public RangeMatch(Range range) {
             this(range.getStart(), range.getEnd());
         }
 
-        protected abstract Long getCount(OsmPrimitive osm);
-
-        protected abstract String getCountString();
+        protected abstract Long getNumber(OsmPrimitive osm);
+
+        protected abstract String getString();
 
         @Override
         public boolean match(OsmPrimitive osm) {
-            Long count = getCount(osm);
-            if (count == null)
+            Long num = getNumber(osm);
+            if (num == null)
                 return false;
             else
-                return (count >= minCount) && (count <= maxCount);
+                return (num >= min) && (num <= max);
         }
 
         @Override
         public String toString() {
-            return getCountString() + "=" + minCount + "-" + maxCount;
+            return getString() + "=" + min + "-" + max;
         }
     }
@@ -870,5 +871,5 @@
      * Matches ways with a number of nodes in given range
      */
-    private static class NodeCountRange extends CountRange {
+    private static class NodeCountRange extends RangeMatch {
         public NodeCountRange(Range range) {
             super(range);
@@ -880,5 +881,5 @@
 
         @Override
-        protected Long getCount(OsmPrimitive osm) {
+        protected Long getNumber(OsmPrimitive osm) {
             if (!(osm instanceof Way))
                 return null;
@@ -888,5 +889,5 @@
 
         @Override
-        protected String getCountString() {
+        protected String getString() {
             return "nodes";
         }
@@ -896,5 +897,5 @@
      * Matches objects with a number of tags in given range
      */
-    private static class TagCountRange extends CountRange {
+    private static class TagCountRange extends RangeMatch {
         public TagCountRange(Range range) {
             super(range);
@@ -906,10 +907,10 @@
 
         @Override
-        protected Long getCount(OsmPrimitive osm) {
+        protected Long getNumber(OsmPrimitive osm) {
             return (long) osm.getKeys().size();
         }
 
         @Override
-        protected String getCountString() {
+        protected String getString() {
             return "tags";
         }
@@ -919,5 +920,5 @@
      * Matches objects with a timestamp in given range
      */
-    private static class TimestampRange extends CountRange {
+    private static class TimestampRange extends RangeMatch {
 
         public TimestampRange(long minCount, long maxCount) {
@@ -926,10 +927,10 @@
 
         @Override
-        protected Long getCount(OsmPrimitive osm) {
+        protected Long getNumber(OsmPrimitive osm) {
             return osm.getTimestamp().getTime();
         }
 
         @Override
-        protected String getCountString() {
+        protected String getString() {
             return "timestamp";
         }
@@ -1051,5 +1052,5 @@
      * @author Ole Jørgen Brønner
      */
-    private static class AreaSize extends CountRange {
+    private static class AreaSize extends RangeMatch {
 
         public AreaSize(Range range) {
@@ -1062,5 +1063,5 @@
 
         @Override
-        protected Long getCount(OsmPrimitive osm) {
+        protected Long getNumber(OsmPrimitive osm) {
             if (!(osm instanceof Way && ((Way) osm).isClosed()))
                 return null;
@@ -1070,5 +1071,5 @@
 
         @Override
-        protected String getCountString() {
+        protected String getString() {
             return "areasize";
         }
