Index: /trunk/src/org/openstreetmap/josm/actions/OverpassDownloadAction.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/actions/OverpassDownloadAction.java	(revision 9240)
+++ /trunk/src/org/openstreetmap/josm/actions/OverpassDownloadAction.java	(revision 9241)
@@ -60,4 +60,11 @@
 
     /**
+     * The {@link StringProperty property} of the currently selected Overpass server.
+     *
+     * @since 9241
+     */
+    public static final StringProperty OVERPASS_SERVER = new StringProperty("download.overpass.server", "http://overpass-api.de/api/");
+
+    /**
      * Constructs a new {@code OverpassDownloadAction}.
      */
@@ -121,5 +128,4 @@
         private JosmTextArea overpassQuery;
         private static OverpassDownloadDialog instance;
-        private static final StringProperty OVERPASS_SERVER = new StringProperty("download.overpass.server", "http://overpass-api.de/api/");
         private static final CollectionProperty OVERPASS_SERVER_HISTORY = new CollectionProperty("download.overpass.servers",
                 Arrays.asList("http://overpass-api.de/api/", "http://overpass.osm.rambler.ru/cgi/"));
Index: /trunk/src/org/openstreetmap/josm/actions/UpdateSelectionAction.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/actions/UpdateSelectionAction.java	(revision 9240)
+++ /trunk/src/org/openstreetmap/josm/actions/UpdateSelectionAction.java	(revision 9241)
@@ -39,5 +39,5 @@
      */
     public static void handlePrimitiveGoneException(long id, OsmPrimitiveType type) {
-        MultiFetchServerObjectReader reader = new MultiFetchServerObjectReader();
+        MultiFetchServerObjectReader reader = MultiFetchServerObjectReader.create();
         reader.append(getCurrentDataSet(), id, type);
         try {
Index: /trunk/src/org/openstreetmap/josm/actions/downloadtasks/DownloadReferrersTask.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/actions/downloadtasks/DownloadReferrersTask.java	(revision 9240)
+++ /trunk/src/org/openstreetmap/josm/actions/downloadtasks/DownloadReferrersTask.java	(revision 9241)
@@ -220,5 +220,5 @@
             nodes.removeAll(targetLayer.data.getNodes());
             if (!nodes.isEmpty()) {
-                reader = new MultiFetchServerObjectReader();
+                reader = MultiFetchServerObjectReader.create();
                 ((MultiFetchServerObjectReader) reader).append(nodes);
                 DataSet wayNodes = reader.parseOsm(progressMonitor.createSubTaskMonitor(1, false));
Index: /trunk/src/org/openstreetmap/josm/gui/dialogs/relation/DownloadRelationMemberTask.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/dialogs/relation/DownloadRelationMemberTask.java	(revision 9240)
+++ /trunk/src/org/openstreetmap/josm/gui/dialogs/relation/DownloadRelationMemberTask.java	(revision 9241)
@@ -117,5 +117,5 @@
             synchronized (this) {
                 if (canceled) return;
-                objectReader = new MultiFetchServerObjectReader();
+                objectReader = MultiFetchServerObjectReader.create();
             }
             objectReader.append(children);
Index: /trunk/src/org/openstreetmap/josm/gui/io/DownloadPrimitivesTask.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/io/DownloadPrimitivesTask.java	(revision 9240)
+++ /trunk/src/org/openstreetmap/josm/gui/io/DownloadPrimitivesTask.java	(revision 9241)
@@ -141,5 +141,5 @@
             synchronized (this) {
                 if (canceled) return;
-                multiObjectReader = new MultiFetchServerObjectReader();
+                multiObjectReader = MultiFetchServerObjectReader.create();
             }
             initMultiFetchReader(multiObjectReader);
Index: /trunk/src/org/openstreetmap/josm/gui/io/UpdatePrimitivesTask.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/io/UpdatePrimitivesTask.java	(revision 9240)
+++ /trunk/src/org/openstreetmap/josm/gui/io/UpdatePrimitivesTask.java	(revision 9241)
@@ -128,5 +128,5 @@
             synchronized (this) {
                 if (canceled) return;
-                multiObjectReader = new MultiFetchServerObjectReader();
+                multiObjectReader = MultiFetchServerObjectReader.create();
             }
             initMultiFetchReaderWithNodes(multiObjectReader);
Index: /trunk/src/org/openstreetmap/josm/io/MultiFetchOverpassObjectReader.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/io/MultiFetchOverpassObjectReader.java	(revision 9241)
+++ /trunk/src/org/openstreetmap/josm/io/MultiFetchOverpassObjectReader.java	(revision 9241)
@@ -0,0 +1,33 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.io;
+
+import org.openstreetmap.josm.actions.OverpassDownloadAction;
+import org.openstreetmap.josm.data.osm.OsmPrimitiveType;
+import org.openstreetmap.josm.tools.Utils;
+
+import java.util.Set;
+
+/**
+ * Retrieves a set of {@link org.openstreetmap.josm.data.osm.OsmPrimitive}s from an Overpass API server.
+ *
+ * @since 9241
+ */
+class MultiFetchOverpassObjectReader extends MultiFetchServerObjectReader {
+
+    @Override
+    protected String buildRequestString(final OsmPrimitiveType type, Set<Long> idPackage) {
+        final Utils.Function<Long, Object> toOverpassExpression = new Utils.Function<Long, Object>() {
+            @Override
+            public Object apply(Long x) {
+                return type.getAPIName() + "(" + x + ");>;";
+            }
+        };
+        final String query = "(" + Utils.join("", Utils.transform(idPackage, toOverpassExpression)) + ");out meta;";
+        return "interpreter?data=" + Utils.encodeUrl(query);
+    }
+
+    @Override
+    protected String getBaseUrl() {
+        return OverpassDownloadAction.OVERPASS_SERVER.get();
+    }
+}
Index: /trunk/src/org/openstreetmap/josm/io/MultiFetchServerObjectReader.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/io/MultiFetchServerObjectReader.java	(revision 9240)
+++ /trunk/src/org/openstreetmap/josm/io/MultiFetchServerObjectReader.java	(revision 9241)
@@ -10,4 +10,5 @@
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.Collections;
 import java.util.HashSet;
 import java.util.Iterator;
@@ -74,5 +75,5 @@
      * Constructs a {@code MultiFetchServerObjectReader}.
      */
-    public MultiFetchServerObjectReader() {
+    protected MultiFetchServerObjectReader() {
         nodes = new LinkedHashSet<>();
         ways = new LinkedHashSet<>();
@@ -80,4 +81,31 @@
         this.outputDataSet = new DataSet();
         this.missingPrimitives = new LinkedHashSet<>();
+    }
+
+    /**
+     * Creates a new instance of {@link MultiFetchServerObjectReader} or {@link MultiFetchOverpassObjectReader}
+     * depending on the {@code download.overpass.for-multi-fetch} preference.
+     *
+     * @return a new instance
+     * @since 9241
+     */
+    public static MultiFetchServerObjectReader create() {
+        return create(Main.pref.getBoolean("download.overpass.for-multi-fetch", false));
+    }
+
+    /**
+     * Creates a new instance of {@link MultiFetchServerObjectReader} or {@link MultiFetchOverpassObjectReader}
+     * depending on the {@code fromMirror} parameter.
+     *
+     * @param fromMirror {@code false} for {@link MultiFetchServerObjectReader}, {@code true} for {@link MultiFetchOverpassObjectReader}
+     * @return a new instance
+     * @since 9241
+     */
+    static MultiFetchServerObjectReader create(final boolean fromMirror) {
+        if (fromMirror) {
+            return new MultiFetchOverpassObjectReader();
+        } else {
+            return new MultiFetchServerObjectReader();
+        }
     }
 
@@ -240,33 +268,11 @@
      * @return the request string
      */
-    protected static String buildRequestString(OsmPrimitiveType type, Set<Long> idPackage) {
-        StringBuilder sb = new StringBuilder();
-        sb.append(type.getAPIName()).append("s?")
-        .append(type.getAPIName()).append("s=");
-
-        Iterator<Long> it = idPackage.iterator();
-        for (int i = 0; i < idPackage.size(); i++) {
-            sb.append(it.next());
-            if (i < idPackage.size()-1) {
-                sb.append(',');
-            }
-        }
-        return sb.toString();
-    }
-
-    /**
-     * builds the Multi Get request string for a single id and a given {@link OsmPrimitiveType}.
-     *
-     * @param type The primitive type. Must be one of {@link OsmPrimitiveType#NODE NODE}, {@link OsmPrimitiveType#WAY WAY},
-     * {@link OsmPrimitiveType#RELATION RELATION}
-     * @param id the id
-     * @return the request string
-     */
-    protected static String buildRequestString(OsmPrimitiveType type, long id) {
-        StringBuilder sb = new StringBuilder();
-        sb.append(type.getAPIName()).append("s?")
-        .append(type.getAPIName()).append("s=")
-        .append(id);
-        return sb.toString();
+    protected String buildRequestString(final OsmPrimitiveType type, Set<Long> idPackage) {
+        return type.getAPIName() + "s?" + type.getAPIName() + "s=" + Utils.join(",", idPackage);
+    }
+
+    @Override
+    protected String getBaseUrl() {
+        return super.getBaseUrl();
     }
 
@@ -304,5 +310,5 @@
     protected void fetchPrimitives(Set<Long> ids, OsmPrimitiveType type, ProgressMonitor progressMonitor) throws OsmTransferException {
         String msg = "";
-        String baseUrl = OsmApi.getOsmApi().getBaseUrl();
+        final String baseUrl = getBaseUrl();
         switch (type) {
             case NODE:     msg = tr("Fetching a package of nodes from ''{0}''",     baseUrl); break;
@@ -429,5 +435,5 @@
      * @see FetchResult
      */
-    protected static class Fetcher extends OsmServerReader implements Callable<FetchResult> {
+    protected class Fetcher extends OsmServerReader implements Callable<FetchResult> {
 
         private final Set<Long> pkg;
@@ -477,4 +483,9 @@
                 }
             }
+        }
+
+        @Override
+        protected String getBaseUrl() {
+            return MultiFetchServerObjectReader.this.getBaseUrl();
         }
 
@@ -520,5 +531,5 @@
          */
         protected DataSet singleGetId(OsmPrimitiveType type, long id, ProgressMonitor progressMonitor) throws OsmTransferException {
-            String request = buildRequestString(type, id);
+            String request = buildRequestString(type, Collections.singleton(id));
             DataSet result = null;
             try (InputStream in = getInputStream(request, NullProgressMonitor.INSTANCE)) {
