Index: /trunk/.settings/org.sonarlint.eclipse.core.prefs
===================================================================
--- /trunk/.settings/org.sonarlint.eclipse.core.prefs	(revision 10198)
+++ /trunk/.settings/org.sonarlint.eclipse.core.prefs	(revision 10198)
@@ -0,0 +1,5 @@
+autoEnabled=true
+eclipse.preferences.version=1
+extraProperties=
+moduleKey=josm
+serverId=josm
Index: /trunk/src/org/openstreetmap/josm/gui/dialogs/InspectPrimitiveDataText.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/dialogs/InspectPrimitiveDataText.java	(revision 10198)
+++ /trunk/src/org/openstreetmap/josm/gui/dialogs/InspectPrimitiveDataText.java	(revision 10198)
@@ -0,0 +1,239 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.gui.dialogs;
+
+import static org.openstreetmap.josm.tools.I18n.tr;
+import static org.openstreetmap.josm.tools.I18n.trn;
+
+import java.util.List;
+
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.data.conflict.Conflict;
+import org.openstreetmap.josm.data.coor.EastNorth;
+import org.openstreetmap.josm.data.osm.BBox;
+import org.openstreetmap.josm.data.osm.Node;
+import org.openstreetmap.josm.data.osm.OsmPrimitive;
+import org.openstreetmap.josm.data.osm.Relation;
+import org.openstreetmap.josm.data.osm.RelationMember;
+import org.openstreetmap.josm.data.osm.Way;
+import org.openstreetmap.josm.gui.layer.OsmDataLayer;
+import org.openstreetmap.josm.tools.Geometry;
+import org.openstreetmap.josm.tools.date.DateUtils;
+
+/**
+ * Textual representation of primitive contents, used in {@code InspectPrimitiveDialog}.
+ * @since 10198
+ */
+public class InspectPrimitiveDataText {
+    private static final String INDENT = "  ";
+    private static final char NL = '\n';
+
+    private final StringBuilder s = new StringBuilder();
+    private final OsmDataLayer layer;
+
+    InspectPrimitiveDataText(OsmDataLayer layer) {
+        this.layer = layer;
+    }
+
+    private InspectPrimitiveDataText add(String title, String... values) {
+        s.append(INDENT).append(title);
+        for (String v : values) {
+            s.append(v);
+        }
+        s.append(NL);
+        return this;
+    }
+
+    private static String getNameAndId(String name, long id) {
+        if (name != null) {
+            return name + tr(" ({0})", /* sic to avoid thousand seperators */ Long.toString(id));
+        } else {
+            return Long.toString(id);
+        }
+    }
+
+    /**
+     * Adds a new OSM primitive.
+     * @param o primitive to add
+     */
+    public void addPrimitive(OsmPrimitive o) {
+
+        addHeadline(o);
+
+        if (!(o.getDataSet() != null && o.getDataSet().getPrimitiveById(o) != null)) {
+            s.append(NL).append(INDENT).append(tr("not in data set")).append(NL);
+            return;
+        }
+        if (o.isIncomplete()) {
+            s.append(NL).append(INDENT).append(tr("incomplete")).append(NL);
+            return;
+        }
+        s.append(NL);
+
+        addState(o);
+        addCommon(o);
+        addAttributes(o);
+        addSpecial(o);
+        addReferrers(s, o);
+        addConflicts(o);
+        s.append(NL);
+    }
+
+    void addHeadline(OsmPrimitive o) {
+        addType(o);
+        addNameAndId(o);
+    }
+
+    void addType(OsmPrimitive o) {
+        if (o instanceof Node) {
+            s.append(tr("Node: "));
+        } else if (o instanceof Way) {
+            s.append(tr("Way: "));
+        } else if (o instanceof Relation) {
+            s.append(tr("Relation: "));
+        }
+    }
+
+    void addNameAndId(OsmPrimitive o) {
+        String name = o.get("name");
+        if (name == null) {
+            s.append(o.getUniqueId());
+        } else {
+            s.append(getNameAndId(name, o.getUniqueId()));
+        }
+    }
+
+    void addState(OsmPrimitive o) {
+        StringBuilder sb = new StringBuilder(INDENT);
+        /* selected state is left out: not interesting as it is always selected */
+        if (o.isDeleted()) {
+            sb.append(tr("deleted")).append(INDENT);
+        }
+        if (!o.isVisible()) {
+            sb.append(tr("deleted-on-server")).append(INDENT);
+        }
+        if (o.isModified()) {
+            sb.append(tr("modified")).append(INDENT);
+        }
+        if (o.isDisabledAndHidden()) {
+            sb.append(tr("filtered/hidden")).append(INDENT);
+        }
+        if (o.isDisabled()) {
+            sb.append(tr("filtered/disabled")).append(INDENT);
+        }
+        if (o.hasDirectionKeys()) {
+            if (o.reversedDirection()) {
+                sb.append(tr("has direction keys (reversed)")).append(INDENT);
+            } else {
+                sb.append(tr("has direction keys")).append(INDENT);
+            }
+        }
+        String state = sb.toString().trim();
+        if (!state.isEmpty()) {
+            add(tr("State: "), sb.toString().trim());
+        }
+    }
+
+    void addCommon(OsmPrimitive o) {
+        add(tr("Data Set: "), Integer.toHexString(o.getDataSet().hashCode()));
+        add(tr("Edited at: "), o.isTimestampEmpty() ? tr("<new object>")
+                : DateUtils.fromTimestamp(o.getRawTimestamp()));
+        add(tr("Edited by: "), o.getUser() == null ? tr("<new object>")
+                : getNameAndId(o.getUser().getName(), o.getUser().getId()));
+        add(tr("Version: "), Integer.toString(o.getVersion()));
+        add(tr("In changeset: "), Integer.toString(o.getChangesetId()));
+    }
+
+    void addAttributes(OsmPrimitive o) {
+        if (o.hasKeys()) {
+            add(tr("Tags: "));
+            for (String key : o.keySet()) {
+                s.append(INDENT).append(INDENT);
+                s.append(String.format("\"%s\"=\"%s\"%n", key, o.get(key)));
+            }
+        }
+    }
+
+    void addSpecial(OsmPrimitive o) {
+        if (o instanceof Node) {
+            addCoordinates((Node) o);
+        } else if (o instanceof Way) {
+            addBbox(o);
+            add(tr("Centroid: "), Main.getProjection().eastNorth2latlon(
+                    Geometry.getCentroid(((Way) o).getNodes())).toStringCSV(", "));
+            addWayNodes((Way) o);
+        } else if (o instanceof Relation) {
+            addBbox(o);
+            addRelationMembers((Relation) o);
+        }
+    }
+
+    void addRelationMembers(Relation r) {
+        add(trn("{0} Member: ", "{0} Members: ", r.getMembersCount(), r.getMembersCount()));
+        for (RelationMember m : r.getMembers()) {
+            s.append(INDENT).append(INDENT);
+            addHeadline(m.getMember());
+            s.append(tr(" as \"{0}\"", m.getRole()));
+            s.append(NL);
+        }
+    }
+
+    void addWayNodes(Way w) {
+        add(tr("{0} Nodes: ", w.getNodesCount()));
+        for (Node n : w.getNodes()) {
+            s.append(INDENT).append(INDENT);
+            addNameAndId(n);
+            s.append(NL);
+        }
+    }
+
+    void addBbox(OsmPrimitive o) {
+        BBox bbox = o.getBBox();
+        if (bbox != null) {
+            add(tr("Bounding box: "), bbox.toStringCSV(", "));
+            EastNorth bottomRigth = Main.getProjection().latlon2eastNorth(bbox.getBottomRight());
+            EastNorth topLeft = Main.getProjection().latlon2eastNorth(bbox.getTopLeft());
+            add(tr("Bounding box (projected): "),
+                    Double.toString(topLeft.east()), ", ",
+                    Double.toString(bottomRigth.north()), ", ",
+                    Double.toString(bottomRigth.east()), ", ",
+                    Double.toString(topLeft.north()));
+            add(tr("Center of bounding box: "), bbox.getCenter().toStringCSV(", "));
+        }
+    }
+
+    void addCoordinates(Node n) {
+        if (n.getCoor() != null) {
+            add(tr("Coordinates: "),
+                    Double.toString(n.getCoor().lat()), ", ",
+                    Double.toString(n.getCoor().lon()));
+            add(tr("Coordinates (projected): "),
+                    Double.toString(n.getEastNorth().east()), ", ",
+                    Double.toString(n.getEastNorth().north()));
+        }
+    }
+
+    void addReferrers(StringBuilder s, OsmPrimitive o) {
+        List<OsmPrimitive> refs = o.getReferrers();
+        if (!refs.isEmpty()) {
+            add(tr("Part of: "));
+            for (OsmPrimitive p : refs) {
+                s.append(INDENT).append(INDENT);
+                addHeadline(p);
+                s.append(NL);
+            }
+        }
+    }
+
+    void addConflicts(OsmPrimitive o) {
+        Conflict<?> c = layer.getConflicts().getConflictForMy(o);
+        if (c != null) {
+            add(tr("In conflict with: "));
+            addNameAndId(c.getTheir());
+        }
+    }
+
+    @Override
+    public String toString() {
+        return s.toString();
+    }
+}
Index: /trunk/src/org/openstreetmap/josm/gui/dialogs/InspectPrimitiveDialog.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/dialogs/InspectPrimitiveDialog.java	(revision 10197)
+++ /trunk/src/org/openstreetmap/josm/gui/dialogs/InspectPrimitiveDialog.java	(revision 10198)
@@ -25,13 +25,6 @@
 
 import org.openstreetmap.josm.Main;
