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 31494)
+++ /applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/MapillaryLayer.java	(revision 31495)
@@ -190,5 +190,5 @@
   public void destroy() {
     setMode(null);
-
+    MapillaryRecord.getInstance().reset();
     AbstractMode.resetThread();
     MapillaryDownloader.stopAll();
@@ -211,27 +211,4 @@
   public static void clearInstance() {
     INSTANCE = null;
-  }
-
-  /**
-   * Zooms to fit all the {@link MapillaryAbstractImage} icons into the map
-   * view.
-   */
-  public void showAllPictures() {
-    double minLat = 90;
-    double minLon = 180;
-    double maxLat = -90;
-    double maxLon = -180;
-    for (MapillaryAbstractImage img : this.data.getImages()) {
-      if (img.getLatLon().lat() < minLat)
-        minLat = img.getLatLon().lat();
-      if (img.getLatLon().lon() < minLon)
-        minLon = img.getLatLon().lon();
-      if (img.getLatLon().lat() > maxLat)
-        maxLat = img.getLatLon().lat();
-      if (img.getLatLon().lon() > maxLon)
-        maxLon = img.getLatLon().lon();
-    }
-    Main.map.mapView.zoomTo(new Bounds(new LatLon(minLat, minLon), new LatLon(
-        maxLat, maxLon)));
   }
 
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 31494)
+++ /applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/actions/MapillaryImportAction.java	(revision 31495)
@@ -118,5 +118,5 @@
       }
       MapillaryRecord.getInstance().addCommand(new CommandImport(images));
-      MapillaryLayer.getInstance().showAllPictures();
+      MapillaryUtils.showAllPictures();
     }
   }
Index: /applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/actions/MapillaryImportIntoSequenceAction.java
===================================================================
--- /applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/actions/MapillaryImportIntoSequenceAction.java	(revision 31494)
+++ /applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/actions/MapillaryImportIntoSequenceAction.java	(revision 31495)
@@ -116,5 +116,5 @@
       MapillaryRecord.getInstance().addCommand(new CommandImport(this.images));
     }
-    MapillaryLayer.getInstance().showAllPictures();
+    MapillaryUtils.showAllPictures();
   }
 
Index: /applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/gui/FinishedUploadDialog.java
===================================================================
--- /applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/gui/FinishedUploadDialog.java	(revision 31494)
+++ /applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/gui/FinishedUploadDialog.java	(revision 31495)
@@ -36,5 +36,5 @@
     text.setAlignmentX(Component.CENTER_ALIGNMENT);
     this.add(text);
-    JButton web = new JButton("Approve upload in the website.");
+    JButton web = new JButton("Approve upload on the website.");
     web.addActionListener(new WebAction());
     web.setAlignmentX(Component.CENTER_ALIGNMENT);
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 31494)
+++ /applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/gui/MapillaryHistoryDialog.java	(revision 31495)
@@ -9,6 +9,9 @@
 import java.awt.event.ActionEvent;
 import java.awt.event.KeyEvent;
+import java.awt.event.MouseEvent;
+import java.awt.event.MouseListener;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.concurrent.ConcurrentHashMap;
 
 import javax.swing.AbstractAction;
@@ -18,6 +21,9 @@
 import javax.swing.JTree;
 import javax.swing.SwingUtilities;
+import javax.swing.event.TreeSelectionEvent;
+import javax.swing.event.TreeSelectionListener;
 import javax.swing.tree.DefaultTreeCellRenderer;
 import javax.swing.tree.DefaultTreeModel;
+import javax.swing.tree.TreeSelectionModel;
 
 import org.openstreetmap.josm.gui.SideButton;
@@ -25,5 +31,7 @@
 import org.openstreetmap.josm.plugins.mapillary.history.MapillaryRecord;
 import org.openstreetmap.josm.plugins.mapillary.history.MapillaryRecordListener;
+import org.openstreetmap.josm.plugins.mapillary.history.commands.CommandDelete;
 import org.openstreetmap.josm.plugins.mapillary.history.commands.MapillaryCommand;
+import org.openstreetmap.josm.plugins.mapillary.utils.MapillaryUtils;
 import org.openstreetmap.josm.tools.GBC;
 import org.openstreetmap.josm.tools.ImageProvider;
@@ -48,4 +56,7 @@
   private static MapillaryHistoryDialog INSTANCE;
 
+  private transient UndoRedoSelectionListener undoSelectionListener;
+  private transient UndoRedoSelectionListener redoSelectionListener;
+
   private final DefaultTreeModel undoTreeModel = new DefaultTreeModel(
       new DefaultMutableTreeNode());
@@ -61,4 +72,6 @@
   private SideButton redoButton;
 
