Index: /applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/MapillaryLayer.java
===================================================================
--- /applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/MapillaryLayer.java	(revision 31380)
+++ /applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/MapillaryLayer.java	(revision 31381)
@@ -73,5 +73,5 @@
   public static MapillaryImage RED;
 
-  public final MapillaryData data = MapillaryData.getInstance();
+  private final MapillaryData data = MapillaryData.getInstance();
 
   public ArrayList<Bounds> bounds;
@@ -588,5 +588,5 @@
   public void layerRemoved(Layer oldLayer) {
   }
-  
+
   public void updateHelpText() {
     String ret = "";
@@ -596,5 +596,5 @@
       ret += tr("No images found");
     ret += " -- " + tr(mode.toString());
-    
+
      Main.map.statusLine.setHelpText(ret);
   }
Index: /applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/downloads/MapillaryDownloader.java
===================================================================
--- /applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/downloads/MapillaryDownloader.java	(revision 31380)
+++ /applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/downloads/MapillaryDownloader.java	(revision 31381)
@@ -1,3 +1,7 @@
 package org.openstreetmap.josm.plugins.mapillary.downloads;
+
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.Executor;
+import java.util.concurrent.Executors;
 
 import org.openstreetmap.josm.Main;
@@ -6,12 +10,8 @@
 import org.openstreetmap.josm.plugins.mapillary.MapillaryLayer;
 
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.Executor;
-import java.util.concurrent.Executors;
-
 /**
  * Class that concentrates all the ways of downloading of the plugin. All the
  * download petitions will be managed one by one.
- * 
+ *
  * @author nokutu
  *
@@ -23,7 +23,4 @@
   public final static Executor EXECUTOR = Executors.newSingleThreadExecutor();
 
-  private String[] parameters = { "lat", "lon", "distance", "limit", "min_lat",
-      "min_lon", "max_lat", "max_lon" };
-
   public MapillaryDownloader() {
   }
@@ -32,5 +29,5 @@
    * Gets all the images in a square. It downloads all the images of all the
    * sequences that pass through the given rectangle.
-   * 
+   *
    * @param minLatLon
    *          The minimum latitude and longitude of the rectangle.
@@ -39,23 +36,12 @@
    */
   public void getImages(LatLon minLatLon, LatLon maxLatLon) {
-    String url1 = BASE_URL;
-    String url2 = BASE_URL;
-    String url3 = BASE_URL;
-    url1 += "search/im/";
-    url2 += "search/s/";
-    url3 += "search/im/or";
-    ConcurrentHashMap<String, Double> hash = new ConcurrentHashMap<>();
-    hash.put("min_lat", minLatLon.lat());
-    hash.put("min_lon", minLatLon.lon());
-    hash.put("max_lat", maxLatLon.lat());
-    hash.put("max_lon", maxLatLon.lon());
-    url1 += buildParameters(hash);
-    url2 += buildParameters(hash);
-    url3 += buildParameters(hash);
+    ConcurrentHashMap<String, Double> queryStringParts = new ConcurrentHashMap<>();
+    queryStringParts.put("min_lat", minLatLon.lat());
+    queryStringParts.put("min_lon", minLatLon.lon());
+    queryStringParts.put("max_lat", maxLatLon.lat());
+    queryStringParts.put("max_lon", maxLatLon.lon());
 
     try {
-      Main.info("GET " + url2 + " (Mapillary plugin)");
-      EXECUTOR.execute(new MapillarySquareDownloadManagerThread(url1, url2,
-          url3, MapillaryLayer.getInstance()));
+      EXECUTOR.execute(new MapillarySquareDownloadManagerThread(queryStringParts, MapillaryLayer.getInstance()));
     } catch (Exception e) {
       Main.error(e);
@@ -65,5 +51,5 @@
   /**
    * Gets the images within the given bounds.
-   * 
+   *
    * @param bounds
    */
@@ -71,11 +57,3 @@
     getImages(bounds.getMin(), bounds.getMax());
   }
-
-  private String buildParameters(ConcurrentHashMap<String, Double> hash) {
-    String ret = "?client_id=" + CLIENT_ID;
-    for (int i = 0; i < parameters.length; i++)
-      if (hash.get(parameters[i]) != null)
-        ret += "&" + parameters[i] + "=" + hash.get(parameters[i]);
-    return ret;
-  }
 }
