Index: /applications/editors/josm/plugins/MicrosoftStreetside/gradle.properties
===================================================================
--- /applications/editors/josm/plugins/MicrosoftStreetside/gradle.properties	(revision 34348)
+++ /applications/editors/josm/plugins/MicrosoftStreetside/gradle.properties	(revision 34349)
@@ -9,4 +9,5 @@
 # You can check if the plugin compiles against this version by executing `./gradlew minJosmVersionClasses`.
 plugin.main.version=13860
+plugin.version=13860
 # Version of JOSM against which the plugin is compiled
 # Please check, if the specified version is available for download from https://josm.openstreetmap.de/download/ .
Index: /applications/editors/josm/plugins/MicrosoftStreetside/ivy.xml
===================================================================
--- /applications/editors/josm/plugins/MicrosoftStreetside/ivy.xml	(revision 34348)
+++ /applications/editors/josm/plugins/MicrosoftStreetside/ivy.xml	(revision 34349)
@@ -1,5 +1,5 @@
 <ivy-module version="2.0">
 	<info organisation="org.openstreetmap.josm.plugins" module="MicrosoftStreetside" revision="0.0.1" />
-	<configurations defaultconf="default" defaultconfmapping="default->default,sources">
+	<configurations defaultconf="default" defaultconfmapping="default->default">
 			<conf name="default" />
 	</configurations>
Index: /applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/StreetsideData.java
===================================================================
--- /applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/StreetsideData.java	(revision 34348)
+++ /applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/StreetsideData.java	(revision 34349)
@@ -290,5 +290,5 @@
 		throw new IllegalStateException();
 	}
