Index: /applications/editors/josm/plugins/comfort0/src/net/simon04/comfort0/OsmToLevel0L.java
===================================================================
--- /applications/editors/josm/plugins/comfort0/src/net/simon04/comfort0/OsmToLevel0L.java	(revision 35288)
+++ /applications/editors/josm/plugins/comfort0/src/net/simon04/comfort0/OsmToLevel0L.java	(revision 35289)
@@ -1,10 +1,9 @@
 package net.simon04.comfort0;
 
-import java.util.Collections;
-import java.util.List;
+import java.util.Collection;
 
 import org.openstreetmap.josm.data.coor.LatLon;
-import org.openstreetmap.josm.data.osm.AbstractPrimitive;
-import org.openstreetmap.josm.data.osm.Changeset;
+import org.openstreetmap.josm.data.osm.DefaultNameFormatter;
+import org.openstreetmap.josm.data.osm.KeyValueVisitor;
 import org.openstreetmap.josm.data.osm.Node;
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
@@ -12,17 +11,19 @@
 import org.openstreetmap.josm.data.osm.Relation;
 import org.openstreetmap.josm.data.osm.RelationMember;
+import org.openstreetmap.josm.data.osm.Tagged;
 import org.openstreetmap.josm.data.osm.Way;
-import org.openstreetmap.josm.data.osm.visitor.Visitor;
-import org.openstreetmap.josm.gui.DefaultNameFormatter;
+import org.openstreetmap.josm.data.osm.visitor.OsmPrimitiveVisitor;
 
