Index: /trunk/src/org/openstreetmap/josm/actions/search/SearchAction.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/actions/search/SearchAction.java	(revision 966)
+++ /trunk/src/org/openstreetmap/josm/actions/search/SearchAction.java	(revision 967)
@@ -8,4 +8,5 @@
 import java.awt.event.KeyEvent;
 import java.util.Collection;
+import java.util.LinkedList;
 
 import javax.swing.ButtonGroup;
@@ -23,120 +24,167 @@
 
 public class SearchAction extends JosmAction {
-	public static enum SearchMode {replace, add, remove}
 
-    private String lastSearch = "";
+    public static final int SEARCH_HISTORY_SIZE = 10;
+
+    public static enum SearchMode {
+        replace, add, remove
+    }
+
+    public static final LinkedList<SearchSetting> searchHistory = new LinkedList<SearchSetting>();
+
+    private static SearchSetting lastSearch = null;
 
     public SearchAction() {
-    	super(tr("Search ..."), "dialogs/search", tr("Search for objects."), KeyEvent.VK_F, KeyEvent.CTRL_DOWN_MASK, true);
+        super(tr("Search ..."), "dialogs/search", tr("Search for objects."), KeyEvent.VK_F, KeyEvent.CTRL_DOWN_MASK,
+                true);
     }
 
     public void actionPerformed(ActionEvent e) {
-    	if (Main.map == null) {
-    		JOptionPane.showMessageDialog(Main.parent, tr("No data loaded."));
-    		return;
-    	}
-    	JLabel label = new JLabel(tr("Please enter a search string."));
-    	final JTextField input = new JTextField(lastSearch);
-    	input.setToolTipText(tr("<html>Fulltext search:<ul>" +
-    			"<li><b>Baker Street</b> - 'Baker' and 'Street' in any key or name.</li>" +
-    			"<li><b>\"Baker Street\"</b> - 'Baker Street' in any key or name.</li>" +
-    			"<li><b>name:Bak</b> - 'Bak' anywhere in the name.</li>" +
-    			"<li><b>-name:Bak</b> - not 'Bak' in the name.</li>" +
-    			"<li><b>foot:</b> - key=foot set to any value.</li>" +
-    			"<li>Special targets:</li>" +
-    			"<li><b>type:</b> - type of the object (<b>node</b>, <b>way</b>, <b>relation</b>)</li>" +
-    			"<li><b>user:</b>... - all objects changed by user</li>" +
-    			"<li><b>id:</b>... - object with given ID</li>" +
-    			"<li><b>nodes:</b>... - object with given number of nodes</li>" +
-    			"<li><b>modified</b> - all changed objects</li>" +
-    			"<li><b>incomplete</b> - all incomplete objects</li>" +
-    			"<li>Use <b>|</b> or <b>OR</b> to combine with logical or</li>" +
-    			"<li>Use <b>\"</b> to quote operators (e.g. if key contains :)</li>" +
-    			"<li>Use <b>(</b> and <b>)</b> to group expressions</li>" +
-    	"</ul></html>"));
-    
-    	JRadioButton replace = new JRadioButton(tr("replace selection"), true);
-    	JRadioButton add = new JRadioButton(tr("add to selection"), false);
-    	JRadioButton remove = new JRadioButton(tr("remove from selection"), false);
-    	ButtonGroup bg = new ButtonGroup();
-    	bg.add(replace);
-    	bg.add(add);
-    	bg.add(remove);
-    	
-    	JCheckBox caseSensitive = new JCheckBox(tr("case sensitive"), false);
-    
-    	JPanel p = new JPanel(new GridBagLayout());
-    	p.add(label, GBC.eop());
-    	p.add(input, GBC.eop().fill(GBC.HORIZONTAL));
-    	p.add(replace, GBC.eol());
-    	p.add(add, GBC.eol());
-    	p.add(remove, GBC.eop());
-    	p.add(caseSensitive, GBC.eol());
-    	JOptionPane pane = new JOptionPane(p, JOptionPane.INFORMATION_MESSAGE, JOptionPane.OK_CANCEL_OPTION, null){
-    		@Override public void selectInitialValue() {
-    			input.requestFocusInWindow();
-    			input.selectAll();
-    		}
-    	};
-    	pane.createDialog(Main.parent,tr("Search")).setVisible(true);
-    	if (!Integer.valueOf(JOptionPane.OK_OPTION).equals(pane.getValue()))
-    		return;
-    	lastSearch = input.getText();
-    	SearchAction.SearchMode mode = replace.isSelected() ? SearchAction.SearchMode.replace : (add.isSelected() ? SearchAction.SearchMode.add : SearchAction.SearchMode.remove);
-    	search(lastSearch, mode, caseSensitive.isSelected());
+        if (Main.map == null) {
+            JOptionPane.showMessageDialog(Main.parent, tr("No data loaded."));
+            return;
+        }
+        SearchSetting s = lastSearch;
+        if (s == null)
+            s = new SearchSetting("", false, SearchMode.replace);
+        showSearchDialog(s);
     }
 
-	public static void search(String search, SearchMode mode, boolean caseSensitive) {
-    	if (search.startsWith("http://") || search.startsWith("ftp://") || search.startsWith("https://") || search.startsWith("file:/")) {
-    		SelectionWebsiteLoader loader = new SelectionWebsiteLoader(search, mode);
-    		if (loader.url != null) {
-    			Main.worker.execute(loader);
-    			return;
-    		}
-    	}
-		try {
-			Collection<OsmPrimitive> sel = Main.ds.getSelected();
-			SearchCompiler.Match matcher = SearchCompiler.compile(search, caseSensitive);
-			int foundMatches = 0;
-			for (OsmPrimitive osm : Main.ds.allNonDeletedCompletePrimitives()) {
-				if (mode == SearchMode.replace)
-				{
-					if (matcher.match(osm))
-					{
-						sel.add(osm);
-						++foundMatches;
-					}
-					else
-						sel.remove(osm);
-				}
-				else if (mode == SearchMode.add && !osm.selected && matcher.match(osm))
-				{
-					sel.add(osm);
-					++foundMatches;
-				}
-				else if (mode == SearchMode.remove && osm.selected && matcher.match(osm))
-				{
-					sel.remove(osm);
-					++foundMatches;
-				}
-			}
-			Main.ds.setSelected(sel);
-			if(foundMatches == 0)
-			{
-				String msg = null;
-				if (mode == SearchMode.replace)
-					msg = tr("No match found for ''{0}''", search);
-				else if (mode == SearchMode.add)
-					msg = tr("Nothing added to selection by searching for ''{0}''", search);
-				else if (mode == SearchMode.remove)
-					msg = tr("Nothing removed from selection by searching for ''{0}''", search);
-				Main.map.statusLine.setHelpText(msg);
-				JOptionPane.showMessageDialog(Main.parent, msg);
-			}
-			else
-				Main.map.statusLine.setHelpText(tr("Found {0} matches", foundMatches));
-		} catch (SearchCompiler.ParseError e) {
-			JOptionPane.showMessageDialog(Main.parent, e.getMessage());
-		}
+    public void showSearchDialog(SearchSetting initialValues) {
+        JLabel label = new JLabel(tr("Please enter a search string."));
+        final JTextField input = new JTextField(initialValues.text);
+        input.setToolTipText(tr("<html>Fulltext search:<ul>"
+                + "<li><b>Baker Street</b> - 'Baker' and 'Street' in any key or name.</li>"
+                + "<li><b>\"Baker Street\"</b> - 'Baker Street' in any key or name.</li>"
+                + "<li><b>name:Bak</b> - 'Bak' anywhere in the name.</li>"
+                + "<li><b>-name:Bak</b> - not 'Bak' in the name.</li>"
+                + "<li><b>foot:</b> - key=foot set to any value.</li>" + "<li>Special targets:</li>"
+                + "<li><b>type:</b> - type of the object (<b>node</b>, <b>way</b>, <b>relation</b>)</li>"
+                + "<li><b>user:</b>... - all objects changed by user</li>"
+                + "<li><b>id:</b>... - object with given ID</li>"
+                + "<li><b>nodes:</b>... - object with given number of nodes</li>"
+                + "<li><b>modified</b> - all changed objects</li>"
+                + "<li><b>incomplete</b> - all incomplete objects</li>"
+                + "<li>Use <b>|</b> or <b>OR</b> to combine with logical or</li>"
+                + "<li>Use <b>\"</b> to quote operators (e.g. if key contains :)</li>"
+                + "<li>Use <b>(</b> and <b>)</b> to group expressions</li>" + "</ul></html>"));
+
+        JRadioButton replace = new JRadioButton(tr("replace selection"), initialValues.mode == SearchMode.replace);
+        JRadioButton add = new JRadioButton(tr("add to selection"), initialValues.mode == SearchMode.add);
+        JRadioButton remove = new JRadioButton(tr("remove from selection"), initialValues.mode == SearchMode.remove);
+        ButtonGroup bg = new ButtonGroup();
+        bg.add(replace);
+        bg.add(add);
+        bg.add(remove);
+
+        JCheckBox caseSensitive = new JCheckBox(tr("case sensitive"), initialValues.caseSensitive);
+
+        JPanel p = new JPanel(new GridBagLayout());
+        p.add(label, GBC.eop());
+        p.add(input, GBC.eop().fill(GBC.HORIZONTAL));
+        p.add(replace, GBC.eol());
+        p.add(add, GBC.eol());
+        p.add(remove, GBC.eop());
+        p.add(caseSensitive, GBC.eol());
+        JOptionPane pane = new JOptionPane(p, JOptionPane.INFORMATION_MESSAGE, JOptionPane.OK_CANCEL_OPTION, null) {
+            @Override
+            public void selectInitialValue() {
+                input.requestFocusInWindow();
+                input.selectAll();
+            }
+        };
+        pane.createDialog(Main.parent, tr("Search")).setVisible(true);
+        if (!Integer.valueOf(JOptionPane.OK_OPTION).equals(pane.getValue()))
+            return;
+        // User pressed OK - let's perform the search
+        SearchMode mode = replace.isSelected() ? SearchAction.SearchMode.replace
+                : (add.isSelected() ? SearchAction.SearchMode.add : SearchAction.SearchMode.remove);
+        SearchSetting setting = new SearchSetting(input.getText(), caseSensitive.isSelected(), mode);
+        searchWithHistory(setting);
+    }
+
+    /**
+     * Adds the search specified by the settings in <code>s</code> to the 
+     * search history and performs the search.
+     * 
+     * @param s
+     */
+    public static void searchWithHistory(SearchSetting s) {
+        searchHistory.addFirst(s);
+        while (searchHistory.size() > SEARCH_HISTORY_SIZE)
+            searchHistory.removeLast();
+        lastSearch = s;
+        search(s.text, s.mode, s.caseSensitive);
+    }
+
+    public static void searchWithoutHistory(SearchSetting s) {
+        lastSearch = s;
+        search(s.text, s.mode, s.caseSensitive);
+    }
+
+    public static void search(String search, SearchMode mode, boolean caseSensitive) {
+        if (search.startsWith("http://") || search.startsWith("ftp://") || search.startsWith("https://")
+                || search.startsWith("file:/")) {
+            SelectionWebsiteLoader loader = new SelectionWebsiteLoader(search, mode);
+            if (loader.url != null) {
+                Main.worker.execute(loader);
+                return;
+            }
+        }
+        try {
+            Collection<OsmPrimitive> sel = Main.ds.getSelected();
+            SearchCompiler.Match matcher = SearchCompiler.compile(search, caseSensitive);
+            int foundMatches = 0;
+            for (OsmPrimitive osm : Main.ds.allNonDeletedCompletePrimitives()) {
+                if (mode == SearchMode.replace) {
+                    if (matcher.match(osm)) {
+                        sel.add(osm);
+                        ++foundMatches;
+                    } else
+                        sel.remove(osm);
+                } else if (mode == SearchMode.add && !osm.selected && matcher.match(osm)) {
+                    sel.add(osm);
+                    ++foundMatches;
+                } else if (mode == SearchMode.remove && osm.selected && matcher.match(osm)) {
+                    sel.remove(osm);
+                    ++foundMatches;
+                }
+            }
+            Main.ds.setSelected(sel);
+            if (foundMatches == 0) {
+                String msg = null;
+                if (mode == SearchMode.replace)
+                    msg = tr("No match found for ''{0}''", search);
+                else if (mode == SearchMode.add)
+                    msg = tr("Nothing added to selection by searching for ''{0}''", search);
+                else if (mode == SearchMode.remove)
+                    msg = tr("Nothing removed from selection by searching for ''{0}''", search);
+                Main.map.statusLine.setHelpText(msg);
+                JOptionPane.showMessageDialog(Main.parent, msg);
+            } else
+                Main.map.statusLine.setHelpText(tr("Found {0} matches", foundMatches));
+        } catch (SearchCompiler.ParseError e) {
+            JOptionPane.showMessageDialog(Main.parent, e.getMessage());
+        }
+    }
+
+    public static class SearchSetting {
+        String text;
+        SearchMode mode;
+        boolean caseSensitive;
+
+        public SearchSetting(String text, boolean caseSensitive, SearchMode mode) {
+            super();
+            this.caseSensitive = caseSensitive;
+            this.mode = mode;
+            this.text = text;
+        }
+
+        @Override
+        public String toString() {
+            String cs = caseSensitive ? tr("CI") : tr("CS");
+            return "\"" + text + "\" (" + cs + ", " + mode + ")";
+        }
+
     }
 }
Index: /trunk/src/org/openstreetmap/josm/gui/dialogs/SelectionListDialog.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/dialogs/SelectionListDialog.java	(revision 966)
+++ /trunk/src/org/openstreetmap/josm/gui/dialogs/SelectionListDialog.java	(revision 967)
@@ -2,9 +2,11 @@
 package org.openstreetmap.josm.gui.dialogs;
 
+import static org.openstreetmap.josm.tools.I18n.marktr;
 import static org.openstreetmap.josm.tools.I18n.tr;
-import static org.openstreetmap.josm.tools.I18n.marktr;
 
 import java.awt.BorderLayout;
+import java.awt.Color;
 import java.awt.GridLayout;
+import java.awt.Rectangle;
 import java.awt.event.ActionEvent;
 import java.awt.event.ActionListener;
@@ -12,18 +14,29 @@
 import java.awt.event.MouseAdapter;
 import java.awt.event.MouseEvent;
-import java.util.Arrays;
 import java.util.Collection;
 import java.util.LinkedList;
-
+import java.util.NoSuchElementException;
+
+import javax.swing.BorderFactory;
 import javax.swing.DefaultListModel;
 import javax.swing.JList;
+import javax.swing.JMenuItem;
 import javax.swing.JPanel;
+import javax.swing.JPopupMenu;
 import javax.swing.JScrollPane;
 import javax.swing.ListSelectionModel;
+import javax.swing.SwingConstants;
+import javax.swing.plaf.basic.BasicArrowButton;
 
 import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.actions.AutoScaleAction;
+import org.openstreetmap.josm.actions.search.SearchAction;
+import org.openstreetmap.josm.actions.search.SearchAction.SearchSetting;
 import org.openstreetmap.josm.data.SelectionChangedListener;
 import org.openstreetmap.josm.data.osm.DataSet;
+import org.openstreetmap.josm.data.osm.Node;
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
+import org.openstreetmap.josm.data.osm.Way;
+import org.openstreetmap.josm.data.osm.visitor.BoundingXYVisitor;
 import org.openstreetmap.josm.gui.OsmPrimitivRenderer;
 import org.openstreetmap.josm.gui.SideButton;
@@ -38,80 +51,272 @@
 public class SelectionListDialog extends ToggleDialog implements SelectionChangedListener {
 
-	/**
-	 * The selection's list data.
-	 */
-	private final DefaultListModel list = new DefaultListModel();
-	/**
-	 * The display list.
-	 */
-	private JList displaylist = new JList(list);
-
-	public SelectionListDialog() {
-		super(tr("Current Selection"), "selectionlist", tr("Open a selection list window."), KeyEvent.VK_T, 150);
-		displaylist.setCellRenderer(new OsmPrimitivRenderer());
-		displaylist.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
-		displaylist.addMouseListener(new MouseAdapter(){
-			@Override public void mouseClicked(MouseEvent e) {
-				if (e.getClickCount() < 2)
-					return;
-				updateMap();
-			}
-		});
-
-		add(new JScrollPane(displaylist), BorderLayout.CENTER);
-
-		JPanel buttonPanel = new JPanel(new GridLayout(1,2));
-
-		buttonPanel.add(new SideButton(marktr("Select"), "select", "SelectionList",
-		tr("Set the selected elements on the map to the selected items in the list above."), new ActionListener(){
-			public void actionPerformed(ActionEvent e) {
-				updateMap();
-			}
-		}));
-
-		buttonPanel.add(new SideButton(marktr("Reload"), "refresh", "SelectionList", tr("Refresh the selection list."), new ActionListener(){
-			public void actionPerformed(ActionEvent e) {
-				selectionChanged(Main.ds.getSelected());
-            }
-		}));
-
-		buttonPanel.add(new SideButton(marktr("Search"), "search", "SelectionList", tr("Search for objects."), Main.main.menu.search));
-
-		add(buttonPanel, BorderLayout.SOUTH);
-		selectionChanged(Main.ds.getSelected());
-
-		DataSet.selListeners.add(this);
-	}
-
-	@Override public void setVisible(boolean b) {
-		super.setVisible(b);
-		if (b)
-			selectionChanged(Main.ds.getSelected());
-	}
-
-
-	/**
-	 * Called when the selection in the dataset changed.
-	 * @param newSelection The new selection array.
-	 */
-	public void selectionChanged(Collection<? extends OsmPrimitive> newSelection) {
-		if (list == null || !isVisible())
-			return; // selection changed may be received in base class constructor before init
-		OsmPrimitive selArr[] = Main.ds.sort(newSelection);
-		list.setSize(selArr.length);
-		int i = 0;
-		for (OsmPrimitive osm : selArr)
-			list.setElementAt(osm, i++);
-	}
-
-	/**
-	 * Sets the selection of the map to the current selected items.
-	 */
-	public void updateMap() {
-		Collection<OsmPrimitive> sel = new LinkedList<OsmPrimitive>();
-		for (int i = 0; i < list.getSize(); ++i)
-			if (displaylist.isSelectedIndex(i))
-				sel.add((OsmPrimitive)list.get(i));
-		Main.ds.setSelected(sel);
-	}
+    private static final int SELECTION_HISTORY_SIZE = 10;
+
+    /**
+     * The selection's list data.
+     */
+    private final DefaultListModel list = new DefaultListModel();
+
+    private LinkedList<Collection<? extends OsmPrimitive>> selectionHistory;
+
+    /**
+     * The display list.
+     */
+    private JList displaylist = new JList(list);
+    private SideButton selectButton;
+    private SideButton searchButton;
+    private JPopupMenu popupMenu;
+    private JMenuItem zoomToElement;
+
+    /**
+     * If the selection changed event is triggered with newSelection equals 
+     * this element, the newSelection will not be added to the selection history 
+     */
+    private Collection<? extends OsmPrimitive> historyIgnoreSelection = null;
+
+    public SelectionListDialog() {
+        super(tr("Current Selection"), "selectionlist", tr("Open a selection list window."), KeyEvent.VK_T, 150);
+
+        selectionHistory = new LinkedList<Collection<? extends OsmPrimitive>>();
+        popupMenu = new JPopupMenu();
+        displaylist.setCellRenderer(new OsmPrimitivRenderer());
+        displaylist.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
+        displaylist.addMouseListener(new MouseAdapter() {
+            @Override
+            public void mouseClicked(MouseEvent e) {
+                if (e.getClickCount() == 2 && e.getButton() == MouseEvent.BUTTON1)
+                    updateMap();
+            }
+
+            @Override
+            public void mousePressed(MouseEvent e) {
+                showPopupMenu(e);
+            }
+
+            @Override
+            public void mouseReleased(MouseEvent e) {
+                showPopupMenu(e);
+            }
+
+        });
+
+        add(new JScrollPane(displaylist), BorderLayout.CENTER);
+
+        JPanel buttonPanel = new JPanel(new GridLayout(1, 2));
+
+        selectButton = new SideButton(marktr("Select"), "select", "SelectionList",
+                tr("Set the selected elements on the map to the selected items in the list above."),
+                new ActionListener() {
+                    public void actionPerformed(ActionEvent e) {
+                        updateMap();
+                    }
+                });
+        buttonPanel.add(selectButton);
+        BasicArrowButton selectionHistoryMenuButton = createArrowButton(selectButton);
+        selectionHistoryMenuButton.addActionListener(new ActionListener() {
+            public void actionPerformed(ActionEvent e) {
+                showSelectionHistoryMenu();
+            }
+        });
+        add(buttonPanel, BorderLayout.SOUTH);
+
+        zoomToElement = new JMenuItem(tr("Zoom to selected element(s)"));
+        zoomToElement.addActionListener(new ActionListener() {
+            public void actionPerformed(ActionEvent e) {
+                zoomToSelectedElement();
+            }
+        });
+
+        buttonPanel.add(new SideButton(marktr("Reload"), "refresh", "SelectionList", tr("Refresh the selection list."),
+                new ActionListener() {
+                    public void actionPerformed(ActionEvent e) {
+                        selectionChanged(Main.ds.getSelected());
+                    }
+                }));
+
+        searchButton = new SideButton(marktr("Search"), "search", "SelectionList", tr("Search for objects."),
+                Main.main.menu.search);
+        buttonPanel.add(searchButton);
+
+        BasicArrowButton searchHistoryMenuButton = createArrowButton(searchButton);
+        searchHistoryMenuButton.addActionListener(new ActionListener() {
+            public void actionPerformed(ActionEvent e) {
+                showSearchHistoryMenu();
+            }
+        });
+
+        popupMenu.add(zoomToElement);
+        JMenuItem zoomToSelection = new JMenuItem(tr("Zoom to selection"));
+        zoomToSelection.addActionListener(new ActionListener() {
+            public void actionPerformed(ActionEvent e) {
+                zoomToSelection();
+            }
+        });
+        popupMenu.add(zoomToSelection);
+
+        selectionChanged(Main.ds.getSelected());
+
+        DataSet.selListeners.add(this);
+    }
+
+    private BasicArrowButton createArrowButton(SideButton parentButton) {
+        BasicArrowButton arrowButton = new BasicArrowButton(SwingConstants.SOUTH, null, null, Color.BLACK, null);
+        arrowButton.setBorder(BorderFactory.createEmptyBorder());
+        //        selectionHistoryMenuButton.setContentAreaFilled(false);
+        //        selectionHistoryMenuButton.setOpaque(false);
+        //        selectionHistoryMenuButton.setBorderPainted(false);
+        //        selectionHistoryMenuButton.setBackground(null);
+        parentButton.setLayout(new BorderLayout());
+        parentButton.add(arrowButton, BorderLayout.EAST);
+        return arrowButton;
+    }
+
+    @Override
+    public void setVisible(boolean b) {
+        super.setVisible(b);
+        if (b)
+            selectionChanged(Main.ds.getSelected());
+    }
+
+    protected void showPopupMenu(MouseEvent e) {
+        if (e.isPopupTrigger()) {
+            zoomToElement.setVisible(displaylist.getSelectedIndex() >= 0);
+            popupMenu.show(e.getComponent(), e.getX(), e.getY());
+        }
+    }
+
+    public void zoomToSelection() {
+        new AutoScaleAction("selection").actionPerformed(null);
+    }
+
+    /**
+     * Zooms to the element(s) selected in {@link #displaylist} 
+     */
+    public void zoomToSelectedElement() {
+        BoundingXYVisitor box = new BoundingXYVisitor();
+        int[] selected = displaylist.getSelectedIndices();
+        if (selected.length == 0)
+            return;
+        for (int i = 0; i < selected.length; i++) {
+            Object o = list.get(selected[i]);
+            if (o instanceof OsmPrimitive)
+                ((OsmPrimitive) o).visit(box);
+        }
+        if (box.max == null || box.min == null)
+            return;
+        box.enlargeBoundingBox();
+        Main.map.mapView.recalculateCenterScale(box);
+    }
+
+    private void showSelectionHistoryMenu() {
+        if (selectionHistory.size() == 0)
+            return;
+        JPopupMenu historyMenu = new JPopupMenu();
+        for (Collection<? extends OsmPrimitive> sel : selectionHistory) {
+            SelectionMenuItem item = new SelectionMenuItem(sel);
+            historyMenu.add(item);
+        }
+        Rectangle r = selectButton.getBounds();
+        historyMenu.show(selectButton, r.x, r.y + r.height);
+    }
+
+    private void showSearchHistoryMenu() {
+        if (SearchAction.searchHistory.size() == 0)
+            return;
+        JPopupMenu historyMenu = new JPopupMenu();
+        for (SearchAction.SearchSetting s : SearchAction.searchHistory) {
+            SearchMenuItem item = new SearchMenuItem(s);
+            historyMenu.add(item);
+        }
+        Rectangle r = searchButton.getBounds();
+        historyMenu.show(searchButton, r.x, r.y + r.height);
+    }
+
+    /**
+     * Called when the selection in the dataset changed.
+     * @param newSelection The new selection array.
+     */
+    public void selectionChanged(Collection<? extends OsmPrimitive> newSelection) {
+        if (list == null || !isVisible())
+            return; // selection changed may be received in base class constructor before init
+        OsmPrimitive selArr[] = DataSet.sort(newSelection);
+        list.setSize(selArr.length);
+        int i = 0;
+        for (OsmPrimitive osm : selArr)
+            list.setElementAt(osm, i++);
+        if (selectionHistory != null && newSelection.size() > 0 && !newSelection.equals(historyIgnoreSelection)) {
+            historyIgnoreSelection = null;
+            try {
+                // Check if the newSelection has already been added to the history 
+                Collection<? extends OsmPrimitive> first = selectionHistory.getFirst();
+                if (first.equals(newSelection))
+                    return;
+            } catch (NoSuchElementException e) {
+            }
+            selectionHistory.addFirst(newSelection);
+            while (selectionHistory.size() > SELECTION_HISTORY_SIZE)
+                selectionHistory.removeLast();
+        }
+    }
+
+    /**
+     * Sets the selection of the map to the current selected items.
+     */
+    public void updateMap() {
+        Collection<OsmPrimitive> sel = new LinkedList<OsmPrimitive>();
+        for (int i = 0; i < list.getSize(); ++i)
+            if (displaylist.isSelectedIndex(i))
+                sel.add((OsmPrimitive) list.get(i));
+        Main.ds.setSelected(sel);
+    }
+
+    /**
+     * A specialized {@link JMenuItem} for presenting one entry of the selection history
+     *   
+     * @author Jan Peter Stotz
+     */
+    protected class SelectionMenuItem extends JMenuItem implements ActionListener {
+        protected Collection<? extends OsmPrimitive> sel;
+
+        public SelectionMenuItem(Collection<? extends OsmPrimitive> sel) {
+            super();
+            this.sel = sel;
+            int ways = 0;
+            int nodes = 0;
+            for (OsmPrimitive o : sel) {
+                if (o instanceof Way)
+                    ways++;
+                else if (o instanceof Node)
+                    nodes++;
+            }
+            setText(String.format(tr("Selection: %d way(s) and %d node(s)"), new Object[] { ways, nodes }));
+            addActionListener(this);
+        }
+
+        public void actionPerformed(ActionEvent e) {
+            historyIgnoreSelection = sel;
+            Main.ds.setSelected(sel);
+        }
+
+    }
+
+    /**
+     * A specialized {@link JMenuItem} for presenting one entry of the search history
+     *   
+     * @author Jan Peter Stotz
+     */
+    protected class SearchMenuItem extends JMenuItem implements ActionListener {
+        protected SearchSetting s;
+
+        public SearchMenuItem(SearchSetting s) {
+            super(s.toString());
+            this.s = s;
+            addActionListener(this);
+        }
+
+        public void actionPerformed(ActionEvent e) {
+            SearchAction.searchWithoutHistory(s);
+        }
+
+    }
 }
