Index: trunk/src/org/openstreetmap/josm/actions/AddImageryLayerAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/AddImageryLayerAction.java	(revision 7692)
+++ trunk/src/org/openstreetmap/josm/actions/AddImageryLayerAction.java	(revision 7693)
@@ -12,5 +12,4 @@
 
 import javax.swing.Action;
-import javax.swing.ImageIcon;
 import javax.swing.JComboBox;
 import javax.swing.JOptionPane;
@@ -29,5 +28,6 @@
 import org.openstreetmap.josm.tools.GBC;
 import org.openstreetmap.josm.tools.ImageProvider;
-import org.openstreetmap.josm.tools.ImageProvider.ImageCallback;
+import org.openstreetmap.josm.tools.ImageProvider.ImageResourceCallback;
+import org.openstreetmap.josm.tools.ImageResource;
 
 /**
@@ -52,28 +52,14 @@
         // change toolbar icon from if specified
         try {
-            if (info.getIcon() != null) {
-                new ImageProvider(info.getIcon()).setOptional(true).
-                        setMaxSize(ImageProvider.ImageSizes.SMALLICON).getInBackground(new ImageCallback() {
+            String icon = info.getIcon();
+            if (icon != null) {
+                new ImageProvider(icon).setOptional(true).getInBackground(new ImageResourceCallback() {
                             @Override
-                            public void finished(final ImageIcon result) {
+                            public void finished(final ImageResource result) {
                                 if (result != null) {
                                     GuiHelper.runInEDT(new Runnable() {
                                         @Override
                                         public void run() {
-                                            putValue(Action.SMALL_ICON, result);
-                                        }
-                                    });
-                                }
-                            }
-                        });
-                new ImageProvider(info.getIcon()).setOptional(true).
-                        setMaxSize(ImageProvider.ImageSizes.LARGEICON).getInBackground(new ImageCallback() {
-                            @Override
-                            public void finished(final ImageIcon result) {
-                                if (result != null) {
-                                    GuiHelper.runInEDT(new Runnable() {
-                                        @Override
-                                        public void run() {
-                                            putValue(Action.LARGE_ICON_KEY, result);
+                                            result.getImageIcon(AddImageryLayerAction.this);
                                         }
                                     });
Index: trunk/src/org/openstreetmap/josm/actions/JosmAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/JosmAction.java	(revision 7692)
+++ trunk/src/org/openstreetmap/josm/actions/JosmAction.java	(revision 7693)
@@ -72,5 +72,7 @@
      * @param toolbarId identifier for the toolbar preferences. The iconName is used, if this parameter is null
      * @param installAdapters false, if you don't want to install layer changed and selection changed adapters
-     */
+     * @deprecated do not pass Icon, pass ImageProvider instead
+     */
+    @Deprecated
     public JosmAction(String name, Icon icon, String tooltip, Shortcut shortcut, boolean registerInToolbar, String toolbarId, boolean installAdapters) {
         super(name, icon);
@@ -93,4 +95,41 @@
 
     /**
+     * Constructs a {@code JosmAction}.
+     *
+     * @param name the action's text as displayed on the menu (if it is added to a menu)
+     * @param icon the icon to use
+     * @param tooltip  a longer description of the action that will be displayed in the tooltip. Please note
+     *           that html is not supported for menu actions on some platforms.
+     * @param shortcut a ready-created shortcut object or null if you don't want a shortcut. But you always
+     *            do want a shortcut, remember you can always register it with group=none, so you
+     *            won't be assigned a shortcut unless the user configures one. If you pass null here,
+     *            the user CANNOT configure a shortcut for your action.
+     * @param registerInToolbar register this action for the toolbar preferences?
+     * @param toolbarId identifier for the toolbar preferences. The iconName is used, if this parameter is null
+     * @param installAdapters false, if you don't want to install layer changed and selection changed adapters
+     * TODO: do not pass Icon, pass ImageProvider instead
+     */
+    public JosmAction(String name, ImageProvider icon, String tooltip, Shortcut shortcut, boolean registerInToolbar, String toolbarId, boolean installAdapters) {
+        super(name);
+        if(icon != null)
+            icon.getResource().getImageIcon(this);
+        setHelpId();
+        sc = shortcut;
+        if (sc != null) {
+            Main.registerActionShortcut(this, sc);
+        }
+        setTooltip(tooltip);
+        if (getValue("toolbar") == null) {
+            putValue("toolbar", toolbarId);
+        }
+        if (registerInToolbar && Main.toolbar != null) {
+            Main.toolbar.register(this);
+        }
+        if (installAdapters) {
+            installAdapters();
+        }
+    }
+
+    /**
      * The new super for all actions.
      *
@@ -110,5 +149,5 @@
      */
     public JosmAction(String name, String iconName, String tooltip, Shortcut shortcut, boolean registerInToolbar, String toolbarId, boolean installAdapters) {
-        this(name, iconName == null ? null : ImageProvider.get(iconName), tooltip, shortcut, registerInToolbar,
+        this(name, iconName == null ? null : new ImageProvider(iconName), tooltip, shortcut, registerInToolbar,
                 toolbarId == null ? iconName : toolbarId, installAdapters);
     }
Index: trunk/src/org/openstreetmap/josm/actions/JumpToAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/JumpToAction.java	(revision 7692)
+++ trunk/src/org/openstreetmap/josm/actions/JumpToAction.java	(revision 7693)
@@ -9,5 +9,4 @@
 import java.awt.event.KeyEvent;
 
-import javax.swing.Icon;
 import javax.swing.JLabel;
 import javax.swing.JOptionPane;
@@ -24,4 +23,5 @@
 import org.openstreetmap.josm.gui.widgets.JosmTextField;
 import org.openstreetmap.josm.tools.GBC;
+import org.openstreetmap.josm.tools.ImageProvider;
 import org.openstreetmap.josm.tools.OsmUrlToBounds;
 import org.openstreetmap.josm.tools.Shortcut;
@@ -37,5 +37,5 @@
      */
     public JumpToAction() {
-        super(tr("Jump To Position"), (Icon) null, tr("Opens a dialog that allows to jump to a specific location"),
+        super(tr("Jump To Position"), (ImageProvider) null, tr("Opens a dialog that allows to jump to a specific location"),
                 Shortcut.registerShortcut("tools:jumpto", tr("Tool: {0}", tr("Jump To Position")),
                         KeyEvent.VK_J, Shortcut.CTRL), true, "action/jumpto", true);
Index: trunk/src/org/openstreetmap/josm/gui/tagging/TaggingPreset.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/tagging/TaggingPreset.java	(revision 7692)
+++ trunk/src/org/openstreetmap/josm/gui/tagging/TaggingPreset.java	(revision 7693)
@@ -52,4 +52,5 @@
 import org.openstreetmap.josm.tools.GBC;
 import org.openstreetmap.josm.tools.ImageProvider;
+import org.openstreetmap.josm.tools.ImageResource;
 import org.openstreetmap.josm.tools.Predicate;
 import org.openstreetmap.josm.tools.Utils;
@@ -153,36 +154,16 @@
         imgProv.setArchive(arch);
         imgProv.setOptional(true);
-        imgProv.setSize(ImageProvider.ImageSizes.SMALLICON);
-        imgProv.getInBackground(new ImageProvider.ImageCallback() {
+        imgProv.getInBackground(new ImageProvider.ImageResourceCallback() {
             @Override
-            public void finished(final ImageIcon result) {
+            public void finished(final ImageResource result) {
                 if (result != null) {
                     GuiHelper.runInEDT(new Runnable() {
                         @Override
                         public void run() {
-                            putValue(Action.SMALL_ICON, result);
+                            result.getImageIcon(TaggingPreset.this);
                         }
                     });
                 } else {
                     Main.warn("Could not get presets icon " + iconName);
-                }
-            }
-        });
-        imgProv = new ImageProvider(iconName);
-        imgProv.setDirs(s);
-        imgProv.setId("presets");
-        imgProv.setArchive(arch);
-        imgProv.setOptional(true);
-        imgProv.setSize(ImageProvider.ImageSizes.LARGEICON);
-        imgProv.getInBackground(new ImageProvider.ImageCallback() {
-            @Override
-            public void finished(final ImageIcon result) {
-                if (result != null) {
-                    GuiHelper.runInEDT(new Runnable() {
-                        @Override
-                        public void run() {
-                            putValue(Action.LARGE_ICON_KEY, result);
-                        }
-                    });
                 }
             }
Index: trunk/src/org/openstreetmap/josm/tools/ImageProvider.java
===================================================================
--- trunk/src/org/openstreetmap/josm/tools/ImageProvider.java	(revision 7692)
+++ trunk/src/org/openstreetmap/josm/tools/ImageProvider.java	(revision 7693)
@@ -163,6 +163,17 @@
     private static final ExecutorService IMAGE_FETCHER = Executors.newSingleThreadExecutor();
 
+    /**
+     * Callback interface for asynchronous image loading.
+     */
     public interface ImageCallback {
         void finished(ImageIcon result);
+    }
+
+    /**
+     * Callback interface for asynchronous image loading (with delayed scaling possibility).
+     * @since 7693
+     */
+    public interface ImageResourceCallback {
+        void finished(ImageResource result);
     }
 
@@ -237,5 +248,5 @@
      * @since 7687
      */
-    public Dimension getImageSizes(ImageSizes size) {
+    static public Dimension getImageSizes(ImageSizes size) {
         int sizeval;
         switch(size) {
@@ -382,8 +393,21 @@
 
     /**
+     * Execute the image request and scale result.
+     * @return the requested image or null if the request failed
+     */
+    public ImageIcon get() {
+        ImageResource ir = getResource();
+        if (maxWidth != -1 || maxHeight != -1)
+            return ir.getImageIconBounded(new Dimension(maxWidth, maxHeight));
+        else
+            return ir.getImageIcon(new Dimension(width, height));
+    }
+
+    /**
      * Execute the image request.
      * @return the requested image or null if the request failed
-     */
-    public ImageIcon get() {
+     * @since 7693
+     */
+    public ImageResource getResource() {
         ImageResource ir = getIfAvailableImpl(additionalClassLoaders);
         if (ir == null) {
@@ -398,8 +422,5 @@
             }
         }
-        if (maxWidth != -1 || maxHeight != -1)
-            return ir.getImageIconBounded(new Dimension(maxWidth, maxHeight));
-        else
-            return ir.getImageIcon(new Dimension(width, height));
+        return ir;
     }
 
@@ -428,4 +449,30 @@
             ImageIcon result = get();
             callback.finished(result);
+        }
+    }
+
+    /**
+     * Load the image in a background thread.
+     *
+     * This method returns immediately and runs the image request
+     * asynchronously.
+     *
+     * @param callback a callback. It is called, when the image is ready.
+     * This can happen before the call to this method returns or it may be
+     * invoked some time (seconds) later. If no image is available, a null
+     * value is returned to callback (just like {@link #get}).
+     * @since 7693
+     */
+    public void getInBackground(final ImageResourceCallback callback) {
+        if (name.startsWith("http://") || name.startsWith("wiki://")) {
+            Runnable fetch = new Runnable() {
+                @Override
+                public void run() {
+                    callback.finished(getResource());
+                }
+            };
+            IMAGE_FETCHER.submit(fetch);
+        } else {
+            callback.finished(getResource());
         }
     }
Index: trunk/src/org/openstreetmap/josm/tools/ImageResource.java
===================================================================
--- trunk/src/org/openstreetmap/josm/tools/ImageResource.java	(revision 7692)
+++ trunk/src/org/openstreetmap/josm/tools/ImageResource.java	(revision 7693)
@@ -8,4 +8,6 @@
 import java.util.Map;
 
+import javax.swing.Action;
+import javax.swing.AbstractAction;
 import javax.swing.ImageIcon;
 
@@ -20,5 +22,5 @@
  * @since 4271
  */
-class ImageResource {
+public class ImageResource {
 
     /**
@@ -43,4 +45,16 @@
     }
 
+    /**
+     * Set both icons of an Action
+     * @param action The action for the icons
+     * @since 7693
+     */
+    public void getImageIcon(AbstractAction a) {
+        ImageIcon icon = getImageIcon(ImageProvider.getImageSizes(ImageProvider.ImageSizes.SMALLICON));
+        a.putValue(Action.SMALL_ICON, icon);
+        icon = getImageIcon(ImageProvider.getImageSizes(ImageProvider.ImageSizes.LARGEICON));
+        a.putValue(Action.LARGE_ICON_KEY, icon);
+    }
+    
     /**
      * Get an ImageIcon object for the image of this resource
