Index: applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/MapillaryAbstractImage.java
===================================================================
--- applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/MapillaryAbstractImage.java	(revision 31349)
+++ applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/MapillaryAbstractImage.java	(revision 31350)
@@ -5,5 +5,4 @@
 import java.text.SimpleDateFormat;
 import java.util.Calendar;
-import java.util.TimeZone;
 import java.util.concurrent.locks.Lock;
 import java.util.concurrent.locks.ReentrantLock;
@@ -15,5 +14,5 @@
  * Abstract superclass for all image objects. At the moment there is just 2,
  * {@code MapillaryImportedImage} and {@code MapillaryImage}.
- * 
+ *
  * @author nokutu
  *
@@ -21,203 +20,203 @@
 public abstract class MapillaryAbstractImage {
 
-    public static Lock lock = new ReentrantLock();
-
-    /** The time the image was captured, in Epoch format */
-    private long capturedAt;
-    /** Position of the picture */
-    public final LatLon latLon;
-    /** Direction of the picture */
-    public final double ca;
-    public boolean isModified = false;
-    /** Temporal position of the picture until it is uploaded */
-    public LatLon tempLatLon;
-    /**
-     * When the object is being dragged in the map, the temporal position is
-     * stored here
-     */
-    public LatLon movingLatLon;
-    /** Temporal direction of the picture until it is uploaded */
-    public double tempCa;
-    /**
-     * When the object direction is being moved in the map, the temporal
-     * direction is stored here
-     */
-    protected double movingCa;
-    private boolean visible;
-
-    public MapillaryAbstractImage(double lat, double lon, double ca) {
-        this.latLon = new LatLon(lat, lon);
-        this.tempLatLon = this.latLon;
-        this.movingLatLon = this.latLon;
-        this.ca = ca;
-        this.tempCa = ca;
-        this.movingCa = ca;
-        this.visible = true;
+  public static Lock lock = new ReentrantLock();
+
+  /** The time the image was captured, in Epoch format */
+  private long capturedAt;
+  /** Position of the picture */
+  public final LatLon latLon;
+  /** Direction of the picture */
+  public final double ca;
+  public boolean isModified = false;
+  /** Temporal position of the picture until it is uploaded */
+  public LatLon tempLatLon;
+  /**
+   * When the object is being dragged in the map, the temporal position is
+   * stored here
+   */
+  public LatLon movingLatLon;
+  /** Temporal direction of the picture until it is uploaded */
+  public double tempCa;
+  /**
+   * When the object direction is being moved in the map, the temporal direction
+   * is stored here
+   */
+  protected double movingCa;
+  private boolean visible;
+
+  public MapillaryAbstractImage(double lat, double lon, double ca) {
+    this.latLon = new LatLon(lat, lon);
+    this.tempLatLon = this.latLon;
+    this.movingLatLon = this.latLon;
+    this.ca = ca;
+    this.tempCa = ca;
+    this.movingCa = ca;
+    this.visible = true;
+  }
+
+  /**
+   * Returns whether the object has been modified or not.
+   *
+   * @return true if the object has been modified; false otherwise.
+   */
+  public boolean isModified() {
+    return this.isModified;
+  }
+
+  /**
+   * Returns a LatLon object containing the current coordinates of the object.
+   * When you are dragging the image this changes.
+   *
+   * @return The LatLon object with the position of the object.
+   */
+  public LatLon getLatLon() {
+    return movingLatLon;
+  }
+
+  /**
+   * Returns whether the image is visible on the map or not.
+   *
+   * @return True if the image is visible; false otherwise.
+   */
+  public boolean isVisible() {
+    return visible;
+  }
+
+  public void setVisible(boolean visible) {
+    this.visible = visible;
+  }
+
+  /**
+   * Returns the last fixed coordinates of the object.
+   *
+   * @return A LatLon object containing.
+   */
+  public LatLon getTempLatLon() {
+    return tempLatLon;
+  }
+
+  /**
+   * Moves the image temporally to another position
+   *
+   * @param x
+   *          The movement of the image in longitude units.
+   * @param y
+   *          The movement of the image in latitude units.
+   */
+  public void move(double x, double y) {
+    this.movingLatLon = new LatLon(this.tempLatLon.getY() + y,
+        this.tempLatLon.getX() + x);
+    this.isModified = true;
+  }
+
+  /**
+   * Turns the image direction.
+   *
+   * @param ca
+   *          The angle the image is moving.
+   */
+  public void turn(double ca) {
+    this.movingCa = this.tempCa + ca;
+    this.isModified = true;
+  }
+
+  /**
+   * Called when the mouse button is released, meaning that the picture has
+   * stopped being dragged.
+   */
+  public void stopMoving() {
+    this.tempLatLon = this.movingLatLon;
+    this.tempCa = this.movingCa;
+  }
+
+  /**
+   * Returns the direction towards the image has been taken.
+   *
+   * @return The direction of the image (0 means north and goes clockwise).
+   */
+  public double getCa() {
+    return movingCa;
+  }
+
+  /**
+   * Returns the last fixed direction of the object.
+   *
+   * @return The last fixed direction of the object. 0 means north.
+   */
+  public double getTempCa() {
+    return tempCa;
+  }
+
+  /**
+   * Returns the date the picture was taken in DMY format.
+   *
+   * @return A String object containing the date when the picture was taken.
+   */
+  public String getDate() {
+    String format = "";
+    if (Main.pref.getBoolean("iso.dates"))
+      format += "yyyy-MM-dd";
+    else
+      format += "dd/MM/yyyy";
+    if (Main.pref.getBoolean("mapillary.display-hour", true)) {
+      if (Main.pref.getBoolean("mapillary.format-24"))
+        format += " - HH:mm:ss (z)";
+      else
+        format += " - h:mm:ss a (z)";
     }
-
-    /**
-     * Returns whether the object has been modified or not.
-     * 
-     * @return true if the object has been modified; false otherwise.
-     */
-    public boolean isModified() {
-        return this.isModified;
+    return getDate(format);
+  }
+
+  public void setCapturedAt(long capturedAt) {
+    this.capturedAt = capturedAt;
+  }
+
+  public long getCapturedAt() {
+    return capturedAt;
+  }
+
+  /**
+   * Returns the date the picture was taken in the given format.
+   *
+   * @param format
+   * @return
+   */
+  public String getDate(String format) {
+    Date date = new Date(getCapturedAt());
+
+    SimpleDateFormat formatter = new SimpleDateFormat(format);
+    formatter.setTimeZone(Calendar.getInstance().getTimeZone());
+    return formatter.format(date);
+  }
+
+  /**
+   * Parses a string with a given format and returns the Epoch time.
+   *
+   * @param date
+   *          The string containing the date.
+   * @param format
+   *          The format of the date.
+   * @return The date in Epoch format.
+   */
+  public long getEpoch(String date, String format) {
+
+    SimpleDateFormat formatter = new SimpleDateFormat(format);
+    try {
+      Date dateTime = (Date) formatter.parse(date);
+      return dateTime.getTime();
+    } catch (ParseException e) {
+      Main.error(e);
     }
-
-    /**
-     * Returns a LatLon object containing the current coordinates of the object.
-     * When you are dragging the image this changes.
-     * 
-     * @return The LatLon object with the position of the object.
-     */
-    public LatLon getLatLon() {
-        return movingLatLon;
-    }
-
-    /**
-     * Returns whether the image is visible on the map or not.
-     * 
-     * @return True if the image is visible; false otherwise.
-     */
-    public boolean isVisible() {
-        return visible;
-    }
-
-    public void setVisible(boolean visible) {
-        this.visible = visible;
-    }
-
-    /**
-     * Returns the last fixed coordinates of the object.
-     * 
-     * @return A LatLon object containing.
-     */
-    public LatLon getTempLatLon() {
-        return tempLatLon;
-    }
-
-    /**
-     * Moves the image temporally to another position
-     * 
-     * @param x
-     *            The movement of the image in longitude units.
-     * @param y
-     *            The movement of the image in latitude units.
-     */
-    public void move(double x, double y) {
-        this.movingLatLon = new LatLon(this.tempLatLon.getY() + y,
-                this.tempLatLon.getX() + x);
-        this.isModified = true;
-    }
-
-    /**
-     * Turns the image direction.
-     * 
-     * @param ca
-     *            The angle the image is moving.
-     */
-    public void turn(double ca) {
-        this.movingCa = this.tempCa + ca;
-        this.isModified = true;
-    }
-
-    /**
-     * Called when the mouse button is released, meaning that the picture has
-     * stopped being dragged.
-     */
-    public void stopMoving() {
-        this.tempLatLon = this.movingLatLon;
-        this.tempCa = this.movingCa;
-    }
-
-    /**
-     * Returns the direction towards the image has been taken.
-     * 
-     * @return The direction of the image (0 means north and goes clockwise).
-     */
-    public double getCa() {
-        return movingCa;
-    }
-
-    /**
-     * Returns the last fixed direction of the object.
-     * 
-     * @return The last fixed direction of the object. 0 means north.
-     */
-    public double getTempCa() {
-        return tempCa;
-    }
-
-    /**
-     * Returns the date the picture was taken in DMY format.
-     * 
-     * @return A String object containing the date when the picture was taken.
-     */
-    public String getDate() {
-        String format = "";
-        if (Main.pref.getBoolean("iso.dates"))
-            format += "yyyy-MM-dd";
-        else
-            format += "dd/MM/yyyy";
-        if (Main.pref.getBoolean("mapillary.display-hour", true)) {
-            if (Main.pref.getBoolean("mapillary.format-24"))
-                format += " - HH:mm:ss (z)";
-            else
-                format += " - h:mm:ss a (z)";
-        }
-        return getDate(format);
-    }
-
-    public void setCapturedAt(long capturedAt) {
-        this.capturedAt = capturedAt;
-    }
-
-    public long getCapturedAt() {
-        return capturedAt;
-    }
-
-    /**
-     * Returns the date the picture was taken in the given format.
-     * 
-     * @param format
-     * @return
-     */
-    public String getDate(String format) {
-        Date date = new Date(getCapturedAt());
-
-        SimpleDateFormat formatter = new SimpleDateFormat(format);
-        formatter.setTimeZone(TimeZone.getTimeZone("GMT"));
-        return formatter.format(date);
-    }
-
-    /**
-     * Parses a string with a given format and returns the Epoch time.
-     * 
-     * @param date
-     *            The string containing the date.
-     * @param format
-     *            The format of the date.
-     * @return The date in Epoch format.
-     */
-    public long getEpoch(String date, String format) {
-
-        SimpleDateFormat formatter = new SimpleDateFormat(format);
-        try {
-            Date dateTime = (Date) formatter.parse(date);
-            return dateTime.getTime();
-        } catch (ParseException e) {
-            Main.error(e);
-        }
-        return currentTime();
-    }
-
-    /**
-     * Returns current time in Epoch format
-     * 
-     * @return The current date in Epoch format.
-     */
-    private long currentTime() {
-        Calendar cal = Calendar.getInstance();
-        return cal.getTimeInMillis();
-    }
+    return currentTime();
+  }
+
+  /**
+   * Returns current time in Epoch format
+   *
+   * @return The current date in Epoch format.
+   */
+  private long currentTime() {
+    Calendar cal = Calendar.getInstance();
+    return cal.getTimeInMillis();
+  }
 }
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 31349)
+++ applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/MapillaryData.java	(revision 31350)
@@ -20,325 +20,319 @@
  */
 public class MapillaryData implements ICachedLoaderListener {
-    public volatile static MapillaryData INSTANCE;
-    public static boolean TEST_MODE = false;
-
-    private final List<MapillaryAbstractImage> images;
-    private MapillaryAbstractImage selectedImage;
-    /** The image under the cursor */
-    private MapillaryAbstractImage highlightedImage;
-    private final List<MapillaryAbstractImage> multiSelectedImages;
-
-    private List<MapillaryDataListener> listeners = new ArrayList<>();
-
-    public MapillaryData() {
-        images = new CopyOnWriteArrayList<>();
-        multiSelectedImages = new ArrayList<>();
-        selectedImage = null;
-    }
-
-    public static MapillaryData getInstance() {
-        if (INSTANCE == null) {
-            INSTANCE = new MapillaryData();
+  public volatile static MapillaryData INSTANCE;
+  public static boolean TEST_MODE = false;
+
+  private final List<MapillaryAbstractImage> images;
+  private MapillaryAbstractImage selectedImage;
+  /** The image under the cursor */
+  private MapillaryAbstractImage highlightedImage;
+  private final List<MapillaryAbstractImage> multiSelectedImages;
+
+  private List<MapillaryDataListener> listeners = new ArrayList<>();
+
+  public MapillaryData() {
+    images = new CopyOnWriteArrayList<>();
+    multiSelectedImages = new ArrayList<>();
+    selectedImage = null;
+  }
+
+  public static MapillaryData getInstance() {
+    if (INSTANCE == null) {
+      INSTANCE = new MapillaryData();
+    }
+    return INSTANCE;
+  }
+
+  /**
+   * Adds a set of MapillaryImages to the object, and then repaints mapView.
+   *
+   * @param images
+   *          The set of images to be added.
+   */
+  public synchronized void add(List<MapillaryAbstractImage> images) {
+    for (MapillaryAbstractImage image : images) {
+      add(image);
+    }
+  }
+
+  /**
+   * Adds an MapillaryImage to the object, and then repaints mapView.
+   *
+   * @param image
+   *          The image to be added.
+   */
+  public synchronized void add(MapillaryAbstractImage image) {
+    if (!images.contains(image)) {
+      this.images.add(image);
+    }
+    dataUpdated();
+    fireImagesAdded();
+  }
+
+  public void addListener(MapillaryDataListener lis) {
+    listeners.add(lis);
+  }
+
+  public void removeListener(MapillaryDataListener lis) {
+    listeners.remove(lis);
+  }
+
+  /**
+   * Adds a set of MapillaryImages to the object, but doesn't repaint mapView.
+   * This is needed for concurrency.
+   *
+   * @param images
+   *          The set of images to be added.
+   */
+  public synchronized void addWithoutUpdate(List<MapillaryAbstractImage> images) {
+    for (MapillaryAbstractImage image : images) {
+      addWithoutUpdate(image);
+    }
+  }
+
+  /**
+   * Highlights the image under the cursor.
+   *
+   * @param image
+   *          The image under the cursor.
+   */
+  public void setHighlightedImage(MapillaryAbstractImage image) {
+    highlightedImage = image;
+  }
+
+  /**
+   * Returns the image under the mouse cursor.
+   *
+   * @return The image under the mouse cursor.
+   */
+  public MapillaryAbstractImage getHoveredImage() {
+    return highlightedImage;
+  }
+
+  /**
+   * Adds a MapillaryImage to the object, but doesn't repaint mapView. This is
+   * needed for concurrency.
+   *
+   * @param image
+   *          The image to be added.
+   */
+  public synchronized void addWithoutUpdate(MapillaryAbstractImage image) {
+    if (!images.contains(image)) {
+      this.images.add(image);
+    }
+    fireImagesAdded();
+  }
+
+  /**
+   * Repaints mapView object.
+   */
+  public synchronized void dataUpdated() {
+    if (!TEST_MODE)
+      Main.map.mapView.repaint();
+  }
+
+  /**
+   * Returns a List containing all images.
+   *
+   * @return A List object containing all images.
+   */
+  public List<MapillaryAbstractImage> getImages() {
+    return images;
+  }
+
+  /**
+   * Returns the MapillaryImage object that is currently selected.
+   *
+   * @return The selected MapillaryImage object.
+   */
+  public MapillaryAbstractImage getSelectedImage() {
+    return selectedImage;
+  }
+
+  private void fireImagesAdded() {
+    if (listeners.isEmpty())
+      return;
+    for (MapillaryDataListener lis : listeners)
+      lis.imagesAdded();
+  }
+
+  /**
+   * If the selected MapillaryImage is part of a MapillarySequence then the
+   * following visible MapillaryImage is selected. In case there is none, does
+   * nothing.
+   */
+  public void selectNext() {
+    if (getSelectedImage() instanceof MapillaryImage) {
+      if (getSelectedImage() == null)
+        return;
+      if (((MapillaryImage) getSelectedImage()).getSequence() == null)
+        return;
+      if (selectedImage instanceof MapillaryImage
+          && ((MapillaryImage) selectedImage).getSequence() != null) {
+        MapillaryImage tempImage = (MapillaryImage) selectedImage;
+        while (tempImage.next() != null) {
+          tempImage = tempImage.next();
+          if (tempImage.isVisible()) {
+            setSelectedImage(tempImage,
+                Main.pref.getBoolean("mapillary.move-to-picture", true));
+            break;
+          }
         }
-        return INSTANCE;
-    }
-
-    /**
-     * Adds a set of MapillaryImages to the object, and then repaints mapView.
-     *
-     * @param images
-     *            The set of images to be added.
-     */
-    public synchronized void add(List<MapillaryAbstractImage> images) {
-        for (MapillaryAbstractImage image : images) {
-            add(image);
+      }
+    }
+  }
+
+  /**
+   * If the selected MapillaryImage is part of a MapillarySequence then the
+   * previous visible MapillaryImage is selected. In case there is none, does
+   * nothing.
+   */
+  public void selectPrevious() {
+    if (getSelectedImage() instanceof MapillaryImage) {
+      if (getSelectedImage() == null)
+        return;
+      if (((MapillaryImage) getSelectedImage()).getSequence() == null)
+        throw new IllegalStateException();
+      if (selectedImage instanceof MapillaryImage
+          && ((MapillaryImage) selectedImage).getSequence() != null) {
+        MapillaryImage tempImage = (MapillaryImage) selectedImage;
+        while (tempImage.previous() != null) {
+          tempImage = tempImage.previous();
+          if (tempImage.isVisible()) {
+            setSelectedImage(tempImage,
+                Main.pref.getBoolean("mapillary.move-to-picture", true));
+            break;
+          }
         }
-    }
-
-    /**
-     * Adds an MapillaryImage to the object, and then repaints mapView.
-     *
-     * @param image
-     *            The image to be added.
-     */
-    public synchronized void add(MapillaryAbstractImage image) {
-        if (!images.contains(image)) {
-            this.images.add(image);
+      }
+    }
+  }
+
+  /**
+   * Selects a new image and then starts a new
+   * {@link MapillaryImageDownloadThread} thread in order to download its
+   * surrounding thumbnails. If the user does ctrl+click, this isn't triggered.
+   *
+   * @param image
+   *          The MapillaryImage which is going to be selected
+   */
+  public void setSelectedImage(MapillaryAbstractImage image) {
+    setSelectedImage(image, false);
+  }
+
+  /**
+   * Selects a new image and then starts a new
+   * {@link MapillaryImageDownloadThread} thread in order to download its
+   * surrounding thumbnails. If the user does ctrl+click, this isn't triggered.
+   * You can choose whether to center the view on the new image or not.
+   *
+   * @param image
+   *          The {@link MapillaryImage} which is going to be selected.
+   * @param zoom
+   *          True if the view must be centered on the image; false otherwise.
+   */
+  public void setSelectedImage(MapillaryAbstractImage image, boolean zoom) {
+    MapillaryAbstractImage oldImage = selectedImage;
+    selectedImage = image;
+    multiSelectedImages.clear();
+    multiSelectedImages.add(image);
+    if (image != null) {
+      if (image instanceof MapillaryImage) {
+        MapillaryImage mapillaryImage = (MapillaryImage) image;
+        // Donwloadins thumbnails of surrounding pictures.
+        if (mapillaryImage.next() != null) {
+          new MapillaryCache(mapillaryImage.next().getKey(),
+              MapillaryCache.Type.THUMBNAIL).submit(this, false);
+          if (mapillaryImage.next().next() != null)
+            new MapillaryCache(mapillaryImage.next().next().getKey(),
+                MapillaryCache.Type.THUMBNAIL).submit(this, false);
         }
-        dataUpdated();
-        fireImagesAdded();
-    }
-
-    public void addListener(MapillaryDataListener lis) {
-        listeners.add(lis);
-    }
-
-    public void removeListener(MapillaryDataListener lis) {
-        listeners.remove(lis);
-    }
-
-    /**
-     * Adds a set of MapillaryImages to the object, but doesn't repaint mapView.
-     * This is needed for concurrency.
-     *
-     * @param images
-     *            The set of images to be added.
-     */
-    public synchronized void addWithoutUpdate(
-            List<MapillaryAbstractImage> images) {
-        for (MapillaryAbstractImage image : images) {
-            addWithoutUpdate(image);
+        if (mapillaryImage.previous() != null) {
+          new MapillaryCache(mapillaryImage.previous().getKey(),
+              MapillaryCache.Type.THUMBNAIL).submit(this, false);
+          if (mapillaryImage.previous().previous() != null)
+            new MapillaryCache(mapillaryImage.previous().previous().getKey(),
+                MapillaryCache.Type.THUMBNAIL).submit(this, false);
         }
-    }
-
-    /**
-     * Highlights the image under the cursor.
-     *
-     * @param image
-     *            The image under the cursor.
-     */
-    public void setHighlightedImage(MapillaryAbstractImage image) {
-        highlightedImage = image;
-    }
-
-    /**
-     * Returns the image under the mouse cursor.
-     *
-     * @return The image under the mouse cursor.
-     */
-    public MapillaryAbstractImage getHoveredImage() {
-        return highlightedImage;
-    }
-
-    /**
-     * Adds a MapillaryImage to the object, but doesn't repaint mapView. This is
-     * needed for concurrency.
-     *
-     * @param image
-     *            The image to be added.
-     */
-    public synchronized void addWithoutUpdate(MapillaryAbstractImage image) {
-        if (!images.contains(image)) {
-            this.images.add(image);
-        }
-        fireImagesAdded();
-    }
-
-    /**
-     * Repaints mapView object.
-     */
-    public synchronized void dataUpdated() {
-        if (!TEST_MODE)
-            Main.map.mapView.repaint();
-    }
-
-    /**
-     * Returns a List containing all images.
-     *
-     * @return A List object containing all images.
-     */
-    public List<MapillaryAbstractImage> getImages() {
-        return images;
-    }
-
-    /**
-     * Returns the MapillaryImage object that is currently selected.
-     *
-     * @return The selected MapillaryImage object.
-     */
-    public MapillaryAbstractImage getSelectedImage() {
-        return selectedImage;
-    }
-
-    private void fireImagesAdded() {
-        if (listeners.isEmpty())
-            return;
-        for (MapillaryDataListener lis : listeners)
-            lis.imagesAdded();
-    }
-
-    /**
-     * If the selected MapillaryImage is part of a MapillarySequence then the
-     * following visible MapillaryImage is selected. In case there is none, does
-     * nothing.
-     */
-    public void selectNext() {
-        if (getSelectedImage() instanceof MapillaryImage) {
-            if (getSelectedImage() == null)
-                return;
-            if (((MapillaryImage) getSelectedImage()).getSequence() == null)
-                return;
-            if (selectedImage instanceof MapillaryImage
-                    && ((MapillaryImage) selectedImage).getSequence() != null) {
-                MapillaryImage tempImage = (MapillaryImage) selectedImage;
-                while (tempImage.next() != null) {
-                    tempImage = tempImage.next();
-                    if (tempImage.isVisible()) {
-                        setSelectedImage(tempImage, Main.pref.getBoolean(
-                                "mapillary.move-to-picture", true));
-                        break;
-                    }
-                }
-            }
-        }
-    }
-
-    /**
-     * If the selected MapillaryImage is part of a MapillarySequence then the
-     * previous visible MapillaryImage is selected. In case there is none, does
-     * nothing.
-     */
-    public void selectPrevious() {
-        if (getSelectedImage() instanceof MapillaryImage) {
-            if (getSelectedImage() == null)
-                return;
-            if (((MapillaryImage) getSelectedImage()).getSequence() == null)
-                throw new IllegalStateException();
-            if (selectedImage instanceof MapillaryImage
-                    && ((MapillaryImage) selectedImage).getSequence() != null) {
-                MapillaryImage tempImage = (MapillaryImage) selectedImage;
-                while (tempImage.previous() != null) {
-                    tempImage = tempImage.previous();
-                    if (tempImage.isVisible()) {
-                        setSelectedImage(tempImage, Main.pref.getBoolean(
-                                "mapillary.move-to-picture", true));
-                        break;
-                    }
-                }
-            }
-        }
-    }
-
-    /**
-     * Selects a new image and then starts a new
-     * {@link MapillaryImageDownloadThread} thread in order to download its
-     * surrounding thumbnails. If the user does ctrl+click, this isn't
-     * triggered.
-     *
-     * @param image
-     *            The MapillaryImage which is going to be selected
-     */
-    public void setSelectedImage(MapillaryAbstractImage image) {
-        setSelectedImage(image, false);
-    }
-
-    /**
-     * Selects a new image and then starts a new
-     * {@link MapillaryImageDownloadThread} thread in order to download its
-     * surrounding thumbnails. If the user does ctrl+click, this isn't
-     * triggered. You can choose whether to center the view on the new image or
-     * not.
-     *
-     * @param image
-     *            The {@link MapillaryImage} which is going to be selected.
-     * @param zoom
-     *            True if the view must be centered on the image; false
-     *            otherwise.
-     */
-    public void setSelectedImage(MapillaryAbstractImage image, boolean zoom) {
-        MapillaryAbstractImage oldImage = selectedImage;
-        selectedImage = image;
-        multiSelectedImages.clear();
-        multiSelectedImages.add(image);
-        if (image != null) {
-            if (image instanceof MapillaryImage) {
-                MapillaryImage mapillaryImage = (MapillaryImage) image;
-                // Donwloadins thumbnails of surrounding pictures.
-                if (mapillaryImage.next() != null) {
-                    new MapillaryCache(mapillaryImage.next().getKey(),
-                            MapillaryCache.Type.THUMBNAIL).submit(this, false);
-                    if (mapillaryImage.next().next() != null)
-                        new MapillaryCache(mapillaryImage.next().next()
-                                .getKey(), MapillaryCache.Type.THUMBNAIL)
-                                .submit(this, false);
-                }
-                if (mapillaryImage.previous() != null) {
-                    new MapillaryCache(mapillaryImage.previous().getKey(),
-                            MapillaryCache.Type.THUMBNAIL).submit(this, false);
-                    if (mapillaryImage.previous().previous() != null)
-                        new MapillaryCache(mapillaryImage.previous().previous()
-                                .getKey(), MapillaryCache.Type.THUMBNAIL)
-                                .submit(this, false);
-                }
-            }
-        }
-        if (zoom)
-            Main.map.mapView.zoomTo(MapillaryData.getInstance()
-                    .getSelectedImage().getLatLon());
-        if (Main.map != null)
-            Main.map.mapView.repaint();
-        fireSelectedImageChanged(oldImage, selectedImage);
-    }
-
-    private void fireSelectedImageChanged(MapillaryAbstractImage oldImage,
-            MapillaryAbstractImage newImage) {
-        if (listeners.isEmpty())
-            return;
-        for (MapillaryDataListener lis : listeners)
-            lis.selectedImageChanged(oldImage, newImage);
-    }
-
-    /**
-     * Adds a MapillaryImage object to the list of selected images, (when ctrl +
-     * click)
-     *
-     * @param image
-     *            The MapillaryImage object to be added.
-     */
-    public void addMultiSelectedImage(MapillaryAbstractImage image) {
-        if (!this.multiSelectedImages.contains(image)) {
-            if (this.getSelectedImage() != null)
-                this.multiSelectedImages.add(image);
-            else
-                this.setSelectedImage(image);
-        }
-        Main.map.mapView.repaint();
-    }
-
-    /**
-     * Adds a set of {@code MapillaryAbstractImage} objects to the list of
-     * selected images.
-     *
-     * @param images
-     *            A List object containing the set of images to be added.
-     */
-    public void addMultiSelectedImage(List<MapillaryAbstractImage> images) {
-        for (MapillaryAbstractImage image : images)
-            if (!this.multiSelectedImages.contains(image)) {
-                if (this.getSelectedImage() != null)
-                    this.multiSelectedImages.add(image);
-                else
-                    this.setSelectedImage(image);
-            }
-        Main.map.mapView.repaint();
-    }
-
-    /**
-     * Returns a List containing all {@code MapillaryAbstractImage} objects
-     * selected with ctrl + click
-     *
-     * @return A List object containing all the images selected.
-     */
-    public List<MapillaryAbstractImage> getMultiSelectedImages() {
-        return multiSelectedImages;
-    }
-
-    /**
-     * This is empty because it is used just to make sure that certain images
-     * have already been downloaded.
-     */
-    @Override
-    public void loadingFinished(CacheEntry data,
-            CacheEntryAttributes attributes, LoadResult result) {
-        // DO NOTHING
-    }
-
-    /**
-     * Returns the amount of images contained by this object.
-     *
-     * @return The amount of images in stored.
-     */
-    public int size() {
-        return images.size();
-    }
+      }
+    }
+    if (zoom)
+      Main.map.mapView.zoomTo(MapillaryData.getInstance().getSelectedImage()
+          .getLatLon());
+    if (Main.map != null)
+      Main.map.mapView.repaint();
+    fireSelectedImageChanged(oldImage, selectedImage);
+  }
+
+  private void fireSelectedImageChanged(MapillaryAbstractImage oldImage,
+      MapillaryAbstractImage newImage) {
+    if (listeners.isEmpty())
+      return;
+    for (MapillaryDataListener lis : listeners)
+      lis.selectedImageChanged(oldImage, newImage);
+  }
+
+  /**
+   * Adds a MapillaryImage object to the list of selected images, (when ctrl +
+   * click)
+   *
+   * @param image
+   *          The MapillaryImage object to be added.
+   */
+  public void addMultiSelectedImage(MapillaryAbstractImage image) {
+    if (!this.multiSelectedImages.contains(image)) {
+      if (this.getSelectedImage() != null)
+        this.multiSelectedImages.add(image);
+      else
+        this.setSelectedImage(image);
+    }
+    Main.map.mapView.repaint();
+  }
+
+  /**
+   * Adds a set of {@code MapillaryAbstractImage} objects to the list of
+   * selected images.
+   *
+   * @param images
+   *          A List object containing the set of images to be added.
+   */
+  public void addMultiSelectedImage(List<MapillaryAbstractImage> images) {
+    for (MapillaryAbstractImage image : images)
+      if (!this.multiSelectedImages.contains(image)) {
+        if (this.getSelectedImage() != null)
+          this.multiSelectedImages.add(image);
+        else
+          this.setSelectedImage(image);
+      }
+    Main.map.mapView.repaint();
+  }
+
+  /**
+   * Returns a List containing all {@code MapillaryAbstractImage} objects
+   * selected with ctrl + click
+   *
+   * @return A List object containing all the images selected.
+   */
+  public List<MapillaryAbstractImage> getMultiSelectedImages() {
+    return multiSelectedImages;
+  }
+
+  /**
+   * This is empty because it is used just to make sure that certain images have
+   * already been downloaded.
+   */
+  @Override
+  public void loadingFinished(CacheEntry data, CacheEntryAttributes attributes,
+      LoadResult result) {
+    // DO NOTHING
+  }
+
+  /**
+   * Returns the amount of images contained by this object.
+   *
+   * @return The amount of images in stored.
+   */
+  public int size() {
+    return images.size();
+  }
 }
Index: applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/MapillaryDataListener.java
===================================================================
--- applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/MapillaryDataListener.java	(revision 31349)
+++ applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/MapillaryDataListener.java	(revision 31350)
@@ -3,15 +3,15 @@
 public interface MapillaryDataListener {
 
-    /**
-     * Fired when any image is added to the database.
-     */
-    public void imagesAdded();
+  /**
+   * Fired when any image is added to the database.
+   */
+  public void imagesAdded();
 
-    /**
-     * Fired when the selected image is changed by something different from
-     * manually clicking on the icon.
-     */
-    public void selectedImageChanged(MapillaryAbstractImage oldImage,
-            MapillaryAbstractImage newImage);
+  /**
+   * Fired when the selected image is changed by something different from
+   * manually clicking on the icon.
+   */
+  public void selectedImageChanged(MapillaryAbstractImage oldImage,
+      MapillaryAbstractImage newImage);
 
 }
Index: applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/MapillaryImage.java
===================================================================
--- applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/MapillaryImage.java	(revision 31349)
+++ applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/MapillaryImage.java	(revision 31350)
@@ -12,143 +12,145 @@
  */
 public class MapillaryImage extends MapillaryAbstractImage {
-    /** Unique identifier of the object */
-    private final String key;
-    /** Sequence of pictures containing this object */
-    private MapillarySequence sequence;
+  /** Unique identifier of the object */
+  private final String key;
+  /** Sequence of pictures containing this object */
+  private MapillarySequence sequence;
 
-    /** The user that made the image */
-    private String user;
-    /** Set of traffic signs in the image */
-    private List<String> signs;
-    private String location;
+  /** The user that made the image */
+  private String user;
+  /** Set of traffic signs in the image */
+  private List<String> signs;
+  private String location;
 
-    public String getLocation() {
-        return location;
+  public String getLocation() {
+    return location;
+  }
+
+  public void setLocation(String location) {
+    this.location = location;
+  }
+
+  /**
+   * Main contructor of the class MapillaryImage
+   * 
+   * @param key
+   *          The unique identifier of the image.
+   * @param lat
+   *          The latitude where it is positioned.
+   * @param lon
+   *          The longitude where it is positioned.
+   * @param ca
+   *          The direction of the images in degrees, meaning 0 north.
+   */
+  public MapillaryImage(String key, double lat, double lon, double ca) {
+    super(lat, lon, ca);
+    this.key = key;
+    this.signs = new ArrayList<>();
+  }
+
+  /**
+   * Returns the unique identifier of the object.
+   * 
+   * @return A String containing the unique identifier of the object.
+   */
+  public String getKey() {
+    return this.key;
+  }
+
+  /**
+   * Adds a new sign to the set of signs.
+   * 
+   * @param sign
+   *          A String that identifies the type of sign.
+   */
+  public void addSign(String sign) {
+    signs.add(sign);
+  }
+
+  /**
+   * Returns a List containing the signs assigned to this image.
+   * 
+   * @return A List object containing the signs assigned to this image.
+   */
+  public List<String> getSigns() {
+    return signs;
+  }
+
+  /**
+   * Sets the username of the person who took the image.
+   * 
+   * @param user
+   *          A String containing the username of the person who took the image.
+   */
+  public void setUser(String user) {
+    this.user = user;
+  }
+
+  public String getUser() {
+    return user;
+  }
+
+  /**
+   * Sets the MapillarySequence object which contains the MapillaryImage.
+   * 
+   * @param sequence
+   *          The MapillarySequence that contains the MapillaryImage.
+   */
+  public void setSequence(MapillarySequence sequence) {
+    this.sequence = sequence;
+  }
+
+  /**
+   * Returns the sequence which contains this image.
+   * 
+   * @return The MapillarySequence object that contains this MapillaryImage.
+   */
+  public MapillarySequence getSequence() {
+    return this.sequence;
+  }
+
+  public String toString() {
+    return "Image[key=" + this.key + ";lat=" + this.latLon.lat() + ";lon="
+        + this.latLon.lon() + ";ca=" + this.ca + "]";
+  }
+
+  /**
+   * If the MapillaryImage belongs to a MapillarySequence, returns the next
+   * MapillarySequence in it.
+   * 
+   * @return The following MapillaryImage, or null if there is none.
+   */
+  public MapillaryImage next() {
+    synchronized (lock) {
+      if (this.getSequence() == null)
+        return null;
+      return this.getSequence().next(this);
     }
+  }
 
-    public void setLocation(String location) {
-        this.location = location;
+  /**
+   * If the MapillaryImage belongs to a MapillarySequence, returns the previous
+   * MapillarySequence in it.
+   * 
+   * @return The previous MapillaryImage, or null if there is none.
+   */
+  public MapillaryImage previous() {
+    synchronized (lock) {
+      if (this.getSequence() == null)
+        return null;
+      return this.getSequence().previous(this);
     }
+  }
 
-    /**
-     * Main contructor of the class MapillaryImage
-     * 
-     * @param key
-     *            The unique identifier of the image.
-     * @param lat
-     *            The latitude where it is positioned.
-     * @param lon
-     *            The longitude where it is positioned.
-     * @param ca
-     *            The direction of the images in degrees, meaning 0 north.
-     */
-    public MapillaryImage(String key, double lat, double lon, double ca) {
-        super(lat, lon, ca);
-        this.key = key;
-        this.signs = new ArrayList<>();
-    }
+  @Override
+  public boolean equals(Object object) {
+    if (object instanceof MapillaryImage)
+      return this.key.equals(((MapillaryImage) object).getKey());
+    return false;
+  }
 
-    /**
-     * Returns the unique identifier of the object.
-     * 
-     * @return A String containing the unique identifier of the object.
-     */
-    public String getKey() {
-        return this.key;
-    }
-
-    /**
-     * Adds a new sign to the set of signs.
-     * 
-     * @param sign
-     *            A String that identifies the type of sign.
-     */
-    public void addSign(String sign) {
-        signs.add(sign);
-    }
-
-    /**
-     * Returns a List containing the signs assigned to this image.
-     * 
-     * @return A List object containing the signs assigned to this image.
-     */
-    public List<String> getSigns() {
-        return signs;
-    }
-
-    /**
-     * Sets the username of the person who took the image.
-     * @param user A String containing the username of the person who took the image.
-     */
-    public void setUser(String user) {
-        this.user = user;
-    }
-
-    public String getUser() {
-        return user;
-    }
-
-    /**
-     * Sets the MapillarySequence object which contains the MapillaryImage.
-     * 
-     * @param sequence
-     *            The MapillarySequence that contains the MapillaryImage.
-     */
-    public void setSequence(MapillarySequence sequence) {
-        this.sequence = sequence;
-    }
-
-    /**
-     * Returns the sequence which contains this image.
-     * 
-     * @return The MapillarySequence object that contains this MapillaryImage.
-     */
-    public MapillarySequence getSequence() {
-        return this.sequence;
-    }
-
-    public String toString() {
-        return "Image[key=" + this.key + ";lat=" + this.latLon.lat() + ";lon="
-                + this.latLon.lon() + ";ca=" + this.ca + "]";
-    }
-
-    /**
-     * If the MapillaryImage belongs to a MapillarySequence, returns the next
-     * MapillarySequence in it.
-     * 
-     * @return The following MapillaryImage, or null if there is none.
-     */
-    public MapillaryImage next() {
-        synchronized (lock) {
-            if (this.getSequence() == null)
-                return null;
-            return this.getSequence().next(this);
-        }
-    }
-
-    /**
-     * If the MapillaryImage belongs to a MapillarySequence, returns the
-     * previous MapillarySequence in it.
-     * 
-     * @return The previous MapillaryImage, or null if there is none.
-     */
-    public MapillaryImage previous() {
-        synchronized (lock) {
-            if (this.getSequence() == null)
-                return null;
-            return this.getSequence().previous(this);
-        }
-    }
-
-    @Override
-    public boolean equals(Object object) {
-        if (object instanceof MapillaryImage)
-            return this.key.equals(((MapillaryImage) object).getKey());
-        return false;
-    }
-
-    @Override
-    public int hashCode() {
-        return this.key.hashCode();
-    }
+  @Override
+  public int hashCode() {
+    return this.key.hashCode();
+  }
 }
Index: applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/MapillaryImportedImage.java
===================================================================
--- applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/MapillaryImportedImage.java	(revision 31349)
+++ applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/MapillaryImportedImage.java	(revision 31350)
@@ -11,59 +11,60 @@
 public class MapillaryImportedImage extends MapillaryAbstractImage {
 
-    /**
-     * The picture file.
-     */
-    protected File file;
-    public final long datetimeOriginal;
+  /**
+   * The picture file.
+   */
+  protected File file;
+  public final long datetimeOriginal;
 
-    public MapillaryImportedImage(double lat, double lon, double ca, File file) {
-        this(lat, lon, ca, file, currentDate());
-    }
+  public MapillaryImportedImage(double lat, double lon, double ca, File file) {
+    this(lat, lon, ca, file, currentDate());
+  }
 
-    public MapillaryImportedImage(double lat, double lon, double ca, File file,
-            String datetimeOriginal) {
-        super(lat, lon, ca);
-        this.file = file;
-        this.datetimeOriginal = getEpoch(datetimeOriginal,
-                "yyyy:MM:dd hh:mm:ss");
-    }
+  public MapillaryImportedImage(double lat, double lon, double ca, File file,
+      String datetimeOriginal) {
+    super(lat, lon, ca);
+    this.file = file;
+    this.datetimeOriginal = getEpoch(datetimeOriginal, "yyyy:MM:dd hh:mm:ss");
+  }
 
-    /**
-     * Returns the pictures of the file.
-     *
-     * @return A BufferedImage object containing the pictures.
-     * @throws IOException
-     * @throws IllegalArgumentException if file is currently set to null
-     */
-    public BufferedImage getImage() throws IOException {
-        return ImageIO.read(file);
-    }
+  /**
+   * Returns the pictures of the file.
+   *
+   * @return A BufferedImage object containing the pictures.
+   * @throws IOException
+   * @throws IllegalArgumentException
+   *           if file is currently set to null
+   */
+  public BufferedImage getImage() throws IOException {
+    return ImageIO.read(file);
+  }
 
-    /**
-     * Returns the File object where the picture is located.
-     * @return The File object where the picture is located.
-     */
-    public File getFile() {
-        return file;
-    }
+  /**
+   * Returns the File object where the picture is located.
+   * 
+   * @return The File object where the picture is located.
+   */
+  public File getFile() {
+    return file;
+  }
 
-    @Override
-    public boolean equals(Object object) {
-        if (object instanceof MapillaryImportedImage)
-            return this.file.equals(((MapillaryImportedImage) object).file);
-        return false;
-    }
+  @Override
+  public boolean equals(Object object) {
+    if (object instanceof MapillaryImportedImage)
+      return this.file.equals(((MapillaryImportedImage) object).file);
+    return false;
+  }
 
-    @Override
-    public int hashCode() {
-        return this.file.hashCode();
-    }
+  @Override
+  public int hashCode() {
+    return this.file.hashCode();
+  }
 
-    private static String currentDate() {
-        Calendar cal = Calendar.getInstance();
+  private static String currentDate() {
+    Calendar cal = Calendar.getInstance();
 
-        SimpleDateFormat formatter = new SimpleDateFormat("yyyy:MM:dd hh:mm:ss");
-        return formatter.format(cal.getTime());
+    SimpleDateFormat formatter = new SimpleDateFormat("yyyy:MM:dd hh:mm:ss");
+    return formatter.format(cal.getTime());
 
-    }
+  }
 }
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 31349)
+++ applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/MapillaryLayer.java	(revision 31350)
@@ -59,522 +59,510 @@
 
 public class MapillaryLayer extends AbstractModifiableLayer implements
-        DataSetListener, EditLayerChangeListener, LayerChangeListener {
-
-    public final static int SEQUENCE_MAX_JUMP_DISTANCE = Main.pref.getInteger(
-            "mapillary.sequence-max-jump-distance", 100);
-
-    private boolean TEMP_MANUAL = false;
-
-    public static MapillaryLayer INSTANCE;
-    public static CacheAccess<String, BufferedImageCacheEntry> CACHE;
-    public static MapillaryImage BLUE;
-    public static MapillaryImage RED;
-
-    public final MapillaryData data = MapillaryData.getInstance();
-
-    public ArrayList<Bounds> bounds;
-
-    private MouseAdapter mouseAdapter;
-
-    private int highlightPointRadius = Main.pref.getInteger(
-            "mappaint.highlight.radius", 7);
-    private int highlightStep = Main.pref.getInteger("mappaint.highlight.step",
-            4);
-
-    private volatile TexturePaint hatched;
-
-    private MapillaryLayer() {
-        super(tr("Mapillary Images"));
-        bounds = new ArrayList<>();
-        init();
-    }
-
-    /**
-     * Initializes the Layer.
-     */
-    private void init() {
-        mouseAdapter = new MapillaryMouseAdapter();
-        try {
-            CACHE = JCSCacheManager.getCache("Mapillary");
-        } catch (IOException e) {
-            Main.error(e);
+    DataSetListener, EditLayerChangeListener, LayerChangeListener {
+
+  public final static int SEQUENCE_MAX_JUMP_DISTANCE = Main.pref.getInteger(
+      "mapillary.sequence-max-jump-distance", 100);
+
+  private boolean TEMP_MANUAL = false;
+
+  public static MapillaryLayer INSTANCE;
+  public static CacheAccess<String, BufferedImageCacheEntry> CACHE;
+  public static MapillaryImage BLUE;
+  public static MapillaryImage RED;
+
+  public final MapillaryData data = MapillaryData.getInstance();
+
+  public ArrayList<Bounds> bounds;
+
+  private MouseAdapter mouseAdapter;
+
+  private int highlightPointRadius = Main.pref.getInteger(
+      "mappaint.highlight.radius", 7);
+  private int highlightStep = Main.pref
+      .getInteger("mappaint.highlight.step", 4);
+
+  private volatile TexturePaint hatched;
+
+  private MapillaryLayer() {
+    super(tr("Mapillary Images"));
+    bounds = new ArrayList<>();
+    init();
+  }
+
+  /**
+   * Initializes the Layer.
+   */
+  private void init() {
+    mouseAdapter = new MapillaryMouseAdapter();
+    try {
+      CACHE = JCSCacheManager.getCache("Mapillary");
+    } catch (IOException e) {
+      Main.error(e);
+    }
+    if (Main.map != null && Main.map.mapView != null) {
+      Main.map.mapView.addMouseListener(mouseAdapter);
+      Main.map.mapView.addMouseMotionListener(mouseAdapter);
+      Main.map.mapView.addLayer(this);
+      MapView.addEditLayerChangeListener(this, false);
+      MapView.addLayerChangeListener(this);
+      if (Main.map.mapView.getEditLayer() != null)
+        Main.map.mapView.getEditLayer().data.addDataSetListener(this);
+    }
+    if (MapillaryPlugin.EXPORT_MENU != null) { // Does not execute when in
+                                               // headless mode
+      MapillaryPlugin.setMenuEnabled(MapillaryPlugin.EXPORT_MENU, true);
+      if (!MapillaryMainDialog.getInstance().isShowing())
+        MapillaryMainDialog.getInstance().getButton().doClick();
+    }
+
+    createHatchTexture();
+    data.dataUpdated();
+  }
+
+  public synchronized static MapillaryLayer getInstance() {
+    if (MapillaryLayer.INSTANCE == null)
+      MapillaryLayer.INSTANCE = new MapillaryLayer();
+    return MapillaryLayer.INSTANCE;
+  }
+
+  /**
+   * Downloads all images of the area covered by the OSM data. This is only just
+   * for automatic download.
+   */
+  public void download() {
+    checkAreaTooBig();
+    if (Main.pref.getBoolean("mapillary.download-manually") || TEMP_MANUAL)
+      return;
+    for (Bounds bounds : Main.map.mapView.getEditLayer().data
+        .getDataSourceBounds()) {
+      if (!this.bounds.contains(bounds)) {
+        this.bounds.add(bounds);
+        new MapillaryDownloader().getImages(bounds.getMin(), bounds.getMax());
+      }
+    }
+  }
+
+  /**
+   * Checks if the area of the OSM data is too big. This means that probably
+   * lots of Mapillary images are going to be downloaded, slowing down the
+   * program too much. To solve this the automatic is stopped, an alert is shown
+   * and you will have to download areas manually.
+   */
+  private void checkAreaTooBig() {
+    double area = 0;
+    for (Bounds bounds : Main.map.mapView.getEditLayer().data
+        .getDataSourceBounds()) {
+      area += bounds.getArea();
+    }
+    if (area > MapillaryDownloadViewAction.MAX_AREA) {
+      TEMP_MANUAL = true;
+      MapillaryPlugin.setMenuEnabled(MapillaryPlugin.DOWNLOAD_VIEW_MENU, true);
+      JOptionPane
+          .showMessageDialog(
+              Main.parent,
+              tr("The downloaded OSM area is too big. Download mode has been changed to manual until the layer is restarted."));
+    }
+  }
+
+  /**
+   * Returns the MapillaryData object, which acts as the database of the Layer.
+   *
+   * @return
+   */
+  public MapillaryData getMapillaryData() {
+    return data;
+  }
+
+  /**
+   * Method invoked when the layer is destroyed.
+   */
+  @Override
+  public void destroy() {
+    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);
+    Main.map.mapView.removeMouseListener(mouseAdapter);
+    Main.map.mapView.removeMouseMotionListener(mouseAdapter);
+    MapView.removeEditLayerChangeListener(this);
+    if (Main.map.mapView.getEditLayer() != null)
+      Main.map.mapView.getEditLayer().data.removeDataSetListener(this);
+    super.destroy();
+  }
+
+  /**
+   * Returns true any of the images from the database has been modified.
+   */
+  @Override
+  public boolean isModified() {
+    for (MapillaryAbstractImage image : data.getImages())
+      if (image.isModified())
+        return true;
+    return false;
+  }
+
+  @Override
+  public void setVisible(boolean visible) {
+    super.setVisible(visible);
+    for (MapillaryAbstractImage img : data.getImages())
+      img.setVisible(visible);
+    MapillaryFilterDialog.getInstance().refresh();
+  }
+
+  /**
+   * Replies background color for downloaded areas.
+   *
+   * @return background color for downloaded areas. Black by default
+   */
+  private Color getBackgroundColor() {
+    return Main.pref.getColor(marktr("background"), Color.BLACK);
+  }
+
+  /**
+   * Replies background color for non-downloaded areas.
+   *
+   * @return background color for non-downloaded areas. Yellow by default
+   */
+  private Color getOutsideColor() {
+    return Main.pref.getColor(marktr("outside downloaded area"), Color.YELLOW);
+  }
+
+  /**
+   * Initialize the hatch pattern used to paint the non-downloaded area
+   */
+  private void createHatchTexture() {
+    BufferedImage bi = new BufferedImage(15, 15, BufferedImage.TYPE_INT_ARGB);
+    Graphics2D big = bi.createGraphics();
+    big.setColor(getBackgroundColor());
+    Composite comp = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.3f);
+    big.setComposite(comp);
+    big.fillRect(0, 0, 15, 15);
+    big.setColor(getOutsideColor());
+    big.drawLine(0, 15, 15, 0);
+    Rectangle r = new Rectangle(0, 0, 15, 15);
+    hatched = new TexturePaint(bi, r);
+  }
+
+  /**
+   * Paints the database in the map.
+   */
+  @Override
+  public synchronized void paint(Graphics2D g, MapView mv, Bounds box) {
+    if (Main.map.mapView.getActiveLayer() == this) {
+      Rectangle b = mv.getBounds();
+      // on some platforms viewport bounds seem to be offset from the
+      // left,
+      // over-grow it just to be sure
+      b.grow(100, 100);
+      Area a = new Area(b);
+      // now successively subtract downloaded areas
+      for (Bounds bounds : this.bounds) {
+        Point p1 = mv.getPoint(bounds.getMin());
+        Point p2 = mv.getPoint(bounds.getMax());
+        Rectangle r = new Rectangle(Math.min(p1.x, p2.x), Math.min(p1.y, p2.y),
+            Math.abs(p2.x - p1.x), Math.abs(p2.y - p1.y));
+        a.subtract(new Area(r));
+      }
+      // paint remainder
+      g.setPaint(hatched);
+      g.fill(a);
+    }
+
+    // Draw colored lines
+    MapillaryLayer.BLUE = null;
+    MapillaryLayer.RED = null;
+    MapillaryMainDialog.getInstance().blueButton.setEnabled(false);
+    MapillaryMainDialog.getInstance().redButton.setEnabled(false);
+
+    // Sets blue and red lines and enables/disables the buttons
+    if (data.getSelectedImage() != null) {
+      MapillaryImage[] closestImages = getClosestImagesFromDifferentSequences();
+      Point selected = mv.getPoint(data.getSelectedImage().getLatLon());
+      if (closestImages[0] != null) {
+        MapillaryLayer.BLUE = closestImages[0];
+        g.setColor(Color.BLUE);
+        g.drawLine(mv.getPoint(closestImages[0].getLatLon()).x,
+            mv.getPoint(closestImages[0].getLatLon()).y, selected.x, selected.y);
+        MapillaryMainDialog.getInstance().blueButton.setEnabled(true);
+      }
+      if (closestImages[1] != null) {
+        MapillaryLayer.RED = closestImages[1];
+        g.setColor(Color.RED);
+        g.drawLine(mv.getPoint(closestImages[1].getLatLon()).x,
+            mv.getPoint(closestImages[1].getLatLon()).y, selected.x, selected.y);
+        MapillaryMainDialog.getInstance().redButton.setEnabled(true);
+      }
+    }
+    g.setColor(Color.WHITE);
+    for (MapillaryAbstractImage imageAbs : data.getImages()) {
+      if (!imageAbs.isVisible())
+        continue;
+      Point p = mv.getPoint(imageAbs.getLatLon());
+      if (imageAbs instanceof MapillaryImage) {
+        MapillaryImage image = (MapillaryImage) imageAbs;
+        Point nextp = null;
+        // Draw sequence line
+        if (image.getSequence() != null) {
+          MapillaryImage tempImage = image.next();
+          while (tempImage != null) {
+            if (tempImage.isVisible()) {
+              nextp = mv.getPoint(tempImage.getLatLon());
+              break;
+            }
+            tempImage = tempImage.next();
+          }
+          if (nextp != null)
+            g.drawLine(p.x, p.y, nextp.x, nextp.y);
         }
-        if (Main.map != null && Main.map.mapView != null) {
-            Main.map.mapView.addMouseListener(mouseAdapter);
-            Main.map.mapView.addMouseMotionListener(mouseAdapter);
-            Main.map.mapView.addLayer(this);
-            MapView.addEditLayerChangeListener(this, false);
-            MapView.addLayerChangeListener(this);
-            if (Main.map.mapView.getEditLayer() != null)
-                Main.map.mapView.getEditLayer().data.addDataSetListener(this);
+
+        ImageIcon icon;
+        if (!data.getMultiSelectedImages().contains(image))
+          icon = MapillaryPlugin.MAP_ICON;
+        else
+          icon = MapillaryPlugin.MAP_ICON_SELECTED;
+        draw(g, image, icon, p);
+        if (!image.getSigns().isEmpty()) {
+          g.drawImage(MapillaryPlugin.MAP_SIGN.getImage(),
+              p.x + icon.getIconWidth() / 2, p.y - icon.getIconHeight() / 2,
+              Main.map.mapView);
         }
-        if (MapillaryPlugin.EXPORT_MENU != null) { // Does not execute when in headless mode
-            MapillaryPlugin.setMenuEnabled(MapillaryPlugin.EXPORT_MENU, true);
-            if (!MapillaryMainDialog.getInstance().isShowing())
-                MapillaryMainDialog.getInstance().getButton().doClick();
+      } else if (imageAbs instanceof MapillaryImportedImage) {
+        MapillaryImportedImage image = (MapillaryImportedImage) imageAbs;
+        ImageIcon icon;
+        if (!data.getMultiSelectedImages().contains(image))
+          icon = MapillaryPlugin.MAP_ICON_IMPORTED;
+        else
+          icon = MapillaryPlugin.MAP_ICON_SELECTED;
+        draw(g, image, icon, p);
+      }
+    }
+  }
+
+  /**
+   * Draws the highlight of the icon.
+   *
+   * @param g
+   * @param p
+   * @param size
+   */
+  private void drawPointHighlight(Graphics2D g, Point p, int size) {
+    Color oldColor = g.getColor();
+    Color highlightColor = PaintColors.HIGHLIGHT.get();
+    Color highlightColorTransparent = new Color(highlightColor.getRed(),
+        highlightColor.getGreen(), highlightColor.getBlue(), 100);
+    g.setColor(highlightColorTransparent);
+    int s = size + highlightPointRadius;
+    while (s >= size) {
+      int r = (int) Math.floor(s / 2d);
+      g.fillRoundRect(p.x - r, p.y - r, s, s, r, r);
+      s -= highlightStep;
+    }
+    g.setColor(oldColor);
+  }
+
+  /**
+   * Draws the given icon of an image. Also checks if the mouse is over the
+   * image.
+   *
+   * @param g
+   * @param image
+   * @param icon
+   * @param p
+   */
+  private void draw(Graphics2D g, MapillaryAbstractImage image, ImageIcon icon,
+      Point p) {
+    Image imagetemp = icon.getImage();
+    BufferedImage bi = (BufferedImage) imagetemp;
+    int width = icon.getIconWidth();
+    int height = icon.getIconHeight();
+
+    // Rotate the image
+    double rotationRequired = Math.toRadians(image.getCa());
+    double locationX = width / 2;
+    double locationY = height / 2;
+    AffineTransform tx = AffineTransform.getRotateInstance(rotationRequired,
+        locationX, locationY);
+    AffineTransformOp op = new AffineTransformOp(tx,
+        AffineTransformOp.TYPE_BILINEAR);
+
+    g.drawImage(op.filter(bi, null), p.x - (width / 2), p.y - (height / 2),
+        Main.map.mapView);
+    if (data.getHoveredImage() == image) {
+      drawPointHighlight(g, p, 16);
+    }
+  }
+
+  @Override
+  public Icon getIcon() {
+    return MapillaryPlugin.ICON16;
+  }
+
+  @Override
+  public boolean isMergable(Layer other) {
+    return false;
+  }
+
+  @Override
+  public void mergeFrom(Layer from) {
+    throw new UnsupportedOperationException(
+        "This layer does not support merging yet");
+  }
+
+  @Override
+  public Action[] getMenuEntries() {
+    List<Action> actions = new ArrayList<>();
+    actions.add(LayerListDialog.getInstance().createShowHideLayerAction());
+    actions.add(LayerListDialog.getInstance().createDeleteLayerAction());
+    actions.add(new LayerListPopup.InfoAction(this));
+    return actions.toArray(new Action[actions.size()]);
+  }
+
+  /**
+   * Returns the 2 closest images belonging to a different sequence.
+   *
+   * @return
+   */
+  private MapillaryImage[] getClosestImagesFromDifferentSequences() {
+    if (!(data.getSelectedImage() instanceof MapillaryImage))
+      return new MapillaryImage[2];
+    MapillaryImage selected = (MapillaryImage) data.getSelectedImage();
+    MapillaryImage[] ret = new MapillaryImage[2];
+    double[] distances = { SEQUENCE_MAX_JUMP_DISTANCE,
+        SEQUENCE_MAX_JUMP_DISTANCE };
+    LatLon selectedCoords = data.getSelectedImage().getLatLon();
+    for (MapillaryAbstractImage imagePrev : data.getImages()) {
+      if (!(imagePrev instanceof MapillaryImage))
+        continue;
+      if (!imagePrev.isVisible())
+        continue;
+      MapillaryImage image = (MapillaryImage) imagePrev;
+      if (image.getLatLon().greatCircleDistance(selectedCoords) < SEQUENCE_MAX_JUMP_DISTANCE
+          && selected.getSequence() != image.getSequence()) {
+        if ((ret[0] == null && ret[1] == null)
+            || (image.getLatLon().greatCircleDistance(selectedCoords) < distances[0] && (ret[1] == null || image
+                .getSequence() != ret[1].getSequence()))) {
+          ret[0] = image;
+          distances[0] = image.getLatLon().greatCircleDistance(selectedCoords);
+        } else if ((ret[1] == null || image.getLatLon().greatCircleDistance(
+            selectedCoords) < distances[1])
+            && image.getSequence() != ret[0].getSequence()) {
+          ret[1] = image;
+          distances[1] = image.getLatLon().greatCircleDistance(selectedCoords);
         }
-
-        createHatchTexture();
-        data.dataUpdated();
-    }
-
-    public synchronized static MapillaryLayer getInstance() {
-        if (MapillaryLayer.INSTANCE == null)
-            MapillaryLayer.INSTANCE = new MapillaryLayer();
-        return MapillaryLayer.INSTANCE;
-    }
-
-    /**
-     * Downloads all images of the area covered by the OSM data. This is only
-     * just for automatic download.
-     */
-    public void download() {
-        checkAreaTooBig();
-        if (Main.pref.getBoolean("mapillary.download-manually") || TEMP_MANUAL)
-            return;
-        for (Bounds bounds : Main.map.mapView.getEditLayer().data
-                .getDataSourceBounds()) {
-            if (!this.bounds.contains(bounds)) {
-                this.bounds.add(bounds);
-                new MapillaryDownloader().getImages(bounds.getMin(),
-                        bounds.getMax());
-            }
-        }
-    }
-
-    /**
-     * Checks if the area of the OSM data is too big. This means that probably
-     * lots of Mapillary images are going to be downloaded, slowing down the
-     * program too much. To solve this the automatic is stopped, an alert is
-     * shown and you will have to download areas manually.
-     */
-    private void checkAreaTooBig() {
-        double area = 0;
-        for (Bounds bounds : Main.map.mapView.getEditLayer().data
-                .getDataSourceBounds()) {
-            area += bounds.getArea();
-        }
-        if (area > MapillaryDownloadViewAction.MAX_AREA) {
-            TEMP_MANUAL = true;
-            MapillaryPlugin.setMenuEnabled(MapillaryPlugin.DOWNLOAD_VIEW_MENU,
-                    true);
-            JOptionPane
-                    .showMessageDialog(
-                            Main.parent,
-                            tr("The downloaded OSM area is too big. Download mode has been changed to manual until the layer is restarted."));
-        }
-    }
-
-    /**
-     * Returns the MapillaryData object, which acts as the database of the
-     * Layer.
-     *
-     * @return
-     */
-    public MapillaryData getMapillaryData() {
-        return data;
-    }
-
-    /**
-     * Method invoked when the layer is destroyed.
-     */
+      }
+    }
+    // Predownloads the thumbnails
+    if (ret[0] != null)
+      new MapillaryCache(ret[0].getKey(), MapillaryCache.Type.THUMBNAIL)
+          .submit(data, false);
+    if (ret[1] != null)
+      new MapillaryCache(ret[1].getKey(), MapillaryCache.Type.THUMBNAIL)
+          .submit(data, false);
+    return ret;
+  }
+
+  @Override
+  public Object getInfoComponent() {
+    StringBuilder sb = new StringBuilder();
+    sb.append(tr("Mapillary layer"));
+    sb.append("\n");
+    sb.append(tr("Total images:"));
+    sb.append(" ");
+    sb.append(data.size());
+    sb.append("\n");
+    return sb.toString();
+  }
+
+  @Override
+  public String getToolTipText() {
+    return data.size() + " " + tr("images");
+  }
+
+  // EditDataLayerChanged
+  @Override
+  public void editLayerChanged(OsmDataLayer oldLayer, OsmDataLayer newLayer) {
+    if (oldLayer == null && newLayer != null) {
+      newLayer.data.addDataSetListener(this);
+
+    } else if (oldLayer != null && newLayer == null) {
+      oldLayer.data.removeDataSetListener(this);
+    }
+  }
+
+  /**
+   * When more data is downloaded, a delayed update is thrown, in order to wait
+   * for the data bounds to be set.
+   *
+   * @param event
+   */
+  @Override
+  public void dataChanged(DataChangedEvent event) {
+    Main.worker.submit(new delayedDownload());
+  }
+
+  private class delayedDownload extends Thread {
+
     @Override
-    public void destroy() {
-        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);
-        Main.map.mapView.removeMouseListener(mouseAdapter);
-        Main.map.mapView.removeMouseMotionListener(mouseAdapter);
-        MapView.removeEditLayerChangeListener(this);
-        if (Main.map.mapView.getEditLayer() != null)
-            Main.map.mapView.getEditLayer().data.removeDataSetListener(this);
-        super.destroy();
-    }
-
-    /**
-     * Returns true any of the images from the database has been modified.
-     */
-    @Override
-    public boolean isModified() {
-        for (MapillaryAbstractImage image : data.getImages())
-            if (image.isModified())
-                return true;
-        return false;
-    }
-
-    @Override
-    public void setVisible(boolean visible) {
-        super.setVisible(visible);
-        for (MapillaryAbstractImage img : data.getImages())
-            img.setVisible(visible);
-        MapillaryFilterDialog.getInstance().refresh();
-    }
-
-    /**
-     * Replies background color for downloaded areas.
-     *
-     * @return background color for downloaded areas. Black by default
-     */
-    private Color getBackgroundColor() {
-        return Main.pref.getColor(marktr("background"), Color.BLACK);
-    }
-
-    /**
-     * Replies background color for non-downloaded areas.
-     *
-     * @return background color for non-downloaded areas. Yellow by default
-     */
-    private Color getOutsideColor() {
-        return Main.pref.getColor(marktr("outside downloaded area"),
-                Color.YELLOW);
-    }
-
-    /**
-     * Initialize the hatch pattern used to paint the non-downloaded area
-     */
-    private void createHatchTexture() {
-        BufferedImage bi = new BufferedImage(15, 15,
-                BufferedImage.TYPE_INT_ARGB);
-        Graphics2D big = bi.createGraphics();
-        big.setColor(getBackgroundColor());
-        Composite comp = AlphaComposite.getInstance(AlphaComposite.SRC_OVER,
-                0.3f);
-        big.setComposite(comp);
-        big.fillRect(0, 0, 15, 15);
-        big.setColor(getOutsideColor());
-        big.drawLine(0, 15, 15, 0);
-        Rectangle r = new Rectangle(0, 0, 15, 15);
-        hatched = new TexturePaint(bi, r);
-    }
-
-    /**
-     * Paints the database in the map.
-     */
-    @Override
-    public synchronized void paint(Graphics2D g, MapView mv, Bounds box) {
-        if (Main.map.mapView.getActiveLayer() == this) {
-            Rectangle b = mv.getBounds();
-            // on some platforms viewport bounds seem to be offset from the
-            // left,
-            // over-grow it just to be sure
-            b.grow(100, 100);
-            Area a = new Area(b);
-            // now successively subtract downloaded areas
-            for (Bounds bounds : this.bounds) {
-                Point p1 = mv.getPoint(bounds.getMin());
-                Point p2 = mv.getPoint(bounds.getMax());
-                Rectangle r = new Rectangle(Math.min(p1.x, p2.x), Math.min(
-                        p1.y, p2.y), Math.abs(p2.x - p1.x), Math.abs(p2.y
-                        - p1.y));
-                a.subtract(new Area(r));
-            }
-            // paint remainder
-            g.setPaint(hatched);
-            g.fill(a);
-        }
-
-        // Draw colored lines
-        MapillaryLayer.BLUE = null;
-        MapillaryLayer.RED = null;
-        MapillaryMainDialog.getInstance().blueButton.setEnabled(false);
-        MapillaryMainDialog.getInstance().redButton.setEnabled(false);
-
-        // Sets blue and red lines and enables/disables the buttons
-        if (data.getSelectedImage() != null) {
-            MapillaryImage[] closestImages = getClosestImagesFromDifferentSequences();
-            Point selected = mv.getPoint(data.getSelectedImage().getLatLon());
-            if (closestImages[0] != null) {
-                MapillaryLayer.BLUE = closestImages[0];
-                g.setColor(Color.BLUE);
-                g.drawLine(mv.getPoint(closestImages[0].getLatLon()).x,
-                        mv.getPoint(closestImages[0].getLatLon()).y,
-                        selected.x, selected.y);
-                MapillaryMainDialog.getInstance().blueButton.setEnabled(true);
-            }
-            if (closestImages[1] != null) {
-                MapillaryLayer.RED = closestImages[1];
-                g.setColor(Color.RED);
-                g.drawLine(mv.getPoint(closestImages[1].getLatLon()).x,
-                        mv.getPoint(closestImages[1].getLatLon()).y,
-                        selected.x, selected.y);
-                MapillaryMainDialog.getInstance().redButton.setEnabled(true);
-            }
-        }
-        g.setColor(Color.WHITE);
-        for (MapillaryAbstractImage imageAbs : data.getImages()) {
-            if (!imageAbs.isVisible())
-                continue;
-            Point p = mv.getPoint(imageAbs.getLatLon());
-            if (imageAbs instanceof MapillaryImage) {
-                MapillaryImage image = (MapillaryImage) imageAbs;
-                Point nextp = null;
-                // Draw sequence line
-                if (image.getSequence() != null) {
-                    MapillaryImage tempImage = image.next();
-                    while (tempImage != null) {
-                        if (tempImage.isVisible()) {
-                            nextp = mv.getPoint(tempImage.getLatLon());
-                            break;
-                        }
-                        tempImage = tempImage.next();
-                    }
-                    if (nextp != null)
-                        g.drawLine(p.x, p.y, nextp.x, nextp.y);
-                }
-
-                ImageIcon icon;
-                if (!data.getMultiSelectedImages().contains(image))
-                    icon = MapillaryPlugin.MAP_ICON;
-                else
-                    icon = MapillaryPlugin.MAP_ICON_SELECTED;
-                draw(g, image, icon, p);
-                if (!image.getSigns().isEmpty()) {
-                    g.drawImage(MapillaryPlugin.MAP_SIGN.getImage(),
-                            p.x + icon.getIconWidth() / 2,
-                            p.y - icon.getIconHeight() / 2, Main.map.mapView);
-                }
-            } else if (imageAbs instanceof MapillaryImportedImage) {
-                MapillaryImportedImage image = (MapillaryImportedImage) imageAbs;
-                ImageIcon icon;
-                if (!data.getMultiSelectedImages().contains(image))
-                    icon = MapillaryPlugin.MAP_ICON_IMPORTED;
-                else
-                    icon = MapillaryPlugin.MAP_ICON_SELECTED;
-                draw(g, image, icon, p);
-            }
-        }
-    }
-
-    /**
-     * Draws the highlight of the icon.
-     *
-     * @param g
-     * @param p
-     * @param size
-     */
-    private void drawPointHighlight(Graphics2D g, Point p, int size) {
-        Color oldColor = g.getColor();
-        Color highlightColor = PaintColors.HIGHLIGHT.get();
-        Color highlightColorTransparent = new Color(highlightColor.getRed(),
-                highlightColor.getGreen(), highlightColor.getBlue(), 100);
-        g.setColor(highlightColorTransparent);
-        int s = size + highlightPointRadius;
-        while (s >= size) {
-            int r = (int) Math.floor(s / 2d);
-            g.fillRoundRect(p.x - r, p.y - r, s, s, r, r);
-            s -= highlightStep;
-        }
-        g.setColor(oldColor);
-    }
-
-    /**
-     * Draws the given icon of an image. Also checks if the mouse is over the
-     * image.
-     *
-     * @param g
-     * @param image
-     * @param icon
-     * @param p
-     */
-    private void draw(Graphics2D g, MapillaryAbstractImage image,
-            ImageIcon icon, Point p) {
-        Image imagetemp = icon.getImage();
-        BufferedImage bi = (BufferedImage) imagetemp;
-        int width = icon.getIconWidth();
-        int height = icon.getIconHeight();
-
-        // Rotate the image
-        double rotationRequired = Math.toRadians(image.getCa());
-        double locationX = width / 2;
-        double locationY = height / 2;
-        AffineTransform tx = AffineTransform.getRotateInstance(
-                rotationRequired, locationX, locationY);
-        AffineTransformOp op = new AffineTransformOp(tx,
-                AffineTransformOp.TYPE_BILINEAR);
-
-        g.drawImage(op.filter(bi, null), p.x - (width / 2), p.y - (height / 2),
-                Main.map.mapView);
-        if (data.getHoveredImage() == image) {
-            drawPointHighlight(g, p, 16);
-        }
-    }
-
-    @Override
-    public Icon getIcon() {
-        return MapillaryPlugin.ICON16;
-    }
-
-    @Override
-    public boolean isMergable(Layer other) {
-        return false;
-    }
-
-    @Override
-    public void mergeFrom(Layer from) {
-        throw new UnsupportedOperationException(
-                "This layer does not support merging yet");
-    }
-
-    @Override
-    public Action[] getMenuEntries() {
-        List<Action> actions = new ArrayList<>();
-        actions.add(LayerListDialog.getInstance().createShowHideLayerAction());
-        actions.add(LayerListDialog.getInstance().createDeleteLayerAction());
-        actions.add(new LayerListPopup.InfoAction(this));
-        return actions.toArray(new Action[actions.size()]);
-    }
-
-    /**
-     * Returns the 2 closest images belonging to a different sequence.
-     *
-     * @return
-     */
-    private MapillaryImage[] getClosestImagesFromDifferentSequences() {
-        if (!(data.getSelectedImage() instanceof MapillaryImage))
-            return new MapillaryImage[2];
-        MapillaryImage selected = (MapillaryImage) data.getSelectedImage();
-        MapillaryImage[] ret = new MapillaryImage[2];
-        double[] distances = { SEQUENCE_MAX_JUMP_DISTANCE,
-                SEQUENCE_MAX_JUMP_DISTANCE };
-        LatLon selectedCoords = data.getSelectedImage().getLatLon();
-        for (MapillaryAbstractImage imagePrev : data.getImages()) {
-            if (!(imagePrev instanceof MapillaryImage))
-                continue;
-            if (!imagePrev.isVisible())
-                continue;
-            MapillaryImage image = (MapillaryImage) imagePrev;
-            if (image.getLatLon().greatCircleDistance(selectedCoords) < SEQUENCE_MAX_JUMP_DISTANCE
-                    && selected.getSequence() != image.getSequence()) {
-                if ((ret[0] == null && ret[1] == null)
-                        || (image.getLatLon().greatCircleDistance(
-                                selectedCoords) < distances[0] && (ret[1] == null || image
-                                .getSequence() != ret[1].getSequence()))) {
-                    ret[0] = image;
-                    distances[0] = image.getLatLon().greatCircleDistance(
-                            selectedCoords);
-                } else if ((ret[1] == null || image.getLatLon()
-                        .greatCircleDistance(selectedCoords) < distances[1])
-                        && image.getSequence() != ret[0].getSequence()) {
-                    ret[1] = image;
-                    distances[1] = image.getLatLon().greatCircleDistance(
-                            selectedCoords);
-                }
-            }
-        }
-        // Predownloads the thumbnails
-        if (ret[0] != null)
-            new MapillaryCache(ret[0].getKey(), MapillaryCache.Type.THUMBNAIL)
-                    .submit(data, false);
-        if (ret[1] != null)
-            new MapillaryCache(ret[1].getKey(), MapillaryCache.Type.THUMBNAIL)
-                    .submit(data, false);
-        return ret;
-    }
-
-    @Override
-    public Object getInfoComponent() {
-        StringBuilder sb = new StringBuilder();
-        sb.append(tr("Mapillary layer"));
-        sb.append("\n");
-        sb.append(tr("Total images:"));
-        sb.append(" ");
-        sb.append(data.size());
-        sb.append("\n");
-        return sb.toString();
-    }
-
-    @Override
-    public String getToolTipText() {
-        return data.size() + " " + tr("images");
-    }
-
-    // EditDataLayerChanged
-    @Override
-    public void editLayerChanged(OsmDataLayer oldLayer, OsmDataLayer newLayer) {
-        if (oldLayer == null && newLayer != null) {
-            newLayer.data.addDataSetListener(this);
-
-        } else if (oldLayer != null && newLayer == null) {
-            oldLayer.data.removeDataSetListener(this);
-        }
-    }
-
-    /**
-     * When more data is downloaded, a delayed update is thrown, in order to
-     * wait for the data bounds to be set.
-     *
-     * @param event
-     */
-    @Override
-    public void dataChanged(DataChangedEvent event) {
-        Main.worker.submit(new delayedDownload());
-    }
-
-    private class delayedDownload extends Thread {
-
-        @Override
-        public void run() {
-            try {
-                sleep(1000);
-            } catch (InterruptedException e) {
-                Main.error(e);
-            }
-            MapillaryLayer.getInstance().download();
-        }
-    }
-
-    @Override
-    public void primitivesAdded(PrimitivesAddedEvent event) {
-    }
-
-    @Override
-    public void primitivesRemoved(PrimitivesRemovedEvent event) {
-    }
-
-    @Override
-    public void tagsChanged(TagsChangedEvent event) {
-    }
-
-    @Override
-    public void nodeMoved(NodeMovedEvent event) {
-    }
-
-    @Override
-    public void wayNodesChanged(WayNodesChangedEvent event) {
-    }
-
-    @Override
-    public void relationMembersChanged(RelationMembersChangedEvent event) {
-    }
-
-    @Override
-    public void otherDatasetChange(AbstractDatasetChangedEvent event) {
-    }
-
-    @Override
-    public void visitBoundingBox(BoundingXYVisitor v) {
-    }
-
-    @Override
-    public void activeLayerChange(Layer oldLayer, Layer newLayer) {
-        if (newLayer == this) {
-            if (data.size() > 0)
-                Main.map.statusLine.setHelpText(tr("Total images: {0}",
-                        data.size()));
-            else
-                Main.map.statusLine.setHelpText(tr("No images found"));
-        }
-    }
-
-    @Override
-    public void layerAdded(Layer newLayer) {
-    }
-
-    @Override
-    public void layerRemoved(Layer oldLayer) {
-    }
+    public void run() {
+      try {
+        sleep(1000);
+      } catch (InterruptedException e) {
+        Main.error(e);
+      }
+      MapillaryLayer.getInstance().download();
+    }
+  }
+
+  @Override
+  public void primitivesAdded(PrimitivesAddedEvent event) {
+  }
+
+  @Override
+  public void primitivesRemoved(PrimitivesRemovedEvent event) {
+  }
+
+  @Override
+  public void tagsChanged(TagsChangedEvent event) {
+  }
+
+  @Override
+  public void nodeMoved(NodeMovedEvent event) {
+  }
+
+  @Override
+  public void wayNodesChanged(WayNodesChangedEvent event) {
+  }
+
+  @Override
+  public void relationMembersChanged(RelationMembersChangedEvent event) {
+  }
+
+  @Override
+  public void otherDatasetChange(AbstractDatasetChangedEvent event) {
+  }
+
+  @Override
+  public void visitBoundingBox(BoundingXYVisitor v) {
+  }
+
+  @Override
+  public void activeLayerChange(Layer oldLayer, Layer newLayer) {
+    if (newLayer == this) {
+      if (data.size() > 0)
+        Main.map.statusLine.setHelpText(tr("Total images: {0}", data.size()));
+      else
+        Main.map.statusLine.setHelpText(tr("No images found"));
+    }
+  }
+
+  @Override
+  public void layerAdded(Layer newLayer) {
+  }
+
+  @Override
+  public void layerRemoved(Layer oldLayer) {
+  }
 }
Index: applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/MapillaryMouseAdapter.java
===================================================================
--- applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/MapillaryMouseAdapter.java	(revision 31349)
+++ applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/MapillaryMouseAdapter.java	(revision 31350)
@@ -22,224 +22,216 @@
  */
 public class MapillaryMouseAdapter extends MouseAdapter {
-    private Point start;
-    private int lastButton;
-    private MapillaryAbstractImage closest;
-    private MapillaryAbstractImage lastClicked;
-    private MapillaryData mapillaryData;
-    private MapillaryRecord record;
-
-    private boolean nothingHighlighted;
-    private boolean imageHighlighted = false;
-
-    public MapillaryMouseAdapter() {
-        mapillaryData = MapillaryData.getInstance();
-        record = MapillaryRecord.getInstance();
-    }
-
-    @Override
-    public void mousePressed(MouseEvent e) {
-        lastButton = e.getButton();
-        if (e.getButton() != MouseEvent.BUTTON1)
-            return;
-        MapillaryAbstractImage closestTemp = getClosest(e.getPoint());
-        if (Main.map.mapView.getActiveLayer() instanceof OsmDataLayer
-                && closestTemp != null
-                && Main.map.mapMode == Main.map.mapModeSelect) {
-            this.lastClicked = this.closest;
-            MapillaryData.getInstance().setSelectedImage(closestTemp);
-            return;
-        } else if (Main.map.mapView.getActiveLayer() != MapillaryLayer
-                .getInstance())
-            return;
-        if (closestTemp instanceof MapillaryImage || closestTemp == null) {
-            MapillaryImage closest = (MapillaryImage) closestTemp;
-            // Doube click
-            if (e.getClickCount() == 2
-                    && mapillaryData.getSelectedImage() != null
-                    && closest != null) {
-                for (MapillaryAbstractImage img : closest.getSequence()
-                        .getImages()) {
-                    mapillaryData.addMultiSelectedImage(img);
-                }
-            }
-            this.start = e.getPoint();
-            this.lastClicked = this.closest;
-            this.closest = closest;
-            if (mapillaryData.getMultiSelectedImages().contains(closest))
-                return;
-            // ctrl+click
-            if (e.getModifiers() == (MouseEvent.BUTTON1_MASK | MouseEvent.CTRL_MASK)
-                    && closest != null)
-                mapillaryData.addMultiSelectedImage(closest);
-            // shift + click
-            else if (e.getModifiers() == (MouseEvent.BUTTON1_MASK | MouseEvent.SHIFT_MASK)
-                    && this.closest instanceof MapillaryImage
-                    && this.lastClicked instanceof MapillaryImage) {
-                if (this.closest != null
-                        && this.lastClicked != null
-                        && ((MapillaryImage) this.closest).getSequence() == ((MapillaryImage) this.lastClicked)
-                                .getSequence()) {
-                    int i = ((MapillaryImage) this.closest).getSequence()
-                            .getImages().indexOf(this.closest);
-                    int j = ((MapillaryImage) this.lastClicked).getSequence()
-                            .getImages().indexOf(this.lastClicked);
-                    if (i < j)
-                        mapillaryData
-                                .addMultiSelectedImage(new ArrayList<MapillaryAbstractImage>(
-                                        ((MapillaryImage) this.closest)
-                                                .getSequence().getImages()
-                                                .subList(i, j + 1)));
-                    else
-                        mapillaryData
-                                .addMultiSelectedImage(new ArrayList<MapillaryAbstractImage>(
-                                        ((MapillaryImage) this.closest)
-                                                .getSequence().getImages()
-                                                .subList(j, i + 1)));
-                }
-                // click
-            } else
-                mapillaryData.setSelectedImage(closest);
-            // If you select an imported image
-        } else if (closestTemp instanceof MapillaryImportedImage) {
-            MapillaryImportedImage closest = (MapillaryImportedImage) closestTemp;
-            this.start = e.getPoint();
-            this.lastClicked = this.closest;
-            this.closest = closest;
-            if (mapillaryData.getMultiSelectedImages().contains(closest))
-                return;
-            if (e.getModifiers() == (MouseEvent.BUTTON1_MASK | MouseEvent.CTRL_MASK)
-                    && closest != null)
-                mapillaryData.addMultiSelectedImage(closest);
-            else
-                mapillaryData.setSelectedImage(closest);
-        }
-    }
-
-    private MapillaryAbstractImage getClosest(Point clickPoint) {
-        double snapDistance = 10;
-        double minDistance = Double.MAX_VALUE;
-        MapillaryAbstractImage closest = null;
-        for (MapillaryAbstractImage image : mapillaryData.getImages()) {
-            Point imagePoint = Main.map.mapView.getPoint(image.getLatLon());
-            imagePoint.setLocation(imagePoint.getX(), imagePoint.getY());
-            double dist = clickPoint.distanceSq(imagePoint);
-            if (minDistance > dist
-                    && clickPoint.distance(imagePoint) < snapDistance
-                    && image.isVisible()) {
-                minDistance = dist;
-                closest = image;
-            }
-        }
-        return closest;
-    }
-
-    @Override
-    public void mouseDragged(MouseEvent e) {
-        if (Main.map.mapView.getActiveLayer() != MapillaryLayer.getInstance())
-            return;
-
-        if (!Main.pref.getBoolean("mapillary.developer"))
-            for (MapillaryAbstractImage img : MapillaryData.getInstance()
-                    .getMultiSelectedImages()) {
-                if (img instanceof MapillaryImage)
-                    return;
-            }
-        if (MapillaryData.getInstance().getSelectedImage() != null) {
-            if (lastButton == MouseEvent.BUTTON1 && !e.isShiftDown()) {
-                LatLon to = Main.map.mapView.getLatLon(e.getX(), e.getY());
-                LatLon from = Main.map.mapView.getLatLon(start.getX(),
-                        start.getY());
-                for (MapillaryAbstractImage img : MapillaryData.getInstance()
-                        .getMultiSelectedImages()) {
-
-                    img.move(to.getX() - from.getX(), to.getY() - from.getY());
-                }
-                Main.map.repaint();
-            } else if (lastButton == MouseEvent.BUTTON1 && e.isShiftDown()) {
-                this.closest.turn(Math.toDegrees(Math.atan2(
-                        (e.getX() - start.x), -(e.getY() - start.y)))
-                        - closest.getTempCa());
-                for (MapillaryAbstractImage img : MapillaryData.getInstance()
-                        .getMultiSelectedImages()) {
-                    img.turn(Math.toDegrees(Math.atan2((e.getX() - start.x),
-                            -(e.getY() - start.y))) - closest.getTempCa());
-                }
-                Main.map.repaint();
-            }
-        }
-    }
-
-    @Override
-    public void mouseReleased(MouseEvent e) {
-        if (mapillaryData.getSelectedImage() == null)
-            return;
-        if (mapillaryData.getSelectedImage().getTempCa() != mapillaryData
-                .getSelectedImage().getCa()) {
-            double from = mapillaryData.getSelectedImage().getTempCa();
-            double to = mapillaryData.getSelectedImage().getCa();
-            record.addCommand(new CommandTurnImage(mapillaryData
-                    .getMultiSelectedImages(), to - from));
-        } else if (mapillaryData.getSelectedImage().getTempLatLon() != mapillaryData
-                .getSelectedImage().getLatLon()) {
-            LatLon from = mapillaryData.getSelectedImage().getTempLatLon();
-            LatLon to = mapillaryData.getSelectedImage().getLatLon();
-            record.addCommand(new CommandMoveImage(mapillaryData
-                    .getMultiSelectedImages(), to.getX() - from.getX(), to
-                    .getY() - from.getY()));
-        }
-        for (MapillaryAbstractImage img : mapillaryData
-                .getMultiSelectedImages()) {
-            if (img != null)
-                img.stopMoving();
-        }
-    }
-
-    /**
-     * Checks if the mouse is over pictures.
-     */
-    @Override
-    public void mouseMoved(MouseEvent e) {
-        MapillaryAbstractImage closestTemp = getClosest(e.getPoint());
-        if (Main.map.mapView.getActiveLayer() instanceof OsmDataLayer
-                && Main.map.mapMode != Main.map.mapModeSelect)
-            return;
-        if (closestTemp != null
-                && Main.map.mapView.getActiveLayer() instanceof OsmDataLayer
-                && !imageHighlighted) {
-            Main.map.mapMode.putValue("active", Boolean.FALSE);
-            imageHighlighted = true;
-
-        } else if (closestTemp == null
-                && Main.map.mapView.getActiveLayer() instanceof OsmDataLayer
-                && imageHighlighted && nothingHighlighted) {
-            nothingHighlighted = false;
-            Main.map.mapMode.putValue("active", Boolean.TRUE);
-
-        } else if (imageHighlighted && !nothingHighlighted
-                && Main.map.mapView != null
-                && Main.map.mapView.getEditLayer().data != null
-                && Main.map.mapView.getActiveLayer() instanceof OsmDataLayer) {
-
-            for (OsmPrimitive primivitive : Main.map.mapView.getEditLayer().data
-                    .allPrimitives()) {
-                primivitive.setHighlighted(false);
-            }
-            imageHighlighted = false;
-            nothingHighlighted = true;
-        }
-
-        if (MapillaryData.getInstance().getHoveredImage() != closestTemp
-                && closestTemp != null) {
-            MapillaryData.getInstance().setHighlightedImage(closestTemp);
-            MapillaryMainDialog.getInstance().setImage(closestTemp);
-            MapillaryMainDialog.getInstance().updateImage();
-        } else if (MapillaryData.getInstance().getHoveredImage() != closestTemp
-                && closestTemp == null) {
-            MapillaryData.getInstance().setHighlightedImage(null);
-            MapillaryMainDialog.getInstance().setImage(
-                    MapillaryData.getInstance().getSelectedImage());
-            MapillaryMainDialog.getInstance().updateImage();
-        }
-        MapillaryData.getInstance().dataUpdated();
-    }
+  private Point start;
+  private int lastButton;
+  private MapillaryAbstractImage closest;
+  private MapillaryAbstractImage lastClicked;
+  private MapillaryData mapillaryData;
+  private MapillaryRecord record;
+
+  private boolean nothingHighlighted;
+  private boolean imageHighlighted = false;
+
+  public MapillaryMouseAdapter() {
+    mapillaryData = MapillaryData.getInstance();
+    record = MapillaryRecord.getInstance();
+  }
+
+  @Override
+  public void mousePressed(MouseEvent e) {
+    lastButton = e.getButton();
+    if (e.getButton() != MouseEvent.BUTTON1)
+      return;
+    MapillaryAbstractImage closestTemp = getClosest(e.getPoint());
+    if (Main.map.mapView.getActiveLayer() instanceof OsmDataLayer
+        && closestTemp != null && Main.map.mapMode == Main.map.mapModeSelect) {
+      this.lastClicked = this.closest;
+      MapillaryData.getInstance().setSelectedImage(closestTemp);
+      return;
+    } else if (Main.map.mapView.getActiveLayer() != MapillaryLayer
+        .getInstance())
+      return;
+    if (closestTemp instanceof MapillaryImage || closestTemp == null) {
+      MapillaryImage closest = (MapillaryImage) closestTemp;
+      // Doube click
+      if (e.getClickCount() == 2 && mapillaryData.getSelectedImage() != null
+          && closest != null) {
+        for (MapillaryAbstractImage img : closest.getSequence().getImages()) {
+          mapillaryData.addMultiSelectedImage(img);
+        }
+      }
+      this.start = e.getPoint();
+      this.lastClicked = this.closest;
+      this.closest = closest;
+      if (mapillaryData.getMultiSelectedImages().contains(closest))
+        return;
+      // ctrl+click
+      if (e.getModifiers() == (MouseEvent.BUTTON1_MASK | MouseEvent.CTRL_MASK)
+          && closest != null)
+        mapillaryData.addMultiSelectedImage(closest);
+      // shift + click
+      else if (e.getModifiers() == (MouseEvent.BUTTON1_MASK | MouseEvent.SHIFT_MASK)
+          && this.closest instanceof MapillaryImage
+          && this.lastClicked instanceof MapillaryImage) {
+        if (this.closest != null
+            && this.lastClicked != null
+            && ((MapillaryImage) this.closest).getSequence() == ((MapillaryImage) this.lastClicked)
+                .getSequence()) {
+          int i = ((MapillaryImage) this.closest).getSequence().getImages()
+              .indexOf(this.closest);
+          int j = ((MapillaryImage) this.lastClicked).getSequence().getImages()
+              .indexOf(this.lastClicked);
+          if (i < j)
+            mapillaryData
+                .addMultiSelectedImage(new ArrayList<MapillaryAbstractImage>(
+                    ((MapillaryImage) this.closest).getSequence().getImages()
+                        .subList(i, j + 1)));
+          else
+            mapillaryData
+                .addMultiSelectedImage(new ArrayList<MapillaryAbstractImage>(
+                    ((MapillaryImage) this.closest).getSequence().getImages()
+                        .subList(j, i + 1)));
+        }
+        // click
+      } else
+        mapillaryData.setSelectedImage(closest);
+      // If you select an imported image
+    } else if (closestTemp instanceof MapillaryImportedImage) {
+      MapillaryImportedImage closest = (MapillaryImportedImage) closestTemp;
+      this.start = e.getPoint();
+      this.lastClicked = this.closest;
+      this.closest = closest;
+      if (mapillaryData.getMultiSelectedImages().contains(closest))
+        return;
+      if (e.getModifiers() == (MouseEvent.BUTTON1_MASK | MouseEvent.CTRL_MASK)
+          && closest != null)
+        mapillaryData.addMultiSelectedImage(closest);
+      else
+        mapillaryData.setSelectedImage(closest);
+    }
+  }
+
+  private MapillaryAbstractImage getClosest(Point clickPoint) {
+    double snapDistance = 10;
+    double minDistance = Double.MAX_VALUE;
+    MapillaryAbstractImage closest = null;
+    for (MapillaryAbstractImage image : mapillaryData.getImages()) {
+      Point imagePoint = Main.map.mapView.getPoint(image.getLatLon());
+      imagePoint.setLocation(imagePoint.getX(), imagePoint.getY());
+      double dist = clickPoint.distanceSq(imagePoint);
+      if (minDistance > dist && clickPoint.distance(imagePoint) < snapDistance
+          && image.isVisible()) {
+        minDistance = dist;
+        closest = image;
+      }
+    }
+    return closest;
+  }
+
+  @Override
+  public void mouseDragged(MouseEvent e) {
+    if (Main.map.mapView.getActiveLayer() != MapillaryLayer.getInstance())
+      return;
+
+    if (!Main.pref.getBoolean("mapillary.developer"))
+      for (MapillaryAbstractImage img : MapillaryData.getInstance()
+          .getMultiSelectedImages()) {
+        if (img instanceof MapillaryImage)
+          return;
+      }
+    if (MapillaryData.getInstance().getSelectedImage() != null) {
+      if (lastButton == MouseEvent.BUTTON1 && !e.isShiftDown()) {
+        LatLon to = Main.map.mapView.getLatLon(e.getX(), e.getY());
+        LatLon from = Main.map.mapView.getLatLon(start.getX(), start.getY());
+        for (MapillaryAbstractImage img : MapillaryData.getInstance()
+            .getMultiSelectedImages()) {
+
+          img.move(to.getX() - from.getX(), to.getY() - from.getY());
+        }
+        Main.map.repaint();
+      } else if (lastButton == MouseEvent.BUTTON1 && e.isShiftDown()) {
+        this.closest.turn(Math.toDegrees(Math.atan2((e.getX() - start.x),
+            -(e.getY() - start.y)))
+            - closest.getTempCa());
+        for (MapillaryAbstractImage img : MapillaryData.getInstance()
+            .getMultiSelectedImages()) {
+          img.turn(Math.toDegrees(Math.atan2((e.getX() - start.x),
+              -(e.getY() - start.y))) - closest.getTempCa());
+        }
+        Main.map.repaint();
+      }
+    }
+  }
+
+  @Override
+  public void mouseReleased(MouseEvent e) {
+    if (mapillaryData.getSelectedImage() == null)
+      return;
+    if (mapillaryData.getSelectedImage().getTempCa() != mapillaryData
+        .getSelectedImage().getCa()) {
+      double from = mapillaryData.getSelectedImage().getTempCa();
+      double to = mapillaryData.getSelectedImage().getCa();
+      record.addCommand(new CommandTurnImage(mapillaryData
+          .getMultiSelectedImages(), to - from));
+    } else if (mapillaryData.getSelectedImage().getTempLatLon() != mapillaryData
+        .getSelectedImage().getLatLon()) {
+      LatLon from = mapillaryData.getSelectedImage().getTempLatLon();
+      LatLon to = mapillaryData.getSelectedImage().getLatLon();
+      record.addCommand(new CommandMoveImage(mapillaryData
+          .getMultiSelectedImages(), to.getX() - from.getX(), to.getY()
+          - from.getY()));
+    }
+    for (MapillaryAbstractImage img : mapillaryData.getMultiSelectedImages()) {
+      if (img != null)
+        img.stopMoving();
+    }
+  }
+
+  /**
+   * Checks if the mouse is over pictures.
+   */
+  @Override
+  public void mouseMoved(MouseEvent e) {
+    MapillaryAbstractImage closestTemp = getClosest(e.getPoint());
+    if (Main.map.mapView.getActiveLayer() instanceof OsmDataLayer
+        && Main.map.mapMode != Main.map.mapModeSelect)
+      return;
+    if (closestTemp != null
+        && Main.map.mapView.getActiveLayer() instanceof OsmDataLayer
+        && !imageHighlighted) {
+      Main.map.mapMode.putValue("active", Boolean.FALSE);
+      imageHighlighted = true;
+
+    } else if (closestTemp == null
+        && Main.map.mapView.getActiveLayer() instanceof OsmDataLayer
+        && imageHighlighted && nothingHighlighted) {
+      nothingHighlighted = false;
+      Main.map.mapMode.putValue("active", Boolean.TRUE);
+
+    } else if (imageHighlighted && !nothingHighlighted
+        && Main.map.mapView != null
+        && Main.map.mapView.getEditLayer().data != null
+        && Main.map.mapView.getActiveLayer() instanceof OsmDataLayer) {
+
+      for (OsmPrimitive primivitive : Main.map.mapView.getEditLayer().data
+          .allPrimitives()) {
+        primivitive.setHighlighted(false);
+      }
+      imageHighlighted = false;
+      nothingHighlighted = true;
+    }
+
+    if (MapillaryData.getInstance().getHoveredImage() != closestTemp
+        && closestTemp != null) {
+      MapillaryData.getInstance().setHighlightedImage(closestTemp);
+      MapillaryMainDialog.getInstance().setImage(closestTemp);
+      MapillaryMainDialog.getInstance().updateImage();
+    } else if (MapillaryData.getInstance().getHoveredImage() != closestTemp
+        && closestTemp == null) {
+      MapillaryData.getInstance().setHighlightedImage(null);
+      MapillaryMainDialog.getInstance().setImage(
+          MapillaryData.getInstance().getSelectedImage());
+      MapillaryMainDialog.getInstance().updateImage();
+    }
+    MapillaryData.getInstance().dataUpdated();
+  }
 }
Index: applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/MapillaryPlugin.java
===================================================================
--- applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/MapillaryPlugin.java	(revision 31349)
+++ applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/MapillaryPlugin.java	(revision 31350)
@@ -33,108 +33,103 @@
 public class MapillaryPlugin extends Plugin implements EditLayerChangeListener {
 
-    public static final ImageIcon ICON24 = new ImageProvider("icon24.png")
-            .get();
-    public static final ImageIcon ICON16 = new ImageProvider("icon16.png")
-            .get();
-    public static final ImageIcon MAP_ICON = new ImageProvider("mapicon.png")
-            .get();
-    public static final ImageIcon MAP_ICON_SELECTED = new ImageProvider(
-            "mapiconselected.png").get();
-    public static final ImageIcon MAP_ICON_IMPORTED = new ImageProvider(
-            "mapiconimported.png").get();
-    public static final ImageIcon MAP_SIGN = new ImageProvider("sign.png")
-            .get();
-    public static final int ICON_SIZE = 24;
+  public static final ImageIcon ICON24 = new ImageProvider("icon24.png").get();
+  public static final ImageIcon ICON16 = new ImageProvider("icon16.png").get();
+  public static final ImageIcon MAP_ICON = new ImageProvider("mapicon.png")
+      .get();
+  public static final ImageIcon MAP_ICON_SELECTED = new ImageProvider(
+      "mapiconselected.png").get();
+  public static final ImageIcon MAP_ICON_IMPORTED = new ImageProvider(
+      "mapiconimported.png").get();
+  public static final ImageIcon MAP_SIGN = new ImageProvider("sign.png").get();
+  public static final int ICON_SIZE = 24;
 
-    public static CacheAccess<String, BufferedImageCacheEntry> CACHE;
+  public static CacheAccess<String, BufferedImageCacheEntry> CACHE;
 
-    private final MapillaryDownloadAction downloadAction;
-    private final MapillaryExportAction exportAction;
-    private final MapillaryImportAction importAction;
-    private final MapillaryZoomAction zoomAction;
-    private final MapillaryDownloadViewAction downloadViewAction;
+  private final MapillaryDownloadAction downloadAction;
+  private final MapillaryExportAction exportAction;
+  private final MapillaryImportAction importAction;
+  private final MapillaryZoomAction zoomAction;
+  private final MapillaryDownloadViewAction downloadViewAction;
 
-    public static JMenuItem DOWNLOAD_MENU;
-    public static JMenuItem EXPORT_MENU;
-    public static JMenuItem IMPORT_MENU;
-    public static JMenuItem ZOOM_MENU;
-    public static JMenuItem DOWNLOAD_VIEW_MENU;
+  public static JMenuItem DOWNLOAD_MENU;
+  public static JMenuItem EXPORT_MENU;
+  public static JMenuItem IMPORT_MENU;
+  public static JMenuItem ZOOM_MENU;
+  public static JMenuItem DOWNLOAD_VIEW_MENU;
 
-    public MapillaryPlugin(PluginInformation info) {
-        super(info);
-        downloadAction = new MapillaryDownloadAction();
-        exportAction = new MapillaryExportAction();
-        importAction = new MapillaryImportAction();
-        zoomAction = new MapillaryZoomAction();
-        downloadViewAction = new MapillaryDownloadViewAction();
+  public MapillaryPlugin(PluginInformation info) {
+    super(info);
+    downloadAction = new MapillaryDownloadAction();
+    exportAction = new MapillaryExportAction();
+    importAction = new MapillaryImportAction();
+    zoomAction = new MapillaryZoomAction();
+    downloadViewAction = new MapillaryDownloadViewAction();
 
-        if (Main.main != null) { // important for headless mode
-            DOWNLOAD_MENU = MainMenu.add(Main.main.menu.imageryMenu,
-                    downloadAction, false);
-            EXPORT_MENU = MainMenu.add(Main.main.menu.fileMenu, exportAction,
-                    false, 14);
-            IMPORT_MENU = MainMenu.add(Main.main.menu.fileMenu, importAction,
-                    false, 14);
-            ZOOM_MENU = MainMenu
-                    .add(Main.main.menu.viewMenu, zoomAction, false, 15);
-            DOWNLOAD_VIEW_MENU = MainMenu.add(Main.main.menu.fileMenu,
-                    downloadViewAction, false, 14);
-        }
-
-        EXPORT_MENU.setEnabled(false);
-        DOWNLOAD_MENU.setEnabled(false);
-        IMPORT_MENU.setEnabled(false);
-        ZOOM_MENU.setEnabled(false);
-        DOWNLOAD_VIEW_MENU.setEnabled(false);
-
-        MapView.addEditLayerChangeListener(this);
-        try {
-            CACHE = JCSCacheManager.getCache("mapillary", 10, 10000,
-                    this.getPluginDir() + "/cache/");
-        } catch (IOException e) {
-            Main.error(e);
-        }
+    if (Main.main != null) { // important for headless mode
+      DOWNLOAD_MENU = MainMenu.add(Main.main.menu.imageryMenu, downloadAction,
+          false);
+      EXPORT_MENU = MainMenu.add(Main.main.menu.fileMenu, exportAction, false,
+          14);
+      IMPORT_MENU = MainMenu.add(Main.main.menu.fileMenu, importAction, false,
+          14);
+      ZOOM_MENU = MainMenu.add(Main.main.menu.viewMenu, zoomAction, false, 15);
+      DOWNLOAD_VIEW_MENU = MainMenu.add(Main.main.menu.fileMenu,
+          downloadViewAction, false, 14);
     }
 
-    /**
-     * Called when the JOSM map frame is created or destroyed.
-     */
-    @Override
-    public void mapFrameInitialized(MapFrame oldFrame, MapFrame newFrame) {
-        if (oldFrame == null && newFrame != null) { // map frame added
-            Main.map.addToggleDialog(MapillaryMainDialog.getInstance(), false);
-            Main.map.addToggleDialog(MapillaryHistoryDialog.getInstance(),
-                    false);
-            Main.map.addToggleDialog(MapillaryFilterDialog.getInstance(), false);
-            setMenuEnabled(DOWNLOAD_MENU, true);
-            if (Main.pref.getBoolean("mapillary.download-manually"))
-                setMenuEnabled(DOWNLOAD_VIEW_MENU, true);
-            setMenuEnabled(IMPORT_MENU, true);
-        }
-        if (oldFrame != null && newFrame == null) { // map frame destroyed
-            MapillaryMainDialog.destroyInstance();
-            MapillaryHistoryDialog.destroyInstance();
-            MapillaryFilterDialog.destroyInstance();
-            setMenuEnabled(DOWNLOAD_MENU, false);
-            setMenuEnabled(DOWNLOAD_VIEW_MENU, false);
-            setMenuEnabled(IMPORT_MENU, false);
-        }
+    EXPORT_MENU.setEnabled(false);
+    DOWNLOAD_MENU.setEnabled(false);
+    IMPORT_MENU.setEnabled(false);
+    ZOOM_MENU.setEnabled(false);
+    DOWNLOAD_VIEW_MENU.setEnabled(false);
+
+    MapView.addEditLayerChangeListener(this);
+    try {
+      CACHE = JCSCacheManager.getCache("mapillary", 10, 10000,
+          this.getPluginDir() + "/cache/");
+    } catch (IOException e) {
+      Main.error(e);
     }
+  }
 
-    public static void setMenuEnabled(JMenuItem menu, boolean value) {
-        menu.setEnabled(value);
-        menu.getAction().setEnabled(value);
+  /**
+   * Called when the JOSM map frame is created or destroyed.
+   */
+  @Override
+  public void mapFrameInitialized(MapFrame oldFrame, MapFrame newFrame) {
+    if (oldFrame == null && newFrame != null) { // map frame added
+      Main.map.addToggleDialog(MapillaryMainDialog.getInstance(), false);
+      Main.map.addToggleDialog(MapillaryHistoryDialog.getInstance(), false);
+      Main.map.addToggleDialog(MapillaryFilterDialog.getInstance(), false);
+      setMenuEnabled(DOWNLOAD_MENU, true);
+      if (Main.pref.getBoolean("mapillary.download-manually"))
+        setMenuEnabled(DOWNLOAD_VIEW_MENU, true);
+      setMenuEnabled(IMPORT_MENU, true);
     }
+    if (oldFrame != null && newFrame == null) { // map frame destroyed
+      MapillaryMainDialog.destroyInstance();
+      MapillaryHistoryDialog.destroyInstance();
+      MapillaryFilterDialog.destroyInstance();
+      setMenuEnabled(DOWNLOAD_MENU, false);
+      setMenuEnabled(DOWNLOAD_VIEW_MENU, false);
+      setMenuEnabled(IMPORT_MENU, false);
+    }
+  }
 
-    @Override
-    public PreferenceSetting getPreferenceSetting() {
-        return new MapillaryPreferenceSetting();
+  public static void setMenuEnabled(JMenuItem menu, boolean value) {
+    menu.setEnabled(value);
+    menu.getAction().setEnabled(value);
+  }
+
+  @Override
+  public PreferenceSetting getPreferenceSetting() {
+    return new MapillaryPreferenceSetting();
+  }
+
+  @Override
+  public void editLayerChanged(OsmDataLayer oldLayer, OsmDataLayer newLayer) {
+    if (oldLayer == null && newLayer != null) {
+    } else if (oldLayer != null && newLayer == null) {
     }
-
-    @Override
-    public void editLayerChanged(OsmDataLayer oldLayer, OsmDataLayer newLayer) {
-        if (oldLayer == null && newLayer != null) {
-        } else if (oldLayer != null && newLayer == null) {
-        }
-    }
+  }
 }
Index: applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/MapillarySequence.java
===================================================================
--- applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/MapillarySequence.java	(revision 31349)
+++ applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/MapillarySequence.java	(revision 31350)
@@ -12,116 +12,115 @@
  */
 public class MapillarySequence {
-    private final List<MapillaryImage> images;
-    private final String key;
-    private final long created_at;
+  private final List<MapillaryImage> images;
+  private final String key;
+  private final long created_at;
 
-    public MapillarySequence(String key, long created_at) {
-        this.images = new ArrayList<>();
-        this.key = key;
-        this.created_at = created_at;
-    }
+  public MapillarySequence(String key, long created_at) {
+    this.images = new ArrayList<>();
+    this.key = key;
+    this.created_at = created_at;
+  }
 
-    /**
-     * Returns all MapillaryImages objects contained by this object.
-     * 
-     * @return
-     */
-    public List<MapillaryImage> getImages() {
-        return this.images;
-    }
+  /**
+   * Returns all MapillaryImages objects contained by this object.
+   * 
+   * @return
+   */
+  public List<MapillaryImage> getImages() {
+    return this.images;
+  }
 
-    public long getCreatedAt() {
-        return created_at;
-    }
+  public long getCreatedAt() {
+    return created_at;
+  }
 
-    /**
-     * Adds a new MapillaryImage object to this object.
-     * 
-     * @param image
-     */
-    public synchronized void add(MapillaryImage image) {
-        this.images.add(image);
-    }
+  /**
+   * Adds a new MapillaryImage object to this object.
+   * 
+   * @param image
+   */
+  public synchronized void add(MapillaryImage image) {
+    this.images.add(image);
+  }
 
-    public String getKey() {
-        return this.key;
-    }
+  public String getKey() {
+    return this.key;
+  }
 
-    /**
-     * Adds a set of MapillaryImage objects to this object.
-     * 
-     * @param images
-     */
-    public synchronized void add(List<MapillaryImage> images) {
-        for (MapillaryImage image : images)
-            add(image);
-    }
+  /**
+   * Adds a set of MapillaryImage objects to this object.
+   * 
+   * @param images
+   */
+  public synchronized void add(List<MapillaryImage> images) {
+    for (MapillaryImage image : images)
+      add(image);
+  }
 
-    /**
-     * Removes a MapillaryImage object from this object.
-     * 
-     * @param image
-     */
-    public void remove(MapillaryImage image) {
-        this.images.remove(image);
-    }
+  /**
+   * Removes a MapillaryImage object from this object.
+   * 
+   * @param image
+   */
+  public void remove(MapillaryImage image) {
+    this.images.remove(image);
+  }
 
-    /**
-     * Returns the next MapillaryImage in the sequence.
-     * 
-     * @param image
-     * @return
-     */
-    public MapillaryImage next(MapillaryImage image) {
-        if (!images.contains(image))
-            throw new IllegalArgumentException();
-        int i = images.indexOf(image);
-        if (i == images.size() - 1)
-            return null;
-        else
-            return images.get(i + 1);
-    }
+  /**
+   * Returns the next MapillaryImage in the sequence.
+   * 
+   * @param image
+   * @return
+   */
+  public MapillaryImage next(MapillaryImage image) {
+    if (!images.contains(image))
+      throw new IllegalArgumentException();
+    int i = images.indexOf(image);
+    if (i == images.size() - 1)
+      return null;
+    else
+      return images.get(i + 1);
+  }
 
-    /**
-     * Returns the previous MapillaryImage in the sequence.
-     * 
-     * @param image
-     * @return
-     */
-    public MapillaryImage previous(MapillaryImage image) {
-        if (!images.contains(image))
-            throw new IllegalArgumentException();
-        int i = images.indexOf(image);
-        if (i == 0)
-            return null;
-        else
-            return images.get(i - 1);
-    }
+  /**
+   * Returns the previous MapillaryImage in the sequence.
+   * 
+   * @param image
+   * @return
+   */
+  public MapillaryImage previous(MapillaryImage image) {
+    if (!images.contains(image))
+      throw new IllegalArgumentException();
+    int i = images.indexOf(image);
+    if (i == 0)
+      return null;
+    else
+      return images.get(i - 1);
+  }
 
-    /**
-     * Returns the difference of index between two MapillaryImage objects
-     * belonging to the same MapillarySequence.
-     * 
-     * @param image1
-     * @param image2
-     * @return
-     */
-    public int getDistance(MapillaryImage image1, MapillaryImage image2) {
-        if (!this.images.contains(image1) || !this.images.contains(image2))
-            throw new IllegalArgumentException();
-        return Math.abs(this.images.indexOf(image1)
-                - this.images.indexOf(image2));
-    }
+  /**
+   * Returns the difference of index between two MapillaryImage objects
+   * belonging to the same MapillarySequence.
+   * 
+   * @param image1
+   * @param image2
+   * @return
+   */
+  public int getDistance(MapillaryImage image1, MapillaryImage image2) {
+    if (!this.images.contains(image1) || !this.images.contains(image2))
+      throw new IllegalArgumentException();
+    return Math.abs(this.images.indexOf(image1) - this.images.indexOf(image2));
+  }
 
-    @Override
-    public boolean equals(Object obj) {
-        if (obj instanceof MapillarySequence)
-            return this.getKey().equals(((MapillarySequence) obj).getKey());
-        return false;
-    }
+  @Override
+  public boolean equals(Object obj) {
+    if (obj instanceof MapillarySequence)
+      return this.getKey().equals(((MapillarySequence) obj).getKey());
+    return false;
+  }
 
-    @Override
-    public int hashCode() {
-        return this.key.hashCode();
-    }
+  @Override
+  public int hashCode() {
+    return this.key.hashCode();
+  }
 }
Index: applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/actions/MapillaryDownloadAction.java
===================================================================
--- applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/actions/MapillaryDownloadAction.java	(revision 31349)
+++ applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/actions/MapillaryDownloadAction.java	(revision 31350)
@@ -18,5 +18,5 @@
  * Action that triggers the plugin. If in automatic mode, it will automatically
  * download the images in the areas where there is OSM data.
- * 
+ *
  * @author nokutu
  *
@@ -24,26 +24,23 @@
 public class MapillaryDownloadAction extends JosmAction {
 
-    public MapillaryDownloadAction() {
-        super(tr("Mapillary"), new ImageProvider("icon24.png"),
-                tr("Create Mapillary layer"), Shortcut.registerShortcut(
-                        "Mapillary", tr("Start Mapillary layer"),
-                        KeyEvent.VK_COMMA, Shortcut.SHIFT), false,
-                "mapillaryDownload", false);
-        this.setEnabled(false);
+  public MapillaryDownloadAction() {
+    super(tr("Mapillary"), new ImageProvider("icon24.png"),
+        tr("Create Mapillary layer"), Shortcut.registerShortcut("Mapillary",
+            tr("Start Mapillary layer"), KeyEvent.VK_COMMA, Shortcut.SHIFT),
+        false, "mapillaryDownload", false);
+    this.setEnabled(false);
+  }
+
+  @Override
+  public void actionPerformed(ActionEvent arg0) {
+    if (MapillaryLayer.INSTANCE == null) {
+      if (Main.map.mapView.getEditLayer() != null)
+        MapillaryLayer.getInstance().download();
+    } else {
+      if (Main.map.mapView.getActiveLayer() != MapillaryLayer.getInstance())
+        Main.map.mapView.setActiveLayer(MapillaryLayer.getInstance());
+      else
+        Main.map.mapView.setActiveLayer(Main.map.mapView.getEditLayer());
     }
-
-    @Override
-    public void actionPerformed(ActionEvent arg0) {
-        if (MapillaryLayer.INSTANCE == null) {
-            if (Main.map.mapView.getEditLayer() != null)
-                MapillaryLayer.getInstance().download();
-        } else {
-            if (Main.map.mapView.getActiveLayer() != MapillaryLayer
-                    .getInstance())
-                Main.map.mapView.setActiveLayer(MapillaryLayer.getInstance());
-            else
-                Main.map.mapView
-                        .setActiveLayer(Main.map.mapView.getEditLayer());
-        }
-    }
+  }
 }
Index: applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/actions/MapillaryDownloadViewAction.java
===================================================================
--- applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/actions/MapillaryDownloadViewAction.java	(revision 31349)
+++ applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/actions/MapillaryDownloadViewAction.java	(revision 31350)
@@ -23,29 +23,25 @@
 public class MapillaryDownloadViewAction extends JosmAction {
 
-    public static final double MAX_AREA = Main.pref.getDouble(
-            "mapillary.max-download-area", 0.020);
+  public static final double MAX_AREA = Main.pref.getDouble(
+      "mapillary.max-download-area", 0.020);
 
-    public MapillaryDownloadViewAction() {
-        super(tr("Download Mapillary images in current view"),
-                new ImageProvider("icon24.png"),
-                tr("Download Mapillary images in current view"),
-                Shortcut.registerShortcut("Mapillary area",
-                        tr("Download Mapillary images in current view"),
-                        KeyEvent.VK_PERIOD, Shortcut.SHIFT), false,
-                "mapillaryArea", false);
-        this.setEnabled(false);
+  public MapillaryDownloadViewAction() {
+    super(tr("Download Mapillary images in current view"), new ImageProvider(
+        "icon24.png"), tr("Download Mapillary images in current view"),
+        Shortcut.registerShortcut("Mapillary area",
+            tr("Download Mapillary images in current view"),
+            KeyEvent.VK_PERIOD, Shortcut.SHIFT), false, "mapillaryArea", false);
+    this.setEnabled(false);
+  }
+
+  @Override
+  public void actionPerformed(ActionEvent arg0) {
+    MapillaryLayer.getInstance().bounds.add(Main.map.mapView.getRealBounds());
+    if (Main.map.mapView.getRealBounds().getArea() <= MAX_AREA) {
+      new MapillaryDownloader().getImages(Main.map.mapView.getRealBounds());
+    } else {
+      JOptionPane.showMessageDialog(Main.parent,
+          tr("This area is too big to be downloaded"));
     }
-
-    @Override
-    public void actionPerformed(ActionEvent arg0) {
-        MapillaryLayer.getInstance().bounds.add(Main.map.mapView
-                .getRealBounds());
-        if (Main.map.mapView.getRealBounds().getArea() <= MAX_AREA) {
-            new MapillaryDownloader().getImages(Main.map.mapView
-                    .getRealBounds());
-        } else {
-            JOptionPane.showMessageDialog(Main.parent,
-                    tr("This area is too big to be downloaded"));
-        }
-    }
+  }
 }
Index: applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/actions/MapillaryExportAction.java
===================================================================
--- applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/actions/MapillaryExportAction.java	(revision 31349)
+++ applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/actions/MapillaryExportAction.java	(revision 31350)
@@ -32,69 +32,66 @@
 public class MapillaryExportAction extends JosmAction {
 
-    MapillaryExportDialog dialog;
+  MapillaryExportDialog dialog;
 
-    public MapillaryExportAction() {
-        super(tr("Export pictures"), new ImageProvider("icon24.png"),
-                tr("Export pictures"), Shortcut.registerShortcut(
-                        "Export Mapillary", tr("Export Mapillary pictures"),
-                        KeyEvent.CHAR_UNDEFINED, Shortcut.NONE), false,
-                "mapillaryExport", false);
-        this.setEnabled(false);
+  public MapillaryExportAction() {
+    super(tr("Export pictures"), new ImageProvider("icon24.png"),
+        tr("Export pictures"), Shortcut.registerShortcut("Export Mapillary",
+            tr("Export Mapillary pictures"), KeyEvent.CHAR_UNDEFINED,
+            Shortcut.NONE), false, "mapillaryExport", false);
+    this.setEnabled(false);
+  }
+
+  @Override
+  public void actionPerformed(ActionEvent e) {
+    dialog = new MapillaryExportDialog();
+    JOptionPane pane = new JOptionPane(dialog, JOptionPane.PLAIN_MESSAGE,
+        JOptionPane.OK_CANCEL_OPTION);
+    JDialog dlg = pane.createDialog(Main.parent, tr("Export images"));
+    dlg.setMinimumSize(new Dimension(400, 150));
+    dlg.setVisible(true);
+
+    // Checks if the inputs are correct and starts the export process.
+    if (pane.getValue() != null
+        && (int) pane.getValue() == JOptionPane.OK_OPTION
+        && dialog.chooser != null) {
+      if (dialog.group.isSelected(dialog.all.getModel())) {
+        export(MapillaryData.getInstance().getImages());
+      } else if (dialog.group.isSelected(dialog.sequence.getModel())) {
+        ArrayList<MapillaryAbstractImage> images = new ArrayList<>();
+        for (MapillaryAbstractImage image : MapillaryData.getInstance()
+            .getMultiSelectedImages())
+          if (image instanceof MapillaryImage) {
+            if (!images.contains(image))
+              images.addAll(((MapillaryImage) image).getSequence().getImages());
+          } else
+            images.add(image);
+        export(images);
+      } else if (dialog.group.isSelected(dialog.selected.getModel())) {
+        export(MapillaryData.getInstance().getMultiSelectedImages());
+      }
+      // This option ignores the selected directory.
+    } else if (dialog.group.isSelected(dialog.rewrite.getModel())) {
+      ArrayList<MapillaryImportedImage> images = new ArrayList<>();
+      for (MapillaryAbstractImage image : MapillaryData.getInstance()
+          .getImages())
+        if (image instanceof MapillaryImportedImage) {
+          images.add(((MapillaryImportedImage) image));
+        }
+      try {
+        Main.worker.submit(new Thread(new MapillaryExportManager(images)));
+      } catch (IOException e1) {
+        Main.error(e1);
+      }
     }
+    dlg.dispose();
+  }
 
-    @Override
-    public void actionPerformed(ActionEvent e) {
-        dialog = new MapillaryExportDialog();
-        JOptionPane pane = new JOptionPane(dialog, JOptionPane.PLAIN_MESSAGE,
-                JOptionPane.OK_CANCEL_OPTION);
-        JDialog dlg = pane.createDialog(Main.parent, tr("Export images"));
-        dlg.setMinimumSize(new Dimension(400, 150));
-        dlg.setVisible(true);
-
-        // Checks if the inputs are correct and starts the export process.
-        if (pane.getValue() != null
-                && (int) pane.getValue() == JOptionPane.OK_OPTION
-                && dialog.chooser != null) {
-            if (dialog.group.isSelected(dialog.all.getModel())) {
-                export(MapillaryData.getInstance().getImages());
-            } else if (dialog.group.isSelected(dialog.sequence.getModel())) {
-                ArrayList<MapillaryAbstractImage> images = new ArrayList<>();
-                for (MapillaryAbstractImage image : MapillaryData.getInstance()
-                        .getMultiSelectedImages())
-                    if (image instanceof MapillaryImage) {
-                        if (!images.contains(image))
-                            images.addAll(((MapillaryImage) image)
-                                    .getSequence().getImages());
-                    } else
-                        images.add(image);
-                export(images);
-            } else if (dialog.group.isSelected(dialog.selected.getModel())) {
-                export(MapillaryData.getInstance().getMultiSelectedImages());
-            }
-            // This option ignores the selected directory.
-        } else if (dialog.group.isSelected(dialog.rewrite.getModel())) {
-            ArrayList<MapillaryImportedImage> images = new ArrayList<>();
-            for (MapillaryAbstractImage image : MapillaryData.getInstance()
-                    .getImages())
-                if (image instanceof MapillaryImportedImage) {
-                    images.add(((MapillaryImportedImage) image));
-                }
-            try {
-                Main.worker.submit(new Thread(
-                        new MapillaryExportManager(images)));
-            } catch (IOException e1) {
-                Main.error(e1);
-            }
-        }
-        dlg.dispose();
-    }
-
-    /**
-     * Exports the given images from the database.
-     */
-    public void export(List<MapillaryAbstractImage> images) {
-        Main.worker.submit(new Thread(new MapillaryExportManager(images,
-                dialog.chooser.getSelectedFile().toString())));
-    }
+  /**
+   * Exports the given images from the database.
+   */
+  public void export(List<MapillaryAbstractImage> images) {
+    Main.worker.submit(new Thread(new MapillaryExportManager(images,
+        dialog.chooser.getSelectedFile().toString())));
+  }
 
 }
Index: applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/actions/MapillaryImportAction.java
===================================================================
--- applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/actions/MapillaryImportAction.java	(revision 31349)
+++ applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/actions/MapillaryImportAction.java	(revision 31350)
@@ -30,5 +30,5 @@
 /**
  * Imports a set of picture files into JOSM. They must be in jpg or png format.
- * 
+ *
  * @author nokutu
  *
@@ -36,147 +36,141 @@
 public class MapillaryImportAction extends JosmAction {
 
-    public JFileChooser chooser;
+  public JFileChooser chooser;
 
-    /**
-     * Amount of pictures without the proper EXIF tags.
-     */
-    private int noTagsPics = 0;
+  /**
+   * Amount of pictures without the proper EXIF tags.
+   */
+  private int noTagsPics = 0;
 
-    public MapillaryImportAction() {
-        super(tr("Import pictures"), new ImageProvider("icon24.png"),
-                tr("Import local pictures"), Shortcut.registerShortcut(
-                        "Import Mapillary",
-                        tr("Import pictures into Mapillary layer"),
-                        KeyEvent.CHAR_UNDEFINED, Shortcut.NONE), false,
-                "mapillaryImport", false);
-        this.setEnabled(false);
+  public MapillaryImportAction() {
+    super(tr("Import pictures"), new ImageProvider("icon24.png"),
+        tr("Import local pictures"), Shortcut.registerShortcut(
+            "Import Mapillary", tr("Import pictures into Mapillary layer"),
+            KeyEvent.CHAR_UNDEFINED, Shortcut.NONE), false, "mapillaryImport",
+        false);
+    this.setEnabled(false);
+  }
+
+  @Override
+  public void actionPerformed(ActionEvent e) {
+    chooser = new JFileChooser();
+    chooser.setCurrentDirectory(new java.io.File(System
+        .getProperty("user.home")));
+    chooser.setDialogTitle(tr("Select pictures"));
+    chooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
+    chooser.setAcceptAllFileFilterUsed(false);
+    chooser.addChoosableFileFilter(new FileNameExtensionFilter("images", "jpg",
+        "jpeg", "png"));
+    chooser.setMultiSelectionEnabled(true);
+    if (chooser.showOpenDialog(Main.parent) == JFileChooser.APPROVE_OPTION) {
+      for (int i = 0; i < chooser.getSelectedFiles().length; i++) {
+        File file = chooser.getSelectedFiles()[i];
+        if (file.isDirectory()) {
+
+        } else {
+          MapillaryLayer.getInstance();
+          if (file.getPath().substring(file.getPath().length() - 4)
+              .equals(".jpg")
+              || file.getPath().substring(file.getPath().length() - 5)
+                  .equals(".jpeg")) {
+            try {
+              readJPG(file);
+            } catch (ImageReadException ex) {
+              Main.error(ex);
+            } catch (IOException ex) {
+              Main.error(ex);
+            }
+          } else if (file.getPath().substring(file.getPath().length() - 4)
+              .equals(".png")) {
+            readPNG(file);
+          }
+        }
+      }
     }
+  }
 
-    @Override
-    public void actionPerformed(ActionEvent e) {
-        chooser = new JFileChooser();
-        chooser.setCurrentDirectory(new java.io.File(System
-                .getProperty("user.home")));
-        chooser.setDialogTitle(tr("Select pictures"));
-        chooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
-        chooser.setAcceptAllFileFilterUsed(false);
-        chooser.addChoosableFileFilter(new FileNameExtensionFilter("images",
-                "jpg", "jpeg", "png"));
-        chooser.setMultiSelectionEnabled(true);
-        if (chooser.showOpenDialog(Main.parent) == JFileChooser.APPROVE_OPTION) {
-            for (int i = 0; i < chooser.getSelectedFiles().length; i++) {
-                File file = chooser.getSelectedFiles()[i];
-                if (file.isDirectory()) {
+  /**
+   * Reads a jpg pictures that contains the needed GPS information (position and
+   * direction) and creates a new icon in that position.
+   *
+   * @param file
+   * @throws ImageReadException
+   * @throws IOException
+   */
+  public void readJPG(File file) throws ImageReadException, IOException {
+    final ImageMetadata metadata = Imaging.getMetadata(file);
+    if (metadata instanceof JpegImageMetadata) {
+      final JpegImageMetadata jpegMetadata = (JpegImageMetadata) metadata;
+      final TiffField lat_ref = jpegMetadata
+          .findEXIFValueWithExactMatch(GpsTagConstants.GPS_TAG_GPS_LATITUDE_REF);
+      final TiffField lat = jpegMetadata
+          .findEXIFValueWithExactMatch(GpsTagConstants.GPS_TAG_GPS_LATITUDE);
+      final TiffField lon_ref = jpegMetadata
+          .findEXIFValueWithExactMatch(GpsTagConstants.GPS_TAG_GPS_LONGITUDE_REF);
+      final TiffField lon = jpegMetadata
+          .findEXIFValueWithExactMatch(GpsTagConstants.GPS_TAG_GPS_LONGITUDE);
+      final TiffField ca = jpegMetadata
+          .findEXIFValueWithExactMatch(GpsTagConstants.GPS_TAG_GPS_IMG_DIRECTION);
+      final TiffField datetimeOriginal = jpegMetadata
+          .findEXIFValueWithExactMatch(ExifTagConstants.EXIF_TAG_DATE_TIME_ORIGINAL);
+      if (lat_ref == null || lat == null || lon == null || lon_ref == null) {
+        readNoTags(file);
+        return;
+      }
+      double latValue = 0;
+      double lonValue = 0;
+      double caValue = 0;
+      if (lat != null && lat.getValue() instanceof RationalNumber[])
+        latValue = DegMinSecToDouble((RationalNumber[]) lat.getValue(), lat_ref
+            .getValue().toString());
+      if (lon != null && lon.getValue() instanceof RationalNumber[])
+        lonValue = DegMinSecToDouble((RationalNumber[]) lon.getValue(), lon_ref
+            .getValue().toString());
+      if (ca != null && ca.getValue() instanceof RationalNumber)
+        caValue = ((RationalNumber) ca.getValue()).doubleValue();
+      if (lat_ref.getValue().toString().equals("S"))
+        latValue = -latValue;
+      if (lon_ref.getValue().toString().equals("W"))
+        lonValue = -lonValue;
+      if (datetimeOriginal != null)
+        MapillaryData.getInstance().add(
+            new MapillaryImportedImage(latValue, lonValue, caValue, file,
+                datetimeOriginal.getStringValue()));
+      else
+        MapillaryData.getInstance().add(
+            new MapillaryImportedImage(latValue, lonValue, caValue, file));
+    }
+  }
 
-                } else {
-                    MapillaryLayer.getInstance();
-                    if (file.getPath().substring(file.getPath().length() - 4)
-                            .equals(".jpg")
-                            || file.getPath()
-                                    .substring(file.getPath().length() - 5)
-                                    .equals(".jpeg")) {
-                        try {
-                            readJPG(file);
-                        } catch (ImageReadException ex) {
-                            Main.error(ex);
-                        } catch (IOException ex) {
-                            Main.error(ex);
-                        }
-                    } else if (file.getPath()
-                            .substring(file.getPath().length() - 4)
-                            .equals(".png")) {
-                        readPNG(file);
-                    }
-                }
-            }
-        }
-    }
+  /**
+   * Reads a image file that doesn't contain the needed GPS information. And
+   * creates a new icon in the middle of the map.
+   *
+   * @param file
+   */
+  private void readNoTags(File file) {
+    double HORIZONTAL_DISTANCE = 0.0001;
+    double horDev;
+    if (noTagsPics % 2 == 0)
+      horDev = HORIZONTAL_DISTANCE * noTagsPics / 2;
+    else
+      horDev = -HORIZONTAL_DISTANCE * ((noTagsPics + 1) / 2);
+    LatLon pos = Main.map.mapView.getProjection().eastNorth2latlon(
+        Main.map.mapView.getCenter());
+    MapillaryData.getInstance().add(
+        new MapillaryImportedImage(pos.lat(), pos.lon() + horDev, 0, file));
+    noTagsPics++;
+  }
 
-    /**
-     * Reads a jpg pictures that contains the needed GPS information (position
-     * and direction) and creates a new icon in that position.
-     * 
-     * @param file
-     * @throws ImageReadException
-     * @throws IOException
-     */
-    public void readJPG(File file) throws ImageReadException, IOException {
-        final ImageMetadata metadata = Imaging.getMetadata(file);
-        if (metadata instanceof JpegImageMetadata) {
-            final JpegImageMetadata jpegMetadata = (JpegImageMetadata) metadata;
-            final TiffField lat_ref = jpegMetadata
-                    .findEXIFValueWithExactMatch(GpsTagConstants.GPS_TAG_GPS_LATITUDE_REF);
-            final TiffField lat = jpegMetadata
-                    .findEXIFValueWithExactMatch(GpsTagConstants.GPS_TAG_GPS_LATITUDE);
-            final TiffField lon_ref = jpegMetadata
-                    .findEXIFValueWithExactMatch(GpsTagConstants.GPS_TAG_GPS_LONGITUDE_REF);
-            final TiffField lon = jpegMetadata
-                    .findEXIFValueWithExactMatch(GpsTagConstants.GPS_TAG_GPS_LONGITUDE);
-            final TiffField ca = jpegMetadata
-                    .findEXIFValueWithExactMatch(GpsTagConstants.GPS_TAG_GPS_IMG_DIRECTION);
-            final TiffField datetimeOriginal = jpegMetadata
-                    .findEXIFValueWithExactMatch(ExifTagConstants.EXIF_TAG_DATE_TIME_ORIGINAL);
-            if (lat_ref == null || lat == null || lon == null
-                    || lon_ref == null) {
-                readNoTags(file);
-                return;
-            }
-            double latValue = 0;
-            double lonValue = 0;
-            double caValue = 0;
-            if (lat != null && lat.getValue() instanceof RationalNumber[])
-                latValue = DegMinSecToDouble((RationalNumber[]) lat.getValue(),
-                        lat_ref.getValue().toString());
-            if (lon != null && lon.getValue() instanceof RationalNumber[])
-                lonValue = DegMinSecToDouble((RationalNumber[]) lon.getValue(),
-                        lon_ref.getValue().toString());
-            if (ca != null && ca.getValue() instanceof RationalNumber)
-                caValue = ((RationalNumber) ca.getValue()).doubleValue();
-            if (lat_ref.getValue().toString().equals("S"))
-                latValue = -latValue;
-            if (lon_ref.getValue().toString().equals("W"))
-                lonValue = -lonValue;
-            if (datetimeOriginal != null)
-                MapillaryData.getInstance().add(
-                        new MapillaryImportedImage(latValue, lonValue, caValue,
-                                file, datetimeOriginal.getStringValue()));
-            else
-                MapillaryData.getInstance().add(
-                        new MapillaryImportedImage(latValue, lonValue, caValue,
-                                file));
-        }
-    }
+  private void readPNG(File file) {
+    readNoTags(file);
+  }
 
-    /**
-     * Reads a image file that doesn't contain the needed GPS information. And
-     * creates a new icon in the middle of the map.
-     * 
-     * @param file
-     */
-    private void readNoTags(File file) {
-        double HORIZONTAL_DISTANCE = 0.0001;
-        double horDev;
-        if (noTagsPics % 2 == 0)
-            horDev = HORIZONTAL_DISTANCE * noTagsPics / 2;
-        else
-            horDev = -HORIZONTAL_DISTANCE * ((noTagsPics + 1) / 2);
-        LatLon pos = Main.map.mapView.getProjection().eastNorth2latlon(
-                Main.map.mapView.getCenter());
-        MapillaryData.getInstance().add(
-                new MapillaryImportedImage(pos.lat(), pos.lon() + horDev, 0,
-                        file));
-        noTagsPics++;
-    }
-
-    private void readPNG(File file) {
-        readNoTags(file);
-    }
-
-    private double DegMinSecToDouble(RationalNumber[] degMinSec, String ref) {
-        RationalNumber deg = degMinSec[0];
-        RationalNumber min = degMinSec[1];
-        RationalNumber sec = degMinSec[2];
-        return deg.doubleValue() + min.doubleValue() / 60 + sec.doubleValue()
-                / 3600;
-    }
+  private double DegMinSecToDouble(RationalNumber[] degMinSec, String ref) {
+    RationalNumber deg = degMinSec[0];
+    RationalNumber min = degMinSec[1];
+    RationalNumber sec = degMinSec[2];
+    return deg.doubleValue() + min.doubleValue() / 60 + sec.doubleValue()
+        / 3600;
+  }
 }
Index: applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/actions/MapillaryZoomAction.java
===================================================================
--- applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/actions/MapillaryZoomAction.java	(revision 31349)
+++ applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/actions/MapillaryZoomAction.java	(revision 31350)
@@ -22,36 +22,36 @@
  */
 public class MapillaryZoomAction extends JosmAction implements
-        MapillaryDataListener {
+    MapillaryDataListener {
 
-    public MapillaryZoomAction() {
-        super(tr("Zoom to selected image"), new ImageProvider("icon24.png"),
-                tr("Zoom to selected image"), Shortcut.registerShortcut(
-                        "Zoom Mapillary",
-                        tr("Zoom to the currently selected Mapillary image"),
-                        KeyEvent.CHAR_UNDEFINED, Shortcut.NONE), false,
-                "mapillaryZoom", false);
-        MapillaryData.getInstance().addListener(this);
-        this.setEnabled(false);
-    }
+  public MapillaryZoomAction() {
+    super(tr("Zoom to selected image"), new ImageProvider("icon24.png"),
+        tr("Zoom to selected image"), Shortcut.registerShortcut(
+            "Zoom Mapillary",
+            tr("Zoom to the currently selected Mapillary image"),
+            KeyEvent.CHAR_UNDEFINED, Shortcut.NONE), false, "mapillaryZoom",
+        false);
+    MapillaryData.getInstance().addListener(this);
+    this.setEnabled(false);
+  }
 
-    @Override
-    public void actionPerformed(ActionEvent arg0) {
-        if (MapillaryData.getInstance().getSelectedImage() == null)
-            throw new IllegalStateException();
-        Main.map.mapView.zoomTo(MapillaryData.getInstance().getSelectedImage()
-                .getLatLon());
-    }
+  @Override
+  public void actionPerformed(ActionEvent arg0) {
+    if (MapillaryData.getInstance().getSelectedImage() == null)
+      throw new IllegalStateException();
+    Main.map.mapView.zoomTo(MapillaryData.getInstance().getSelectedImage()
+        .getLatLon());
+  }
 
-    @Override
-    public void selectedImageChanged(MapillaryAbstractImage oldImage,
-            MapillaryAbstractImage newImage) {
-        if (oldImage == null && newImage != null)
-            MapillaryPlugin.setMenuEnabled(MapillaryPlugin.ZOOM_MENU, true);
-        else if (oldImage != null && newImage == null)
-            MapillaryPlugin.setMenuEnabled(MapillaryPlugin.ZOOM_MENU, false);
-    }
+  @Override
+  public void selectedImageChanged(MapillaryAbstractImage oldImage,
+      MapillaryAbstractImage newImage) {
+    if (oldImage == null && newImage != null)
+      MapillaryPlugin.setMenuEnabled(MapillaryPlugin.ZOOM_MENU, true);
+    else if (oldImage != null && newImage == null)
+      MapillaryPlugin.setMenuEnabled(MapillaryPlugin.ZOOM_MENU, false);
+  }
 
-    @Override
-    public void imagesAdded() {
-    }
+  @Override
+  public void imagesAdded() {
+  }
 }
Index: applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/cache/MapillaryCache.java
===================================================================
--- applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/cache/MapillaryCache.java	(revision 31349)
+++ applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/cache/MapillaryCache.java	(revision 31350)
@@ -11,59 +11,58 @@
 
 public class MapillaryCache extends
-        JCSCachedTileLoaderJob<String, BufferedImageCacheEntry> {
+    JCSCachedTileLoaderJob<String, BufferedImageCacheEntry> {
 
-    private volatile URL url;
-    private volatile String key;
+  private volatile URL url;
+  private volatile String key;
 
-    public static enum Type {
-        FULL_IMAGE, THUMBNAIL
+  public static enum Type {
+    FULL_IMAGE, THUMBNAIL
+  }
+
+  public MapillaryCache(String key, Type type) {
+    super(MapillaryPlugin.CACHE, 50000, 50000, new HashMap<String, String>());
+    this.key = key;
+    try {
+      if (type == Type.FULL_IMAGE) {
+        url = new URL("https://d1cuyjsrcm0gby.cloudfront.net/" + key
+            + "/thumb-2048.jpg");
+        this.key += ".FULL_IMAGE";
+
+      } else if (type == Type.THUMBNAIL) {
+        url = new URL("https://d1cuyjsrcm0gby.cloudfront.net/" + key
+            + "/thumb-320.jpg");
+        this.key += ".THUMBNAIL";
+      }
+    } catch (MalformedURLException e) {
+      Main.error(e);
     }
+  }
 
-    public MapillaryCache(String key, Type type) {
-        super(MapillaryPlugin.CACHE, 50000, 50000,
-                new HashMap<String, String>());
-        this.key = key;
-        try {
-            if (type == Type.FULL_IMAGE) {
-                url = new URL("https://d1cuyjsrcm0gby.cloudfront.net/" + key
-                        + "/thumb-2048.jpg");
-                this.key += ".FULL_IMAGE";
+  @Override
+  public String getCacheKey() {
+    return key;
+  }
 
-            } else if (type == Type.THUMBNAIL) {
-                url = new URL("https://d1cuyjsrcm0gby.cloudfront.net/" + key
-                        + "/thumb-320.jpg");
-                this.key += ".THUMBNAIL";
-            }
-        } catch (MalformedURLException e) {
-            Main.error(e);
-        }
-    }
+  @Override
+  public URL getUrl() {
+    return url;
+  }
 
-    @Override
-    public String getCacheKey() {
-        return key;
-    }
+  @Override
+  protected BufferedImageCacheEntry createCacheEntry(byte[] content) {
+    return new BufferedImageCacheEntry(content);
+  }
 
-    @Override
-    public URL getUrl() {
-        return url;
-    }
+  @Override
+  protected boolean isObjectLoadable() {
+    if (cacheData == null)
+      return false;
+    byte[] content = cacheData.getContent();
+    return content != null && content.length > 0;
+  }
 
-    @Override
-    protected BufferedImageCacheEntry createCacheEntry(byte[] content) {
-        return new BufferedImageCacheEntry(content);
-    }
-
-    @Override
-    protected boolean isObjectLoadable() {
-        if (cacheData == null)
-            return false;
-        byte[] content = cacheData.getContent();
-        return content != null && content.length > 0;
-    }
-
-    // @Override
-    protected boolean handleNotFound() {
-        return false;
-    }
+  // @Override
+  protected boolean handleNotFound() {
+    return false;
+  }
 }
Index: applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/commands/CommandMoveImage.java
===================================================================
--- applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/commands/CommandMoveImage.java	(revision 31349)
+++ applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/commands/CommandMoveImage.java	(revision 31350)
@@ -16,45 +16,45 @@
  */
 public class CommandMoveImage extends MapillaryCommand {
-    private double x;
-    private double y;
+  private double x;
+  private double y;
 
-    public CommandMoveImage(List<MapillaryAbstractImage> images, double x,
-            double y) {
-        this.images = new ArrayList<>(images);
-        this.x = x;
-        this.y = y;
+  public CommandMoveImage(List<MapillaryAbstractImage> images, double x,
+      double y) {
+    this.images = new ArrayList<>(images);
+    this.x = x;
+    this.y = y;
+  }
+
+  @Override
+  public void undo() {
+    for (MapillaryAbstractImage image : images) {
+      image.move(-x, -y);
+      image.stopMoving();
     }
+    checkModified();
+    Main.map.repaint();
+  }
 
-    @Override
-    public void undo() {
-        for (MapillaryAbstractImage image : images) {
-            image.move(-x, -y);
-            image.stopMoving();
-        }
-        checkModified();
-        Main.map.repaint();
+  @Override
+  public void redo() {
+    for (MapillaryAbstractImage image : images) {
+      image.move(x, y);
+      image.stopMoving();
     }
+    checkModified();
+    Main.map.repaint();
+  }
 
-    @Override
-    public void redo() {
-        for (MapillaryAbstractImage image : images) {
-            image.move(x, y);
-            image.stopMoving();
-        }
-        checkModified();
-        Main.map.repaint();
+  public String toString() {
+    return trn("Moved {0} image", "Moved {0} images", images.size(),
+        images.size());
+  }
+
+  @Override
+  public void sum(MapillaryCommand command) {
+    if (command instanceof CommandMoveImage) {
+      this.x += ((CommandMoveImage) command).x;
+      this.y += ((CommandMoveImage) command).y;
     }
-
-    public String toString() {
-        return trn("Moved {0} image", "Moved {0} images", images.size(),
-                images.size());
-    }
-
-    @Override
-    public void sum(MapillaryCommand command) {
-        if (command instanceof CommandMoveImage) {
-            this.x += ((CommandMoveImage) command).x;
-            this.y += ((CommandMoveImage) command).y;
-        }
-    }
+  }
 }
Index: applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/commands/CommandTurnImage.java
===================================================================
--- applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/commands/CommandTurnImage.java	(revision 31349)
+++ applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/commands/CommandTurnImage.java	(revision 31350)
@@ -16,41 +16,41 @@
  */
 public class CommandTurnImage extends MapillaryCommand {
-    private double ca;
+  private double ca;
 
-    public CommandTurnImage(List<MapillaryAbstractImage> images, double ca) {
-        this.images = new ArrayList<>(images);
-        this.ca = ca;
+  public CommandTurnImage(List<MapillaryAbstractImage> images, double ca) {
+    this.images = new ArrayList<>(images);
+    this.ca = ca;
+  }
+
+  @Override
+  public void undo() {
+    for (MapillaryAbstractImage image : images) {
+      image.turn(-ca);
+      image.stopMoving();
     }
+    checkModified();
+    Main.map.repaint();
+  }
 
-    @Override
-    public void undo() {
-        for (MapillaryAbstractImage image : images) {
-            image.turn(-ca);
-            image.stopMoving();
-        }
-        checkModified();
-        Main.map.repaint();
+  @Override
+  public void redo() {
+    for (MapillaryAbstractImage image : images) {
+      image.turn(ca);
+      image.stopMoving();
     }
+    checkModified();
+    Main.map.repaint();
+  }
 
-    @Override
-    public void redo() {
-        for (MapillaryAbstractImage image : images) {
-            image.turn(ca);
-            image.stopMoving();
-        }
-        checkModified();
-        Main.map.repaint();
+  public String toString() {
+    return trn("Turned {0} image", "Turned {0} images", this.images.size(),
+        this.images.size());
+  }
+
+  @Override
+  public void sum(MapillaryCommand command) {
+    if (command instanceof CommandTurnImage) {
+      this.ca += ((CommandTurnImage) command).ca;
     }
-
-    public String toString() {
-        return trn("Turned {0} image", "Turned {0} images", this.images.size(),
-                this.images.size());
-    }
-
-    @Override
-    public void sum(MapillaryCommand command) {
-        if (command instanceof CommandTurnImage) {
-            this.ca += ((CommandTurnImage) command).ca;
-        }
-    }
+  }
 }
Index: applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/commands/MapillaryCommand.java
===================================================================
--- applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/commands/MapillaryCommand.java	(revision 31349)
+++ applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/commands/MapillaryCommand.java	(revision 31350)
@@ -12,25 +12,24 @@
  */
 public abstract class MapillaryCommand {
-    protected List<MapillaryAbstractImage> images;
+  protected List<MapillaryAbstractImage> images;
 
-    public abstract void undo();
+  public abstract void undo();
 
-    public abstract void redo();
+  public abstract void redo();
 
-    /**
-     * If two equal commands are applied consecutively to the same set of
-     * images, they are summed in order to reduce them to just one command.
-     * 
-     * @param command
-     */
-    public abstract void sum(MapillaryCommand command);
+  /**
+   * If two equal commands are applied consecutively to the same set of images,
+   * they are summed in order to reduce them to just one command.
+   * 
+   * @param command
+   */
+  public abstract void sum(MapillaryCommand command);
 
-    /**
-     * Checks if the image has been modified, compairing with its original
-     * values.
-     */
-    public void checkModified() {
-        for (MapillaryAbstractImage image : images)
-            image.isModified = (image.tempLatLon == image.latLon || image.tempCa == image.ca);
-    }
+  /**
+   * Checks if the image has been modified, compairing with its original values.
+   */
+  public void checkModified() {
+    for (MapillaryAbstractImage image : images)
+      image.isModified = (image.tempLatLon == image.latLon || image.tempCa == image.ca);
+  }
 }
Index: applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/commands/MapillaryRecord.java
===================================================================
--- applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/commands/MapillaryRecord.java	(revision 31349)
+++ applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/commands/MapillaryRecord.java	(revision 31350)
@@ -12,87 +12,86 @@
  */
 public class MapillaryRecord {
-    public static MapillaryRecord INSTANCE;
+  public static MapillaryRecord INSTANCE;
 
-    private ArrayList<MapillaryRecordListener> listeners;
+  private ArrayList<MapillaryRecordListener> listeners;
 
-    public ArrayList<MapillaryCommand> commandList;
-    /** Last written command */
-    public int position;
+  public ArrayList<MapillaryCommand> commandList;
+  /** Last written command */
+  public int position;
 
-    public MapillaryRecord() {
-        commandList = new ArrayList<>();
-        position = -1;
-        listeners = new ArrayList<>();
+  public MapillaryRecord() {
+    commandList = new ArrayList<>();
+    position = -1;
+    listeners = new ArrayList<>();
+  }
+
+  public static synchronized MapillaryRecord getInstance() {
+    if (MapillaryRecord.INSTANCE == null)
+      MapillaryRecord.INSTANCE = new MapillaryRecord();
+    return MapillaryRecord.INSTANCE;
+  }
+
+  public void addListener(MapillaryRecordListener lis) {
+    this.listeners.add(lis);
+  }
+
+  public void removeListener(MapillaryRecordListener lis) {
+    this.listeners.remove(lis);
+  }
+
+  /**
+   * Adds a new command to the list.
+   * 
+   * @param command
+   */
+  public void addCommand(MapillaryCommand command) {
+    // Checks if it is a continuation of last command
+    if (position != -1) {
+      boolean equalSets = true;
+      for (MapillaryAbstractImage img : commandList.get(position).images)
+        if (!command.images.contains(img))
+          equalSets = false;
+      if (equalSets
+          && commandList.get(position).getClass() == command.getClass()) {
+        commandList.get(position).sum(command);
+        fireRecordChanged();
+        return;
+      }
     }
+    // Adds the command to the las position of the list.
+    commandList.add(position + 1, command);
+    position++;
+    while (commandList.size() > position + 1) {
+      commandList.remove(position + 1);
+    }
+    fireRecordChanged();
+  }
 
-    public static synchronized MapillaryRecord getInstance() {
-        if (MapillaryRecord.INSTANCE == null)
-            MapillaryRecord.INSTANCE = new MapillaryRecord();
-        return MapillaryRecord.INSTANCE;
-    }
+  /**
+   * Undo latest command.
+   */
+  public void undo() {
+    if (position == -1)
+      return;
+    commandList.get(position).undo();
+    position--;
+    fireRecordChanged();
+  }
 
-    public void addListener(MapillaryRecordListener lis) {
-        this.listeners.add(lis);
-    }
+  /**
+   * Redo latest undoed action.
+   */
+  public void redo() {
+    if (position + 1 >= commandList.size())
+      return;
+    position++;
+    commandList.get(position).redo();
+    fireRecordChanged();
+  }
 
-    public void removeListener(MapillaryRecordListener lis) {
-        this.listeners.remove(lis);
-    }
-
-    /**
-     * Adds a new command to the list.
-     * 
-     * @param command
-     */
-    public void addCommand(MapillaryCommand command) {
-        // Checks if it is a continuation of last command
-        if (position != -1) {
-            boolean equalSets = true;
-            for (MapillaryAbstractImage img : commandList.get(position).images)
-                if (!command.images.contains(img))
-                    equalSets = false;
-            if (equalSets
-                    && commandList.get(position).getClass() == command
-                            .getClass()) {
-                commandList.get(position).sum(command);
-                fireRecordChanged();
-                return;
-            }
-        }
-        // Adds the command to the las position of the list.
-        commandList.add(position + 1, command);
-        position++;
-        while (commandList.size() > position + 1) {
-            commandList.remove(position + 1);
-        }
-        fireRecordChanged();
-    }
-
-    /**
-     * Undo latest command.
-     */
-    public void undo() {
-        if (position == -1)
-            return;
-        commandList.get(position).undo();
-        position--;
-        fireRecordChanged();
-    }
-
-    /**
-     * Redo latest undoed action.
-     */
-    public void redo() {
-        if (position + 1 >= commandList.size())
-            return;
-        position++;
-        commandList.get(position).redo();
-        fireRecordChanged();
-    }
-
-    private void fireRecordChanged() {
-        for (MapillaryRecordListener lis : listeners)
-            if (lis != null)
-                lis.recordChanged();
-    }
+  private void fireRecordChanged() {
+    for (MapillaryRecordListener lis : listeners)
+      if (lis != null)
+        lis.recordChanged();
+  }
 }
Index: applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/commands/MapillaryRecordListener.java
===================================================================
--- applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/commands/MapillaryRecordListener.java	(revision 31349)
+++ applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/commands/MapillaryRecordListener.java	(revision 31350)
@@ -2,4 +2,4 @@
 
 public interface MapillaryRecordListener {
-    public void recordChanged();
+  public void recordChanged();
 }
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 31349)
+++ applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/downloads/MapillaryDownloader.java	(revision 31350)
@@ -19,63 +19,63 @@
 public class MapillaryDownloader {
 
-    public final static String BASE_URL = "https://a.mapillary.com/v2/";
-    public final static String CLIENT_ID = "NzNRM2otQkR2SHJzaXJmNmdQWVQ0dzo1YTA2NmNlODhlNWMwOTBm";
-    public final static Executor EXECUTOR = Executors.newSingleThreadExecutor();
+  public final static String BASE_URL = "https://a.mapillary.com/v2/";
+  public final static String CLIENT_ID = "NzNRM2otQkR2SHJzaXJmNmdQWVQ0dzo1YTA2NmNlODhlNWMwOTBm";
+  public final static Executor EXECUTOR = Executors.newSingleThreadExecutor();
 
-    private String[] parameters = { "lat", "lon", "distance", "limit",
-            "min_lat", "min_lon", "max_lat", "max_lon" };
+  private String[] parameters = { "lat", "lon", "distance", "limit", "min_lat",
+      "min_lon", "max_lat", "max_lon" };
 
-    public MapillaryDownloader() {
+  public MapillaryDownloader() {
+  }
+
+  /**
+   * 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.
+   * @param maxLatLon
+   *          The maximum latitude and longitude of the rectangle
+   */
+  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);
+
+    try {
+      Main.info("GET " + url2 + " (Mapillary plugin)");
+      EXECUTOR.execute(new MapillarySquareDownloadManagerThread(url1, url2,
+          url3, MapillaryLayer.getInstance()));
+    } catch (Exception e) {
+      Main.error(e);
     }
+  }
 
-    /**
-     * 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.
-     * @param maxLatLon
-     *            The maximum latitude and longitude of the rectangle
-     */
-    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);
+  /**
+   * Gets the images within the given bounds.
+   * 
+   * @param bounds
+   */
+  public void getImages(Bounds bounds) {
+    getImages(bounds.getMin(), bounds.getMax());
+  }
 
-        try {
-            Main.info("GET " + url2 + " (Mapillary plugin)");
-            EXECUTOR.execute(new MapillarySquareDownloadManagerThread(url1,
-                    url2, url3, MapillaryLayer.getInstance()));
-        } catch (Exception e) {
-            Main.error(e);
-        }
-    }
-
-    /**
-     * Gets the images within the given bounds.
-     * 
-     * @param bounds
-     */
-    public void getImages(Bounds bounds) {
-        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;
-    }
+  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/MapillaryExportDownloadThread.java
===================================================================
--- applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/downloads/MapillaryExportDownloadThread.java	(revision 31349)
+++ applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/downloads/MapillaryExportDownloadThread.java	(revision 31350)
@@ -25,41 +25,41 @@
  */
 public class MapillaryExportDownloadThread extends Thread implements
-        ICachedLoaderListener {
+    ICachedLoaderListener {
 
-    String url;
-    ArrayBlockingQueue<BufferedImage> queue;
-    ArrayBlockingQueue<MapillaryAbstractImage> queueImages;
+  String url;
+  ArrayBlockingQueue<BufferedImage> queue;
+  ArrayBlockingQueue<MapillaryAbstractImage> queueImages;
 
-    ProgressMonitor monitor;
-    MapillaryImage image;
+  ProgressMonitor monitor;
+  MapillaryImage image;
 
-    public MapillaryExportDownloadThread(MapillaryImage image,
-            ArrayBlockingQueue<BufferedImage> queue,
-            ArrayBlockingQueue<MapillaryAbstractImage> queueImages) {
-        url = "https://d1cuyjsrcm0gby.cloudfront.net/" + image.getKey()
-                + "/thumb-2048.jpg";
-        this.queue = queue;
-        this.image = image;
-        this.queueImages = queueImages;
+  public MapillaryExportDownloadThread(MapillaryImage image,
+      ArrayBlockingQueue<BufferedImage> queue,
+      ArrayBlockingQueue<MapillaryAbstractImage> queueImages) {
+    url = "https://d1cuyjsrcm0gby.cloudfront.net/" + image.getKey()
+        + "/thumb-2048.jpg";
+    this.queue = queue;
+    this.image = image;
+    this.queueImages = queueImages;
+  }
+
+  @Override
+  public void run() {
+    new MapillaryCache(image.getKey(), MapillaryCache.Type.FULL_IMAGE).submit(
+        this, false);
+  }
+
+  @Override
+  public void loadingFinished(CacheEntry data, CacheEntryAttributes attributes,
+      LoadResult result) {
+    try {
+      queue.put(ImageIO.read(new ByteArrayInputStream(data.getContent())));
+      queueImages.put(image);
+
+    } catch (InterruptedException e) {
+      Main.error(e);
+    } catch (IOException e) {
+      Main.error(e);
     }
-
-    @Override
-    public void run() {
-        new MapillaryCache(image.getKey(), MapillaryCache.Type.FULL_IMAGE)
-                .submit(this, false);
-    }
-
-    @Override
-    public void loadingFinished(CacheEntry data,
-            CacheEntryAttributes attributes, LoadResult result) {
-        try {
-            queue.put(ImageIO.read(new ByteArrayInputStream(data.getContent())));
-            queueImages.put(image);
-
-        } catch (InterruptedException e) {
-            Main.error(e);
-        } catch (IOException e) {
-            Main.error(e);
-        }
-    }
+  }
 }
Index: applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/downloads/MapillaryExportManager.java
===================================================================
--- applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/downloads/MapillaryExportManager.java	(revision 31349)
+++ applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/downloads/MapillaryExportManager.java	(revision 31350)
@@ -32,104 +32,103 @@
 public class MapillaryExportManager extends PleaseWaitRunnable {
 
-    ArrayBlockingQueue<BufferedImage> queue;
-    ArrayBlockingQueue<MapillaryAbstractImage> queueImages;
+  ArrayBlockingQueue<BufferedImage> queue;
+  ArrayBlockingQueue<MapillaryAbstractImage> queueImages;
 
-    final int amount;
-    List<MapillaryAbstractImage> images;
-    String path;
-    
-    private Thread writer;
-    private ThreadPoolExecutor ex;
+  final int amount;
+  List<MapillaryAbstractImage> images;
+  String path;
 
-    public MapillaryExportManager(List<MapillaryAbstractImage> images,
-            String path) {
-        super(tr("Downloading") + "...", new PleaseWaitProgressMonitor(
-                "Exporting Mapillary Images"), true);
-        queue = new ArrayBlockingQueue<>(10);
-        queueImages = new ArrayBlockingQueue<>(10);
+  private Thread writer;
+  private ThreadPoolExecutor ex;
 
-        this.images = images;
-        amount = images.size();
-        this.path = path;
+  public MapillaryExportManager(List<MapillaryAbstractImage> images, String path) {
+    super(tr("Downloading") + "...", new PleaseWaitProgressMonitor(
+        "Exporting Mapillary Images"), true);
+    queue = new ArrayBlockingQueue<>(10);
+    queueImages = new ArrayBlockingQueue<>(10);
+
+    this.images = images;
+    amount = images.size();
+    this.path = path;
+  }
+
+  /**
+   * Constructor used to rewrite imported images.
+   * 
+   * @param images
+   * @throws IOException
+   */
+  public MapillaryExportManager(List<MapillaryImportedImage> images)
+      throws IOException {
+    super(tr("Downloading") + "...", new PleaseWaitProgressMonitor(
+        "Exporting Mapillary Images"), true);
+    queue = new ArrayBlockingQueue<>(10);
+    queueImages = new ArrayBlockingQueue<>(10);
+    for (MapillaryImportedImage image : images) {
+      queue.add(image.getImage());
+      queueImages.add(image);
+    }
+    amount = images.size();
+  }
+
+  @Override
+  protected void cancel() {
+    writer.interrupt();
+    ex.shutdown();
+  }
+
+  @Override
+  protected void realRun() throws SAXException, IOException,
+      OsmTransferException {
+    // Starts a writer thread in order to write the pictures on the disk.
+    writer = new MapillaryExportWriterThread(path, queue, queueImages, amount,
+        this.getProgressMonitor());
+    writer.start();
+    if (path == null) {
+      try {
+        writer.join();
+      } catch (InterruptedException e) {
+        Main.error(e);
+      }
+      return;
+    }
+    ex = new ThreadPoolExecutor(20, 35, 25, TimeUnit.SECONDS,
+        new ArrayBlockingQueue<Runnable>(10));
+    for (MapillaryAbstractImage image : images) {
+      if (image instanceof MapillaryImage) {
+        try {
+          ex.execute(new MapillaryExportDownloadThread((MapillaryImage) image,
+              queue, queueImages));
+        } catch (Exception e) {
+          Main.error(e);
+        }
+      } else if (image instanceof MapillaryImportedImage) {
+        try {
+          queue.put(((MapillaryImportedImage) image).getImage());
+          queueImages.put((MapillaryImportedImage) image);
+        } catch (InterruptedException e) {
+          Main.error(e);
+        }
+      }
+      try {
+        // If the queue is full, waits for it to have more space
+        // available before executing anything else.
+        while (ex.getQueue().remainingCapacity() == 0)
+          Thread.sleep(100);
+      } catch (Exception e) {
+        Main.error(e);
+      }
+    }
+    try {
+      writer.join();
+    } catch (InterruptedException e) {
+      Main.error(e);
     }
 
-    /**
-     * Constructor used to rewrite imported images.
-     * 
-     * @param images
-     * @throws IOException
-     */
-    public MapillaryExportManager(List<MapillaryImportedImage> images)
-            throws IOException {
-        super(tr("Downloading") + "...", new PleaseWaitProgressMonitor(
-                "Exporting Mapillary Images"), true);
-        queue = new ArrayBlockingQueue<>(10);
-        queueImages = new ArrayBlockingQueue<>(10);
-        for (MapillaryImportedImage image : images) {
-            queue.add(image.getImage());
-            queueImages.add(image);
-        }
-        amount = images.size();
-    }
+  }
 
-    @Override
-    protected void cancel() {
-        writer.interrupt();
-        ex.shutdown();
-    }
-
-    @Override
-    protected void realRun() throws SAXException, IOException,
-            OsmTransferException {
-        // Starts a writer thread in order to write the pictures on the disk.
-        writer = new MapillaryExportWriterThread(path, queue,
-                queueImages, amount, this.getProgressMonitor());
-        writer.start();
-        if (path == null) {
-            try {
-                writer.join();
-            } catch (InterruptedException e) {
-                Main.error(e);
-            }
-            return;
-        }
-        ex = new ThreadPoolExecutor(20, 35, 25,
-                TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(10));
-        for (MapillaryAbstractImage image : images) {
-            if (image instanceof MapillaryImage) {
-                try {
-                    ex.execute(new MapillaryExportDownloadThread(
-                            (MapillaryImage) image, queue, queueImages));
-                } catch (Exception e) {
-                    Main.error(e);
-                }
-            } else if (image instanceof MapillaryImportedImage) {
-                try {
-                    queue.put(((MapillaryImportedImage) image).getImage());
-                    queueImages.put((MapillaryImportedImage) image);
-                } catch (InterruptedException e) {
-                    Main.error(e);
-                }
-            }
-            try {
-                // If the queue is full, waits for it to have more space
-                // available before executing anything else.
-                while (ex.getQueue().remainingCapacity() == 0)
-                    Thread.sleep(100);
-            } catch (Exception e) {
-                Main.error(e);
-            }
-        }
-        try {
-            writer.join();
-        } catch (InterruptedException e) {
-            Main.error(e);
-        }
-
-    }
-
-    @Override
-    protected void finish() {
-        // TODO Auto-generated method stub
-    }
+  @Override
+  protected void finish() {
+    // TODO Auto-generated method stub
+  }
 }
Index: applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/downloads/MapillaryExportWriterThread.java
===================================================================
--- applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/downloads/MapillaryExportWriterThread.java	(revision 31349)
+++ applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/downloads/MapillaryExportWriterThread.java	(revision 31350)
@@ -34,87 +34,80 @@
 public class MapillaryExportWriterThread extends Thread {
 
-    private final String path;
-    private final ArrayBlockingQueue<BufferedImage> queue;
-    private final ArrayBlockingQueue<MapillaryAbstractImage> queueImages;
-    private final int amount;
-    private final ProgressMonitor monitor;
+  private final String path;
+  private final ArrayBlockingQueue<BufferedImage> queue;
+  private final ArrayBlockingQueue<MapillaryAbstractImage> queueImages;
+  private final int amount;
+  private final ProgressMonitor monitor;
 
-    public MapillaryExportWriterThread(String path,
-            ArrayBlockingQueue<BufferedImage> queue,
-            ArrayBlockingQueue<MapillaryAbstractImage> queueImages, int amount,
-            ProgressMonitor monitor) {
-        this.path = path;
-        this.queue = queue;
-        this.queueImages = queueImages;
-        this.amount = amount;
-        this.monitor = monitor;
+  public MapillaryExportWriterThread(String path,
+      ArrayBlockingQueue<BufferedImage> queue,
+      ArrayBlockingQueue<MapillaryAbstractImage> queueImages, int amount,
+      ProgressMonitor monitor) {
+    this.path = path;
+    this.queue = queue;
+    this.queueImages = queueImages;
+    this.amount = amount;
+    this.monitor = monitor;
+  }
+
+  @Override
+  public void run() {
+    monitor.setCustomText("Downloaded 0/" + amount);
+    File tempFile = null;
+    BufferedImage img;
+    MapillaryAbstractImage mimg = null;
+    String finalPath = "";
+    for (int i = 0; i < amount; i++) {
+      try {
+        img = queue.take();
+        mimg = queueImages.take();
+        if (path == null && mimg instanceof MapillaryImportedImage) {
+          String path = ((MapillaryImportedImage) mimg).getFile().getPath();
+          finalPath = path.substring(0, path.lastIndexOf('.'));
+        } else if (mimg instanceof MapillaryImage)
+          finalPath = path + "/" + ((MapillaryImage) mimg).getKey();
+        else
+          finalPath = path + "/" + i;
+        // Creates a temporal file that is going to be deleted after
+        // writing the EXIF tags.
+        tempFile = new File(finalPath + ".tmp");
+        ImageIO.write(img, "jpg", tempFile);
+
+        // Write EXIF tags
+        TiffOutputSet outputSet = new TiffOutputSet();
+        TiffOutputDirectory exifDirectory = outputSet
+            .getOrCreateExifDirectory();
+        exifDirectory.add(GpsTagConstants.GPS_TAG_GPS_IMG_DIRECTION_REF,
+            GpsTagConstants.GPS_TAG_GPS_IMG_DIRECTION_REF_VALUE_TRUE_NORTH);
+        exifDirectory.add(GpsTagConstants.GPS_TAG_GPS_IMG_DIRECTION,
+            RationalNumber.valueOf(mimg.getCa()));
+        if (mimg instanceof MapillaryImportedImage) {
+          exifDirectory.add(ExifTagConstants.EXIF_TAG_DATE_TIME_ORIGINAL,
+              ((MapillaryImportedImage) mimg).getDate("yyyy/MM/dd hh:mm:ss"));
+        } else if (mimg instanceof MapillaryImage)
+          exifDirectory.add(ExifTagConstants.EXIF_TAG_DATE_TIME_ORIGINAL,
+              ((MapillaryImage) mimg).getDate("yyyy/MM/dd hh/mm/ss"));
+        outputSet.setGPSInDegrees(mimg.getLatLon().lon(), mimg.getLatLon()
+            .lat());
+        OutputStream os = new BufferedOutputStream(new FileOutputStream(
+            finalPath + ".jpg"));
+        new ExifRewriter().updateExifMetadataLossless(tempFile, os, outputSet);
+        tempFile.delete();
+        os.close();
+      } catch (InterruptedException e) {
+        Main.info("Mapillary export cancelled");
+        return;
+      } catch (IOException e) {
+        Main.error(e);
+      } catch (ImageWriteException e) {
+        Main.error(e);
+      } catch (ImageReadException e) {
+        Main.error(e);
+      }
+
+      // Increases the progress bar.
+      monitor.worked(PleaseWaitProgressMonitor.PROGRESS_BAR_MAX / amount);
+      monitor.setCustomText("Downloaded " + (i + 1) + "/" + amount);
     }
-
-    @Override
-    public void run() {
-        monitor.setCustomText("Downloaded 0/" + amount);
-        File tempFile = null;
-        BufferedImage img;
-        MapillaryAbstractImage mimg = null;
-        String finalPath = "";
-        for (int i = 0; i < amount; i++) {
-            try {
-                img = queue.take();
-                mimg = queueImages.take();
-                if (path == null && mimg instanceof MapillaryImportedImage) {
-                    String path = ((MapillaryImportedImage) mimg).getFile()
-                            .getPath();
-                    finalPath = path.substring(0, path.lastIndexOf('.'));
-                } else if (mimg instanceof MapillaryImage)
-                    finalPath = path + "/" + ((MapillaryImage) mimg).getKey();
-                else
-                    finalPath = path + "/" + i;
-                // Creates a temporal file that is going to be deleted after
-                // writing the EXIF tags.
-                tempFile = new File(finalPath + ".tmp");
-                ImageIO.write(img, "jpg", tempFile);
-
-                // Write EXIF tags
-                TiffOutputSet outputSet = new TiffOutputSet();
-                TiffOutputDirectory exifDirectory = outputSet
-                        .getOrCreateExifDirectory();
-                exifDirectory
-                        .add(GpsTagConstants.GPS_TAG_GPS_IMG_DIRECTION_REF,
-                                GpsTagConstants.GPS_TAG_GPS_IMG_DIRECTION_REF_VALUE_TRUE_NORTH);
-                exifDirectory.add(GpsTagConstants.GPS_TAG_GPS_IMG_DIRECTION,
-                        RationalNumber.valueOf(mimg.getCa()));
-                if (mimg instanceof MapillaryImportedImage) {
-                    exifDirectory.add(
-                            ExifTagConstants.EXIF_TAG_DATE_TIME_ORIGINAL,
-                            ((MapillaryImportedImage) mimg)
-                                    .getDate("yyyy/MM/dd hh:mm:ss"));
-                } else if (mimg instanceof MapillaryImage)
-                    exifDirectory.add(
-                            ExifTagConstants.EXIF_TAG_DATE_TIME_ORIGINAL,
-                            ((MapillaryImage) mimg)
-                                    .getDate("yyyy/MM/dd hh/mm/ss"));
-                outputSet.setGPSInDegrees(mimg.getLatLon().lon(), mimg
-                        .getLatLon().lat());
-                OutputStream os = new BufferedOutputStream(
-                        new FileOutputStream(finalPath + ".jpg"));
-                new ExifRewriter().updateExifMetadataLossless(tempFile, os,
-                        outputSet);
-                tempFile.delete();
-                os.close();
-            } catch (InterruptedException e) {
-                Main.info("Mapillary export cancelled");
-                return;
-            } catch (IOException e) {
-                Main.error(e);
-            } catch (ImageWriteException e) {
-                Main.error(e);
-            } catch (ImageReadException e) {
-                Main.error(e);
-            }
-
-            // Increases the progress bar.
-            monitor.worked(PleaseWaitProgressMonitor.PROGRESS_BAR_MAX / amount);
-            monitor.setCustomText("Downloaded " + (i + 1) + "/" + amount);
-        }
-    }
+  }
 }
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 31349)
+++ applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/downloads/MapillaryImageInfoDownloaderThread.java	(revision 31350)
@@ -25,44 +25,43 @@
  */
 public class MapillaryImageInfoDownloaderThread extends Thread {
-    private final String url;
-    private final ExecutorService ex;
-    private final MapillaryLayer layer;
+  private final String url;
+  private final ExecutorService ex;
+  private final MapillaryLayer layer;
 
-    public MapillaryImageInfoDownloaderThread(ExecutorService ex, String url,
-            MapillaryLayer layer) {
-        this.ex = ex;
-        this.url = url;
-        this.layer = layer;
+  public MapillaryImageInfoDownloaderThread(ExecutorService ex, String url,
+      MapillaryLayer layer) {
+    this.ex = ex;
+    this.url = url;
+    this.layer = layer;
+  }
+
+  public void run() {
+    try {
+      BufferedReader br = new BufferedReader(new InputStreamReader(
+          new URL(url).openStream(), "UTF-8"));
+      JsonObject jsonobj = Json.createReader(br).readObject();
+      if (!jsonobj.getBoolean("more"))
+        ex.shutdown();
+      JsonArray jsonarr = jsonobj.getJsonArray("ims");
+      JsonObject data;
+      for (int i = 0; i < jsonarr.size(); i++) {
+        data = jsonarr.getJsonObject(i);
+        String key = data.getString("key");
+        for (MapillaryAbstractImage image : layer.data.getImages()) {
+          if (image instanceof MapillaryImage) {
+            if (((MapillaryImage) image).getKey().equals(key)
+                && ((MapillaryImage) image).getUser() == null) {
+              ((MapillaryImage) image).setUser(data.getString("user"));
+              ((MapillaryImage) image).setCapturedAt(data.getJsonNumber(
+                  "captured_at").longValue());
+            }
+          }
+        }
+      }
+    } catch (MalformedURLException e) {
+      Main.error(e);
+    } catch (IOException e) {
+      Main.error(e);
     }
-
-    public void run() {
-        try {
-            BufferedReader br = new BufferedReader(new InputStreamReader(
-                    new URL(url).openStream(), "UTF-8"));
-            JsonObject jsonobj = Json.createReader(br).readObject();
-            if (!jsonobj.getBoolean("more"))
-                ex.shutdown();
-            JsonArray jsonarr = jsonobj.getJsonArray("ims");
-            JsonObject data;
-            for (int i = 0; i < jsonarr.size(); i++) {
-                data = jsonarr.getJsonObject(i);
-                String key = data.getString("key");
-                for (MapillaryAbstractImage image : layer.data.getImages()) {
-                    if (image instanceof MapillaryImage) {
-                        if (((MapillaryImage) image).getKey().equals(key)
-                                && ((MapillaryImage) image).getUser() == null) {
-                            ((MapillaryImage) image).setUser(data
-                                    .getString("user"));
-                            ((MapillaryImage) image).setCapturedAt(data
-                                    .getJsonNumber("captured_at").longValue());
-                        }
-                    }
-                }
-            }
-        } catch (MalformedURLException e) {
-            Main.error(e);
-        } catch (IOException e) {
-            Main.error(e);
-        }
-    }
+  }
 }
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 31349)
+++ applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/downloads/MapillarySequenceDownloadThread.java	(revision 31350)
@@ -31,99 +31,96 @@
 public class MapillarySequenceDownloadThread extends Thread {
 
-    private final String url;
-    private final ExecutorService ex;
-    private final List<Bounds> bounds;
-    private final MapillaryLayer layer;
-    private final MapillarySquareDownloadManagerThread manager;
+  private final String url;
+  private final ExecutorService ex;
+  private final List<Bounds> bounds;
+  private final MapillaryLayer layer;
+  private final MapillarySquareDownloadManagerThread manager;
 
-    public MapillarySequenceDownloadThread(ExecutorService ex, String url,
-            MapillaryLayer layer, MapillarySquareDownloadManagerThread manager) {
-        this.url = url;
-        this.ex = ex;
-        this.bounds = layer.bounds;
-        this.layer = layer;
-        this.manager = manager;
+  public MapillarySequenceDownloadThread(ExecutorService ex, String url,
+      MapillaryLayer layer, MapillarySquareDownloadManagerThread manager) {
+    this.url = url;
+    this.ex = ex;
+    this.bounds = layer.bounds;
+    this.layer = layer;
+    this.manager = manager;
+  }
+
+  public void run() {
+    try {
+      BufferedReader br;
+      br = new BufferedReader(new InputStreamReader(new URL(url).openStream(),
+          "UTF-8"));
+      JsonObject jsonall = Json.createReader(br).readObject();
+
+      if (!jsonall.getBoolean("more") && !ex.isShutdown())
+        ex.shutdown();
+      JsonArray jsonseq = jsonall.getJsonArray("ss");
+      boolean isSequenceWrong = false;
+      for (int i = 0; i < jsonseq.size(); i++) {
+        JsonObject jsonobj = jsonseq.getJsonObject(i);
+        JsonArray cas = jsonobj.getJsonArray("cas");
+        JsonArray coords = jsonobj.getJsonArray("coords");
+        JsonArray keys = jsonobj.getJsonArray("keys");
+        ArrayList<MapillaryImage> images = new ArrayList<>();
+        for (int j = 0; j < cas.size(); j++) {
+          try {
+            images.add(new MapillaryImage(keys.getString(j), coords
+                .getJsonArray(j).getJsonNumber(1).doubleValue(), coords
+                .getJsonArray(j).getJsonNumber(0).doubleValue(), cas
+                .getJsonNumber(j).doubleValue()));
+          } catch (IndexOutOfBoundsException e) {
+            Main.warn("Mapillary bug at " + url);
+            isSequenceWrong = true;
+          }
+        }
+        if (isSequenceWrong)
+          break;
+        MapillarySequence sequence = new MapillarySequence(
+            jsonobj.getString("key"), jsonobj.getJsonNumber("captured_at")
+                .longValue());
+
+        List<MapillaryImage> finalImages = new ArrayList<>(images);
+        // Here it gets only those images which are in the downloaded
+        // area.
+        for (MapillaryAbstractImage img : images) {
+          if (!isInside(img))
+            finalImages.remove(img);
+        }
+
+        boolean imagesAdded = false;
+        MapillaryImage.lock.lock();
+        for (MapillaryImage img : finalImages) {
+          if (layer.data.getImages().contains(img)) {
+            sequence.add(img);
+            ((MapillaryImage) layer.data.getImages().get(
+                layer.data.getImages().indexOf(img))).setSequence(sequence);
+            finalImages.set(
+                finalImages.indexOf(img),
+                (MapillaryImage) layer.data.getImages().get(
+                    layer.data.getImages().indexOf(img)));
+          } else {
+            img.setSequence(sequence);
+            imagesAdded = true;
+            sequence.add(img);
+          }
+        }
+        MapillaryImage.lock.unlock();
+        if (manager != null) {
+          manager.imagesAdded = imagesAdded;
+        }
+        layer.data.addWithoutUpdate(new ArrayList<MapillaryAbstractImage>(
+            finalImages));
+      }
+    } catch (IOException e) {
+      Main.error("Error reading the url " + url
+          + " might be a Mapillary problem.");
     }
+  }
 
-    public void run() {
-        try {
-            BufferedReader br;
-            br = new BufferedReader(new InputStreamReader(
-                    new URL(url).openStream(), "UTF-8"));
-            JsonObject jsonall = Json.createReader(br).readObject();
-
-            if (!jsonall.getBoolean("more") && !ex.isShutdown())
-                ex.shutdown();
-            JsonArray jsonseq = jsonall.getJsonArray("ss");
-            boolean isSequenceWrong = false;
-            for (int i = 0; i < jsonseq.size(); i++) {
-                JsonObject jsonobj = jsonseq.getJsonObject(i);
-                JsonArray cas = jsonobj.getJsonArray("cas");
-                JsonArray coords = jsonobj.getJsonArray("coords");
-                JsonArray keys = jsonobj.getJsonArray("keys");
-                ArrayList<MapillaryImage> images = new ArrayList<>();
-                for (int j = 0; j < cas.size(); j++) {
-                    try {
-                        images.add(new MapillaryImage(keys.getString(j),
-                                coords.getJsonArray(j).getJsonNumber(1)
-                                        .doubleValue(), coords.getJsonArray(j)
-                                        .getJsonNumber(0).doubleValue(), cas
-                                        .getJsonNumber(j).doubleValue()));
-                    } catch (IndexOutOfBoundsException e) {
-                        Main.warn("Mapillary bug at " + url);
-                        isSequenceWrong = true;
-                    }
-                }
-                if (isSequenceWrong)
-                    break;
-                MapillarySequence sequence = new MapillarySequence(
-                        jsonobj.getString("key"), jsonobj.getJsonNumber(
-                                "captured_at").longValue());
-
-                List<MapillaryImage> finalImages = new ArrayList<>(images);
-                // Here it gets only those images which are in the downloaded
-                // area.
-                for (MapillaryAbstractImage img : images) {
-                    if (!isInside(img))
-                        finalImages.remove(img);
-                }
-
-                boolean imagesAdded = false;
-                MapillaryImage.lock.lock();
-                for (MapillaryImage img : finalImages) {
-                    if (layer.data.getImages().contains(img)) {
-                        sequence.add(img);
-                        ((MapillaryImage) layer.data.getImages().get(
-                                layer.data.getImages().indexOf(img)))
-                                .setSequence(sequence);
-                        finalImages.set(
-                                finalImages.indexOf(img),
-                                (MapillaryImage) layer.data.getImages().get(
-                                        layer.data.getImages().indexOf(img)));
-                    } else {
-                        img.setSequence(sequence);
-                        imagesAdded = true;
-                        sequence.add(img);
-                    }
-                }
-                MapillaryImage.lock.unlock();
-                if (manager != null) {
-                	manager.imagesAdded = imagesAdded;
-                }
-                layer.data
-                        .addWithoutUpdate(new ArrayList<MapillaryAbstractImage>(
-                                finalImages));
-            }
-        } catch (IOException e) {
-            Main.error("Error reading the url " + url
-                    + " might be a Mapillary problem.");
-        }
-    }
-
-    private boolean isInside(MapillaryAbstractImage image) {
-        for (int i = 0; i < bounds.size(); i++)
-            if (bounds.get(i).contains(image.getLatLon()))
-                return true;
-        return false;
-    }
+  private boolean isInside(MapillaryAbstractImage image) {
+    for (int i = 0; i < bounds.size(); i++)
+      if (bounds.get(i).contains(image.getLatLon()))
+        return true;
+    return false;
+  }
 }
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 31349)
+++ applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/downloads/MapillarySignDownloaderThread.java	(revision 31350)
@@ -19,68 +19,60 @@
 public class MapillarySignDownloaderThread extends Thread {
 
-    private final String url;
-    private final ExecutorService ex;
-    private final MapillaryLayer layer;
+  private final String url;
+  private final ExecutorService ex;
+  private final MapillaryLayer layer;
 
-    public MapillarySignDownloaderThread(ExecutorService ex, String url,
-            MapillaryLayer layer) {
-        this.ex = ex;
-        this.url = url;
-        this.layer = layer;
+  public MapillarySignDownloaderThread(ExecutorService ex, String url,
+      MapillaryLayer layer) {
+    this.ex = ex;
+    this.url = url;
+    this.layer = layer;
+  }
+
+  @Override
+  public void run() {
+    BufferedReader br;
+    try {
+      br = new BufferedReader(new InputStreamReader(new URL(url).openStream(),
+          "UTF-8"));
+      JsonObject jsonobj = Json.createReader(br).readObject();
+      if (!jsonobj.getBoolean("more")) {
+        ex.shutdown();
+      }
+      JsonArray jsonarr = jsonobj.getJsonArray("ims");
+      for (int i = 0; i < jsonarr.size(); i++) {
+        JsonArray rects = jsonarr.getJsonObject(i).getJsonArray("rects");
+        JsonArray rectversions = jsonarr.getJsonObject(i).getJsonArray(
+            "rectversions");
+        String key = jsonarr.getJsonObject(i).getString("key");
+        if (rectversions != null) {
+          for (int j = 0; j < rectversions.size(); j++) {
+            rects = rectversions.getJsonObject(j).getJsonArray("rects");
+            for (int k = 0; k < rects.size(); k++) {
+              JsonObject data = rects.getJsonObject(k);
+              for (MapillaryAbstractImage image : layer.data.getImages())
+                if (image instanceof MapillaryImage
+                    && ((MapillaryImage) image).getKey().equals(key))
+                  ((MapillaryImage) image).addSign(data.getString("type"));
+            }
+          }
+        }
+
+        // Just one sign on the picture
+        else if (rects != null) {
+          for (int j = 0; j < rects.size(); j++) {
+            JsonObject data = rects.getJsonObject(j);
+            for (MapillaryAbstractImage image : layer.data.getImages())
+              if (image instanceof MapillaryImage
+                  && ((MapillaryImage) image).getKey().equals(key))
+                ((MapillaryImage) image).addSign(data.getString("type"));
+          }
+        }
+      }
+    } catch (MalformedURLException e) {
+      Main.error(e);
+    } catch (IOException e) {
+      Main.error(e);
     }
-
-    @Override
-    public void run() {
-        BufferedReader br;
-        try {
-            br = new BufferedReader(new InputStreamReader(
-                    new URL(url).openStream(), "UTF-8"));
-            JsonObject jsonobj = Json.createReader(br).readObject();
-            if (!jsonobj.getBoolean("more")) {
-                ex.shutdown();
-            }
-            JsonArray jsonarr = jsonobj.getJsonArray("ims");
-            for (int i = 0; i < jsonarr.size(); i++) {
-                JsonArray rects = jsonarr.getJsonObject(i)
-                        .getJsonArray("rects");
-                JsonArray rectversions = jsonarr.getJsonObject(i).getJsonArray(
-                        "rectversions");
-                String key = jsonarr.getJsonObject(i).getString("key");
-                if (rectversions != null) {
-                    for (int j = 0; j < rectversions.size(); j++) {
-                        rects = rectversions.getJsonObject(j).getJsonArray(
-                                "rects");
-                        for (int k = 0; k < rects.size(); k++) {
-                            JsonObject data = rects.getJsonObject(k);
-                            for (MapillaryAbstractImage image : layer.data
-                                    .getImages())
-                                if (image instanceof MapillaryImage
-                                        && ((MapillaryImage) image).getKey()
-                                                .equals(key))
-                                    ((MapillaryImage) image).addSign(data
-                                            .getString("type"));
-                        }
-                    }
-                }
-
-                // Just one sign on the picture
-                else if (rects != null) {
-                    for (int j = 0; j < rects.size(); j++) {
-                        JsonObject data = rects.getJsonObject(j);
-                        for (MapillaryAbstractImage image : layer.data
-                                .getImages())
-                            if (image instanceof MapillaryImage
-                                    && ((MapillaryImage) image).getKey()
-                                            .equals(key))
-                                ((MapillaryImage) image).addSign(data
-                                        .getString("type"));
-                    }
-                }
-            }
-        } catch (MalformedURLException e) {
-            Main.error(e);
-        } catch (IOException e) {
-            Main.error(e);
-        }
-    }
+  }
 }
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 31349)
+++ applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/downloads/MapillarySquareDownloadManagerThread.java	(revision 31350)
@@ -14,6 +14,6 @@
 /**
  * This Class is needed to create an indeterminate amount of downloads, because
- * the Mapillary API has a parameter called page which is needed when the
- * amount of requested images is quite big.
+ * the Mapillary API has a parameter called page which is needed when the amount
+ * of requested images is quite big.
  * 
  * @author nokutu
@@ -23,84 +23,83 @@
 public class MapillarySquareDownloadManagerThread extends Thread {
 
-    private final String urlImages;
-    private final String urlSequences;
-    private final String urlSigns;
-    private final MapillaryLayer layer;
-    public boolean imagesAdded = false;
+  private final String urlImages;
+  private final String urlSequences;
+  private final String urlSigns;
+  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;
-        this.layer = layer;
+  public MapillarySquareDownloadManagerThread(String urlImages,
+      String urlSequences, String urlSigns, MapillaryLayer layer) {
+    this.urlImages = urlImages;
+    this.urlSequences = urlSequences;
+    this.urlSigns = urlSigns;
+    this.layer = layer;
+  }
+
+  public void run() {
+    Main.map.statusLine.setHelpText("Downloading images from Mapillary");
+    try {
+      downloadSequences();
+      if (imagesAdded) {
+        Main.map.statusLine.setHelpText("Downloading image's information");
+        completeImages();
+        MapillaryMainDialog.getInstance().updateTitle();
+        Main.map.statusLine.setHelpText("Downloading signs");
+        downloadSigns();
+      }
+    } catch (InterruptedException e) {
+      Main.error(e);
     }
+    if (layer.data.getImages().size() > 0)
+      Main.map.statusLine.setHelpText(tr("Total images: ")
+          + layer.data.getImages().size());
+    else
+      Main.map.statusLine.setHelpText(tr("No images found"));
+    layer.data.dataUpdated();
+    MapillaryFilterDialog.getInstance().refresh();
+    MapillaryMainDialog.getInstance().updateImage();
+  }
 
-    public void run() {
-        Main.map.statusLine.setHelpText("Downloading images from Mapillary");
-        try {
-            downloadSequences();
-            if (imagesAdded) {
-                Main.map.statusLine
-                        .setHelpText("Downloading image's information");
-                completeImages();
-                MapillaryMainDialog.getInstance().updateTitle();
-                Main.map.statusLine.setHelpText("Downloading signs");
-                downloadSigns();
-            }
-        } catch (InterruptedException e) {
-            Main.error(e);
-        }
-        if (layer.data.getImages().size() > 0)
-            Main.map.statusLine.setHelpText(tr("Total images: ")
-                    + layer.data.getImages().size());
-        else
-            Main.map.statusLine.setHelpText(tr("No images found"));
-        layer.data.dataUpdated();
-        MapillaryFilterDialog.getInstance().refresh();
-        MapillaryMainDialog.getInstance().updateImage();
+  private void downloadSequences() throws InterruptedException {
+    ThreadPoolExecutor ex = new ThreadPoolExecutor(3, 5, 25, TimeUnit.SECONDS,
+        new ArrayBlockingQueue<Runnable>(5));
+    int page = 0;
+    while (!ex.isShutdown()) {
+      ex.execute(new MapillarySequenceDownloadThread(ex, urlSequences
+          + "&page=" + page + "&limit=10", layer, this));
+      while (ex.getQueue().remainingCapacity() == 0)
+        Thread.sleep(500);
+      page++;
     }
+    ex.awaitTermination(15, TimeUnit.SECONDS);
+    layer.data.dataUpdated();
+  }
 
-    private void downloadSequences() throws InterruptedException {
-        ThreadPoolExecutor ex = new ThreadPoolExecutor(3, 5, 25,
-                TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(5));
-        int page = 0;
-        while (!ex.isShutdown()) {
-            ex.execute(new MapillarySequenceDownloadThread(ex, urlSequences
-                    + "&page=" + page + "&limit=10", layer, this));
-            while (ex.getQueue().remainingCapacity() == 0)
-                Thread.sleep(500);
-            page++;
-        }
-        ex.awaitTermination(15, TimeUnit.SECONDS);
-        layer.data.dataUpdated();
+  private void completeImages() throws InterruptedException {
+    ThreadPoolExecutor ex = new ThreadPoolExecutor(3, 5, 25, TimeUnit.SECONDS,
+        new ArrayBlockingQueue<Runnable>(5));
+    int page = 0;
+    while (!ex.isShutdown()) {
+      ex.execute(new MapillaryImageInfoDownloaderThread(ex, urlImages
+          + "&page=" + page + "&limit=20", layer));
+      while (ex.getQueue().remainingCapacity() == 0)
+        Thread.sleep(100);
+      page++;
     }
+    ex.awaitTermination(15, TimeUnit.SECONDS);
+  }
 
-    private void completeImages() throws InterruptedException {
-        ThreadPoolExecutor ex = new ThreadPoolExecutor(3, 5, 25,
-                TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(5));
-        int page = 0;
-        while (!ex.isShutdown()) {
-            ex.execute(new MapillaryImageInfoDownloaderThread(ex, urlImages
-                    + "&page=" + page + "&limit=20", layer));
-            while (ex.getQueue().remainingCapacity() == 0)
-                Thread.sleep(100);
-            page++;
-        }
-        ex.awaitTermination(15, TimeUnit.SECONDS);
+  private void downloadSigns() throws InterruptedException {
+    ThreadPoolExecutor ex = new ThreadPoolExecutor(3, 5, 25, TimeUnit.SECONDS,
+        new ArrayBlockingQueue<Runnable>(5));
+    int page = 0;
+    while (!ex.isShutdown()) {
+      ex.execute(new MapillarySignDownloaderThread(ex, urlSigns + "&page="
+          + page + "&limit=20", layer));
+      while (ex.getQueue().remainingCapacity() == 0)
+        Thread.sleep(100);
+      page++;
     }
-
-    private void downloadSigns() throws InterruptedException {
-        ThreadPoolExecutor ex = new ThreadPoolExecutor(3, 5, 25,
-                TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(5));
-        int page = 0;
-        while (!ex.isShutdown()) {
-            ex.execute(new MapillarySignDownloaderThread(ex, urlSigns
-                    + "&page=" + page + "&limit=20", layer));
-            while (ex.getQueue().remainingCapacity() == 0)
-                Thread.sleep(100);
-            page++;
-        }
-        ex.awaitTermination(15, TimeUnit.SECONDS);
-    }
+    ex.awaitTermination(15, TimeUnit.SECONDS);
+  }
 }
Index: applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/gui/HyperlinkLabel.java
===================================================================
--- applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/gui/HyperlinkLabel.java	(revision 31349)
+++ applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/gui/HyperlinkLabel.java	(revision 31350)
@@ -21,106 +21,107 @@
 public class HyperlinkLabel extends JLabel implements ActionListener {
 
-    private String text;
-    private URL url;
+  private String text;
+  private URL url;
 
-    /**
-     * Creates a new HyperlinlLabel.
-     */
-    public HyperlinkLabel() {
-        super(tr("View in website"), SwingUtilities.RIGHT);
-        this.addActionListener(this);
-        setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
+  /**
+   * Creates a new HyperlinlLabel.
+   */
+  public HyperlinkLabel() {
+    super(tr("View in website"), SwingUtilities.RIGHT);
+    this.addActionListener(this);
+    setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
 
-        enableEvents(MouseEvent.MOUSE_EVENT_MASK);
+    enableEvents(MouseEvent.MOUSE_EVENT_MASK);
+  }
+
+  /**
+   * Sets the text of the label.
+   */
+  public void setText(String text) {
+    super
+        .setText("<html><font color=\"#0000CF\" size=\"2\">" + text + "</font></html>"); //$NON-NLS-1$ //$NON-NLS-2$
+    this.text = text;
+  }
+
+  /**
+   * Sets a new URL, just pass the key of the image or null if there is none.
+   * 
+   * @param key
+   */
+  public void setURL(String key) {
+    if (key == null) {
+      this.url = null;
+      return;
     }
+    try {
+      this.url = new URL("http://www.mapillary.com/map/im/" + key);
+    } catch (MalformedURLException e) {
+      Main.error(e);
+    }
+  }
 
-    /**
-     * Sets the text of the label.
-     */
-    public void setText(String text) {
-        super.setText("<html><font color=\"#0000CF\" size=\"2\">" + text + "</font></html>"); //$NON-NLS-1$ //$NON-NLS-2$
-        this.text = text;
+  /**
+   * Returns the text set by the user.
+   */
+  public String getNormalText() {
+    return text;
+  }
+
+  /**
+   * Processes mouse events and responds to clicks.
+   */
+  protected void processMouseEvent(MouseEvent evt) {
+    super.processMouseEvent(evt);
+    if (evt.getID() == MouseEvent.MOUSE_CLICKED)
+      fireActionPerformed(new ActionEvent(this, ActionEvent.ACTION_PERFORMED,
+          getNormalText()));
+  }
+
+  /**
+   * Adds an ActionListener to the list of listeners receiving notifications
+   * when the label is clicked.
+   */
+  public void addActionListener(ActionListener listener) {
+    listenerList.add(ActionListener.class, listener);
+  }
+
+  /**
+   * Removes the given ActionListener from the list of listeners receiving
+   * notifications when the label is clicked.
+   */
+  public void removeActionListener(ActionListener listener) {
+    listenerList.remove(ActionListener.class, listener);
+  }
+
+  /**
+   * Fires an ActionEvent to all interested listeners.
+   */
+  protected void fireActionPerformed(ActionEvent evt) {
+    Object[] listeners = listenerList.getListenerList();
+    for (int i = 0; i < listeners.length; i += 2) {
+      if (listeners[i] == ActionListener.class) {
+        ActionListener listener = (ActionListener) listeners[i + 1];
+        listener.actionPerformed(evt);
+      }
     }
+  }
 
-    /**
-     * Sets a new URL, just pass the key of the image or null if there is none.
-     * 
-     * @param key
-     */
-    public void setURL(String key) {
-        if (key == null) {
-            this.url = null;
-            return;
-        }
-        try {
-            this.url = new URL("http://www.mapillary.com/map/im/" + key);
-        } catch (MalformedURLException e) {
-            Main.error(e);
-        }
+  @Override
+  public void actionPerformed(ActionEvent e) {
+    if (this.url == null)
+      return;
+    Desktop desktop = Desktop.getDesktop();
+    try {
+      desktop.browse(url.toURI());
+    } catch (IOException | URISyntaxException ex) {
+      ex.printStackTrace();
+    } catch (UnsupportedOperationException ex) {
+      Runtime runtime = Runtime.getRuntime();
+      try {
+        runtime.exec("xdg-open " + url);
+      } catch (IOException exc) {
+        exc.printStackTrace();
+      }
     }
-
-    /**
-     * Returns the text set by the user.
-     */
-    public String getNormalText() {
-        return text;
-    }
-
-    /**
-     * Processes mouse events and responds to clicks.
-     */
-    protected void processMouseEvent(MouseEvent evt) {
-        super.processMouseEvent(evt);
-        if (evt.getID() == MouseEvent.MOUSE_CLICKED)
-            fireActionPerformed(new ActionEvent(this,
-                    ActionEvent.ACTION_PERFORMED, getNormalText()));
-    }
-
-    /**
-     * Adds an ActionListener to the list of listeners receiving notifications
-     * when the label is clicked.
-     */
-    public void addActionListener(ActionListener listener) {
-        listenerList.add(ActionListener.class, listener);
-    }
-
-    /**
-     * Removes the given ActionListener from the list of listeners receiving
-     * notifications when the label is clicked.
-     */
-    public void removeActionListener(ActionListener listener) {
-        listenerList.remove(ActionListener.class, listener);
-    }
-
-    /**
-     * Fires an ActionEvent to all interested listeners.
-     */
-    protected void fireActionPerformed(ActionEvent evt) {
-        Object[] listeners = listenerList.getListenerList();
-        for (int i = 0; i < listeners.length; i += 2) {
-            if (listeners[i] == ActionListener.class) {
-                ActionListener listener = (ActionListener) listeners[i + 1];
-                listener.actionPerformed(evt);
-            }
-        }
-    }
-
-    @Override
-    public void actionPerformed(ActionEvent e) {
-        if (this.url == null)
-            return;
-        Desktop desktop = Desktop.getDesktop();
-        try {
-            desktop.browse(url.toURI());
-        } catch (IOException | URISyntaxException ex) {
-            ex.printStackTrace();
-        } catch (UnsupportedOperationException ex) {
-            Runtime runtime = Runtime.getRuntime();
-            try {
-                runtime.exec("xdg-open " + url);
-            } catch (IOException exc) {
-                exc.printStackTrace();
-            }
-        }
-    }
+  }
 }
Index: applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/gui/MapillaryExportDialog.java
===================================================================
--- applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/gui/MapillaryExportDialog.java	(revision 31349)
+++ applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/gui/MapillaryExportDialog.java	(revision 31350)
@@ -30,115 +30,113 @@
 public class MapillaryExportDialog extends JPanel implements ActionListener {
 
-    protected JOptionPane optionPane;
-    /** Button to export all downloaded images. */
-    public JRadioButton all;
-    /**
-     * Button to export all images in the sequence of the selected
-     * MapillaryImage.
-     */
-    public JRadioButton sequence;
-    /**
-     * Button to export all images belonging to the selected MapillaryImage
-     * objects.
-     */
-    public JRadioButton selected;
-    public JRadioButton rewrite;
-    public ButtonGroup group;
-    protected JButton choose;
-    protected JLabel path;
-    public JFileChooser chooser;
-    protected String exportDirectory;
+  protected JOptionPane optionPane;
+  /** Button to export all downloaded images. */
+  public JRadioButton all;
+  /**
+   * Button to export all images in the sequence of the selected MapillaryImage.
+   */
+  public JRadioButton sequence;
+  /**
+   * Button to export all images belonging to the selected MapillaryImage
+   * objects.
+   */
+  public JRadioButton selected;
+  public JRadioButton rewrite;
+  public ButtonGroup group;
+  protected JButton choose;
+  protected JLabel path;
+  public JFileChooser chooser;
+  protected String exportDirectory;
 
-    public MapillaryExportDialog() {
-        setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));
-        
-        RewriteButtonAction action = new RewriteButtonAction(this);
-        group = new ButtonGroup();
-        all = new JRadioButton(action);
-        all.setText(tr("Export all images"));
-        sequence = new JRadioButton(action);
-        sequence.setText(tr("Export selected sequence"));
-        selected = new JRadioButton(action);
-        selected.setText(tr("Export selected images"));
-        rewrite = new JRadioButton(action);
-        rewrite.setText(tr("Rewrite imported images"));
-        group.add(all);
-        group.add(sequence);
-        group.add(selected);
-        group.add(rewrite);
-        // Some options are disabled depending on the circumstances
-        if (MapillaryData.getInstance().getSelectedImage() == null
-                || !(MapillaryData.getInstance().getSelectedImage() instanceof MapillaryImage && ((MapillaryImage) MapillaryData
-                        .getInstance().getSelectedImage()).getSequence() != null)) {
-            sequence.setEnabled(false);
-        }
-        if (MapillaryData.getInstance().getMultiSelectedImages().isEmpty()) {
-            selected.setEnabled(false);
-        }
-        rewrite.setEnabled(false);
-        for (MapillaryAbstractImage img : MapillaryData.getInstance().getImages())
-            if (img instanceof MapillaryImportedImage)
-                rewrite.setEnabled(true);
-        
-        path = new JLabel(tr("Select a folder"));
-        choose = new JButton(tr("Explore"));
-        choose.addActionListener(this);
+  public MapillaryExportDialog() {
+    setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));
 
-        // All options belong to the same jpanel so the are in line.
-        JPanel jpanel = new JPanel();
-        jpanel.setLayout(new BoxLayout(jpanel, BoxLayout.PAGE_AXIS));
-        jpanel.add(all);
-        jpanel.add(sequence);
-        jpanel.add(selected);
-        jpanel.add(rewrite);
-        jpanel.setAlignmentX(Component.CENTER_ALIGNMENT);
-        path.setAlignmentX(Component.CENTER_ALIGNMENT);
-        choose.setAlignmentX(Component.CENTER_ALIGNMENT);
+    RewriteButtonAction action = new RewriteButtonAction(this);
+    group = new ButtonGroup();
+    all = new JRadioButton(action);
+    all.setText(tr("Export all images"));
+    sequence = new JRadioButton(action);
+    sequence.setText(tr("Export selected sequence"));
+    selected = new JRadioButton(action);
+    selected.setText(tr("Export selected images"));
+    rewrite = new JRadioButton(action);
+    rewrite.setText(tr("Rewrite imported images"));
+    group.add(all);
+    group.add(sequence);
+    group.add(selected);
+    group.add(rewrite);
+    // Some options are disabled depending on the circumstances
+    if (MapillaryData.getInstance().getSelectedImage() == null
+        || !(MapillaryData.getInstance().getSelectedImage() instanceof MapillaryImage && ((MapillaryImage) MapillaryData
+            .getInstance().getSelectedImage()).getSequence() != null)) {
+      sequence.setEnabled(false);
+    }
+    if (MapillaryData.getInstance().getMultiSelectedImages().isEmpty()) {
+      selected.setEnabled(false);
+    }
+    rewrite.setEnabled(false);
+    for (MapillaryAbstractImage img : MapillaryData.getInstance().getImages())
+      if (img instanceof MapillaryImportedImage)
+        rewrite.setEnabled(true);
 
-        add(jpanel);
-        add(path);
-        add(choose);
+    path = new JLabel(tr("Select a folder"));
+    choose = new JButton(tr("Explore"));
+    choose.addActionListener(this);
+
+    // All options belong to the same jpanel so the are in line.
+    JPanel jpanel = new JPanel();
+    jpanel.setLayout(new BoxLayout(jpanel, BoxLayout.PAGE_AXIS));
+    jpanel.add(all);
+    jpanel.add(sequence);
+    jpanel.add(selected);
+    jpanel.add(rewrite);
+    jpanel.setAlignmentX(Component.CENTER_ALIGNMENT);
+    path.setAlignmentX(Component.CENTER_ALIGNMENT);
+    choose.setAlignmentX(Component.CENTER_ALIGNMENT);
+
+    add(jpanel);
+    add(path);
+    add(choose);
+  }
+
+  /**
+   * Creates the folder choser GUI.
+   */
+  @Override
+  public void actionPerformed(ActionEvent e) {
+    chooser = new JFileChooser();
+    chooser.setCurrentDirectory(new java.io.File(System
+        .getProperty("user.home")));
+    chooser.setDialogTitle(tr("Select a directory"));
+    chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
+    chooser.setAcceptAllFileFilterUsed(false);
+
+    if (chooser.showOpenDialog(this) == JFileChooser.APPROVE_OPTION) {
+      path.setText(chooser.getSelectedFile().toString());
+      this.updateUI();
+    }
+  }
+
+  public class RewriteButtonAction extends AbstractAction {
+
+    private String lastPath;
+    private MapillaryExportDialog dlg;
+
+    public RewriteButtonAction(MapillaryExportDialog dlg) {
+      this.dlg = dlg;
     }
 
-    /**
-     * Creates the folder choser GUI.
-     */
     @Override
-    public void actionPerformed(ActionEvent e) {
-        chooser = new JFileChooser();
-        chooser.setCurrentDirectory(new java.io.File(System
-                .getProperty("user.home")));
-        chooser.setDialogTitle(tr("Select a directory"));
-        chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
-        chooser.setAcceptAllFileFilterUsed(false);
+    public void actionPerformed(ActionEvent arg0) {
+      choose.setEnabled(!rewrite.isSelected());
+      if (rewrite.isSelected()) {
+        lastPath = dlg.path.getText();
+        dlg.path.setText(" ");
+      } else if (lastPath != null) {
+        dlg.path.setText(lastPath);
+      }
 
-        if (chooser.showOpenDialog(this) == JFileChooser.APPROVE_OPTION) {
-            path.setText(chooser.getSelectedFile().toString());
-            this.updateUI();
-        }
     }
-    
-    public class RewriteButtonAction extends AbstractAction {
 
-        private String lastPath;
-        private MapillaryExportDialog dlg;
-        
-        public RewriteButtonAction(MapillaryExportDialog dlg) {
-            this.dlg = dlg;
-        }
-        
-        @Override
-        public void actionPerformed(ActionEvent arg0) {
-           choose.setEnabled(!rewrite.isSelected());
-           if (rewrite.isSelected()) {
-               lastPath = dlg.path.getText();
-               dlg.path.setText(" ");
-           } 
-           else if (lastPath != null){
-               dlg.path.setText(lastPath);
-           }
-           
-        }
-        
-    }
+  }
 }
Index: applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/gui/MapillaryFilterChooseSigns.java
===================================================================
--- applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/gui/MapillaryFilterChooseSigns.java	(revision 31349)
+++ applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/gui/MapillaryFilterChooseSigns.java	(revision 31350)
@@ -14,149 +14,149 @@
 
 public class MapillaryFilterChooseSigns extends JPanel implements
-        ActionListener {
+    ActionListener {
 
-    public final JCheckBox maxspeed = new JCheckBox();
-    public final JCheckBox stop = new JCheckBox();
-    public final JCheckBox giveWay = new JCheckBox();
-    public final JCheckBox roundabout = new JCheckBox();
-    public final JCheckBox access = new JCheckBox();
-    public final JCheckBox intersection = new JCheckBox();
-    public final JCheckBox direction = new JCheckBox();
-    public final JCheckBox uneven = new JCheckBox();
-    public final JCheckBox noParking = new JCheckBox();
-    public final JCheckBox noOvertaking = new JCheckBox();
-    public final JCheckBox crossing = new JCheckBox();
-    public final JCheckBox noTurn = new JCheckBox();
+  public final JCheckBox maxspeed = new JCheckBox();
+  public final JCheckBox stop = new JCheckBox();
+  public final JCheckBox giveWay = new JCheckBox();
+  public final JCheckBox roundabout = new JCheckBox();
+  public final JCheckBox access = new JCheckBox();
+  public final JCheckBox intersection = new JCheckBox();
+  public final JCheckBox direction = new JCheckBox();
+  public final JCheckBox uneven = new JCheckBox();
+  public final JCheckBox noParking = new JCheckBox();
+  public final JCheckBox noOvertaking = new JCheckBox();
+  public final JCheckBox crossing = new JCheckBox();
+  public final JCheckBox noTurn = new JCheckBox();
 
-    private static MapillaryFilterChooseSigns INSTANCE;
+  private static MapillaryFilterChooseSigns INSTANCE;
 
-    public MapillaryFilterChooseSigns() {
-        maxspeed.setSelected(true);
-        stop.setSelected(true);
-        giveWay.setSelected(true);
-        roundabout.setSelected(true);
-        access.setSelected(true);
-        intersection.setSelected(true);
-        direction.setSelected(true);
-        uneven.setSelected(true);
-        noParking.setSelected(true);
-        noOvertaking.setSelected(true);
-        crossing.setSelected(true);
-        noTurn.setSelected(true);
+  public MapillaryFilterChooseSigns() {
+    maxspeed.setSelected(true);
+    stop.setSelected(true);
+    giveWay.setSelected(true);
+    roundabout.setSelected(true);
+    access.setSelected(true);
+    intersection.setSelected(true);
+    direction.setSelected(true);
+    uneven.setSelected(true);
+    noParking.setSelected(true);
+    noOvertaking.setSelected(true);
+    crossing.setSelected(true);
+    noTurn.setSelected(true);
 
-        // Max speed sign
-        JPanel maxspeedPanel = new JPanel();
-        JLabel maxspeedLabel = new JLabel(tr("Speed limit"));
-        maxspeedLabel.setIcon(new ImageProvider("signs/speed.png").get());
-        maxspeedPanel.add(maxspeedLabel);
-        maxspeedPanel.add(maxspeed);
-        this.add(maxspeedPanel);
+    // Max speed sign
+    JPanel maxspeedPanel = new JPanel();
+    JLabel maxspeedLabel = new JLabel(tr("Speed limit"));
+    maxspeedLabel.setIcon(new ImageProvider("signs/speed.png").get());
+    maxspeedPanel.add(maxspeedLabel);
+    maxspeedPanel.add(maxspeed);
+    this.add(maxspeedPanel);
 
-        // Stop sign
-        JPanel stopPanel = new JPanel();
-        JLabel stopLabel = new JLabel(tr("Stop"));
-        stopLabel.setIcon(new ImageProvider("signs/stop.png").get());
-        stopPanel.add(stopLabel);
-        stopPanel.add(stop);
-        this.add(stopPanel);
+    // Stop sign
+    JPanel stopPanel = new JPanel();
+    JLabel stopLabel = new JLabel(tr("Stop"));
+    stopLabel.setIcon(new ImageProvider("signs/stop.png").get());
+    stopPanel.add(stopLabel);
+    stopPanel.add(stop);
+    this.add(stopPanel);
 
-        // Give way sign
-        JPanel giveWayPanel = new JPanel();
-        JLabel giveWayLabel = new JLabel(tr("Give way"));
-        giveWayLabel.setIcon(new ImageProvider("signs/right_of_way.png").get());
-        giveWayPanel.add(giveWayLabel);
-        giveWayPanel.add(giveWay);
-        this.add(giveWayPanel);
+    // Give way sign
+    JPanel giveWayPanel = new JPanel();
+    JLabel giveWayLabel = new JLabel(tr("Give way"));
+    giveWayLabel.setIcon(new ImageProvider("signs/right_of_way.png").get());
+    giveWayPanel.add(giveWayLabel);
+    giveWayPanel.add(giveWay);
+    this.add(giveWayPanel);
 
-        // Roundabout sign
-        JPanel roundaboutPanel = new JPanel();
-        JLabel roundaboutLabel = new JLabel(tr("Give way"));
-        roundaboutLabel.setIcon(new ImageProvider("signs/roundabout_right.png")
-                .get());
-        roundaboutPanel.add(roundaboutLabel);
-        roundaboutPanel.add(roundabout);
-        this.add(roundaboutPanel);
+    // Roundabout sign
+    JPanel roundaboutPanel = new JPanel();
+    JLabel roundaboutLabel = new JLabel(tr("Give way"));
+    roundaboutLabel.setIcon(new ImageProvider("signs/roundabout_right.png")
+        .get());
+    roundaboutPanel.add(roundaboutLabel);
+    roundaboutPanel.add(roundabout);
+    this.add(roundaboutPanel);
 
-        // No entry sign
-        JPanel noEntryPanel = new JPanel();
-        JLabel noEntryLabel = new JLabel(tr("No entry"));
-        noEntryLabel.setIcon(new ImageProvider("signs/no_entry.png").get());
-        noEntryPanel.add(noEntryLabel);
-        noEntryPanel.add(access);
-        this.add(noEntryPanel);
+    // No entry sign
+    JPanel noEntryPanel = new JPanel();
+    JLabel noEntryLabel = new JLabel(tr("No entry"));
+    noEntryLabel.setIcon(new ImageProvider("signs/no_entry.png").get());
+    noEntryPanel.add(noEntryLabel);
+    noEntryPanel.add(access);
+    this.add(noEntryPanel);
 
-        // Danger intersection
-        JPanel intersectionPanel = new JPanel();
-        JLabel intersectionLabel = new JLabel(tr("Intersection danger"));
-        intersectionLabel.setIcon(new ImageProvider(
-                "signs/intersection_danger.png").get());
-        intersectionPanel.add(intersectionLabel);
-        intersectionPanel.add(intersection);
-        this.add(intersectionPanel);
+    // Danger intersection
+    JPanel intersectionPanel = new JPanel();
+    JLabel intersectionLabel = new JLabel(tr("Intersection danger"));
+    intersectionLabel
+        .setIcon(new ImageProvider("signs/intersection_danger.png").get());
+    intersectionPanel.add(intersectionLabel);
+    intersectionPanel.add(intersection);
+    this.add(intersectionPanel);
 
-        // Mandatory direction
-        JPanel directionPanel = new JPanel();
-        JLabel directionLabel = new JLabel(tr("Mandatory direction (any)"));
-        directionLabel.setIcon(new ImageProvider("signs/only_straight_on.png")
-                .get());
-        directionPanel.add(directionLabel);
-        directionPanel.add(direction);
-        this.add(directionPanel);
+    // Mandatory direction
+    JPanel directionPanel = new JPanel();
+    JLabel directionLabel = new JLabel(tr("Mandatory direction (any)"));
+    directionLabel.setIcon(new ImageProvider("signs/only_straight_on.png")
+        .get());
+    directionPanel.add(directionLabel);
+    directionPanel.add(direction);
+    this.add(directionPanel);
 
-        // No turn
-        JPanel noTurnPanel = new JPanel();
-        JLabel noTurnLabel = new JLabel(tr("No turn"));
-        noTurnLabel.setIcon(new ImageProvider("signs/no_turn.png").get());
-        noTurnPanel.add(noTurnLabel);
-        noTurnPanel.add(noTurn);
-        this.add(noTurnPanel);
+    // No turn
+    JPanel noTurnPanel = new JPanel();
+    JLabel noTurnLabel = new JLabel(tr("No turn"));
+    noTurnLabel.setIcon(new ImageProvider("signs/no_turn.png").get());
+    noTurnPanel.add(noTurnLabel);
+    noTurnPanel.add(noTurn);
+    this.add(noTurnPanel);
 
-        // Uneven road
-        JPanel unevenPanel = new JPanel();
-        JLabel unevenLabel = new JLabel(tr("Uneven road"));
-        unevenLabel.setIcon(new ImageProvider("signs/uneaven.png").get());
-        unevenPanel.add(unevenLabel);
-        unevenPanel.add(uneven);
-        this.add(unevenPanel);
+    // Uneven road
+    JPanel unevenPanel = new JPanel();
+    JLabel unevenLabel = new JLabel(tr("Uneven road"));
+    unevenLabel.setIcon(new ImageProvider("signs/uneaven.png").get());
+    unevenPanel.add(unevenLabel);
+    unevenPanel.add(uneven);
+    this.add(unevenPanel);
 
-        // No parking
-        JPanel noParkingPanel = new JPanel();
-        JLabel noParkingLabel = new JLabel(tr("No parking"));
-        noParkingLabel.setIcon(new ImageProvider("signs/no_parking.png").get());
-        noParkingPanel.add(noParkingLabel);
-        noParkingPanel.add(noParking);
-        this.add(noParkingPanel);
+    // No parking
+    JPanel noParkingPanel = new JPanel();
+    JLabel noParkingLabel = new JLabel(tr("No parking"));
+    noParkingLabel.setIcon(new ImageProvider("signs/no_parking.png").get());
+    noParkingPanel.add(noParkingLabel);
+    noParkingPanel.add(noParking);
+    this.add(noParkingPanel);
 
-        // No overtaking
-        JPanel noOvertakingPanel = new JPanel();
-        JLabel noOvertakingLabel = new JLabel(tr("No overtaking"));
-        noOvertakingLabel.setIcon(new ImageProvider("signs/no_overtaking.png")
-                .get());
-        noOvertakingPanel.add(noOvertakingLabel);
-        noOvertakingPanel.add(noOvertaking);
-        this.add(noOvertakingPanel);
+    // No overtaking
+    JPanel noOvertakingPanel = new JPanel();
+    JLabel noOvertakingLabel = new JLabel(tr("No overtaking"));
+    noOvertakingLabel.setIcon(new ImageProvider("signs/no_overtaking.png")
+        .get());
+    noOvertakingPanel.add(noOvertakingLabel);
+    noOvertakingPanel.add(noOvertaking);
+    this.add(noOvertakingPanel);
 
-        // Pedestrian crossing
-        JPanel crossingPanel = new JPanel();
-        JLabel crossingLabel = new JLabel(tr("Pedestrian crossing"));
-        crossingLabel.setIcon(new ImageProvider("signs/crossing.png").get());
-        crossingPanel.add(crossingLabel);
-        crossingPanel.add(crossing);
-        this.add(crossingPanel);
+    // Pedestrian crossing
+    JPanel crossingPanel = new JPanel();
+    JLabel crossingLabel = new JLabel(tr("Pedestrian crossing"));
+    crossingLabel.setIcon(new ImageProvider("signs/crossing.png").get());
+    crossingPanel.add(crossingLabel);
+    crossingPanel.add(crossing);
+    this.add(crossingPanel);
 
-        this.setPreferredSize(new Dimension(600, 150));
-    }
+    this.setPreferredSize(new Dimension(600, 150));
+  }
 
-    public static MapillaryFilterChooseSigns getInstance() {
-        if (INSTANCE == null)
-            INSTANCE = new MapillaryFilterChooseSigns();
-        return INSTANCE;
-    }
+  public static MapillaryFilterChooseSigns getInstance() {
+    if (INSTANCE == null)
+      INSTANCE = new MapillaryFilterChooseSigns();
+    return INSTANCE;
+  }
 
-    @Override
-    public void actionPerformed(ActionEvent arg0) {
-        // TODO Auto-generated method stub
+  @Override
+  public void actionPerformed(ActionEvent arg0) {
+    // TODO Auto-generated method stub
 
-    }
+  }
 
 }
Index: applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/gui/MapillaryFilterDialog.java
===================================================================
--- applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/gui/MapillaryFilterDialog.java	(revision 31349)
+++ applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/gui/MapillaryFilterDialog.java	(revision 31350)
@@ -38,282 +38,278 @@
  */
 public class MapillaryFilterDialog extends ToggleDialog implements
-        MapillaryDataListener {
-
-    public static MapillaryFilterDialog INSTANCE;
-
-    private final static String[] TIME_LIST = { tr("All time"),
-            tr("This year"), tr("This month"), tr("This week") };
-
-    private final static int ROWS = 0;
-    private final static int COLUMNS = 3;
-
-    private final JPanel panel = new JPanel(new GridLayout(ROWS, COLUMNS));
-
-    public final JCheckBox imported = new JCheckBox("Imported images");
-    public final JCheckBox downloaded = new JCheckBox(
-            new downloadCheckBoxAction());
-    public final JCheckBox onlySigns = new JCheckBox(new OnlySignsAction());
-    public final JComboBox<String> time;
-    public final JTextField user;
-
-    public final SideButton updateButton = new SideButton(new UpdateAction());
-    public final SideButton resetButton = new SideButton(new ResetAction());
-    public final JButton signChooser = new JButton(new SignChooserAction());
-
-    public final MapillaryFilterChooseSigns signFilter = MapillaryFilterChooseSigns
-            .getInstance();
-
-    /** The list of sign names */
-    private final String[] SIGN_TAGS = { "prohibitory_speed_limit",
-            "priority_stop", "other_give_way", "mandatory_roundabout",
-            "other_no_entry", "prohibitory_no_traffic_both_ways",
-            "danger_intersection", "mandatory_go", "mandatory_keep",
-            "danger_priority_next_intersection", "danger_uneven_road",
-            "prohibitory_no_parking", "prohibitory_on_overtaking",
-            "danger_pedestrian_crossing", "prohibitory_no_u_turn",
-            "prohibitory_noturn" };
-    /** The the {@link JCheckBox} where the respective tag should be searched */
-    private final JCheckBox[] SIGN_CHECKBOXES = { signFilter.maxspeed,
-            signFilter.stop, signFilter.giveWay, signFilter.roundabout,
-            signFilter.access, signFilter.access, signFilter.intersection,
-            signFilter.direction, signFilter.direction,
-            signFilter.intersection, signFilter.uneven, signFilter.noParking,
-            signFilter.noOvertaking, signFilter.crossing, signFilter.noTurn,
-            signFilter.noTurn };
-
-    public MapillaryFilterDialog() {
-        super(tr("Mapillary filter"), "mapillaryfilter.png",
-                tr("Open Mapillary filter dialog"), Shortcut.registerShortcut(
-                        tr("Mapillary filter"),
-                        tr("Open Mapillary filter dialog"), KeyEvent.VK_M,
-                        Shortcut.NONE), 200);
-
-        signChooser.setEnabled(false);
-        JPanel signChooserPanel = new JPanel();
-        signChooserPanel.setLayout(new FlowLayout(FlowLayout.LEFT));
-        signChooserPanel.add(signChooser);
-
-        JPanel fromPanel = new JPanel();
-        fromPanel.setLayout(new FlowLayout(FlowLayout.LEFT));
-        fromPanel.add(new JLabel("From"));
-        time = new JComboBox<>(TIME_LIST);
-        fromPanel.add(time);
-
-        JPanel userSearchPanel = new JPanel();
-        userSearchPanel.setLayout(new FlowLayout(FlowLayout.LEFT));
-        user = new JTextField(10);
-        user.addActionListener(new UpdateAction());
-        userSearchPanel.add(new JLabel("User"));
-        userSearchPanel.add(user);
-
-        imported.setSelected(true);
-        downloaded.setSelected(true);
-
-        panel.add(downloaded);
-        panel.add(imported);
-        panel.add(onlySigns);
-        panel.add(fromPanel);
-        panel.add(userSearchPanel);
-        panel.add(signChooserPanel);
-
-        createLayout(panel, true,
-                Arrays.asList(new SideButton[] { updateButton, resetButton }));
-    }
-
-    public static MapillaryFilterDialog getInstance() {
-        if (INSTANCE == null)
-            INSTANCE = new MapillaryFilterDialog();
-        return INSTANCE;
-    }
-
-    @Override
-    public void imagesAdded() {
-        refresh();
-    }
-
-    @Override
-    public void selectedImageChanged(MapillaryAbstractImage oldImage,
-            MapillaryAbstractImage newImage) {
-    }
-
-    /**
-     * Resets the dialog to its default state.
-     */
-    public void reset() {
-        imported.setSelected(true);
-        downloaded.setSelected(true);
-        onlySigns.setEnabled(true);
-        onlySigns.setSelected(false);
-        user.setText("");
-        time.setSelectedItem(TIME_LIST[0]);
-        refresh();
-    }
-
-    /**
-     * Applies the selected filter.
-     */
-    public synchronized void refresh() {
-        boolean imported = this.imported.isSelected();
-        boolean downloaded = this.downloaded.isSelected();
-        boolean onlySigns = this.onlySigns.isSelected();
-
-        for (MapillaryAbstractImage img : MapillaryData.getInstance()
-                .getImages()) {
-            img.setVisible(true);
-            if (img instanceof MapillaryImportedImage) {
-                if (!imported)
-                    img.setVisible(false);
-                continue;
-            } else if (img instanceof MapillaryImage) {
-                if (!downloaded) {
-                    img.setVisible(false);
-                    continue;
-                }
-                if (onlySigns) {
-                    if (((MapillaryImage) img).getSigns().isEmpty()) {
-                        img.setVisible(false);
-                        continue;
-                    }
-                    if (!checkSigns((MapillaryImage) img)) {
-                        img.setVisible(false);
-                        continue;
-                    }
-                }
-                if (!user.getText().equals("")
-                        && !user.getText().equals(
-                                ((MapillaryImage) img).getUser())) {
-                    img.setVisible(false);
-                    continue;
-                }
-            }
-            // Calculates the amount of days since the image was taken
-            Long currentTime = currentTime();
-            if (time.getSelectedItem() == TIME_LIST[1]) {
-                if ((currentTime - img.getCapturedAt()) / (24 * 60 * 60 * 1000) > 365) {
-                    img.setVisible(false);
-                    continue;
-                }
-            }
-            if (time.getSelectedItem() == TIME_LIST[2]) {
-                if ((currentTime - img.getCapturedAt()) / (24 * 60 * 60 * 1000) > 30) {
-                    img.setVisible(false);
-                    continue;
-                }
-            }
-            if (time.getSelectedItem() == TIME_LIST[3]) {
-                if ((currentTime - img.getCapturedAt()) / (24 * 60 * 60 * 1000) > 7) {
-                    img.setVisible(false);
-                    continue;
-                }
-            }
-        }
-        Main.map.repaint();
-    }
-
-    /**
-     * Checks if the image fulfills the sign conditions.
-     * 
-     * @param img
-     *            The {@link MapillaryAbstractImage} object that is going to be
-     *            checked.
-     * @return {@code true} if it fulfills the conditions; {@code false}
-     *         otherwise.
-     */
-    private boolean checkSigns(MapillaryImage img) {
-        for (int i = 0; i < SIGN_TAGS.length; i++) {
-            if (checkSign(img, SIGN_CHECKBOXES[i], SIGN_TAGS[i]))
-                return true;
-        }
-        return false;
-    }
-
-    private boolean checkSign(MapillaryImage img, JCheckBox signCheckBox,
-            String singString) {
-        boolean contains = false;
-        for (String sign : img.getSigns()) {
-            if (sign.contains(singString))
-                contains = true;
-        }
-        if (contains == signCheckBox.isSelected() && contains)
-            return true;
-        return false;
-    }
-
-    private long currentTime() {
-        Calendar cal = Calendar.getInstance();
-        return cal.getTimeInMillis();
-    }
-
-    private class downloadCheckBoxAction extends AbstractAction {
-
-        public downloadCheckBoxAction() {
-            putValue(NAME, tr("Downloaded images"));
-        }
-
-        @Override
-        public void actionPerformed(ActionEvent arg0) {
-            onlySigns.setEnabled(downloaded.isSelected());
-        }
-    }
-
-    private class UpdateAction extends AbstractAction {
-        public UpdateAction() {
-            putValue(NAME, tr("Update"));
-        }
-
-        @Override
-        public void actionPerformed(ActionEvent arg0) {
-            MapillaryFilterDialog.getInstance().refresh();
-        }
-    }
-
-    private class ResetAction extends AbstractAction {
-        public ResetAction() {
-            putValue(NAME, tr("Reset"));
-        }
-
-        @Override
-        public void actionPerformed(ActionEvent arg0) {
-            MapillaryFilterDialog.getInstance().reset();
-        }
-    }
-
-    private class OnlySignsAction extends AbstractAction {
-        public OnlySignsAction() {
-            putValue(NAME, tr("Only images with signs"));
-        }
-
-        @Override
-        public void actionPerformed(ActionEvent arg0) {
-            signChooser.setEnabled(onlySigns.isSelected());
-        }
-    }
-
-    /**
-     * Opens a new window where you can specifically filter signs.
-     * 
-     * @author nokutu
-     *
-     */
-    private class SignChooserAction extends AbstractAction {
-        public SignChooserAction() {
-            putValue(NAME, tr("Choose signs"));
-        }
-
-        @Override
-        public void actionPerformed(ActionEvent arg0) {
-            JPanel dialog = MapillaryFilterChooseSigns.getInstance();
-            JOptionPane pane = new JOptionPane(dialog,
-                    JOptionPane.PLAIN_MESSAGE, JOptionPane.OK_CANCEL_OPTION);
-            JDialog dlg = pane.createDialog(Main.parent, tr("Choose signs"));
-            dlg.setVisible(true);
-            if ((int) pane.getValue() == JOptionPane.OK_OPTION)
-                MapillaryFilterDialog.getInstance().refresh();
-            dlg.dispose();
-        }
-    }
-
-    public static void destroyInstance() {
-        MapillaryFilterDialog.INSTANCE = null;
-    }
+    MapillaryDataListener {
+
+  public static MapillaryFilterDialog INSTANCE;
+
+  private final static String[] TIME_LIST = { tr("All time"), tr("This year"),
+      tr("This month"), tr("This week") };
+
+  private final static int ROWS = 0;
+  private final static int COLUMNS = 3;
+
+  private final JPanel panel = new JPanel(new GridLayout(ROWS, COLUMNS));
+
+  public final JCheckBox imported = new JCheckBox("Imported images");
+  public final JCheckBox downloaded = new JCheckBox(
+      new downloadCheckBoxAction());
+  public final JCheckBox onlySigns = new JCheckBox(new OnlySignsAction());
+  public final JComboBox<String> time;
+  public final JTextField user;
+
+  public final SideButton updateButton = new SideButton(new UpdateAction());
+  public final SideButton resetButton = new SideButton(new ResetAction());
+  public final JButton signChooser = new JButton(new SignChooserAction());
+
+  public final MapillaryFilterChooseSigns signFilter = MapillaryFilterChooseSigns
+      .getInstance();
+
+  /** The list of sign names */
+  private final String[] SIGN_TAGS = { "prohibitory_speed_limit",
+      "priority_stop", "other_give_way", "mandatory_roundabout",
+      "other_no_entry", "prohibitory_no_traffic_both_ways",
+      "danger_intersection", "mandatory_go", "mandatory_keep",
+      "danger_priority_next_intersection", "danger_uneven_road",
+      "prohibitory_no_parking", "prohibitory_on_overtaking",
+      "danger_pedestrian_crossing", "prohibitory_no_u_turn",
+      "prohibitory_noturn" };
+  /** The the {@link JCheckBox} where the respective tag should be searched */
+  private final JCheckBox[] SIGN_CHECKBOXES = { signFilter.maxspeed,
+      signFilter.stop, signFilter.giveWay, signFilter.roundabout,
+      signFilter.access, signFilter.access, signFilter.intersection,
+      signFilter.direction, signFilter.direction, signFilter.intersection,
+      signFilter.uneven, signFilter.noParking, signFilter.noOvertaking,
+      signFilter.crossing, signFilter.noTurn, signFilter.noTurn };
+
+  public MapillaryFilterDialog() {
+    super(tr("Mapillary filter"), "mapillaryfilter.png",
+        tr("Open Mapillary filter dialog"), Shortcut.registerShortcut(
+            tr("Mapillary filter"), tr("Open Mapillary filter dialog"),
+            KeyEvent.VK_M, Shortcut.NONE), 200);
+
+    signChooser.setEnabled(false);
+    JPanel signChooserPanel = new JPanel();
+    signChooserPanel.setLayout(new FlowLayout(FlowLayout.LEFT));
+    signChooserPanel.add(signChooser);
+
+    JPanel fromPanel = new JPanel();
+    fromPanel.setLayout(new FlowLayout(FlowLayout.LEFT));
+    fromPanel.add(new JLabel("From"));
+    time = new JComboBox<>(TIME_LIST);
+    fromPanel.add(time);
+
+    JPanel userSearchPanel = new JPanel();
+    userSearchPanel.setLayout(new FlowLayout(FlowLayout.LEFT));
+    user = new JTextField(10);
+    user.addActionListener(new UpdateAction());
+    userSearchPanel.add(new JLabel("User"));
+    userSearchPanel.add(user);
+
+    imported.setSelected(true);
+    downloaded.setSelected(true);
+
+    panel.add(downloaded);
+    panel.add(imported);
+    panel.add(onlySigns);
+    panel.add(fromPanel);
+    panel.add(userSearchPanel);
+    panel.add(signChooserPanel);
+
+    createLayout(panel, true,
+        Arrays.asList(new SideButton[] { updateButton, resetButton }));
+  }
+
+  public static MapillaryFilterDialog getInstance() {
+    if (INSTANCE == null)
+      INSTANCE = new MapillaryFilterDialog();
+    return INSTANCE;
+  }
+
+  @Override
+  public void imagesAdded() {
+    refresh();
+  }
+
+  @Override
+  public void selectedImageChanged(MapillaryAbstractImage oldImage,
+      MapillaryAbstractImage newImage) {
+  }
+
+  /**
+   * Resets the dialog to its default state.
+   */
+  public void reset() {
+    imported.setSelected(true);
+    downloaded.setSelected(true);
+    onlySigns.setEnabled(true);
+    onlySigns.setSelected(false);
+    user.setText("");
+    time.setSelectedItem(TIME_LIST[0]);
+    refresh();
+  }
+
+  /**
+   * Applies the selected filter.
+   */
+  public synchronized void refresh() {
+    boolean imported = this.imported.isSelected();
+    boolean downloaded = this.downloaded.isSelected();
+    boolean onlySigns = this.onlySigns.isSelected();
+
+    for (MapillaryAbstractImage img : MapillaryData.getInstance().getImages()) {
+      img.setVisible(true);
+      if (img instanceof MapillaryImportedImage) {
+        if (!imported)
+          img.setVisible(false);
+        continue;
+      } else if (img instanceof MapillaryImage) {
+        if (!downloaded) {
+          img.setVisible(false);
+          continue;
+        }
+        if (onlySigns) {
+          if (((MapillaryImage) img).getSigns().isEmpty()) {
+            img.setVisible(false);
+            continue;
+          }
+          if (!checkSigns((MapillaryImage) img)) {
+            img.setVisible(false);
+            continue;
+          }
+        }
+        if (!user.getText().equals("")
+            && !user.getText().equals(((MapillaryImage) img).getUser())) {
+          img.setVisible(false);
+          continue;
+        }
+      }
+      // Calculates the amount of days since the image was taken
+      Long currentTime = currentTime();
+      if (time.getSelectedItem() == TIME_LIST[1]) {
+        if ((currentTime - img.getCapturedAt()) / (24 * 60 * 60 * 1000) > 365) {
+          img.setVisible(false);
+          continue;
+        }
+      }
+      if (time.getSelectedItem() == TIME_LIST[2]) {
+        if ((currentTime - img.getCapturedAt()) / (24 * 60 * 60 * 1000) > 30) {
+          img.setVisible(false);
+          continue;
+        }
+      }
+      if (time.getSelectedItem() == TIME_LIST[3]) {
+        if ((currentTime - img.getCapturedAt()) / (24 * 60 * 60 * 1000) > 7) {
+          img.setVisible(false);
+          continue;
+        }
+      }
+    }
+    Main.map.repaint();
+  }
+
+  /**
+   * Checks if the image fulfills the sign conditions.
+   * 
+   * @param img
+   *          The {@link MapillaryAbstractImage} object that is going to be
+   *          checked.
+   * @return {@code true} if it fulfills the conditions; {@code false}
+   *         otherwise.
+   */
+  private boolean checkSigns(MapillaryImage img) {
+    for (int i = 0; i < SIGN_TAGS.length; i++) {
+      if (checkSign(img, SIGN_CHECKBOXES[i], SIGN_TAGS[i]))
+        return true;
+    }
+    return false;
+  }
+
+  private boolean checkSign(MapillaryImage img, JCheckBox signCheckBox,
+      String singString) {
+    boolean contains = false;
+    for (String sign : img.getSigns()) {
+      if (sign.contains(singString))
+        contains = true;
+    }
+    if (contains == signCheckBox.isSelected() && contains)
+      return true;
+    return false;
+  }
+
+  private long currentTime() {
+    Calendar cal = Calendar.getInstance();
+    return cal.getTimeInMillis();
+  }
+
+  private class downloadCheckBoxAction extends AbstractAction {
+
+    public downloadCheckBoxAction() {
+      putValue(NAME, tr("Downloaded images"));
+    }
+
+    @Override
+    public void actionPerformed(ActionEvent arg0) {
+      onlySigns.setEnabled(downloaded.isSelected());
+    }
+  }
+
+  private class UpdateAction extends AbstractAction {
+    public UpdateAction() {
+      putValue(NAME, tr("Update"));
+    }
+
+    @Override
+    public void actionPerformed(ActionEvent arg0) {
+      MapillaryFilterDialog.getInstance().refresh();
+    }
+  }
+
+  private class ResetAction extends AbstractAction {
+    public ResetAction() {
+      putValue(NAME, tr("Reset"));
+    }
+
+    @Override
+    public void actionPerformed(ActionEvent arg0) {
+      MapillaryFilterDialog.getInstance().reset();
+    }
+  }
+
+  private class OnlySignsAction extends AbstractAction {
+    public OnlySignsAction() {
+      putValue(NAME, tr("Only images with signs"));
+    }
+
+    @Override
+    public void actionPerformed(ActionEvent arg0) {
+      signChooser.setEnabled(onlySigns.isSelected());
+    }
+  }
+
+  /**
+   * Opens a new window where you can specifically filter signs.
+   * 
+   * @author nokutu
+   *
+   */
+  private class SignChooserAction extends AbstractAction {
+    public SignChooserAction() {
+      putValue(NAME, tr("Choose signs"));
+    }
+
+    @Override
+    public void actionPerformed(ActionEvent arg0) {
+      JPanel dialog = MapillaryFilterChooseSigns.getInstance();
+      JOptionPane pane = new JOptionPane(dialog, JOptionPane.PLAIN_MESSAGE,
+          JOptionPane.OK_CANCEL_OPTION);
+      JDialog dlg = pane.createDialog(Main.parent, tr("Choose signs"));
+      dlg.setVisible(true);
+      if ((int) pane.getValue() == JOptionPane.OK_OPTION)
+        MapillaryFilterDialog.getInstance().refresh();
+      dlg.dispose();
+    }
+  }
+
+  public static void destroyInstance() {
+    MapillaryFilterDialog.INSTANCE = null;
+  }
 }
Index: applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/gui/MapillaryHistoryDialog.java
===================================================================
--- applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/gui/MapillaryHistoryDialog.java	(revision 31349)
+++ applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/gui/MapillaryHistoryDialog.java	(revision 31350)
@@ -31,6 +31,6 @@
 
 /**
- * Toggle dialog that shows you the latest {@link MapillaryCommand} done and allows the user to
- * revert them.
+ * Toggle dialog that shows you the latest {@link MapillaryCommand} done and
+ * allows the user to revert them.
  * 
  * @see MapillaryRecord
@@ -40,146 +40,143 @@
  */
 public class MapillaryHistoryDialog extends ToggleDialog implements
-        MapillaryRecordListener {
+    MapillaryRecordListener {
 
-    public static MapillaryHistoryDialog INSTANCE;
+  public static MapillaryHistoryDialog INSTANCE;
 
-    private final DefaultTreeModel undoTreeModel = new DefaultTreeModel(
-            new DefaultMutableTreeNode());
-    private final DefaultTreeModel redoTreeModel = new DefaultTreeModel(
-            new DefaultMutableTreeNode());
-    private final JTree undoTree = new JTree(undoTreeModel);
-    private final JTree redoTree = new JTree(redoTreeModel);
+  private final DefaultTreeModel undoTreeModel = new DefaultTreeModel(
+      new DefaultMutableTreeNode());
+  private final DefaultTreeModel redoTreeModel = new DefaultTreeModel(
+      new DefaultMutableTreeNode());
+  private final JTree undoTree = new JTree(undoTreeModel);
+  private final JTree redoTree = new JTree(redoTreeModel);
 
-    private JSeparator separator = new JSeparator();
-    private Component spacer = Box.createRigidArea(new Dimension(0, 3));
+  private JSeparator separator = new JSeparator();
+  private Component spacer = Box.createRigidArea(new Dimension(0, 3));
 
-    private SideButton undoButton;
-    private SideButton redoButton;
+  private SideButton undoButton;
+  private SideButton redoButton;
 
-    public MapillaryHistoryDialog() {
-        super(tr("Mapillary history"), "mapillaryhistory.png",
-                tr("Open Mapillary history dialog"), Shortcut.registerShortcut(
-                        tr("Mapillary history"),
-                        tr("Open Mapillary history dialog"), KeyEvent.VK_M,
-                        Shortcut.NONE), 200);
+  public MapillaryHistoryDialog() {
+    super(tr("Mapillary history"), "mapillaryhistory.png",
+        tr("Open Mapillary history dialog"), Shortcut.registerShortcut(
+            tr("Mapillary history"), tr("Open Mapillary history dialog"),
+            KeyEvent.VK_M, Shortcut.NONE), 200);
 
-        MapillaryRecord.getInstance().addListener(this);
+    MapillaryRecord.getInstance().addListener(this);
 
-        undoTree.expandRow(0);
-        undoTree.setShowsRootHandles(true);
-        undoTree.setRootVisible(false);
-        undoTree.setCellRenderer(new MapillaryCellRenderer());
-        redoTree.expandRow(0);
-        redoTree.setCellRenderer(new MapillaryCellRenderer());
-        redoTree.setShowsRootHandles(true);
-        redoTree.setRootVisible(false);
+    undoTree.expandRow(0);
+    undoTree.setShowsRootHandles(true);
+    undoTree.setRootVisible(false);
+    undoTree.setCellRenderer(new MapillaryCellRenderer());
+    redoTree.expandRow(0);
+    redoTree.setCellRenderer(new MapillaryCellRenderer());
+    redoTree.setShowsRootHandles(true);
+    redoTree.setRootVisible(false);
 
-        JPanel treesPanel = new JPanel(new GridBagLayout());
-        treesPanel.add(spacer, GBC.eol());
-        spacer.setVisible(false);
-        treesPanel.add(undoTree, GBC.eol().fill(GBC.HORIZONTAL));
-        separator.setVisible(false);
-        treesPanel.add(separator, GBC.eol().fill(GBC.HORIZONTAL));
-        treesPanel.add(redoTree, GBC.eol().fill(GBC.HORIZONTAL));
-        treesPanel.add(Box.createRigidArea(new Dimension(0, 0)), GBC.std()
-                .weight(0, 1));
-        treesPanel.setBackground(redoTree.getBackground());
+    JPanel treesPanel = new JPanel(new GridBagLayout());
+    treesPanel.add(spacer, GBC.eol());
+    spacer.setVisible(false);
+    treesPanel.add(undoTree, GBC.eol().fill(GBC.HORIZONTAL));
+    separator.setVisible(false);
+    treesPanel.add(separator, GBC.eol().fill(GBC.HORIZONTAL));
+    treesPanel.add(redoTree, GBC.eol().fill(GBC.HORIZONTAL));
+    treesPanel.add(Box.createRigidArea(new Dimension(0, 0)),
+        GBC.std().weight(0, 1));
+    treesPanel.setBackground(redoTree.getBackground());
 
-        undoButton = new SideButton(new UndoAction());
-        redoButton = new SideButton(new RedoAction());
+    undoButton = new SideButton(new UndoAction());
+    redoButton = new SideButton(new RedoAction());
 
-        createLayout(treesPanel, true,
-                Arrays.asList(new SideButton[] { undoButton, redoButton }));
+    createLayout(treesPanel, true,
+        Arrays.asList(new SideButton[] { undoButton, redoButton }));
+  }
+
+  public static MapillaryHistoryDialog getInstance() {
+    if (INSTANCE == null)
+      INSTANCE = new MapillaryHistoryDialog();
+    return INSTANCE;
+  }
+
+  private void buildTree() {
+    redoButton.setEnabled(true);
+    undoButton.setEnabled(true);
+    ArrayList<MapillaryCommand> commands = MapillaryRecord.getInstance().commandList;
+    int position = MapillaryRecord.getInstance().position;
+    ArrayList<MapillaryCommand> undoCommands = new ArrayList<>();
+    if (position >= 0)
+      undoCommands = new ArrayList<>(commands.subList(0, position + 1));
+    else
+      undoButton.setEnabled(false);
+    ArrayList<MapillaryCommand> redoCommands = new ArrayList<>();
+    if (commands.size() > 0 && position + 1 < commands.size())
+      redoCommands = new ArrayList<>(commands.subList(position + 1,
+          commands.size()));
+    else
+      redoButton.setEnabled(false);
+
+    DefaultMutableTreeNode redoRoot = new DefaultMutableTreeNode();
+    DefaultMutableTreeNode undoRoot = new DefaultMutableTreeNode();
+
+    for (MapillaryCommand command : undoCommands) {
+      if (command != null)
+        undoRoot.add(new DefaultMutableTreeNode(command.toString()));
+    }
+    for (MapillaryCommand command : redoCommands) {
+      if (command != null)
+        redoRoot.add(new DefaultMutableTreeNode(command.toString()));
     }
 
-    public static MapillaryHistoryDialog getInstance() {
-        if (INSTANCE == null)
-            INSTANCE = new MapillaryHistoryDialog();
-        return INSTANCE;
-    }
+    separator.setVisible(!undoCommands.isEmpty() || !redoCommands.isEmpty());
+    spacer.setVisible(undoCommands.isEmpty() && !redoCommands.isEmpty());
 
-    private void buildTree() {
-        redoButton.setEnabled(true);
-        undoButton.setEnabled(true);
-        ArrayList<MapillaryCommand> commands = MapillaryRecord.getInstance().commandList;
-        int position = MapillaryRecord.getInstance().position;
-        ArrayList<MapillaryCommand> undoCommands = new ArrayList<>();
-        if (position >= 0)
-            undoCommands = new ArrayList<>(commands.subList(0, position + 1));
-        else
-            undoButton.setEnabled(false);
-        ArrayList<MapillaryCommand> redoCommands = new ArrayList<>();
-        if (commands.size() > 0 && position + 1 < commands.size())
-            redoCommands = new ArrayList<>(commands.subList(position + 1,
-                    commands.size()));
-        else
-            redoButton.setEnabled(false);
+    undoTreeModel.setRoot(undoRoot);
+    redoTreeModel.setRoot(redoRoot);
+  }
 
-        DefaultMutableTreeNode redoRoot = new DefaultMutableTreeNode();
-        DefaultMutableTreeNode undoRoot = new DefaultMutableTreeNode();
+  @Override
+  public void recordChanged() {
+    buildTree();
+  }
 
-        for (MapillaryCommand command : undoCommands) {
-            if (command != null)
-                undoRoot.add(new DefaultMutableTreeNode(command.toString()));
-        }
-        for (MapillaryCommand command : redoCommands) {
-            if (command != null)
-                redoRoot.add(new DefaultMutableTreeNode(command.toString()));
-        }
+  private class UndoAction extends AbstractAction {
 
-        separator
-                .setVisible(!undoCommands.isEmpty() || !redoCommands.isEmpty());
-        spacer.setVisible(undoCommands.isEmpty() && !redoCommands.isEmpty());
-
-        undoTreeModel.setRoot(undoRoot);
-        redoTreeModel.setRoot(redoRoot);
+    public UndoAction() {
+      putValue(NAME, tr("Undo"));
+      putValue(SMALL_ICON, ImageProvider.get("undo"));
     }
 
     @Override
-    public void recordChanged() {
-        buildTree();
+    public void actionPerformed(ActionEvent arg0) {
+      MapillaryRecord.getInstance().undo();
     }
 
-    private class UndoAction extends AbstractAction {
+  }
 
-        public UndoAction() {
-            putValue(NAME, tr("Undo"));
-            putValue(SMALL_ICON, ImageProvider.get("undo"));
-        }
-
-        @Override
-        public void actionPerformed(ActionEvent arg0) {
-            MapillaryRecord.getInstance().undo();
-        }
-
+  private class RedoAction extends AbstractAction {
+    public RedoAction() {
+      putValue(NAME, tr("Redo"));
+      putValue(SMALL_ICON, ImageProvider.get("redo"));
     }
 
-    private class RedoAction extends AbstractAction {
-        public RedoAction() {
-            putValue(NAME, tr("Redo"));
-            putValue(SMALL_ICON, ImageProvider.get("redo"));
-        }
-
-        @Override
-        public void actionPerformed(ActionEvent arg0) {
-            MapillaryRecord.getInstance().redo();
-        }
-
+    @Override
+    public void actionPerformed(ActionEvent arg0) {
+      MapillaryRecord.getInstance().redo();
     }
 
-    private static class MapillaryCellRenderer extends DefaultTreeCellRenderer {
-        @Override
-        public Component getTreeCellRendererComponent(JTree tree, Object value,
-                boolean sel, boolean expanded, boolean leaf, int row,
-                boolean hasFocus) {
-            super.getTreeCellRendererComponent(tree, value, sel, expanded,
-                    leaf, row, hasFocus);
-            setIcon(ImageProvider.get("data/node.png"));
-            return this;
-        }
+  }
+
+  private static class MapillaryCellRenderer extends DefaultTreeCellRenderer {
+    @Override
+    public Component getTreeCellRendererComponent(JTree tree, Object value,
+        boolean sel, boolean expanded, boolean leaf, int row, boolean hasFocus) {
+      super.getTreeCellRendererComponent(tree, value, sel, expanded, leaf, row,
+          hasFocus);
+      setIcon(ImageProvider.get("data/node.png"));
+      return this;
     }
+  }
 
-    public static void destroyInstance() {
-        MapillaryHistoryDialog.INSTANCE = null;
-    }
+  public static void destroyInstance() {
+    MapillaryHistoryDialog.INSTANCE = null;
+  }
 }
Index: applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/gui/MapillaryImageDisplay.java
===================================================================
--- applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/gui/MapillaryImageDisplay.java	(revision 31349)
+++ applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/gui/MapillaryImageDisplay.java	(revision 31350)
@@ -33,501 +33,485 @@
 public class MapillaryImageDisplay extends JComponent {
 
-    private static final int DRAG_BUTTON = Main.pref.getInteger(
-            "mapillary.picture-drag-button", 3);
-    private static final int OPTION_BUTTON = Main.pref.getInteger(
-            "mapillary.picture-option-button", 2);
-    private static final int ZOOM_BUTTON = Main.pref.getInteger(
-            "mapillary.picture-zoom-button", 1);
-
-    /** The image currently displayed */
-    private transient BufferedImage image = null;
+  private static final int DRAG_BUTTON = Main.pref.getInteger(
+      "mapillary.picture-drag-button", 3);
+  private static final int OPTION_BUTTON = Main.pref.getInteger(
+      "mapillary.picture-option-button", 2);
+  private static final int ZOOM_BUTTON = Main.pref.getInteger(
+      "mapillary.picture-zoom-button", 1);
+
+  /** The image currently displayed */
+  private transient BufferedImage image = null;
+
+  /**
+   * The rectangle (in image coordinates) of the image that is visible. This
+   * rectangle is calculated each time the zoom is modified
+   */
+  private Rectangle visibleRect = null;
+
+  /**
+   * When a selection is done, the rectangle of the selection (in image
+   * coordinates)
+   */
+  private Rectangle selectedRect = null;
+
+  public HyperlinkLabel hyperlink;
+
+  private class ImgDisplayMouseListener implements MouseListener,
+      MouseWheelListener, MouseMotionListener {
+    private boolean mouseIsDragging = false;
+    private long lastTimeForMousePoint = 0L;
+    private Point mousePointInImg = null;
 
     /**
-     * The rectangle (in image coordinates) of the image that is visible. This
-     * rectangle is calculated each time the zoom is modified
+     * Zoom in and out, trying to preserve the point of the image that was under
+     * the mouse cursor at the same place
      */
-    private Rectangle visibleRect = null;
+    @Override
+    public void mouseWheelMoved(MouseWheelEvent e) {
+      Image image;
+      Rectangle visibleRect;
+      synchronized (MapillaryImageDisplay.this) {
+        image = MapillaryImageDisplay.this.image;
+        visibleRect = MapillaryImageDisplay.this.visibleRect;
+      }
+      mouseIsDragging = false;
+      selectedRect = null;
+      if (image == null)
+        return;
+      // Calculate the mouse cursor position in image coordinates, so that
+      // we can center the zoom
+      // on that mouse position.
+      // To avoid issues when the user tries to zoom in on the image
+      // borders, this point is not calculated
+      // again if there was less than 1.5seconds since the last event.
+      if (e.getWhen() - lastTimeForMousePoint > 1500 || mousePointInImg == null) {
+        lastTimeForMousePoint = e.getWhen();
+        mousePointInImg = comp2imgCoord(visibleRect, e.getX(), e.getY());
+      }
+      // Applicate the zoom to the visible rectangle in image coordinates
+      if (e.getWheelRotation() > 0) {
+        visibleRect.width = visibleRect.width * 3 / 2;
+        visibleRect.height = visibleRect.height * 3 / 2;
+      } else {
+        visibleRect.width = visibleRect.width * 2 / 3;
+        visibleRect.height = visibleRect.height * 2 / 3;
+      }
+      // Check that the zoom doesn't exceed 2:1
+      if (visibleRect.width < getSize().width / 2) {
+        visibleRect.width = getSize().width / 2;
+      }
+      if (visibleRect.height < getSize().height / 2) {
+        visibleRect.height = getSize().height / 2;
+      }
+      // Set the same ratio for the visible rectangle and the display area
+      int hFact = visibleRect.height * getSize().width;
+      int wFact = visibleRect.width * getSize().height;
+      if (hFact > wFact) {
+        visibleRect.width = hFact / getSize().height;
+      } else {
+        visibleRect.height = wFact / getSize().width;
+      }
+      // The size of the visible rectangle is limited by the image size.
+      checkVisibleRectSize(image, visibleRect);
+      // Set the position of the visible rectangle, so that the mouse
+      // cursor doesn't move on the image.
+      Rectangle drawRect = calculateDrawImageRectangle(visibleRect);
+      visibleRect.x = mousePointInImg.x
+          + ((drawRect.x - e.getX()) * visibleRect.width) / drawRect.width;
+      visibleRect.y = mousePointInImg.y
+          + ((drawRect.y - e.getY()) * visibleRect.height) / drawRect.height;
+      // The position is also limited by the image size
+      checkVisibleRectPos(image, visibleRect);
+      synchronized (MapillaryImageDisplay.this) {
+        MapillaryImageDisplay.this.visibleRect = visibleRect;
+      }
+      MapillaryImageDisplay.this.repaint();
+    }
+
+    /** Center the display on the point that has been clicked */
+    @Override
+    public void mouseClicked(MouseEvent e) {
+      // Move the center to the clicked point.
+      Image image;
+      Rectangle visibleRect;
+      synchronized (MapillaryImageDisplay.this) {
+        image = MapillaryImageDisplay.this.image;
+        visibleRect = MapillaryImageDisplay.this.visibleRect;
+      }
+      if (image == null)
+        return;
+      if (e.getButton() == OPTION_BUTTON) {
+        if (!MapillaryImageDisplay.this.visibleRect.equals(new Rectangle(0, 0,
+            image.getWidth(null), image.getHeight(null))))
+          // Zooms to 1:1
+          MapillaryImageDisplay.this.visibleRect = new Rectangle(0, 0,
+              image.getWidth(null), image.getHeight(null));
+        else
+          // Zooms to best fit.
+          MapillaryImageDisplay.this.visibleRect = new Rectangle(0,
+              (image.getHeight(null) - (image.getWidth(null) * getHeight())
+                  / getWidth()) / 2, image.getWidth(null),
+              (image.getWidth(null) * getHeight()) / getWidth());
+        MapillaryImageDisplay.this.repaint();
+        return;
+      } else if (e.getButton() != DRAG_BUTTON)
+        return;
+      // Calculate the translation to set the clicked point the center of
+      // the view.
+      Point click = comp2imgCoord(visibleRect, e.getX(), e.getY());
+      Point center = getCenterImgCoord(visibleRect);
+      visibleRect.x += click.x - center.x;
+      visibleRect.y += click.y - center.y;
+      checkVisibleRectPos(image, visibleRect);
+      synchronized (MapillaryImageDisplay.this) {
+        MapillaryImageDisplay.this.visibleRect = visibleRect;
+      }
+      MapillaryImageDisplay.this.repaint();
+    }
 
     /**
-     * When a selection is done, the rectangle of the selection (in image
-     * coordinates)
+     * Initialize the dragging, either with button 1 (simple dragging) or button
+     * 3 (selection of a picture part)
      */
-    private Rectangle selectedRect = null;
-
-    public HyperlinkLabel hyperlink;
-
-    private class ImgDisplayMouseListener implements MouseListener,
-            MouseWheelListener, MouseMotionListener {
-        private boolean mouseIsDragging = false;
-        private long lastTimeForMousePoint = 0L;
-        private Point mousePointInImg = null;
-
-        /**
-         * Zoom in and out, trying to preserve the point of the image that was
-         * under the mouse cursor at the same place
-         */
-        @Override
-        public void mouseWheelMoved(MouseWheelEvent e) {
-            Image image;
-            Rectangle visibleRect;
-            synchronized (MapillaryImageDisplay.this) {
-                image = MapillaryImageDisplay.this.image;
-                visibleRect = MapillaryImageDisplay.this.visibleRect;
-            }
-            mouseIsDragging = false;
-            selectedRect = null;
-            if (image == null)
-                return;
-            // Calculate the mouse cursor position in image coordinates, so that
-            // we can center the zoom
-            // on that mouse position.
-            // To avoid issues when the user tries to zoom in on the image
-            // borders, this point is not calculated
-            // again if there was less than 1.5seconds since the last event.
-            if (e.getWhen() - lastTimeForMousePoint > 1500
-                    || mousePointInImg == null) {
-                lastTimeForMousePoint = e.getWhen();
-                mousePointInImg = comp2imgCoord(visibleRect, e.getX(), e.getY());
-            }
-            // Applicate the zoom to the visible rectangle in image coordinates
-            if (e.getWheelRotation() > 0) {
-                visibleRect.width = visibleRect.width * 3 / 2;
-                visibleRect.height = visibleRect.height * 3 / 2;
-            } else {
-                visibleRect.width = visibleRect.width * 2 / 3;
-                visibleRect.height = visibleRect.height * 2 / 3;
-            }
-            // Check that the zoom doesn't exceed 2:1
-            if (visibleRect.width < getSize().width / 2) {
-                visibleRect.width = getSize().width / 2;
-            }
-            if (visibleRect.height < getSize().height / 2) {
-                visibleRect.height = getSize().height / 2;
-            }
-            // Set the same ratio for the visible rectangle and the display area
-            int hFact = visibleRect.height * getSize().width;
-            int wFact = visibleRect.width * getSize().height;
-            if (hFact > wFact) {
-                visibleRect.width = hFact / getSize().height;
-            } else {
-                visibleRect.height = wFact / getSize().width;
-            }
-            // The size of the visible rectangle is limited by the image size.
-            checkVisibleRectSize(image, visibleRect);
-            // Set the position of the visible rectangle, so that the mouse
-            // cursor doesn't move on the image.
-            Rectangle drawRect = calculateDrawImageRectangle(visibleRect);
-            visibleRect.x = mousePointInImg.x
-                    + ((drawRect.x - e.getX()) * visibleRect.width)
-                    / drawRect.width;
-            visibleRect.y = mousePointInImg.y
-                    + ((drawRect.y - e.getY()) * visibleRect.height)
-                    / drawRect.height;
-            // The position is also limited by the image size
-            checkVisibleRectPos(image, visibleRect);
-            synchronized (MapillaryImageDisplay.this) {
-                MapillaryImageDisplay.this.visibleRect = visibleRect;
-            }
-            MapillaryImageDisplay.this.repaint();
-        }
-
-        /** Center the display on the point that has been clicked */
-        @Override
-        public void mouseClicked(MouseEvent e) {
-            // Move the center to the clicked point.
-            Image image;
-            Rectangle visibleRect;
-            synchronized (MapillaryImageDisplay.this) {
-                image = MapillaryImageDisplay.this.image;
-                visibleRect = MapillaryImageDisplay.this.visibleRect;
-            }
-            if (image == null)
-                return;
-            if (e.getButton() == OPTION_BUTTON) {
-                if (!MapillaryImageDisplay.this.visibleRect
-                        .equals(new Rectangle(0, 0, image.getWidth(null), image
-                                .getHeight(null))))
-                    // Zooms to 1:1
-                    MapillaryImageDisplay.this.visibleRect = new Rectangle(0,
-                            0, image.getWidth(null), image.getHeight(null));
-                else
-                    // Zooms to best fit.
-                    MapillaryImageDisplay.this.visibleRect = new Rectangle(
-                            0,
-                            (image.getHeight(null) - (image.getWidth(null) * getHeight())
-                                    / getWidth()) / 2, image.getWidth(null),
-                            (image.getWidth(null) * getHeight()) / getWidth());
-                MapillaryImageDisplay.this.repaint();
-                return;
-            } else if (e.getButton() != DRAG_BUTTON)
-                return;
-            // Calculate the translation to set the clicked point the center of
-            // the view.
-            Point click = comp2imgCoord(visibleRect, e.getX(), e.getY());
-            Point center = getCenterImgCoord(visibleRect);
-            visibleRect.x += click.x - center.x;
-            visibleRect.y += click.y - center.y;
-            checkVisibleRectPos(image, visibleRect);
-            synchronized (MapillaryImageDisplay.this) {
-                MapillaryImageDisplay.this.visibleRect = visibleRect;
-            }
-            MapillaryImageDisplay.this.repaint();
-        }
-
-        /**
-         * Initialize the dragging, either with button 1 (simple dragging) or
-         * button 3 (selection of a picture part)
-         */
-        @Override
-        public void mousePressed(MouseEvent e) {
-            if (image == null) {
-                mouseIsDragging = false;
-                selectedRect = null;
-                return;
-            }
-            Image image;
-            Rectangle visibleRect;
-            synchronized (MapillaryImageDisplay.this) {
-                image = MapillaryImageDisplay.this.image;
-                visibleRect = MapillaryImageDisplay.this.visibleRect;
-            }
-            if (image == null)
-                return;
-            if (e.getButton() == DRAG_BUTTON) {
-                mousePointInImg = comp2imgCoord(visibleRect, e.getX(), e.getY());
-                mouseIsDragging = true;
-                selectedRect = null;
-            } else if (e.getButton() == ZOOM_BUTTON) {
-                mousePointInImg = comp2imgCoord(visibleRect, e.getX(), e.getY());
-                checkPointInVisibleRect(mousePointInImg, visibleRect);
-                mouseIsDragging = false;
-                selectedRect = new Rectangle(mousePointInImg.x,
-                        mousePointInImg.y, 0, 0);
-                MapillaryImageDisplay.this.repaint();
-            } else {
-                mouseIsDragging = false;
-                selectedRect = null;
-            }
-        }
-
-        @Override
-        public void mouseDragged(MouseEvent e) {
-            if (!mouseIsDragging && selectedRect == null)
-                return;
-            Image image;
-            Rectangle visibleRect;
-            synchronized (MapillaryImageDisplay.this) {
-                image = MapillaryImageDisplay.this.image;
-                visibleRect = MapillaryImageDisplay.this.visibleRect;
-            }
-            if (image == null) {
-                mouseIsDragging = false;
-                selectedRect = null;
-                return;
-            }
-            if (mouseIsDragging) {
-                Point p = comp2imgCoord(visibleRect, e.getX(), e.getY());
-                visibleRect.x += mousePointInImg.x - p.x;
-                visibleRect.y += mousePointInImg.y - p.y;
-                checkVisibleRectPos(image, visibleRect);
-                synchronized (MapillaryImageDisplay.this) {
-                    MapillaryImageDisplay.this.visibleRect = visibleRect;
-                }
-                MapillaryImageDisplay.this.repaint();
-            } else if (selectedRect != null) {
-                Point p = comp2imgCoord(visibleRect, e.getX(), e.getY());
-                checkPointInVisibleRect(p, visibleRect);
-                Rectangle rect = new Rectangle(p.x < mousePointInImg.x ? p.x
-                        : mousePointInImg.x, p.y < mousePointInImg.y ? p.y
-                        : mousePointInImg.y,
-                        p.x < mousePointInImg.x ? mousePointInImg.x - p.x : p.x
-                                - mousePointInImg.x,
-                        p.y < mousePointInImg.y ? mousePointInImg.y - p.y : p.y
-                                - mousePointInImg.y);
-                checkVisibleRectSize(image, rect);
-                checkVisibleRectPos(image, rect);
-                MapillaryImageDisplay.this.selectedRect = rect;
-                MapillaryImageDisplay.this.repaint();
-            }
-        }
-
-        @Override
-        public void mouseReleased(MouseEvent e) {
-            if (!mouseIsDragging && selectedRect == null)
-                return;
-            Image image;
-            synchronized (MapillaryImageDisplay.this) {
-                image = MapillaryImageDisplay.this.image;
-            }
-            if (image == null) {
-                mouseIsDragging = false;
-                selectedRect = null;
-                return;
-            }
-            if (mouseIsDragging) {
-                mouseIsDragging = false;
-            } else if (selectedRect != null) {
-                int oldWidth = selectedRect.width;
-                int oldHeight = selectedRect.height;
-                // Check that the zoom doesn't exceed 2:1
-                if (selectedRect.width < getSize().width / 2) {
-                    selectedRect.width = getSize().width / 2;
-                }
-                if (selectedRect.height < getSize().height / 2) {
-                    selectedRect.height = getSize().height / 2;
-                }
-                // Set the same ratio for the visible rectangle and the display
-                // area
-                int hFact = selectedRect.height * getSize().width;
-                int wFact = selectedRect.width * getSize().height;
-                if (hFact > wFact) {
-                    selectedRect.width = hFact / getSize().height;
-                } else {
-                    selectedRect.height = wFact / getSize().width;
-                }
-                // Keep the center of the selection
-                if (selectedRect.width != oldWidth) {
-                    selectedRect.x -= (selectedRect.width - oldWidth) / 2;
-                }
-                if (selectedRect.height != oldHeight) {
-                    selectedRect.y -= (selectedRect.height - oldHeight) / 2;
-                }
-                checkVisibleRectSize(image, selectedRect);
-                checkVisibleRectPos(image, selectedRect);
-                synchronized (MapillaryImageDisplay.this) {
-                    MapillaryImageDisplay.this.visibleRect = selectedRect;
-                }
-                selectedRect = null;
-                MapillaryImageDisplay.this.repaint();
-            }
-        }
-
-        @Override
-        public void mouseEntered(MouseEvent e) {
-        }
-
-        @Override
-        public void mouseExited(MouseEvent e) {
-        }
-
-        @Override
-        public void mouseMoved(MouseEvent e) {
-        }
-
-        private void checkPointInVisibleRect(Point p, Rectangle visibleRect) {
-            if (p.x < visibleRect.x) {
-                p.x = visibleRect.x;
-            }
-            if (p.x > visibleRect.x + visibleRect.width) {
-                p.x = visibleRect.x + visibleRect.width;
-            }
-            if (p.y < visibleRect.y) {
-                p.y = visibleRect.y;
-            }
-            if (p.y > visibleRect.y + visibleRect.height) {
-                p.y = visibleRect.y + visibleRect.height;
-            }
-        }
-    }
-
-    public MapillaryImageDisplay() {
-        ImgDisplayMouseListener mouseListener = new ImgDisplayMouseListener();
-        addMouseListener(mouseListener);
-        addMouseWheelListener(mouseListener);
-        addMouseMotionListener(mouseListener);
-        this.setLayout(new BorderLayout());
-        JPanel southPanel = new JPanel();
-        southPanel.setLayout(new BorderLayout());
-        hyperlink = new HyperlinkLabel();
-        southPanel.add(hyperlink, BorderLayout.EAST);
-        southPanel.setOpaque(false);
-
-        add(southPanel, BorderLayout.SOUTH);
-    }
-
-    /**
-     * Sets a new picture to be displayed.
-     * 
-     * @param image
-     */
-    public void setImage(BufferedImage image) {
-        synchronized (this) {
-            this.image = image;
-            selectedRect = null;
-            if (image != null)
-                this.visibleRect = new Rectangle(0, 0, image.getWidth(null),
-                        image.getHeight(null));
-        }
-        repaint();
-    }
-
-    /**
-     * Returns the picture that is being displayerd
-     * 
-     * @return
-     */
-    public BufferedImage getImage() {
-        return this.image;
-    }
-
-    /**
-     * Paints the visible part of the picture.
-     */
-    public void paintComponent(Graphics g) {
-        Image image;
-        Rectangle visibleRect;
-        synchronized (this) {
-            image = this.image;
-            visibleRect = this.visibleRect;
-        }
-        if (image == null) {
-            g.setColor(Color.black);
-            String noImageStr = tr("No image");
-            Rectangle2D noImageSize = g.getFontMetrics(g.getFont())
-                    .getStringBounds(noImageStr, g);
-            Dimension size = getSize();
-            g.drawString(noImageStr,
-                    (int) ((size.width - noImageSize.getWidth()) / 2),
-                    (int) ((size.height - noImageSize.getHeight()) / 2));
+    @Override
+    public void mousePressed(MouseEvent e) {
+      if (image == null) {
+        mouseIsDragging = false;
+        selectedRect = null;
+        return;
+      }
+      Image image;
+      Rectangle visibleRect;
+      synchronized (MapillaryImageDisplay.this) {
+        image = MapillaryImageDisplay.this.image;
+        visibleRect = MapillaryImageDisplay.this.visibleRect;
+      }
+      if (image == null)
+        return;
+      if (e.getButton() == DRAG_BUTTON) {
+        mousePointInImg = comp2imgCoord(visibleRect, e.getX(), e.getY());
+        mouseIsDragging = true;
+        selectedRect = null;
+      } else if (e.getButton() == ZOOM_BUTTON) {
+        mousePointInImg = comp2imgCoord(visibleRect, e.getX(), e.getY());
+        checkPointInVisibleRect(mousePointInImg, visibleRect);
+        mouseIsDragging = false;
+        selectedRect = new Rectangle(mousePointInImg.x, mousePointInImg.y, 0, 0);
+        MapillaryImageDisplay.this.repaint();
+      } else {
+        mouseIsDragging = false;
+        selectedRect = null;
+      }
+    }
+
+    @Override
+    public void mouseDragged(MouseEvent e) {
+      if (!mouseIsDragging && selectedRect == null)
+        return;
+      Image image;
+      Rectangle visibleRect;
+      synchronized (MapillaryImageDisplay.this) {
+        image = MapillaryImageDisplay.this.image;
+        visibleRect = MapillaryImageDisplay.this.visibleRect;
+      }
+      if (image == null) {
+        mouseIsDragging = false;
+        selectedRect = null;
+        return;
+      }
+      if (mouseIsDragging) {
+        Point p = comp2imgCoord(visibleRect, e.getX(), e.getY());
+        visibleRect.x += mousePointInImg.x - p.x;
+        visibleRect.y += mousePointInImg.y - p.y;
+        checkVisibleRectPos(image, visibleRect);
+        synchronized (MapillaryImageDisplay.this) {
+          MapillaryImageDisplay.this.visibleRect = visibleRect;
+        }
+        MapillaryImageDisplay.this.repaint();
+      } else if (selectedRect != null) {
+        Point p = comp2imgCoord(visibleRect, e.getX(), e.getY());
+        checkPointInVisibleRect(p, visibleRect);
+        Rectangle rect = new Rectangle(p.x < mousePointInImg.x ? p.x
+            : mousePointInImg.x, p.y < mousePointInImg.y ? p.y
+            : mousePointInImg.y, p.x < mousePointInImg.x ? mousePointInImg.x
+            - p.x : p.x - mousePointInImg.x,
+            p.y < mousePointInImg.y ? mousePointInImg.y - p.y : p.y
+                - mousePointInImg.y);
+        checkVisibleRectSize(image, rect);
+        checkVisibleRectPos(image, rect);
+        MapillaryImageDisplay.this.selectedRect = rect;
+        MapillaryImageDisplay.this.repaint();
+      }
+    }
+
+    @Override
+    public void mouseReleased(MouseEvent e) {
+      if (!mouseIsDragging && selectedRect == null)
+        return;
+      Image image;
+      synchronized (MapillaryImageDisplay.this) {
+        image = MapillaryImageDisplay.this.image;
+      }
+      if (image == null) {
+        mouseIsDragging = false;
+        selectedRect = null;
+        return;
+      }
+      if (mouseIsDragging) {
+        mouseIsDragging = false;
+      } else if (selectedRect != null) {
+        int oldWidth = selectedRect.width;
+        int oldHeight = selectedRect.height;
+        // Check that the zoom doesn't exceed 2:1
+        if (selectedRect.width < getSize().width / 2) {
+          selectedRect.width = getSize().width / 2;
+        }
+        if (selectedRect.height < getSize().height / 2) {
+          selectedRect.height = getSize().height / 2;
+        }
+        // Set the same ratio for the visible rectangle and the display
+        // area
+        int hFact = selectedRect.height * getSize().width;
+        int wFact = selectedRect.width * getSize().height;
+        if (hFact > wFact) {
+          selectedRect.width = hFact / getSize().height;
         } else {
-            Rectangle target = calculateDrawImageRectangle(visibleRect);
-            g.drawImage(image, target.x, target.y, target.x + target.width,
-                    target.y + target.height, visibleRect.x, visibleRect.y,
-                    visibleRect.x + visibleRect.width, visibleRect.y
-                            + visibleRect.height, null);
-            if (selectedRect != null) {
-                Point topLeft = img2compCoord(visibleRect, selectedRect.x,
-                        selectedRect.y);
-                Point bottomRight = img2compCoord(visibleRect, selectedRect.x
-                        + selectedRect.width, selectedRect.y
-                        + selectedRect.height);
-                g.setColor(new Color(128, 128, 128, 180));
-                g.fillRect(target.x, target.y, target.width, topLeft.y
-                        - target.y);
-                g.fillRect(target.x, target.y, topLeft.x - target.x,
-                        target.height);
-                g.fillRect(bottomRight.x, target.y, target.x + target.width
-                        - bottomRight.x, target.height);
-                g.fillRect(target.x, bottomRight.y, target.width, target.y
-                        + target.height - bottomRight.y);
-                g.setColor(Color.black);
-                g.drawRect(topLeft.x, topLeft.y, bottomRight.x - topLeft.x,
-                        bottomRight.y - topLeft.y);
-            }
-        }
-    }
-
-    private final Point img2compCoord(Rectangle visibleRect, int xImg, int yImg) {
-        Rectangle drawRect = calculateDrawImageRectangle(visibleRect);
-        return new Point(drawRect.x + ((xImg - visibleRect.x) * drawRect.width)
-                / visibleRect.width, drawRect.y
-                + ((yImg - visibleRect.y) * drawRect.height)
-                / visibleRect.height);
-    }
-
-    private final Point comp2imgCoord(Rectangle visibleRect, int xComp,
-            int yComp) {
-        Rectangle drawRect = calculateDrawImageRectangle(visibleRect);
-        return new Point(visibleRect.x
-                + ((xComp - drawRect.x) * visibleRect.width) / drawRect.width,
-                visibleRect.y + ((yComp - drawRect.y) * visibleRect.height)
-                        / drawRect.height);
-    }
-
-    private final Point getCenterImgCoord(Rectangle visibleRect) {
-        return new Point(visibleRect.x + visibleRect.width / 2, visibleRect.y
-                + visibleRect.height / 2);
-    }
-
-    private Rectangle calculateDrawImageRectangle(Rectangle visibleRect) {
-        return calculateDrawImageRectangle(visibleRect, new Rectangle(0, 0,
-                getSize().width, getSize().height));
-    }
-
-    /**
-     * calculateDrawImageRectangle
-     *
-     * @param imgRect
-     *            the part of the image that should be drawn (in image
-     *            coordinates)
-     * @param compRect
-     *            the part of the component where the image should be drawn (in
-     *            component coordinates)
-     * @return the part of compRect with the same width/height ratio as the
-     *         image
-     */
-    static Rectangle calculateDrawImageRectangle(Rectangle imgRect,
-            Rectangle compRect) {
-        int x, y, w, h;
-        x = 0;
-        y = 0;
-        w = compRect.width;
-        h = compRect.height;
-        int wFact = w * imgRect.height;
-        int hFact = h * imgRect.width;
-        if (wFact != hFact) {
-            if (wFact > hFact) {
-                w = hFact / imgRect.height;
-                x = (compRect.width - w) / 2;
-            } else {
-                h = wFact / imgRect.width;
-                y = (compRect.height - h) / 2;
-            }
-        }
-        return new Rectangle(x + compRect.x, y + compRect.y, w, h);
-    }
-
-    /**
-     * Zooms to 1:1 and, if it is already in 1:1, to best fit.
-     */
-    public void zoomBestFitOrOne() {
-        Image image;
-        Rectangle visibleRect;
-        synchronized (this) {
-            image = MapillaryImageDisplay.this.image;
-            visibleRect = MapillaryImageDisplay.this.visibleRect;
-        }
-        if (image == null)
-            return;
-        if (visibleRect.width != image.getWidth(null)
-                || visibleRect.height != image.getHeight(null)) {
-            // The display is not at best fit. => Zoom to best fit
-            visibleRect = new Rectangle(0, 0, image.getWidth(null),
-                    image.getHeight(null));
-        } else {
-            // The display is at best fit => zoom to 1:1
-            Point center = getCenterImgCoord(visibleRect);
-            visibleRect = new Rectangle(center.x - getWidth() / 2, center.y
-                    - getHeight() / 2, getWidth(), getHeight());
-            checkVisibleRectPos(image, visibleRect);
-        }
-        synchronized (this) {
-            this.visibleRect = visibleRect;
-        }
-        repaint();
-    }
-
-    private final void checkVisibleRectPos(Image image, Rectangle visibleRect) {
-        if (visibleRect.x < 0) {
-            visibleRect.x = 0;
-        }
-        if (visibleRect.y < 0) {
-            visibleRect.y = 0;
-        }
-        if (visibleRect.x + visibleRect.width > image.getWidth(null)) {
-            visibleRect.x = image.getWidth(null) - visibleRect.width;
-        }
-        if (visibleRect.y + visibleRect.height > image.getHeight(null)) {
-            visibleRect.y = image.getHeight(null) - visibleRect.height;
-        }
-    }
-
-    private void checkVisibleRectSize(Image image, Rectangle visibleRect) {
-        if (visibleRect.width > image.getWidth(null)) {
-            visibleRect.width = image.getWidth(null);
-        }
-        if (visibleRect.height > image.getHeight(null)) {
-            visibleRect.height = image.getHeight(null);
-        }
-    }
+          selectedRect.height = wFact / getSize().width;
+        }
+        // Keep the center of the selection
+        if (selectedRect.width != oldWidth) {
+          selectedRect.x -= (selectedRect.width - oldWidth) / 2;
+        }
+        if (selectedRect.height != oldHeight) {
+          selectedRect.y -= (selectedRect.height - oldHeight) / 2;
+        }
+        checkVisibleRectSize(image, selectedRect);
+        checkVisibleRectPos(image, selectedRect);
+        synchronized (MapillaryImageDisplay.this) {
+          MapillaryImageDisplay.this.visibleRect = selectedRect;
+        }
+        selectedRect = null;
+        MapillaryImageDisplay.this.repaint();
+      }
+    }
+
+    @Override
+    public void mouseEntered(MouseEvent e) {
+    }
+
+    @Override
+    public void mouseExited(MouseEvent e) {
+    }
+
+    @Override
+    public void mouseMoved(MouseEvent e) {
+    }
+
+    private void checkPointInVisibleRect(Point p, Rectangle visibleRect) {
+      if (p.x < visibleRect.x) {
+        p.x = visibleRect.x;
+      }
+      if (p.x > visibleRect.x + visibleRect.width) {
+        p.x = visibleRect.x + visibleRect.width;
+      }
+      if (p.y < visibleRect.y) {
+        p.y = visibleRect.y;
+      }
+      if (p.y > visibleRect.y + visibleRect.height) {
+        p.y = visibleRect.y + visibleRect.height;
+      }
+    }
+  }
+
+  public MapillaryImageDisplay() {
+    ImgDisplayMouseListener mouseListener = new ImgDisplayMouseListener();
+    addMouseListener(mouseListener);
+    addMouseWheelListener(mouseListener);
+    addMouseMotionListener(mouseListener);
+    this.setLayout(new BorderLayout());
+    JPanel southPanel = new JPanel();
+    southPanel.setLayout(new BorderLayout());
+    hyperlink = new HyperlinkLabel();
+    southPanel.add(hyperlink, BorderLayout.EAST);
+    southPanel.setOpaque(false);
+
+    add(southPanel, BorderLayout.SOUTH);
+  }
+
+  /**
+   * Sets a new picture to be displayed.
+   * 
+   * @param image
+   */
+  public void setImage(BufferedImage image) {
+    synchronized (this) {
+      this.image = image;
+      selectedRect = null;
+      if (image != null)
+        this.visibleRect = new Rectangle(0, 0, image.getWidth(null),
+            image.getHeight(null));
+    }
+    repaint();
+  }
+
+  /**
+   * Returns the picture that is being displayerd
+   * 
+   * @return
+   */
+  public BufferedImage getImage() {
+    return this.image;
+  }
+
+  /**
+   * Paints the visible part of the picture.
+   */
+  public void paintComponent(Graphics g) {
+    Image image;
+    Rectangle visibleRect;
+    synchronized (this) {
+      image = this.image;
+      visibleRect = this.visibleRect;
+    }
+    if (image == null) {
+      g.setColor(Color.black);
+      String noImageStr = tr("No image");
+      Rectangle2D noImageSize = g.getFontMetrics(g.getFont()).getStringBounds(
+          noImageStr, g);
+      Dimension size = getSize();
+      g.drawString(noImageStr,
+          (int) ((size.width - noImageSize.getWidth()) / 2),
+          (int) ((size.height - noImageSize.getHeight()) / 2));
+    } else {
+      Rectangle target = calculateDrawImageRectangle(visibleRect);
+      g.drawImage(image, target.x, target.y, target.x + target.width, target.y
+          + target.height, visibleRect.x, visibleRect.y, visibleRect.x
+          + visibleRect.width, visibleRect.y + visibleRect.height, null);
+      if (selectedRect != null) {
+        Point topLeft = img2compCoord(visibleRect, selectedRect.x,
+            selectedRect.y);
+        Point bottomRight = img2compCoord(visibleRect, selectedRect.x
+            + selectedRect.width, selectedRect.y + selectedRect.height);
+        g.setColor(new Color(128, 128, 128, 180));
+        g.fillRect(target.x, target.y, target.width, topLeft.y - target.y);
+        g.fillRect(target.x, target.y, topLeft.x - target.x, target.height);
+        g.fillRect(bottomRight.x, target.y, target.x + target.width
+            - bottomRight.x, target.height);
+        g.fillRect(target.x, bottomRight.y, target.width, target.y
+            + target.height - bottomRight.y);
+        g.setColor(Color.black);
+        g.drawRect(topLeft.x, topLeft.y, bottomRight.x - topLeft.x,
+            bottomRight.y - topLeft.y);
+      }
+    }
+  }
+
+  private final Point img2compCoord(Rectangle visibleRect, int xImg, int yImg) {
+    Rectangle drawRect = calculateDrawImageRectangle(visibleRect);
+    return new Point(drawRect.x + ((xImg - visibleRect.x) * drawRect.width)
+        / visibleRect.width, drawRect.y
+        + ((yImg - visibleRect.y) * drawRect.height) / visibleRect.height);
+  }
+
+  private final Point comp2imgCoord(Rectangle visibleRect, int xComp, int yComp) {
+    Rectangle drawRect = calculateDrawImageRectangle(visibleRect);
+    return new Point(visibleRect.x + ((xComp - drawRect.x) * visibleRect.width)
+        / drawRect.width, visibleRect.y
+        + ((yComp - drawRect.y) * visibleRect.height) / drawRect.height);
+  }
+
+  private final Point getCenterImgCoord(Rectangle visibleRect) {
+    return new Point(visibleRect.x + visibleRect.width / 2, visibleRect.y
+        + visibleRect.height / 2);
+  }
+
+  private Rectangle calculateDrawImageRectangle(Rectangle visibleRect) {
+    return calculateDrawImageRectangle(visibleRect, new Rectangle(0, 0,
+        getSize().width, getSize().height));
+  }
+
+  /**
+   * calculateDrawImageRectangle
+   *
+   * @param imgRect
+   *          the part of the image that should be drawn (in image coordinates)
+   * @param compRect
+   *          the part of the component where the image should be drawn (in
+   *          component coordinates)
+   * @return the part of compRect with the same width/height ratio as the image
+   */
+  static Rectangle calculateDrawImageRectangle(Rectangle imgRect,
+      Rectangle compRect) {
+    int x, y, w, h;
+    x = 0;
+    y = 0;
+    w = compRect.width;
+    h = compRect.height;
+    int wFact = w * imgRect.height;
+    int hFact = h * imgRect.width;
+    if (wFact != hFact) {
+      if (wFact > hFact) {
+        w = hFact / imgRect.height;
+        x = (compRect.width - w) / 2;
+      } else {
+        h = wFact / imgRect.width;
+        y = (compRect.height - h) / 2;
+      }
+    }
+    return new Rectangle(x + compRect.x, y + compRect.y, w, h);
+  }
+
+  /**
+   * Zooms to 1:1 and, if it is already in 1:1, to best fit.
+   */
+  public void zoomBestFitOrOne() {
+    Image image;
+    Rectangle visibleRect;
+    synchronized (this) {
+      image = MapillaryImageDisplay.this.image;
+      visibleRect = MapillaryImageDisplay.this.visibleRect;
+    }
+    if (image == null)
+      return;
+    if (visibleRect.width != image.getWidth(null)
+        || visibleRect.height != image.getHeight(null)) {
+      // The display is not at best fit. => Zoom to best fit
+      visibleRect = new Rectangle(0, 0, image.getWidth(null),
+          image.getHeight(null));
+    } else {
+      // The display is at best fit => zoom to 1:1
+      Point center = getCenterImgCoord(visibleRect);
+      visibleRect = new Rectangle(center.x - getWidth() / 2, center.y
+          - getHeight() / 2, getWidth(), getHeight());
+      checkVisibleRectPos(image, visibleRect);
+    }
+    synchronized (this) {
+      this.visibleRect = visibleRect;
+    }
+    repaint();
+  }
+
+  private final void checkVisibleRectPos(Image image, Rectangle visibleRect) {
+    if (visibleRect.x < 0) {
+      visibleRect.x = 0;
+    }
+    if (visibleRect.y < 0) {
+      visibleRect.y = 0;
+    }
+    if (visibleRect.x + visibleRect.width > image.getWidth(null)) {
+      visibleRect.x = image.getWidth(null) - visibleRect.width;
+    }
+    if (visibleRect.y + visibleRect.height > image.getHeight(null)) {
+      visibleRect.y = image.getHeight(null) - visibleRect.height;
+    }
+  }
+
+  private void checkVisibleRectSize(Image image, Rectangle visibleRect) {
+    if (visibleRect.width > image.getWidth(null)) {
+      visibleRect.width = image.getWidth(null);
+    }
+    if (visibleRect.height > image.getHeight(null)) {
+      visibleRect.height = image.getHeight(null);
+    }
+  }
 }
Index: applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/gui/MapillaryMainDialog.java
===================================================================
--- applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/gui/MapillaryMainDialog.java	(revision 31349)
+++ applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/gui/MapillaryMainDialog.java	(revision 31350)
@@ -45,369 +45,362 @@
  */
 public class MapillaryMainDialog extends ToggleDialog implements
-        ICachedLoaderListener, MapillaryDataListener {
-
-    public final static String BASE_TITLE = "Mapillary picture";
-
-    public static MapillaryMainDialog INSTANCE;
-
-    public volatile MapillaryAbstractImage image;
-
-    public final SideButton nextButton = new SideButton(new nextPictureAction());
-    public final SideButton previousButton = new SideButton(
-            new previousPictureAction());
-    public final SideButton redButton = new SideButton(new redAction());
-    public final SideButton blueButton = new SideButton(new blueAction());
-
-    private JPanel buttonsPanel;
-
-    public MapillaryImageDisplay mapillaryImageDisplay;
-
-    private MapillaryCache imageCache;
-    private MapillaryCache thumbnailCache;
-
-    public MapillaryMainDialog() {
-        super(tr(BASE_TITLE), "mapillary.png", tr("Open Mapillary window"),
-                Shortcut.registerShortcut(tr("Mapillary dialog"),
-                        tr("Open Mapillary main dialog"), KeyEvent.VK_M,
-                        Shortcut.NONE), 200, false,
-                MapillaryPreferenceSetting.class);
-        MapillaryData.getInstance().addListener(this);
-        addShortcuts();
-        mapillaryImageDisplay = new MapillaryImageDisplay();
-
-        blueButton.setForeground(Color.BLUE);
-        redButton.setForeground(Color.RED);
-
-        createLayout(
-                mapillaryImageDisplay,
-                Arrays.asList(new SideButton[] { blueButton, previousButton,
-                        nextButton, redButton }),
-                Main.pref.getBoolean("mapillary.reverse-buttons"));
+    ICachedLoaderListener, MapillaryDataListener {
+
+  public final static String BASE_TITLE = "Mapillary picture";
+
+  public static MapillaryMainDialog INSTANCE;
+
+  public volatile MapillaryAbstractImage image;
+
+  public final SideButton nextButton = new SideButton(new nextPictureAction());
+  public final SideButton previousButton = new SideButton(
+      new previousPictureAction());
+  public final SideButton redButton = new SideButton(new redAction());
+  public final SideButton blueButton = new SideButton(new blueAction());
+
+  private JPanel buttonsPanel;
+
+  public MapillaryImageDisplay mapillaryImageDisplay;
+
+  private MapillaryCache imageCache;
+  private MapillaryCache thumbnailCache;
+
+  public MapillaryMainDialog() {
+    super(tr(BASE_TITLE), "mapillary.png", tr("Open Mapillary window"),
+        Shortcut.registerShortcut(tr("Mapillary dialog"),
+            tr("Open Mapillary main dialog"), KeyEvent.VK_M, Shortcut.NONE),
+        200, false, MapillaryPreferenceSetting.class);
+    MapillaryData.getInstance().addListener(this);
+    addShortcuts();
+    mapillaryImageDisplay = new MapillaryImageDisplay();
+
+    blueButton.setForeground(Color.BLUE);
+    redButton.setForeground(Color.RED);
+
+    createLayout(
+        mapillaryImageDisplay,
+        Arrays.asList(new SideButton[] { blueButton, previousButton,
+            nextButton, redButton }),
+        Main.pref.getBoolean("mapillary.reverse-buttons"));
+    disableAllButtons();
+
+  }
+
+  /**
+   * Adds the shortcuts to the buttons.
+   */
+  private void addShortcuts() {
+    nextButton.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(
+        KeyStroke.getKeyStroke("PAGE_DOWN"), "next");
+    nextButton.getActionMap().put("next", new nextPictureAction());
+    previousButton.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(
+        KeyStroke.getKeyStroke("PAGE_UP"), "previous");
+    previousButton.getActionMap().put("previous", new previousPictureAction());
+    blueButton.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(
+        KeyStroke.getKeyStroke("control PAGE_UP"), "blue");
+    blueButton.getActionMap().put("blue", new blueAction());
+    redButton.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(
+        KeyStroke.getKeyStroke("control PAGE_DOWN"), "red");
+    redButton.getActionMap().put("red", new redAction());
+  }
+
+  public static MapillaryMainDialog getInstance() {
+    if (INSTANCE == null)
+      INSTANCE = new MapillaryMainDialog();
+    return INSTANCE;
+  }
+
+  public static void destroyInstance() {
+    INSTANCE = null;
+  }
+
+  /**
+   * Downloads the image of the selected MapillaryImage and sets in the
+   * MapillaryImageDisplay object.
+   */
+  public synchronized void updateImage() {
+    if (!SwingUtilities.isEventDispatchThread()) {
+      SwingUtilities.invokeLater(new Runnable() {
+        @Override
+        public void run() {
+          updateImage();
+        }
+      });
+    } else {
+      if (MapillaryLayer.INSTANCE == null) {
+        return;
+      }
+      if (this.image == null) {
+        mapillaryImageDisplay.setImage(null);
+        setTitle(tr(BASE_TITLE));
         disableAllButtons();
-
-    }
-
-    /**
-     * Adds the shortcuts to the buttons.
-     */
-    private void addShortcuts() {
-        nextButton.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(
-                KeyStroke.getKeyStroke("PAGE_DOWN"), "next");
-        nextButton.getActionMap().put("next", new nextPictureAction());
-        previousButton.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(
-                KeyStroke.getKeyStroke("PAGE_UP"), "previous");
-        previousButton.getActionMap().put("previous",
-                new previousPictureAction());
-        blueButton.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(
-                KeyStroke.getKeyStroke("control PAGE_UP"), "blue");
-        blueButton.getActionMap().put("blue", new blueAction());
-        redButton.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(
-                KeyStroke.getKeyStroke("control PAGE_DOWN"), "red");
-        redButton.getActionMap().put("red", new redAction());
-    }
-
-    public static MapillaryMainDialog getInstance() {
-        if (INSTANCE == null)
-            INSTANCE = new MapillaryMainDialog();
-        return INSTANCE;
-    }
-
-    public static void destroyInstance() {
-        INSTANCE = null;
-    }
-
-    /**
-     * Downloads the image of the selected MapillaryImage and sets in the
-     * MapillaryImageDisplay object.
-     */
-    public synchronized void updateImage() {
-        if (!SwingUtilities.isEventDispatchThread()) {
-            SwingUtilities.invokeLater(new Runnable() {
-                @Override
-                public void run() {
-                    updateImage();
-                }
-            });
-        } else {
-            if (MapillaryLayer.INSTANCE == null) {
-                return;
+        return;
+      }
+      if (image instanceof MapillaryImage) {
+        mapillaryImageDisplay.hyperlink.setVisible(true);
+        MapillaryImage mapillaryImage = (MapillaryImage) this.image;
+        updateTitle();
+        // Enables/disables next/previous buttons
+        this.nextButton.setEnabled(false);
+        this.previousButton.setEnabled(false);
+        if (((MapillaryImage) image).getSequence() != null) {
+          MapillaryImage tempImage = (MapillaryImage) image;
+          while (tempImage.next() != null) {
+            tempImage = tempImage.next();
+            if (tempImage.isVisible()) {
+              this.nextButton.setEnabled(true);
+              break;
             }
-            if (this.image == null) {
-                mapillaryImageDisplay.setImage(null);
-                setTitle(tr(BASE_TITLE));
-                disableAllButtons();
-                return;
+          }
+        }
+        if (((MapillaryImage) image).getSequence() != null) {
+          MapillaryImage tempImage = (MapillaryImage) image;
+          while (tempImage.previous() != null) {
+            tempImage = tempImage.previous();
+            if (tempImage.isVisible()) {
+              this.previousButton.setEnabled(true);
+              break;
             }
-            if (image instanceof MapillaryImage) {
-                mapillaryImageDisplay.hyperlink.setVisible(true);
-                MapillaryImage mapillaryImage = (MapillaryImage) this.image;
-                updateTitle();
-                // Enables/disables next/previous buttons
-                this.nextButton.setEnabled(false);
-                this.previousButton.setEnabled(false);
-                if (((MapillaryImage) image).getSequence() != null) {
-                    MapillaryImage tempImage = (MapillaryImage) image;
-                    while (tempImage.next() != null) {
-                        tempImage = tempImage.next();
-                        if (tempImage.isVisible()) {
-                            this.nextButton.setEnabled(true);
-                            break;
-                        }
-                    }
-                }
-                if (((MapillaryImage) image).getSequence() != null) {
-                    MapillaryImage tempImage = (MapillaryImage) image;
-                    while (tempImage.previous() != null) {
-                        tempImage = tempImage.previous();
-                        if (tempImage.isVisible()) {
-                            this.previousButton.setEnabled(true);
-                            break;
-                        }
-                    }
-                }
-
-                mapillaryImageDisplay.hyperlink.setURL(mapillaryImage.getKey());
-                // Downloads the thumbnail.
-                this.mapillaryImageDisplay.setImage(null);
-                if (thumbnailCache != null)
-                    thumbnailCache.cancelOutstandingTasks();
-                thumbnailCache = new MapillaryCache(mapillaryImage.getKey(),
-                        MapillaryCache.Type.THUMBNAIL);
-                thumbnailCache.submit(this, false);
-
-                // Downloads the full resolution image.
-                if (imageCache != null)
-                    imageCache.cancelOutstandingTasks();
-                imageCache = new MapillaryCache(mapillaryImage.getKey(),
-                        MapillaryCache.Type.FULL_IMAGE);
-                imageCache.submit(this, false);
-            } else if (image instanceof MapillaryImportedImage) {
-                mapillaryImageDisplay.hyperlink.setVisible(false);
-                this.nextButton.setEnabled(false);
-                this.previousButton.setEnabled(false);
-                MapillaryImportedImage mapillaryImage = (MapillaryImportedImage) this.image;
-                try {
-                    mapillaryImageDisplay.setImage(mapillaryImage.getImage());
-                } catch (IOException e) {
-                    Main.error(e);
-                }
-                mapillaryImageDisplay.hyperlink.setURL(null);
-            }
-        }
-    }
-
-    private void disableAllButtons() {
-        nextButton.setEnabled(false);
-        previousButton.setEnabled(false);
-        blueButton.setEnabled(false);
-        redButton.setEnabled(false);
+          }
+        }
+
+        mapillaryImageDisplay.hyperlink.setURL(mapillaryImage.getKey());
+        // Downloads the thumbnail.
+        this.mapillaryImageDisplay.setImage(null);
+        if (thumbnailCache != null)
+          thumbnailCache.cancelOutstandingTasks();
+        thumbnailCache = new MapillaryCache(mapillaryImage.getKey(),
+            MapillaryCache.Type.THUMBNAIL);
+        thumbnailCache.submit(this, false);
+
+        // Downloads the full resolution image.
+        if (imageCache != null)
+          imageCache.cancelOutstandingTasks();
+        imageCache = new MapillaryCache(mapillaryImage.getKey(),
+            MapillaryCache.Type.FULL_IMAGE);
+        imageCache.submit(this, false);
+      } else if (image instanceof MapillaryImportedImage) {
         mapillaryImageDisplay.hyperlink.setVisible(false);
-    }
-
-    /**
-     * Sets a new MapillaryImage to be shown.
-     * 
-     * @param image
-     */
-    public synchronized void setImage(MapillaryAbstractImage image) {
-        this.image = image;
-    }
-
-    /**
-     * Updates the title of the dialog.
-     */
-    public synchronized void updateTitle() {
-        if (!SwingUtilities.isEventDispatchThread()) {
-            SwingUtilities.invokeLater(new Runnable() {
-                @Override
-                public void run() {
-                    updateTitle();
-                }
-            });
-        } else {
-            if (this.image != null) {
-                MapillaryImage mapillaryImage = (MapillaryImage) this.image;
-                String title = tr(BASE_TITLE);
-                if (mapillaryImage.getUser() != null)
-                    title += " -- " + mapillaryImage.getUser();
-                if (mapillaryImage.getCapturedAt() != 0)
-                    title += " -- " + mapillaryImage.getDate();
-                setTitle(title);
-            }
-        }
-    }
-
-    /**
-     * Returns the MapillaryImage objects which is being shown.
-     * 
-     * @return
-     */
-    public synchronized MapillaryAbstractImage getImage() {
-        return this.image;
-    }
-
-    /**
-     * Action class form the next image button.
-     * 
-     * @author Jorge
-     *
-     */
-    class nextPictureAction extends AbstractAction {
-        public nextPictureAction() {
-            putValue(NAME, tr("Next picture"));
-            putValue(SHORT_DESCRIPTION,
-                    tr("Shows the next picture in the sequence"));
-        }
-
+        this.nextButton.setEnabled(false);
+        this.previousButton.setEnabled(false);
+        MapillaryImportedImage mapillaryImage = (MapillaryImportedImage) this.image;
+        try {
+          mapillaryImageDisplay.setImage(mapillaryImage.getImage());
+        } catch (IOException e) {
+          Main.error(e);
+        }
+        mapillaryImageDisplay.hyperlink.setURL(null);
+      }
+    }
+  }
+
+  private void disableAllButtons() {
+    nextButton.setEnabled(false);
+    previousButton.setEnabled(false);
+    blueButton.setEnabled(false);
+    redButton.setEnabled(false);
+    mapillaryImageDisplay.hyperlink.setVisible(false);
+  }
+
+  /**
+   * Sets a new MapillaryImage to be shown.
+   * 
+   * @param image
+   */
+  public synchronized void setImage(MapillaryAbstractImage image) {
+    this.image = image;
+  }
+
+  /**
+   * Updates the title of the dialog.
+   */
+  public synchronized void updateTitle() {
+    if (!SwingUtilities.isEventDispatchThread()) {
+      SwingUtilities.invokeLater(new Runnable() {
         @Override
-        public void actionPerformed(ActionEvent e) {
-            if (MapillaryMainDialog.getInstance().getImage() != null) {
-                MapillaryData.getInstance().selectNext();
-            }
-        }
-    }
-
-    /**
-     * Action class for the previous image button.
-     * 
-     * @author Jorge
-     *
-     */
-    class previousPictureAction extends AbstractAction {
-        public previousPictureAction() {
-            putValue(NAME, tr("Previous picture"));
-            putValue(SHORT_DESCRIPTION,
-                    tr("Shows the previous picture in the sequence"));
-        }
-
+        public void run() {
+          updateTitle();
+        }
+      });
+    } else {
+      if (this.image != null) {
+        MapillaryImage mapillaryImage = (MapillaryImage) this.image;
+        String title = tr(BASE_TITLE);
+        if (mapillaryImage.getUser() != null)
+          title += " -- " + mapillaryImage.getUser();
+        if (mapillaryImage.getCapturedAt() != 0)
+          title += " -- " + mapillaryImage.getDate();
+        setTitle(title);
+      }
+    }
+  }
+
+  /**
+   * Returns the MapillaryImage objects which is being shown.
+   * 
+   * @return
+   */
+  public synchronized MapillaryAbstractImage getImage() {
+    return this.image;
+  }
+
+  /**
+   * Action class form the next image button.
+   * 
+   * @author Jorge
+   *
+   */
+  class nextPictureAction extends AbstractAction {
+    public nextPictureAction() {
+      putValue(NAME, tr("Next picture"));
+      putValue(SHORT_DESCRIPTION, tr("Shows the next picture in the sequence"));
+    }
+
+    @Override
+    public void actionPerformed(ActionEvent e) {
+      if (MapillaryMainDialog.getInstance().getImage() != null) {
+        MapillaryData.getInstance().selectNext();
+      }
+    }
+  }
+
+  /**
+   * Action class for the previous image button.
+   * 
+   * @author Jorge
+   *
+   */
+  class previousPictureAction extends AbstractAction {
+    public previousPictureAction() {
+      putValue(NAME, tr("Previous picture"));
+      putValue(SHORT_DESCRIPTION,
+          tr("Shows the previous picture in the sequence"));
+    }
+
+    @Override
+    public void actionPerformed(ActionEvent e) {
+      if (MapillaryMainDialog.getInstance().getImage() != null) {
+        MapillaryData.getInstance().selectPrevious();
+      }
+    }
+  }
+
+  /**
+   * Action class to jump to the image following the red line.
+   * 
+   * @author nokutu
+   *
+   */
+  class redAction extends AbstractAction {
+    public redAction() {
+      putValue(NAME, tr("Jump to red"));
+      putValue(SHORT_DESCRIPTION,
+          tr("Jumps to the picture at the other side of the red line"));
+    }
+
+    @Override
+    public void actionPerformed(ActionEvent e) {
+      if (MapillaryMainDialog.getInstance().getImage() != null) {
+        MapillaryData.getInstance().setSelectedImage(MapillaryLayer.RED, true);
+      }
+    }
+  }
+
+  /**
+   * Action class to jump to the image following the blue line.
+   * 
+   * @author nokutu
+   *
+   */
+  class blueAction extends AbstractAction {
+    public blueAction() {
+      putValue(NAME, tr("Jump to blue"));
+      putValue(SHORT_DESCRIPTION,
+          tr("Jumps to the picture at the other side of the blue line"));
+    }
+
+    @Override
+    public void actionPerformed(ActionEvent e) {
+      if (MapillaryMainDialog.getInstance().getImage() != null) {
+        MapillaryData.getInstance().setSelectedImage(MapillaryLayer.BLUE, true);
+      }
+    }
+  }
+
+  /**
+   * When the pictures are returned from the cache, they are set in the
+   * {@link MapillaryImageDisplay} object.
+   */
+  @Override
+  public void loadingFinished(final CacheEntry data,
+      final CacheEntryAttributes attributes, final LoadResult result) {
+    if (!SwingUtilities.isEventDispatchThread()) {
+      SwingUtilities.invokeLater(new Runnable() {
         @Override
-        public void actionPerformed(ActionEvent e) {
-            if (MapillaryMainDialog.getInstance().getImage() != null) {
-                MapillaryData.getInstance().selectPrevious();
-            }
-        }
-    }
-
-    /**
-     * Action class to jump to the image following the red line.
-     * 
-     * @author nokutu
-     *
-     */
-    class redAction extends AbstractAction {
-        public redAction() {
-            putValue(NAME, tr("Jump to red"));
-            putValue(
-                    SHORT_DESCRIPTION,
-                    tr("Jumps to the picture at the other side of the red line"));
-        }
-
-        @Override
-        public void actionPerformed(ActionEvent e) {
-            if (MapillaryMainDialog.getInstance().getImage() != null) {
-                MapillaryData.getInstance().setSelectedImage(
-                        MapillaryLayer.RED, true);
-            }
-        }
-    }
-
-    /**
-     * Action class to jump to the image following the blue line.
-     * 
-     * @author nokutu
-     *
-     */
-    class blueAction extends AbstractAction {
-        public blueAction() {
-            putValue(NAME, tr("Jump to blue"));
-            putValue(
-                    SHORT_DESCRIPTION,
-                    tr("Jumps to the picture at the other side of the blue line"));
-        }
-
-        @Override
-        public void actionPerformed(ActionEvent e) {
-            if (MapillaryMainDialog.getInstance().getImage() != null) {
-                MapillaryData.getInstance().setSelectedImage(
-                        MapillaryLayer.BLUE, true);
-            }
-        }
-    }
-
-    /**
-     * When the pictures are returned from the cache, they are set in the
-     * {@link MapillaryImageDisplay} object.
-     */
-    @Override
-    public void loadingFinished(final CacheEntry data,
-            final CacheEntryAttributes attributes, final LoadResult result) {
-        if (!SwingUtilities.isEventDispatchThread()) {
-            SwingUtilities.invokeLater(new Runnable() {
-                @Override
-                public void run() {
-                    loadingFinished(data, attributes, result);
-                }
-            });
-        } else if (data != null && result == LoadResult.SUCCESS) {
-            try {
-                BufferedImage img = ImageIO.read(new ByteArrayInputStream(data
-                        .getContent()));
-                if (img == null)
-                    return;
-                if (this.mapillaryImageDisplay.getImage() == null)
-                    mapillaryImageDisplay.setImage(img);
-                else if (img.getHeight() > this.mapillaryImageDisplay
-                        .getImage().getHeight()) {
-                    mapillaryImageDisplay.setImage(img);
-                }
-            } catch (IOException e) {
-                Main.error(e);
-            }
-        }
-    }
-
-    /**
-     * Creates the layout of the dialog.
-     * 
-     * @param data
-     *            The content of the dialog
-     * @param buttons
-     *            The buttons where you can click
-     * @param reverse
-     *            {@code true} if the buttons should go at the top;
-     *            {@code false} otherwise.
-     */
-    public void createLayout(Component data, List<SideButton> buttons,
-            boolean reverse) {
-        this.removeAll();
-        JPanel panel = new JPanel();
-        panel.setLayout(new BorderLayout());
-        panel.add(data, BorderLayout.CENTER);
-        if (reverse) {
-            buttonsPanel = new JPanel(new GridLayout(1, 1));
-            if (!buttons.isEmpty() && buttons.get(0) != null) {
-                final JPanel buttonRowPanel = new JPanel(Main.pref.getBoolean(
-                        "dialog.align.left", false) ? new FlowLayout(
-                        FlowLayout.LEFT) : new GridLayout(1, buttons.size()));
-                buttonsPanel.add(buttonRowPanel);
-                for (SideButton button : buttons)
-                    buttonRowPanel.add(button);
-            }
-            panel.add(buttonsPanel, BorderLayout.NORTH);
-            createLayout(panel, true, null);
-        } else
-            createLayout(panel, true, buttons);
-        this.add(titleBar, BorderLayout.NORTH);
-    }
-
-    @Override
-    public void selectedImageChanged(MapillaryAbstractImage oldImage,
-            MapillaryAbstractImage newImage) {
-        setImage(MapillaryData.getInstance().getSelectedImage());
-        updateImage();
-    }
-
-    @Override
-    public void imagesAdded() {
-    }
+        public void run() {
+          loadingFinished(data, attributes, result);
+        }
+      });
+    } else if (data != null && result == LoadResult.SUCCESS) {
+      try {
+        BufferedImage img = ImageIO.read(new ByteArrayInputStream(data
+            .getContent()));
+        if (img == null)
+          return;
+        if (this.mapillaryImageDisplay.getImage() == null)
+          mapillaryImageDisplay.setImage(img);
+        else if (img.getHeight() > this.mapillaryImageDisplay.getImage()
+            .getHeight()) {
+          mapillaryImageDisplay.setImage(img);
+        }
+      } catch (IOException e) {
+        Main.error(e);
+      }
+    }
+  }
+
+  /**
+   * Creates the layout of the dialog.
+   * 
+   * @param data
+   *          The content of the dialog
+   * @param buttons
+   *          The buttons where you can click
+   * @param reverse
+   *          {@code true} if the buttons should go at the top; {@code false}
+   *          otherwise.
+   */
+  public void createLayout(Component data, List<SideButton> buttons,
+      boolean reverse) {
+    this.removeAll();
+    JPanel panel = new JPanel();
+    panel.setLayout(new BorderLayout());
+    panel.add(data, BorderLayout.CENTER);
+    if (reverse) {
+      buttonsPanel = new JPanel(new GridLayout(1, 1));
+      if (!buttons.isEmpty() && buttons.get(0) != null) {
+        final JPanel buttonRowPanel = new JPanel(Main.pref.getBoolean(
+            "dialog.align.left", false) ? new FlowLayout(FlowLayout.LEFT)
+            : new GridLayout(1, buttons.size()));
+        buttonsPanel.add(buttonRowPanel);
+        for (SideButton button : buttons)
+          buttonRowPanel.add(button);
+      }
+      panel.add(buttonsPanel, BorderLayout.NORTH);
+      createLayout(panel, true, null);
+    } else
+      createLayout(panel, true, buttons);
+    this.add(titleBar, BorderLayout.NORTH);
+  }
+
+  @Override
+  public void selectedImageChanged(MapillaryAbstractImage oldImage,
+      MapillaryAbstractImage newImage) {
+    setImage(MapillaryData.getInstance().getSelectedImage());
+    updateImage();
+  }
+
+  @Override
+  public void imagesAdded() {
+  }
 }
Index: applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/gui/MapillaryOAuthUI.java
===================================================================
--- applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/gui/MapillaryOAuthUI.java	(revision 31349)
+++ applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/gui/MapillaryOAuthUI.java	(revision 31350)
@@ -20,23 +20,23 @@
 public class MapillaryOAuthUI extends JPanel {
 
-    private static final Token EMPTY_TOKEN = null;
+  private static final Token EMPTY_TOKEN = null;
 
-    public MapillaryOAuthUI() {
-        Scanner in = new Scanner(System.in);
-        OAuthService service = new ServiceBuilder()
-                .provider(MapillaryOAuthApi.class)
-                .apiKey("NzNRM2otQkR2SHJzaXJmNmdQWVQ0dzo1YTA2NmNlODhlNWMwOTBm")
-                .apiSecret("Secret").build();
-        String authorizationUrl = service.getAuthorizationUrl(EMPTY_TOKEN);
-        this.add(new JLabel("Login"));
-        System.out.println("Fetching the Authorization URL...");
-        System.out.println("Got the Authorization URL!");
-        System.out.println("Now go and authorize Scribe here:");
-        System.out.println(authorizationUrl);
-        System.out.println("And paste the authorization code here");
-        System.out.print(">>");
-        Verifier verifier = new Verifier(in.nextLine());
-        System.out.println();
-    }
+  public MapillaryOAuthUI() {
+    Scanner in = new Scanner(System.in);
+    OAuthService service = new ServiceBuilder()
+        .provider(MapillaryOAuthApi.class)
+        .apiKey("NzNRM2otQkR2SHJzaXJmNmdQWVQ0dzo1YTA2NmNlODhlNWMwOTBm")
+        .apiSecret("Secret").build();
+    String authorizationUrl = service.getAuthorizationUrl(EMPTY_TOKEN);
+    this.add(new JLabel("Login"));
+    System.out.println("Fetching the Authorization URL...");
+    System.out.println("Got the Authorization URL!");
+    System.out.println("Now go and authorize Scribe here:");
+    System.out.println(authorizationUrl);
+    System.out.println("And paste the authorization code here");
+    System.out.print(">>");
+    Verifier verifier = new Verifier(in.nextLine());
+    System.out.println();
+  }
 
 }
Index: applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/gui/MapillaryPreferenceSetting.java
===================================================================
--- applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/gui/MapillaryPreferenceSetting.java	(revision 31349)
+++ applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/gui/MapillaryPreferenceSetting.java	(revision 31350)
@@ -21,107 +21,105 @@
 public class MapillaryPreferenceSetting implements SubPreferenceSetting {
 
-    private JCheckBox reverseButtons = new JCheckBox(
-            tr("Reverse buttons position when displaying images."));
-    private JCheckBox downloadMode = new JCheckBox(
-            tr("Download images manually"));
-    private JCheckBox displayHour = new JCheckBox(
-            tr("Display hour when the picture was taken"));
-    private JCheckBox format24 = new JCheckBox(tr("Use 24 hour format"));
-    private JCheckBox moveTo = new JCheckBox(
-            tr("Move to picture's location with next/previous buttons"));
+  private JCheckBox reverseButtons = new JCheckBox(
+      tr("Reverse buttons position when displaying images."));
+  private JCheckBox downloadMode = new JCheckBox(tr("Download images manually"));
+  private JCheckBox displayHour = new JCheckBox(
+      tr("Display hour when the picture was taken"));
+  private JCheckBox format24 = new JCheckBox(tr("Use 24 hour format"));
+  private JCheckBox moveTo = new JCheckBox(
+      tr("Move to picture's location with next/previous buttons"));
+
+  @Override
+  public TabPreferenceSetting getTabPreferenceSetting(PreferenceTabbedPane gui) {
+    return gui.getDisplayPreference();
+  }
+
+  @Override
+  public void addGui(PreferenceTabbedPane gui) {
+    JPanel panel = new JPanel();
+
+    reverseButtons.setSelected(Main.pref
+        .getBoolean("mapillary.reverse-buttons"));
+    downloadMode.setSelected(Main.pref
+        .getBoolean("mapillary.download-manually"));
+    displayHour.setSelected(Main.pref
+        .getBoolean("mapillary.display-hour", true));
+    format24.setSelected(Main.pref.getBoolean("mapillary.format-24"));
+    moveTo.setSelected(Main.pref.getBoolean("mapillary.move-to-picture", true));
+
+    panel.setLayout(new FlowLayout(FlowLayout.LEFT));
+    panel.add(reverseButtons);
+    panel.add(downloadMode);
+    panel.add(displayHour);
+    panel.add(format24);
+    panel.add(moveTo);
+    JButton oauth = new JButton(new OAuthAction());
+    oauth.setText("Login");
+    panel.add(oauth);
+    gui.getDisplayPreference().addSubTab(this, "Mapillary", panel);
+  }
+
+  @Override
+  public boolean ok() {
+    boolean mod = false;
+    Main.pref.put("mapillary.reverse-buttons", reverseButtons.isSelected());
+    Main.pref.put("mapillary.download-manually", downloadMode.isSelected());
+    MapillaryPlugin.setMenuEnabled(MapillaryPlugin.DOWNLOAD_VIEW_MENU,
+        downloadMode.isSelected());
+
+    Main.pref.put("mapillary.display-hour", displayHour.isSelected());
+    Main.pref.put("mapillary.format-24", format24.isSelected());
+    Main.pref.put("mapillary.move-to-picture", moveTo.isSelected());
+    return mod;
+  }
+
+  @Override
+  public boolean isExpert() {
+    return false;
+  }
+
+  public class OAuthAction extends AbstractAction {
 
     @Override
-    public TabPreferenceSetting getTabPreferenceSetting(PreferenceTabbedPane gui) {
-        return gui.getDisplayPreference();
+    public void actionPerformed(ActionEvent arg0) {
+      JButton login = new JButton();
+      JButton cancel = new JButton();
+      JOptionPane pane = new JOptionPane(new MapillaryOAuthUI(),
+          JOptionPane.PLAIN_MESSAGE, JOptionPane.DEFAULT_OPTION, null,
+          new JButton[] { login, cancel });
+      login.setAction(new LoginAction(pane));
+      cancel.setAction(new CancelAction(pane));
+      JDialog dlg = pane.createDialog(Main.parent, tr("Login"));
+      dlg.setVisible(true);
+      dlg.dispose();
+    }
+  }
+
+  private class LoginAction extends AbstractAction {
+    private JOptionPane pane;
+
+    public LoginAction(JOptionPane pane) {
+      putValue(NAME, tr("Login"));
+      this.pane = pane;
     }
 
     @Override
-    public void addGui(PreferenceTabbedPane gui) {
-        JPanel panel = new JPanel();
+    public void actionPerformed(ActionEvent e) {
+      pane.setValue(JOptionPane.OK_OPTION);
+    }
+  }
 
-        reverseButtons.setSelected(Main.pref
-                .getBoolean("mapillary.reverse-buttons"));
-        downloadMode.setSelected(Main.pref
-                .getBoolean("mapillary.download-manually"));
-        displayHour.setSelected(Main.pref.getBoolean("mapillary.display-hour",
-                true));
-        format24.setSelected(Main.pref.getBoolean("mapillary.format-24"));
-        moveTo.setSelected(Main.pref.getBoolean("mapillary.move-to-picture",
-                true));
+  private class CancelAction extends AbstractAction {
+    private JOptionPane pane;
 
-        panel.setLayout(new FlowLayout(FlowLayout.LEFT));
-        panel.add(reverseButtons);
-        panel.add(downloadMode);
-        panel.add(displayHour);
-        panel.add(format24);
-        panel.add(moveTo);
-        JButton oauth = new JButton(new OAuthAction());
-        oauth.setText("Login");
-        panel.add(oauth);
-        gui.getDisplayPreference().addSubTab(this, "Mapillary", panel);
+    public CancelAction(JOptionPane pane) {
+      putValue(NAME, tr("Cancel"));
+      this.pane = pane;
     }
 
     @Override
-    public boolean ok() {
-        boolean mod = false;
-        Main.pref.put("mapillary.reverse-buttons", reverseButtons.isSelected());
-        Main.pref.put("mapillary.download-manually", downloadMode.isSelected());
-        MapillaryPlugin.setMenuEnabled(MapillaryPlugin.DOWNLOAD_VIEW_MENU,
-                downloadMode.isSelected());
-
-        Main.pref.put("mapillary.display-hour", displayHour.isSelected());
-        Main.pref.put("mapillary.format-24", format24.isSelected());
-        Main.pref.put("mapillary.move-to-picture", moveTo.isSelected());
-        return mod;
+    public void actionPerformed(ActionEvent e) {
+      pane.setValue(JOptionPane.CANCEL_OPTION);
     }
-
-    @Override
-    public boolean isExpert() {
-        return false;
-    }
-
-    public class OAuthAction extends AbstractAction {
-
-        @Override
-        public void actionPerformed(ActionEvent arg0) {
-            JButton login = new JButton();
-            JButton cancel = new JButton();
-            JOptionPane pane = new JOptionPane(new MapillaryOAuthUI(),
-                    JOptionPane.PLAIN_MESSAGE, JOptionPane.DEFAULT_OPTION,
-                    null, new JButton[] { login, cancel });
-            login.setAction(new LoginAction(pane));
-            cancel.setAction(new CancelAction(pane));
-            JDialog dlg = pane.createDialog(Main.parent, tr("Login"));
-            dlg.setVisible(true);
-            dlg.dispose();
-        }
-    }
-
-    private class LoginAction extends AbstractAction {
-        private JOptionPane pane;
-
-        public LoginAction(JOptionPane pane) {
-            putValue(NAME, tr("Login"));
-            this.pane = pane;
-        }
-        
-        @Override
-        public void actionPerformed(ActionEvent e) {
-            pane.setValue(JOptionPane.OK_OPTION);
-        }
-    }
-    
-    private class CancelAction extends AbstractAction {
-        private JOptionPane pane;
-
-        public CancelAction(JOptionPane pane) {
-            putValue(NAME, tr("Cancel"));
-            this.pane = pane;
-        }
-        
-        @Override
-        public void actionPerformed(ActionEvent e) {
-            pane.setValue(JOptionPane.CANCEL_OPTION);
-        }
-    }
+  }
 }
Index: applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/oauth/MapillaryOAuthApi.java
===================================================================
--- applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/oauth/MapillaryOAuthApi.java	(revision 31349)
+++ applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/oauth/MapillaryOAuthApi.java	(revision 31350)
@@ -13,17 +13,17 @@
 public class MapillaryOAuthApi extends DefaultApi20 {
 
-    @Override
-    public String getAccessTokenEndpoint() {
-        return "https://a.mapillary.com/v2/oauth/token";
-    }
+  @Override
+  public String getAccessTokenEndpoint() {
+    return "https://a.mapillary.com/v2/oauth/token";
+  }
 
-    @Override
-    public String getAuthorizationUrl(OAuthConfig config) {
-        return "http://www.mapillary.io/connect?client_id=MkJKbDA0bnZuZlcxeTJHTmFqN3g1dzplZTlkZjQyYjYyZTczOTdi&redirect_uri=https:%2F%2Fjosm.openstreetmap.de%2F&response_type=token&scope=upload";
-    }
+  @Override
+  public String getAuthorizationUrl(OAuthConfig config) {
+    return "http://www.mapillary.io/connect?client_id=MkJKbDA0bnZuZlcxeTJHTmFqN3g1dzplZTlkZjQyYjYyZTczOTdi&redirect_uri=https:%2F%2Fjosm.openstreetmap.de%2F&response_type=token&scope=upload";
+  }
 
-    @Override
-    public Verb getAccessTokenVerb() {
-        return Verb.POST;
-    }
+  @Override
+  public Verb getAccessTokenVerb() {
+    return Verb.POST;
+  }
 }
