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 31221)
+++ /applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/MapillaryData.java	(revision 31222)
@@ -183,8 +183,10 @@
 	 */
 	public void addMultiSelectedImage(MapillaryImage image) {
-		if (this.getSelectedImage() != null)
-			this.multiSelectedImages.add(image);
-		else
-			this.setSelectedImage(image);
+		if (!this.multiSelectedImages.contains(image)) {
+			if (this.getSelectedImage() != null)
+				this.multiSelectedImages.add(image);
+			else
+				this.setSelectedImage(image);
+		}
 		Main.map.mapView.repaint();
 	}
Index: /applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/MapillaryDownloadAction.java
===================================================================
--- /applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/MapillaryDownloadAction.java	(revision 31221)
+++ /applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/MapillaryDownloadAction.java	(revision 31222)
@@ -28,5 +28,6 @@
 				tr("Create Mapillary layer."), Shortcut.registerShortcut(
 						"menu:Mapillary", tr("Menu: {0}", tr("Mapillary")),
-						KeyEvent.VK_M, Shortcut.ALT_CTRL_SHIFT), false, "mapillaryDownload", false);
+						KeyEvent.VK_M, Shortcut.ALT_CTRL_SHIFT), false,
+				"mapillaryDownload", false);
 	}
 
@@ -40,5 +41,6 @@
 	public void actionPerformed(ActionEvent arg0) {
 		this.layer = null;
-		if (Main.map == null) {
+		if (Main.map == null || Main.map.mapView == null
+				|| Main.map.mapView.getEditLayer() == null) {
 			return;
 		}
@@ -55,5 +57,6 @@
 				Main.map.mapView.setActiveLayer(layer);
 			else
-				Main.map.mapView.setActiveLayer(Main.map.mapView.getEditLayer());
+				Main.map.mapView
+						.setActiveLayer(Main.map.mapView.getEditLayer());
 		}
 	}
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 31221)
+++ /applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/MapillaryImage.java	(revision 31222)
@@ -14,5 +14,5 @@
 	private final String key;
 	/** Postion of the picture */
-	private final LatLon latLon;
+	public final LatLon latLon;
 	/** Direction of the picture */
 	private final double ca;
@@ -22,10 +22,10 @@
 	private boolean isModified = false;
 	/** Temporal position of the picture until it is uplaoded */
-	private LatLon tempLatLon;
+	public LatLon tempLatLon;
 	/**
 	 * When the object is being dragged in the map, the temporal position is
 	 * stored here
 	 */
-	private LatLon movingLatLon;
+	public LatLon movingLatLon;
 	/** Temporal direction of the picture until it is uplaoded */
 	private double tempCa;
@@ -74,4 +74,8 @@
 	public LatLon getLatLon() {
 		return movingLatLon;
+	}
+	
+	public LatLon getTempLatLon() {
+		return tempLatLon;
 	}
 
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 31221)
+++ /applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/MapillaryLayer.java	(revision 31222)
@@ -5,4 +5,7 @@
 import org.apache.commons.jcs.access.CacheAccess;
 import org.openstreetmap.josm.plugins.mapillary.cache.MapillaryCache;
+import org.openstreetmap.josm.plugins.mapillary.commands.CommandMoveImage;
+import org.openstreetmap.josm.plugins.mapillary.commands.CommandTurnImage;
+import org.openstreetmap.josm.plugins.mapillary.commands.MapillaryRecord;
 import org.openstreetmap.josm.plugins.mapillary.downloads.MapillaryDownloader;
 import org.openstreetmap.josm.Main;
@@ -58,5 +61,7 @@
 	public static MapillaryImage RED;
 
-	private final MapillaryData mapillaryData;
+	private final MapillaryData mapillaryData = MapillaryData.getInstance();
+	private final MapillaryRecord record = MapillaryRecord.getInstance();
+
 	private List<Bounds> bounds;
 	private MapillaryToggleDialog tgd;
@@ -66,5 +71,4 @@
 	public MapillaryLayer() {
 		super(tr("Mapillary Images"));
-		mapillaryData = MapillaryData.getInstance();
 		bounds = new ArrayList<>();
 		init();
@@ -117,21 +121,24 @@
 						.getInstance())
 					return;
