Index: /applications/editors/josm/plugins/surveyor/.classpath
===================================================================
--- /applications/editors/josm/plugins/surveyor/.classpath	(revision 35261)
+++ /applications/editors/josm/plugins/surveyor/.classpath	(revision 35262)
@@ -2,7 +2,14 @@
 <classpath>
 	<classpathentry kind="src" path="src"/>
+	<classpathentry kind="src" output="bintest" path="unit">
+		<attributes>
+			<attribute name="test" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry including="resources/" kind="src" path=""/>
 	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
 	<classpathentry combineaccessrules="false" kind="src" path="/JOSM"/>
 	<classpathentry combineaccessrules="false" kind="src" path="/JOSM-livegps"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/4"/>
 	<classpathentry kind="output" path="bin"/>
 </classpath>
Index: /applications/editors/josm/plugins/surveyor/resources/surveyor.xml
===================================================================
--- /applications/editors/josm/plugins/surveyor/resources/surveyor.xml	(revision 35261)
+++ /applications/editors/josm/plugins/surveyor/resources/surveyor.xml	(revision 35262)
@@ -4,5 +4,5 @@
   <!-- action class: either fully qualified classnames or if not found,
        package at.dallermassl.josm.plugin.surveyor.action is assumed -->
-  <button label="Tunnel Start" hotkey="T" icon="styles/standard/vehicle/tunnel.png">
+  <button label="Tunnel Start" hotkey="T" icon="presets/transport/passage/tunnel.svg">
     <action class="PlayAudioAction" params="resource://audio/KDE_Window_Iconify.wav"/>
     <action class="SetWaypointAction" params="tunnel start"/>
@@ -14,5 +14,5 @@
     <action class="SetWaypointAction" params="bridge"/>
   </button>
-  <button label="Village/City" hotkey="V" icon="styles/standard/place.png">
+  <button label="Village/City" hotkey="V" icon="presets/place/village.svg">
     <action class="PlayAudioAction" params="resource://audio/KDE_Window_Iconify.wav"/>
     <action class="SetWaypointAction" params="village"/>
@@ -22,41 +22,37 @@
     -->
   </button>
-  <button label="Parking" hotkey="P" icon="styles/standard/vehicle/parking.png">
+  <button label="Parking" hotkey="P" icon="presets/vehicle/parking/parking.svg">
     <!--action class="SetNodeAction" params="amenity=parking"/-->
     <action class="PlayAudioAction" params="resource://audio/KDE_Window_Iconify.wav"/>
     <action class="SetWaypointAction" params="Parking"/>
   </button>
-  <button label="One Way" hotkey="O" icon="presets/oneway.png">
-    <action class="PlayAudioAction" params="resource://audio/KDE_Window_Iconify.wav"/>
-    <action class="SetWaypointAction" params="oneway=yes"/>
-  </button>
-  <button label="Church" hotkey="C" icon="styles/standard/religion/church.png">
+  <button label="Church" hotkey="C" icon="presets/religion/church.svg">
     <action class="PlayAudioAction" params="resource://audio/KDE_Window_Iconify.wav"/>
     <action class="SetNodeAction" params="amenity=place_of_worship,denomination=christian"/>
     <action class="SetWaypointAction" params="Church"/>
   </button>
-  <button label="Fuel Station" hotkey="F" icon="styles/standard/vehicle/fuel.png">
+  <button label="Fuel Station" hotkey="F" icon="presets/vehicle/fuel.svg">
     <!--action class="SetNodeAction" params="amenity=fuel"/-->
     <action class="PlayAudioAction" params="resource://audio/KDE_Window_Iconify.wav"/>
     <action class="SetWaypointAction" params="Fuel"/>
   </button>
-  <button label="Hotel" hotkey="H" icon="styles/standard/accommodation/hotel.png">
+  <button label="Hotel" hotkey="H" icon="presets/accommodation/hotel.svg">
     <action class="PlayAudioAction" params="resource://audio/KDE_Window_Iconify.wav"/>
     <action class="SetWaypointAction" params="Hotel"/>
   </button>
-  <button label="Restaurant" hotkey="R" icon="styles/standard/food/restaurant.png">
+  <button label="Restaurant" hotkey="R" icon="presets/food/restaurant.svg">
     <action class="PlayAudioAction" params="resource://audio/KDE_Window_Iconify.wav"/>
     <action class="SetNodeAction" params="amenity=restaurant"/>
     <action class="SetWaypointAction" params="Restaurant"/>
   </button>
-  <button label="Shopping" hotkey="S" icon="styles/standard/shop.png">
+  <button label="Shopping" hotkey="S" icon="presets/shop/mall.svg">
     <action class="PlayAudioAction" params="resource://audio/KDE_Window_Iconify.wav"/>
     <action class="SetWaypointAction" params="Info"/>
   </button>
-  <button label="WC" hotkey="W" icon="styles/standard/vehicle/parking/restarea_toilets.png">
+  <button label="WC" hotkey="W" icon="presets/service/toilets.svg">
     <action class="PlayAudioAction" params="resource://audio/KDE_Window_Iconify.wav"/>
     <action class="SetWaypointAction" params="Info"/>
   </button>