Index: /applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/downloads/MapillaryImageInfoDownloaderThread.java
===================================================================
--- /applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/downloads/MapillaryImageInfoDownloaderThread.java	(revision 31380)
+++ /applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/downloads/MapillaryImageInfoDownloaderThread.java	(revision 31381)
@@ -3,13 +3,12 @@
 import java.io.BufferedReader;
 import java.io.IOException;
+import java.io.InputStreamReader;
 import java.net.MalformedURLException;
 import java.net.URL;
-import java.io.InputStreamReader;
+import java.util.concurrent.ExecutorService;
 
+import javax.json.Json;
 import javax.json.JsonArray;
 import javax.json.JsonObject;
-import javax.json.Json;
-
-import java.util.concurrent.ExecutorService;
 
 import org.openstreetmap.josm.Main;
@@ -25,12 +24,12 @@
  */
 public class MapillaryImageInfoDownloaderThread extends Thread {
-  private final String url;
+  private static final String URL = MapillaryDownloader.BASE_URL + "search/im/";
+  private final String queryString;
   private final ExecutorService ex;
   private final MapillaryLayer layer;
 
-  public MapillaryImageInfoDownloaderThread(ExecutorService ex, String url,
-      MapillaryLayer layer) {
+  public MapillaryImageInfoDownloaderThread(ExecutorService ex, String queryString, MapillaryLayer layer) {
     this.ex = ex;
-    this.url = url;
+    this.queryString = queryString;
     this.layer = layer;
   }
@@ -40,5 +39,5 @@
     try {
       BufferedReader br = new BufferedReader(new InputStreamReader(
-          new URL(url).openStream(), "UTF-8"));
+          new URL(URL + queryString).openStream(), "UTF-8"));
       JsonObject jsonobj = Json.createReader(br).readObject();
       if (!jsonobj.getBoolean("more"))
@@ -49,5 +48,5 @@
         data = jsonarr.getJsonObject(i);
         String key = data.getString("key");
-        for (MapillaryAbstractImage image : layer.data.getImages()) {
+        for (MapillaryAbstractImage image : layer.getMapillaryData().getImages()) {
           if (image instanceof MapillaryImage) {
             if (((MapillaryImage) image).getKey().equals(key)
Index: /applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/downloads/MapillarySequenceDownloadThread.java
===================================================================
--- /applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/downloads/MapillarySequenceDownloadThread.java	(revision 31380)
+++ /applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/downloads/MapillarySequenceDownloadThread.java	(revision 31381)
@@ -30,6 +30,7 @@
  */
 public class MapillarySequenceDownloadThread extends Thread {
+  private static final String URL = MapillaryDownloader.BASE_URL + "search/s/";
 
-  private final String url;
+  private final String queryString;
   private final ExecutorService ex;
   private final List<Bounds> bounds;
@@ -37,7 +38,7 @@
   private final MapillarySquareDownloadManagerThread manager;
 
-  public MapillarySequenceDownloadThread(ExecutorService ex, String url,
+  public MapillarySequenceDownloadThread(ExecutorService ex, String queryString,
       MapillaryLayer layer, MapillarySquareDownloadManagerThread manager) {
-    this.url = url;
+    this.queryString = queryString;
     this.ex = ex;
     this.bounds = layer.bounds;
@@ -50,6 +51,5 @@
     try {
       BufferedReader br;
-      br = new BufferedReader(new InputStreamReader(new URL(url).openStream(),
-          "UTF-8"));
+      br = new BufferedReader(new InputStreamReader(new URL(URL + queryString).openStream(), "UTF-8"));
       JsonObject jsonall = Json.createReader(br).readObject();
 
@@ -71,5 +71,5 @@
                 .getJsonNumber(j).doubleValue()));
           } catch (IndexOutOfBoundsException e) {
-            Main.warn("Mapillary bug at " + url);
+            Main.warn("Mapillary bug at " + URL + queryString);
             isSequenceWrong = true;
           }
@@ -92,12 +92,12 @@
         MapillaryImage.lock.lock();
         for (MapillaryImage img : finalImages) {
-          if (layer.data.getImages().contains(img)) {
+          if (layer.getMapillaryData().getImages().contains(img)) {
             sequence.add(img);
-            ((MapillaryImage) layer.data.getImages().get(
-                layer.data.getImages().indexOf(img))).setSequence(sequence);
+            ((MapillaryImage) layer.getMapillaryData().getImages().get(
+                layer.getMapillaryData().getImages().indexOf(img))).setSequence(sequence);
             finalImages.set(
                 finalImages.indexOf(img),
-                (MapillaryImage) layer.data.getImages().get(
-                    layer.data.getImages().indexOf(img)));
+                (MapillaryImage) layer.getMapillaryData().getImages().get(
+                    layer.getMapillaryData().getImages().indexOf(img)));
           } else {
             img.setSequence(sequence);
@@ -110,9 +110,9 @@
           manager.imagesAdded = imagesAdded;
         }
-        layer.data.addWithoutUpdate(new ArrayList<MapillaryAbstractImage>(
+        layer.getMapillaryData().addWithoutUpdate(new ArrayList<MapillaryAbstractImage>(
             finalImages));
       }
     } catch (IOException e) {
-      Main.error("Error reading the url " + url
+      Main.error("Error reading the url " + URL + queryString
           + " might be a Mapillary problem.");
     }
Index: /applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/downloads/MapillarySignDownloaderThread.java
===================================================================
--- /applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/downloads/MapillarySignDownloaderThread.java	(revision 31380)
+++ /applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/downloads/MapillarySignDownloaderThread.java	(revision 31381)
@@ -18,13 +18,12 @@
 
 public class MapillarySignDownloaderThread extends Thread {
-
-  private final String url;
+  private static final String URL = MapillaryDownloader.BASE_URL + "search/im/or/";
+  private final String queryString;
   private final ExecutorService ex;
   private final MapillaryLayer layer;
 
-  public MapillarySignDownloaderThread(ExecutorService ex, String url,
-      MapillaryLayer layer) {
+  public MapillarySignDownloaderThread(ExecutorService ex, String queryString, MapillaryLayer layer) {
     this.ex = ex;
-    this.url = url;
+    this.queryString = queryString;
     this.layer = layer;
   }
@@ -34,6 +33,5 @@
     BufferedReader br;
     try {
-      br = new BufferedReader(new InputStreamReader(new URL(url).openStream(),
-          "UTF-8"));
+      br = new BufferedReader(new InputStreamReader(new URL(URL + queryString).openStream(), "UTF-8"));
       JsonObject jsonobj = Json.createReader(br).readObject();
       if (!jsonobj.getBoolean("more")) {
@@ -51,5 +49,5 @@
             for (int k = 0; k < rects.size(); k++) {
               JsonObject data = rects.getJsonObject(k);
-              for (MapillaryAbstractImage image : layer.data.getImages())
+              for (MapillaryAbstractImage image : layer.getMapillaryData().getImages())
                 if (image instanceof MapillaryImage
                     && ((MapillaryImage) image).getKey().equals(key))
@@ -63,5 +61,5 @@
           for (int j = 0; j < rects.size(); j++) {
             JsonObject data = rects.getJsonObject(j);
-            for (MapillaryAbstractImage image : layer.data.getImages())
+            for (MapillaryAbstractImage image : layer.getMapillaryData().getImages())
               if (image instanceof MapillaryImage
                   && ((MapillaryImage) image).getKey().equals(key))
Index: /applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/downloads/MapillarySquareDownloadManagerThread.java
===================================================================
--- /applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/downloads/MapillarySquareDownloadManagerThread.java	(revision 31380)
+++ /applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/downloads/MapillarySquareDownloadManagerThread.java	(revision 31381)
@@ -5,5 +5,9 @@
 import java.util.concurrent.ThreadPoolExecutor;
 import java.util.concurrent.TimeUnit;
+import java.io.UnsupportedEncodingException;
+import java.net.URLEncoder;
+import java.util.Locale;
 import java.util.concurrent.ArrayBlockingQueue;
+import java.util.concurrent.ConcurrentHashMap;
 
 import org.openstreetmap.josm.Main;
@@ -23,16 +27,32 @@
 public class MapillarySquareDownloadManagerThread extends Thread {
 
-  private final String urlImages;
-  private final String urlSequences;
-  private final String urlSigns;
+  private final String imageQueryString;
+  private final String sequenceQueryString;
+  private final String signQueryString;
   private final MapillaryLayer layer;
   public boolean imagesAdded = false;
 
-  public MapillarySquareDownloadManagerThread(String urlImages, String urlSequences, String urlSigns,
-      MapillaryLayer layer) {
-    this.urlImages = urlImages;
-    this.urlSequences = urlSequences;
-    this.urlSigns = urlSigns;
+  public MapillarySquareDownloadManagerThread(ConcurrentHashMap<String, Double> queryStringParts, MapillaryLayer layer) {
+    this.imageQueryString = buildQueryString(queryStringParts);
+    this.sequenceQueryString = buildQueryString(queryStringParts);
+    this.signQueryString = buildQueryString(queryStringParts);
+
+    Main.info("GET " + sequenceQueryString + " (Mapillary plugin)"); // TODO: Move this line to the appropriate place, here's no GET-request
+
     this.layer = layer;
+  }
+
+  //TODO: Maybe move into a separate utility class?
+  private String buildQueryString(ConcurrentHashMap<String, Double> hash) {
+    StringBuilder ret = new StringBuilder("?client_id=" + MapillaryDownloader.CLIENT_ID);
+    for (String key : hash.keySet())
+      if (key != null)
+        try {
+          ret.append("&" + URLEncoder.encode(key, "UTF-8"))
+             .append("=" + URLEncoder.encode(String.format(Locale.UK, "%f", hash.get(key)), "UTF-8"));
+        } catch (UnsupportedEncodingException e) {
+          // This should not happen, as the encoding is hard-coded
+        }
+    return ret.toString();
   }
 
@@ -53,5 +73,5 @@
     }
     layer.updateHelpText();
-    layer.data.dataUpdated();
+    layer.getMapillaryData().dataUpdated();
     MapillaryFilterDialog.getInstance().refresh();
     MapillaryMainDialog.getInstance().updateImage();
@@ -63,6 +83,12 @@
     int page = 0;
     while (!ex.isShutdown()) {
-      ex.execute(new MapillarySequenceDownloadThread(ex, urlSequences
-          + "&page=" + page + "&limit=10", layer, this));
+      ex.execute(
+        new MapillarySequenceDownloadThread(
+          ex,
+          sequenceQueryString + "&page=" + page + "&limit=10",
+          layer,
+          this
+        )
+      );
       while (ex.getQueue().remainingCapacity() == 0)
         Thread.sleep(500);
@@ -70,5 +96,5 @@
     }
     ex.awaitTermination(15, TimeUnit.SECONDS);
-    layer.data.dataUpdated();
+    layer.getMapillaryData().dataUpdated();
   }
 
@@ -78,5 +104,5 @@
     int page = 0;
     while (!ex.isShutdown()) {
-      ex.execute(new MapillaryImageInfoDownloaderThread(ex, urlImages
+      ex.execute(new MapillaryImageInfoDownloaderThread(ex, imageQueryString
           + "&page=" + page + "&limit=20", layer));
       while (ex.getQueue().remainingCapacity() == 0)
@@ -92,5 +118,5 @@
     int page = 0;
     while (!ex.isShutdown()) {
-      ex.execute(new MapillarySignDownloaderThread(ex, urlSigns + "&page="
+      ex.execute(new MapillarySignDownloaderThread(ex, signQueryString + "&page="
           + page + "&limit=20", layer));
       while (ex.getQueue().remainingCapacity() == 0)
Index: /applications/editors/josm/plugins/mapillary/test/unit/org/openstreetmap/josm/plugins/mapillary/MapillarySequenceDownloadThreadTest.java
===================================================================
--- /applications/editors/josm/plugins/mapillary/test/unit/org/openstreetmap/josm/plugins/mapillary/MapillarySequenceDownloadThreadTest.java	(revision 31380)
+++ /applications/editors/josm/plugins/mapillary/test/unit/org/openstreetmap/josm/plugins/mapillary/MapillarySequenceDownloadThreadTest.java	(revision 31381)
@@ -48,8 +48,7 @@
 
         ExecutorService ex = Executors.newSingleThreadExecutor();
-        String url = String.format(
+        String queryString = String.format(
             Locale.UK,
-            "%ssearch/s?max_lat=%.8f&max_lon=%.8f&min_lat=%.8f&min_lon=%.8f&limit=10&client_id=%s",
-            MapillaryDownloader.BASE_URL,
+            "?max_lat=%.8f&max_lon=%.8f&min_lat=%.8f&min_lon=%.8f&limit=10&client_id=%s",
             maxLatLon.lat(),
             maxLatLon.lon(),
@@ -63,5 +62,5 @@
         while (!ex.isShutdown() && MapillaryLayer.getInstance().getMapillaryData().getImages().size() <= 0 && page < 50) {
             System.out.println("Sending sequence-request "+page+" to Mapillary-servers…");
-            Thread downloadThread = new MapillarySequenceDownloadThread(ex, url+"&page="+page, MapillaryLayer.getInstance(), null);
+            Thread downloadThread = new MapillarySequenceDownloadThread(ex, queryString+"&page="+page, MapillaryLayer.getInstance(), null);
             downloadThread.start();
             downloadThread.join();
