Index: /applications/editors/josm/plugins/mapillary/build.gradle
===================================================================
--- /applications/editors/josm/plugins/mapillary/build.gradle	(revision 31403)
+++ /applications/editors/josm/plugins/mapillary/build.gradle	(revision 31404)
@@ -138,5 +138,5 @@
 
 task runJosm(type: Exec) {
- commandLine 'josm'
+ commandLine 'java', '-jar', '/home/nokutu/josm/core/dist/josm-custom.jar'
 }
 runJosm.dependsOn installPluginToJosm
Index: /applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/MapillaryData.java
===================================================================
--- /applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/MapillaryData.java	(revision 31403)
+++ /applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/MapillaryData.java	(revision 31404)
@@ -29,5 +29,5 @@
   private final List<MapillaryAbstractImage> multiSelectedImages;
 
-  private List<MapillaryDataListener> listeners = new CopyOnWriteArrayList<>();
+  private CopyOnWriteArrayList<MapillaryDataListener> listeners = new CopyOnWriteArrayList<>();
 
   /**
@@ -52,4 +52,11 @@
     }
     return INSTANCE;
+  }
+
+  /**
+   * Destroys the unique instance.
+   */
+  public void destroy() {
+    INSTANCE = null;
   }
 
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 31403)
+++ /applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/MapillaryLayer.java	(revision 31404)
@@ -54,4 +54,5 @@
 import java.util.List;
 import java.util.ArrayList;
+import java.util.concurrent.CopyOnWriteArrayList;
 
 /**
@@ -83,5 +84,5 @@
 
   /** The bounds of the areas for which the pictures have been downloaded */
-  public ArrayList<Bounds> bounds;
+  public CopyOnWriteArrayList<Bounds> bounds;
 
   /** Mode of the layer */
@@ -98,5 +99,5 @@
     super(tr("Mapillary Images"));
     data = MapillaryData.getInstance();
-    bounds = new ArrayList<>();
+    bounds = new CopyOnWriteArrayList<>();
     init();
   }
@@ -120,5 +121,4 @@
         MapillaryMainDialog.getInstance().getButton().doClick();
     }
-
     createHatchTexture();
     data.dataUpdated();
@@ -138,9 +138,11 @@
     }
     this.mode = mode;
-    Main.map.mapView.setNewCursor(mode.cursor, this);
-    Main.map.mapView.addMouseListener(mode);
-    Main.map.mapView.addMouseMotionListener(mode);
-    NavigatableComponent.addZoomChangeListener(mode);
-    updateHelpText();
+    if (mode != null) {
+      Main.map.mapView.setNewCursor(mode.cursor, this);
+      Main.map.mapView.addMouseListener(mode);
+      Main.map.mapView.addMouseMotionListener(mode);
+      NavigatableComponent.addZoomChangeListener(mode);
+      updateHelpText();
+    }
   }
 
@@ -168,9 +170,8 @@
   @Override
   public void destroy() {
+    setMode(null);
+    MapillaryDownloader.stopAll();
     MapillaryMainDialog.getInstance().setImage(null);
     MapillaryMainDialog.getInstance().updateImage();
-    data.getImages().clear();
-    MapillaryLayer.INSTANCE = null;
-    MapillaryData.INSTANCE = null;
     MapillaryPlugin.setMenuEnabled(MapillaryPlugin.EXPORT_MENU, false);
     MapillaryPlugin.setMenuEnabled(MapillaryPlugin.ZOOM_MENU, false);
@@ -180,4 +181,5 @@
     if (Main.map.mapView.getEditLayer() != null)
       Main.map.mapView.getEditLayer().data.removeDataSetListener(this);
+    MapillaryLayer.INSTANCE = null;
     super.destroy();
   }
@@ -593,6 +595,6 @@
     else
       ret += tr("No images found");
-    ret += " -- " + tr(mode.toString());
-
+    if (mode != null)
+      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 31403)
+++ /applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/downloads/MapillaryDownloader.java	(revision 31404)
@@ -3,7 +3,8 @@
 import static org.openstreetmap.josm.tools.I18n.tr;
 
+import java.util.concurrent.ArrayBlockingQueue;
 import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.Executor;
-import java.util.concurrent.Executors;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
 
 import javax.swing.JOptionPane;
@@ -34,5 +35,6 @@
   public final static String CLIENT_ID = "NzNRM2otQkR2SHJzaXJmNmdQWVQ0dzo1YTA2NmNlODhlNWMwOTBm";
   /** Executor that will run the petitions */