-import org.openstreetmap.josm.data.conflict.Conflict;
-import org.openstreetmap.josm.data.coor.EastNorth;
-import org.openstreetmap.josm.data.osm.BBox;
-import org.openstreetmap.josm.data.osm.Node;
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
 import org.openstreetmap.josm.data.osm.OsmPrimitiveComparator;
-import org.openstreetmap.josm.data.osm.Relation;
-import org.openstreetmap.josm.data.osm.RelationMember;
-import org.openstreetmap.josm.data.osm.Way;
 import org.openstreetmap.josm.gui.DefaultNameFormatter;
 import org.openstreetmap.josm.gui.ExtendedDialog;
@@ -50,7 +43,5 @@
 import org.openstreetmap.josm.gui.widgets.JosmTextArea;
 import org.openstreetmap.josm.tools.GBC;
-import org.openstreetmap.josm.tools.Geometry;
 import org.openstreetmap.josm.tools.WindowGeometry;
-import org.openstreetmap.josm.tools.date.DateUtils;
 
 /**
@@ -68,5 +59,10 @@
     private boolean editcountTabLoaded;
 
-    public InspectPrimitiveDialog(Collection<OsmPrimitive> primitives, OsmDataLayer layer) {
+    /**
+     * Constructs a new {@code InspectPrimitiveDialog}.
+     * @param primitives collection of primitives
+     * @param layer data layer
+     */
+    public InspectPrimitiveDialog(final Collection<OsmPrimitive> primitives, OsmDataLayer layer) {
         super(Main.parent, tr("Advanced object info"), new String[] {tr("Close")});
         this.primitives = new ArrayList<>(primitives);
@@ -78,5 +74,5 @@
         final JTabbedPane tabs = new JTabbedPane();
 
-        tabs.addTab(tr("data"), genericMonospacePanel(new JPanel(), buildDataText()));
+        tabs.addTab(tr("data"), genericMonospacePanel(new JPanel(), buildDataText(layer, this.primitives)));
 
         final JPanel pMapPaint = new JPanel();
@@ -101,5 +97,5 @@
                 if (!editcountTabLoaded && ((SingleSelectionModel) e.getSource()).getSelectedIndex() == 2) {
                     editcountTabLoaded = true;
-                    genericMonospacePanel(pEditCounts, buildListOfEditorsText());
+                    genericMonospacePanel(pEditCounts, buildListOfEditorsText(primitives));
                 }
             }
