Index: trunk/src/org/openstreetmap/josm/gui/autofilter/AutoFilterManager.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/autofilter/AutoFilterManager.java	(revision 15838)
+++ trunk/src/org/openstreetmap/josm/gui/autofilter/AutoFilterManager.java	(revision 15839)
@@ -16,7 +16,4 @@
 import java.util.TreeSet;
 import java.util.function.Consumer;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-import java.util.stream.IntStream;
 
 import org.openstreetmap.josm.actions.mapmode.MapMode;
@@ -26,5 +23,4 @@
 import org.openstreetmap.josm.data.osm.FilterModel;
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
-import org.openstreetmap.josm.data.osm.OsmUtils;
 import org.openstreetmap.josm.data.osm.event.AbstractDatasetChangedEvent;
 import org.openstreetmap.josm.data.osm.event.DataChangedEvent;
@@ -58,5 +54,4 @@
 import org.openstreetmap.josm.spi.preferences.PreferenceChangeEvent;
 import org.openstreetmap.josm.spi.preferences.PreferenceChangedListener;
-import org.openstreetmap.josm.tools.Logging;
 
 /**
@@ -79,9 +74,4 @@
 
     /**
-     * Property to determine if the auto filter should assume sensible defaults for values (such as layer=1 for bridge=yes).
-     */
-    private static final BooleanProperty PROP_AUTO_FILTER_DEFAULTS = new BooleanProperty("auto.filter.defaults", true);
-
-    /**
      * The unique instance.
      */
@@ -111,5 +101,5 @@
      * The currently enabled rule, if any.
      */