+  private ConcurrentHashMap<Object, MapillaryCommand> map;
+
   private MapillaryHistoryDialog() {
     super(tr("Mapillary history"), "mapillaryhistory.png",
@@ -69,12 +82,27 @@
     MapillaryRecord.getInstance().addListener(this);
 
+    this.map = new ConcurrentHashMap<>();
+
     this.undoTree.expandRow(0);
     this.undoTree.setShowsRootHandles(true);
     this.undoTree.setRootVisible(false);
     this.undoTree.setCellRenderer(new MapillaryCellRenderer());
+    this.undoTree.getSelectionModel().setSelectionMode(
+        TreeSelectionModel.SINGLE_TREE_SELECTION);
+    this.undoTree.addMouseListener(new MouseEventHandler());
+    this.undoSelectionListener = new UndoRedoSelectionListener(this.undoTree);
+    this.undoTree.getSelectionModel().addTreeSelectionListener(
+        this.undoSelectionListener);
+
     this.redoTree.expandRow(0);
     this.redoTree.setCellRenderer(new MapillaryCellRenderer());
     this.redoTree.setShowsRootHandles(true);
     this.redoTree.setRootVisible(false);
+    this.redoTree.getSelectionModel().setSelectionMode(
+        TreeSelectionModel.SINGLE_TREE_SELECTION);
+    this.redoTree.addMouseListener(new MouseEventHandler());
+    this.redoSelectionListener = new UndoRedoSelectionListener(this.redoTree);
+    this.redoTree.getSelectionModel().addTreeSelectionListener(
+        this.redoSelectionListener);
 
     JPanel treesPanel = new JPanel(new GridBagLayout());
@@ -130,11 +158,20 @@
     DefaultMutableTreeNode undoRoot = new DefaultMutableTreeNode();
 
+    this.map.clear();
     for (MapillaryCommand command : undoCommands) {
-      if (command != null)
-        undoRoot.add(new DefaultMutableTreeNode(command.toString()));
+      if (command != null) {
+        DefaultMutableTreeNode node = new DefaultMutableTreeNode(
+            command.toString());
+        this.map.put(node, command);
+        undoRoot.add(node);
+      }
     }
     for (MapillaryCommand command : redoCommands) {
-      if (command != null)
-        redoRoot.add(new DefaultMutableTreeNode(command.toString()));
+      if (command != null) {
+        DefaultMutableTreeNode node = new DefaultMutableTreeNode(
+            command.toString());
+        this.map.put(node, command);
+        redoRoot.add(node);
+      }
     }
 
@@ -213,3 +250,69 @@
     MapillaryHistoryDialog.INSTANCE = null;
   }
+
+  private class MouseEventHandler implements MouseListener {
+
+    @Override
+    public void mouseClicked(MouseEvent e) {
+    }
+
+    @Override
+    public void mouseEntered(MouseEvent e) {
+    }
+
+    @Override
+    public void mouseExited(MouseEvent e) {
+    }
+
+    @Override
+    public void mousePressed(MouseEvent e) {
+      if (e.getClickCount() == 2) {
+        if (MapillaryHistoryDialog.this.undoTree.getSelectionPath() != null) {
+          MapillaryCommand cmd = MapillaryHistoryDialog.this.map
+              .get(MapillaryHistoryDialog.this.undoTree.getSelectionPath()
+                  .getLastPathComponent());
+          if (!(cmd instanceof CommandDelete))
+            MapillaryUtils.showPictures(cmd.images, true);
+        } else
+          MapillaryUtils.showPictures(MapillaryHistoryDialog.this.map
+              .get(MapillaryHistoryDialog.this.redoTree.getSelectionPath()
+                  .getLastPathComponent()).images, true);
+      }
+    }
+
+    @Override
+    public void mouseReleased(MouseEvent e) {
+    }
+  }
+
+  private class UndoRedoSelectionListener implements TreeSelectionListener {
+
+    private JTree source;
+
+    private UndoRedoSelectionListener(JTree source) {
+      this.source = source;
+    }
+
+    @Override
+    public void valueChanged(TreeSelectionEvent e) {
+      if (this.source == MapillaryHistoryDialog.this.undoTree) {
+        MapillaryHistoryDialog.this.redoTree.getSelectionModel()
+            .removeTreeSelectionListener(
+                MapillaryHistoryDialog.this.redoSelectionListener);
+        MapillaryHistoryDialog.this.redoTree.clearSelection();
+        MapillaryHistoryDialog.this.redoTree.getSelectionModel()
+            .addTreeSelectionListener(
+                MapillaryHistoryDialog.this.redoSelectionListener);
+      }
+      if (this.source == MapillaryHistoryDialog.this.redoTree) {
+        MapillaryHistoryDialog.this.undoTree.getSelectionModel()
+            .removeTreeSelectionListener(
+                MapillaryHistoryDialog.this.undoSelectionListener);
+        MapillaryHistoryDialog.this.undoTree.clearSelection();
+        MapillaryHistoryDialog.this.undoTree.getSelectionModel()
+            .addTreeSelectionListener(
+                MapillaryHistoryDialog.this.undoSelectionListener);
+      }
+    }
+  }
 }
