Index: trunk/src/org/openstreetmap/josm/actions/OverpassDownloadAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/OverpassDownloadAction.java	(revision 8743)
+++ trunk/src/org/openstreetmap/josm/actions/OverpassDownloadAction.java	(revision 8744)
@@ -8,6 +8,4 @@
 import java.awt.event.ActionEvent;
 import java.awt.event.KeyEvent;
-import java.io.UnsupportedEncodingException;
-import java.net.URLEncoder;
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -26,17 +24,14 @@
 import org.openstreetmap.josm.actions.downloadtasks.PostDownloadHandler;
 import org.openstreetmap.josm.data.Bounds;
-import org.openstreetmap.josm.data.DataSource;
-import org.openstreetmap.josm.data.osm.DataSet;
 import org.openstreetmap.josm.data.preferences.CollectionProperty;
 import org.openstreetmap.josm.data.preferences.StringProperty;
 import org.openstreetmap.josm.gui.HelpAwareOptionPane;
 import org.openstreetmap.josm.gui.download.DownloadDialog;
-import org.openstreetmap.josm.gui.progress.ProgressMonitor;
 import org.openstreetmap.josm.gui.util.GuiHelper;
 import org.openstreetmap.josm.gui.widgets.HistoryComboBox;
 import org.openstreetmap.josm.gui.widgets.JosmTextArea;
-import org.openstreetmap.josm.io.BoundingBoxDownloader;
-import org.openstreetmap.josm.io.OsmTransferException;
+import org.openstreetmap.josm.io.OverpassDownloadReader;
 import org.openstreetmap.josm.tools.GBC;
+import org.openstreetmap.josm.tools.OverpassTurboQueryWizard;
 import org.openstreetmap.josm.tools.Shortcut;
 import org.openstreetmap.josm.tools.Utils;
@@ -134,5 +129,5 @@
             pnl.add(overpassWizard, GBC.eol().fill(GBC.HORIZONTAL));
 
-            overpassQuery = new JosmTextArea("[timeout:15];", 8, 80);
+            overpassQuery = new JosmTextArea("", 8, 80);
             overpassQuery.setFont(GuiHelper.getMonospacedFont(overpassQuery));
             JScrollPane scrollPane = new JScrollPane(overpassQuery);
@@ -175,91 +170,3 @@
     }
 
-    static class OverpassDownloadReader extends BoundingBoxDownloader {
-
-        final String overpassServer;
-        final String overpassQuery;
-
-        public OverpassDownloadReader(Bounds downloadArea, String overpassServer, String overpassQuery) {
-            super(downloadArea);
-            this.overpassServer = overpassServer;
-            this.overpassQuery = overpassQuery.trim();
-        }
-
-        @Override
-        protected String getBaseUrl() {
-            return overpassServer;
-        }
-
-        @Override
-        protected String getRequestForBbox(double lon1, double lat1, double lon2, double lat2) {
-            if (overpassQuery.isEmpty())
-                return super.getRequestForBbox(lon1, lat1, lon2, lat2);
-            else {
-                String realQuery = completeOverpassQuery(overpassQuery);
-                try {
-                    return "interpreter?data=" + URLEncoder.encode(realQuery, "UTF-8")
-                            + "&bbox=" + lon1 + "," + lat1 + "," + lon2 + "," + lat2;
-                } catch (UnsupportedEncodingException e) {
-                    throw new IllegalStateException();
-                }
-            }
-        }
-
-        private String completeOverpassQuery(String query) {
-            int firstColon = query.indexOf(";");
-            if (firstColon == -1) {
-                return "[bbox];" + query;
-            }
-            int bboxPos = query.indexOf("[bbox");
-            if (bboxPos > -1 && bboxPos < firstColon) {
-                return query;
-            }
-
-            int bracketCount = 0;
-            int pos = 0;
-            for (; pos < firstColon; ++pos) {
-                if (query.charAt(pos) == '[')
-                    ++bracketCount;
-                else if (query.charAt(pos) == '[')
-                    --bracketCount;
-                else if (bracketCount == 0) {
-                    if (!Character.isWhitespace(query.charAt(pos)))
-                        break;
-                }
-            }
-
-            if (pos < firstColon) {
-                // We start with a statement, not with declarations
-                return "[bbox];" + query;
-            }
-
-            // We start with declarations. Add just one more declaration in this case.
-            return "[bbox]" + query;
-        }
-
-        @Override
-        public DataSet parseOsm(ProgressMonitor progressMonitor) throws OsmTransferException {
-
-            DataSet ds = super.parseOsm(progressMonitor);
-
-            // add bounds if necessary (note that Overpass API does not return bounds in the response XML)
-            if (ds != null && ds.dataSources.isEmpty()) {
-                if (crosses180th) {
-                    Bounds bounds = new Bounds(lat1, lon1, lat2, 180.0);
-                    DataSource src = new DataSource(bounds, getBaseUrl());
-                    ds.dataSources.add(src);
-
-                    bounds = new Bounds(lat1, -180.0, lat2, lon2);
-                    src = new DataSource(bounds, getBaseUrl());
-                    ds.dataSources.add(src);
-                } else {
-                    Bounds bounds = new Bounds(lat1, lon1, lat2, lon2);
-                    DataSource src = new DataSource(bounds, getBaseUrl());
-                    ds.dataSources.add(src);
-                }
-            }
-
-            return ds;
-        }
-    }
 }
