diff --git a/data/maps.xsd b/data/maps.xsd
index 59fa397..98195bb 100644
--- a/data/maps.xsd
+++ b/data/maps.xsd
@@ -623,6 +623,8 @@
 						<xs:element name="terms-of-use-url" minOccurs="0" maxOccurs="1" type="xs:string" />
 						<!-- The ISO 3166 country code -->
 						<xs:element name="country-code" minOccurs="0" maxOccurs="1" type="tns:iso3166" />
+                                                <!-- A base64-encoded image that is displayed as menu/toolbar icon -->
+						<xs:element name="icon" minOccurs="0" maxOccurs="1" type="xs:string" />
 					</xs:all>
 				</xs:complexType>
 			</xs:element>
diff --git a/src/org/openstreetmap/josm/actions/AddImageryLayerAction.java b/src/org/openstreetmap/josm/actions/AddImageryLayerAction.java
index 95cccca..80cfa4d 100644
--- a/src/org/openstreetmap/josm/actions/AddImageryLayerAction.java
+++ b/src/org/openstreetmap/josm/actions/AddImageryLayerAction.java
@@ -3,24 +3,43 @@ package org.openstreetmap.josm.actions;
 
 import static org.openstreetmap.josm.tools.I18n.tr;
 
+import java.awt.Image;
 import java.awt.event.ActionEvent;
-
+import javax.swing.Action;
+import javax.swing.ImageIcon;
 import javax.swing.JOptionPane;
-
 import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.data.imagery.ImageryInfo;
 import org.openstreetmap.josm.data.imagery.ImageryInfo.ImageryType;
 import org.openstreetmap.josm.gui.layer.ImageryLayer;
+import org.openstreetmap.josm.tools.ImageProvider;
 
 public class AddImageryLayerAction extends JosmAction implements AdaptableAction {
 
+    private static final int MAX_ICON_SIZE = 24;
     private final ImageryInfo info;
 
     public AddImageryLayerAction(ImageryInfo info) {
-        super(info.getMenuName(), /* ICON */"imagery_menu", tr("Add imagery layer {0}",info.getName()), null, false, false);
+        super(info.getMenuName(),
+                /* ICON */ "imagery_menu",
+                tr("Add imagery layer {0}", info.getName()),
+                null, false, false);
         putValue("toolbar", "imagery_" + info.getToolbarName());
         this.info = info;
         installAdapters();
+
+        // change toolbar icon from if specified
+        try {
+            if (info.getIcon() != null) {
+                ImageIcon i = ImageProvider.getIfAvailable(info.getIcon());
+                if (i.getIconHeight() > MAX_ICON_SIZE || i.getIconWidth() > MAX_ICON_SIZE) {
+                    i = new ImageIcon(i.getImage().getScaledInstance(MAX_ICON_SIZE, MAX_ICON_SIZE, Image.SCALE_SMOOTH));
+                }
+                putValue(Action.SMALL_ICON, i);
+            }
+        } catch (Exception ex) {
+            throw new RuntimeException(ex.getMessage(), ex);
+        }
     }
 
     @Override
@@ -52,4 +71,4 @@ public class AddImageryLayerAction extends JosmAction implements AdaptableAction
             setEnabled(false);
         }
     }
