Index: applications/viewer/jmapviewer/src/org/openstreetmap/gui/jmapviewer/FeatureAdapter.java
===================================================================
--- applications/viewer/jmapviewer/src/org/openstreetmap/gui/jmapviewer/FeatureAdapter.java	(revision 36223)
+++ applications/viewer/jmapviewer/src/org/openstreetmap/gui/jmapviewer/FeatureAdapter.java	(revision 36292)
@@ -217,4 +217,15 @@
 
     /**
+     * Reads an image using the current {@link ImageAdapter}.
+     * @param url image URI to read
+     * @return a <code>BufferedImage</code> containing the decoded contents of the input, or <code>null</code>.
+     * @throws java.net.MalformedURLException if the URI could not be converted to a URL
+     * @throws IOException if an error occurs during reading.
+     */
+    public static BufferedImage readImage(URI url) throws IOException {
+        return imageAdapter.read(url.toURL(), false, false);
+    }
+
+    /**
      * Translates a text using the current {@link TranslationAdapter}.
      * @param text the text to translate.
Index: applications/viewer/jmapviewer/src/org/openstreetmap/gui/jmapviewer/tilesources/BingAerialTileSource.java
===================================================================
--- applications/viewer/jmapviewer/src/org/openstreetmap/gui/jmapviewer/tilesources/BingAerialTileSource.java	(revision 36223)
+++ applications/viewer/jmapviewer/src/org/openstreetmap/gui/jmapviewer/tilesources/BingAerialTileSource.java	(revision 36292)
@@ -5,4 +5,6 @@
 import java.io.IOException;
 import java.net.MalformedURLException;
+import java.net.URI;
+import java.net.URISyntaxException;
 import java.net.URL;
 import java.util.ArrayList;
@@ -128,7 +130,13 @@
 
     protected URL getAttributionUrl() throws MalformedURLException {
-        return new URL(FeatureAdapter.getSetting(METADATA_API_SETTING, METADATA_API_URL)
-                .replace(API_KEY_PLACEHOLDER, FeatureAdapter.getSetting(API_KEY_SETTING, API_KEY))
-                .replace(API_KEY_LAYER, this.layer));
+        try {
+            return new URI(FeatureAdapter.getSetting(METADATA_API_SETTING, METADATA_API_URL)
+                    .replace(API_KEY_PLACEHOLDER, FeatureAdapter.getSetting(API_KEY_SETTING, API_KEY))
+                    .replace(API_KEY_LAYER, this.layer)).toURL();
+        } catch (URISyntaxException e) {
+            MalformedURLException malformedURLException = new MalformedURLException(e.getMessage());
+            malformedURLException.initCause(e);
+            throw malformedURLException;
+        }
     }
 
@@ -233,9 +241,9 @@
                 if (brandLogoUri != null && !brandLogoUri.isEmpty()) {
                     LOG.log(Level.FINE, "Reading Bing logo from {0}", brandLogoUri);
-                    return FeatureAdapter.readImage(new URL(brandLogoUri));
-                }
-            }
-        } catch (IOException e) {
-            LOG.log(Level.SEVERE, "Error while retrieving Bing logo: "+e.getMessage());
+                    return FeatureAdapter.readImage(new URI(brandLogoUri));
+                }
+            }
+        } catch (URISyntaxException | IOException e) {
+            LOG.log(Level.SEVERE, String.format("Error while retrieving Bing logo: %s", e.getMessage()));
         }
         return null;
@@ -267,5 +275,5 @@
                     return r;
                 } catch (IOException ex) {
-                    LOG.log(Level.SEVERE, "Could not connect to Bing API. Will retry in " + waitTimeSec + " seconds.");
+                    LOG.log(Level.SEVERE, String.format("Could not connect to Bing API. Will retry in %d seconds.", waitTimeSec));
                     LOG.log(Level.FINE, ex.getMessage(), ex);
                     Thread.sleep(TimeUnit.SECONDS.toMillis(waitTimeSec));
@@ -276,4 +284,8 @@
     }
 
+    /**
+     * Get the attribution data that is currently loaded
+     * @return The list of {@link Attribution} data or {@code null}, if no attribution data has been loaded yet.
+     */
     protected List<Attribution> getAttribution() {
         if (attributions == null) {
@@ -287,12 +299,14 @@
             }
         }
-        try {
-            return attributions.get();
-        } catch (ExecutionException ex) {
-            throw new JMapViewerRuntimeException(ex);
-        } catch (InterruptedException ign) {
-            LOG.log(Level.SEVERE, "InterruptedException: {0}", ign.getMessage());
-            LOG.log(Level.FINE, ign.getMessage(), ign);
-            Thread.currentThread().interrupt();
+        if (attributions.isDone()) {
+            try {
+                return attributions.get();
+            } catch (ExecutionException ex) {
+                throw new JMapViewerRuntimeException(ex);
+            } catch (InterruptedException ign) {
+                LOG.log(Level.SEVERE, "InterruptedException: {0}", ign.getMessage());
+                LOG.log(Level.FINE, ign.getMessage(), ign);
+                Thread.currentThread().interrupt();
+            }
         }
         return null;