-  <button label="Camping" hotkey="Z" icon="styles/standard/accommodation/camping/caravan.png">
+  <button label="Camping" hotkey="Z" icon="presets/accommodation/caravan.svg">
     <action class="PlayAudioAction" params="resource://audio/KDE_Window_Iconify.wav"/>
     <action class="SetWaypointAction" params="Camping"/>
Index: /applications/editors/josm/plugins/surveyor/src/org/openstreetmap/josm/plugins/surveyor/ButtonDescription.java
===================================================================
--- /applications/editors/josm/plugins/surveyor/src/org/openstreetmap/josm/plugins/surveyor/ButtonDescription.java	(revision 35261)
+++ /applications/editors/josm/plugins/surveyor/src/org/openstreetmap/josm/plugins/surveyor/ButtonDescription.java	(revision 35262)
@@ -175,11 +175,14 @@
         String actionName = tr(getLabel()) + " (" + hotkey + ")";
 
-        Icon icon = ImageProvider.getIfAvailable(iconName);
-        if (icon == null)
-            icon = ImageProvider.getIfAvailable("markers", iconName);
-        if (icon == null)
-            icon = ImageProvider.getIfAvailable("symbols", iconName);
-        if (icon == null)
-            icon = ImageProvider.getIfAvailable("nodes", iconName);
+        Icon icon = null;
+        if (iconName != null) {
+            icon = ImageProvider.getIfAvailable(iconName);
+            if (icon == null)
+                icon = ImageProvider.getIfAvailable("markers", iconName);
+            if (icon == null)
+                icon = ImageProvider.getIfAvailable("symbols", iconName);
+            if (icon == null)
+                icon = ImageProvider.getIfAvailable("nodes", iconName);
+        }
 
         MetaAction action = new MetaAction(actionName, icon);
Index: /applications/editors/josm/plugins/surveyor/src/org/openstreetmap/josm/plugins/surveyor/SurveyorComponent.java
===================================================================
--- /applications/editors/josm/plugins/surveyor/src/org/openstreetmap/josm/plugins/surveyor/SurveyorComponent.java	(revision 35261)
+++ /applications/editors/josm/plugins/surveyor/src/org/openstreetmap/josm/plugins/surveyor/SurveyorComponent.java	(revision 35262)
@@ -64,5 +64,4 @@
      */
     public void setColumns(String columnsString) {
-        System.out.println("setting columns to " +columnsString);
         columns = Integer.parseInt(columnsString);
         buttonPanel.setLayout(new GridLayout(rows, columns));
Index: /applications/editors/josm/plugins/surveyor/src/org/openstreetmap/josm/plugins/surveyor/SurveyorShowAction.java
===================================================================
--- /applications/editors/josm/plugins/surveyor/src/org/openstreetmap/josm/plugins/surveyor/SurveyorShowAction.java	(revision 35261)
+++ /applications/editors/josm/plugins/surveyor/src/org/openstreetmap/josm/plugins/surveyor/SurveyorShowAction.java	(revision 35262)
@@ -23,5 +23,5 @@
 import org.openstreetmap.josm.actions.JosmAction;
 import org.openstreetmap.josm.gui.MainApplication;
-import org.openstreetmap.josm.plugins.surveyor.util.ResourceLoader;
+import org.openstreetmap.josm.io.CachedFile;
 import org.openstreetmap.josm.spi.preferences.Config;
 import org.openstreetmap.josm.tools.Logging;
@@ -107,14 +107,11 @@
     }
 