-}
+}
\ No newline at end of file
diff --git a/src/org/openstreetmap/josm/data/imagery/ImageryInfo.java b/src/org/openstreetmap/josm/data/imagery/ImageryInfo.java
index 955d94e..538eda4 100644
--- a/src/org/openstreetmap/josm/data/imagery/ImageryInfo.java
+++ b/src/org/openstreetmap/josm/data/imagery/ImageryInfo.java
@@ -84,6 +84,7 @@ public class ImageryInfo implements Comparable<ImageryInfo>, Attributed {
     private String termsOfUseText;
     private String termsOfUseURL;
     private String countryCode = "";
+    private String icon;
 
     /** auxiliary class to save an ImageryInfo object in the preferences */
     public static class ImageryPreferenceEntry {
@@ -105,6 +106,7 @@ public class ImageryInfo implements Comparable<ImageryInfo>, Attributed {
         @pref String bounds;
         @pref String shapes;
         @pref String projections;
+        @pref String icon;
 
         public ImageryPreferenceEntry() {
         }
@@ -125,6 +127,7 @@ public class ImageryInfo implements Comparable<ImageryInfo>, Attributed {
             max_zoom = i.defaultMaxZoom;
             min_zoom = i.defaultMinZoom;
             cookies = i.cookies;
+            icon = i.icon;
             if (i.bounds != null) {
                 bounds = i.bounds.encodeAsString(",");
                 String shapesString = "";
@@ -218,6 +221,7 @@ public class ImageryInfo implements Comparable<ImageryInfo>, Attributed {
         termsOfUseText = e.terms_of_use_text;
         termsOfUseURL = e.terms_of_use_url;
         countryCode = e.country_code;
+        icon = e.icon;
     }
 
     public ImageryInfo(Collection<String> list) {
@@ -284,6 +288,7 @@ public class ImageryInfo implements Comparable<ImageryInfo>, Attributed {
         this.termsOfUseText = i.termsOfUseText;
         this.termsOfUseURL = i.termsOfUseURL;
         this.serverProjections = i.serverProjections;
+        this.icon = i.icon;
     }
 
     @Override
@@ -514,6 +519,14 @@ public class ImageryInfo implements Comparable<ImageryInfo>, Attributed {
         this.countryCode = countryCode;
     }
 
+    public String getIcon() {
+        return icon;
+    }
+
+    public void setIcon(String icon) {
+        this.icon = icon;
+    }
+
     /**
      * Get the projections supported by the server. Only relevant for
      * WMS-type ImageryInfo at the moment.
diff --git a/src/org/openstreetmap/josm/io/imagery/ImageryReader.java b/src/org/openstreetmap/josm/io/imagery/ImageryReader.java
index acdec59..10f8ab3 100644
--- a/src/org/openstreetmap/josm/io/imagery/ImageryReader.java
+++ b/src/org/openstreetmap/josm/io/imagery/ImageryReader.java
@@ -4,11 +4,8 @@ package org.openstreetmap.josm.io.imagery;
 import static org.openstreetmap.josm.tools.I18n.tr;
 import static org.openstreetmap.josm.tools.Utils.equal;
 
-import java.io.BufferedReader;
 import java.io.IOException;
 import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.UnsupportedEncodingException;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
@@ -17,14 +14,12 @@ import java.util.Stack;
 import javax.xml.parsers.ParserConfigurationException;
 import javax.xml.parsers.SAXParserFactory;
 
-import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.data.imagery.ImageryInfo;
 import org.openstreetmap.josm.data.imagery.ImageryInfo.ImageryBounds;
 import org.openstreetmap.josm.data.imagery.ImageryInfo.ImageryType;
 import org.openstreetmap.josm.data.imagery.Shape;
 import org.openstreetmap.josm.io.MirroredInputStream;
 import org.openstreetmap.josm.io.UTFInputStreamReader;
-import org.openstreetmap.josm.tools.Utils;
 import org.xml.sax.Attributes;
 import org.xml.sax.InputSource;
 import org.xml.sax.SAXException;
@@ -129,6 +124,7 @@ public class ImageryReader {
                         "terms-of-use-text",
                         "terms-of-use-url",
                         "country-code",
+                        "icon",
                     }).contains(qName)) {
                         newState = State.ENTRY_ATTRIBUTE;
                     } else if (qName.equals("bounds")) {
@@ -259,6 +255,8 @@ public class ImageryReader {
                         entry.setTermsOfUseURL(accumulator.toString());
                     } else if (qName.equals("country-code")) {
                         entry.setCountryCode(accumulator.toString());
+                    } else if (qName.equals("icon")) {
+                        entry.setIcon(accumulator.toString());
                     } else {
                     }
                     break;
diff --git a/src/org/openstreetmap/josm/tools/ImageProvider.java b/src/org/openstreetmap/josm/tools/ImageProvider.java
index 39678d6..06ee30c 100644
--- a/src/org/openstreetmap/josm/tools/ImageProvider.java
+++ b/src/org/openstreetmap/josm/tools/ImageProvider.java
@@ -20,23 +20,26 @@ import java.io.ByteArrayInputStream;
 import java.io.File;
 import java.io.IOException;
 import java.io.InputStream;
+import java.io.UnsupportedEncodingException;
 import java.net.MalformedURLException;
 import java.net.URI;
 import java.net.URL;
+import java.net.URLDecoder;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.HashMap;
 import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 import java.util.zip.ZipEntry;
 import java.util.zip.ZipFile;
 import javax.swing.Icon;
 import javax.swing.ImageIcon;
-
+import org.apache.commons.codec.binary.Base64;
 import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.data.osm.OsmPrimitiveType;
 import org.openstreetmap.josm.io.MirroredInputStream;
 import org.openstreetmap.josm.plugins.PluginHandler;
-import org.openstreetmap.josm.tools.Utils;
 import org.xml.sax.Attributes;
 import org.xml.sax.EntityResolver;
 import org.xml.sax.InputSource;
@@ -44,7 +47,6 @@ import org.xml.sax.SAXException;
 import org.xml.sax.XMLReader;
 import org.xml.sax.helpers.DefaultHandler;
 import org.xml.sax.helpers.XMLReaderFactory;
-
 import com.kitfox.svg.SVGDiagram;
 import com.kitfox.svg.SVGException;
 import com.kitfox.svg.SVGUniverse;
@@ -153,11 +155,35 @@ public class ImageProvider {
         return ir.getImageIcon(dim == null ? ImageResource.DEFAULT_DIMENSION : dim, sanitize);
     }
 
+    /**
+     * {@code data:[<mediatype>][;base64],<data>}
+     * @see RFC2397
+     */
+    private static final Pattern dataUrlPattern = Pattern.compile(
+            "^data:([a-zA-Z]+/[a-zA-Z]+)?(;base64)?,(.+)$");
+
     private static ImageResource getIfAvailableImpl(Collection<String> dirs, String id, String subdir, String name, File archive) {
         if (name == null)
             return null;
         ImageType type = name.toLowerCase().endsWith(".svg") ? ImageType.SVG : ImageType.OTHER;
 
+        try {
+            if (name.startsWith("data:")) {
+                Matcher m = dataUrlPattern.matcher(name);
+                if (m.matches()) {
+                    String mediatype = m.group(1);
+                    String base64 = m.group(2);
+                    String data = m.group(3);
+                    byte[] bytes = ";base64".equals(base64)
+                            ? Base64.decodeBase64(data)
+                            : URLDecoder.decode(data, "utf-8").getBytes();
+                    return new ImageResource(new ImageIcon(bytes).getImage(), true);
+                }
+            }
+        } catch (UnsupportedEncodingException ex) {
+            throw new RuntimeException(ex.getMessage(), ex);
+        }
+
         if (name.startsWith("http://")) {
             String url = name;
             ImageResource ir = cache.get(url);
