Index: /applications/editors/josm/plugins/terracer/src/terracer/HouseNumberInputDialog.java
===================================================================
--- /applications/editors/josm/plugins/terracer/src/terracer/HouseNumberInputDialog.java	(revision 21093)
+++ /applications/editors/josm/plugins/terracer/src/terracer/HouseNumberInputDialog.java	(revision 21094)
@@ -18,4 +18,6 @@
 import java.awt.GridBagLayout;
 import java.awt.GridLayout;
+import java.awt.event.ActionEvent;
+
 import java.util.TreeSet;
 
@@ -23,5 +25,4 @@
 import javax.swing.JButton;
 import javax.swing.JCheckBox;
-import javax.swing.JDialog;
 import javax.swing.JLabel;
 import javax.swing.JOptionPane;
@@ -34,5 +35,6 @@
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
 import org.openstreetmap.josm.data.osm.Way;
-import org.openstreetmap.josm.gui.tagging.ac.AutoCompletingComboBox;
+import org.openstreetmap.josm.gui.ExtendedDialog;
+import org.openstreetmap.josm.gui.tagging.ac.AutoCompletingComboBox; 
 import org.openstreetmap.josm.tools.GBC;
 
@@ -48,5 +50,5 @@
  *
  */
-public class HouseNumberInputDialog extends JDialog {
+public class HouseNumberInputDialog extends ExtendedDialog {
     /*
     final static String MIN_NUMBER = "plugin.terracer.lowest_number";
@@ -64,5 +66,4 @@
     private Container jContentPane;
     private JPanel inputPanel;
-    private JPanel buttonPanel;
     private JLabel loLabel;
     JTextField lo;
@@ -74,6 +75,4 @@
     JTextField segments;
     JTextArea messageLabel;
-    JButton okButton;
-    JButton cancelButton;
     private JLabel interpolationLabel;
     Choice interpolation;
@@ -81,4 +80,6 @@
     JCheckBox deleteOutlineCheckBox;
 
+	HouseNumberInputHandler inputHandler;
+	
     /**
      * @param street If street is not null, we assume, the name of the street to be fixed
@@ -86,12 +87,24 @@
      * @param relationExists If the buildings can be added to an existing relation or not.
      */
-    public HouseNumberInputDialog(Way street, boolean relationExists) {
-        super(JOptionPane.getFrameForComponent(Main.parent));
+    public HouseNumberInputDialog(HouseNumberInputHandler handler, Way street, boolean relationExists) {
+        super(Main.parent,
+                tr("Terrace a house"),
+                new String[] { tr("OK"), tr("Cancel")},
+                true
+        );
+        this.inputHandler = handler;
         this.street = street;
         this.relationExists = relationExists;
+        handler.dialog = this;
+        JPanel content = getInputPanel();
+        setContent(content);
+        setButtonIcons(new String[] {"ok.png", "cancel.png" });
+        getJContentPane();
         initialize();
-    }
-
-    /**
+        setupDialog();
+        setVisible(true);
+    }
+
+	/**
      * This method initializes this
      *
@@ -99,11 +112,10 @@
      */
     private void initialize() {
-        this.setTitle(tr("Terrace a house"));
-        getJContentPane();
-        SwingUtilities.invokeLater(new Runnable() { public void run() { lo.requestFocus(); } } );
-        this.pack();
-        this.setLocationRelativeTo(Main.parent);
-    }
-
+        this.lo.addFocusListener(this.inputHandler);
+        this.hi.addFocusListener(this.inputHandler);
+        this.segments.addFocusListener(this.inputHandler);
+		this.interpolation.addItemListener(this.inputHandler);
+    }
+	
     /**
      * This method initializes jContentPane
@@ -113,4 +125,5 @@
     private Container getJContentPane() {
         if (jContentPane == null) {
+        
             messageLabel = new JTextArea();
             messageLabel.setText(DEFAULT_MESSAGE);
@@ -121,10 +134,9 @@
             messageLabel.setBackground(new Color(238, 238, 238));
             messageLabel.setEditable(false);
+            
             jContentPane = this.getContentPane();
-            jContentPane.setLayout(new BoxLayout(jContentPane,
-                    BoxLayout.Y_AXIS));
+            jContentPane.setLayout(new BoxLayout(jContentPane, BoxLayout.Y_AXIS));
             jContentPane.add(messageLabel, jContentPane);
             jContentPane.add(getInputPanel(), jContentPane);
-            jContentPane.add(getButtonPanel(), jContentPane);
         }
         return jContentPane;
@@ -176,17 +188,10 @@
     }
 
-    /**
-     * This method initializes buttonPanel
-     *
-     * @return javax.swing.JPanel
-     */
-    private JPanel getButtonPanel() {
-        if (buttonPanel == null) {
-            buttonPanel = new JPanel();
-            buttonPanel.setLayout(new FlowLayout());
-            buttonPanel.add(getOkButton(), null);
-            buttonPanel.add(getCancelButton(), null);
-        }
-        return buttonPanel;
+	/**
+     * Overrides the default actions. Will not close the window when upload trace is clicked
+     */
+    @Override protected void buttonAction(final ActionEvent evt) {
+        String a = evt.getActionCommand();
+        this.inputHandler.actionPerformed(evt);
     }
 
@@ -251,32 +256,4 @@
 
     /**
-     * This method initializes okButton
-     *
-     * @return javax.swing.JButton
-     */
-    private JButton getOkButton() {
-        if (okButton == null) {
-            okButton = new JButton();
-            okButton.setText(tr("OK"));
-            okButton.setName("OK");
-        }
-        return okButton;
-    }
-
-    /**
-     * This method initializes cancelButton
-     *
-     * @return javax.swing.JButton
-     */
-    private JButton getCancelButton() {
-        if (cancelButton == null) {
-            cancelButton = new JButton();
-            cancelButton.setText(tr("Cancel"));
-            cancelButton.setName("CANCEL");
-        }
-        return cancelButton;
-    }
-
-    /**
      * This method initializes interpolation
      *
@@ -290,26 +267,4 @@
         }
         return interpolation;
-    }
-
-    /**
-     * Registers the handler as a listener to all relevant events.
-     *
-     * @param handler the handler
-     */
-    public void addHandler(HouseNumberInputHandler handler) {
-        this.hi.addActionListener(handler);
-        this.hi.addFocusListener(handler);
-
-        this.lo.addActionListener(handler);
-        this.lo.addFocusListener(handler);
-
-        this.segments.addActionListener(handler);
-        this.segments.addFocusListener(handler);
-
-        this.okButton.addActionListener(handler);
-        this.cancelButton.addActionListener(handler);
-
-        this.interpolation.addItemListener(handler);
-
     }
 
Index: /applications/editors/josm/plugins/terracer/src/terracer/HouseNumberInputHandler.java
===================================================================
--- /applications/editors/josm/plugins/terracer/src/terracer/HouseNumberInputHandler.java	(revision 21093)
+++ /applications/editors/josm/plugins/terracer/src/terracer/HouseNumberInputHandler.java	(revision 21094)
@@ -11,4 +11,6 @@
 
 import java.awt.Color;
+import java.awt.Component;
+import java.awt.Container;
 import java.awt.event.ActionEvent;
 import java.awt.event.ActionListener;
@@ -20,10 +22,10 @@
 import javax.swing.JButton;
 import javax.swing.JTextField;
-import javax.swing.event.ChangeEvent;
-import javax.swing.event.ChangeListener;
+import javax.swing.JOptionPane;
 
 import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.data.osm.Way;
 import org.openstreetmap.josm.data.osm.Relation;
+import org.openstreetmap.josm.actions.JosmAction;
 
 /**
@@ -37,11 +39,9 @@
  * @author casualwalker
  */
-public class HouseNumberInputHandler implements ChangeListener, ItemListener,
-        ActionListener, FocusListener {
-
+ public class HouseNumberInputHandler extends JosmAction implements ActionListener, FocusListener, ItemListener {
     private TerracerAction terracerAction;
     private Way outline, street;
     private Relation associatedStreet;
-    private HouseNumberInputDialog dialog;
+    public HouseNumberInputDialog dialog;
 
     /**
@@ -61,12 +61,36 @@
         this.street = street;
         this.associatedStreet = associatedStreet;
-        dialog = new HouseNumberInputDialog(street, associatedStreet != null);
-        dialog.addHandler(this);
-
-        dialog.setVisible(true);
-        dialog.setTitle(title);
-
-    }
-
+        
+        // This dialog is started modal
+        this.dialog = new HouseNumberInputDialog(this, street, associatedStreet != null);
+        
+        // We're done
+    }
+
+	/**
+	 * Find a button with a certain caption.
+	 * Loops recursively through all objects to find all buttons.
+	 * Function returns on the first match.
+	 *
+	 * @param root A container object that is recursively searched for other containers or buttons
+	 * @param caption The caption of the button that is being searched
+	 *
+	 * @return The first button that matches the caption or null if not found
+	 */
+	private static JButton getButton(Container root, String caption) {
+		Component children[] = root.getComponents();
+         for (Component child : children) {
+         	JButton b;
+         	if (child instanceof JButton) {
+				b = (JButton) child;
+				if (caption.equals(b.getText())) return b;
+			} else if (child instanceof Container) {
+                  b = getButton((Container)child, caption);
+                  if (b != null) return b;
+             }
+         }
+		return null;
+	}
+	
     /**
      * Validate the current input fields.
@@ -76,5 +100,5 @@
      * Should be triggered each time the input changes.
      */
-    private void validateInput() {
+    private boolean validateInput() {
         boolean isOk = true;
         StringBuffer message = new StringBuffer();
@@ -83,7 +107,11 @@
         isOk = isOk && checkSegmentsFromHousenumber(message);
         isOk = isOk && checkSegments(message);
-        isOk = isOk
-                && checkNumberStringField(dialog.lo, tr("Lowest number"),
-                        message);
+
+        // Allow non numeric characters for the low number as long as there is no high number of the segmentcount is 1
+        if (dialog.hi.getText().length() > 0 | segments() > 1) {
+		    isOk = isOk
+		            && checkNumberStringField(dialog.lo, tr("Lowest number"),
+		                    message);
+		}
         isOk = isOk
                 && checkNumberStringField(dialog.hi, tr("Highest number"),
@@ -94,13 +122,23 @@
 
         if (isOk) {
-            dialog.okButton.setEnabled(true);
+            JButton okButton = getButton(dialog, "OK");
+            if (okButton != null)
+            	okButton.setEnabled(true);
+            
+            // For some reason the messageLabel doesn't want to show up
             dialog.messageLabel.setForeground(Color.black);
-            dialog.messageLabel
-                    .setText(tr(HouseNumberInputDialog.DEFAULT_MESSAGE));
-
+            dialog.messageLabel.setText(tr(HouseNumberInputDialog.DEFAULT_MESSAGE));
+            return true;
         } else {
-            dialog.okButton.setEnabled(false);
-            dialog.messageLabel.setForeground(Color.red);
-            dialog.messageLabel.setText(message.toString());
+            JButton okButton = getButton(dialog, "OK");
+            if (okButton != null)
+		       	okButton.setEnabled(false);
+		        	
+	        // For some reason the messageLabel doesn't want to show up, so a MessageDialog is shown instead. Someone more knowledgeable might fix this.
+	        dialog.messageLabel.setForeground(Color.red);
+	        dialog.messageLabel.setText(message.toString());
+	        JOptionPane.showMessageDialog(null, message.toString(), tr("Error"), JOptionPane.ERROR_MESSAGE);
+
+            return false;
         }
     }
@@ -119,6 +157,5 @@
             if (numberFrom().intValue() > numberTo().intValue()) {
                 appendMessageNewLine(message);
-                message
-                        .append(tr("Lowest housenumber cannot be higher than highest housenumber"));
+                message.append(tr("Lowest housenumber cannot be higher than highest housenumber"));
                 return false;
             }
@@ -147,6 +184,5 @@
             if (segments % stepSize() != 0) {
                 appendMessageNewLine(message);
-                message
-                        .append(tr("Housenumbers do not match odd/even setting"));
+                message.append(tr("Housenumbers do not match odd/even setting"));
                 return false;
             }
@@ -222,13 +258,6 @@
 
     /* (non-Javadoc)
-     * @see javax.swing.event.ChangeListener#stateChanged(javax.swing.event.ChangeEvent)
-     */
-    public void stateChanged(ChangeEvent e) {
-        validateInput();
-
-    }
-
-    /* (non-Javadoc)
      * @see java.awt.event.ItemListener#itemStateChanged(java.awt.event.ItemEvent)
+     * Called when the user selects from a pulldown selection
      */
     public void itemStateChanged(ItemEvent e) {
@@ -240,31 +269,32 @@
      */
     public void actionPerformed(final ActionEvent e) {
-
         // OK or Cancel button-actions
         if (e.getSource() instanceof JButton) {
             JButton button = (JButton) e.getSource();
-            if ("OK".equals(button.getName())) {
-                saveValues();
-                terracerAction.terraceBuilding(
-                    outline,
-                    street,
-                    associatedStreet,
-                    segments(),
-                    numberFrom(),
-                    numberTo(),
-                    stepSize(),
-                    streetName(),
-                    doHandleRelation(),
-                    doDeleteOutline());
-
-                this.dialog.dispose();
-            } else if ("CANCEL".equals(button.getName())) {
+            if ("OK".equals(button.getActionCommand()) & button.isEnabled()) {
+            	if (validateInput()) {
+		            saveValues();
+		            
+			        terracerAction.terraceBuilding(
+			            outline,
+			            street,
+			            associatedStreet,
+			            segments(),
+			            dialog.lo.getText(),
+			            dialog.hi.getText(),
+			            stepSize(),
+			            streetName(),
+			            doHandleRelation(),
+			            doDeleteOutline());
+				
+		            this.dialog.dispose();
+		        }
+            } else if ("Cancel".equals(button.getActionCommand())) {
                 this.dialog.dispose();
             }
         } else {
-            // anything else is a change in the input
+            // Anything else is a change in the input (we don't get here though)
             validateInput();
         }
-
     }
 
@@ -327,4 +357,5 @@
         if (street != null)
             return null;
+            
         Object selected = dialog.streetComboBox.getSelectedItem();
         if (selected == null) {
@@ -345,5 +376,13 @@
      */
     public boolean doHandleRelation() {
-        return dialog.handleRelationCheckBox.isSelected();
+    	if (this.dialog == null) {
+    		JOptionPane.showMessageDialog(null, "dialog", "alert", JOptionPane.ERROR_MESSAGE); 
+    	}
+    	if (this.dialog.handleRelationCheckBox == null) {
+    		JOptionPane.showMessageDialog(null, "checkbox", "alert", JOptionPane.ERROR_MESSAGE); 
+    		return true;
+    	}  else {
+        	return this.dialog.handleRelationCheckBox.isSelected();
+        }
     }
 
@@ -359,5 +398,5 @@
      */
     public void focusGained(FocusEvent e) {
-        validateInput();
+		// Empty, but placeholder is required
     }
 
@@ -366,4 +405,7 @@
      */
     public void focusLost(FocusEvent e) {
+    	if (e.getOppositeComponent() == null)
+    		return;
+
         validateInput();
     }
Index: /applications/editors/josm/plugins/terracer/src/terracer/TerracerAction.java
===================================================================
--- /applications/editors/josm/plugins/terracer/src/terracer/TerracerAction.java	(revision 21093)
+++ /applications/editors/josm/plugins/terracer/src/terracer/TerracerAction.java	(revision 21094)
@@ -25,4 +25,5 @@
 import org.openstreetmap.josm.actions.JosmAction;
 import org.openstreetmap.josm.command.AddCommand;
+import org.openstreetmap.josm.command.ChangePropertyCommand;
 import org.openstreetmap.josm.command.ChangeCommand;
 import org.openstreetmap.josm.command.Command;
@@ -57,5 +58,7 @@
     // repeated terraces. this is the easiest, but not necessarily nicest, way.
     // private static String lastSelectedValue = "";
-
+	
+	Collection<Command> commands;
+	
     public TerracerAction() {
         super(tr("Terrace a building"), "terrace",
@@ -149,4 +152,12 @@
     }
 
+	public Integer getNumber(String number) {
+		try {
+            return Integer.parseInt(number);
+        } catch (NumberFormatException ex) {
+            return null;
+        }
+	}
+	
     /**
      * Terraces a single, closed, quadrilateral way.
@@ -159,10 +170,26 @@
      * @param outline The closed, quadrilateral way to terrace.
      * @param street The street, the buildings belong to (may be null)
+     * @param associatedStreet
+     * @param From
+     * @param To
+     * @param streetName the name of a street (may be null). Used if not null and street is null.
      * @param handleRelations If the user likes to add a relation or extend an existing relation
      * @param deleteOutline If the outline way should be deleted, when done
      */
-    public void terraceBuilding(Way outline, Way street, Relation associatedStreet, Integer segments, Integer from,
-            Integer to, int step, String streetName, boolean handleRelations, boolean deleteOutline) {
+    public void terraceBuilding(Way outline,
+				Way street,
+				Relation associatedStreet,
+				Integer segments,
+				String From,
+				String To,
+				int step,
+				String streetName,
+				boolean handleRelations,
+				boolean deleteOutline) {
         final int nb;
+        
+        Integer to, from;
+        to = getNumber(To);
+        from = getNumber(From);
         if (to != null && from != null) {
             nb = 1 + (to.intValue() - from.intValue()) / step;
@@ -176,5 +203,5 @@
                             + " from " + from + " to " + to + " step " + step);
         }
-
+		
         // now find which is the longest side connecting the first node
         Pair<Way, Way> interp = findFrontAndBack(outline);
@@ -186,74 +213,105 @@
         Node[][] new_nodes = new Node[2][nb + 1];
 
-        Collection<Command> commands = new LinkedList<Command>();
+        this.commands = new LinkedList<Command>();
         Collection<Way> ways = new LinkedList<Way>();
 
-        // create intermediate nodes by interpolating.
-        for (int i = 0; i <= nb; ++i) {
-            new_nodes[0][i] = interpolateAlong(interp.a, frontLength * i / nb);
-            new_nodes[1][i] = interpolateAlong(interp.b, backLength * i / nb);
-            commands.add(new AddCommand(new_nodes[0][i]));
-            commands.add(new AddCommand(new_nodes[1][i]));
-        }
-
-        // assemble new quadrilateral, closed ways
-        for (int i = 0; i < nb; ++i) {
-            Way terr = new Way();
-            // Using Way.nodes.add rather than Way.addNode because the latter
-            // doesn't
-            // exist in older versions of JOSM.
-            terr.addNode(new_nodes[0][i]);
-            terr.addNode(new_nodes[0][i + 1]);
-            terr.addNode(new_nodes[1][i + 1]);
-            terr.addNode(new_nodes[1][i]);
-            terr.addNode(new_nodes[0][i]);
-            
-            // add the tags of the outline to each building (e.g. source=*)
-            TagCollection.from(outline).applyTo(terr);
-            
-            if (from != null) {
-                // only, if the user has specified house numbers
-                terr.put("addr:housenumber", "" + (from + i * step));
-            }
-            terr.put("building", "yes");
-            if (street != null) {
-                terr.put("addr:street", street.get("name"));
-            } else if (streetName != null) {
-                terr.put("addr:street", streetName);
-            }
-            ways.add(terr);
-            commands.add(new AddCommand(terr));
-        }
-
-        if (handleRelations) { // create a new relation or merge with existing
-            if (associatedStreet == null) {  // create a new relation
-                associatedStreet = new Relation();
-                associatedStreet.put("type", "associatedStreet");
-                if (street != null) { // a street was part of the selection
-                    associatedStreet.put("name", street.get("name"));
-                    associatedStreet.addMember(new RelationMember("street", street));
-                } else {
-                    associatedStreet.put("name", streetName);
-                }
-                for (Way w : ways) {
-                    associatedStreet.addMember(new RelationMember("house", w));
-                }
-                commands.add(new AddCommand(associatedStreet));
-            }
-            else { // relation exists already - add new members
-                Relation newAssociatedStreet = new Relation(associatedStreet);
-                for (Way w : ways) {
-                    newAssociatedStreet.addMember(new RelationMember("house", w));
-                }
-                commands.add(new ChangeCommand(associatedStreet, newAssociatedStreet));
-            }
-        }
-
-        if (deleteOutline) {
-            commands.add(DeleteCommand.delete(Main.main.getEditLayer(), Collections.singleton(outline), true, true));
-        }
-
-        Main.main.undoRedo.add(new SequenceCommand(tr("Terrace"), commands));
-        Main.main.getCurrentDataSet().setSelected(ways);
+		if (nb > 1) {
+		    // create intermediate nodes by interpolating.
+		    for (int i = 0; i <= nb; ++i) {
+		        new_nodes[0][i] = interpolateAlong(interp.a, frontLength * i / nb);
+		        new_nodes[1][i] = interpolateAlong(interp.b, backLength * i / nb);
+		        this.commands.add(new AddCommand(new_nodes[0][i]));
+		        this.commands.add(new AddCommand(new_nodes[1][i]));
+		    }
+
+		    // assemble new quadrilateral, closed ways
+		    for (int i = 0; i < nb; ++i) {
+		        Way terr = new Way();
+		        // Using Way.nodes.add rather than Way.addNode because the latter
+		        // doesn't
+		        // exist in older versions of JOSM.
+		        terr.addNode(new_nodes[0][i]);
+		        terr.addNode(new_nodes[0][i + 1]);
+		        terr.addNode(new_nodes[1][i + 1]);
+		        terr.addNode(new_nodes[1][i]);
+		        terr.addNode(new_nodes[0][i]);
+		        
+		        // add the tags of the outline to each building (e.g. source=*)
+		        TagCollection.from(outline).applyTo(terr);
+				
+				String number = Integer.toString(from + i * step);
+
+		       	terr = addressBuilding(terr, street, streetName, number);
+
+		        ways.add(terr);
+		        this.commands.add(new AddCommand(terr));
+		    }
+
+		    if (deleteOutline) {
+		        this.commands.add(DeleteCommand.delete(Main.main.getEditLayer(), Collections.singleton(outline), true, true));
+		    }
+		} else {
+			// Single building, just add the address details
+			Way newOutline;
+			newOutline = addressBuilding(outline, street, streetName, From);
+			ways.add(newOutline);
+			this.commands.add(new ChangeCommand(outline, newOutline));
+		}
+		
+		if (handleRelations) { // create a new relation or merge with existing
+		    if (associatedStreet == null) {  // create a new relation
+		        associatedStreet = new Relation();
+		        associatedStreet.put("type", "associatedStreet");
+		        if (street != null) { // a street was part of the selection
+		            associatedStreet.put("name", street.get("name"));
+		            associatedStreet.addMember(new RelationMember("street", street));
+		        } else {
+		            associatedStreet.put("name", streetName);
+		        }
+		        for (Way w : ways) {
+		            associatedStreet.addMember(new RelationMember("house", w));
+		        }
+		        this.commands.add(new AddCommand(associatedStreet));
+		    }
+		    else { // relation exists already - add new members
+		        Relation newAssociatedStreet = new Relation(associatedStreet);
+		        for (Way w : ways) {
+		            newAssociatedStreet.addMember(new RelationMember("house", w));
+		        }
+		        this.commands.add(new ChangeCommand(associatedStreet, newAssociatedStreet));
+		    }
+		}
+		Main.main.undoRedo.add(new SequenceCommand(tr("Terrace"), commands));
+		if (nb > 1) {
+			// Select the new building outlines (for quick reversing)
+		    Main.main.getCurrentDataSet().setSelected(ways);
+		} else if (street != null) {
+			// Select the way (for quick selection of a new house (with the same way))
+		    Main.main.getCurrentDataSet().setSelected(street);
+		}
+    }
+
+    /**
+     * Adds address details to a single building
+     *
+     * @param outline The closed, quadrilateral way to add the address to.
+     * @param street The street, the buildings belong to (may be null)
+     * @param streetName the name of a street (may be null). Used if not null and street is null.
+     * @param number The house number
+     * @return the way with added address details
+     */
+    private Way addressBuilding(Way outline, Way street, String streetName, String number) {
+    	Way changedOutline = outline;
+        if (number != null) {
+            // only, if the user has specified house numbers
+            this.commands.add(new ChangePropertyCommand(changedOutline, "addr:housenumber", number));
+        }
+        changedOutline.put("building", "yes");
+        if (street != null) {
+            this.commands.add(new ChangePropertyCommand(changedOutline, "addr:street", street.get("name")));
+        } else if (streetName != null) {
+            this.commands.add(new ChangePropertyCommand(changedOutline, "addr:street", streetName));
+        }
+        return changedOutline;
     }
 
