Index: trunk/src/org/openstreetmap/josm/actions/OverpassDownloadAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/OverpassDownloadAction.java	(revision 8753)
+++ trunk/src/org/openstreetmap/josm/actions/OverpassDownloadAction.java	(revision 8756)
@@ -5,18 +5,29 @@
 import static org.openstreetmap.josm.tools.I18n.tr;
 
+import java.awt.BorderLayout;
 import java.awt.Component;
+import java.awt.GridLayout;
+import java.awt.Rectangle;
 import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
 import java.awt.event.KeyEvent;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collection;
 import java.util.Collections;
+import java.util.Deque;
+import java.util.LinkedList;
 import java.util.concurrent.Future;
 
 import javax.swing.AbstractAction;
 import javax.swing.JButton;
+import javax.swing.JComponent;
 import javax.swing.JLabel;
+import javax.swing.JMenuItem;
 import javax.swing.JOptionPane;
 import javax.swing.JPanel;
+import javax.swing.JPopupMenu;
 import javax.swing.JScrollPane;
+import javax.swing.plaf.basic.BasicArrowButton;
 
 import org.openstreetmap.josm.Main;
@@ -25,4 +36,5 @@
 import org.openstreetmap.josm.data.Bounds;
 import org.openstreetmap.josm.data.preferences.CollectionProperty;
+import org.openstreetmap.josm.data.preferences.IntegerProperty;
 import org.openstreetmap.josm.data.preferences.StringProperty;
 import org.openstreetmap.josm.gui.HelpAwareOptionPane;
@@ -132,8 +144,18 @@
             overpassQuery.setFont(GuiHelper.getMonospacedFont(overpassQuery));
             JScrollPane scrollPane = new JScrollPane(overpassQuery);
+            final JPanel pane = new JPanel(new BorderLayout());
+            final BasicArrowButton arrowButton = new BasicArrowButton(BasicArrowButton.SOUTH);
+            arrowButton.addActionListener(new AbstractAction() {
+                @Override
+                public void actionPerformed(ActionEvent e) {
+                    OverpassQueryHistoryPopup.show(arrowButton, OverpassDownloadDialog.this);
+                }
+            });
+            pane.add(scrollPane, BorderLayout.CENTER);
+            pane.add(arrowButton, BorderLayout.EAST);
             pnl.add(new JLabel(tr("Overpass query: ")), GBC.std().insets(5, 5, 5, 5));
             GBC gbc = GBC.eol().fill(GBC.HORIZONTAL);
             gbc.ipady = 200;
-            pnl.add(scrollPane, gbc);
+            pnl.add(pane, gbc);
 
             overpassServer = new HistoryComboBox();
@@ -149,4 +171,8 @@
         public String getOverpassQuery() {
             return overpassQuery.getText();
+        }
+
+        public void setOverpassQuery(String text) {
+            overpassQuery.setText(text);
         }
 
@@ -166,6 +192,57 @@
             OVERPASS_SERVER_HISTORY.put(overpassServer.getHistory());
             OVERPASS_WIZARD_HISTORY.put(overpassWizard.getHistory());
-        }
-
+            OverpassQueryHistoryPopup.addToHistory(getOverpassQuery());
+        }
+
+    }
+
+    static class OverpassQueryHistoryPopup extends JPopupMenu {
+
+        static final CollectionProperty OVERPASS_QUERY_HISTORY = new CollectionProperty("download.overpass.query", new ArrayList<String>());
+        static final IntegerProperty OVERPASS_QUERY_HISTORY_SIZE = new IntegerProperty("download.overpass.query.size", 12);
+
+        OverpassQueryHistoryPopup(final OverpassDownloadDialog dialog) {
+            final Collection<String> history = OVERPASS_QUERY_HISTORY.get();
+            setLayout(new GridLayout((int) Math.ceil(history.size() / 2.), 2));
+            for (final String i : history) {
+                add(new OverpassQueryHistoryItem(i, dialog));
+            }
+        }
+
+        static void show(final JComponent parent, final OverpassDownloadDialog dialog) {
+            final OverpassQueryHistoryPopup menu = new OverpassQueryHistoryPopup(dialog);
+            final Rectangle r = parent.getBounds();
+            menu.show(parent.getParent(), r.x + r.width - (int) menu.getPreferredSize().getWidth(), r.y + r.height);
+        }
+
+        static void addToHistory(final String query) {
+            final Deque<String> history = new LinkedList<>(OVERPASS_QUERY_HISTORY.get());
+            if (!history.contains(query)) {
+                history.add(query);
+            }
+            while (history.size() > OVERPASS_QUERY_HISTORY_SIZE.get()) {
+                history.removeFirst();
+            }
+            OVERPASS_QUERY_HISTORY.put(history);
+        }
+    }
+
+    static class OverpassQueryHistoryItem extends JMenuItem implements ActionListener {
+
+        final String query;
+        final OverpassDownloadDialog dialog;
+
+        OverpassQueryHistoryItem(final String query, final OverpassDownloadDialog dialog) {
+            this.query = query;
+            this.dialog = dialog;
+            setText("<html><pre style='width:300px;'>" +
+                    Utils.escapeReservedCharactersHTML(Utils.restrictStringLines(query, 7)));
+            addActionListener(this);
+        }
+
+        @Override
+        public void actionPerformed(ActionEvent e) {
+            dialog.setOverpassQuery(query);
+        }
     }
 