-public class OsmToLevel0L implements Visitor, AbstractPrimitive.KeyValueVisitor {
+/**
+ * Implements a conversion from {@link OsmPrimitive} to <a href="https://wiki.openstreetmap.org/wiki/Level0L">Level0L</a>.
+ */
+public class OsmToLevel0L implements OsmPrimitiveVisitor, KeyValueVisitor {
 
     private final StringBuilder sb = new StringBuilder();
 
-    public void visit(List<OsmPrimitive> primitives) {
-        Collections.sort(primitives, new OsmPrimitiveComparator());
-        for (OsmPrimitive primitive : primitives) {
-            primitive.accept(this);
-        }
+    public void visit(Collection<OsmPrimitive> primitives) {
+        primitives.stream()
+                .sorted(OsmPrimitiveComparator.orderingWaysRelationsNodes().thenComparing(OsmPrimitiveComparator.comparingUniqueId()))
+                .forEachOrdered(p -> p.accept(this));
     }
 
@@ -56,4 +57,6 @@
                     sb.append("rel ");
                     break;
+                default:
+                    break;
             }
             sb.append(member.getUniqueId()).append(" ");
@@ -66,7 +69,9 @@
         sb.append("\n");
         sb.append(p.getType().getAPIName()).append(" ").append(p.getUniqueId());
-        if (p instanceof Node && ((Node) p).isLatLonKnown()) {
-            final LatLon coor = ((Node) p).getCoor();
-            sb.append(": ").append(coor.lat()).append(", ").append(coor.lon());
+        if (p instanceof Node) {
+            final LatLon latLon = ((Node) p).getCoor();
+            if (latLon != null) {
+                sb.append(": ").append(latLon.lat()).append(", ").append(latLon.lon());
+            }
         }
         appendDisplayName(p);
@@ -79,9 +84,5 @@
 
     @Override
-    public void visit(Changeset cs) {
-    }
-
-    @Override
-    public void visitKeyValue(AbstractPrimitive primitive, String key, String value) {
+    public void visitKeyValue(Tagged primitive, String key, String value) {
         if (key.contains("#") || key.contains("=")) {
             throw new UnsupportedOperationException("# and = are not supported in keys");
Index: /applications/editors/josm/plugins/comfort0/test/unit/net/simon04/comfort0/OsmToLevel0LTest.java
===================================================================
--- /applications/editors/josm/plugins/comfort0/test/unit/net/simon04/comfort0/OsmToLevel0LTest.java	(revision 35288)
+++ /applications/editors/josm/plugins/comfort0/test/unit/net/simon04/comfort0/OsmToLevel0LTest.java	(revision 35289)
@@ -5,19 +5,28 @@
 
 import java.io.InputStream;
-import java.util.ArrayList;
 
+import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
 import org.junit.Before;
+import org.junit.Rule;
 import org.junit.Test;
-import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.data.Preferences;
 import org.openstreetmap.josm.data.coor.LatLon;
 import org.openstreetmap.josm.data.osm.DataSet;
 import org.openstreetmap.josm.data.osm.Node;
 import org.openstreetmap.josm.io.OsmReader;
+import org.openstreetmap.josm.testutils.JOSMTestRules;
 
 public class OsmToLevel0LTest {
 
+    /**
+     * Setup rule
+     */
+    @Rule
+    @SuppressFBWarnings(value = "URF_UNREAD_PUBLIC_OR_PROTECTED_FIELD")
+    public JOSMTestRules test = new JOSMTestRules().preferences();
+
     @Before
     public void setUp() throws Exception {
-        Main.initApplicationPreferences();
+        Preferences.main().putBoolean("osm-primitives.showcoor", true);
     }
 
@@ -38,9 +47,11 @@
         // from https://wiki.openstreetmap.org/wiki/OSM_XML#OSM_XML_file_format
         // compare to https://wiki.openstreetmap.org/wiki/Level0L#Examples
-        try (InputStream in = getClass().getResource("/example.osm").openStream()) {
+        try (InputStream in = getClass().getClassLoader().getResource("example.osm").openStream()) {
             final DataSet dataSet = OsmReader.parseDataSet(in, null);
             final OsmToLevel0L converter = new OsmToLevel0L();
-            converter.visit(new ArrayList<>(dataSet.allPrimitives()));
+            converter.visit(dataSet.allPrimitives());
             assertThat(converter.toString(), is("" +
+                    "way 4579143 #\u200Eincomplete\n" +
+                    "\n" +
                     "way 26659127 #\u200EPastower Straße\u200E (3 nodes)\n" +
                     "  highway = unclassified\n" +
@@ -49,6 +60,4 @@
                     "  n298884289 #incomplete\n" +
                     "  n261728686 #261728686 \u200E(54.0906309, 12.2441924)\n" +
-                    "\n" +
-                    "way 4579143 #\u200Eincomplete\n" +
                     "\n" +
                     "relation 56688 #route (\"Küstenbus Linie 123\", 4 members, incomplete)\n" +
@@ -64,9 +73,7 @@
                     "  nd 249673494  #incomplete\n" +
                     "\n" +
-                    "node 1831881213: 54.0900666, 12.2539381 #Neu Broderstorf \u200E(54.0900666, 12.2539381)\n" +
-                    "  name = Neu Broderstorf\n" +
-                    "  traffic_sign = city_limit\n" +
+                    "node 249673494 #incomplete\n" +
                     "\n" +
-                    "node 249673494 #incomplete\n" +
+                    "node 261728686: 54.0906309, 12.2441924 #261728686 \u200E(54.0906309, 12.2441924)\n" +
                     "\n" +
                     "node 292403538 #incomplete\n" +
@@ -74,13 +81,15 @@
                     "node 294942404 #incomplete\n" +
                     "\n" +
-                    "node 364933006 #incomplete\n" +
+                    "node 298884269: 54.0901746, 12.2482632 #298884269 \u200E(54.0901746, 12.2482632)\n" +
+                    "\n" +
+                    "node 298884272: 54.0901447, 12.2516513 #298884272 \u200E(54.0901447, 12.2516513)\n" +
                     "\n" +
                     "node 298884289 #incomplete\n" +
                     "\n" +
-                    "node 261728686: 54.0906309, 12.2441924 #261728686 \u200E(54.0906309, 12.2441924)\n" +
+                    "node 364933006 #incomplete\n" +
                     "\n" +
-                    "node 298884269: 54.0901746, 12.2482632 #298884269 \u200E(54.0901746, 12.2482632)\n" +
-                    "\n" +
-                    "node 298884272: 54.0901447, 12.2516513 #298884272 \u200E(54.0901447, 12.2516513)"));
+                    "node 1831881213: 54.0900666, 12.2539381 #Neu Broderstorf \u200E(54.0900666, 12.2539381)\n" +
+                    "  name = Neu Broderstorf\n" +
+                    "  traffic_sign = city_limit"));
         }
     }
