Index: trunk/data/defaultpresets.xml
===================================================================
--- trunk/data/defaultpresets.xml	(revision 5638)
+++ trunk/data/defaultpresets.xml	(revision 5639)
@@ -35,4 +35,10 @@
   default: default string to display (defaults to "")
   use_last_as_default: true/false/force (default is "false")
+  auto_increment: may contain a comma separated list of integer increments or 
+                  decrements, e.g. "-2,-1,+1,+2"; a button will be shown next
+                  to the text field for each value, allowing the user to select
+                  auto-increment with the given stepping. auto-increment only
+                  happens if the user selects it. default is no auto-increment;
+                  mutually exclusive with use_last_as_default.
   match: none/key/key!/keyvalue (default is "none", see below for more information)
   length: length of input box (number of characters allowed)
@@ -5727,5 +5733,5 @@
             <label text="Edit Address Information" />
             <space />
-            <text key="addr:housenumber" text="House number" match="key" />
+            <text key="addr:housenumber" text="House number" match="key" auto_increment="-2,-1,+1,+2" />
             <optional>
                 <text key="addr:housename" text="House name" match="key" />
Index: trunk/data/tagging-preset.xsd
===================================================================
--- trunk/data/tagging-preset.xsd	(revision 5638)
+++ trunk/data/tagging-preset.xsd	(revision 5639)
@@ -117,4 +117,5 @@
 		<attribute name="default" type="string" />
 		<attribute name="use_last_as_default" type="tns:last_default" />
+		<attribute name="auto_increment" type="string" />
 		<attribute name="match" type="tns:match" />
         <attribute name="length" type="positiveInteger" />
Index: trunk/src/org/openstreetmap/josm/gui/tagging/TaggingPreset.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/tagging/TaggingPreset.java	(revision 5638)
+++ trunk/src/org/openstreetmap/josm/gui/tagging/TaggingPreset.java	(revision 5639)
@@ -12,4 +12,5 @@
 import java.awt.Insets;
 import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
 import java.io.BufferedReader;
 import java.io.File;
@@ -19,4 +20,6 @@
 import java.io.Reader;
 import java.io.UnsupportedEncodingException;
+import java.text.NumberFormat;
+import java.text.ParseException;
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -34,5 +37,7 @@
 import javax.swing.AbstractAction;
 import javax.swing.Action;
+import javax.swing.ButtonGroup;
 import javax.swing.ImageIcon;
+import javax.swing.JButton;
 import javax.swing.JComponent;
 import javax.swing.JLabel;
@@ -42,4 +47,5 @@
 import javax.swing.JScrollPane;
 import javax.swing.JTextField;
+import javax.swing.JToggleButton;
 import javax.swing.ListCellRenderer;
 import javax.swing.ListModel;
@@ -393,4 +399,5 @@
         public String originalValue;
         public String use_last_as_default = "false";
+        public String auto_increment;
         public String length;
 
@@ -411,4 +418,10 @@
                     if (!"false".equals(use_last_as_default) && lastValue.containsKey(key)) {
                         textField.setText(lastValue.get(key));
+                    } else if (auto_increment_selected != 0  && auto_increment != null) {
+                        try {
+                            textField.setText(Integer.toString(Integer.parseInt(lastValue.get(key)) + auto_increment_selected));
+                        } catch (NumberFormatException ex) {
+                            // Ignore - cannot auto-increment if last was non-numeric
+                        }
                     } else {
                         textField.setText(default_);
@@ -443,4 +456,55 @@
                 }
             }
+
+            // if there's an auto_increment setting, then wrap the text field
+            // into a panel, appending a number of buttons.
+            // auto_increment has a format like -2,-1,1,2
+            // the text box being the first component in the panel is relied
+            // on in a rather ugly fashion further down.
+            if (auto_increment != null) {
+                ButtonGroup bg = new ButtonGroup();
+                JPanel pnl = new JPanel(new GridBagLayout());
+                pnl.add(value, GBC.std().fill(GBC.HORIZONTAL));
+
+                // first, one button for each auto_increment value
+                for (final String ai : auto_increment.split(",")) {
+                    JToggleButton aibutton = new JToggleButton(ai);
+                    aibutton.setToolTipText(tr("Select auto-increment of {0} for this field", ai));
+                    aibutton.setMargin(new java.awt.Insets(0,0,0,0));
+                    bg.add(aibutton);
+                    try {
+                        // TODO there must be a better way to parse a number like "+3" than this.
+                        final int buttonvalue = ((Number)NumberFormat.getIntegerInstance().parse(ai.replace("+", ""))).intValue();
+                        if (auto_increment_selected == buttonvalue) aibutton.setSelected(true);
+                        aibutton.addActionListener(new ActionListener() {
+                            public void actionPerformed(ActionEvent e) {
+                                auto_increment_selected = buttonvalue;
+                            }
+                        });
+                        pnl.add(aibutton, GBC.std());
+                    } catch (ParseException x) {
+                        System.err.println("Cannot parse auto-increment value of '" + ai + "' into an integer");
+                    }
+                }
+
+                // an invisible toggle button for "release" of the button group
+                final JToggleButton clearbutton = new JToggleButton("X");
+                clearbutton.setVisible(false);
+                bg.add(clearbutton);
+                // and its visible counterpart. - this mechanism allows us to 
+                // have *no* button selected after the X is clicked, instead 
+                // of the X remaining selected
+                JButton releasebutton = new JButton("X");
+                releasebutton.setToolTipText(tr("Cancel auto-increment for this field"));
+                releasebutton.setMargin(new java.awt.Insets(0,0,0,0));
+                releasebutton.addActionListener(new ActionListener() {
+                    public void actionPerformed(ActionEvent e) {
+                        auto_increment_selected = 0;
+                        clearbutton.setSelected(true);
+                    }
+                });
+                pnl.add(releasebutton, GBC.std().eol());
+                value = pnl;
+            }
             p.add(new JLabel(locale_text+":"), GBC.std().insets(0,0,10,0));
             p.add(value, GBC.eol().fill(GBC.HORIZONTAL));
@@ -452,16 +516,26 @@
 
             // return if unchanged
-            String v = (value instanceof JosmComboBox)
-                    ? ((JosmComboBox) value).getEditor().getItem().toString()
-                            : ((JTextField) value).getText();
-                    v = v.trim();
-
-                    if (!"false".equals(use_last_as_default)) {
-                        lastValue.put(key, v);
-                    }
-                    if (v.equals(originalValue) || (originalValue == null && v.length() == 0))
-                        return;
-
-                    changedTags.add(new Tag(key, v));
+            String v = null;
+            if (value instanceof JosmComboBox) {
+                v = ((JosmComboBox) value).getEditor().getItem().toString();
+            } else if (value instanceof JTextField) {
+                v = ((JTextField) value).getText();
+            } else if (value instanceof JPanel) {
+                // this is what was alluded to with "ugly fashion" above.
+                v = ((JTextField) (((JPanel)value).getComponent(0))).getText();
+            } else {
+                System.err.println("No 'last value' support for component " + value);
+                return;
+            }
+               
+            v = v.trim();
+
+            if (!"false".equals(use_last_as_default) || auto_increment != null) {
+                lastValue.put(key, v);
+            }
+            if (v.equals(originalValue) || (originalValue == null && v.length() == 0))
+                return;
+
+            changedTags.add(new Tag(key, v));
         }
 
@@ -1257,4 +1331,5 @@
     public Match nameTemplateFilter;
     private static final HashMap<String,String> lastValue = new HashMap<String,String>();
+    private static int auto_increment_selected = 0;
 
     /**