Index: /applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/history/MapillaryRecord.java
===================================================================
--- /applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/history/MapillaryRecord.java	(revision 31494)
+++ /applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/history/MapillaryRecord.java	(revision 31495)
@@ -127,3 +127,11 @@
         lis.recordChanged();
   }
+
+  /**
+   * Resets the object to its start state.
+   */
+  public void reset() {
+    this.commandList.clear();
+    this.position = -1;
+  }
 }
Index: /applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/utils/MapillaryUtils.java
===================================================================
--- /applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/utils/MapillaryUtils.java	(revision 31494)
+++ /applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/utils/MapillaryUtils.java	(revision 31495)
@@ -8,8 +8,13 @@
 import java.net.URL;
 import java.util.ArrayList;
+import java.util.List;
+
+import javax.swing.SwingUtilities;
 
 import org.apache.commons.imaging.common.RationalNumber;
 import org.apache.commons.imaging.formats.tiff.constants.GpsTagConstants;
 import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.data.Bounds;
+import org.openstreetmap.josm.data.coor.LatLon;
 import org.openstreetmap.josm.plugins.mapillary.MapillaryAbstractImage;
 import org.openstreetmap.josm.plugins.mapillary.MapillaryData;
@@ -25,4 +30,7 @@
  */
 public class MapillaryUtils {
+
+  private static double MIN_ZOOM_SQUARE_SIDE = 0.002;
+
   /**
    * Updates the help text at the bottom of the window.
@@ -199,3 +207,63 @@
       MapillaryData.dataUpdated();
   }
+
+  /**
+   * Zooms to fit all the given {@link MapillaryAbstractImage} objects.
+   *
+   * @param images
+   *          The images your are zooming to.
+   * @param select
+   *          Whether the added images must be selected or not.
+   */
+  public static void showPictures(final List<MapillaryAbstractImage> images,
+      final boolean select) {
+    if (!SwingUtilities.isEventDispatchThread()) {
+      SwingUtilities.invokeLater(new Runnable() {
+        @Override
+        public void run() {
+          showPictures(images, select);
+        }
+      });
+    } else {
+      double minLat = 90;
+      double minLon = 180;
+      double maxLat = -90;
+      double maxLon = -180;
+      for (MapillaryAbstractImage img : images) {
+        if (img.getLatLon().lat() < minLat)
+          minLat = img.getLatLon().lat();
+        if (img.getLatLon().lon() < minLon)
+          minLon = img.getLatLon().lon();
+        if (img.getLatLon().lat() > maxLat)
+          maxLat = img.getLatLon().lat();
+        if (img.getLatLon().lon() > maxLon)
+          maxLon = img.getLatLon().lon();
+      }
+      Bounds zoomBounds = new Bounds(new LatLon(minLat, minLon), new LatLon(
+          maxLat, maxLon));
+      // The zoom rectangle must have a minimum size.
+      double latExtent = zoomBounds.getMaxLat() - zoomBounds.getMinLat() >= MIN_ZOOM_SQUARE_SIDE ? zoomBounds
+          .getMaxLat() - zoomBounds.getMinLat()
+          : MIN_ZOOM_SQUARE_SIDE;
+      double lonExtent = zoomBounds.getMaxLon() - zoomBounds.getMinLon() >= MIN_ZOOM_SQUARE_SIDE ? zoomBounds
+          .getMaxLon() - zoomBounds.getMinLon()
+          : MIN_ZOOM_SQUARE_SIDE;
+      zoomBounds = new Bounds(zoomBounds.getCenter(), latExtent, lonExtent);
+
+      Main.map.mapView.zoomTo(zoomBounds);
+      MapillaryLayer.getInstance().getData().setSelectedImage(null);
+      if (select)
+        MapillaryLayer.getInstance().getData().addMultiSelectedImage(images);
+      if (Main.main != null)
+        MapillaryData.dataUpdated();
+    }
+  }
+
+  /**
+   * Zooms to fit all the {@link MapillaryAbstractImage} objects stored in the
+   * database.
+   */
+  public static void showAllPictures() {
+    showPictures(MapillaryLayer.getInstance().getData().getImages(), false);
+  }
 }
