Index: /applications/editors/josm/plugins/openstreetbugs/src/org/openstreetmap/josm/plugins/osb/gui/action/AddCommentAction.java
===================================================================
--- /applications/editors/josm/plugins/openstreetbugs/src/org/openstreetmap/josm/plugins/osb/gui/action/AddCommentAction.java	(revision 14747)
+++ /applications/editors/josm/plugins/openstreetbugs/src/org/openstreetmap/josm/plugins/osb/gui/action/AddCommentAction.java	(revision 14748)
@@ -31,9 +31,12 @@
 
 import java.awt.event.ActionEvent;
-
-import javax.swing.JOptionPane;
+import java.util.List;
 
 import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.plugins.osb.OsbPlugin;
 import org.openstreetmap.josm.plugins.osb.api.EditAction;
+import org.openstreetmap.josm.plugins.osb.gui.dialogs.TextInputDialog;
+import org.openstreetmap.josm.plugins.osb.gui.historycombobox.HistoryChangedListener;
+import org.openstreetmap.josm.plugins.osb.gui.historycombobox.StringUtils;
 
 public class AddCommentAction extends OsbAction {
@@ -49,5 +52,17 @@
     @Override
     protected void doActionPerformed(ActionEvent e) throws Exception {
-        String comment = JOptionPane.showInputDialog(Main.parent, tr("Enter your comment"));
+        List<String> history = StringUtils.stringToList(Main.pref.get("osb.comment.history"), "§§§");
+        HistoryChangedListener l = new HistoryChangedListener() {
+            public void historyChanged(List<String> history) {
+                Main.pref.put("osb.comment.history", StringUtils.listToString(history, "§§§"));
+            }
+        };
+        String comment = TextInputDialog.showDialog(
+                Main.map,
+                tr("Add a comment"), 
+                tr("Enter your comment"),
+                OsbPlugin.loadIcon("add_comment22.png"),
+                history, l);
+        
         if(comment != null) {
             comment = addMesgInfo(comment);
Index: /applications/editors/josm/plugins/openstreetbugs/src/org/openstreetmap/josm/plugins/osb/gui/action/CloseIssueAction.java
===================================================================
--- /applications/editors/josm/plugins/openstreetbugs/src/org/openstreetmap/josm/plugins/osb/gui/action/CloseIssueAction.java	(revision 14747)
+++ /applications/editors/josm/plugins/openstreetbugs/src/org/openstreetmap/josm/plugins/osb/gui/action/CloseIssueAction.java	(revision 14748)
@@ -31,9 +31,13 @@
 
 import java.awt.event.ActionEvent;
-
-import javax.swing.JOptionPane;
+import java.util.List;
 
 import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.plugins.osb.OsbPlugin;
 import org.openstreetmap.josm.plugins.osb.api.CloseAction;
+import org.openstreetmap.josm.plugins.osb.api.EditAction;
+import org.openstreetmap.josm.plugins.osb.gui.dialogs.TextInputDialog;
+import org.openstreetmap.josm.plugins.osb.gui.historycombobox.HistoryChangedListener;
+import org.openstreetmap.josm.plugins.osb.gui.historycombobox.StringUtils;
 
 public class CloseIssueAction extends OsbAction {
@@ -42,4 +46,5 @@
 
     private CloseAction closeAction = new CloseAction();
+    private EditAction commentAction = new EditAction();
 
     public CloseIssueAction() {
@@ -49,16 +54,19 @@
     @Override
     protected void doActionPerformed(ActionEvent e) throws Exception {
-        int closeOk = JOptionPane.showConfirmDialog(Main.parent,
-                tr("Really mark this issue as ''done''?"),
+        List<String> history = StringUtils.stringToList(Main.pref.get("osb.comment.history"), "§§§");
+        HistoryChangedListener l = new HistoryChangedListener() {
+            public void historyChanged(List<String> history) {
+                Main.pref.put("osb.comment.history", StringUtils.listToString(history, "§§§"));
+            }
+        };
+        String comment = TextInputDialog.showDialog(Main.map,
                 tr("Really close?"),
-                JOptionPane.YES_NO_OPTION);
+                tr("<html>Really mark this issue as ''done''?<br><br>You may add an optional comment:</html>"),
+                OsbPlugin.loadIcon("icon_valid22.png"),
+                history, l);
 
-        if(closeOk == JOptionPane.YES_OPTION) {
-            int addComment = JOptionPane.showConfirmDialog(Main.parent,
-                    tr("Do you want to add a comment?"),
-                    tr("Add comment?"),
-                    JOptionPane.YES_NO_OPTION);
-            if(addComment == JOptionPane.YES_OPTION) {
-                new AddCommentAction().doActionPerformed(new ActionEvent(this, 0, "add_comment"));
+        if(comment != null) {
+            if(comment.length() > 0) {
+                commentAction.execute(getSelectedNode(), comment);
             }
             closeAction.execute(getSelectedNode());
Index: /applications/editors/josm/plugins/openstreetbugs/src/org/openstreetmap/josm/plugins/osb/gui/action/NewIssueAction.java
===================================================================
--- /applications/editors/josm/plugins/openstreetbugs/src/org/openstreetmap/josm/plugins/osb/gui/action/NewIssueAction.java	(revision 14747)
+++ /applications/editors/josm/plugins/openstreetbugs/src/org/openstreetmap/josm/plugins/osb/gui/action/NewIssueAction.java	(revision 14748)
@@ -35,4 +35,5 @@
 import java.awt.event.MouseListener;
 import java.io.IOException;
+import java.util.List;
 
 import javax.swing.JOptionPane;
@@ -44,4 +45,7 @@
 import org.openstreetmap.josm.plugins.osb.OsbPlugin;
 import org.openstreetmap.josm.plugins.osb.api.NewAction;
+import org.openstreetmap.josm.plugins.osb.gui.dialogs.TextInputDialog;
+import org.openstreetmap.josm.plugins.osb.gui.historycombobox.HistoryChangedListener;
+import org.openstreetmap.josm.plugins.osb.gui.historycombobox.StringUtils;
 
 public class NewIssueAction extends OsbAction implements MouseListener {
@@ -93,9 +97,16 @@
 
     private void addNewIssue(MouseEvent e) {
-        // get the comment
-        String result = JOptionPane.showInputDialog(Main.parent,
+        List<String> history = StringUtils.stringToList(Main.pref.get("osb.new.history"), "§§§");
+        HistoryChangedListener l = new HistoryChangedListener() {
+            public void historyChanged(List<String> history) {
+                Main.pref.put("osb.new.history", StringUtils.listToString(history, "§§§"));
+            }
+        };
+        String result = TextInputDialog.showDialog(
+                Main.map,
+                tr("Create issue"), 
                 tr("Describe the problem precisely"),
-                tr("Create issue"),
-                JOptionPane.QUESTION_MESSAGE);
+                OsbPlugin.loadIcon("icon_error_add22.png"),
+                history, l);
 
         if(result != null && result.length() > 0) {
Index: /applications/editors/josm/plugins/openstreetbugs/src/org/openstreetmap/josm/plugins/osb/gui/dialogs/TextInputDialog.java
===================================================================
--- /applications/editors/josm/plugins/openstreetbugs/src/org/openstreetmap/josm/plugins/osb/gui/dialogs/TextInputDialog.java	(revision 14748)
+++ /applications/editors/josm/plugins/openstreetbugs/src/org/openstreetmap/josm/plugins/osb/gui/dialogs/TextInputDialog.java	(revision 14748)
@@ -0,0 +1,183 @@
+package org.openstreetmap.josm.plugins.osb.gui.dialogs;
+import java.awt.BorderLayout;
+import java.awt.Dimension;
+import java.awt.FlowLayout;
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
+import java.awt.Insets;
+import java.awt.Point;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.util.List;
+
+import javax.swing.Icon;
+import javax.swing.JButton;
+import javax.swing.JComponent;
+import javax.swing.JDialog;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.SwingConstants;
+import javax.swing.SwingUtilities;
+
+import org.openstreetmap.josm.plugins.osb.gui.historycombobox.HistoryChangedListener;
+import org.openstreetmap.josm.plugins.osb.gui.historycombobox.SuggestingJHistoryComboBox;
+
+/**
+* This code was edited or generated using CloudGarden's Jigloo
+* SWT/Swing GUI Builder, which is free for non-commercial
+* use. If Jigloo is being used commercially (ie, by a corporation,
+* company or business for any purpose whatever) then you
+* should purchase a license for each developer using Jigloo.
+* Please visit www.cloudgarden.com for details.
+* Use of Jigloo implies acceptance of these licensing terms.
+* A COMMERCIAL LICENSE HAS NOT BEEN PURCHASED FOR
+* THIS MACHINE, SO JIGLOO OR THIS CODE CANNOT BE USED
+* LEGALLY FOR ANY CORPORATE OR COMMERCIAL PURPOSE.
+*/
+public class TextInputDialog extends JDialog {
+    private JLabel lblIcon;
+    private JButton btnCancel;
+    private JButton btnOk;
+    private JPanel pnlButtons;
+    private SuggestingJHistoryComboBox input;
+    private JLabel lblText;
+    private JPanel pnlMain;
+    
+    private String value = null;
+    
+    private TextInputDialog() {
+        initGUI();
+        initListeners();
+    }
+
+    private void initListeners() {
+        input.getEditor().addActionListener(new ActionListener() {
+            public void actionPerformed(ActionEvent e) {
+                okPressed();
+            }
+        });
+        
+        btnOk.addActionListener(new ActionListener() {
+            public void actionPerformed(ActionEvent e) {
+                okPressed();
+            }
+        });
+        
+        btnCancel.addActionListener(new ActionListener() {
+            public void actionPerformed(ActionEvent e) {
+                dispose();
+            }
+        });
+    }
+    
+    private void okPressed() {
+        value = input.getText();
+        input.addCurrentItemToHistory();
+        dispose();
+    }
+
+    private void initGUI() {
+        BorderLayout thisLayout = new BorderLayout();
+        getContentPane().setLayout(thisLayout);
+        thisLayout.setHgap(5);
+        thisLayout.setVgap(5);
+        {
+            pnlMain = new JPanel();
+            GridBagLayout pnlMainLayout = new GridBagLayout();
+            pnlMainLayout.rowWeights = new double[] {0.1, 0.1, 0.1};
+            pnlMainLayout.rowHeights = new int[] {7, 7, 7};
+            pnlMainLayout.columnWeights = new double[] {0.1, 0.1};
+            pnlMainLayout.columnWidths = new int[] {7, 7};
+            getContentPane().add(pnlMain, BorderLayout.CENTER);
+            pnlMain.setLayout(pnlMainLayout);
+            pnlMain.setPreferredSize(new java.awt.Dimension(487, 132));
+            {
+                lblIcon = new JLabel();
+                pnlMain.add(lblIcon, new GridBagConstraints(0, 0, 1, 3, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(10, 10, 10, 10), 0, 0));
+                lblIcon.setVerticalAlignment(SwingConstants.TOP);
+                lblIcon.setVerticalTextPosition(SwingConstants.TOP);
+            }
+            {
+                lblText = new JLabel();
+                pnlMain.add(lblText, new GridBagConstraints(1, 0, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.BOTH, new Insets(5, 5, 5, 5), 0, 0));
+            }
+            {
+                input = new SuggestingJHistoryComboBox();
+                pnlMain.add(input, new GridBagConstraints(1, 1, 1, 1, 1.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(5, 5, 5, 5), 0, 0));
+                input.setSize(503, 22);
+            }
+            {
+                pnlButtons = new JPanel();
+                FlowLayout pnlButtonsLayout = new FlowLayout();
+                pnlButtonsLayout.setAlignment(FlowLayout.RIGHT);
+                pnlMain.add(pnlButtons, new GridBagConstraints(1, 2, 1, 1, 0.0, 0.0, GridBagConstraints.SOUTHEAST, GridBagConstraints.NONE, new Insets(5, 5, 5, 5), 0, 0));
+                pnlButtons.setLayout(pnlButtonsLayout);
+                {
+                    btnOk = new JButton();
+                    pnlButtons.add(btnOk);
+                    btnOk.setText("OK");
+                    btnOk.setPreferredSize(new java.awt.Dimension(100, 25));
+                }
+                {
+                    btnCancel = new JButton();
+                    pnlButtons.add(btnCancel);
+                    btnCancel.setText("Cancel");
+                    btnCancel.setPreferredSize(new java.awt.Dimension(100, 25));
+                }
+            }
+        }
+        setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
+    }
+    
+    public static String showDialog(JComponent parent, String title, String text, List<String> history, HistoryChangedListener l) {
+        return showDialog(parent, title, text, null, history, l);
+    }
+    
+    /**
+     * Opens a text input dialog and returns the entered text
+     * @return the entered text or null if the cancel button has been pressed;
+     */
+    public static String showDialog(JComponent parent, String title, String description, Icon icon, List<String> history, HistoryChangedListener l) {
+        TextInputDialog tid = new TextInputDialog();
+        tid.setTitle(title);
+        tid.setSize(new Dimension(500, 180));
+        tid.setDescription(description);
+        tid.setHistory(history);
+        tid.addHistoryChangedListener(l);
+        tid.setModal(true);
+        tid.setIcon(icon);
+
+        // center tid on parent comp;
+        Point p = new Point(0,0);
+        SwingUtilities.convertPointToScreen(p, parent);
+        int x = (int) (p.getX() + (double)(parent.getWidth() - tid.getWidth()) / 2);
+        int y = (int) (p.getY() +  (double)(parent.getHeight() - tid.getHeight()) / 2);
+        tid.setLocation(x, y);
+        
+        //tid.pack();
+        tid.setVisible(true);
+        return tid.getValue();
+    }
+
+    private String getValue() {
+        return this.value;
+    }
+    
+    public void setDescription(String text) {
+        lblText.setText(text);
+    }
+    
+    public void setHistory(List<String> history) {
+        input.setHistory(history);
+        input.setText("");
+        value = null;
+    }
+    
+    public void addHistoryChangedListener(HistoryChangedListener l) {
+        input.addHistoryChangedListener(l);
+    }
+    
+    public void setIcon(Icon icon) {
+        lblIcon.setIcon(icon);
+    }
+}
Index: /applications/editors/josm/plugins/openstreetbugs/src/org/openstreetmap/josm/plugins/osb/gui/historycombobox/ComboBoxHistory.java
===================================================================
--- /applications/editors/josm/plugins/openstreetbugs/src/org/openstreetmap/josm/plugins/osb/gui/historycombobox/ComboBoxHistory.java	(revision 14748)
+++ /applications/editors/josm/plugins/openstreetbugs/src/org/openstreetmap/josm/plugins/osb/gui/historycombobox/ComboBoxHistory.java	(revision 14748)
@@ -0,0 +1,130 @@
+/* Copyright (c) 2008, Henrik Niehaus
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * 
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice, 
+ *    this list of conditions and the following disclaimer in the documentation 
+ *    and/or other materials provided with the distribution.
+ * 3. Neither the name of the project nor the names of its 
+ *    contributors may be used to endorse or promote products derived from this 
+ *    software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.openstreetmap.josm.plugins.osb.gui.historycombobox;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+
+import javax.swing.DefaultComboBoxModel;
+
+public class ComboBoxHistory extends DefaultComboBoxModel implements Iterable<String> {
+
+	private int maxSize = 10;
+	
+	private List<HistoryChangedListener> listeners = new ArrayList<HistoryChangedListener>();
+	
+	public ComboBoxHistory(int size) {
+		maxSize = size;
+	}
+	
+	/**
+	 * Adds or moves an element to the top of the history
+	 */
+	public void addElement(Object o) {
+		String newEntry = (String)o;
+		
+		// if history contains this object already, delete it,
+		// so that it looks like a move to the top
+		for (int i = 0; i < getSize(); i++) {
+			String oldEntry = (String) getElementAt(i);
+			if(oldEntry.equals(newEntry)) {
+				removeElementAt(i);
+			}
+		}
+		
+		// insert element at the top
+		insertElementAt(o, 0);
+		
+		// remove an element, if the history gets too large
+		if(getSize()> maxSize) {
+			removeElementAt(getSize()-1);
+		}
+		
+		// set selected item to the one just added
+		setSelectedItem(o);
+		
+		fireHistoryChanged();
+	}
+	
+	public Iterator<String> iterator() {
+		return new Iterator<String>() {
+
+			private int position = -1;
+			
+			public void remove() {
+				removeElementAt(position);
+			}
+
+			public boolean hasNext() {
+				if(position < getSize()-1 && getSize()>0) {
+					return true;
+				}
+				return false;
+			}
+
+			public String next() {
+				position++;
+				return getElementAt(position).toString();
+			}
+			
+		};
+	}
+
+	public void setItems(List<String> items) {
+	    removeAllElements();
+	    Collections.reverse(items);
+	    for (String item : items) {
+            addElement(item);
+        }
+	    Collections.reverse(items);
+	}
+	
+    public List<String> asList() {
+        List<String> list = new ArrayList<String>(maxSize);
+        for (String item : this) {
+            list.add(item);
+        }
+        return list;
+    }
+    
+    public void addHistoryChangedListener(HistoryChangedListener l) {
+        listeners.add(l);
+    }
+    
+    public void removeHistoryChangedListener(HistoryChangedListener l) {
+        listeners.remove(l);
+    }
+    
+    private void fireHistoryChanged() {
+        for (HistoryChangedListener l : listeners) {
+            l.historyChanged(asList());
+        }
+    }
+}
Index: /applications/editors/josm/plugins/openstreetbugs/src/org/openstreetmap/josm/plugins/osb/gui/historycombobox/EventConsumingPlainDocument.java
===================================================================
--- /applications/editors/josm/plugins/openstreetbugs/src/org/openstreetmap/josm/plugins/osb/gui/historycombobox/EventConsumingPlainDocument.java	(revision 14748)
+++ /applications/editors/josm/plugins/openstreetbugs/src/org/openstreetmap/josm/plugins/osb/gui/historycombobox/EventConsumingPlainDocument.java	(revision 14748)
@@ -0,0 +1,74 @@
+/* Copyright (c) 2008, Henrik Niehaus
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * 
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice, 
+ *    this list of conditions and the following disclaimer in the documentation 
+ *    and/or other materials provided with the distribution.
+ * 3. Neither the name of the project nor the names of its 
+ *    contributors may be used to endorse or promote products derived from this 
+ *    software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.openstreetmap.josm.plugins.osb.gui.historycombobox;
+
+import javax.swing.event.DocumentEvent;
+import javax.swing.event.UndoableEditEvent;
+import javax.swing.text.PlainDocument;
+
+public class EventConsumingPlainDocument extends PlainDocument {
+	private boolean consumeEvents;
+
+	public boolean isConsumeEvents() {
+		return consumeEvents;
+	}
+
+	public void setConsumeEvents(boolean consumeEvents) {
+		this.consumeEvents = consumeEvents;
+	}
+
+	@Override
+	protected void fireChangedUpdate(DocumentEvent e) {
+		if(!consumeEvents) {
+			super.fireChangedUpdate(e);
+		}
+	}
+
+	@Override
+	protected void fireInsertUpdate(DocumentEvent e) {
+		if(!consumeEvents) {
+			super.fireInsertUpdate(e);
+		}
+	}
+
+	@Override
+	protected void fireRemoveUpdate(DocumentEvent e) {
+		if(!consumeEvents) {
+			super.fireRemoveUpdate(e);
+		}
+	}
+
+	@Override
+	protected void fireUndoableEditUpdate(UndoableEditEvent e) {
+		if(!consumeEvents) {
+			super.fireUndoableEditUpdate(e);
+		}
+	}
+	
+	
+}
Index: /applications/editors/josm/plugins/openstreetbugs/src/org/openstreetmap/josm/plugins/osb/gui/historycombobox/HistoryChangedListener.java
===================================================================
--- /applications/editors/josm/plugins/openstreetbugs/src/org/openstreetmap/josm/plugins/osb/gui/historycombobox/HistoryChangedListener.java	(revision 14748)
+++ /applications/editors/josm/plugins/openstreetbugs/src/org/openstreetmap/josm/plugins/osb/gui/historycombobox/HistoryChangedListener.java	(revision 14748)
@@ -0,0 +1,34 @@
+/* Copyright (c) 2008, Henrik Niehaus
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * 
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice, 
+ *    this list of conditions and the following disclaimer in the documentation 
+ *    and/or other materials provided with the distribution.
+ * 3. Neither the name of the project nor the names of its 
+ *    contributors may be used to endorse or promote products derived from this 
+ *    software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.openstreetmap.josm.plugins.osb.gui.historycombobox;
+
+import java.util.List;
+
+public interface HistoryChangedListener {
+    public void historyChanged(List<String> history);
+}
Index: /applications/editors/josm/plugins/openstreetbugs/src/org/openstreetmap/josm/plugins/osb/gui/historycombobox/JHistoryComboBox.java
===================================================================
--- /applications/editors/josm/plugins/openstreetbugs/src/org/openstreetmap/josm/plugins/osb/gui/historycombobox/JHistoryComboBox.java	(revision 14748)
+++ /applications/editors/josm/plugins/openstreetbugs/src/org/openstreetmap/josm/plugins/osb/gui/historycombobox/JHistoryComboBox.java	(revision 14748)
@@ -0,0 +1,93 @@
+/* Copyright (c) 2008, Henrik Niehaus
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * 
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice, 
+ *    this list of conditions and the following disclaimer in the documentation 
+ *    and/or other materials provided with the distribution.
+ * 3. Neither the name of the project nor the names of its 
+ *    contributors may be used to endorse or promote products derived from this 
+ *    software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.openstreetmap.josm.plugins.osb.gui.historycombobox;
+
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.util.List;
+
+import javax.swing.JComboBox;
+
+/**
+ * Extends the standard JComboBox with a history. Works with Strings only. 
+ * @author henni
+ *
+ */
+public class JHistoryComboBox extends JComboBox implements ActionListener {
+
+    protected ComboBoxHistory model;
+    
+    /**
+     * Default constructor for GUI editors. Don't use this!!!
+     */
+    public JHistoryComboBox() {}
+    
+    /**
+     * @param history the history as a list of strings
+     */
+    public JHistoryComboBox(List<String> history) {
+        model = new ComboBoxHistory(15);
+        setModel(model);
+        getEditor().addActionListener(this);
+        setEditable(true);
+        setHistory(history);
+    }
+    
+    public void actionPerformed(ActionEvent e) {
+        addCurrentItemToHistory();
+    }
+
+    public void addCurrentItemToHistory() {
+        String regex = (String)getEditor().getItem();
+        model.addElement(regex);
+    }
+    
+    public void setText(String text) {
+    	getEditor().setItem(text);
+    }
+    
+    public String getText() {
+    	return getEditor().getItem().toString();
+    }
+    
+    public void addHistoryChangedListener(HistoryChangedListener l) {
+        model.addHistoryChangedListener(l);
+    }
+    
+    public void removeHistoryChangedListener(HistoryChangedListener l) {
+        model.removeHistoryChangedListener(l);
+    }
+    
+    public void setHistory(List<String> history) {
+        model.setItems(history);
+    }
+    
+    public List<String> getHistory() {
+        return model.asList();
+    }
+}
Index: /applications/editors/josm/plugins/openstreetbugs/src/org/openstreetmap/josm/plugins/osb/gui/historycombobox/StringUtils.java
===================================================================
--- /applications/editors/josm/plugins/openstreetbugs/src/org/openstreetmap/josm/plugins/osb/gui/historycombobox/StringUtils.java	(revision 14748)
+++ /applications/editors/josm/plugins/openstreetbugs/src/org/openstreetmap/josm/plugins/osb/gui/historycombobox/StringUtils.java	(revision 14748)
@@ -0,0 +1,30 @@
+package org.openstreetmap.josm.plugins.osb.gui.historycombobox;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+public class StringUtils {
+    public static List<String> stringToList(String string, String delim) {
+        List<String> list = new ArrayList<String>();
+        if(string != null && delim != null) {
+            String[] s = string.split(delim);
+            for (String str : s) {
+                list.add(str);
+            }
+        }
+        return list;
+    }
+    
+    public static String listToString(List<String> list, String delim) {
+        if(list != null && list.size() > 0) {
+            Iterator<String> iter = list.iterator();
+            StringBuilder sb = new StringBuilder(iter.next());
+            while(iter.hasNext()) {
+                sb.append(delim).append(iter.next());
+            }
+            return sb.toString();
+        }
+        return "";
+    }
+}
Index: /applications/editors/josm/plugins/openstreetbugs/src/org/openstreetmap/josm/plugins/osb/gui/historycombobox/SuggestingJHistoryComboBox.java
===================================================================
--- /applications/editors/josm/plugins/openstreetbugs/src/org/openstreetmap/josm/plugins/osb/gui/historycombobox/SuggestingJHistoryComboBox.java	(revision 14748)
+++ /applications/editors/josm/plugins/openstreetbugs/src/org/openstreetmap/josm/plugins/osb/gui/historycombobox/SuggestingJHistoryComboBox.java	(revision 14748)
@@ -0,0 +1,128 @@
+/* Copyright (c) 2008, Henrik Niehaus
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * 
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice, 
+ *    this list of conditions and the following disclaimer in the documentation 
+ *    and/or other materials provided with the distribution.
+ * 3. Neither the name of the project nor the names of its 
+ *    contributors may be used to endorse or promote products derived from this 
+ *    software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.openstreetmap.josm.plugins.osb.gui.historycombobox;
+
+import java.awt.event.ActionEvent;
+import java.awt.event.KeyEvent;
+import java.awt.event.KeyListener;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.swing.JTextField;
+import javax.swing.text.AbstractDocument;
+import javax.swing.text.AttributeSet;
+import javax.swing.text.BadLocationException;
+import javax.swing.text.DocumentFilter;
+import javax.swing.text.JTextComponent;
+
+public class SuggestingJHistoryComboBox extends JHistoryComboBox implements KeyListener {
+
+	private EventConsumingPlainDocument doc = new EventConsumingPlainDocument();
+	
+    public SuggestingJHistoryComboBox(List<String> history) {
+        super(history);
+
+        // add keylistener for ctrl + space
+        getEditor().getEditorComponent().addKeyListener(this);
+        
+        // add specialized document, which can consume events, which are
+        // produced by the suggestion
+        ((JTextComponent)getEditor().getEditorComponent()).setDocument(doc);
+        
+        // add DocumentFilter to trigger suggestion
+        JTextField editor = (JTextField) getEditor().getEditorComponent();
+        final AbstractDocument doc = (AbstractDocument) editor.getDocument();
+        doc.setDocumentFilter(new DocumentFilter() {
+			@Override
+			public void insertString(FilterBypass fb, int offset,
+					String string, AttributeSet attr)
+					throws BadLocationException {
+				super.insertString(fb, offset, string, attr);
+				if(doc.getLength() > 0) {
+					suggest();
+				}
+			}
+
+			@Override
+			public void replace(FilterBypass fb, int offset, int length,
+					String text, AttributeSet attrs)
+					throws BadLocationException {
+				super.replace(fb, offset, length, text, attrs);
+				if(doc.getLength() > 0) {
+					suggest();
+				}
+			}
+        });
+    }
+
+    public SuggestingJHistoryComboBox() {
+        this(new ArrayList<String>());
+    }
+
+    @Override
+    public void actionPerformed(ActionEvent e) {
+        if(e.getSource() instanceof JTextField) {
+            JTextField textField = (JTextField) e.getSource();
+    
+            // if the ActionCommand equals SUGGEST, the user confirms a suggestion
+            if("SUGGEST".equals(e.getActionCommand())) {
+                textField.setSelectionStart(textField.getText().length());
+                textField.setSelectionEnd(textField.getText().length());
+                textField.setActionCommand("");
+            } else { // the user has finished the input
+                super.actionPerformed(e);
+            }
+        }
+    }
+
+    private void suggest() {
+		JTextField textField = (JTextField) getEditor().getEditorComponent();
+		String text = textField.getText();
+
+		// suggest text
+		for (String suggestion : super.model) {
+			if (suggestion.startsWith(text)) {
+				textField.setActionCommand("SUGGEST");
+				doc.setConsumeEvents(true);
+				textField.setText(suggestion);
+				textField.setSelectionStart(text.length());
+				textField.setSelectionEnd(textField.getText().length());
+				doc.setConsumeEvents(false);
+				break;
+			}
+		}
+	}
+    
+    public void keyReleased(KeyEvent e) {
+    	if(e.getKeyCode() == KeyEvent.VK_SPACE && e.isControlDown()) {
+        	suggest();
+        } 
+    }
+    public void keyPressed(KeyEvent e) {}
+    public void keyTyped(KeyEvent e) {}
+}
Index: /applications/editors/josm/plugins/openstreetbugs/src/org/openstreetmap/josm/plugins/osb/gui/historycombobox/SuggestionListener.java
===================================================================
--- /applications/editors/josm/plugins/openstreetbugs/src/org/openstreetmap/josm/plugins/osb/gui/historycombobox/SuggestionListener.java	(revision 14748)
+++ /applications/editors/josm/plugins/openstreetbugs/src/org/openstreetmap/josm/plugins/osb/gui/historycombobox/SuggestionListener.java	(revision 14748)
@@ -0,0 +1,37 @@
+/* Copyright (c) 2008, Henrik Niehaus
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * 
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice, 
+ *    this list of conditions and the following disclaimer in the documentation 
+ *    and/or other materials provided with the distribution.
+ * 3. Neither the name of the project nor the names of its 
+ *    contributors may be used to endorse or promote products derived from this 
+ *    software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.openstreetmap.josm.plugins.osb.gui.historycombobox;
+
+public interface SuggestionListener {
+
+	/**
+	 * Invoked, if an attempt to suggest text has been made
+	 * @param suggestion The suggested text or null if no suggestion could be found
+	 */
+	public void suggested(String suggestion);
+}