-    StreetsideAbstractImage tempImage = this.selectedImage;
+    StreetsideAbstractImage tempImage = selectedImage;
     while (tempImage.previous() != null) {
       tempImage = tempImage.previous();
Index: /applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/StreetsideImage.java
===================================================================
--- /applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/StreetsideImage.java	(revision 34348)
+++ /applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/StreetsideImage.java	(revision 34349)
@@ -2,7 +2,4 @@
 package org.openstreetmap.josm.plugins.streetside;
 
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
 import java.util.List;
 
@@ -10,7 +7,4 @@
 import org.openstreetmap.josm.plugins.streetside.cubemap.CubemapUtils;
 import org.openstreetmap.josm.plugins.streetside.model.UserProfile;
-import org.openstreetmap.josm.tools.Logging;
-
-import org.openstreetmap.josm.plugins.streetside.model.ImageDetection;
 
 /**
@@ -48,4 +42,7 @@
   private double pi;
 
+  // Heading (equivalent to Mapillary cd attribute - not currently supported.
+  private double he;
+
   // Blurring instructions - not currently used by the plugin
   private String bl;
@@ -62,7 +59,7 @@
   /**
    * Set of traffic signs in the image.
-   */
+   *//*
   private final List<ImageDetection> detections = Collections.synchronizedList(new ArrayList<>());
-
+*/
   /**
    * Main constructor of the class StreetsideImage
@@ -103,9 +100,9 @@
   }
 
-  public List<ImageDetection> getDetections() {
+  /*public List<ImageDetection> getDetections() {
     return detections;
-  }
-
-  public void setAllDetections(Collection<ImageDetection> newDetections) {
+  }*/
+
+  /*public void setAllDetections(Collection<ImageDetection> newDetections) {
     Logging.debug("Add {0} detections to image {1}", newDetections.size(), getId());
     synchronized (detections) {
@@ -113,5 +110,5 @@
       detections.addAll(newDetections);
     }
-  }
+  }*/
 
   public UserProfile getUser() {
@@ -122,4 +119,5 @@
   public String toString() {
     return String.format(
+      // TODO: format date cd (Gradle build error command line)
       "Image[id=%s,lat=%f,lon=%f,he=%f,user=%s]",
       id, latLon.lat(), latLon.lon(), he, "null"//, cd
Index: /applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/StreetsideLayer.java
===================================================================
--- /applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/StreetsideLayer.java	(revision 34348)
+++ /applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/StreetsideLayer.java	(revision 34349)
@@ -81,11 +81,12 @@
   ) / 3;
 
-  private static final DataSetListenerAdapter DATASET_LISTENER = new DataSetListenerAdapter(e -> {
-    if (e instanceof DataChangedEvent && StreetsideDownloader.getMode() == DOWNLOAD_MODE.OSM_AREA) {
-      // When more data is downloaded, a delayed update is thrown, in order to
-      // wait for the data bounds to be set.
-      MainApplication.worker.execute(StreetsideDownloader::downloadOSMArea);
-    }
-  });
+	private static final DataSetListenerAdapter DATASET_LISTENER =
+			new DataSetListenerAdapter(e -> {
+				if (e instanceof DataChangedEvent && StreetsideDownloader.getMode() == DOWNLOAD_MODE.OSM_AREA) {
+					// When more data is downloaded, a delayed update is thrown, in order to
+					// wait for the data bounds to be set.
+					MainApplication.worker.execute(StreetsideDownloader::downloadOSMArea);
+				}
+			});
 
 	/** Unique instance of the class. */
@@ -258,5 +259,5 @@
 
 
-  @Override
+	@Override
   public boolean isModified() {
     return data.getImages().parallelStream().anyMatch(StreetsideAbstractImage::isModified);
@@ -313,5 +314,4 @@
 
     // Draw sequence line
-    // TODO: reimplement sequence lines for Streetside
     /*g.setStroke(new BasicStroke(2));
     final StreetsideAbstractImage selectedImage = getData().getSelectedImage();
@@ -392,6 +392,6 @@
 
 
-		if (img instanceof StreetsideImage && !((StreetsideImage) img).getDetections().isEmpty()) {
-			Path2D trafficSign = new Path2D.Double();
+		/*if (img instanceof StreetsideImage && !((StreetsideImage) img).getDetections().isEmpty()) {
+			final Path2D trafficSign = new Path2D.Double();
 			trafficSign.moveTo(p.getX() - StreetsideLayer.TRAFFIC_SIGN_SIZE / 2d, p.getY() - StreetsideLayer.TRAFFIC_SIGN_HEIGHT_3RD);
 			trafficSign.lineTo(p.getX() + StreetsideLayer.TRAFFIC_SIGN_SIZE / 2d, p.getY() - StreetsideLayer.TRAFFIC_SIGN_HEIGHT_3RD);
@@ -403,5 +403,5 @@
 			g.setColor(Color.RED);
 			g.draw(trafficSign);
-		}
+		}*/
 	}
 
Index: /applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/StreetsidePlugin.java
===================================================================
--- /applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/StreetsidePlugin.java	(revision 34348)
+++ /applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/StreetsidePlugin.java	(revision 34349)
@@ -26,6 +26,4 @@
 import org.openstreetmap.josm.tools.ImageProvider;
 
-import org.openstreetmap.josm.plugins.streetside.gui.StreetsideChangesetDialog;
-
 /**
  * This is the main class of the Streetside plugin.
@@ -50,4 +48,5 @@
       MainMenu.add(MainApplication.getMenu().dataMenu, new StreetsideJoinAction(), false);
       MainMenu.add(MainApplication.getMenu().moreToolsMenu, WALK_ACTION, false);
+      //MainMenu.add(MainApplication.getMenu().imagerySubMenu, new MapObjectLayerAction(), false);
       //MainMenu.add(MainApplication.getMenu().imagerySubMenu, new MapObjectLayerAction(), false);
     }
@@ -76,5 +75,5 @@
    * @return the {@link StreetsideWalkAction} for the plugin
    */
-  public static StreetsideWalkAction getWalkAction() {
+  public static StreetsideWalkAction getStreetsideWalkAction() {
     return WALK_ACTION;
   }
@@ -92,5 +91,5 @@
       MainApplication.getMap().addToggleDialog(StreetsideViewerDialog.getInstance(), false);
       //MainApplication.getMap().addToggleDialog(StreetsideHistoryDialog.getInstance(), false);
-      MainApplication.getMap().addToggleDialog(StreetsideChangesetDialog.getInstance(), false);
+      //MainApplication.getMap().addToggleDialog(StreetsideChangesetDialog.getInstance(), false);
       //MainApplication.getMap().addToggleDialog(StreetsideFilterDialog.getInstance(), false);
     }
@@ -98,5 +97,5 @@
       StreetsideMainDialog.destroyInstance();
       //StreetsideHistoryDialog.destroyInstance();
-      StreetsideChangesetDialog.destroyInstance();
+      //StreetsideChangesetDialog.destroyInstance();
       //StreetsideFilterDialog.destroyInstance();
       ImageInfoPanel.destroyInstance();
@@ -132,7 +131,6 @@
    * @return the {@link StreetsideZoomAction} for the plugin
    */
-  public static StreetsideZoomAction getZoomAction() {
+  /*public static StreetsideZoomAction getZoomAction() {
     return ZOOM_ACTION;
+  }*/
   }
-
-}
Index: /applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/actions/StreetsideDownloadAction.java
===================================================================
--- /applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/actions/StreetsideDownloadAction.java	(revision 34348)
+++ /applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/actions/StreetsideDownloadAction.java	(revision 34349)
@@ -47,5 +47,9 @@
   @Override
   public void actionPerformed(ActionEvent ae) {
-    if (!StreetsideLayer.hasInstance() || !MainApplication.getLayerManager().containsLayer(StreetsideLayer.getInstance())) {
+    if (!StreetsideLayer.hasInstance()) {
+      // A new streetside layer is created, so the active layer is not changed
+      StreetsideLayer.getInstance();
+      return;
+    } else if (!MainApplication.getLayerManager().containsLayer(StreetsideLayer.getInstance())) {
       MainApplication.getLayerManager().addLayer(StreetsideLayer.getInstance());
       return;
Index: /applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/actions/StreetsideDownloadViewAction.java
===================================================================
--- /applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/actions/StreetsideDownloadViewAction.java	(revision 34348)
+++ /applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/actions/StreetsideDownloadViewAction.java	(revision 34349)
@@ -26,4 +26,5 @@
 
   private static final long serialVersionUID = 6738276777802831669L;
+
   private static final String DESCRIPTION = I18n.marktr("Download Streetside images in current view");
 
Index: /applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/actions/StreetsideExportAction.java
===================================================================
--- /applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/actions/StreetsideExportAction.java	(revision 34348)
+++ /applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/actions/StreetsideExportAction.java	(revision 34349)
@@ -63,6 +63,6 @@
     cancel.addActionListener(e -> pane.setValue(JOptionPane.CANCEL_OPTION));
 
-    this.dialog = new StreetsideExportDialog(ok);
-    pane.setMessage(this.dialog);
+    dialog = new StreetsideExportDialog(ok);
+    pane.setMessage(dialog);
     pane.setOptions(new JButton[] {ok, cancel});
 
@@ -74,8 +74,8 @@
     if (pane.getValue() != null
         && (int) pane.getValue() == JOptionPane.OK_OPTION
-        && this.dialog.chooser != null) {
-      if (this.dialog.group.isSelected(this.dialog.all.getModel())) {
+        && dialog.chooser != null) {
+      if (dialog.group.isSelected(dialog.all.getModel())) {
         export(StreetsideLayer.getInstance().getData().getImages());
-      } else if (this.dialog.group.isSelected(this.dialog.sequence.getModel())) {
+      } else if (dialog.group.isSelected(dialog.sequence.getModel())) {
         Set<StreetsideAbstractImage> images = new ConcurrentSkipListSet<>();
         for (StreetsideAbstractImage image : StreetsideLayer.getInstance().getData().getMultiSelectedImages()) {
@@ -89,9 +89,9 @@
         }
         export(images);
-      } else if (this.dialog.group.isSelected(dialog.selected.getModel())) {
+      } else if (dialog.group.isSelected(dialog.selected.getModel())) {
         export(StreetsideLayer.getInstance().getData().getMultiSelectedImages());
       }
       // This option ignores the selected directory.
-    } else if (this.dialog.group.isSelected(dialog.rewrite.getModel())) {
+    } else if (dialog.group.isSelected(dialog.rewrite.getModel())) {
       ArrayList<StreetsideImportedImage> images = new ArrayList<>();
       StreetsideLayer.getInstance().getData().getImages().stream().filter(img -> img instanceof StreetsideImportedImage).forEach(img -> images.add((StreetsideImportedImage) img));
@@ -113,5 +113,5 @@
   public void export(Set<StreetsideAbstractImage> images) {
     MainApplication.worker.execute(new StreetsideExportManager(images,
-        this.dialog.chooser.getSelectedFile().toString()));
+        dialog.chooser.getSelectedFile().toString()));
   }
 
Index: /applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/actions/StreetsideWalkAction.java
===================================================================
--- /applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/actions/StreetsideWalkAction.java	(revision 34348)
+++ /applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/actions/StreetsideWalkAction.java	(revision 34349)
@@ -55,5 +55,5 @@
     if (pane.getValue() != null
         && (int) pane.getValue() == JOptionPane.OK_OPTION) {
-      this.thread = new WalkThread((int) dialog.spin.getValue(),
+      thread = new WalkThread((int) dialog.spin.getValue(),
           dialog.waitForPicture.isSelected(),
           dialog.followSelection.isSelected(), dialog.goForward.isSelected());
@@ -76,5 +76,5 @@
    */
   public void addListener(WalkListener lis) {
-    this.listeners.add(lis);
+    listeners.add(lis);
   }
 
@@ -86,13 +86,13 @@
    */
   public void removeListener(WalkListener lis) {
-    this.listeners.remove(lis);
+    listeners.remove(lis);
   }
 
   private void fireWalkStarted() {
-    if (this.listeners.isEmpty()) {
+    if (listeners.isEmpty()) {
       return;
     }
-    for (WalkListener lis : this.listeners) {
-      lis.walkStarted(this.thread);
+    for (WalkListener lis : listeners) {
+      lis.walkStarted(thread);
     }
   }
Index: /applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/actions/StreetsideZoomAction.java
===================================================================
--- /applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/actions/StreetsideZoomAction.java	(revision 34348)
+++ /applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/actions/StreetsideZoomAction.java	(revision 34349)
@@ -6,9 +6,10 @@
 import java.awt.event.ActionEvent;
 
+import org.openstreetmap.josm.plugins.streetside.StreetsideLayer;
+
 import org.openstreetmap.josm.actions.JosmAction;
 import org.openstreetmap.josm.gui.MainApplication;
 import org.openstreetmap.josm.plugins.streetside.StreetsideAbstractImage;
 import org.openstreetmap.josm.plugins.streetside.StreetsideDataListener;
-import org.openstreetmap.josm.plugins.streetside.StreetsideLayer;
 import org.openstreetmap.josm.plugins.streetside.StreetsidePlugin;
 import org.openstreetmap.josm.tools.ImageProvider;
Index: /applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/actions/WalkThread.java
===================================================================
--- /applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/actions/WalkThread.java	(revision 34348)
+++ /applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/actions/WalkThread.java	(revision 34349)
@@ -2,19 +2,16 @@
 package org.openstreetmap.josm.plugins.streetside.actions;
 
+import java.awt.image.BufferedImage;
+
 import javax.swing.SwingUtilities;
 
-import org.openstreetmap.josm.gui.Notification;
 import org.openstreetmap.josm.plugins.streetside.StreetsideAbstractImage;
 import org.openstreetmap.josm.plugins.streetside.StreetsideData;
 import org.openstreetmap.josm.plugins.streetside.StreetsideDataListener;
+import org.openstreetmap.josm.plugins.streetside.StreetsideImage;
 import org.openstreetmap.josm.plugins.streetside.StreetsideLayer;
-import org.openstreetmap.josm.plugins.streetside.StreetsidePlugin;
 import org.openstreetmap.josm.plugins.streetside.cache.CacheUtils;
-import org.openstreetmap.josm.plugins.streetside.cache.StreetsideCache;
 import org.openstreetmap.josm.plugins.streetside.gui.StreetsideMainDialog;
-import org.openstreetmap.josm.tools.I18n;
-import org.openstreetmap.josm.tools.Logging;
-
-import org.openstreetmap.josm.plugins.streetside.StreetsideImage;
+
 
 /**
@@ -30,4 +27,5 @@
   private final boolean followSelected;
   private final boolean goForward;
+  private BufferedImage lastImage;
   private volatile boolean paused;
 
@@ -54,29 +52,31 @@
   public void run() {
     try {
-      StreetsideAbstractImage curSelection;
-      StreetsideImage curImage;
-      while (
-          !end &&
-          (curSelection = data.getSelectedImage().next()) != null &&
-          (curImage = curSelection instanceof StreetsideImage ? (StreetsideImage) curSelection : null) != null
-      ) {
-        // Predownload next 10 thumbnails.
-        preDownloadImages(curImage, 10, CacheUtils.PICTURE.THUMBNAIL, goForward);
-        if (waitForFullQuality) {
-          // Start downloading 3 next full images.
-          preDownloadImages(curImage, 3, CacheUtils.PICTURE.FULL_IMAGE, goForward);
+      while (!end && data.getSelectedImage().next() != null) {
+        StreetsideAbstractImage image = data.getSelectedImage();
+        if (image != null && image.next() instanceof StreetsideImage) {
+          // Predownload next 10 thumbnails.
+          preDownloadImages((StreetsideImage) image.next(), 10, CacheUtils.PICTURE.THUMBNAIL);
+          // TODO: WalkThread for cubemaps? @rrh
+      	  //preDownloadCubemaps((StreetsideImage) image.next(), 10, CacheUtils.PICTURE.CUBEMAP);
+          if (waitForFullQuality) {
+            // Start downloading 3 next full images.
+            StreetsideAbstractImage currentImage = image.next();
+        	preDownloadImages((StreetsideImage) currentImage, 3, CacheUtils.PICTURE.FULL_IMAGE);
+        	// TODO: WalkThread for cubemaps? @rrh
+        	/*if (StreetsideProperties.PREDOWNLOAD_CUBEMAPS.get().booleanValue()) {
+          	  preDownloadCubemaps((StreetsideImage) currentImage, 3, CacheUtils.PICTURE.CUBEMAP);
+            }*/
+          }
         }
         try {
-          // Wait for picture for 1 minute.
-          final StreetsideCache cache = new StreetsideCache(curImage.getId(), waitForFullQuality ? StreetsideCache.Type.FULL_IMAGE : StreetsideCache.Type.THUMBNAIL);
-          int limit = 240; // 240 * 250 = 60000 ms
-          while (cache.get() == null) {
-            Thread.sleep(250);
-            if (limit-- < 0) {
-              new Notification(I18n.tr("Walk mode: Waiting for next image takes too long! Exiting walk mode…"))
-                  .setIcon(StreetsidePlugin.LOGO.get())
-                  .show();
-              end();
-              return;
+          // Waits for full quality picture.
+          final BufferedImage displayImage = StreetsideMainDialog.getInstance().getStreetsideImageDisplay().getImage();
+          if (waitForFullQuality && image instanceof StreetsideImage) {
+            while (displayImage == lastImage || displayImage == null || displayImage.getWidth() < 2048) {
+              Thread.sleep(100);
+            }
+          } else { // Waits for thumbnail.
+            while (displayImage == lastImage || displayImage == null || displayImage.getWidth() < 320) {
+              Thread.sleep(100);
             }
           }
@@ -84,8 +84,9 @@
             Thread.sleep(100);
           }
-          Thread.sleep(interval);
+          wait(interval);
           while (paused) {
             Thread.sleep(100);
           }
+          lastImage = StreetsideMainDialog.getInstance().getStreetsideImageDisplay().getImage();
           if (goForward) {
             data.selectNext(followSelected);
@@ -94,12 +95,52 @@
           }
         } catch (InterruptedException e) {
-          end();
           return;
         }
-
       }
+
+    	// TODO: WalkThread for cubemaps? @rrh
+      	/*while (!end && data.getSelectedImage().next() != null) {
+            StreetsideAbstractImage cubemap = data.getSelectedImage();
+            if (cubemap != null && cubemap.next() instanceof StreetsideCubemap) {
+              if (waitForFullQuality) {
+                // Start downloading 3 next full images.
+
+            	// TODO: cubemap handling @rrh
+            	preDownloadCubemaps((StreetsideCubemap) cubemap.next(), 6, CacheUtils.PICTURE.CUBEMAP);
+              }
+            }
+            try {
+              // Waits for full quality picture.
+              final BufferedImage[] displayCubemap = StreetsideMainDialog.getInstance().streetsideViewerDisplay.getCubemap();
+              if (waitForFullQuality && cubemap instanceof StreetsideCubemap) {
+                  // TODO: handle cubemap width? @rrh
+            	  while (displayCubemap == lastCubemap || displayCubemap == null || displayCubemap.getWidth() < 2048) {
+                  Thread.sleep(100);
+                }
+              } else { // Waits for thumbnail.
+            	  // TODO: handle cubemap width? @rrh
+            	  while (displayCubemap == lastCubemap || displayCubemap == null || displayCubemap.getWidth() < 320) {
+                  Thread.sleep(100);
+                }
+              }
+              while (paused) {
+                Thread.sleep(100);
+              }
+              wait(interval);
+              while (paused) {
+                Thread.sleep(100);
+              }
+              lastCubemap = StreetsideMainDialog.getInstance().streetsideViewerDisplay.getCubemap();
+              // TODO: forward / previous for cubemap? @rrh
+              if (goForward) {
+                data.selectNext(followSelected);
+              } else {
+                data.selectPrevious(followSelected);
+              }
+            } catch (InterruptedException e) {
+              return;
+            }
+          }*/
     } catch (NullPointerException e) {
-      Logging.warn(e);
-      end();
       // TODO: Avoid NPEs instead of waiting until they are thrown and then catching them
       return;
@@ -108,5 +149,22 @@
   }
 
-  /**
+  private void preDownloadCubemaps(StreetsideImage startImage, int n, CacheUtils.PICTURE type) {
+	  if (n >= 1 && startImage != null) {
+
+		  for (int i = 0; i < 6; i++) {
+				for (int j = 0; j < 4; j++) {
+					for (int k = 0; k < 4; k++) {
+
+						CacheUtils.downloadPicture(startImage, type);
+						if (startImage.next() instanceof StreetsideImage && n >= 2) {
+							preDownloadImages((StreetsideImage) startImage.next(), n - 1, type);
+						}
+					}
+				}
+		  }
+	  }
+  }
+
+/**
    * Downloads n images into the cache beginning from the supplied start-image (including the start-image itself).
    *
@@ -114,12 +172,10 @@
    * @param n the number of images to download
    * @param type the quality of the image (full or thumbnail)
-   * @param goForward true if the next images, false if the previous ones should be downloaded
-   */
-  private static void preDownloadImages(StreetsideImage startImage, int n, CacheUtils.PICTURE type, final boolean goForward) {
+   */
+  private static void preDownloadImages(StreetsideImage startImage, int n, CacheUtils.PICTURE type) {
     if (n >= 1 && startImage != null) {
       CacheUtils.downloadPicture(startImage, type);
-      final StreetsideAbstractImage nextImg = goForward ? startImage.next() : startImage.previous();
-      if (nextImg instanceof StreetsideImage && n >= 2) {
-        preDownloadImages((StreetsideImage) nextImg, n - 1, type, goForward);
+      if (startImage.next() instanceof StreetsideImage && n >= 2) {
+        preDownloadImages((StreetsideImage) startImage.next(), n - 1, type);
       }
     }
@@ -168,5 +224,5 @@
    * Called when the walk stops by itself of forcefully.
    */
-  private void end() {
+  public void end() {
     if (SwingUtilities.isEventDispatchThread()) {
       end = true;
@@ -176,4 +232,12 @@
       SwingUtilities.invokeLater(this::end);
     }
+    // TODO: WalkThread for Cubemaps? @rrh
+    /*if (Platform.isEventDispatchThread()) {
+        end = true;
+        data.removeListener(this);
+        StreetsideViewerDialog.getInstance().setMode(StreetsideViewerDialog.MODE.NORMAL);
+      } else {
+        Platform.invokeLater(this::end);
+      }*/
   }
 }
Index: /applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/cache/package-info.java
===================================================================
--- /applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/cache/package-info.java	(revision 34348)
+++ /applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/cache/package-info.java	(revision 34349)
@@ -2,5 +2,5 @@
 /**
  * This package is all about caching resources downloaded from
- * <a href="https://www.microsoft.com/en-us/maps/streetside">Streetside</a>
+ * <a href="https://mapillary.com">mapillary.com</a>
  * for faster access to those resources in the future.
  */
Index: /applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/cubemap/CubemapBuilder.java
===================================================================
--- /applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/cubemap/CubemapBuilder.java	(revision 34348)
+++ /applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/cubemap/CubemapBuilder.java	(revision 34349)
@@ -44,26 +44,26 @@
 	}
 
-  @Override
-  public void selectedImageChanged(StreetsideAbstractImage oldImage, StreetsideAbstractImage newImage) {
-    startTime = System.nanoTime();
-
-    if (newImage != null) {
-
-      cubemap = null;
-      cubemap = new StreetsideCubemap(newImage.getId(), newImage.getLatLon(), newImage.getHe());
-      cubemap.setCd(newImage.getCd());
-
-      // download cubemap images in different threads and then subsequently
-      // set the cubeface images in JavaFX
-      downloadCubemapImages(cubemap.getId());
-    }
-  }
-
-  public void reload(String imageId) {
-    if (cubemap != null && imageId.equals(cubemap.getId())) {
-      CubemapBuilder.getInstance().getCubemap().resetFaces2TileMap();
-      downloadCubemapImages(imageId);
-    }
-  }
+	@Override
+	public void selectedImageChanged(StreetsideAbstractImage oldImage, StreetsideAbstractImage newImage) {
+		startTime = System.currentTimeMillis();
+
+		if (newImage != null) {
+
+			cubemap = null;
+			cubemap = new StreetsideCubemap(newImage.getId(), newImage.getLatLon(), newImage.getHe());
+			cubemap.setCd(newImage.getCd());
+
+			// download cubemap images in different threads and then subsequently
+			// set the cubeface images in JavaFX
+			downloadCubemapImages(cubemap.getId());
+		}
+	}
+
+	public void reload(String imageId) {
+		if (cubemap != null && imageId.equals(cubemap.getId())) {
+			CubemapBuilder.getInstance().getCubemap().resetFaces2TileMap();
+			downloadCubemapImages(imageId);
+		}
+	}
 
 	public void downloadCubemapImages(String imageId) {
@@ -75,5 +75,5 @@
 		int fails = 0;
 
-		long startTime = System.nanoTime();
+		long startTime = System.currentTimeMillis();
 
 		try {
@@ -102,6 +102,6 @@
 				for (Future<String> ff : results) {
 
-					Logging.info(I18n.tr("Completed tile downloading task {0} in {1}", ff.get(),
-							CubemapUtils.msToString(startTime - System.nanoTime())));
+					Logging.debug(I18n.tr("Completed tile downloading task {0} in {1}", ff.get(),
+							CubemapUtils.msToString(startTime - System.currentTimeMillis())));
 				}
 
@@ -115,5 +115,5 @@
 									+ String.valueOf(Integer.valueOf(j).toString() + Integer.valueOf(k).toString()));
 							tasks.add(new TileDownloadingTask(tileId));
-							Logging.info(
+							Logging.debug(
 									I18n.tr("Starting tile downloading task for imageId {0}, cubeface {1}, tileID {2}",
 											imageId, CubemapUtils.getFaceNumberForCount(i), tileId));
@@ -124,6 +124,6 @@
 				List<Future<String>> results = pool.invokeAll(tasks);
 				for (Future<String> ff : results) {
-					Logging.debug(I18n.tr("Completed tile downloading task {0} in {1}", ff.get(),
-							CubemapUtils.msToString(startTime - System.nanoTime())));
+					Logging.info(I18n.tr("Completed tile downloading task {0} in {1}", ff.get(),
+							CubemapUtils.msToString(startTime - System.currentTimeMillis())));
 				}
 			}
@@ -134,8 +134,8 @@
 		}
 
-		long stopTime = System.nanoTime();
+		long stopTime = System.currentTimeMillis();
 		long runTime = stopTime - startTime;
 
-		Logging.info(I18n.tr("Imagery downloading tasks completed for all tiles in {0} seconds.", runTime % 1000));
+		Logging.info(I18n.tr("Tile imagery downloading tasks completed in {0}", CubemapUtils.msToString(runTime)));
 
 		if (fails > 0) {
@@ -164,10 +164,10 @@
 
 		if (tileCount == (CubemapUtils.NUM_SIDES * maxCols * maxRows)) {
-			Logging.debug(I18n.tr("{0} tile images ready for building cumbemap faces for cubemap {0}", tileCount,
+			Logging.info(I18n.tr("{0} tile images ready for building cumbemap faces for cubemap {0}", tileCount,
 					CubemapBuilder.getInstance().getCubemap().getId()));
 
 			buildCubemapFaces();
 		} else {
-			Logging.debug(I18n.tr("{0} tile images received for cubemap {1}", Integer.valueOf(tileCount).toString(),
+			Logging.info(I18n.tr("{0} tile images received for cubemap {1}", Integer.valueOf(tileCount).toString(),
 					CubemapBuilder.getInstance().getCubemap().getId()));
 		}
@@ -246,8 +246,8 @@
 		StreetsideViewerPanel.getThreeSixtyDegreeViewerPanel().repaint();
 
-		long endTime = System.nanoTime();
+		long endTime = System.currentTimeMillis();
 		long runTime = endTime - startTime;
 		Logging.info(I18n.tr("Completed downloading, assembling and setting cubemap imagery for cubemap {0} in {1}",
-				cubemap.getId(), runTime));
+				cubemap.getId(), CubemapUtils.msToString(runTime)));
 	}
 
Index: /applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/cubemap/GraphicsUtils.java
===================================================================
--- /applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/cubemap/GraphicsUtils.java	(revision 34348)
+++ /applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/cubemap/GraphicsUtils.java	(revision 34349)
@@ -44,56 +44,64 @@
 		BufferedImage res = null;
 
-		int pixelBuffer = StreetsideProperties.SHOW_HIGH_RES_STREETSIDE_IMAGERY.get() ? 2 : 1;
+		int pixelBuffer = StreetsideProperties.SHOW_HIGH_RES_STREETSIDE_IMAGERY.get()?2:1;
 
 		tiles = cropMultiTiledImages(tiles, pixelBuffer);
 
-		int rows = StreetsideProperties.SHOW_HIGH_RES_STREETSIDE_IMAGERY.get() ? 4 : 2; // we assume the no. of rows and
-																						// cols are known and each chunk
-																						// has
-																						// equal width and height
-		int cols = StreetsideProperties.SHOW_HIGH_RES_STREETSIDE_IMAGERY.get() ? 4 : 2;
+		int rows = StreetsideProperties.SHOW_HIGH_RES_STREETSIDE_IMAGERY.get()?4:2; //we assume the no. of rows and cols are known and each chunk has equal width and height
+        int cols = StreetsideProperties.SHOW_HIGH_RES_STREETSIDE_IMAGERY.get()?4:2;
 
-		int chunkWidth, chunkHeight;
+        int chunkWidth, chunkHeight;
 
-		chunkWidth = tiles[0].getWidth();
-		chunkHeight = tiles[0].getHeight();
+        chunkWidth = tiles[0].getWidth();
+        chunkHeight = tiles[0].getHeight();
 
-		// Initializing the final image
-		BufferedImage img = new BufferedImage(chunkWidth * cols, chunkHeight * rows, BufferedImage.TYPE_INT_ARGB);
+        //Initializing the final image
+        BufferedImage img = new BufferedImage(chunkWidth*cols, chunkHeight*rows, BufferedImage.TYPE_INT_ARGB);
 
-		int num = 0;
-		for (int i = 0; i < rows; i++) {
-			for (int j = 0; j < cols; j++) {
-				// TODO: mirror image
-				img.createGraphics().drawImage(tiles[num], chunkWidth * j, chunkHeight * i, null);
+        int num = 0;
+        for (int i = 0; i < rows; i++) {
+            for (int j = 0; j < cols; j++) {
+                // TODO: this makes the image a mirror image. why!?!
+            	img.createGraphics().drawImage(tiles[num], chunkWidth * j, chunkHeight * i, null);
 
-				int width = StreetsideProperties.SHOW_HIGH_RES_STREETSIDE_IMAGERY.get() ? 1014 : 510;
-				int height = StreetsideProperties.SHOW_HIGH_RES_STREETSIDE_IMAGERY.get() ? 1014 : 510;
+            	// TODO: remove file test!
+            	/*try {
+        			ImageIO.write(img, "jpeg", new File("/Users/renerr18/Desktop/TileImagesTest/tile16b" + Long.valueOf(System.currentTimeMillis()).toString() + "createGraphicsAfter.jpeg"));
+        			//ImageIO.write(res[i], "jpeg", outputfileAfter);
+        		} catch (IOException e) {
+        			// TODO Auto-generated catch block
+        			e.printStackTrace();
+        		}*/
 
-				res = new BufferedImage(StreetsideProperties.SHOW_HIGH_RES_STREETSIDE_IMAGERY.get() ? 1014 : 510,
-						StreetsideProperties.SHOW_HIGH_RES_STREETSIDE_IMAGERY.get() ? 1014 : 510,
-						BufferedImage.TYPE_INT_ARGB);
+                int width = StreetsideProperties.SHOW_HIGH_RES_STREETSIDE_IMAGERY.get()?1014:510;
+                int height = StreetsideProperties.SHOW_HIGH_RES_STREETSIDE_IMAGERY.get()?1014:510;
 
-				// Create mirror image pixel by pixel
-				for (int y = 0; y < height; y++) {
-					for (int lx = 0, rx = width - 1; lx < width; lx++, rx--) {
-						// lx starts from the left side of the image
-						// rx starts from the right side of the image
-						// lx is used since we are getting pixel from left side
-						// rx is used to set from right side
-						// get source pixel value
-						int p = img.getRGB(lx, y);
+                // BufferedImage for mirror image
+                res = new BufferedImage(StreetsideProperties.SHOW_HIGH_RES_STREETSIDE_IMAGERY.get()?1014:510, StreetsideProperties.SHOW_HIGH_RES_STREETSIDE_IMAGERY.get()?1014:510,
+                                                BufferedImage.TYPE_INT_ARGB);
 
-						// set mirror image pixel value
-						res.setRGB(rx, y, p);
-					}
-				}
-				num++;
-			}
-		}
+                // Create mirror image pixel by pixel
+                for (int y = 0; y < height; y++)
+                {
+                    for (int lx = 0, rx = width - 1; lx < width; lx++, rx--)
+                    {
+                        // lx starts from the left side of the image
+                        // rx starts from the right side of the image
+                        // lx is used since we are getting pixel from left side
+                        // rx is used to set from right side
+                        // get source pixel value
+                        int p = img.getRGB(lx, y);
 
-		Logging.debug("Image concatenated.....");
+                        // set mirror image pixel value
+                        res.setRGB(rx, y, p);
+                    }
+                }
+                num++;
+            }
+        }
 
-		return res;
+        Logging.info("Image concatenated.....");
+
+        return res;
 	}
 
Index: /applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/cubemap/TileDownloadingTask.java
===================================================================
--- /applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/cubemap/TileDownloadingTask.java	(revision 34348)
+++ /applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/cubemap/TileDownloadingTask.java	(revision 34349)
@@ -22,5 +22,5 @@
 
 	private String tileId;
-	private final long startTime = System.nanoTime();
+	private final long startTime = System.currentTimeMillis();
 	private StreetsideCache cache;
 	protected CubemapBuilder cb;
@@ -120,7 +120,7 @@
 		fireTileAdded(tileId);
 
-		long endTime = System.nanoTime();
-		long runTime = endTime - startTime;
-		Logging.info("Loaded image for tile {0} in {1} seconds", tileId, runTime);
+		long endTime = System.currentTimeMillis();
+		long runTime = startTime - endTime;
+		Logging.debug("Loaded image for tile {0} in {1} seconds", tileId, CubemapUtils.msToString(runTime));
 
 		return tileId;
Index: /applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/gui/StreetsideExportDialog.java
===================================================================
--- /applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/gui/StreetsideExportDialog.java	(revision 34348)
+++ /applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/gui/StreetsideExportDialog.java	(revision 34349)
@@ -134,5 +134,6 @@
 
     private static final long serialVersionUID = 1035332841101190301L;
-    private String lastPath;
+
+	private String lastPath;
     private final StreetsideExportDialog dlg;
 
Index: /applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/gui/StreetsideImageDisplay.java
===================================================================
--- /applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/gui/StreetsideImageDisplay.java	(revision 34348)
+++ /applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/gui/StreetsideImageDisplay.java	(revision 34349)
@@ -39,6 +39,4 @@
  *
  * @author nokutu
- * @author renerr18
- * 
  * @see StreetsideImageDisplay
  * @see StreetsideMainDialog
@@ -82,5 +80,5 @@
         visibleRect = StreetsideImageDisplay.this.visibleRect;
       }
-      this.mouseIsDragging = false;
+      mouseIsDragging = false;
       selectedRect = null;
       if (image != null && Math.min(getSize().getWidth(), getSize().getHeight()) > 0) {
@@ -91,7 +89,7 @@
         // borders, this point is not calculated
         // again if there was less than 1.5seconds since the last event.
-        if (e.getWhen() - this.lastTimeForMousePoint > 1500 || this.mousePointInImg == null) {
-          this.lastTimeForMousePoint = e.getWhen();
-          this.mousePointInImg = comp2imgCoord(visibleRect, e.getX(), e.getY());
+        if (e.getWhen() - lastTimeForMousePoint > 1500 || mousePointInImg == null) {
+          lastTimeForMousePoint = e.getWhen();
+          mousePointInImg = comp2imgCoord(visibleRect, e.getX(), e.getY());
         }
         // Set the zoom to the visible rectangle in image coordinates
@@ -123,7 +121,7 @@
         // cursor doesn't move on the image.
         Rectangle drawRect = calculateDrawImageRectangle(visibleRect);
-        visibleRect.x = this.mousePointInImg.x
+        visibleRect.x = mousePointInImg.x
             + ((drawRect.x - e.getX()) * visibleRect.width) / drawRect.width;
-        visibleRect.y = this.mousePointInImg.y
+        visibleRect.y = mousePointInImg.y
             + ((drawRect.y - e.getY()) * visibleRect.height) / drawRect.height;
         // The position is also limited by the image size
@@ -187,6 +185,6 @@
     public void mousePressed(MouseEvent e) {
       if (getImage() == null) {
-        this.mouseIsDragging = false;
-       StreetsideImageDisplay.this.selectedRect = null;
+        mouseIsDragging = false;
+        selectedRect = null;
         return;
       }
@@ -200,16 +198,16 @@
         return;
       if (e.getButton() == StreetsideProperties.PICTURE_DRAG_BUTTON.get()) {
-        this.mousePointInImg = comp2imgCoord(visibleRect, e.getX(), e.getY());
-        this.mouseIsDragging = true;
-        StreetsideImageDisplay.this.selectedRect = null;
+        mousePointInImg = comp2imgCoord(visibleRect, e.getX(), e.getY());
+        mouseIsDragging = true;
+        selectedRect = null;
       } else if (e.getButton() == StreetsideProperties.PICTURE_ZOOM_BUTTON.get()) {
         mousePointInImg = comp2imgCoord(visibleRect, e.getX(), e.getY());
-        checkPointInVisibleRect(this.mousePointInImg, visibleRect);
-        this.mouseIsDragging = false;
-        StreetsideImageDisplay.this.selectedRect = new Rectangle(mousePointInImg.x, mousePointInImg.y, 0, 0);
+        checkPointInVisibleRect(mousePointInImg, visibleRect);
+        mouseIsDragging = false;
+        selectedRect = new Rectangle(mousePointInImg.x, mousePointInImg.y, 0, 0);
         StreetsideImageDisplay.this.repaint();
       } else {
-        this.mouseIsDragging = false;
-        StreetsideImageDisplay.this.selectedRect = null;
+        mouseIsDragging = false;
+        selectedRect = null;
       }
     }
@@ -217,5 +215,5 @@
     @Override
     public void mouseDragged(MouseEvent e) {
-      if (!this.mouseIsDragging && StreetsideImageDisplay.this.selectedRect == null)
+      if (!mouseIsDragging && selectedRect == null)
         return;
       Image image;
@@ -226,12 +224,12 @@
       }
       if (image == null) {
-        this.mouseIsDragging = false;
-        StreetsideImageDisplay.this.selectedRect = null;
+        mouseIsDragging = false;
+        selectedRect = null;
         return;
       }
-      if (this.mouseIsDragging) {
+      if (mouseIsDragging) {
         Point p = comp2imgCoord(visibleRect, e.getX(), e.getY());
-        visibleRect.x += this.mousePointInImg.x - p.x;
-        visibleRect.y += this.mousePointInImg.y - p.y;
+        visibleRect.x += mousePointInImg.x - p.x;
+        visibleRect.y += mousePointInImg.y - p.y;
         checkVisibleRectPos(image, visibleRect);
         synchronized (StreetsideImageDisplay.this) {
@@ -239,16 +237,16 @@
         }
         StreetsideImageDisplay.this.repaint();
-      } else if (StreetsideImageDisplay.this.selectedRect != null) {
+      } else if (selectedRect != null) {
         Point p = comp2imgCoord(visibleRect, e.getX(), e.getY());
         checkPointInVisibleRect(p, visibleRect);
-        Rectangle rect = new Rectangle(p.x < this.mousePointInImg.x ? p.x
-            : this.mousePointInImg.x, p.y < this.mousePointInImg.y ? p.y
-            : this.mousePointInImg.y, p.x < this.mousePointInImg.x ? this.mousePointInImg.x
-            - p.x : p.x - this.mousePointInImg.x,
-            p.y < this.mousePointInImg.y ? this.mousePointInImg.y - p.y : p.y
-                - this.mousePointInImg.y);
+        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);
-        StreetsideImageDisplay.this.selectedRect = rect;
+        selectedRect = rect;
         StreetsideImageDisplay.this.repaint();
       }
@@ -257,5 +255,5 @@
     @Override
     public void mouseReleased(MouseEvent e) {
-      if (!this.mouseIsDragging && StreetsideImageDisplay.this.selectedRect == null)
+      if (!mouseIsDragging && selectedRect == null)
         return;
       Image image;
@@ -264,42 +262,42 @@
       }
       if (image == null) {
-        this.mouseIsDragging = false;
-        StreetsideImageDisplay.this.selectedRect = null;
+        mouseIsDragging = false;
+        selectedRect = null;
         return;
       }
-      if (this.mouseIsDragging) {
-        this.mouseIsDragging = false;
-      } else if (StreetsideImageDisplay.this.selectedRect != null) {
-        int oldWidth = StreetsideImageDisplay.this.selectedRect.width;
-        int oldHeight = StreetsideImageDisplay.this.selectedRect.height;
+      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 (StreetsideImageDisplay.this.selectedRect.width < getSize().width / 2) {
-        	StreetsideImageDisplay.this.selectedRect.width = getSize().width / 2;
-        }
-        if (StreetsideImageDisplay.this.selectedRect.height < getSize().height / 2) {
-        	StreetsideImageDisplay.this.selectedRect.height = getSize().height / 2;
+        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 = StreetsideImageDisplay.this.selectedRect.height * getSize().width;
-        int wFact = StreetsideImageDisplay.this.selectedRect.width * getSize().height;
+        int hFact = selectedRect.height * getSize().width;
+        int wFact = selectedRect.width * getSize().height;
         if (hFact > wFact) {
-        	StreetsideImageDisplay.this.selectedRect.width = hFact / getSize().height;
+          selectedRect.width = hFact / getSize().height;
         } else {
-        	StreetsideImageDisplay.this.selectedRect.height = wFact / getSize().width;
+          selectedRect.height = wFact / getSize().width;
         }
         // Keep the center of the selection
-        if (StreetsideImageDisplay.this.selectedRect.width != oldWidth) {
-        	StreetsideImageDisplay.this.selectedRect.x -= (StreetsideImageDisplay.this.selectedRect.width - oldWidth) / 2;
-        }
-        if (StreetsideImageDisplay.this.selectedRect.height != oldHeight) {
-        	StreetsideImageDisplay.this.selectedRect.y -= (StreetsideImageDisplay.this.selectedRect.height - oldHeight) / 2;
-        }
-        checkVisibleRectSize(image, StreetsideImageDisplay.this.selectedRect);
-        checkVisibleRectPos(image, StreetsideImageDisplay.this.selectedRect);
+        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 (StreetsideImageDisplay.this) {
-          StreetsideImageDisplay.this.visibleRect = StreetsideImageDisplay.this.selectedRect;
-        }
-        StreetsideImageDisplay.this.selectedRect = null;
+          visibleRect = selectedRect;
+        }
+        selectedRect = null;
         StreetsideImageDisplay.this.repaint();
       }
@@ -362,7 +360,7 @@
         this.detections.addAll(detections);
       }
-      this.selectedRect = null;
+      selectedRect = null;
       if (image != null)
-        this.visibleRect = new Rectangle(0, 0, image.getWidth(null),
+        visibleRect = new Rectangle(0, 0, image.getWidth(null),
             image.getHeight(null));
     }
@@ -376,5 +374,5 @@
    */
   public BufferedImage getImage() {
-    return this.image;
+    return image;
   }
 
@@ -404,9 +402,9 @@
           + target.height, visibleRect.x, visibleRect.y, visibleRect.x
           + visibleRect.width, visibleRect.y + visibleRect.height, null);
-      if (this.selectedRect != null) {
-        Point topLeft = img2compCoord(visibleRect, this.selectedRect.x,
-            this.selectedRect.y);
-        Point bottomRight = img2compCoord(visibleRect, this.selectedRect.x
-            + this.selectedRect.width, this.selectedRect.y + this.selectedRect.height);
+      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);
Index: /applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/gui/StreetsideMainDialog.java
===================================================================
--- /applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/gui/StreetsideMainDialog.java	(revision 34348)
+++ /applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/gui/StreetsideMainDialog.java	(revision 34349)
@@ -1,8 +1,4 @@
 // License: GPL. For details, see LICENSE file.
 package org.openstreetmap.josm.plugins.streetside.gui;
-
-import static org.openstreetmap.josm.tools.I18n.marktr;
-import static org.openstreetmap.josm.tools.I18n.tr;
-import static org.openstreetmap.josm.tools.I18n.trc;
 
 import java.awt.BorderLayout;
@@ -18,4 +14,5 @@
 import javax.imageio.ImageIO;
 import javax.swing.AbstractAction;
+import javax.swing.Action;
 import javax.swing.JComponent;
 import javax.swing.KeyStroke;
@@ -37,6 +34,7 @@
 import org.openstreetmap.josm.plugins.streetside.cache.StreetsideCache;
 import org.openstreetmap.josm.plugins.streetside.gui.imageinfo.ImageInfoHelpPopup;
-import org.openstreetmap.josm.plugins.streetside.model.UserProfile;
+import org.openstreetmap.josm.plugins.streetside.gui.imageinfo.StreetsideViewerHelpPopup;
 import org.openstreetmap.josm.plugins.streetside.utils.StreetsideProperties;
+import org.openstreetmap.josm.tools.I18n;
 import org.openstreetmap.josm.tools.ImageProvider;
 import org.openstreetmap.josm.tools.Logging;
@@ -46,569 +44,608 @@
  *
  * @author nokutu
+ * @author renerr18
  */
 public final class StreetsideMainDialog extends ToggleDialog implements
-        ICachedLoaderListener, StreetsideDataListener {
-
-  private static final long serialVersionUID = 6856496736429480600L;
-
-  private static final String BASE_TITLE = marktr("Streetside image");
-  private static final String MESSAGE_SEPARATOR = " — ";
-
-  private static StreetsideMainDialog instance;
-
-  private volatile StreetsideAbstractImage image;
-
-  private final SideButton nextButton = new SideButton(new NextPictureAction());
-  private final SideButton previousButton = new SideButton(new PreviousPictureAction());
-  /**
-   * Button used to jump to the image following the red line
-   */
-  public final SideButton redButton = new SideButton(new RedAction());
-  /**
-   * Button used to jump to the image following the blue line
-   */
-  public final SideButton blueButton = new SideButton(new BlueAction());
-
-  private final SideButton playButton = new SideButton(new PlayAction());
-  private final SideButton pauseButton = new SideButton(new PauseAction());
-  private final SideButton stopButton = new SideButton(new StopAction());
-
-  private ImageInfoHelpPopup imageInfoHelp;
-
-  /**
-   * Buttons mode.
-   *
-   * @author nokutu
-   */
-  public enum MODE {
-    /**
-     * Standard mode to view pictures.
-     */
-    NORMAL,
-    /**
-     * Mode when in walk.
-     */
-    WALK
-  }
-
-  /**
-   * Object containing the shown image and that handles zoom and drag
-   */
-  public final StreetsideImageDisplay streetsideImageDisplay;
-
-  private StreetsideCache imageCache;
-  private StreetsideCache thumbnailCache;
-
-  private StreetsideMainDialog() {
-    super(tr(BASE_TITLE), "streetside-main", tr("Open Streetside window"), null, 200,
-        true, StreetsidePreferenceSetting.class);
-    addShortcuts();
-    streetsideImageDisplay = new StreetsideImageDisplay();
-
-    blueButton.setForeground(Color.BLUE);
-    redButton.setForeground(Color.RED);
-
-    setMode(MODE.NORMAL);
-  }
-
-  /**
-   * 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());
-  }
-
-  /**
-   * Returns the unique instance of the class.
-   *
-   * @return The unique instance of the class.
-   */
-  public static synchronized StreetsideMainDialog getInstance() {
-    if (instance == null)
-      instance = new StreetsideMainDialog();
-    return instance;
-  }
-
-  /**
-   * @return true, iff the singleton instance is present
-   */
-  public static boolean hasInstance() {
-    return instance != null;
-  }
-
-  public synchronized void setImageInfoHelp(ImageInfoHelpPopup popup) {
-    imageInfoHelp = popup;
-  }
-
-  /**
-   * Sets a new mode for the dialog.
-   *
-   * @param mode The mode to be set. Must not be {@code null}.
-   */
-  public void setMode(MODE mode) {
-    switch (mode) {
-      case WALK:
-        createLayout(
-          streetsideImageDisplay,
-          Arrays.asList(playButton, pauseButton, stopButton)
-        );
-        break;
-      case NORMAL:
-      default:
-        createLayout(
-          streetsideImageDisplay,
-          Arrays.asList(blueButton, previousButton, nextButton, redButton)
-        );
-        break;
-    }
-    disableAllButtons();
-    if (MODE.NORMAL.equals(mode)) {
-      updateImage();
-    }
-    revalidate();
-    repaint();
-  }
-
-  /**
-   * Destroys the unique instance of the class.
-   */
-  public static synchronized void destroyInstance() {
-    instance = null;
-  }
-
-  /**
-   * Downloads the full quality picture of the selected StreetsideImage and sets
-   * in the StreetsideImageDisplay object.
-   */
-  public synchronized void updateImage() {
-    updateImage(true);
-  }
-
-  /**
-   * Downloads the picture of the selected StreetsideImage and sets in the
-   * StreetsideImageDisplay object.
-   *
-   * @param fullQuality If the full quality picture must be downloaded or just the
-   *                    thumbnail.
-   */
-  public synchronized void updateImage(boolean fullQuality) {
-    if (!SwingUtilities.isEventDispatchThread()) {
-      SwingUtilities.invokeLater(this::updateImage);
-    } else {
-      if (!StreetsideLayer.hasInstance()) {
-        return;
-      }
-      if (image == null) {
-        streetsideImageDisplay.setImage(null, null);
-        setTitle(tr(BASE_TITLE));
-        disableAllButtons();
-        return;
-      }
-
-      if (imageInfoHelp != null && StreetsideProperties.IMAGEINFO_HELP_COUNTDOWN.get() > 0 && imageInfoHelp.showPopup()) {
-        // Count down the number of times the popup will be displayed
-        StreetsideProperties.IMAGEINFO_HELP_COUNTDOWN.put(StreetsideProperties.IMAGEINFO_HELP_COUNTDOWN.get() - 1);
-      }
-
-      // Enables/disables next/previous buttons
-      nextButton.setEnabled(false);
-      previousButton.setEnabled(false);
-      if (image.getSequence() != null) {
-        StreetsideAbstractImage tempImage = image;
-        while (tempImage.next() != null) {
-          tempImage = tempImage.next();
-          if (tempImage.isVisible()) {
-            nextButton.setEnabled(true);
-            break;
-          }
-        }
-      }
-      if (image.getSequence() != null) {
-        StreetsideAbstractImage tempImage = image;
-        while (tempImage.previous() != null) {
-          tempImage = tempImage.previous();
-          if (tempImage.isVisible()) {
-            previousButton.setEnabled(true);
-            break;
-          }
-        }
-      }
-      if (image instanceof StreetsideImage) {
-        StreetsideImage streetsideImage = (StreetsideImage) image;
-        // Downloads the thumbnail.
-        streetsideImageDisplay.setImage(null, null);
-        if (thumbnailCache != null)
-          thumbnailCache.cancelOutstandingTasks();
-        thumbnailCache = new StreetsideCache(streetsideImage.getId(),
-                StreetsideCache.Type.THUMBNAIL);
-        try {
-          thumbnailCache.submit(this, false);
-        } catch (IOException e) {
-          Logging.error(e);
-        }
-
-        // Downloads the full resolution image.
-        if (fullQuality || new StreetsideCache(streetsideImage.getId(),
-                StreetsideCache.Type.FULL_IMAGE).get() != null) {
-          if (imageCache != null)
-            imageCache.cancelOutstandingTasks();
-          imageCache = new StreetsideCache(streetsideImage.getId(),
-                  StreetsideCache.Type.FULL_IMAGE);
-          try {
-            imageCache.submit(this, false);
-          } catch (IOException e) {
-            Logging.error(e);
-          }
-        }
-      } else if (image instanceof StreetsideImportedImage) {
-        StreetsideImportedImage streetsideImage = (StreetsideImportedImage) image;
-        try {
-          streetsideImageDisplay.setImage(streetsideImage.getImage(), null);
-        } catch (IOException e) {
-          Logging.error(e);
-        }
-      }
-      updateTitle();
-    }
-
-  }
-
-  /**
-   * Disables all the buttons in the dialog
-   */
-  private void disableAllButtons() {
-    nextButton.setEnabled(false);
-    previousButton.setEnabled(false);
-    blueButton.setEnabled(false);
-    redButton.setEnabled(false);
-  }
-
-  /**
-   * Sets a new StreetsideImage to be shown.
-   *
-   * @param image The image to be shown.
-   */
-  public synchronized void setImage(StreetsideAbstractImage image) {
-    this.image = image;
-  }
-
-  /**
-   * Updates the title of the dialog.
-   */
-  public synchronized void updateTitle() {
-    if (!SwingUtilities.isEventDispatchThread()) {
-      SwingUtilities.invokeLater(this::updateTitle);
-    } else if (image != null) {
-      StringBuilder title = new StringBuilder(tr(BASE_TITLE));
-      if (image instanceof StreetsideImage) {
-        StreetsideImage streetsideImage = (StreetsideImage) image;
-        UserProfile user = streetsideImage.getUser();
-        if (user != null) {
-          title.append(MESSAGE_SEPARATOR).append(user.getUsername());
-        }
-        if (streetsideImage.getCd() != 0) {
-          title.append(MESSAGE_SEPARATOR).append(streetsideImage.getDate());
-        }
-        setTitle(title.toString());
-      } else if (image instanceof StreetsideImportedImage) {
-        StreetsideImportedImage streetsideImportedImage = (StreetsideImportedImage) image;
-        title.append(MESSAGE_SEPARATOR).append(streetsideImportedImage.getFile().getName());
-        title.append(MESSAGE_SEPARATOR).append(streetsideImportedImage.getDate());
-        setTitle(title.toString());
-      }
-    }
-  }
-
-  /**
-   * Returns the {@link StreetsideAbstractImage} object which is being shown.
-   *
-   * @return The {@link StreetsideAbstractImage} object which is being shown.
-   */
-  public synchronized StreetsideAbstractImage getImage() {
-    return image;
-  }
-
-  /**
-   * Action class form the next image button.
-   *
-   * @author nokutu
-   */
-  private static class NextPictureAction extends AbstractAction {
-
-    private static final long serialVersionUID = 3023827221453154340L;
-
-    /**
-     * Constructs a normal NextPictureAction
-     */
-    NextPictureAction() {
-      super(tr("Next picture"));
-      putValue(SHORT_DESCRIPTION, tr("Shows the next picture in the sequence"));
-      new ImageProvider("dialogs", "next").getResource().attachImageIcon(this, true);
-    }
-
-    @Override
-    public void actionPerformed(ActionEvent e) {
-      StreetsideLayer.getInstance().getData().selectNext();
-    }
-  }
-
-  /**
-   * Action class for the previous image button.
-   *
-   * @author nokutu
-   */
-  private static class PreviousPictureAction extends AbstractAction {
-
-    private static final long serialVersionUID = -6420511632957956012L;
-
-    /**
-     * Constructs a normal PreviousPictureAction
-     */
-    PreviousPictureAction() {
-      super(tr("Previous picture"));
-      putValue(SHORT_DESCRIPTION, tr("Shows the previous picture in the sequence"));
-      new ImageProvider("dialogs", "previous").getResource().attachImageIcon(this, true);
-    }
-
-    @Override
-    public void actionPerformed(ActionEvent e) {
-      StreetsideLayer.getInstance().getData().selectPrevious();
-    }
-  }
-
-  /**
-   * Action class to jump to the image following the red line.
-   *
-   * @author nokutu
-   */
-  private static class RedAction extends AbstractAction {
-
-    private static final long serialVersionUID = -6480229431481386376L;
-
-    /**
-     * Constructs a normal RedAction
-     */
-    RedAction() {
-      putValue(NAME, tr("Jump to red"));
-      putValue(SHORT_DESCRIPTION,
-              tr("Jumps to the picture at the other side of the red line"));
-      new ImageProvider("dialogs", "red").getResource().attachImageIcon(this, true);
-    }
-
-    @Override
-    public void actionPerformed(ActionEvent e) {
-      if (StreetsideMainDialog.getInstance().getImage() != null) {
-        StreetsideLayer.getInstance().getData()
-                .setSelectedImage(StreetsideLayer.getInstance().getNNearestImage(1), true);
-      }
-    }
-  }
-
-  /**
-   * Action class to jump to the image following the blue line.
-   *
-   * @author nokutu
-   */
-  private static class BlueAction extends AbstractAction {
-
-    private static final long serialVersionUID = 6250690644594703314L;
-
-    /**
-     * Constructs a normal BlueAction
-     */
-    BlueAction() {
-      putValue(NAME, tr("Jump to blue"));
-      putValue(SHORT_DESCRIPTION,
-              tr("Jumps to the picture at the other side of the blue line"));
-      new ImageProvider("dialogs", "blue").getResource().attachImageIcon(this, true);
-    }
-
-    @Override
-    public void actionPerformed(ActionEvent e) {
-      if (StreetsideMainDialog.getInstance().getImage() != null) {
-        StreetsideLayer.getInstance().getData()
-                .setSelectedImage(StreetsideLayer.getInstance().getNNearestImage(2), true);
-      }
-    }
-  }
-
-  private static class StopAction extends AbstractAction implements WalkListener {
-
-    private static final long serialVersionUID = -6561451575815789198L;
-
-    private WalkThread thread;
-
-    /**
-     * Constructs a normal StopAction
-     */
-    StopAction() {
-      putValue(NAME, trc("as synonym to halt or stand still", "Stop"));
-      putValue(SHORT_DESCRIPTION, tr("Stops the walk."));
-      new ImageProvider("dialogs/streetsideStop.png").getResource().attachImageIcon(this, true);
-      StreetsidePlugin.getWalkAction().addListener(this);
-    }
-
-    @Override
-    public void actionPerformed(ActionEvent e) {
-      if (thread != null)
-        thread.stopWalk();
-    }
-
-    @Override
-    public void walkStarted(WalkThread thread) {
-      this.thread = thread;
-    }
-  }
-
-  private static class PlayAction extends AbstractAction implements WalkListener {
-
-    private static final long serialVersionUID = -17943404752082788L;
-    private transient WalkThread thread;
-
-    /**
-     * Constructs a normal PlayAction
-     */
-    PlayAction() {
-      putValue(NAME, tr("Play"));
-      putValue(SHORT_DESCRIPTION, tr("Continues with the paused walk."));
-      new ImageProvider("dialogs/streetsidePlay.png").getResource().attachImageIcon(this, true);
-      StreetsidePlugin.getWalkAction().addListener(this);
-    }
-
-    @Override
-    public void actionPerformed(ActionEvent e) {
-      if (thread != null)
-        thread.play();
-    }
-
-    @Override
-    public void walkStarted(WalkThread thread) {
-      if (thread != null)
-        this.thread = thread;
-    }
-  }
-
-  private static class PauseAction extends AbstractAction implements WalkListener {
-
-    private static final long serialVersionUID = 4400240686337741192L;
-
-    private WalkThread thread;
-
-    /**
-     * Constructs a normal PauseAction
-     */
-    PauseAction() {
-      putValue(NAME, tr("Pause"));
-      putValue(SHORT_DESCRIPTION, tr("Pauses the walk."));
-      new ImageProvider("dialogs/streetsidePause.png").getResource().attachImageIcon(this, true);
-      StreetsidePlugin.getWalkAction().addListener(this);
-    }
-
-    @Override
-    public void actionPerformed(ActionEvent e) {
-      thread.pause();
-    }
-
-    @Override
-    public void walkStarted(WalkThread thread) {
-      this.thread = thread;
-    }
-  }
-
-  /**
-   * When the pictures are returned from the cache, they are set in the
-   * {@link StreetsideImageDisplay} object.
-   */
-  /*@Override
-  public void loadingFinished(final CacheEntry data, final CacheEntryAttributes attributes, final LoadResult result) {
-    if (!SwingUtilities.isEventDispatchThread()) {
-      SwingUtilities.invokeLater(() -> 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 (
-          streetsideImageDisplay.getImage() == null
-          || img.getHeight() > this.streetsideImageDisplay.getImage().getHeight()
-        ) {
-          final StreetsideAbstractImage mai = getImage();
-          this.streetsideImageDisplay.setImage(
-            img,
-            mai instanceof StreetsideImage ? ((StreetsideImage) getImage()).getDetections() : null
-          );
-        }
-      } catch (IOException e) {
-        Logging.error(e);
-      }
-    }
-  }*/
-
-  /**
-   * When the pictures are returned from the cache, they are set in the
-   * {@link StreetsideImageDisplay} object.
-   */
-  @Override
-  public void loadingFinished(final CacheEntry data, final CacheEntryAttributes attributes, final LoadResult result) {
-    if (!SwingUtilities.isEventDispatchThread()) {
-      SwingUtilities.invokeLater(() -> loadingFinished(data, attributes, result));
-
-    } else if (data != null && result == LoadResult.SUCCESS) {
-      try {
-        final BufferedImage img = ImageIO.read(new ByteArrayInputStream(data.getContent()));
-        if (img == null) {
-          return;
-        }
-        if (
-            streetsideImageDisplay.getImage() == null
-            || img.getHeight() > streetsideImageDisplay.getImage().getHeight()
-            ) {
-          //final StreetsideAbstractImage mai = getImage();
-          streetsideImageDisplay.setImage(
-              img,
-              //mai instanceof StreetsideImage ? ((StreetsideImage) getImage()).getDetections() : null
-              null);
-        }
-      } catch (final IOException e) {
-        Logging.error(e);
-      }
-    }
-  }
-
-  /**
-   * Creates the layout of the dialog.
-   *
-   * @param data    The content of the dialog
-   * @param buttons The buttons where you can click
-   */
-  public void createLayout(Component data, List<SideButton> buttons) {
-    removeAll();
-    createLayout(data, true, buttons);
-    add(titleBar, BorderLayout.NORTH);
-  }
-
-  @Override
-  public void selectedImageChanged(StreetsideAbstractImage oldImage, StreetsideAbstractImage newImage) {
-    setImage(newImage);
-    updateImage();
-  }
-
-  @Override
-  public void imagesAdded() {
-    // This method is enforced by StreetsideDataListener, but only selectedImageChanged() is needed
-  }
-
+		ICachedLoaderListener, StreetsideDataListener {
+
+	private static final long serialVersionUID = 2645654786827812861L;
+
+	public static final String BASE_TITLE = I18n.marktr("Microsoft Streetside image");
+	private static final String MESSAGE_SEPARATOR = " — ";
+
+	private static StreetsideMainDialog instance;
+
+	private volatile StreetsideAbstractImage image;
+
+	public final SideButton nextButton = new SideButton(new NextPictureAction());
+	public final SideButton previousButton = new SideButton(new PreviousPictureAction());
+	/**
+	 * Button used to jump to the image following the red line
+	 */
+	public final SideButton redButton = new SideButton(new RedAction());
+	/**
+	 * Button used to jump to the image following the blue line
+	 */
+	public final SideButton blueButton = new SideButton(new BlueAction());
+
+	private final SideButton playButton = new SideButton(new PlayAction());
+	private final SideButton pauseButton = new SideButton(new PauseAction());
+	private final SideButton stopButton = new SideButton(new StopAction());
+
+	private ImageInfoHelpPopup imageInfoHelp;
+
+	private StreetsideViewerHelpPopup streetsideViewerHelp;
+
+	/**
+	 * Buttons mode.
+	 *
+	 * @author nokutu
+	 */
+	public enum MODE {
+		/**
+		 * Standard mode to view pictures.
+		 */
+		NORMAL,
+		/**
+		 * Mode when in walk.
+		 */
+		WALK
+	}
+
+	/**
+	 * Object containing the shown image and that handles zoom and drag
+	 */
+	public StreetsideImageDisplay streetsideImageDisplay;
+
+	private StreetsideCache imageCache;
+	public StreetsideCache thumbnailCache;
+
+	private StreetsideMainDialog() {
+		super(I18n.tr(StreetsideMainDialog.BASE_TITLE), "streetside-main", I18n.tr("Open Streetside window"), null, 200,
+				true, StreetsidePreferenceSetting.class);
+		addShortcuts();
+
+		streetsideImageDisplay = new StreetsideImageDisplay();
+
+		blueButton.setForeground(Color.BLUE);
+		redButton.setForeground(Color.RED);
+
+		// TODO: Modes for cubemaps? @rrh
+		setMode(MODE.NORMAL);
+	}
+
+	/**
+	 * 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());
+	}
+
+	/**
+	 * Returns the unique instance of the class.
+	 *
+	 * @return The unique instance of the class.
+	 */
+	public static synchronized StreetsideMainDialog getInstance() {
+		if (StreetsideMainDialog.instance == null) {
+			StreetsideMainDialog.instance = new StreetsideMainDialog();
+		}
+		return StreetsideMainDialog.instance;
+	}
+
+	/**
+	 * @return true, iff the singleton instance is present
+	 */
+	public static boolean hasInstance() {
+		return StreetsideMainDialog.instance != null;
+	}
+
+	public synchronized void setImageInfoHelp(ImageInfoHelpPopup popup) {
+		imageInfoHelp = popup;
+	}
+
+	public synchronized void setStreetsideViewerHelp(StreetsideViewerHelpPopup popup) {
+		streetsideViewerHelp = popup;
+	}
+
+	/**
+	 * @return the streetsideViewerHelp
+	 */
+	public StreetsideViewerHelpPopup getStreetsideViewerHelp() {
+		return streetsideViewerHelp;
+	}
+
+	/**
+	 * Sets a new mode for the dialog.
+	 *
+	 * @param mode The mode to be set. Must not be {@code null}.
+	 */
+	public void setMode(MODE mode) {
+		switch (mode) {
+		case WALK:
+			createLayout(
+				streetsideImageDisplay,
+				Arrays.asList(playButton, pauseButton, stopButton)
+			);
+		case NORMAL:
+		default:
+			createLayout(
+		        streetsideImageDisplay,
+		        Arrays.asList(blueButton, previousButton, nextButton, redButton)
+		    );
+		}
+		disableAllButtons();
+		if (MODE.NORMAL.equals(mode)) {
+			updateImage();
+		} 	}
+
+	/**
+	 * Destroys the unique instance of the class.
+	 */
+	public static synchronized void destroyInstance() {
+		StreetsideMainDialog.instance = null;
+	}
+
+	/**
+	 * Downloads the full quality picture of the selected StreetsideImage and sets
+	 * in the StreetsideImageDisplay object.
+	 */
+	public synchronized void updateImage() {
+		updateImage(true);
+	}
+
+	/**
+	 * Downloads the picture of the selected StreetsideImage and sets in the
+	 * StreetsideImageDisplay object.
+	 *
+	 * @param fullQuality If the full quality picture must be downloaded or just the
+	 *                    thumbnail.
+	 */
+	public synchronized void updateImage(boolean fullQuality) {
+		if (!SwingUtilities.isEventDispatchThread()) {
+			SwingUtilities.invokeLater(this::updateImage);
+		} else {
+			if (!StreetsideLayer.hasInstance()) {
+				return;
+			}
+			if (image == null) {
+				streetsideImageDisplay.setImage(null, null);
+				setTitle(I18n.tr(StreetsideMainDialog.BASE_TITLE));
+				disableAllButtons();
+				return;
+			}
+
+			// TODO: help for cubemaps? @rrh
+			if (imageInfoHelp != null && StreetsideProperties.IMAGEINFO_HELP_COUNTDOWN.get() > 0 && imageInfoHelp.showPopup()) {
+				// Count down the number of times the popup will be displayed
+				StreetsideProperties.IMAGEINFO_HELP_COUNTDOWN.put(StreetsideProperties.IMAGEINFO_HELP_COUNTDOWN.get() - 1);
+			}
+
+			// Enables/disables next/previous buttons
+			nextButton.setEnabled(false);
+			previousButton.setEnabled(false);
+			if (image.getSequence() != null) {
+				StreetsideAbstractImage tempImage = image;
+				while (tempImage.next() != null) {
+					tempImage = tempImage.next();
+					if (tempImage.isVisible()) {
+						nextButton.setEnabled(true);
+						break;
+					}
+				}
+			}
+			if (image.getSequence() != null) {
+				StreetsideAbstractImage tempImage = image;
+				while (tempImage.previous() != null) {
+					tempImage = tempImage.previous();
+					if (tempImage.isVisible()) {
+						previousButton.setEnabled(true);
+						break;
+					}
+				}
+			}
+			if (image instanceof StreetsideImage) {
+				final StreetsideImage streetsideImage = (StreetsideImage) image;
+				// Downloads the thumbnail.
+				streetsideImageDisplay.setImage(null, null);
+				if (thumbnailCache != null) {
+					thumbnailCache.cancelOutstandingTasks();
+				}
+				thumbnailCache = new StreetsideCache(streetsideImage.getId(),
+						StreetsideCache.Type.THUMBNAIL);
+				try {
+					thumbnailCache.submit(this, false);
+				} catch (final IOException e) {
+					Logging.error(e);
+				}
+
+				// Downloads the full resolution image.
+				if (fullQuality || new StreetsideCache(streetsideImage.getId(),
+						StreetsideCache.Type.FULL_IMAGE).get() != null) {
+					if (imageCache != null) {
+						imageCache.cancelOutstandingTasks();
+					}
+					imageCache = new StreetsideCache(streetsideImage.getId(),
+							StreetsideCache.Type.FULL_IMAGE);
+					try {
+						imageCache.submit(this, false);
+					} catch (final IOException e) {
+						Logging.error(e);
+					}
+				}
+			// TODO: handle/convert/remove "imported images"
+			} /*else if (image instanceof StreetsideImportedImage) {
+				final StreetsideImportedImage streetsideImage = (StreetsideImportedImage) image;
+				try {
+					streetsideImageDisplay.setImage(streetsideImage.getImage(), null);
+				} catch (final IOException e) {
+					Logging.error(e);
+				}
+			}*/
+			updateTitle();
+		}
+	}
+
+	/**
+	 * Disables all the buttons in the dialog
+	 */
+	public /*private*/ void disableAllButtons() {
+		nextButton.setEnabled(false);
+		previousButton.setEnabled(false);
+		blueButton.setEnabled(false);
+		redButton.setEnabled(false);
+	}
+
+	/**
+	 * Sets a new StreetsideImage to be shown.
+	 *
+	 * @param image The image to be shown.
+	 */
+	public synchronized void setImage(StreetsideAbstractImage image) {
+		this.image = image;
+	}
+
+	/**
+	 * Updates the title of the dialog.
+	 */
+	// TODO: update title for 360 degree viewer? @rrh
+	public synchronized void updateTitle() {
+		if (!SwingUtilities.isEventDispatchThread()) {
+			SwingUtilities.invokeLater(this::updateTitle);
+		} else if (image != null) {
+			final StringBuilder title = new StringBuilder(I18n.tr(StreetsideMainDialog.BASE_TITLE));
+			if (image instanceof StreetsideImage) {
+				final StreetsideImage streetsideImage = (StreetsideImage) image;
+				if (streetsideImage.getCd() != 0) {
+					title.append(StreetsideMainDialog.MESSAGE_SEPARATOR).append(streetsideImage.getDate());
+				}
+				setTitle(title.toString());
+			} else if (image instanceof StreetsideImportedImage) {
+				final StreetsideImportedImage mapillaryImportedImage = (StreetsideImportedImage) image;
+				title.append(StreetsideMainDialog.MESSAGE_SEPARATOR).append(mapillaryImportedImage.getFile().getName());
+				title.append(StreetsideMainDialog.MESSAGE_SEPARATOR).append(mapillaryImportedImage.getDate());
+				setTitle(title.toString());
+			}
+		}
+	}
+
+	/**
+	 * Returns the {@link StreetsideAbstractImage} object which is being shown.
+	 *
+	 * @return The {@link StreetsideAbstractImage} object which is being shown.
+	 */
+	public synchronized StreetsideAbstractImage getImage() {
+		return image;
+	}
+
+	/**
+	 * Action class form the next image button.
+	 *
+	 * @author nokutu
+	 */
+	private static class NextPictureAction extends AbstractAction {
+
+		private static final long serialVersionUID = 6333692154558730392L;
+
+		/**
+		 * Constructs a normal NextPictureAction
+		 */
+		NextPictureAction() {
+			super(I18n.tr("Next picture"));
+			putValue(Action.SHORT_DESCRIPTION, I18n.tr("Shows the next picture in the sequence"));
+			new ImageProvider("help", "next").getResource().attachImageIcon(this, true);
+		}
+
+		@Override
+		public void actionPerformed(ActionEvent e) {
+			StreetsideLayer.getInstance().getData().selectNext();
+		}
+	}
+
+	/**
+	 * Action class for the previous image button.
+	 *
+	 * @author nokutu
+	 */
+	private static class PreviousPictureAction extends AbstractAction {
+
+		private static final long serialVersionUID = 4390593660514657107L;
+
+		/**
+		 * Constructs a normal PreviousPictureAction
+		 */
+		PreviousPictureAction() {
+			super(I18n.tr("Previous picture"));
+			putValue(Action.SHORT_DESCRIPTION, I18n.tr("Shows the previous picture in the sequence"));
+			new ImageProvider("help", "previous").getResource().attachImageIcon(this, true);
+		}
+
+		@Override
+		public void actionPerformed(ActionEvent e) {
+			StreetsideLayer.getInstance().getData().selectPrevious();
+		}
+	}
+
+	/**
+	 * Action class to jump to the image following the red line.
+	 *
+	 * @author nokutu
+	 */
+	private static class RedAction extends AbstractAction {
+
+		private static final long serialVersionUID = -1244456062285831231L;
+
+		/**
+		 * Constructs a normal RedAction
+		 */
+		RedAction() {
+			putValue(Action.NAME, I18n.tr("Jump to red"));
+			putValue(Action.SHORT_DESCRIPTION,
+					I18n.tr("Jumps to the picture at the other side of the red line"));
+			new ImageProvider("dialogs", "red").getResource().attachImageIcon(this, true);
+		}
+
+		// TODO: RedAction for cubemaps? @rrh
+		@Override
+		public void actionPerformed(ActionEvent e) {
+			if (StreetsideMainDialog.getInstance().getImage() != null) {
+				StreetsideLayer.getInstance().getData()
+				.setSelectedImage(StreetsideLayer.getInstance().getNNearestImage(1), true);
+			}
+		}
+	}
+
+	/**
+	 * Action class to jump to the image following the blue line.
+	 *
+	 * @author nokutu
+	 */
+	private static class BlueAction extends AbstractAction {
+
+		private static final long serialVersionUID = 5951233534212838780L;
+
+		/**
+		 * Constructs a normal BlueAction
+		 */
+		BlueAction() {
+			putValue(Action.NAME, I18n.tr("Jump to blue"));
+			putValue(Action.SHORT_DESCRIPTION,
+					I18n.tr("Jumps to the picture at the other side of the blue line"));
+			new ImageProvider("dialogs", "blue").getResource().attachImageIcon(this, true);
+		}
+
+		// TODO: BlueAction for cubemaps?
+		@Override
+		public void actionPerformed(ActionEvent e) {
+			if (StreetsideMainDialog.getInstance().getImage() != null) {
+				StreetsideLayer.getInstance().getData()
+				.setSelectedImage(StreetsideLayer.getInstance().getNNearestImage(2), true);
+			}
+		}
+	}
+
+	private static class StopAction extends AbstractAction implements WalkListener {
+
+		private static final long serialVersionUID = 8789972456611625341L;
+
+		private WalkThread thread;
+
+		/**
+		 * Constructs a normal StopAction
+		 */
+		StopAction() {
+			putValue(Action.NAME, I18n.tr("Stop"));
+			putValue(Action.SHORT_DESCRIPTION, I18n.tr("Stops the walk."));
+			new ImageProvider("dialogs/streetsideStop.png").getResource().attachImageIcon(this, true);
+			StreetsidePlugin.getStreetsideWalkAction().addListener(this);
+		}
+
+		@Override
+		public void actionPerformed(ActionEvent e) {
+			if (thread != null) {
+				thread.stopWalk();
+			}
+		}
+
+		@Override
+		public void walkStarted(WalkThread thread) {
+			this.thread = thread;
+		}
+	}
+
+	private static class PlayAction extends AbstractAction implements WalkListener {
+
+		private static final long serialVersionUID = -1572747020946842769L;
+
+		private transient WalkThread thread;
+
+		/**
+		 * Constructs a normal PlayAction
+		 */
+		PlayAction() {
+			putValue(Action.NAME, I18n.tr("Play"));
+			putValue(Action.SHORT_DESCRIPTION, I18n.tr("Continues with the paused walk."));
+			new ImageProvider("dialogs/streetsidePlay.png").getResource().attachImageIcon(this, true);
+			StreetsidePlugin.getStreetsideWalkAction().addListener(this);
+		}
+
+		@Override
+		public void actionPerformed(ActionEvent e) {
+			if (thread != null) {
+				thread.play();
+			}
+		}
+
+		@Override
+		public void walkStarted(WalkThread thread) {
+			if (thread != null) {
+				this.thread = thread;
+			}
+		}
+	}
+
+	private static class PauseAction extends AbstractAction implements WalkListener {
+
+		/**
+		 *
+		 */
+		private static final long serialVersionUID = -8758326399460817222L;
+		private WalkThread thread;
+
+		/**
+		 * Constructs a normal PauseAction
+		 */
+		PauseAction() {
+			putValue(Action.NAME, I18n.tr("Pause"));
+			putValue(Action.SHORT_DESCRIPTION, I18n.tr("Pauses the walk."));
+			new ImageProvider("dialogs/streetsidePause.png").getResource().attachImageIcon(this, true);
+			StreetsidePlugin.getStreetsideWalkAction().addListener(this);
+		}
+
+		@Override
+		public void actionPerformed(ActionEvent e) {
+			thread.pause();
+		}
+
+		@Override
+		public void walkStarted(WalkThread thread) {
+			this.thread = thread;
+		}
+	}
+
+	/**
+	 * When the pictures are returned from the cache, they are set in the
+	 * {@link StreetsideImageDisplay} object.
+	 */
+	@Override
+	public void loadingFinished(final CacheEntry data, final CacheEntryAttributes attributes, final LoadResult result) {
+		if (!SwingUtilities.isEventDispatchThread()) {
+			SwingUtilities.invokeLater(() -> loadingFinished(data, attributes, result));
+
+		} else if (data != null && result == LoadResult.SUCCESS) {
+			try {
+				final BufferedImage img = ImageIO.read(new ByteArrayInputStream(data.getContent()));
+				if (img == null) {
+					return;
+				}
+				if (
+						streetsideImageDisplay.getImage() == null
+						|| img.getHeight() > streetsideImageDisplay.getImage().getHeight()
+						) {
+					//final StreetsideAbstractImage mai = getImage();
+					streetsideImageDisplay.setImage(
+							img,
+							//mai instanceof StreetsideImage ? ((StreetsideImage) getImage()).getDetections() : null
+							null);
+				}
+			} catch (final IOException e) {
+				Logging.error(e);
+			}
+		}
+	}
+
+
+	/**
+	 * Creates the layout of the dialog.
+	 *
+	 * @param data    The content of the dialog
+	 * @param buttons The buttons where you can click
+	 */
+	public void createLayout(Component data, List<SideButton> buttons) {
+		removeAll();
+		createLayout(data, true, buttons);
+		add(titleBar, BorderLayout.NORTH);
+	}
+
+	@Override
+	public void selectedImageChanged(StreetsideAbstractImage oldImage, StreetsideAbstractImage newImage) {
+		setImage(newImage);
+		updateImage();
+	}
+
+	@Override
+	public void imagesAdded() {
+		// This method is enforced by StreetsideDataListener, but only selectedImageChanged() is needed
+	}
+
+	/**
+	 * @return the streetsideImageDisplay
+	 */
+	public StreetsideImageDisplay getStreetsideImageDisplay() {
+		return streetsideImageDisplay;
+	}
+
+	/**
+	 * @param streetsideImageDisplay the streetsideImageDisplay to set
+	 */
+	public void setStreetsideImageDisplay(StreetsideImageDisplay streetsideImageDisplay) {
+		this.streetsideImageDisplay = streetsideImageDisplay;
+	}
+
+	/**
+	 * @return the streetsideImageDisplay
+	 */
+	/*public StreetsideViewerDisplay getStreetsideViewerDisplay() {
+		return streetsideViewerDisplay;
+	}*/
+
+	/**
+	 * @param streetsideImageDisplay the streetsideImageDisplay to set
+	 */
+	/*public void setStreetsideViewerDisplay(StreetsideViewerDisplay streetsideViewerDisplay) {
+		streetsideViewerDisplay = streetsideViewerDisplay;
+	}*/
+
+	/*private StreetsideViewerDisplay initStreetsideViewerDisplay() {
+		StreetsideViewerDisplay res = new StreetsideViewerDisplay();
+        //this.add(streetsideViewerDisplay);
+
+
+		Platform.runLater(new Runnable() {
+            @Override
+            public void run() {
+            	Scene scene;
+				try {
+					scene = StreetsideViewerDisplay.createScene();
+					res.setScene(scene);
+				} catch (NonInvertibleTransformException e) {
+					// TODO Auto-generated catch block
+					e.printStackTrace();
+				}
+            }
+       });
+		return res;
+	}*/
 }
Index: /applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/gui/boilerplate/package-info.java
===================================================================
--- /applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/gui/boilerplate/package-info.java	(revision 34348)
+++ /applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/gui/boilerplate/package-info.java	(revision 34349)
@@ -1,5 +1,5 @@
 // License: GPL. For details, see LICENSE file.
 /**
- * The GUI components that are special to the streetside plugin.
+ * The GUI components that are special to the mapillary plugin.
  */
 package org.openstreetmap.josm.plugins.streetside.gui.boilerplate;
Index: /applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/gui/imageinfo/ImageInfoPanel.java
===================================================================
--- /applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/gui/imageinfo/ImageInfoPanel.java	(revision 34348)
+++ /applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/gui/imageinfo/ImageInfoPanel.java	(revision 34349)
@@ -12,5 +12,4 @@
 
 import javax.swing.ImageIcon;
-import javax.swing.JCheckBox;
 import javax.swing.JLabel;
 import javax.swing.JPanel;
@@ -19,7 +18,5 @@
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
-
-import org.openstreetmap.josm.data.SelectionChangedListener;
-import org.openstreetmap.josm.data.osm.DataSet;
+import org.openstreetmap.josm.data.osm.DataSelectionListener;
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
 import org.openstreetmap.josm.data.osm.Tag;
@@ -37,5 +34,5 @@
 import org.openstreetmap.josm.tools.I18n;
 
-public final class ImageInfoPanel extends ToggleDialog implements StreetsideDataListener, SelectionChangedListener {
+public final class ImageInfoPanel extends ToggleDialog implements StreetsideDataListener, DataSelectionListener {
   private static final long serialVersionUID = 4141847503072417190L;
   private static final Log L = LogFactory.getLog(ImageInfoPanel.class);
@@ -43,6 +40,6 @@
   private static final ImageIcon EMPTY_USER_AVATAR = new ImageIcon(new BufferedImage(32, 32, BufferedImage.TYPE_INT_ARGB));
 
-  private final JLabel numDetectionsLabel;
-  private final JCheckBox showDetectionsCheck;
+  //private final JLabel numDetectionsLabel;
+  //private final JCheckBox showDetectionsCheck;
   private final JLabel usernameLabel;
   private final JTextPane imgKeyValue;
@@ -62,13 +59,17 @@
       150
     );
-    DataSet.addSelectionListener(this);
-
-    numDetectionsLabel = new JLabel();
-    numDetectionsLabel.setFont(numDetectionsLabel.getFont().deriveFont(Font.PLAIN));
-
-    showDetectionsCheck = new JCheckBox(I18n.tr("Show detections on top of image"));
-
-    // no selections currently available for Streetside
-    showDetectionsCheck.setSelected(false);
+    SelectionEventManager.getInstance().addSelectionListener(this);
+
+    //numDetectionsLabel = new JLabel();
+    //numDetectionsLabel.setFont(numDetectionsLabel.getFont().deriveFont(Font.PLAIN));
+
+    //showDetectionsCheck = new JCheckBox(I18n.tr("Show detections on top of image"));
+    //showDetectionsCheck.setSelected(StreetsideProperties.SHOW_DETECTED_SIGNS.get());
+    /*showDetectionsCheck.addActionListener(
+      action -> StreetsideProperties.SHOW_DETECTED_SIGNS.put(showDetectionsCheck.isSelected())
+    );
+    StreetsideProperties.SHOW_DETECTED_SIGNS.addListener(
+      valueChange -> showDetectionsCheck.setSelected(StreetsideProperties.SHOW_DETECTED_SIGNS.get())
+    );*/
 
     usernameLabel = new JLabel();
@@ -119,8 +120,8 @@
     gbc.gridy = 0;
     gbc.anchor = GridBagConstraints.LINE_START;
-    root.add(numDetectionsLabel, gbc);
-    gbc.gridy++;
-    root.add(showDetectionsCheck, gbc);
-    gbc.gridy++;
+    //root.add(numDetectionsLabel, gbc);
+    //gbc.gridy++;
+    //root.add(showDetectionsCheck, gbc);
+    //gbc.gridy++;
     root.add(usernameLabel, gbc);
     gbc.gridy++;
@@ -171,5 +172,5 @@
 
   /* (non-Javadoc)
-   * @see org.openstreetmap.josm.plugins.mapillary.MapillaryDataListener#selectedImageChanged(org.openstreetmap.josm.plugins.mapillary.MapillaryAbstractImage, org.openstreetmap.josm.plugins.mapillary.MapillaryAbstractImage)
+   * @see org.openstreetmap.josm.plugins.streetside.StreetsideDataListener#selectedImageChanged(org.openstreetmap.josm.plugins.streetside.StreetsideAbstractImage, org.openstreetmap.josm.plugins.streetside.StreetsideAbstractImage)
    */
   @Override
@@ -181,5 +182,5 @@
     ));
 
-    numDetectionsLabel.setText(I18n.tr("{0} detections", newImage instanceof StreetsideImage ? ((StreetsideImage) newImage).getDetections().size() : 0));
+    //numDetectionsLabel.setText(I18n.tr("{0} detections", newImage instanceof StreetsideImage ? ((StreetsideImage) newImage).getDetections().size() : 0));
     imgKeyValue.setEnabled(newImage instanceof StreetsideImage);
     final String newImageKey = newImage instanceof StreetsideImage ? ((StreetsideImage) newImage).getId(): null;
@@ -208,6 +209,5 @@
     }
 
-    // Currently no user info supported in Streetside plugin
-    final UserProfile user = null;
+    final UserProfile user = newImage instanceof StreetsideImage ? ((StreetsideImage) newImage).getUser() : null;
     usernameLabel.setEnabled(user != null);
     if (user != null) {
@@ -232,5 +232,6 @@
    */
   @Override
-  public synchronized void selectionChanged(final Collection<? extends OsmPrimitive> sel) {
+  public synchronized void selectionChanged(final SelectionChangeEvent event) {
+    final Collection<? extends OsmPrimitive> sel = event.getSelection();
     L.debug(String.format("Selection changed. %d primitives are selected.", sel == null ? 0 : sel.size()));
     addStreetsideTagAction.setTarget(sel != null && sel.size() == 1 ? sel.iterator().next() : null);
Index: /applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/gui/imageinfo/StreetsideViewerPanel.java
===================================================================
--- /applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/gui/imageinfo/StreetsideViewerPanel.java	(revision 34348)
+++ /applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/gui/imageinfo/StreetsideViewerPanel.java	(revision 34349)
@@ -84,5 +84,5 @@
 	    checkPanel.add(privacyLink, BorderLayout.PAGE_END);
 
-	    add(checkPanel, BorderLayout.SOUTH);
+	    add(checkPanel, BorderLayout.PAGE_START);
 	    add(threeSixtyDegreeViewerPanel, BorderLayout.CENTER);
 
Index: /applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/gui/package-info.java
===================================================================
--- /applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/gui/package-info.java	(revision 34348)
+++ /applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/gui/package-info.java	(revision 34349)
@@ -1,5 +1,5 @@
 // License: GPL. For details, see LICENSE file.
 /**
- * The GUI components that are special to the streetside plugin.
+ * The GUI components that are special to the mapillary plugin.
  */
 package org.openstreetmap.josm.plugins.streetside.gui;
Index: /applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/io/download/SequenceDownloadRunnable.java
===================================================================
--- /applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/io/download/SequenceDownloadRunnable.java	(revision 34348)
+++ /applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/io/download/SequenceDownloadRunnable.java	(revision 34349)
@@ -48,9 +48,12 @@
     }
 
-    StreetsideSequence seq = new StreetsideSequence(null);
+    StreetsideSequence seq = new StreetsideSequence(StreetsideSequenceIdGenerator.generateId());
+
+    // TODO: how can LatLon and heading / camera angles (he attribute) be set for a sequence?
+    // and does it make sense? @rrh
 
     List<StreetsideImage> bubbleImages = new ArrayList<>();
 
-    final long startTime = System.nanoTime();
+    final long startTime = System.currentTimeMillis();
 
     ObjectMapper mapper = new ObjectMapper();
@@ -64,13 +67,14 @@
     try {
 
-      JsonParser parser = mapper.getFactory().createParser(new BufferedInputStream(con.getInputStream()));
-      if (parser.nextToken() != JsonToken.START_ARRAY) {
-        parser.close();
-        throw new IllegalStateException("Expected an array");
-      }
-
-      StreetsideImage previous = null;
-
-      while (parser.nextToken() == JsonToken.START_OBJECT) {
+    JsonParser parser = mapper.getFactory().createParser(new BufferedInputStream(con.getInputStream()));
+    if(parser.nextToken() != JsonToken.START_ARRAY) {
+      parser.close();
+      throw new IllegalStateException("Expected an array");
+    }
+
+
+    StreetsideImage previous = null;
+
+    while (parser.nextToken() == JsonToken.START_OBJECT) {
         // read everything from this START_OBJECT to the matching END_OBJECT
         // and return it as a tree model ObjectNode
@@ -79,6 +83,7 @@
         if (node.get("id") != null && node.get("la") != null && node.get("lo") != null) {
           StreetsideImage image = new StreetsideImage(CubemapUtils.convertDecimal2Quaternary(node.path("id").asLong()), node.path("la").asDouble(), node.get("lo").asDouble());
-          if (previous != null) {
-              previous.setNe(image.getNe());
+          if(previous!=null) {
+        	  // Analyze sequence behaviour
+        	  //previous.setNext(image.)
           }
           image.setAd(node.path("ad").asInt());
@@ -93,4 +98,6 @@
           image.setPi(node.path("pi").asDouble());
           image.setPr(node.path("pr").asLong());
+          // TODO: inner class @rrh
+          // image.setRn(node.path("rn").asText());
           image.setRo(node.path("ro").asDouble());
 
@@ -98,36 +105,55 @@
           List<StreetsideImage> tiles = new ArrayList<StreetsideImage>();
 
-          EnumSet.allOf(CubemapUtils.CubemapFaces.class).forEach(face -> {
-
-            for (int i = 0; i < 4; i++) {
-              // Initialize four-tiled cubemap faces (four images per cube side with 18-length
-              // Quadkey)
-              if (!StreetsideProperties.SHOW_HIGH_RES_STREETSIDE_IMAGERY.get()) {
-                StreetsideImage tile = new StreetsideImage(String.valueOf(image.getId() + Integer.valueOf(i)));
-                tiles.add(tile);
-              }
-              // Initialize four-tiled cubemap faces (four images per cub eside with 20-length
-              // Quadkey)
-              if (StreetsideProperties.SHOW_HIGH_RES_STREETSIDE_IMAGERY.get()) {
-                for (int j = 0; j < 4; j++) {
-                  StreetsideImage tile = new StreetsideImage(
-                    String.valueOf(
-                      image.getId() + face.getValue() + CubemapUtils.rowCol2StreetsideCellAddressMap
-                        .get(String.valueOf(Integer.valueOf(i).toString() + Integer.valueOf(j).toString()))
-                      ));
-                  tiles.add(tile
-              );
-                }
-              }
-            }
-          });
-
-          bubbleImages.add(image);
-          Logging.debug("Added image with id <" + image.getId() + ">");
+        // TODO: set previous and next @rrh
+
+					EnumSet.allOf(CubemapUtils.CubemapFaces.class).forEach(face -> {
+
+							for (int i = 0; i < 4; i++) {
+								// Initialize four-tiled cubemap faces (four images per cube side with 18-length
+								// Quadkey)
+								//if (StreetsideProperties.CUBEFACE_SIZE.get().intValue() == 4) {
+								if (!StreetsideProperties.SHOW_HIGH_RES_STREETSIDE_IMAGERY.get()) {
+									StreetsideImage tile = new StreetsideImage(
+											String.valueOf(image.getId() + Integer.valueOf(i)));
+									tiles.add(tile);
+								}
+								// Initialize four-tiled cubemap faces (four images per cub eside with 20-length
+								// Quadkey)
+								//if (StreetsideProperties.CUBEFACE_SIZE.get().intValue() == 16) {
+								if (StreetsideProperties.SHOW_HIGH_RES_STREETSIDE_IMAGERY.get()) {
+									for (int j = 0; j < 4; j++) {
+										StreetsideImage tile = new StreetsideImage(String.valueOf(image.getId()
+												+ face.getValue() + CubemapUtils.rowCol2StreetsideCellAddressMap
+														.get(String.valueOf(Integer.valueOf(i).toString() + Integer.valueOf(j).toString()))));
+										tiles.add(tile);
+									}
+								}
+							}
+					});
+
+      	  bubbleImages.add(image);
+          Logging.info("Added image with id <" + image.getId() + ">");
+          // TODO: double check whether this pre-caches successfullly @rrh
+          //StreetsideData.downloadSurroundingCubemaps(image);
 
         }
       }
 
-      parser.close();
+    parser.close();
+
+    //StreetsideImage[] images;
+
+      // First load all of the 'bubbles' from the request as Streetside Images
+      /*List<StreetsideImage> images = mapper
+        .readValue(new BufferedInputStream(con.getInputStream()), new TypeReference<List<StreetsideImage>>() {});
+      */
+
+
+      //images = mapper.readValue(new BufferedInputStream(con.getInputStream()), StreetsideImage[].class);
+
+      /*for (StreetsideImage image : bubbleImages) {
+        image = JsonStreetsideSequencesDecoder.decodeBubbleData(image);
+        if(image != null) bubbleImages.add(image);
+      }*/
 
     } catch (JsonParseException e) {
@@ -164,5 +190,5 @@
     }
 
-    final long endTime = System.nanoTime();//currentTimeMillis();
+    final long endTime = System.currentTimeMillis();
     Logging.info(I18n.tr("Sucessfully loaded {0} Microsoft Streetside images in {0} ",seq.getImages().size(),endTime-startTime%60));
   }
Index: /applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/io/export/package-info.java
===================================================================
--- /applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/io/export/package-info.java	(revision 34348)
+++ /applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/io/export/package-info.java	(revision 34349)
@@ -1,5 +1,5 @@
 // License: GPL. For details, see LICENSE file.
 /**
- * Classes for exporting images that were downloaded from <a href="https://www.microsoft.com/en-us/maps/streetside">Streetside</a>.
+ * Classes for exporting images that were downloaded from <a href="https://mapillary.com">mapillary.com</a> .
  */
 package org.openstreetmap.josm.plugins.streetside.io.export;
Index: /applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/utils/StreetsideURL.java
===================================================================
--- /applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/utils/StreetsideURL.java	(revision 34348)
+++ /applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/utils/StreetsideURL.java	(revision 34349)
@@ -236,50 +236,50 @@
 	}
 
-  public static URL[] string2URLs(String baseUrlPrefix, String cubemapImageId, String baseUrlSuffix) {
-    List<URL> res = new ArrayList<>();
-
-    switch (StreetsideProperties.SHOW_HIGH_RES_STREETSIDE_IMAGERY.get() ? 16 : 4) {
-
-    case 16:
-
-      EnumSet.allOf(CubemapUtils.CubemapFaces.class).forEach(face -> {
-        for (int i = 0; i < 4; i++) {
-          for (int j = 0; j < 4; j++) {
-            try {
-              final String urlStr = baseUrlPrefix + cubemapImageId + CubemapUtils.rowCol2StreetsideCellAddressMap
-                .get(String.valueOf(i) + String.valueOf(j)) + baseUrlSuffix;
-              res.add(new URL(urlStr));
-            } catch (final MalformedURLException e) {
-              Logging.error(I18n.tr("Error creating URL String for cubemap {0}", cubemapImageId));
-              e.printStackTrace();
-            }
-
-          }
-        }
-      });
-
-      break;
-
-    case 4:
-      EnumSet.allOf(CubemapUtils.CubemapFaces.class).forEach(face -> {
-        for (int i = 0; i < 4; i++) {
-
-          try {
-            final String urlStr = baseUrlPrefix + cubemapImageId
-              + CubemapUtils.rowCol2StreetsideCellAddressMap.get(String.valueOf(i)) + baseUrlSuffix;
-            res.add(new URL(urlStr));
-          } catch (final MalformedURLException e) {
-            Logging.error(I18n.tr("Error creating URL String for cubemap {0}", cubemapImageId));
-            e.printStackTrace();
-          }
-
-        }
-      });
-      break; // break is optional
-    default:
-      // Statements
-    }
-    return res.stream().toArray(URL[]::new);
-  }
+	public static URL[] string2URLs(String baseUrlPrefix, String cubemapImageId, String baseUrlSuffix) {
+		List<URL> res = new ArrayList<>();
+
+		switch (StreetsideProperties.SHOW_HIGH_RES_STREETSIDE_IMAGERY.get() ? 16 : 4) {
+
+		case 16:
+
+			EnumSet.allOf(CubemapUtils.CubemapFaces.class).forEach(face -> {
+				for (int i = 0; i < 4; i++) {
+					for (int j = 0; j < 4; j++) {
+						try {
+							final String urlStr = baseUrlPrefix + cubemapImageId
+									+ CubemapUtils.rowCol2StreetsideCellAddressMap
+											.get(String.valueOf(i) + String.valueOf(j))
+									+ baseUrlSuffix;
+							res.add(new URL(urlStr));
+						} catch (final MalformedURLException e) {
+							Logging.error(I18n.tr("Error creating URL String for cubemap {0}", cubemapImageId));
+							e.printStackTrace();
+						}
+
+					}
+				}
+			});
+
+		case 4:
+			EnumSet.allOf(CubemapUtils.CubemapFaces.class).forEach(face -> {
+				for (int i = 0; i < 4; i++) {
+
+					try {
+						final String urlStr = baseUrlPrefix + cubemapImageId
+								+ CubemapUtils.rowCol2StreetsideCellAddressMap.get(String.valueOf(i)) + baseUrlSuffix;
+						res.add(new URL(urlStr));
+					} catch (final MalformedURLException e) {
+						Logging.error(I18n.tr("Error creating URL String for cubemap {0}", cubemapImageId));
+						e.printStackTrace();
+					}
+
+				}
+			});
+			break; // break is optional
+		default:
+			// Statements
+		}
+		return res.stream().toArray(URL[]::new);
+	}
 
 	/**