Index: trunk/src/org/openstreetmap/josm/tools/ExceptionUtil.java
===================================================================
--- trunk/src/org/openstreetmap/josm/tools/ExceptionUtil.java	(revision 8753)
+++ trunk/src/org/openstreetmap/josm/tools/ExceptionUtil.java	(revision 8756)
@@ -236,5 +236,5 @@
                     "<html>Uploading to the server <strong>failed</strong> because your current<br>"
                     + "dataset violates a precondition.<br>" + "The error message is:<br>" + "{0}" + "</html>",
-                    escapeReservedCharactersHTML(e.getMessage()));
+                    Utils.escapeReservedCharactersHTML(e.getMessage()));
         }
     }
@@ -424,5 +424,5 @@
         }
         Main.error(e);
-        return escapeReservedCharactersHTML(msg);
+        return Utils.escapeReservedCharactersHTML(msg);
     }
 
@@ -691,5 +691,5 @@
                 + "<br>"
                 + "The error message is:<br>" + "{0}"
-                + "</html>", escapeReservedCharactersHTML(e.getMessage()));
+                + "</html>", Utils.escapeReservedCharactersHTML(e.getMessage()));
     }
 
@@ -709,11 +709,3 @@
     }
 
-    /**
-     * Replaces some HTML reserved characters (&lt;, &gt; and &amp;) by their equivalent entity (&amp;lt;, &amp;gt; and &amp;amp;);
-     * @param s The unescaped string
-     * @return The escaped string
-     */
-    public static String escapeReservedCharactersHTML(String s) {
-        return s == null ? "" : s.replace("&", "&amp;").replace("<", "&lt;").replace(">", "&gt;");
-    }
 }
Index: trunk/src/org/openstreetmap/josm/tools/Utils.java
===================================================================
--- trunk/src/org/openstreetmap/josm/tools/Utils.java	(revision 8753)
+++ trunk/src/org/openstreetmap/josm/tools/Utils.java	(revision 8756)
@@ -646,4 +646,13 @@
 
     /**
+     * Replaces some HTML reserved characters (&lt;, &gt; and &amp;) by their equivalent entity (&amp;lt;, &amp;gt; and &amp;amp;);
+     * @param s The unescaped string
+     * @return The escaped string
+     */
+    public static String escapeReservedCharactersHTML(String s) {
+        return s == null ? "" : s.replace("&", "&amp;").replace("<", "&lt;").replace(">", "&gt;");
+    }
+
+    /**
      * Represents a function that can be applied to objects of {@code A} and
      * returns objects of {@code B}.
@@ -1184,4 +1193,23 @@
         } else {
             return s;
+        }
+    }
+
+    /**
+     * If the string {@code s} is longer than {@code maxLines} lines, the string is cut and a "..." line is appended.
+     * @param s String to shorten
+     * @param maxLines maximum number of lines to keep (including including the "..." line)
+     * @return the shortened string
+     */
+    public static String restrictStringLines(String s, int maxLines) {
+        if (s == null) {
+            return null;
+        } else {
+            final List<String> lines = Arrays.asList(s.split("\\n"));
+            if (lines.size() > maxLines) {
+                return join("\n", lines.subList(0, maxLines - 1)) + "\n" + "...";
+            } else {
+                return s;
+            }
         }
     }