@@ -109,5 +105,5 @@
     }
 
-    protected JPanel genericMonospacePanel(JPanel p, String s) {
+    protected static JPanel genericMonospacePanel(JPanel p, String s) {
         p.setLayout(new GridBagLayout());
         JosmTextArea jte = new JosmTextArea();
@@ -119,6 +115,6 @@
     }
 
-    protected String buildDataText() {
-        DataText dt = new DataText();
+    protected static String buildDataText(OsmDataLayer layer, List<OsmPrimitive> primitives) {
+        InspectPrimitiveDataText dt = new InspectPrimitiveDataText(layer);
         Collections.sort(primitives, new OsmPrimitiveComparator());
         for (OsmPrimitive o : primitives) {
@@ -128,211 +124,5 @@
     }
 
-    class DataText {
-        private static final String INDENT = "  ";
-        private static final char NL = '\n';
-
-        private final StringBuilder s = new StringBuilder();
-
-        private DataText add(String title, String... values) {
-            s.append(INDENT).append(title);
-            for (String v : values) {
-                s.append(v);
-            }
-            s.append(NL);
-            return this;
-        }
-
-        private String getNameAndId(String name, long id) {
-            if (name != null) {
-                return name + tr(" ({0})", /* sic to avoid thousand seperators */ Long.toString(id));
-            } else {
-                return Long.toString(id);
-            }
-        }
-
-        public void addPrimitive(OsmPrimitive o) {
-
-            addHeadline(o);
-
-            if (!(o.getDataSet() != null && o.getDataSet().getPrimitiveById(o) != null)) {
-                s.append(NL).append(INDENT).append(tr("not in data set")).append(NL);
-                return;
-            }
-            if (o.isIncomplete()) {
-                s.append(NL).append(INDENT).append(tr("incomplete")).append(NL);
-                return;
-            }
-            s.append(NL);
-
-            addState(o);
-            addCommon(o);
-            addAttributes(o);
-            addSpecial(o);
-            addReferrers(s, o);
-            addConflicts(o);
-            s.append(NL);
-        }
-
-        void addHeadline(OsmPrimitive o) {
-            addType(o);
-            addNameAndId(o);
-        }
-
-        void addType(OsmPrimitive o) {
-            if (o instanceof Node) {
-                s.append(tr("Node: "));
-            } else if (o instanceof Way) {
-                s.append(tr("Way: "));
-            } else if (o instanceof Relation) {
-                s.append(tr("Relation: "));
-            }
-        }
-
-        void addNameAndId(OsmPrimitive o) {
-            String name = o.get("name");
-            if (name == null) {
-                s.append(o.getUniqueId());
-            } else {
-                s.append(getNameAndId(name, o.getUniqueId()));
-            }
-        }
-
-        void addState(OsmPrimitive o) {
-            StringBuilder sb = new StringBuilder(INDENT);
-            /* selected state is left out: not interesting as it is always selected */
-            if (o.isDeleted()) {
-                sb.append(tr("deleted")).append(INDENT);
-            }
-            if (!o.isVisible()) {
-                sb.append(tr("deleted-on-server")).append(INDENT);
-            }
-            if (o.isModified()) {
-                sb.append(tr("modified")).append(INDENT);
-            }
-            if (o.isDisabledAndHidden()) {
-                sb.append(tr("filtered/hidden")).append(INDENT);
-            }
-            if (o.isDisabled()) {
-                sb.append(tr("filtered/disabled")).append(INDENT);
-            }
-            if (o.hasDirectionKeys()) {
-                if (o.reversedDirection()) {
-                    sb.append(tr("has direction keys (reversed)")).append(INDENT);
-                } else {
-                    sb.append(tr("has direction keys")).append(INDENT);
-                }
-            }
-            String state = sb.toString().trim();
-            if (!state.isEmpty()) {
-                add(tr("State: "), sb.toString().trim());
-            }
-        }
-
-        void addCommon(OsmPrimitive o) {
-            add(tr("Data Set: "), Integer.toHexString(o.getDataSet().hashCode()));
-            add(tr("Edited at: "), o.isTimestampEmpty() ? tr("<new object>")
-                    : DateUtils.fromTimestamp(o.getRawTimestamp()));
-            add(tr("Edited by: "), o.getUser() == null ? tr("<new object>")
-                    : getNameAndId(o.getUser().getName(), o.getUser().getId()));
-            add(tr("Version: "), Integer.toString(o.getVersion()));
-            add(tr("In changeset: "), Integer.toString(o.getChangesetId()));
-        }
-
-        void addAttributes(OsmPrimitive o) {
-            if (o.hasKeys()) {
-                add(tr("Tags: "));
-                for (String key : o.keySet()) {
-                    s.append(INDENT).append(INDENT);
-                    s.append(String.format("\"%s\"=\"%s\"%n", key, o.get(key)));
-                }
-            }
-        }
-
-        void addSpecial(OsmPrimitive o) {
-            if (o instanceof Node) {
-                addCoordinates((Node) o);
-            } else if (o instanceof Way) {
-                addBbox(o);
-                add(tr("Centroid: "), Main.getProjection().eastNorth2latlon(
-                        Geometry.getCentroid(((Way) o).getNodes())).toStringCSV(", "));
-                addWayNodes((Way) o);
-            } else if (o instanceof Relation) {
-                addBbox(o);
-                addRelationMembers((Relation) o);
-            }
-        }
-
-        void addRelationMembers(Relation r) {
-            add(trn("{0} Member: ", "{0} Members: ", r.getMembersCount(), r.getMembersCount()));
-            for (RelationMember m : r.getMembers()) {
-                s.append(INDENT).append(INDENT);
-                addHeadline(m.getMember());
-                s.append(tr(" as \"{0}\"", m.getRole()));
-                s.append(NL);
-            }
-        }
-
-        void addWayNodes(Way w) {
-            add(tr("{0} Nodes: ", w.getNodesCount()));
-            for (Node n : w.getNodes()) {
-                s.append(INDENT).append(INDENT);
-                addNameAndId(n);
-                s.append(NL);
-            }
-        }
-
-        void addBbox(OsmPrimitive o) {
-            BBox bbox = o.getBBox();
-            if (bbox != null) {
-                add(tr("Bounding box: "), bbox.toStringCSV(", "));
-                EastNorth bottomRigth = Main.getProjection().latlon2eastNorth(bbox.getBottomRight());
-                EastNorth topLeft = Main.getProjection().latlon2eastNorth(bbox.getTopLeft());
-                add(tr("Bounding box (projected): "),
-                        Double.toString(topLeft.east()), ", ",
-                        Double.toString(bottomRigth.north()), ", ",
-                        Double.toString(bottomRigth.east()), ", ",
-                        Double.toString(topLeft.north()));
-                add(tr("Center of bounding box: "), bbox.getCenter().toStringCSV(", "));
-            }
-        }
-
-        void addCoordinates(Node n) {
-            if (n.getCoor() != null) {
-                add(tr("Coordinates: "),
-                        Double.toString(n.getCoor().lat()), ", ",
-                        Double.toString(n.getCoor().lon()));
-                add(tr("Coordinates (projected): "),
-                        Double.toString(n.getEastNorth().east()), ", ",
-                        Double.toString(n.getEastNorth().north()));
-            }
-        }
-
-        void addReferrers(StringBuilder s, OsmPrimitive o) {
-            List<OsmPrimitive> refs = o.getReferrers();
-            if (!refs.isEmpty()) {
-                add(tr("Part of: "));
-                for (OsmPrimitive p : refs) {
-                    s.append(INDENT).append(INDENT);
-                    addHeadline(p);
-                    s.append(NL);
-                }
-            }
-        }
-
-        void addConflicts(OsmPrimitive o) {
-            Conflict<?> c = layer.getConflicts().getConflictForMy(o);
-            if (c != null) {
-                add(tr("In conflict with: "));
-                addNameAndId(c.getTheir());
-            }
-        }
-
-        @Override
-        public String toString() {
-            return s.toString();
-        }
-    }
-
-    protected String buildMapPaintText() {
+    protected static String buildMapPaintText() {
         final Collection<OsmPrimitive> sel = Main.main.getCurrentDataSet().getAllSelected();
         ElemStyles elemstyles = MapPaintStyles.getStyles();
@@ -392,5 +182,5 @@
         Count only tagged nodes (so empty way nodes don't inflate counts).
     */
-    protected String buildListOfEditorsText() {
+    protected static String buildListOfEditorsText(Iterable<OsmPrimitive> primitives) {
         final StringBuilder s = new StringBuilder();
         final Map<String, Integer> editCountByUser = new TreeMap<>(Collator.getInstance(Locale.getDefault()));
@@ -416,5 +206,5 @@
             final String username = entry.getKey();
             final Integer editCount = entry.getValue();
-            s.append(String.format("%6d  %s%n", editCount, username));
+            s.append(String.format("%6d  %s\n", editCount, username));
         }
         return s.toString();
Index: /trunk/src/org/openstreetmap/josm/gui/mappaint/styleelement/NodeElement.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/mappaint/styleelement/NodeElement.java	(revision 10197)
+++ /trunk/src/org/openstreetmap/josm/gui/mappaint/styleelement/NodeElement.java	(revision 10198)
@@ -241,5 +241,5 @@
 
         Stroke stroke = null;
-        if (strokeColor != null) {
+        if (strokeColor != null && strokeWidth != null) {
             Integer strokeAlpha = Utils.color_float2int(c.get("symbol-stroke-opacity", null, Float.class));
             if (strokeAlpha != null) {
Index: /trunk/test/unit/org/openstreetmap/josm/gui/dialogs/InspectPrimitiveDialogTest.java
===================================================================
--- /trunk/test/unit/org/openstreetmap/josm/gui/dialogs/InspectPrimitiveDialogTest.java	(revision 10198)
+++ /trunk/test/unit/org/openstreetmap/josm/gui/dialogs/InspectPrimitiveDialogTest.java	(revision 10198)
@@ -0,0 +1,131 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.gui.dialogs;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import java.util.ArrayList;
+
+import javax.swing.JPanel;
+
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.openstreetmap.josm.JOSMFixture;
+import org.openstreetmap.josm.Main;
+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.data.osm.User;
+import org.openstreetmap.josm.gui.layer.OsmDataLayer;
+
+/**
+ * Unit tests of {@link InspectPrimitiveDialog} class.
+ */
+public class InspectPrimitiveDialogTest {
+
+    /**
+     * Setup tests
+     */
+    @BeforeClass
+    public static void setUpBeforeClass() {
+        JOSMFixture.createUnitTestFixture().init(true);
+    }
+
+    /**
+     * Unit test of {@link InspectPrimitiveDialog#genericMonospacePanel}.
+     */
+    @Test
+    public void testGenericMonospacePanel() {
+        assertNotNull(InspectPrimitiveDialog.genericMonospacePanel(new JPanel(), ""));
+    }
+
+    /**
+     * Unit test of {@link InspectPrimitiveDialog#buildDataText}.
+     */
+    @Test
+    public void testBuildDataText() {
+        DataSet ds = new DataSet();
+        OsmDataLayer layer = new OsmDataLayer(ds, "", null);
+        assertEquals("", InspectPrimitiveDialog.buildDataText(layer, new ArrayList<>(ds.allPrimitives())));
+        Node n = new Node(LatLon.ZERO);
+        n.setOsmId(1, 1);
+        ds.addPrimitive(n);
+        assertEquals(
+                "Node: 1\n" +
+                "  Data Set: "+Integer.toHexString(ds.hashCode())+"\n" +
+                "  Edited at: <new object>\n" +
+                "  Edited by: <new object>\n" +
+                "  Version: 1\n" +
+                "  In changeset: 0\n" +
+                "  Coordinates: 0.0, 0.0\n" +
+                "  Coordinates (projected): 0.0, -7.081154551613622E-10\n" +
+                "\n", InspectPrimitiveDialog.buildDataText(layer, new ArrayList<>(ds.allPrimitives())));
+    }
+
+    /**
+     * Unit test of {@link InspectPrimitiveDialog#buildListOfEditorsText}.
+     */
+    @Test
+    public void testBuildListOfEditorsText() {
+        DataSet ds = new DataSet();
+        assertEquals("0 users last edited the selection:\n\n", InspectPrimitiveDialog.buildListOfEditorsText(ds.allPrimitives()));
+        ds.addPrimitive(new Node(LatLon.ZERO));
+        assertEquals("0 users last edited the selection:\n\n", InspectPrimitiveDialog.buildListOfEditorsText(ds.allPrimitives()));
+        Node n = new Node(LatLon.ZERO);
+        n.setUser(User.getAnonymous());
+        ds.addPrimitive(n);
+        n = new Node(LatLon.ZERO);
+        n.setUser(User.getAnonymous());
+        ds.addPrimitive(n);
+        assertEquals(
+                "1 user last edited the selection:\n" +
+                "\n" +
+                "     2  <anonymous>\n",
+                InspectPrimitiveDialog.buildListOfEditorsText(ds.allPrimitives()));
+    }
+
+    /**
+     * Unit test of {@link InspectPrimitiveDialog#buildMapPaintText}.
+     */
+    @Test
+    public void testBuildMapPaintText() {
+        DataSet ds = new DataSet();
+        OsmDataLayer layer = new OsmDataLayer(ds, "", null);
+
+        // CHECKSTYLE.OFF: LineLength
+        String baseText =
+                "Styles Cache for \"node ‎(0.0, 0.0)\":\n" +
+                "\n" +
+                "> applying mapcss style \"JOSM default (MapCSS)\"\n" +
+                "\n" +
+                "Range:|s119.4328566955879-Infinity\n" +
+                " default: \n" +
+                "Cascade{ symbol-fill-color:#ff0000; symbol-stroke-color:#ff0000; major-z-index:4.95; font-size:8.0; symbol-shape:Keyword{square}; symbol-size:6.0; }\n" +
+                "\n" +
+                "> skipping \"Potlatch 2\" (not active)\n" +
+                "\n" +
+                "List of generated Styles:\n" +
+                " * NodeElemStyle{z_idx=[4.95/0.0/0.0]  symbol=[symbol=SQUARE size=6 stroke=java.awt.BasicStroke strokeColor=java.awt.Color[r=255,g=0,b=0] fillColor=java.awt.Color[r=255,g=0,b=0]]}\n" +
+                "\n" +
+                "\n";
+        // CHECKSTYLE.ON: LineLength
+
+        try {
+            Main.main.addLayer(layer);
+            assertEquals("", InspectPrimitiveDialog.buildMapPaintText());
+            Node n = new Node(LatLon.ZERO);
+            n.setUser(User.getAnonymous());
+            ds.addPrimitive(n);
+            ds.addSelected(n);
+            assertEquals(baseText, InspectPrimitiveDialog.buildMapPaintText().replaceAll("@(\\p{XDigit})+", ""));
+            n = new Node(LatLon.ZERO);
+            n.setUser(User.getAnonymous());
+            ds.addPrimitive(n);
+            ds.addSelected(n);
+            assertEquals(baseText + baseText + "Warning: The 2 selected objects have equal, but not identical style caches.",
+                    InspectPrimitiveDialog.buildMapPaintText().replaceAll("@(\\p{XDigit})+", ""));
+        } finally {
+            Main.main.removeLayer(layer);
+        }
+    }
+}
