Index: /trunk/src/org/openstreetmap/josm/gui/dialogs/SearchDialog.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/dialogs/SearchDialog.java	(revision 16353)
+++ /trunk/src/org/openstreetmap/josm/gui/dialogs/SearchDialog.java	(revision 16354)
@@ -5,4 +5,5 @@
 import static org.openstreetmap.josm.tools.I18n.trc;
 
+import java.awt.Component;
 import java.awt.Cursor;
 import java.awt.Dimension;
@@ -54,5 +55,5 @@
     private final SearchSetting searchSettings;
 
-    private final HistoryComboBox hcbSearchString = new HistoryComboBox();
+    protected final HistoryComboBox hcbSearchString = new HistoryComboBox();
 
     private JCheckBox addOnToolbar;
@@ -76,15 +77,38 @@
      */
     public SearchDialog(SearchSetting initialValues, List<String> searchExpressionHistory, boolean expertMode) {
-        super(MainApplication.getMainFrame(),
+        this(initialValues, searchExpressionHistory, new PanelOptions(expertMode, false), MainApplication.getMainFrame(),
                 initialValues instanceof Filter ? tr("Filter") : tr("Search"),
                 initialValues instanceof Filter ? tr("Submit filter") : tr("Search"),
                 tr("Cancel"));
-        this.searchSettings = new SearchSetting(initialValues);
         setButtonIcons("dialogs/search", "cancel");
         configureContextsensitiveHelp("/Action/Search", true /* show help button */);
-        setContent(buildPanel(searchExpressionHistory, expertMode));
-    }
-
-    private JPanel buildPanel(List<String> searchExpressionHistory, boolean expertMode) {
+    }
+
+    protected SearchDialog(SearchSetting initialValues, List<String> searchExpressionHistory, PanelOptions options,
+                           Component mainFrame, String title, String... buttonTexts) {
+        super(mainFrame, title, buttonTexts);
+        this.searchSettings = new SearchSetting(initialValues);
+        setContent(buildPanel(searchExpressionHistory, options));
+    }
+
+    /**
+     * Determines which parts of the search dialog will be shown
+     */
+    protected static class PanelOptions {
+        private final boolean expertMode;
+        private final boolean overpassQuery;
+
+        /**
+         * Constructs new options which determine which parts of the search dialog will be shown
+         * @param expertMode whether export mode is enabled
+         * @param overpassQuery whether the panel shall be adapted for Overpass query
+         */
+        public PanelOptions(boolean expertMode, boolean overpassQuery) {
+            this.expertMode = expertMode;
+            this.overpassQuery = overpassQuery;
+        }
+    }
+
+    private JPanel buildPanel(List<String> searchExpressionHistory, PanelOptions options) {
 
         // prepare the combo box with the search expressions
@@ -140,5 +164,5 @@
         left.add(additionalSettings, GBC.eol().fill(GBC.BOTH));
 
-        if (expertMode) {
+        if (options.expertMode) {
             additionalSettings.add(allElements, GBC.eol());
             additionalSettings.add(addOnToolbar, GBC.eop());
@@ -153,5 +177,5 @@
         }
 
-        JPanel right = buildHintsSection(hcbSearchString, expertMode);
+        JPanel right = buildHintsSection(hcbSearchString, options);
         JPanel top = new JPanel(new GridBagLayout());
         top.add(label, GBC.std().insets(0, 0, 5, 0));
@@ -214,7 +238,11 @@
         JPanel p = new JPanel(new GridBagLayout());
         p.add(top, GBC.eol().fill(GBC.HORIZONTAL).insets(5, 5, 5, 0));
-        p.add(left, GBC.std().anchor(GBC.NORTH).insets(5, 10, 10, 0).fill(GBC.VERTICAL));
+        if (!options.overpassQuery) {
+            p.add(left, GBC.std().anchor(GBC.NORTH).insets(5, 10, 10, 0).fill(GBC.VERTICAL));
+        }
         p.add(right, GBC.std().fill(GBC.BOTH).insets(0, 10, 0, 0));
-        p.add(selector, GBC.eol().fill(GBC.BOTH).insets(0, 10, 0, 0));
+        if (!options.overpassQuery) {
+            p.add(selector, GBC.eol().fill(GBC.BOTH).insets(0, 10, 0, 0));
+        }
 
         return p;
@@ -279,5 +307,5 @@
     }
 
-    private static JPanel buildHintsSection(HistoryComboBox hcbSearchString, boolean expertMode) {
+    private static JPanel buildHintsSection(HistoryComboBox hcbSearchString, PanelOptions options) {
         JPanel hintPanel = new JPanel(new GridBagLayout());
         hintPanel.setBorder(BorderFactory.createTitledBorder(tr("Hints")));
@@ -317,13 +345,17 @@
                 GBC.eol());
 
-        if (expertMode) {
-            hintPanel.add(new SearchKeywordRow(hcbSearchString)
+        SearchKeywordRow objectHints = new SearchKeywordRow(hcbSearchString)
                 .addTitle(tr("objects"))
                 .addKeyword("type:node", "type:node ", tr("all nodes"))
                 .addKeyword("type:way", "type:way ", tr("all ways"))
-                .addKeyword("type:relation", "type:relation ", tr("all relations"))
+                .addKeyword("type:relation", "type:relation ", tr("all relations"));
+        if (options.expertMode) {
+            objectHints
                 .addKeyword("closed", "closed ", tr("all closed ways"))
-                .addKeyword("untagged", "untagged ", tr("object without useful tags")),
-                GBC.eol());
+                .addKeyword("untagged", "untagged ", tr("object without useful tags"));
+        }
+        hintPanel.add(objectHints, GBC.eol());
+
+        if (options.expertMode) {
             hintPanel.add(new SearchKeywordRow(hcbSearchString)
                     .addKeyword("preset:\"Annotation/Address\"", "preset:\"Annotation/Address\"",
@@ -381,4 +413,17 @@
                 .addKeyword("allindownloadedarea", "allindownloadedarea ",
                         tr("objects (and all its way nodes / relation members) in downloaded area")),
+                GBC.eol());
+        }
+        if (options.overpassQuery) {
+            hintPanel.add(new SearchKeywordRow(hcbSearchString)
+                .addTitle(tr("location"))
+                .addKeyword("<i>key=value in <u>location</u></i>", null,
+                        tr("{0} all objects having {1} as attribute are downloaded.", "<i>tourism=hotel in Berlin</i> -", "'tourism=hotel'"))
+                .addKeyword("<i>key=value around <u>location</u></i>", null,
+                        tr("{0} all object with the corresponding key/value pair located around Berlin. Note, the default value for radius " +
+                                "is set to 1000m, but it can be changed in the generated query.", "<i>tourism=hotel around Berlin</i> -"))
+                .addKeyword("<i>key=value in bbox</i>", null,
+                        tr("{0} all objects within the current selection that have {1} as attribute.", "<i>tourism=hotel in bbox</i> -",
+                                "'tourism=hotel'")),
                 GBC.eol());
         }
Index: /trunk/src/org/openstreetmap/josm/gui/download/OverpassQueryWizardDialog.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/download/OverpassQueryWizardDialog.java	(revision 16353)
+++ /trunk/src/org/openstreetmap/josm/gui/download/OverpassQueryWizardDialog.java	(revision 16354)
@@ -4,29 +4,16 @@
 import static org.openstreetmap.josm.tools.I18n.tr;
 
-import java.awt.GridBagLayout;
 import java.awt.event.ActionEvent;
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.Collections;
-import java.util.List;
 import java.util.Optional;
 
-import javax.swing.JEditorPane;
-import javax.swing.JLabel;
 import javax.swing.JOptionPane;
-import javax.swing.JPanel;
-import javax.swing.JScrollPane;
-import javax.swing.event.HyperlinkEvent;
-import javax.swing.text.JTextComponent;
 
+import org.openstreetmap.josm.data.osm.search.SearchSetting;
 import org.openstreetmap.josm.data.preferences.ListProperty;
-import org.openstreetmap.josm.gui.ExtendedDialog;
+import org.openstreetmap.josm.gui.dialogs.SearchDialog;
 import org.openstreetmap.josm.gui.download.overpass.OverpassWizardRegistration.OverpassWizardCallbacks;
-import org.openstreetmap.josm.gui.util.GuiHelper;
-import org.openstreetmap.josm.gui.widgets.HistoryComboBox;
-import org.openstreetmap.josm.spi.preferences.Config;
-import org.openstreetmap.josm.tools.GBC;
 import org.openstreetmap.josm.tools.Logging;
-import org.openstreetmap.josm.tools.OpenBrowser;
 import org.openstreetmap.josm.tools.OverpassTurboQueryWizard;
 import org.openstreetmap.josm.tools.UncheckedParseException;
@@ -38,18 +25,9 @@
  * @since 12652: Moved here
  */
-public final class OverpassQueryWizardDialog extends ExtendedDialog {
+public final class OverpassQueryWizardDialog extends SearchDialog {
 
-    private final HistoryComboBox queryWizard;
-    private static final String HEADLINE_START = "<h3>";
-    private static final String HEADLINE_END = "</h3>";
-    private static final String TR_START = "<tr>";
-    private static final String TR_END = "</tr>";
-    private static final String TD_START = "<td>";
-    private static final String TD_END = "</td>";
-    private static final String SPAN_START = "<span>";
-    private static final String SPAN_END = "</span>";
     private static final ListProperty OVERPASS_WIZARD_HISTORY =
             new ListProperty("download.overpass.wizard", new ArrayList<String>());
-    private final transient OverpassTurboQueryWizard overpassQueryBuilder;
+    private final OverpassWizardCallbacks callbacks;
 
     // dialog buttons
@@ -58,14 +36,4 @@
     private static final int CANCEL = 2;
 
-    private static final String DESCRIPTION_STYLE =
-            "<style type=\"text/css\">\n"
-            + "table { border-spacing: 0pt;}\n"
-            + "h3 {text-align: center; padding: 8px;}\n"
-            + "td {border: 1px solid #dddddd; text-align: left; padding: 8px;}\n"
-            + "#desc {width: 350px;}"
-            + "</style>\n";
-
-    private final OverpassWizardCallbacks dsPanel;
-
     /**
      * Create a new {@link OverpassQueryWizardDialog}
@@ -73,31 +41,11 @@
      */
     public OverpassQueryWizardDialog(OverpassWizardCallbacks callbacks) {
-        super(callbacks.getParent(), tr("Overpass Turbo Query Wizard"),
+        super(new SearchSetting(), OVERPASS_WIZARD_HISTORY.get(), new PanelOptions(false, true), callbacks.getParent(),
+                tr("Overpass Turbo Query Wizard"),
                 tr("Build query"), tr("Build query and execute"), tr("Cancel"));
-        this.dsPanel = callbacks;
-
-        this.queryWizard = new HistoryComboBox();
-        this.overpassQueryBuilder = OverpassTurboQueryWizard.getInstance();
-
-        JPanel panel = new JPanel(new GridBagLayout());
-
-        JLabel searchLabel = new JLabel(tr("Search:"));
-        JTextComponent descPane = buildDescriptionSection();
-        JScrollPane scroll = GuiHelper.embedInVerticalScrollPane(descPane);
-        scroll.getVerticalScrollBar().setUnitIncrement(10); // make scrolling smooth
-
-        panel.add(searchLabel, GBC.std().insets(0, 0, 0, 20).anchor(GBC.SOUTHEAST));
-        panel.add(queryWizard, GBC.eol().insets(0, 0, 0, 15).fill(GBC.HORIZONTAL).anchor(GBC.SOUTH));
-        panel.add(scroll, GBC.eol().fill(GBC.BOTH).anchor(GBC.CENTER));
-
-        List<String> items = new ArrayList<>(OVERPASS_WIZARD_HISTORY.get());
-        if (!items.isEmpty()) {
-            queryWizard.setText(items.get(0));
-        }
-        queryWizard.setPossibleItemsTopDown(items);
-
+        this.callbacks = callbacks;
+        setButtonIcons("ok", "download-overpass", "cancel");
         setCancelButton(CANCEL + 1);
         setDefaultButton(BUILD_AN_EXECUTE_QUERY + 1);
-        setContent(panel, false);
     }
 
@@ -129,6 +77,6 @@
      */
     private void saveHistory() {
-        queryWizard.addCurrentItemToHistory();
-        OVERPASS_WIZARD_HISTORY.put(queryWizard.getHistory());
+        hcbSearchString.addCurrentItemToHistory();
+        OVERPASS_WIZARD_HISTORY.put(hcbSearchString.getHistory());
     }
 
@@ -143,9 +91,9 @@
     private Optional<String> tryParseSearchTerm(String searchTerm) {
         try {
-            return Optional.of(overpassQueryBuilder.constructQuery(searchTerm));
+            return Optional.of(OverpassTurboQueryWizard.getInstance().constructQuery(searchTerm));
         } catch (UncheckedParseException | IllegalStateException ex) {
             Logging.error(ex);
             JOptionPane.showMessageDialog(
-                    dsPanel.getParent(),
+                    callbacks.getParent(),
                     "<html>" +
                      tr("The Overpass wizard could not parse the following query:") +
@@ -160,93 +108,13 @@
 
     /**
-     * Builds an Overpass query out from {@link OverpassQueryWizardDialog#queryWizard} contents.
+     * Builds an Overpass query out from {@link SearchSetting} contents.
      * @return {@code true} if the query successfully built, {@code false} otherwise.
      */
     private boolean buildQueryAction() {
-        final String wizardSearchTerm = this.queryWizard.getText();
+        final String wizardSearchTerm = getSearchSettings().text;
 
         Optional<String> q = this.tryParseSearchTerm(wizardSearchTerm);
-        q.ifPresent(dsPanel::submitWizardResult);
+        q.ifPresent(callbacks::submitWizardResult);
         return q.isPresent();
     }
-
-    private static JTextComponent buildDescriptionSection() {
-        JEditorPane descriptionSection = new JEditorPane("text/html", getDescriptionContent());
-        descriptionSection.setEditable(false);
-        descriptionSection.addHyperlinkListener(e -> {
-            if (HyperlinkEvent.EventType.ACTIVATED.equals(e.getEventType())) {
-                OpenBrowser.displayUrl(e.getURL().toString());
-            }
-        });
-
-        return descriptionSection;
-    }
-
-    private static String getDescriptionContent() {
-        return new StringBuilder("<html>")
-                .append(DESCRIPTION_STYLE)
-                .append("<body>")
-                .append(HEADLINE_START)
-                .append(tr("Query Wizard"))
-                .append(HEADLINE_END)
-                .append("<p>")
-                .append(tr("Allows you to interact with <i>Overpass API</i> by writing declarative, human-readable terms."))
-                .append(tr("The <i>Query Wizard</i> tool will transform those to a valid overpass query."))
-                .append(tr("For more detailed description see "))
-                .append(tr("<a href=\"{0}\">OSM Wiki</a>.", Config.getUrls().getOSMWebsite() + "/wiki/Overpass_turbo/Wizard"))
-                .append("</p>")
-                .append(HEADLINE_START).append(tr("Hints")).append(HEADLINE_END)
-                .append("<table>").append(TR_START).append(TD_START)
-                .append(Utils.joinAsHtmlUnorderedList(Arrays.asList("<i>type:node</i>", "<i>type:relation</i>", "<i>type:way</i>")))
-                .append(TD_END).append(TD_START)
-                .append(SPAN_START).append(tr("Download objects of a certain type.")).append(SPAN_END)
-                .append(TD_END).append(TR_END)
-                .append(TR_START).append(TD_START)
-                .append(Utils.joinAsHtmlUnorderedList(
-                        Arrays.asList("<i>key=value in <u>location</u></i>",
-                                "<i>key=value around <u>location</u></i>",
-                                "<i>key=value in bbox</i>")))
-                .append(TD_END).append(TD_START)
-                .append(tr("Download object by specifying a specific location. For example,"))
-                .append(Utils.joinAsHtmlUnorderedList(Arrays.asList(
-                        tr("{0} all objects having {1} as attribute are downloaded.", "<i>tourism=hotel in Berlin</i> -", "'tourism=hotel'"),
-                        tr("{0} all object with the corresponding key/value pair located around Berlin. Note, the default value for radius "+
-                                "is set to 1000m, but it can be changed in the generated query.", "<i>tourism=hotel around Berlin</i> -"),
-                        tr("{0} all objects within the current selection that have {1} as attribute.", "<i>tourism=hotel in bbox</i> -",
-                                "'tourism=hotel'"))))
-                .append(SPAN_START)
-                .append(tr("Instead of <i>location</i> any valid place name can be used like address, city, etc."))
-                .append(SPAN_END)
-                .append(TD_END).append(TR_END)
-                .append(TR_START).append(TD_START)
-                .append(Utils.joinAsHtmlUnorderedList(Arrays.asList("<i>key=value</i>", "<i>key=*</i>", "<i>key~regex</i>",
-                        "<i>-key=value</i>", "<i>-key~regex</i>", "<i>key=\"combined value\"</i>")))
-                .append(TD_END).append(TD_START)
-                .append(tr("<span>Download objects that have some concrete key/value pair, only the key with any contents for the value, " +
-                        "the value matching some regular expression. \"Not equal\" operators are supported as well.</span>"))
-                .append(TD_END).append(TR_END)
-                .append(TR_START).append(TD_START)
-                .append(Utils.joinAsHtmlUnorderedList(Arrays.asList(
-                        tr("<i>expression1 {0} expression2</i>", "or"),
-                        tr("<i>expression1 {0} expression2</i>", "and"))))
-                .append(TD_END).append(TD_START)
-                .append(SPAN_START)
-                .append(tr("Basic logical operators can be used to create more sophisticated queries. Instead of \"or\" - \"|\", \"||\" " +
-                        "can be used, and instead of \"and\" - \"&\", \"&&\"."))
-                .append(SPAN_END)
-                .append(TD_END).append(TR_END)
-                .append(TR_START).append(TD_START)
-                .append(Utils.joinAsHtmlUnorderedList(Arrays.asList(
-                        tr("<i>ref ~ \"[0-9]+\"</i>"), tr("<i>name ~ /postnord/i in sweden</i>"))))
-                .append(TD_END).append(TD_START)
-                .append(SPAN_START)
-                .append(tr("Regular expressions can be provided either as plain strings or with the regex notation. " +
-                        "The modifier \"i\" makes the match case-insensitive"))
-                .append(SPAN_END)
-                .append(TD_END).append(TR_END)
-                .append("</table>")
-                .append("</body>")
-                .append("</html>")
-                .toString();
-    }
 }