-				if (e.getClickCount() == 2 && mapillaryData.getSelectedImage() != null) {
-					for (MapillaryImage img : mapillaryData.getSelectedImage().getSequence().getImages()) {
+				MapillaryImage closest = getClosest(e.getPoint());
+				if (e.getClickCount() == 2
+						&& mapillaryData.getSelectedImage() != null
+						&& closest != null) {
+					for (MapillaryImage img : closest.getSequence().getImages()) {
 						mapillaryData.addMultiSelectedImage(img);
 					}
 				}
-				MapillaryImage closest = getClosest(e.getPoint());
 				this.start = e.getPoint();
 				this.closest = closest;
 				if (mapillaryData.getMultiSelectedImages().contains(closest))
 					return;
-				if (e.getModifiers() == (MouseEvent.BUTTON1_MASK | MouseEvent.CTRL_MASK))
+				if (e.getModifiers() == (MouseEvent.BUTTON1_MASK | MouseEvent.CTRL_MASK)
+						&& closest != null)
 					mapillaryData.addMultiSelectedImage(closest);
 				else
 					mapillaryData.setSelectedImage(closest);
 			}
-			
-			private MapillaryImage getClosest(Point clickPoint){
+
+			private MapillaryImage getClosest(Point clickPoint) {
 				double snapDistance = 10;
 				double minDistance = Double.MAX_VALUE;
@@ -149,9 +156,12 @@
 					}
 				}
-				return closest;				
+				return closest;
 			}
 
 			@Override
 			public void mouseDragged(MouseEvent e) {
+				if (Main.map.mapView.getActiveLayer() != MapillaryLayer
+						.getInstance())
+					return;
 				if (MapillaryData.getInstance().getSelectedImage() != null) {
 					if (lastButton == MouseEvent.BUTTON1 && !e.isShiftDown()) {
@@ -169,9 +179,11 @@
 							&& e.isShiftDown()) {
 						this.closest.turn(Math.toDegrees(Math.atan2(
-									(e.getX() - start.x), -(e.getY() - start.y))) - closest.getTempCa());
+								(e.getX() - start.x), -(e.getY() - start.y)))
+								- closest.getTempCa());
 						for (MapillaryImage img : MapillaryData.getInstance()
 								.getMultiSelectedImages()) {
 							img.turn(Math.toDegrees(Math.atan2(
-									(e.getX() - start.x), -(e.getY() - start.y))) - closest.getTempCa());
+									(e.getX() - start.x), -(e.getY() - start.y)))
+									- closest.getTempCa());
 						}
 						Main.map.repaint();