-    private AutoFilterRule enabledRule;
+    AutoFilterRule enabledRule;
 
     /**
@@ -143,5 +133,5 @@
                 && enabledRule.getMinZoomLevel() <= Selector.GeneralSelector.scale2level(map.mapView.getDist100Pixel())) {
             // Retrieve the values from current rule visible on screen
-            NavigableSet<Integer> values = getNumericValues(enabledRule.getKey());
+            NavigableSet<Integer> values = getNumericValues();
             // Make sure current auto filter button remains visible even if no data is found, to allow user to disable it
             if (currentAutoFilter != null) {
@@ -155,14 +145,14 @@
     }
 
-    class CompiledFilter extends Filter implements MatchSupplier {
-        final String key;
+    static class CompiledFilter extends Filter implements MatchSupplier {
+        final AutoFilterRule rule;
         final int value;
 
-        CompiledFilter(String key, int value) {
-            this.key = key;
+        CompiledFilter(AutoFilterRule rule, int value) {
+            this.rule = rule;
             this.value = value;
             this.enable = true;
             this.inverted = true;
-            this.text = key + "=" + value;
+            this.text = rule.getKey() + "=" + value;
         }
 
@@ -172,5 +162,5 @@
                 @Override
                 public boolean match(OsmPrimitive osm) {
-                    return getTagValuesForPrimitive(key, osm).anyMatch(v -> v == value);
+                    return rule.getTagValuesForPrimitive(osm).anyMatch(v -> v == value);
                 }
             };
@@ -187,6 +177,6 @@
         addButton(keyButton, Integer.MIN_VALUE, i++);
         for (final Integer value : values.descendingSet()) {
-            CompiledFilter filter = new CompiledFilter(enabledRule.getKey(), value);
-            String label = enabledRule.getValueFormatter().apply(value);
+            CompiledFilter filter = new CompiledFilter(enabledRule, value);
+            String label = enabledRule.formatValue(value);
             AutoFilter autoFilter = new AutoFilter(label, filter.text, filter);
             AutoFilterButton button = new AutoFilterButton(autoFilter);
@@ -214,5 +204,5 @@
     }
 
-    private NavigableSet<Integer> getNumericValues(String key) {
+    private NavigableSet<Integer> getNumericValues() {
         DataSet ds = MainApplication.getLayerManager().getActiveDataSet();
         if (ds == null) {
@@ -221,35 +211,9 @@
         BBox bbox = MainApplication.getMap().mapView.getState().getViewArea().getLatLonBoundsBox().toBBox();
         NavigableSet<Integer> values = new TreeSet<>();
-        Consumer<OsmPrimitive> consumer = o -> getTagValuesForPrimitive(key, o).forEach(values::add);
+        Consumer<OsmPrimitive> consumer = o -> enabledRule.getTagValuesForPrimitive(o).forEach(values::add);
         ds.searchNodes(bbox).forEach(consumer);
         ds.searchWays(bbox).forEach(consumer);
         ds.searchRelations(bbox).forEach(consumer);
         return values;
-    }
-
-    protected IntStream getTagValuesForPrimitive(String key, OsmPrimitive osm) {
-        if (enabledRule == null) {
-            return IntStream.empty();
-        }
-        String value = osm.get(key);
-        if (value != null) {
-            Pattern p = Pattern.compile("(-?[0-9]+)-(-?[0-9]+)");
-            return OsmUtils.splitMultipleValues(value).flatMapToInt(v -> {
-                Matcher m = p.matcher(v);
-                if (m.matches()) {
-                    int a = Integer.parseInt(m.group(1));
-                    int b = Integer.parseInt(m.group(2));
-                    return IntStream.rangeClosed(Math.min(a, b), Math.max(a, b));
-                } else {
-                    try {
-                        return IntStream.of(enabledRule.getValueExtractor().applyAsInt(v));
-                    } catch (NumberFormatException e) {
-                        Logging.trace(e);
-                        return IntStream.empty();
-                    }
-                }
-            });
-        }
-        return enabledRule.getDefaultValueSupplier().apply(osm);
     }
 
Index: trunk/src/org/openstreetmap/josm/gui/autofilter/AutoFilterRule.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/autofilter/AutoFilterRule.java	(revision 15838)
+++ trunk/src/org/openstreetmap/josm/gui/autofilter/AutoFilterRule.java	(revision 15839)
@@ -8,7 +8,12 @@
 import java.util.function.IntFunction;
 import java.util.function.ToIntFunction;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 import java.util.stream.IntStream;
 
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
+import org.openstreetmap.josm.data.osm.OsmUtils;
+import org.openstreetmap.josm.data.preferences.BooleanProperty;
+import org.openstreetmap.josm.tools.Logging;
 
 /**
@@ -20,4 +25,9 @@
  */
 public class AutoFilterRule {
+
+    /**
+     * Property to determine if the auto filter should assume sensible defaults for values (such as layer=1 for bridge=yes).
+     */
+    private static final BooleanProperty PROP_AUTO_FILTER_DEFAULTS = new BooleanProperty("auto.filter.defaults", true);
 
     private final String key;
@@ -58,9 +68,10 @@
 
     /**
-     * Returns the OSM value formatter that defines the associated button label.
-     * @return the OSM value formatter that defines the associated button label (identity by default)
+     * Formats the numeric value
+     * @param value the numeric value to format
+     * @return the formatted value
      */
-    public IntFunction<String> getValueFormatter() {
-        return valueFormatter;
+    public String formatValue(int value) {
+        return valueFormatter.apply(value);
     }
 
@@ -74,12 +85,4 @@
         this.valueFormatter = Objects.requireNonNull(valueFormatter);
         return this;
-    }
-
-    /**
-     * Returns a function which yields default values for the given OSM primitive
-     * @return a function which yields default values for the given OSM primitive
-     */
-    public Function<OsmPrimitive, IntStream> getDefaultValueSupplier() {
-        return defaultValueSupplier;
     }
 
@@ -97,12 +100,4 @@
 
     /**
-     * Returns a function which extracts a numeric value from an OSM value
-     * @return a function which extracts a numeric value from an OSM value
-     */
-    public ToIntFunction<String> getValueExtractor() {
-        return valueExtractor;
-    }
-
-    /**
      * Sets the function which extracts a numeric value from an OSM value
      * @param valueExtractor the function which extracts a numeric value from an OSM value
@@ -113,4 +108,32 @@
         this.valueExtractor = Objects.requireNonNull(valueExtractor);
         return this;
+    }
+
+    /**
+     * Returns the numeric values for the given OSM primitive
+     * @param osm the primitive
+     * @return a stream of numeric values
+     */
+    public IntStream getTagValuesForPrimitive(OsmPrimitive osm) {
+        String value = osm.get(key);
+        if (value != null) {
+            Pattern p = Pattern.compile("(-?[0-9]+)-(-?[0-9]+)");
+            return OsmUtils.splitMultipleValues(value).flatMapToInt(v -> {
+                Matcher m = p.matcher(v);
+                if (m.matches()) {
+                    int a = Integer.parseInt(m.group(1));
+                    int b = Integer.parseInt(m.group(2));
+                    return IntStream.rangeClosed(Math.min(a, b), Math.max(a, b));
+                } else {
+                    try {
+                        return IntStream.of(valueExtractor.applyAsInt(v));
+                    } catch (NumberFormatException e) {
+                        Logging.trace(e);
+                        return IntStream.empty();
+                    }
+                }
+            });
+        }
+        return PROP_AUTO_FILTER_DEFAULTS.get() ? defaultValueSupplier.apply(osm) : IntStream.empty();
     }
 