-    public SurveyorComponent createComponent() {
+    public static SurveyorComponent createComponent() {
         String source = Config.getPref().get("surveyor.source");
-        if (source == null || source.length() == 0) {
+        if (source == null || source.isEmpty()) {
             source = DEFAULT_SOURCE;
             Config.getPref().put("surveyor.source", DEFAULT_SOURCE);
-            // <FIXXME date="04.05.2007" author="cdaller">
-            // TODO copy xml file to .josm directory if it does not exist!
-            // </FIXXME>
         }
-        try (InputStream in = ResourceLoader.getInputStream(source)) {
+        try (CachedFile cf = new CachedFile(source); InputStream in = cf.getInputStream()) {
             return createComponent(in);
         } catch (IOException e) {
@@ -134,5 +131,5 @@
      * @throws SAXException if the xml could not be read.
      */
-    public SurveyorComponent createComponent(InputStream in) throws SAXException {
+    public static SurveyorComponent createComponent(InputStream in) throws SAXException {
         XmlObjectParser parser = new XmlObjectParser();
         parser.mapOnStart("surveyor", SurveyorComponent.class);
@@ -146,13 +143,10 @@
             Object object = parser.next();
             if (object instanceof SurveyorComponent) {
-                //System.out.println("SurveyorComponent " + object);
                 surveyorComponent = (SurveyorComponent) object;
             } else if (object instanceof ButtonDescription) {
-                //System.out.println("ButtonDescription " + object);
                 ((ButtonDescription) object).setActions(actions);
                 surveyorComponent.addButton(((ButtonDescription) object));
                 actions = new ArrayList<>();
             } else if (object instanceof SurveyorActionDescription) {
-                //System.out.println("SurveyorActionDescription " + object);
                 actions.add((SurveyorActionDescription) object);
             } else {
Index: /applications/editors/josm/plugins/surveyor/src/org/openstreetmap/josm/plugins/surveyor/action/PlayAudioAction.java
===================================================================
--- /applications/editors/josm/plugins/surveyor/src/org/openstreetmap/josm/plugins/surveyor/action/PlayAudioAction.java	(revision 35261)
+++ /applications/editors/josm/plugins/surveyor/src/org/openstreetmap/josm/plugins/surveyor/action/PlayAudioAction.java	(revision 35262)
@@ -4,5 +4,4 @@
 import java.io.BufferedInputStream;
 import java.io.IOException;
-import java.io.InputStream;
 
 import javax.sound.sampled.AudioFormat;
@@ -15,6 +14,6 @@
 
 import org.openstreetmap.josm.gui.MainApplication;
+import org.openstreetmap.josm.io.CachedFile;
 import org.openstreetmap.josm.plugins.surveyor.GpsActionEvent;
-import org.openstreetmap.josm.plugins.surveyor.util.ResourceLoader;
 import org.openstreetmap.josm.tools.Logging;
 
@@ -32,10 +31,9 @@
         // run as a separate thread
         MainApplication.worker.execute(() -> {
-            try {
-                if (audioSource == null) {
-                    audioSource = getParameters().get(0);
-                }
-                InputStream in = new BufferedInputStream(ResourceLoader.getInputStream(audioSource));
-                AudioInputStream stream = AudioSystem.getAudioInputStream(in);
+            if (audioSource == null) {
+                audioSource = getParameters().get(0);
+            }
+            try (CachedFile cf = new CachedFile(audioSource)) {
+                AudioInputStream stream = AudioSystem.getAudioInputStream(new BufferedInputStream(cf.getInputStream()));
 
                 // At present, ALAW and ULAW encodings must be converted
Index: plications/editors/josm/plugins/surveyor/src/org/openstreetmap/josm/plugins/surveyor/util/ResourceLoader.java
===================================================================
--- /applications/editors/josm/plugins/surveyor/src/org/openstreetmap/josm/plugins/surveyor/util/ResourceLoader.java	(revision 35261)
+++ 	(revision )
@@ -1,39 +1,0 @@
-// License: GPL. For details, see LICENSE file.
-package org.openstreetmap.josm.plugins.surveyor.util;
-
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.URL;
-
-/**
- * @author cdaller
- *
- */
-public final class ResourceLoader {
-
-    private ResourceLoader() {
-
-    }
-
-    /**
-     * Returns an inputstream from urls, files and classloaders, depending on the name.
-     * @param source the source: if starting with &quot;http://&quot;, &quot;ftp://&quot; or
-     * &quot;file://&quot; source is interpreted as an URL. If starting with &quot;resource://&quot;
-     * the classloader is used. All other sources are interpreted as filenames.
-     * @return the inputstream.
-     * @throws IOException if an error occurs on opening the url, or if the file is not found.
-     */
-    @SuppressWarnings("resource")
-    public static InputStream getInputStream(String source) throws IOException {
-        InputStream in = null;
-        if (source.startsWith("http://") || source.startsWith("https://") || source.startsWith("ftp://") || source.startsWith("file:")) {
-            in = new URL(source).openStream();
-        } else if (source.startsWith("resource://")) {
-            in = ResourceLoader.class.getResourceAsStream(source.substring("resource:/".length()));
-        } else {
-            in = new FileInputStream(source);
-        }
-        return in;
-    }
-}
Index: /applications/editors/josm/plugins/surveyor/unit/org/openstreetmap/josm/plugins/surveyor/SurveyorShowActionTest.java
===================================================================
--- /applications/editors/josm/plugins/surveyor/unit/org/openstreetmap/josm/plugins/surveyor/SurveyorShowActionTest.java	(revision 35262)
+++ /applications/editors/josm/plugins/surveyor/unit/org/openstreetmap/josm/plugins/surveyor/SurveyorShowActionTest.java	(revision 35262)
@@ -0,0 +1,36 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.plugins.surveyor;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.List;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.openstreetmap.josm.testutils.JOSMTestRules;
+import org.openstreetmap.josm.tools.Logging;
+
+import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
+
+/**
+ * Unit tests of {@link #SurveyorShowAction}
+ */
+public class SurveyorShowActionTest {
+
+    /**
+     * Setup rule
+     */
+    @Rule
+    @SuppressFBWarnings(value = "URF_UNREAD_PUBLIC_OR_PROTECTED_FIELD")
+    public JOSMTestRules test = new JOSMTestRules().preferences();
+
+    @Test
+    public void testCreateComponent() {
+        Logging.clearLastErrorAndWarnings();
+        SurveyorComponent comp = SurveyorShowAction.createComponent();
+        assertNotNull(comp);
+        List<String> errors = Logging.getLastErrorAndWarnings();
+        assertTrue(errors.toString(), errors.isEmpty());
+    }
+}
