Index: src/org/openstreetmap/gui/jmapviewer/tilesources/BingAerialTileSource.java
===================================================================
--- src/org/openstreetmap/gui/jmapviewer/tilesources/BingAerialTileSource.java	(revision 36329)
+++ src/org/openstreetmap/gui/jmapviewer/tilesources/BingAerialTileSource.java	(working copy)
@@ -75,6 +75,7 @@
     private String[] subdomains;
     private String brandLogoUri;
     private String layer = "Aerial";
+    private final String imageryId = "Bing";
 
     /**
      * Constructs a new {@code BingAerialTileSource}.
@@ -131,7 +132,7 @@
     protected URL getAttributionUrl() throws MalformedURLException {
         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_PLACEHOLDER, getKey())
                     .replace(API_KEY_LAYER, this.layer)).toURL();
         } catch (URISyntaxException e) {
             MalformedURLException malformedURLException = new MalformedURLException(e.getMessage());
@@ -140,6 +141,35 @@
         }
     }
 
+    /**
+     * Get the API key for Bing imagery
+     * Order of preference is as follows:
+     * <ol>
+     *     <li>Custom API key provided by {@link FeatureAdapter#getSetting(String, String)} via {@link #API_KEY_SETTING}</li>
+     *     <li>API key provided by {@link FeatureAdapter#retrieveApiKey(String)}</li>
+     *     <li>The hardcoded API key. This should not be used whenever possible.</li>
+     * </ol>
+     * @return The API key to use
+     */
+    private String getKey() {
+        // Preference order for key
+        // 1. Custom API key
+        // 2. Remote API key
+        // 3. Hardcoded API key
+        final String customKey = FeatureAdapter.getSetting(API_KEY_SETTING, API_KEY);
+        String key;
+        try {
+            key = FeatureAdapter.retrieveApiKey(imageryId); // id is getURL from info, for some reason. Probably Bing.
+            if (!API_KEY.equals(customKey)) {
+                key = customKey;
+            }
+        } catch (IOException ioException) {
+            FeatureAdapter.getLogger(this.getClass()).log(Level.WARNING, "Failed to retrieve api key", ioException);
+            key = customKey;
+        }
+        return key;
+    }
+
     protected List<Attribution> parseAttributionText(InputSource xml) throws IOException {
         try {
             DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