@@ -182,5 +194,22 @@
 			@Override
 			public void mouseReleased(MouseEvent e) {
-				for (MapillaryImage img : MapillaryData.getInstance()
+				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 (MapillaryImage img : mapillaryData
 						.getMultiSelectedImages()) {
 					if (img != null)
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 31221)
+++ /applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/MapillaryPlugin.java	(revision 31222)
@@ -10,6 +10,9 @@
 import org.openstreetmap.josm.data.cache.JCSCacheManager;
 import org.openstreetmap.josm.gui.MainMenu;
+import org.openstreetmap.josm.gui.MapView;
+import org.openstreetmap.josm.gui.MapView.EditLayerChangeListener;
 import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.gui.MapFrame;
+import org.openstreetmap.josm.gui.layer.OsmDataLayer;
 import org.openstreetmap.josm.gui.preferences.PreferenceSetting;
 import org.openstreetmap.josm.plugins.Plugin;
@@ -23,5 +26,5 @@
  *
  */
-public class MapillaryPlugin extends Plugin {
+public class MapillaryPlugin extends Plugin implements EditLayerChangeListener{
 
 	public static final ImageIcon ICON24 = new ImageProvider("icon24.png")
@@ -53,4 +56,7 @@
 				false, 14);
 		EXPORT_MENU.setEnabled(false);
+		DOWNLOAD_MENU.setEnabled(false);
+		
+		MapView.addEditLayerChangeListener(this);
 		try {
 			CACHE = JCSCacheManager.getCache("mapillary", 10, 10000,
@@ -81,3 +87,11 @@
 		return new MapillaryPreferenceSetting();
 	}
+
+	@Override
+	public void editLayerChanged(OsmDataLayer oldLayer, OsmDataLayer newLayer) {
+		if (oldLayer == null && newLayer != null)
+			DOWNLOAD_MENU.setEnabled(true);		
+		else if (oldLayer != null && newLayer == null)
+			DOWNLOAD_MENU.setEnabled(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 31222)
+++ /applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/commands/CommandMoveImage.java	(revision 31222)
@@ -0,0 +1,38 @@
+package org.openstreetmap.josm.plugins.mapillary.commands;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.plugins.mapillary.MapillaryImage;
+
+public class CommandMoveImage extends MapillaryCommand {
+	private List<MapillaryImage> images;
+	private double x;
+	private double y;
+
+	public CommandMoveImage(List<MapillaryImage> images, double x, double y) {
+		this.images = new ArrayList<>(images);
+		this.x = x;
+		this.y = y;			
+	}
+
+
+	@Override
+	public void undo() {
+		for (MapillaryImage image : images) {
+			image.move(-x, -y);
+			image.stopMoving();
+		}
+		Main.map.repaint();
+	}
+
+	@Override
+	public void redo() {
+		for (MapillaryImage image : images) {
+			image.move(x, y);
+			image.stopMoving();
+		}
+		Main.map.repaint();
+	}
+}
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 31222)
+++ /applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/commands/CommandTurnImage.java	(revision 31222)
@@ -0,0 +1,37 @@
+package org.openstreetmap.josm.plugins.mapillary.commands;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.plugins.mapillary.MapillaryImage;
+
+public class CommandTurnImage extends MapillaryCommand {
+	private List<MapillaryImage> images;
+	private double ca;
+
+	public CommandTurnImage(List<MapillaryImage> images, double ca) {
+		this.images = new ArrayList<>(images);
+		this.ca = ca;
+	}
+
+
+	@Override
+	public void undo() {
+		for (MapillaryImage image : images) {
+			image.turn(-ca);
+			image.stopMoving();
+		}
+		Main.map.repaint();
+	}
+
+	@Override
+	public void redo() {
+		for (MapillaryImage image : images) {
+			image.turn(ca);
+			image.stopMoving();
+		}
+		Main.map.repaint();
+	}
+
+}
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 31222)
+++ /applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/commands/MapillaryCommand.java	(revision 31222)
@@ -0,0 +1,8 @@
+package org.openstreetmap.josm.plugins.mapillary.commands;
+
+
+public abstract class MapillaryCommand {
+	
+	public abstract void undo();
+	public abstract void redo();
+}
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 31222)
+++ /applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/commands/MapillaryRecord.java	(revision 31222)
@@ -0,0 +1,45 @@
+package org.openstreetmap.josm.plugins.mapillary.commands;
+
+import java.util.ArrayList;
+
+
+public class MapillaryRecord {
+	public static MapillaryRecord INSTANCE;
+	
+	public ArrayList<MapillaryCommand> commandList;
+	/** Last written command */
+	public int position;
+	
+	public MapillaryRecord() {
+		commandList = new ArrayList<>();
+		position = -1;
+	}
+	
+	public static synchronized MapillaryRecord getInstance() {
+		if (MapillaryRecord.INSTANCE == null)
+			MapillaryRecord.INSTANCE = new MapillaryRecord();
+		return MapillaryRecord.INSTANCE;
+	}
+	
+	public void addCommand(MapillaryCommand command) {
+		commandList.add(position + 1, command);
+		position++;
+		while (commandList.size() > position + 1) {
+			commandList.remove(position + 1);
+		}
+	}
+	
+	public void undo() {
+		if (position == -1)
+			return;
+		commandList.get(position).undo();
+		position--;
+	}
+	
+	public void redo() {
+		if (position >= commandList.size())
+			return;
+		commandList.get(position).redo();
+		position++;
+	}
+}