Index: trunk/src/org/openstreetmap/josm/actions/OverpassTurboQueryWizard.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/OverpassTurboQueryWizard.java	(revision 8743)
+++ 	(revision )
@@ -1,83 +1,0 @@
-// License: GPL. For details, see LICENSE file.
-package org.openstreetmap.josm.actions;
-
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.io.Reader;
-import java.nio.charset.StandardCharsets;
-import java.util.regex.Pattern;
-
-import javax.script.Invocable;
-import javax.script.ScriptEngine;
-import javax.script.ScriptEngineManager;
-import javax.script.ScriptException;
-
-/**
- * Uses <a href="https://github.com/tyrasd/overpass-turbo/">Overpass Turbo</a> query wizard code
- * to build an Overpass QL from a {@link org.openstreetmap.josm.actions.search.SearchAction} like query.
- *
- * Requires a JavaScript {@link ScriptEngine}.
- * @since 8684
- */
-public final class OverpassTurboQueryWizard {
-
-    private static OverpassTurboQueryWizard instance;
-    private final ScriptEngine engine = new ScriptEngineManager().getEngineByName("JavaScript");
-
-    /**
-     * An exception to indicate a failed parse.
-     */
-    public static class ParseException extends RuntimeException {
-    }
-
-    /**
-     * Replies the unique instance of this class.
-     *
-     * @return the unique instance of this class
-     */
-    public static synchronized OverpassTurboQueryWizard getInstance() {
-        if (instance == null) {
-            instance = new OverpassTurboQueryWizard();
-        }
-        return instance;
-    }
-
-    private OverpassTurboQueryWizard() {
-        // overpass-turbo is MIT Licensed
-
-        try (final Reader reader = new InputStreamReader(
-                getClass().getResourceAsStream("/data/overpass-turbo-ffs.js"), StandardCharsets.UTF_8)) {
-            //engine.eval("var turbo = {ffs: {noPresets: true}};");
-            engine.eval("var console = {log: function(){}};");
-            engine.eval(reader);
-            engine.eval("var construct_query = turbo.ffs().construct_query;");
-        } catch (ScriptException | IOException ex) {
-            throw new RuntimeException("Failed to initialize OverpassTurboQueryWizard", ex);
-        }
-    }
-
-    /**
-     * Builds an Overpass QL from a {@link org.openstreetmap.josm.actions.search.SearchAction} like query.
-     * @param search the {@link org.openstreetmap.josm.actions.search.SearchAction} like query
-     * @return an Overpass QL query
-     * @throws ParseException when the parsing fails
-     */
-    public String constructQuery(String search) throws ParseException {
-        try {
-            final Object result = ((Invocable) engine).invokeFunction("construct_query", search);
-            if (result == Boolean.FALSE) {
-                throw new ParseException();
-            }
-            String query = (String) result;
-            query = Pattern.compile("^.*\\[out:json\\]", Pattern.DOTALL).matcher(query).replaceFirst("");
-            query = Pattern.compile("^out.*", Pattern.MULTILINE).matcher(query).replaceAll("out meta;");
-            query = query.replace("({{bbox}})", "");
-            return query;
-        } catch (NoSuchMethodException e) {
-            throw new IllegalStateException();
-        } catch (ScriptException e) {
-            throw new RuntimeException("Failed to execute OverpassTurboQueryWizard", e);
-        }
-    }
-
-}
Index: trunk/src/org/openstreetmap/josm/io/OverpassDownloadReader.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/OverpassDownloadReader.java	(revision 8744)
+++ trunk/src/org/openstreetmap/josm/io/OverpassDownloadReader.java	(revision 8744)
@@ -0,0 +1,104 @@
+package org.openstreetmap.josm.io;
+
+import org.openstreetmap.josm.data.Bounds;
+import org.openstreetmap.josm.data.DataSource;
+import org.openstreetmap.josm.data.osm.DataSet;
+import org.openstreetmap.josm.gui.progress.ProgressMonitor;
+import org.openstreetmap.josm.tools.Utils;
+
+/**
+ * Read content from an Overpass server.
+ *
+ * @since 8744
+ */
+public class OverpassDownloadReader extends BoundingBoxDownloader {
+
+    final String overpassServer;
+    final String overpassQuery;
+
+    /**
+     * Constructs a new {@code OverpassDownloadReader}.
+     *
+     * @param downloadArea   The area to download
+     * @param overpassServer The Overpass server to use
+     * @param overpassQuery  The Overpass query
+     */
+    public OverpassDownloadReader(Bounds downloadArea, String overpassServer, String overpassQuery) {
+        super(downloadArea);
+        this.overpassServer = overpassServer;
+        this.overpassQuery = overpassQuery.trim();
+    }
+
+    @Override
+    protected String getBaseUrl() {
+        return overpassServer;
+    }
+
+    @Override
+    protected String getRequestForBbox(double lon1, double lat1, double lon2, double lat2) {
+        if (overpassQuery.isEmpty())
+            return super.getRequestForBbox(lon1, lat1, lon2, lat2);
+        else {
+            String realQuery = completeOverpassQuery(overpassQuery);
+            return "interpreter?data=" + Utils.encodeUrl(realQuery)
+                    + "&bbox=" + lon1 + "," + lat1 + "," + lon2 + "," + lat2;
+        }
+    }
+
+    private String completeOverpassQuery(String query) {
+        int firstColon = query.indexOf(";");
+        if (firstColon == -1) {
+            return "[bbox];" + query;
+        }
+        int bboxPos = query.indexOf("[bbox");
+        if (bboxPos > -1 && bboxPos < firstColon) {
+            return query;
+        }
+
+        int bracketCount = 0;
+        int pos = 0;
+        for (; pos < firstColon; ++pos) {
+            if (query.charAt(pos) == '[')
+                ++bracketCount;
+            else if (query.charAt(pos) == '[')
+                --bracketCount;
+            else if (bracketCount == 0) {
+                if (!Character.isWhitespace(query.charAt(pos)))
+                    break;
+            }
+        }
+
+        if (pos < firstColon) {
+            // We start with a statement, not with declarations
+            return "[bbox];" + query;
+        }
+
+        // We start with declarations. Add just one more declaration in this case.
+        return "[bbox]" + query;
+    }
+
+    @Override
+    public DataSet parseOsm(ProgressMonitor progressMonitor) throws OsmTransferException {
+
+        DataSet ds = super.parseOsm(progressMonitor);
+
+        // add bounds if necessary (note that Overpass API does not return bounds in the response XML)
+        if (ds != null && ds.dataSources.isEmpty()) {
+            if (crosses180th) {
+                Bounds bounds = new Bounds(lat1, lon1, lat2, 180.0);
+                DataSource src = new DataSource(bounds, getBaseUrl());
+                ds.dataSources.add(src);
+
+                bounds = new Bounds(lat1, -180.0, lat2, lon2);
+                src = new DataSource(bounds, getBaseUrl());
+                ds.dataSources.add(src);
+            } else {
+                Bounds bounds = new Bounds(lat1, lon1, lat2, lon2);
+                DataSource src = new DataSource(bounds, getBaseUrl());
+                ds.dataSources.add(src);
+            }
+        }
+
+        return ds;
+    }
+}
Index: trunk/src/org/openstreetmap/josm/tools/OverpassTurboQueryWizard.java
===================================================================
--- trunk/src/org/openstreetmap/josm/tools/OverpassTurboQueryWizard.java	(revision 8744)
+++ trunk/src/org/openstreetmap/josm/tools/OverpassTurboQueryWizard.java	(revision 8744)
@@ -0,0 +1,83 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.tools;
+
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.nio.charset.StandardCharsets;
+import java.util.regex.Pattern;
+
+import javax.script.Invocable;
+import javax.script.ScriptEngine;
+import javax.script.ScriptEngineManager;
+import javax.script.ScriptException;
+
+/**
+ * Uses <a href="https://github.com/tyrasd/overpass-turbo/">Overpass Turbo</a> query wizard code
+ * to build an Overpass QL from a {@link org.openstreetmap.josm.actions.search.SearchAction} like query.
+ *
+ * Requires a JavaScript {@link ScriptEngine}.
+ * @since 8744
+ */
+public final class OverpassTurboQueryWizard {
+
+    private static OverpassTurboQueryWizard instance;
+    private final ScriptEngine engine = new ScriptEngineManager().getEngineByName("JavaScript");
+
+    /**
+     * An exception to indicate a failed parse.
+     */
+    public static class ParseException extends RuntimeException {
+    }
+
+    /**
+     * Replies the unique instance of this class.
+     *
+     * @return the unique instance of this class
+     */
+    public static synchronized OverpassTurboQueryWizard getInstance() {
+        if (instance == null) {
+            instance = new OverpassTurboQueryWizard();
+        }
+        return instance;
+    }
+
+    private OverpassTurboQueryWizard() {
+        // overpass-turbo is MIT Licensed
+
+        try (final Reader reader = new InputStreamReader(
+                getClass().getResourceAsStream("/data/overpass-turbo-ffs.js"), StandardCharsets.UTF_8)) {
+            //engine.eval("var turbo = {ffs: {noPresets: true}};");
+            engine.eval("var console = {log: function(){}};");
+            engine.eval(reader);
+            engine.eval("var construct_query = turbo.ffs().construct_query;");
+        } catch (ScriptException | IOException ex) {
+            throw new RuntimeException("Failed to initialize OverpassTurboQueryWizard", ex);
+        }
+    }
+
+    /**
+     * Builds an Overpass QL from a {@link org.openstreetmap.josm.actions.search.SearchAction} like query.
+     * @param search the {@link org.openstreetmap.josm.actions.search.SearchAction} like query
+     * @return an Overpass QL query
+     * @throws ParseException when the parsing fails
+     */
+    public String constructQuery(String search) throws ParseException {
+        try {
+            final Object result = ((Invocable) engine).invokeFunction("construct_query", search);
+            if (result == Boolean.FALSE) {
+                throw new ParseException();
+            }
+            String query = (String) result;
+            query = Pattern.compile("^.*\\[out:json\\]", Pattern.DOTALL).matcher(query).replaceFirst("");
+            query = Pattern.compile("^out.*", Pattern.MULTILINE).matcher(query).replaceAll("out meta;");
+            query = query.replace("({{bbox}})", "");
+            return query;
+        } catch (NoSuchMethodException e) {
+            throw new IllegalStateException();
+        } catch (ScriptException e) {
+            throw new RuntimeException("Failed to execute OverpassTurboQueryWizard", e);
+        }
+    }
+
+}
