Index: /trunk/src/org/openstreetmap/josm/data/osm/visitor/paint/StyledMapRenderer.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/data/osm/visitor/paint/StyledMapRenderer.java	(revision 6171)
+++ /trunk/src/org/openstreetmap/josm/data/osm/visitor/paint/StyledMapRenderer.java	(revision 6172)
@@ -6,4 +6,5 @@
 import java.awt.Color;
 import java.awt.Component;
+import java.awt.Dimension;
 import java.awt.Font;
 import java.awt.FontMetrics;
@@ -29,7 +30,7 @@
 import java.util.Iterator;
 import java.util.List;
+
 import javax.swing.AbstractButton;
 import javax.swing.FocusManager;
-import javax.swing.ImageIcon;
 
 import org.openstreetmap.josm.Main;
@@ -904,9 +905,6 @@
 
     public void drawRestriction(Image img, Point pVia, double vx, double vx2, double vy, double vy2, double angle, boolean selected) {
-        /* rotate image with direction last node in from to */
-        Image rotatedImg = ImageProvider.createRotatedImage(null , img, angle);
-
-        /* scale down image to 16*16 pixels */
-        Image smallImg = new ImageIcon(rotatedImg.getScaledInstance(16 , 16, Image.SCALE_SMOOTH)).getImage();
+        // rotate image with direction last node in from to, and scale down image to 16*16 pixels
+        Image smallImg = ImageProvider.createRotatedImage(img, angle, new Dimension(16, 16));
         int w = smallImg.getWidth(null), h=smallImg.getHeight(null);
         g.drawImage(smallImg, (int)(pVia.x+vx+vx2)-w/2, (int)(pVia.y+vy+vy2)-h/2, nc);
Index: /trunk/src/org/openstreetmap/josm/gui/dialogs/DialogsPanel.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/dialogs/DialogsPanel.java	(revision 6171)
+++ /trunk/src/org/openstreetmap/josm/gui/dialogs/DialogsPanel.java	(revision 6172)
@@ -1,4 +1,3 @@
 // License: GPL. See LICENSE file for details.
-
 package org.openstreetmap.josm.gui.dialogs;
 
@@ -11,11 +10,12 @@
 import javax.swing.JSplitPane;
 
-import org.openstreetmap.josm.gui.MultiSplitPane;
 import org.openstreetmap.josm.gui.MultiSplitLayout.Divider;
 import org.openstreetmap.josm.gui.MultiSplitLayout.Leaf;
 import org.openstreetmap.josm.gui.MultiSplitLayout.Node;
 import org.openstreetmap.josm.gui.MultiSplitLayout.Split;
-
-public class DialogsPanel extends JPanel {
+import org.openstreetmap.josm.gui.MultiSplitPane;
+import org.openstreetmap.josm.tools.Destroyable;
+
+public class DialogsPanel extends JPanel implements Destroyable {
     protected List<ToggleDialog> allDialogs = new ArrayList<ToggleDialog>();
     protected MultiSplitPane mSpltPane = new MultiSplitPane();
@@ -292,4 +292,5 @@
     }
 
+    @Override
     public void destroy() {
         for (ToggleDialog t : allDialogs) {
Index: /trunk/src/org/openstreetmap/josm/gui/dialogs/ToggleDialog.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/dialogs/ToggleDialog.java	(revision 6171)
+++ /trunk/src/org/openstreetmap/josm/gui/dialogs/ToggleDialog.java	(revision 6172)
@@ -13,5 +13,4 @@
 import java.awt.GridBagLayout;
 import java.awt.GridLayout;
-import java.awt.Image;
 import java.awt.Rectangle;
 import java.awt.Toolkit;
@@ -33,5 +32,4 @@
 import javax.swing.AbstractAction;
 import javax.swing.BorderFactory;
-import javax.swing.ImageIcon;
 import javax.swing.JButton;
 import javax.swing.JCheckBoxMenuItem;
@@ -462,7 +460,5 @@
 
             // scale down the dialog icon
-            ImageIcon inIcon = ImageProvider.get("dialogs", iconName);
-            ImageIcon smallIcon = new ImageIcon(inIcon.getImage().getScaledInstance(16 , 16, Image.SCALE_SMOOTH));
-            lblTitle = new JLabel("",smallIcon, JLabel.TRAILING);
+            lblTitle = new JLabel("", new ImageProvider("dialogs", iconName).setWidth(16).get(), JLabel.TRAILING);
             lblTitle.setIconTextGap(8);
 
@@ -500,7 +496,5 @@
             // show the pref button if applicable
             if (preferenceClass != null) {
-                inIcon = ImageProvider.get("preference");
-                smallIcon = new ImageIcon(inIcon.getImage().getScaledInstance(16 , 16, Image.SCALE_SMOOTH));
-                JButton pref = new JButton(smallIcon);
+                JButton pref = new JButton(new ImageProvider("preference").setWidth(16).get());
                 pref.setToolTipText(tr("Open preferences for this panel"));
                 pref.setBorder(BorderFactory.createEmptyBorder());
Index: /trunk/src/org/openstreetmap/josm/gui/mappaint/NodeElemStyle.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/mappaint/NodeElemStyle.java	(revision 6171)
+++ /trunk/src/org/openstreetmap/josm/gui/mappaint/NodeElemStyle.java	(revision 6172)
@@ -6,4 +6,5 @@
 import java.awt.BasicStroke;
 import java.awt.Color;
+import java.awt.Image;
 import java.awt.Rectangle;
 import java.awt.Stroke;
@@ -19,4 +20,5 @@
 import org.openstreetmap.josm.gui.mappaint.MapPaintStyles.IconReference;
 import org.openstreetmap.josm.gui.mappaint.StyleCache.StyleList;
+import org.openstreetmap.josm.tools.ImageProvider;
 import org.openstreetmap.josm.tools.Utils;
 
@@ -25,6 +27,9 @@
  */
 public class NodeElemStyle extends ElemStyle implements StyleKeys {
-    public MapImage mapImage;
-    public Symbol symbol;
+    public final MapImage mapImage;
+    public final Symbol symbol;
+    
+    private Image enabledNodeIcon;
+    private Image disabledNodeIcon;
 
     public enum SymbolShape { SQUARE, CIRCLE, TRIANGLE, PENTAGON, HEXAGON, HEPTAGON, OCTAGON, NONAGON, DECAGON }
@@ -230,4 +235,15 @@
     }
 
+    private Image getRealNodeIcon(final Image image) {
+        final int maxSize = 16;
+        // Scale down large (.svg) images to 16x16 pixels if no size is explicitely specified
+        if ((mapImage.width  == -1 && image.getWidth(null) > maxSize) 
+         || (mapImage.height == -1 && image.getHeight(null) > maxSize)) {
+            return ImageProvider.createBoundedImage(image, maxSize);
+        } else {
+            return image;
+        }
+    }
+    
     @Override
     public void paintPrimitive(OsmPrimitive primitive, MapPaintSettings settings, StyledMapRenderer painter, boolean selected, boolean member) {
@@ -235,6 +251,17 @@
             Node n = (Node) primitive;
             if (mapImage != null && painter.isShowIcons()) {
-                painter.drawNodeIcon(n, (painter.isInactiveMode() || n.isDisabled()) ? mapImage.getDisabled() : mapImage.getImage(),
-                        Utils.color_int2float(mapImage.alpha), selected, member);
+                final Image nodeIcon;
+                if (painter.isInactiveMode() || n.isDisabled()) {
+                    if (disabledNodeIcon == null) {
+                        disabledNodeIcon = getRealNodeIcon(mapImage.getDisabled());
+                    }
+                    nodeIcon = disabledNodeIcon;
+                } else {
+                    if (enabledNodeIcon == null) {
+                        enabledNodeIcon = getRealNodeIcon(mapImage.getImage());
+                    }
+                    nodeIcon = enabledNodeIcon;
+                }
+                painter.drawNodeIcon(n, nodeIcon, Utils.color_int2float(mapImage.alpha), selected, member);
             } else if (symbol != null) {
                 Color fillColor = symbol.fillColor;
Index: /trunk/src/org/openstreetmap/josm/gui/widgets/TextContextualPopupMenu.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/widgets/TextContextualPopupMenu.java	(revision 6171)
+++ /trunk/src/org/openstreetmap/josm/gui/widgets/TextContextualPopupMenu.java	(revision 6172)
@@ -4,5 +4,4 @@
 import static org.openstreetmap.josm.tools.I18n.tr;
 
-import java.awt.Image;
 import java.awt.event.ActionEvent;
 import java.beans.PropertyChangeEvent;
@@ -149,7 +148,7 @@
             mi.setText(label);
             if (iconName != null && Main.pref.getBoolean("text.popupmenu.useicons", true)) {
-                ImageIcon icon = ImageProvider.get(iconName);
+                ImageIcon icon = new ImageProvider(iconName).setWidth(16).get();
                 if (icon != null) {
-                    mi.setIcon(new ImageIcon(icon.getImage().getScaledInstance(16 , 16, Image.SCALE_SMOOTH)));
+                    mi.setIcon(icon);
                 }
             }
Index: /trunk/src/org/openstreetmap/josm/tools/ImageProvider.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/tools/ImageProvider.java	(revision 6171)
+++ /trunk/src/org/openstreetmap/josm/tools/ImageProvider.java	(revision 6172)
@@ -4,5 +4,4 @@
 import static org.openstreetmap.josm.tools.I18n.tr;
 
-import java.awt.Component;
 import java.awt.Cursor;
 import java.awt.Dimension;
@@ -83,7 +82,12 @@
     }
 
+    /**
+     * Supported image types
+     */
     public static enum ImageType {
-        SVG,    // scalable vector graphics
-        OTHER   // everything else, e.g. png, gif (must be supported by Java)
+        /** Scalable vector graphics */
+        SVG,
+        /** Everything else, e.g. png, gif (must be supported by Java) */
+        OTHER
     }
 
@@ -107,7 +111,12 @@
      * The icon cache
      */
-    private static Map<String, ImageResource> cache = new HashMap<String, ImageResource>();
-
-    private final static ExecutorService imageFetcher = Executors.newSingleThreadExecutor();
+    private static final Map<String, ImageResource> cache = new HashMap<String, ImageResource>();
+
+    /**
+     * Caches the image data for rotated versions of the same image.
+     */
+    private static final Map<Image, Map<Long, ImageResource>> rotateCache = new HashMap<Image, Map<Long, ImageResource>>();
+
+    private static final ExecutorService imageFetcher = Executors.newSingleThreadExecutor();
 
     public interface ImageCallback {
@@ -116,4 +125,5 @@
 
     /**
+     * Constructs a new {@code ImageProvider} from a filename in a given directory.
      * @param subdir    subdirectory the image lies in
      * @param name      the name of the image. If it does not end with '.png' or '.svg',
@@ -125,4 +135,9 @@
     }
 
+    /**
+     * Constructs a new {@code ImageProvider} from a filename.
+     * @param name      the name of the image. If it does not end with '.png' or '.svg',
+     *                  both extensions are tried.
+     */
     public ImageProvider(String name) {
         this.name = name;
@@ -131,4 +146,6 @@
     /**
      * Directories to look for the image.
+     * @param dirs The directories to look for.
+     * @return the current object, for convenience
      */
     public ImageProvider setDirs(Collection<String> dirs) {
@@ -141,4 +158,5 @@
      * If name starts with <tt>http://</tt> Id is not used for the cache.
      * (A URL is unique anyway.)
+     * @return the current object, for convenience
      */
     public ImageProvider setId(String id) {
@@ -151,4 +169,5 @@
      *
      * (optional)
+     * @return the current object, for convenience
      */
     public ImageProvider setArchive(File archive) {
@@ -163,4 +182,5 @@
      *
      * (optional)
+     * @return the current object, for convenience
      */
     public ImageProvider setInArchiveDir(String inArchiveDir) {
@@ -175,4 +195,5 @@
      * The width part of the dimension can be -1. Then it will only set the height but
      * keep the aspect ratio. (And the other way around.)
+     * @return the current object, for convenience
      */
     public ImageProvider setSize(Dimension size) {
@@ -184,4 +205,5 @@
     /**
      * @see #setSize
+     * @return the current object, for convenience
      */
     public ImageProvider setWidth(int width) {
@@ -192,4 +214,5 @@
     /**
      * @see #setSize
+     * @return the current object, for convenience
      */
     public ImageProvider setHeight(int height) {
@@ -205,4 +228,5 @@
      *
      * 'size' and 'maxSize' are not compatible, you should set only one of them.
+     * @return the current object, for convenience
      */
     public ImageProvider setMaxSize(Dimension maxSize) {
@@ -214,4 +238,5 @@
     /**
      * Convenience method, see {@link #setMaxSize(Dimension)}.
+     * @return the current object, for convenience
      */
     public ImageProvider setMaxSize(int maxSize) {
@@ -221,4 +246,5 @@
     /**
      * @see #setMaxSize
+     * @return the current object, for convenience
      */
     public ImageProvider setMaxWidth(int maxWidth) {
@@ -229,4 +255,5 @@
     /**
      * @see #setMaxSize
+     * @return the current object, for convenience
      */
     public ImageProvider setMaxHeight(int maxHeight) {
@@ -253,4 +280,5 @@
      *
      * In combination with setOptional(true);
+     * @return the current object, for convenience
      */
     public ImageProvider setSuppressWarnings(boolean suppressWarnings) {
@@ -261,4 +289,5 @@
     /**
      * Add a collection of additional class loaders to search image for.
+     * @return the current object, for convenience
      */
     public ImageProvider setAdditionalClassLoaders(Collection<ClassLoader> additionalClassLoaders) {
@@ -388,6 +417,4 @@
                 }
             } catch (UnsupportedEncodingException ex) {
-                throw new RuntimeException(ex.getMessage(), ex);
-            } catch (IOException ex) {
                 throw new RuntimeException(ex.getMessage(), ex);
             }
@@ -482,6 +509,7 @@
 
     private static ImageResource getIfAvailableHttp(String url, ImageType type) {
+        MirroredInputStream is = null;
         try {
-            MirroredInputStream is = new MirroredInputStream(url,
+            is = new MirroredInputStream(url,
                     new File(Main.pref.getCacheDirectory(), "images").getPath());
             switch (type) {
@@ -501,4 +529,6 @@
         } catch (IOException e) {
             return null;
+        } finally {
+            Utils.close(is);
         }
     }
@@ -791,60 +821,105 @@
      * Creates a rotated version of the input image.
      *
-     * @param c The component to get properties useful for painting, e.g. the foreground or
-     * background color.
      * @param img the image to be rotated.
      * @param rotatedAngle the rotated angle, in degree, clockwise. It could be any double but we
-     * will mod it with 360 before using it.
+     * will mod it with 360 before using it. More over for caching performance, it will be rounded to 
+     * an entire value between 0 and 360.
      *
      * @return the image after rotating.
-     */
-    public static Image createRotatedImage(Component c, Image img, double rotatedAngle) {
-        // convert rotatedAngle to a value from 0 to 360
-        double originalAngle = rotatedAngle % 360;
+     * @since 6172
+     */
+    public static Image createRotatedImage(Image img, double rotatedAngle) {
+        return createRotatedImage(img, rotatedAngle, ImageResource.DEFAULT_DIMENSION);
+    }
+    
+    /**
+     * Creates a rotated version of the input image, scaled to the given dimension.
+     *
+     * @param img the image to be rotated.
+     * @param rotatedAngle the rotated angle, in degree, clockwise. It could be any double but we
+     * will mod it with 360 before using it. More over for caching performance, it will be rounded to 
+     * an entire value between 0 and 360.
+     * @param dimension The requested dimensions. Use (-1,-1) for the original size
+     * and (width, -1) to set the width, but otherwise scale the image proportionally.
+     * @return the image after rotating and scaling.
+     * @since 6172
+     */
+    public static Image createRotatedImage(Image img, double rotatedAngle, Dimension dimension) {
+        CheckParameterUtil.ensureParameterNotNull(img, "img");
+        
+        // convert rotatedAngle to an integer value from 0 to 360
+        Long originalAngle = Math.round(rotatedAngle % 360);
         if (rotatedAngle != 0 && originalAngle == 0) {
-            originalAngle = 360.0;
-        }
-
-        // convert originalAngle to a value from 0 to 90
-        double angle = originalAngle % 90;
-        if (originalAngle != 0.0 && angle == 0.0) {
-            angle = 90.0;
-        }
-
-        double radian = Math.toRadians(angle);
-
-        new ImageIcon(img); // load completely
-        int iw = img.getWidth(null);
-        int ih = img.getHeight(null);
-        int w;
-        int h;
-
-        if ((originalAngle >= 0 && originalAngle <= 90) || (originalAngle > 180 && originalAngle <= 270)) {
-            w = (int) (iw * Math.sin(DEGREE_90 - radian) + ih * Math.sin(radian));
-            h = (int) (iw * Math.sin(radian) + ih * Math.sin(DEGREE_90 - radian));
-        } else {
-            w = (int) (ih * Math.sin(DEGREE_90 - radian) + iw * Math.sin(radian));
-            h = (int) (ih * Math.sin(radian) + iw * Math.sin(DEGREE_90 - radian));
-        }
-        BufferedImage image = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
-        Graphics g = image.getGraphics();
-        Graphics2D g2d = (Graphics2D) g.create();
-
-        // calculate the center of the icon.
-        int cx = iw / 2;
-        int cy = ih / 2;
-
-        // move the graphics center point to the center of the icon.
-        g2d.translate(w / 2, h / 2);
-
-        // rotate the graphics about the center point of the icon
-        g2d.rotate(Math.toRadians(originalAngle));
-
-        g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
-        g2d.drawImage(img, -cx, -cy, c);
-
-        g2d.dispose();
-        new ImageIcon(image); // load completely
-        return image;
+            originalAngle = 360L;
+        }
+        
+        ImageResource imageResource = null;
+
+        synchronized (rotateCache) {
+            Map<Long, ImageResource> cacheByAngle = rotateCache.get(img);
+            if (cacheByAngle == null) {
+                rotateCache.put(img, cacheByAngle = new HashMap<Long, ImageResource>());
+            }
+            
+            imageResource = cacheByAngle.get(originalAngle);
+            
+            if (imageResource == null) {
+                // convert originalAngle to a value from 0 to 90
+                double angle = originalAngle % 90;
+                if (originalAngle != 0.0 && angle == 0.0) {
+                    angle = 90.0;
+                }
+        
+                double radian = Math.toRadians(angle);
+        
+                new ImageIcon(img); // load completely
+                int iw = img.getWidth(null);
+                int ih = img.getHeight(null);
+                int w;
+                int h;
+        
+                if ((originalAngle >= 0 && originalAngle <= 90) || (originalAngle > 180 && originalAngle <= 270)) {
+                    w = (int) (iw * Math.sin(DEGREE_90 - radian) + ih * Math.sin(radian));
+                    h = (int) (iw * Math.sin(radian) + ih * Math.sin(DEGREE_90 - radian));
+                } else {
+                    w = (int) (ih * Math.sin(DEGREE_90 - radian) + iw * Math.sin(radian));
+                    h = (int) (ih * Math.sin(radian) + iw * Math.sin(DEGREE_90 - radian));
+                }
+                Image image = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
+                cacheByAngle.put(originalAngle, imageResource = new ImageResource(image));
+                Graphics g = image.getGraphics();
+                Graphics2D g2d = (Graphics2D) g.create();
+        
+                // calculate the center of the icon.
+                int cx = iw / 2;
+                int cy = ih / 2;
+        
+                // move the graphics center point to the center of the icon.
+                g2d.translate(w / 2, h / 2);
+        
+                // rotate the graphics about the center point of the icon
+                g2d.rotate(Math.toRadians(originalAngle));
+        
+                g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
+                g2d.drawImage(img, -cx, -cy, null);
+        
+                g2d.dispose();
+                new ImageIcon(image); // load completely
+            }
+            return imageResource.getImageIcon(dimension).getImage();
+        }
+    }
+    
+    /**
+     * Creates a scaled down version of the input image to fit maximum dimensions. (Keeps aspect ratio)
+     *
+     * @param img the image to be scaled down.
+     * @param maxSize the maximum size in pixels (both for width and height) 
+     *
+     * @return the image after scaling.
+     * @since 6172
+     */
+    public static Image createBoundedImage(Image img, int maxSize) {
+        return new ImageResource(img).getImageIconBounded(new Dimension(maxSize, maxSize)).getImage();
     }
 
@@ -886,5 +961,5 @@
         Graphics2D g = img.createGraphics();
         g.setClip(0, 0, width, height);
-        if (scaleX != null) {
+        if (scaleX != null && scaleY != null) {
             g.scale(scaleX, scaleY);
         }
Index: /trunk/styles/standard/elemstyles.xml
===================================================================
--- /trunk/styles/standard/elemstyles.xml	(revision 6171)
+++ /trunk/styles/standard/elemstyles.xml	(revision 6172)
@@ -1816,4 +1816,10 @@
 	</rule>
 
+    <rule>
+        <condition k="emergency" v="aed"/>
+        <icon annotate="true" src="presets/aed.svg"/>
+        <area colour="amenity_light#f7efb7"/>
+    </rule>
+
 	<rule>
 		<condition k="amenity" v="toilets"/>
