Index: /applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/io/download/MapillaryImageInfoDownloadThread.java
===================================================================
--- /applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/io/download/MapillaryImageInfoDownloadThread.java	(revision 32068)
+++ /applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/io/download/MapillaryImageInfoDownloadThread.java	(revision 32069)
@@ -46,5 +46,7 @@
   public void run() {
     try (
-      BufferedReader br = new BufferedReader(new InputStreamReader(MapillaryURL.searchImageURL(bounds, page).openStream(), "UTF-8"));
+      BufferedReader br = new BufferedReader(new InputStreamReader(
+          MapillaryURL.searchImageInfoURL(bounds, page, null).openStream(), "UTF-8"
+      ));
     ) {
       JsonObject jsonobj = Json.createReader(br).readObject();
Index: /applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/io/download/MapillarySequenceDownloadThread.java
===================================================================
--- /applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/io/download/MapillarySequenceDownloadThread.java	(revision 32068)
+++ /applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/io/download/MapillarySequenceDownloadThread.java	(revision 32069)
@@ -53,8 +53,7 @@
   public void run() {
     try (
-            BufferedReader br = new BufferedReader(new InputStreamReader(
-                    MapillaryURL.searchSequenceURL(bounds, page).openStream(),
-                    "UTF-8"
-            ));
+        BufferedReader br = new BufferedReader(new InputStreamReader(
+            MapillaryURL.searchSequenceURL(bounds, page).openStream(), "UTF-8"
+        ));
     ) {
       JsonObject jsonall = Json.createReader(br).readObject();
@@ -121,5 +120,8 @@
       }
     } catch (IOException e) {
-      Main.error("Error reading the url " + MapillaryURL.searchSequenceURL(bounds, page) + " might be a Mapillary problem.", e);
+      Main.error(String.format(
+          "Error reading the url %s, this might be a Mapillary problem.",
+          MapillaryURL.searchSequenceURL(bounds, page)
+      ), e);
     }
     MapillaryData.dataUpdated();
Index: /applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/io/download/MapillaryTrafficSignDownloadThread.java
===================================================================
--- /applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/io/download/MapillaryTrafficSignDownloadThread.java	(revision 32068)
+++ /applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/io/download/MapillaryTrafficSignDownloadThread.java	(revision 32069)
@@ -18,4 +18,5 @@
 import org.openstreetmap.josm.plugins.mapillary.MapillaryLayer;
 import org.openstreetmap.josm.plugins.mapillary.utils.MapillaryURL;
+import org.openstreetmap.josm.plugins.mapillary.utils.MapillaryURL.IMAGE_SELECTOR;
 
 /**
@@ -48,5 +49,5 @@
     try (
       BufferedReader br = new BufferedReader(new InputStreamReader(
-        MapillaryURL.searchTrafficSignURL(bounds, page).openStream(), "UTF-8"
+        MapillaryURL.searchImageInfoURL(bounds, page, IMAGE_SELECTOR.OBJ_REC_ONLY).openStream(), "UTF-8"
       ));
     ) {
@@ -78,7 +79,9 @@
           for (int j = 0; j < rects.size(); j++) {
             JsonObject data = rects.getJsonObject(j);
-            for (MapillaryAbstractImage image : MapillaryLayer.getInstance().getData().getImages())
-              if (image instanceof MapillaryImage && ((MapillaryImage) image).getKey().equals(key))
+            for (MapillaryAbstractImage image : MapillaryLayer.getInstance().getData().getImages()) {
+              if (image instanceof MapillaryImage && ((MapillaryImage) image).getKey().equals(key)) {
                 ((MapillaryImage) image).addSign(data.getString("type"));
+              }
+            }
           }
         }
Index: /applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/utils/MapillaryURL.java
===================================================================
--- /applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/utils/MapillaryURL.java	(revision 32068)
+++ /applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/utils/MapillaryURL.java	(revision 32069)
@@ -20,4 +20,8 @@
   private static final String BASE_WEBSITE_URL = "https://www.mapillary.com/";
 
+  public enum IMAGE_SELECTOR {
+    BLURRED_ONLY, COMMENTED_ONLY, OBJ_REC_ONLY // null is used when all images should be selected
+  }
+
   private MapillaryURL() {
     // Private constructor to avoid instantiation
@@ -33,5 +37,5 @@
   public static URL browseEditURL(String imgKey) {
     ValidationUtil.throwExceptionForInvalidImgKey(imgKey, false);
-    return string2URL(BASE_WEBSITE_URL + "map/e/" + imgKey);
+    return string2URL(BASE_WEBSITE_URL, "map/e/", imgKey);
   }
 
@@ -45,5 +49,5 @@
   public static URL browseImageURL(String key) {
     ValidationUtil.throwExceptionForInvalidImgKey(key, false);
-    return string2URL(BASE_WEBSITE_URL + "map/im/" + key);
+    return string2URL(BASE_WEBSITE_URL, "map/im/", key);
   }
 
@@ -52,5 +56,5 @@
    */
   public static URL browseUploadImageURL() {
-    return string2URL(BASE_WEBSITE_URL + "map/upload/im/");
+    return string2URL(BASE_WEBSITE_URL, "map/upload/im");
   }
 
@@ -67,5 +71,5 @@
     parts.put("response_type", "token");
     parts.put("scope", "user:read public:upload public:write");
-    return string2URL(BASE_WEBSITE_URL + "connect"+queryString(parts));
+    return string2URL(BASE_WEBSITE_URL, "connect", queryString(parts));
   }
 
@@ -75,12 +79,30 @@
    * @param bounds the bounds in which you want to search for images
    * @param page number of the page to retrieve from the API
+   * @param selector
    * @return the API-URL which gives you the images in the given bounds as JSON
    */
-  public static URL searchImageURL(Bounds bounds, int page) {
+  public static URL searchImageInfoURL(Bounds bounds, int page, IMAGE_SELECTOR selector) {
+    String selectorString = "";
+    if (selector != null) {
+      switch (selector) {
+      case BLURRED_ONLY:
+        selectorString = "/b";
+        break;
+      case COMMENTED_ONLY:
+        selectorString = "/cm";
+        break;
+      case OBJ_REC_ONLY:
+        selectorString = "/or";
+        break;
+      default:
+        selectorString = "";
+        break;
+      }
+    }
     HashMap<String, String> parts = new HashMap<>();
     putBoundsInQueryStringParts(parts, bounds);
     parts.put("page", Integer.toString(page));
     parts.put("limit", "20");
-    return string2URL(BASE_API_URL + "search/im/" + queryString(parts));
+    return string2URL(BASE_API_URL, "search/im", selectorString, queryString(parts));
   }
 
@@ -97,20 +119,5 @@
     parts.put("page", Integer.toString(page));
     parts.put("limit", "10");
-    return string2URL(BASE_API_URL + "search/s/" + queryString(parts));
-  }
-
-  /**
-   * Gives you the API-URL where you get the traffic signs for 20 images within the given bounds.
-   * For the signs from more than 20 images you have to use different URLs with different page numbers.
-   * @param bounds the bounds in which you want to search for traffic signs
-   * @param page number of the page to retrieve from the API
-   * @return the API-URL which gives you the traffic signs in the given bounds as JSON
-   */
-  public static URL searchTrafficSignURL(Bounds bounds, int page) {
-    HashMap<String, String> parts = new HashMap<>();
-    putBoundsInQueryStringParts(parts, bounds);
-    parts.put("page", Integer.toString(page));
-    parts.put("limit", "20");
-    return string2URL(BASE_API_URL + "search/im/or/" + queryString(parts));
+    return string2URL(BASE_API_URL, "search/s", queryString(parts));
   }
 
@@ -119,5 +126,5 @@
    */
   public static URL uploadSecretsURL() {
-    return string2URL(BASE_API_URL + "me/uploads/secrets/" + queryString(null));
+    return string2URL(BASE_API_URL, "me/uploads/secrets", queryString(null));
   }
 
@@ -126,5 +133,5 @@
    */
   public static URL userURL() {
-    return string2URL(BASE_API_URL + "me/" + queryString(null));
+    return string2URL(BASE_API_URL, "me", queryString(null));
   }
 
@@ -172,9 +179,17 @@
    * @return the URL that is constructed from the given string
    */
-  private static URL string2URL(String string) {
+  private static URL string2URL(String... strings) {
+    StringBuilder builder = new StringBuilder();
+    for (int i = 0; strings != null && i < strings.length; i++) {
+      builder.append(strings[i]);
+    }
     try {
-      return new URL(string);
+      return new URL(builder.toString());
     } catch (MalformedURLException e) {
-      Main.error(new Exception("The "+MapillaryURL.class.getSimpleName()+" class produces malformed URLs!", e));
+      Main.error(new Exception(String.format(
+          "The class '%s' produces malformed URLs like '%s'!",
+          MapillaryURL.class.getName(),
+          builder
+      ), e));
       return null;
     }
Index: /applications/editors/josm/plugins/mapillary/test/unit/org/openstreetmap/josm/plugins/mapillary/utils/MapillaryURLTest.java
===================================================================
--- /applications/editors/josm/plugins/mapillary/test/unit/org/openstreetmap/josm/plugins/mapillary/utils/MapillaryURLTest.java	(revision 32068)
+++ /applications/editors/josm/plugins/mapillary/test/unit/org/openstreetmap/josm/plugins/mapillary/utils/MapillaryURLTest.java	(revision 32069)
@@ -4,5 +4,4 @@
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
 
 import java.lang.reflect.InvocationTargetException;
@@ -13,6 +12,10 @@
 import org.junit.Test;
 import org.openstreetmap.josm.data.Bounds;
+import org.openstreetmap.josm.plugins.mapillary.utils.MapillaryURL.IMAGE_SELECTOR;
 
 public class MapillaryURLTest {
+  private static final String CLIENT_ID_QUERY_PART = "client_id=T1Fzd20xZjdtR0s1VDk5OFNIOXpYdzoxNDYyOGRkYzUyYTFiMzgz";
+  private static final String LIMIT_20_QUERY_PART = "limit=20";
+
   @Test
   public void testBrowseEditURL() throws MalformedURLException {
@@ -21,16 +24,24 @@
         MapillaryURL.browseEditURL("1234567890123456789012")
     );
-    try {
-      MapillaryURL.browseEditURL(null);
-      fail();
-    } catch (IllegalArgumentException e) {}
-    try {
-      MapillaryURL.browseEditURL("123456789012345678901");
-      fail();
-    } catch (IllegalArgumentException e) {}
-    try {
-      MapillaryURL.browseEditURL("123456789012345678901+");
-      fail();
-    } catch (IllegalArgumentException e) {}
+  }
+
+  @Test(expected=IllegalArgumentException.class)
+  public void testIllegalBrowseEditURL() {
+    MapillaryURL.browseEditURL(null);
+  }
+
+  @Test(expected=IllegalArgumentException.class)
+  public void testIllegalBrowseEditURL2() {
+    MapillaryURL.browseEditURL("123456789012345678901");
+  }
+
+  @Test(expected=IllegalArgumentException.class)
+  public void testIllegalBrowseEditURL3() {
+    MapillaryURL.browseEditURL("12345678901234567890123");
+  }
+
+  @Test(expected=IllegalArgumentException.class)
+  public void testIllegalBrowseEditURL4() {
+    MapillaryURL.browseEditURL("123456789012345678901+");
   }
 
@@ -41,21 +52,29 @@
         MapillaryURL.browseImageURL("1234567890123456789012")
     );
-    try {
-      MapillaryURL.browseImageURL(null);
-      fail();
-    } catch (IllegalArgumentException e) {}
-    try {
-      MapillaryURL.browseImageURL("123456789012345678901");
-      fail();
-    } catch (IllegalArgumentException e) {}
-    try {
-      MapillaryURL.browseImageURL("123456789012345678901+");
-      fail();
-    } catch (IllegalArgumentException e) {}
+  }
+
+  @Test(expected=IllegalArgumentException.class)
+  public void testIllegalBrowseImageURL() {
+    MapillaryURL.browseImageURL(null);
+  }
+
+  @Test(expected=IllegalArgumentException.class)
+  public void testIllegalBrowseImageURL2() {
+    MapillaryURL.browseImageURL("123456789012345678901");
+  }
+
+  @Test(expected=IllegalArgumentException.class)
+  public void testIllegalBrowseImageURL3() {
+    MapillaryURL.browseImageURL("12345678901234567890123");
+  }
+
+  @Test(expected=IllegalArgumentException.class)
+  public void testIllegalBrowseImageURL4() {
+    MapillaryURL.browseImageURL("123456789012345678901+");
   }
 
   @Test
   public void testBrowseUploadImageURL() throws MalformedURLException {
-    assertEquals(new URL("https://www.mapillary.com/map/upload/im/"), MapillaryURL.browseUploadImageURL());
+    assertEquals(new URL("https://www.mapillary.com/map/upload/im"), MapillaryURL.browseUploadImageURL());
   }
 
@@ -65,5 +84,5 @@
         MapillaryURL.connectURL("http://redirect-host/ä"),
         "https://www.mapillary.com/connect",
-        "client_id=T1Fzd20xZjdtR0s1VDk5OFNIOXpYdzoxNDYyOGRkYzUyYTFiMzgz",
+        CLIENT_ID_QUERY_PART,
         "scope=user%3Aread+public%3Aupload+public%3Awrite",
         "response_type=token",
@@ -74,5 +93,5 @@
         MapillaryURL.connectURL(null),
         "https://www.mapillary.com/connect",
-        "client_id=T1Fzd20xZjdtR0s1VDk5OFNIOXpYdzoxNDYyOGRkYzUyYTFiMzgz",
+        CLIENT_ID_QUERY_PART,
         "scope=user%3Aread+public%3Aupload+public%3Awrite",
         "response_type=token"
@@ -82,5 +101,5 @@
         MapillaryURL.connectURL(""),
         "https://www.mapillary.com/connect",
-        "client_id=T1Fzd20xZjdtR0s1VDk5OFNIOXpYdzoxNDYyOGRkYzUyYTFiMzgz",
+        CLIENT_ID_QUERY_PART,
         "scope=user%3Aread+public%3Aupload+public%3Awrite",
         "response_type=token"
@@ -91,19 +110,19 @@
   public void testSearchImageURL() {
     assertUrlEquals(
-        MapillaryURL.searchImageURL(new Bounds(1.1, 2.22, 3.333, 4.4444), 42),
-        "https://a.mapillary.com/v2/search/im/",
-        "client_id=T1Fzd20xZjdtR0s1VDk5OFNIOXpYdzoxNDYyOGRkYzUyYTFiMzgz",
+        MapillaryURL.searchImageInfoURL(new Bounds(1.1, 2.22, 3.333, 4.4444), 42, null),
+        "https://a.mapillary.com/v2/search/im",
+        CLIENT_ID_QUERY_PART,
         "min_lon=2.220000",
         "max_lon=4.444400",
         "min_lat=1.100000",
         "max_lat=3.333000",
-        "limit=20",
+        LIMIT_20_QUERY_PART,
         "page=42"
     );
     assertUrlEquals(
-        MapillaryURL.searchImageURL(null, -73),
-        "https://a.mapillary.com/v2/search/im/",
-        "client_id=T1Fzd20xZjdtR0s1VDk5OFNIOXpYdzoxNDYyOGRkYzUyYTFiMzgz",
-        "limit=20",
+        MapillaryURL.searchImageInfoURL(null, -73, null),
+        "https://a.mapillary.com/v2/search/im",
+        CLIENT_ID_QUERY_PART,
+        LIMIT_20_QUERY_PART,
         "page=-73"
     );
@@ -114,6 +133,6 @@
     assertUrlEquals(
         MapillaryURL.searchSequenceURL(new Bounds(-55.55555, -66.666666, 77.7777777, 88.88888888, false), 42),
-        "https://a.mapillary.com/v2/search/s/",
-        "client_id=T1Fzd20xZjdtR0s1VDk5OFNIOXpYdzoxNDYyOGRkYzUyYTFiMzgz",
+        "https://a.mapillary.com/v2/search/s",
+        CLIENT_ID_QUERY_PART,
         "min_lon=-66.666666",
         "max_lon=88.888889",
@@ -125,6 +144,6 @@
     assertUrlEquals(
         MapillaryURL.searchSequenceURL(null, -73),
-        "https://a.mapillary.com/v2/search/s/",
-        "client_id=T1Fzd20xZjdtR0s1VDk5OFNIOXpYdzoxNDYyOGRkYzUyYTFiMzgz",
+        "https://a.mapillary.com/v2/search/s",
+        CLIENT_ID_QUERY_PART,
         "limit=10",
         "page=-73"
@@ -135,19 +154,19 @@
   public void testSearchTrafficSignURL() {
     assertUrlEquals(
-        MapillaryURL.searchTrafficSignURL(new Bounds(1.1, 2.22, 3.333, 4.4444), -42),
-        "https://a.mapillary.com/v2/search/im/or/",
-        "client_id=T1Fzd20xZjdtR0s1VDk5OFNIOXpYdzoxNDYyOGRkYzUyYTFiMzgz",
+        MapillaryURL.searchImageInfoURL(new Bounds(1.1, 2.22, 3.333, 4.4444), -42, IMAGE_SELECTOR.OBJ_REC_ONLY),
+        "https://a.mapillary.com/v2/search/im/or",
+        CLIENT_ID_QUERY_PART,
         "min_lon=2.220000",
         "max_lon=4.444400",
         "min_lat=1.100000",
         "max_lat=3.333000",
-        "limit=20",
+        LIMIT_20_QUERY_PART,
         "page=-42"
     );
     assertUrlEquals(
-        MapillaryURL.searchTrafficSignURL(null, 73),
-        "https://a.mapillary.com/v2/search/im/or/",
-        "client_id=T1Fzd20xZjdtR0s1VDk5OFNIOXpYdzoxNDYyOGRkYzUyYTFiMzgz",
-        "limit=20",
+        MapillaryURL.searchImageInfoURL(null, 73, IMAGE_SELECTOR.OBJ_REC_ONLY),
+        "https://a.mapillary.com/v2/search/im/or",
+        CLIENT_ID_QUERY_PART,
+        LIMIT_20_QUERY_PART,
         "page=73"
     );
@@ -157,5 +176,5 @@
   public void testUploadSecretsURL() throws MalformedURLException {
     assertEquals(
-        new URL("https://a.mapillary.com/v2/me/uploads/secrets/?client_id=T1Fzd20xZjdtR0s1VDk5OFNIOXpYdzoxNDYyOGRkYzUyYTFiMzgz"),
+        new URL("https://a.mapillary.com/v2/me/uploads/secrets?"+CLIENT_ID_QUERY_PART),
         MapillaryURL.uploadSecretsURL()
     );
@@ -165,5 +184,5 @@
   public void testUserURL() throws MalformedURLException {
     assertEquals(
-        new URL("https://a.mapillary.com/v2/me/?client_id=T1Fzd20xZjdtR0s1VDk5OFNIOXpYdzoxNDYyOGRkYzUyYTFiMzgz"),
+        new URL("https://a.mapillary.com/v2/me?"+CLIENT_ID_QUERY_PART),
         MapillaryURL.userURL()
     );
@@ -172,8 +191,8 @@
   @Test
   public void testString2MalformedURL()
-      throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
-    Method method = MapillaryURL.class.getDeclaredMethod("string2URL", String.class);
+      throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException {
+    Method method = MapillaryURL.class.getDeclaredMethod("string2URL", String[].class);
     method.setAccessible(true);
-    assertNull(method.invoke(null, "bla"));
+    assertNull(method.invoke(null, new Object[]{new String[]{"malformed URL"}})); // this simply invokes string2URL("malformed URL")
   }
 