-  public final static Executor EXECUTOR = Executors.newSingleThreadExecutor();
+  public final static ThreadPoolExecutor EXECUTOR = new ThreadPoolExecutor(1,
+      1, 100, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(50));
 
   /**
@@ -51,11 +53,10 @@
     queryStringParts.put("max_lat", maxLatLon.lat());
     queryStringParts.put("max_lon", maxLatLon.lon());
+    run(new MapillarySquareDownloadManagerThread(queryStringParts,
+        MapillaryLayer.getInstance()));
+  }
 
-    try {
-      EXECUTOR.execute(new MapillarySquareDownloadManagerThread(
-          queryStringParts, MapillaryLayer.getInstance()));
-    } catch (Exception e) {
-      Main.error(e);
-    }
+  private static void run(Thread t) {
+    EXECUTOR.execute(t);
   }
 
@@ -130,3 +131,10 @@
     }
   }
+
+  /**
+   * Stops all running threads.
+   */
+  public static void stopAll() {
+    EXECUTOR.shutdownNow();
+  }
 }
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 31403)
+++ /applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/downloads/MapillarySquareDownloadManagerThread.java	(revision 31404)
@@ -83,5 +83,5 @@
       }
     } catch (InterruptedException e) {
-      Main.error(e);
+      Main.error("Mapillary download interrupted (probably because of closing the layer).");
     }
     layer.updateHelpText();
Index: /applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/mode/AbstractMode.java
===================================================================
--- /applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/mode/AbstractMode.java	(revision 31403)
+++ /applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/mode/AbstractMode.java	(revision 31404)
@@ -27,7 +27,5 @@
 
   protected MapillaryData data = MapillaryData.getInstance();
-
-  /** If in semiautomatic mode, the last Epoch time when there was a download */
-  private long lastDownload;
+  private static final SemiautomaticThread semiautomaticThread = new SemiautomaticThread();
 
   /**
@@ -63,23 +61,43 @@
 
   @Override
-  public synchronized void zoomChanged() {
+  public void zoomChanged() {
     if (Main.pref.get("mapillary.download-mode").equals(
         MapillaryDownloader.MODES[1])
         || MapillaryLayer.getInstance().TEMP_SEMIAUTOMATIC) {
-      if (Calendar.getInstance().getTimeInMillis() - lastDownload >= 2000) {
-        lastDownload = Calendar.getInstance().getTimeInMillis();
-        MapillaryDownloader.completeView();
-      } else {
-        new Thread() {
-          @Override
-          public synchronized void run() {
-            try {
-              wait(100);
-            } catch (InterruptedException e) {
-            }
-            zoomChanged();
+      if (!semiautomaticThread.isAlive())
+        semiautomaticThread.start();
+      semiautomaticThread.moved();
+    }
+  }
+
+  private static class SemiautomaticThread extends Thread {
+
+    /** If in semiautomatic mode, the last Epoch time when there was a download */
+    private long lastDownload;
+
+    private boolean moved = false;
+
+    @Override
+    public void run() {
+      while (true) {
+        if (moved
+            && Calendar.getInstance().getTimeInMillis() - lastDownload >= 2000) {
+          lastDownload = Calendar.getInstance().getTimeInMillis();
+          MapillaryDownloader.completeView();
+          moved = false;
+          MapillaryData.getInstance().dataUpdated();
+        }
+        synchronized (this) {
+          try {
+            wait(100);
+          } catch (InterruptedException e) {
+            Main.error(e);
           }
-        }.start();
+        }
       }
+    }
+
+    public void moved() {
+      moved = true;
     }
   }
Index: /applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/mode/SelectMode.java
===================================================================
--- /applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/mode/SelectMode.java	(revision 31403)
+++ /applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/mode/SelectMode.java	(revision 31404)
@@ -18,4 +18,5 @@
 import org.openstreetmap.josm.plugins.mapillary.commands.CommandTurnImage;
 import org.openstreetmap.josm.plugins.mapillary.commands.MapillaryRecord;
+import org.openstreetmap.josm.plugins.mapillary.downloads.MapillaryDownloader;
 import org.openstreetmap.josm.plugins.mapillary.gui.MapillaryMainDialog;
 
@@ -41,4 +42,7 @@
   public SelectMode() {
     record = MapillaryRecord.getInstance();
+    if (Main.pref.get("mapillary.download-mode").equals(
+        MapillaryDownloader.MODES[1]))
+      zoomChanged();
   }
 
