Index: trunk/src/org/openstreetmap/josm/data/osm/visitor/paint/StyledMapRenderer.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/osm/visitor/paint/StyledMapRenderer.java	(revision 9283)
+++ trunk/src/org/openstreetmap/josm/data/osm/visitor/paint/StyledMapRenderer.java	(revision 9284)
@@ -61,5 +61,5 @@
 import org.openstreetmap.josm.gui.mappaint.ElemStyles;
 import org.openstreetmap.josm.gui.mappaint.MapPaintStyles;
-import org.openstreetmap.josm.gui.mappaint.StyleCache.StyleList;
+import org.openstreetmap.josm.gui.mappaint.StyleElementList;
 import org.openstreetmap.josm.gui.mappaint.mapcss.MapCSSStyleSource;
 import org.openstreetmap.josm.gui.mappaint.mapcss.Selector;
@@ -1825,5 +1825,5 @@
 
         public void add(Node osm, int flags) {
-            StyleList sl = styles.get(osm, circum, nc);
+            StyleElementList sl = styles.get(osm, circum, nc);
             for (StyleElement s : sl) {
                 output.add(new StyleRecord(s, osm, flags));
@@ -1832,5 +1832,5 @@
 
         public void add(Relation osm, int flags) {
-            StyleList sl = styles.get(osm, circum, nc);
+            StyleElementList sl = styles.get(osm, circum, nc);
             for (StyleElement s : sl) {
                 if (drawMultipolygon && drawArea && s instanceof AreaElement && (flags & FLAG_DISABLED) == 0) {
@@ -1843,5 +1843,5 @@
 
         public void add(Way osm, int flags) {
-            StyleList sl = styles.get(osm, circum, nc);
+            StyleElementList sl = styles.get(osm, circum, nc);
             for (StyleElement s : sl) {
                 if (!(drawArea && (flags & FLAG_DISABLED) == 0) && s instanceof AreaElement) {
Index: trunk/src/org/openstreetmap/josm/gui/dialogs/InspectPrimitiveDialog.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/dialogs/InspectPrimitiveDialog.java	(revision 9283)
+++ trunk/src/org/openstreetmap/josm/gui/dialogs/InspectPrimitiveDialog.java	(revision 9284)
@@ -44,5 +44,5 @@
 import org.openstreetmap.josm.gui.mappaint.MultiCascade;
 import org.openstreetmap.josm.gui.mappaint.StyleCache;
-import org.openstreetmap.josm.gui.mappaint.StyleCache.StyleList;
+import org.openstreetmap.josm.gui.mappaint.StyleElementList;
 import org.openstreetmap.josm.gui.mappaint.StyleSource;
 import org.openstreetmap.josm.gui.mappaint.mapcss.MapCSSStyleSource;
@@ -362,5 +362,5 @@
                 }
                 txtMappaint.append(tr("\n\nList of generated Styles:\n"));
-                StyleList sl = elemstyles.get(osm, scale, nc);
+                StyleElementList sl = elemstyles.get(osm, scale, nc);
                 for (StyleElement s : sl) {
                     txtMappaint.append(" * ").append(s).append('\n');
Index: trunk/src/org/openstreetmap/josm/gui/mappaint/DividedScale.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/mappaint/DividedScale.java	(revision 9284)
+++ trunk/src/org/openstreetmap/josm/gui/mappaint/DividedScale.java	(revision 9284)
@@ -0,0 +1,196 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.gui.mappaint;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.openstreetmap.josm.gui.mappaint.styleelement.StyleElement;
+import org.openstreetmap.josm.tools.Pair;
+
+/**
+ * Splits the range of possible scale values (0 &lt; scale &lt; +Infinity) into
+ * multiple subranges, for each scale range it keeps a data object of a certain
+ * type T (can be null).
+ *
+ * Used for caching style information for different zoom levels.
+ *
+ * Immutable class, equals &amp; hashCode is required (the same for
+ * {@link StyleElementList}, {@link StyleElement} and its subclasses).
+ *
+ * @param <T> the type of the data objects
+ */
+public class DividedScale<T> {
+
+    // this exception type is for debugging #8997 and can later be replaced
+    // by AssertionError
+    public static class RangeViolatedError extends Error {
+        public RangeViolatedError() {
+        }
+
+        public RangeViolatedError(String message) {
+            super(message);
+        }
+    }
+
+    /* list of boundaries for the scale ranges */
+    private final List<Double> bd;
+    /* data objects for each scale range */
+    private final List<T> data;
+
+    protected DividedScale() {
+        bd = new ArrayList<>();
+        bd.add(0.0);
+        bd.add(Double.POSITIVE_INFINITY);
+        data = new ArrayList<>();
+        data.add(null);
+    }
+
+    protected DividedScale(DividedScale<T> s) {
+        bd = new ArrayList<>(s.bd);
+        data = new ArrayList<>(s.data);
+    }
+
+    /**
+     * Looks up the data object for a certain scale value.
+     *
+     * @param scale scale
+     * @return the data object at the given scale, can be null
+     */
+    public T get(double scale) {
+        if (scale <= 0)
+            throw new IllegalArgumentException("scale must be <= 0 but is "+scale);
+        for (int i = 0; i < data.size(); ++i) {
+            if (bd.get(i) < scale && scale <= bd.get(i+1)) {
+                return data.get(i);
+            }
+        }
+        throw new AssertionError();
+    }
+
+    /**
+     * Looks up the data object for a certain scale value and additionally returns
+     * the scale range where the object is valid.
+     *
+     * @param scale scale
+     * @return pair containing data object and range
+     */
+    public Pair<T, Range> getWithRange(double scale) {
+        if (scale <= 0)
+            throw new IllegalArgumentException("scale must be <= 0 but is "+scale);
+        for (int i = 0; i < data.size(); ++i) {
+            if (bd.get(i) < scale && scale <= bd.get(i+1)) {
+                return new Pair<>(data.get(i), new Range(bd.get(i), bd.get(i+1)));
+            }
+        }
+        throw new AssertionError();
+    }
+
+    /**
+     * Add data object which is valid for the given range.
+     *
+     * This is only possible, if there is no data for the given range yet.
+     *
+     * @param o data object
+     * @param r the valid range
+     * @return a new, updated, <code>DividedScale</code> object
+     */
+    public DividedScale<T> put(T o, Range r) {
+        DividedScale<T> s = new DividedScale<>(this);
+        s.putImpl(o, r.getLower(), r.getUpper());
+        s.consistencyTest();
+        return s;
+    }
+
+    /**
+     * Implementation of the <code>put</code> operation.
+     *
+     * ASCII-art explanation:
+     *
+     *              data[i]
+     *  --|-------|---------|--
+     * bd[i-1]  bd[i]    bd[i+1]
+     *
+     *         (--------]
+     *       lower     upper
+     * @param o data object
+     * @param lower lower bound
+     * @param upper upper bound
+     */
+    protected void putImpl(T o, double lower, double upper) {
+        int i = 0;
+        while (bd.get(i) < lower) {
+            ++i;
+        }
+        if (bd.get(i) == lower) {
+            if (upper > bd.get(i+1))
+                throw new StyleCache.RangeViolatedError("the new range must be within a single subrange (1)");
+            if (data.get(i) != null)
+                throw new StyleCache.RangeViolatedError("the new range must be within a subrange that has no data");
+
+            if (bd.get(i+1) == upper) {
+                //  --|-------|--------|--
+                //   i-1      i       i+1
+                //            (--------]
+                data.set(i, o);
+            } else {
+                //  --|-------|--------|--
+                //   i-1      i       i+1
+                //            (-----]
+                bd.add(i+1, upper);
+                data.add(i, o);
+            }
+        } else {
+            if (bd.get(i) < upper)
+                throw new StyleCache.RangeViolatedError("the new range must be within a single subrange (2)");
+            if (data.get(i-1) != null)
+                throw new AssertionError();
+
+            //  --|-------|--------|--
+            //   i-1      i       i+1
+            //       (--]   or
+            //       (----]
+            bd.add(i, lower);
+            data.add(i, o);
+
+            //  --|--|----|--------|--
+            //   i-1 i   i+1      i+2
+            //       (--]
+            if (bd.get(i+1) > upper) {
+                bd.add(i+1, upper);
+                data.add(i+1, null);
+            }
+        }
+    }
+
+    public void consistencyTest() {
+        if (bd.size() < 2) throw new AssertionError(bd);
+        if (data.isEmpty()) throw new AssertionError(data);
+        if (bd.size() != data.size() + 1) throw new AssertionError();
+        if (bd.get(0) != 0) throw new AssertionError();
+        if (bd.get(bd.size() - 1) != Double.POSITIVE_INFINITY) throw new AssertionError();
+        for (int i = 0; i < data.size() - 1; ++i) {
+            if (bd.get(i) >= bd.get(i + 1)) throw new AssertionError();
+        }
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (obj == null || getClass() != obj.getClass())
+            return false;
+        final DividedScale other = (DividedScale) obj;
+        return bd.equals(other.bd) && data.equals(other.data);
+    }
+
+    @Override
+    public int hashCode() {
+        int hash = 7;
+        hash = 23 * hash + bd.hashCode();
+        hash = 23 * hash + data.hashCode();
+        return hash;
+    }
+
+    @Override
+    public String toString() {
+        return "DS{" + bd + ' ' + data + '}';
+    }
+}
Index: trunk/src/org/openstreetmap/josm/gui/mappaint/ElemStyles.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/mappaint/ElemStyles.java	(revision 9283)
+++ trunk/src/org/openstreetmap/josm/gui/mappaint/ElemStyles.java	(revision 9284)
@@ -21,5 +21,4 @@
 import org.openstreetmap.josm.data.osm.visitor.paint.relations.MultipolygonCache;
 import org.openstreetmap.josm.gui.NavigatableComponent;
-import org.openstreetmap.josm.gui.mappaint.StyleCache.StyleList;
 import org.openstreetmap.josm.gui.mappaint.mapcss.MapCSSStyleSource;
 import org.openstreetmap.josm.gui.mappaint.styleelement.AreaElement;
@@ -80,5 +79,5 @@
      * @return list of styles
      */
-    public StyleList get(OsmPrimitive osm, double scale, NavigatableComponent nc) {
+    public StyleElementList get(OsmPrimitive osm, double scale, NavigatableComponent nc) {
         return getStyleCacheWithRange(osm, scale, nc).a;
     }
@@ -94,13 +93,13 @@
      * @return pair containing style list and range
      */
-    public Pair<StyleList, Range> getStyleCacheWithRange(OsmPrimitive osm, double scale, NavigatableComponent nc) {
+    public Pair<StyleElementList, Range> getStyleCacheWithRange(OsmPrimitive osm, double scale, NavigatableComponent nc) {
         if (osm.mappaintStyle == null || osm.mappaintCacheIdx != cacheIdx || scale <= 0) {
             osm.mappaintStyle = StyleCache.EMPTY_STYLECACHE;
         } else {
-            Pair<StyleList, Range> lst = osm.mappaintStyle.getWithRange(scale);
+            Pair<StyleElementList, Range> lst = osm.mappaintStyle.getWithRange(scale);
             if (lst.a != null)
                 return lst;
         }
-        Pair<StyleList, Range> p = getImpl(osm, scale, nc);
+        Pair<StyleElementList, Range> p = getImpl(osm, scale, nc);
         if (osm instanceof Node && isDefaultNodes()) {
             if (p.a.isEmpty()) {
@@ -123,8 +122,8 @@
                 }
                 if (!hasNonModifier) {
-                    p.a = new StyleList(p.a, NodeElement.SIMPLE_NODE_ELEMSTYLE);
+                    p.a = new StyleElementList(p.a, NodeElement.SIMPLE_NODE_ELEMSTYLE);
                     if (!hasText) {
                         if (TextLabel.AUTO_LABEL_COMPOSITION_STRATEGY.compose(osm) != null) {
-                            p.a = new StyleList(p.a, BoxTextElement.SIMPLE_NODE_TEXT_ELEMSTYLE);
+                            p.a = new StyleElementList(p.a, BoxTextElement.SIMPLE_NODE_TEXT_ELEMSTYLE);
                         }
                     }
@@ -142,5 +141,5 @@
                 AreaElement area = Utils.find(p.a, AreaElement.class);
                 LineElement line = area == null ? LineElement.UNTAGGED_WAY : LineElement.createSimpleLineStyle(area.color, true);
-                p.a = new StyleList(p.a, line);
+                p.a = new StyleElementList(p.a, line);
             }
         }
@@ -186,9 +185,9 @@
      * @return pair containing style list and range
      */
-    private Pair<StyleList, Range> getImpl(OsmPrimitive osm, double scale, NavigatableComponent nc) {
+    private Pair<StyleElementList, Range> getImpl(OsmPrimitive osm, double scale, NavigatableComponent nc) {
         if (osm instanceof Node)
             return generateStyles(osm, scale, false);
         else if (osm instanceof Way) {
-            Pair<StyleList, Range> p = generateStyles(osm, scale, false);
+            Pair<StyleElementList, Range> p = generateStyles(osm, scale, false);
 
             boolean isOuterWayOfSomeMP = false;
@@ -216,10 +215,10 @@
                             }
                         }
-                        p.a = new StyleList(tmp);
+                        p.a = new StyleElementList(tmp);
                         isOuterWayOfSomeMP = true;
                     }
 
                     if (!hasIndependentLineStyle) {
-                        Pair<StyleList, Range> mpElemStyles;
+                        Pair<StyleElementList, Range> mpElemStyles;
                         synchronized (r) {
                             mpElemStyles = getStyleCacheWithRange(r, scale, nc);
@@ -234,5 +233,5 @@
                         p.b = Range.cut(p.b, mpElemStyles.b);
                         if (mpLine != null) {
-                            p.a = new StyleList(p.a, mpLine);
+                            p.a = new StyleElementList(p.a, mpLine);
                             break;
                         } else if (wayColor == null && isDefaultLines()) {
@@ -255,5 +254,5 @@
                     }
                     if (!hasLineStyle) {
-                        p.a = new StyleList(p.a, LineElement.createSimpleLineStyle(wayColor, true));
+                        p.a = new StyleElementList(p.a, LineElement.createSimpleLineStyle(wayColor, true));
                     }
                 }
@@ -281,5 +280,5 @@
                     if (!hasIndependentElemStyle && !multipolygon.getOuterWays().isEmpty()) {
                         Color mpColor = null;
-                        StyleList mpElemStyles = null;
+                        StyleElementList mpElemStyles = null;
                         synchronized (ref) {
                             mpElemStyles = get(ref, scale, nc);
@@ -291,5 +290,5 @@
                             }
                         }
-                        p.a = new StyleList(p.a, LineElement.createSimpleLineStyle(mpColor, true));
+                        p.a = new StyleElementList(p.a, LineElement.createSimpleLineStyle(mpColor, true));
                     }
                     return p;
@@ -298,5 +297,5 @@
             return p;
         } else if (osm instanceof Relation) {
-            Pair<StyleList, Range> p = generateStyles(osm, scale, true);
+            Pair<StyleElementList, Range> p = generateStyles(osm, scale, true);
             if (drawMultipolygon && ((Relation) osm).isMultipolygon()) {
                 if (!Utils.exists(p.a, AreaElement.class) && Main.pref.getBoolean("multipolygon.deprecated.outerstyle", true)) {
@@ -304,9 +303,9 @@
                     Multipolygon multipolygon = MultipolygonCache.getInstance().get(nc, (Relation) osm);
                     for (Way w : multipolygon.getOuterWays()) {
-                        Pair<StyleList, Range> wayStyles = generateStyles(w, scale, false);
+                        Pair<StyleElementList, Range> wayStyles = generateStyles(w, scale, false);
                         p.b = Range.cut(p.b, wayStyles.b);
                         StyleElement area = Utils.find(wayStyles.a, AreaElement.class);
                         if (area != null) {
-                            p.a = new StyleList(p.a, area);
+                            p.a = new StyleElementList(p.a, area);
                             break;
                         }
@@ -332,5 +331,5 @@
      * @return the generated styles and the valid range as a pair
      */
-    public Pair<StyleList, Range> generateStyles(OsmPrimitive osm, double scale, boolean pretendWayIsClosed) {
+    public Pair<StyleElementList, Range> generateStyles(OsmPrimitive osm, double scale, boolean pretendWayIsClosed) {
 
         List<StyleElement> sl = new ArrayList<>();
@@ -377,5 +376,5 @@
             }
         }
-        return new Pair<>(new StyleList(sl), mc.range);
+        return new Pair<>(new StyleElementList(sl), mc.range);
     }
 
@@ -501,5 +500,5 @@
             if (MapPaintStyles.getStyles() == null)
                 return false;
-            StyleList styles = MapPaintStyles.getStyles().generateStyles(p, 1.0, false).a;
+            StyleElementList styles = MapPaintStyles.getStyles().generateStyles(p, 1.0, false).a;
             if (styles.isEmpty()) {
                 return false;
Index: trunk/src/org/openstreetmap/josm/gui/mappaint/MapPaintStyles.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/mappaint/MapPaintStyles.java	(revision 9283)
+++ trunk/src/org/openstreetmap/josm/gui/mappaint/MapPaintStyles.java	(revision 9284)
@@ -27,5 +27,5 @@
 import org.openstreetmap.josm.data.osm.Tag;
 import org.openstreetmap.josm.gui.PleaseWaitRunnable;
-import org.openstreetmap.josm.gui.mappaint.StyleCache.StyleList;
+import org.openstreetmap.josm.gui.mappaint.StyleElementList;
 import org.openstreetmap.josm.gui.mappaint.mapcss.MapCSSStyleSource;
 import org.openstreetmap.josm.gui.mappaint.styleelement.MapImage;
@@ -184,5 +184,5 @@
             Node virtualNode = new Node(LatLon.ZERO);
             virtualNode.put(tag.getKey(), tag.getValue());
-            StyleList styleList;
+            StyleElementList styleList;
             MapCSSStyleSource.STYLE_SOURCE_LOCK.readLock().lock();
             try {
Index: trunk/src/org/openstreetmap/josm/gui/mappaint/StyleCache.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/mappaint/StyleCache.java	(revision 9283)
+++ trunk/src/org/openstreetmap/josm/gui/mappaint/StyleCache.java	(revision 9284)
@@ -2,27 +2,10 @@
 package org.openstreetmap.josm.gui.mappaint;
 
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Objects;
-
 import org.openstreetmap.josm.data.osm.Storage;
-import org.openstreetmap.josm.gui.mappaint.styleelement.StyleElement;
-import org.openstreetmap.josm.tools.Pair;
 
 /**
  * Caches styles for a single primitive.
- * Splits the range of possible scale values (0 &lt; scale &lt; +Infinity) into multiple
- * subranges, for each scale range it keeps a list of styles.
- * Immutable class, equals &amp; hashCode is required (the same for StyleList, StyleElement
- and its subclasses).
  */
-public final class StyleCache {
-    /* list of boundaries for the scale ranges */
-    private final List<Double> bd;
-    /* styles for each scale range */
-    private final List<StyleList> data;
+public final class StyleCache extends DividedScale<StyleElementList> {
 
     // TODO: clean up the intern pool from time to time (after purge or layer removal)
@@ -31,208 +14,28 @@
     public static final StyleCache EMPTY_STYLECACHE = (new StyleCache()).intern();
 
-    private StyleCache() {
-        bd = new ArrayList<>();
-        bd.add(0.0);
-        bd.add(Double.POSITIVE_INFINITY);
-        data = new ArrayList<>();
-        data.add(null);
+    private StyleCache(StyleCache sc) {
+        super(sc);
     }
 
-    private StyleCache(StyleCache s) {
-        bd = new ArrayList<>(s.bd);
-        data = new ArrayList<>(s.data);
+    private StyleCache() {
+        super();
     }
 
     /**
-     * List of Styles, immutable
+     * Add data object which is valid for the given range.
+     *
+     * This is only possible, if there is no data for the given range yet.
+     *
+     * @param o data object
+     * @param r the valid range
+     * @return a new, updated, <code>DividedScale</code> object
      */
-    public static class StyleList implements Iterable<StyleElement> {
-        private final List<StyleElement> lst;
-
-        /**
-         * Constructs a new {@code StyleList}.
-         */
-        public StyleList() {
-            lst = new ArrayList<>();
-        }
-
-        public StyleList(StyleElement... init) {
-            lst = new ArrayList<>(Arrays.asList(init));
-        }
-
-        public StyleList(Collection<StyleElement> sl) {
-            lst = new ArrayList<>(sl);
-        }
-
-        public StyleList(StyleList sl, StyleElement s) {
-            lst = new ArrayList<>(sl.lst);
-            lst.add(s);
-        }
-
-        @Override
-        public Iterator<StyleElement> iterator() {
-            return lst.iterator();
-        }
-
-        public boolean isEmpty() {
-            return lst.isEmpty();
-        }
-
-        public int size() {
-            return lst.size();
-        }
-
-        @Override
-        public String toString() {
-            return lst.toString();
-        }
-
-        @Override
-        public boolean equals(Object obj) {
-            if (obj == null || getClass() != obj.getClass())
-                return false;
-            final StyleList other = (StyleList) obj;
-            return Objects.equals(lst, other.lst);
-        }
-
-        @Override
-        public int hashCode() {
-            return lst.hashCode();
-        }
-    }
-
-    /**
-     * looks up styles for a certain scale value
-     * @param scale scale
-     * @return style list
-     */
-    public StyleList get(double scale) {
-        if (scale <= 0)
-            throw new IllegalArgumentException("scale must be <= 0 but is "+scale);
-        for (int i = 0; i < data.size(); ++i) {
-            if (bd.get(i) < scale && scale <= bd.get(i+1)) {
-                return data.get(i);
-            }
-        }
-        throw new AssertionError();
-    }
-
-    /**
-     * looks up styles for a certain scale value and additionally returns
-     * the scale range for the returned styles
-     * @param scale scale
-     * @return pair containing syle list and range
-     */
-    public Pair<StyleList, Range> getWithRange(double scale) {
-        if (scale <= 0)
-            throw new IllegalArgumentException("scale must be <= 0 but is "+scale);
-        for (int i = 0; i < data.size(); ++i) {
-            if (bd.get(i) < scale && scale <= bd.get(i+1)) {
-                return new Pair<>(data.get(i), new Range(bd.get(i), bd.get(i+1)));
-            }
-        }
-        throw new AssertionError();
-    }
-
-    public StyleCache put(StyleList sl, Range r) {
-        return put(sl, r.getLower(), r.getUpper());
-    }
-
-    /**
-     * add a new styles to the cache. this is only possible, if
-     * for this scale range, there is nothing in the cache yet.
-     * @param sl style list
-     * @param lower lower bound
-     * @param upper upper bound
-     * @return interned style cache
-     */
-    public StyleCache put(StyleList sl, double lower, double upper) {
+    @Override
+    public StyleCache put(StyleElementList o, Range r) {
         StyleCache s = new StyleCache(this);
-        s.putImpl(sl, lower, upper);
+        s.putImpl(o, r.getLower(), r.getUpper());
         s.consistencyTest();
-        return s.intern();
-    }
-
-    // this exception type is for debugging #8997 and can later be replaced
-    // by AssertionError
-    public static class RangeViolatedError extends Error {
-        public RangeViolatedError() {
-        }
-
-        public RangeViolatedError(String message) {
-            super(message);
-        }
-    }
-
-    /**
-     * ASCII-art explanation:
-     *
-     *              data[i]
-     *  --|-------|---------|--
-     * bd[i-1]  bd[i]    bd[i+1]
-     *
-     *         (--------]
-     *       lower     upper
-     * @param sl style list
-     * @param lower lower bound
-     * @param upper upper bound
-     */
-    private void putImpl(StyleList sl, double lower, double upper) {
-        int i = 0;
-        while (bd.get(i) < lower) {
-            ++i;
-        }
-        if (bd.get(i) == lower) {
-            if (upper > bd.get(i+1))
-                throw new RangeViolatedError("the new range must be within a single subrange (1)");
-            if (data.get(i) != null)
-                throw new RangeViolatedError("the new range must be within a subrange that has no data");
-
-            if (bd.get(i+1) == upper) {
-                //  --|-------|--------|--
-                //   i-1      i       i+1
-                //            (--------]
-                data.set(i, sl);
-            } else {
-                //  --|-------|--------|--
-                //   i-1      i       i+1
-                //            (-----]
-                bd.add(i+1, upper);
-                data.add(i, sl);
-            }
-            return;
-        } else {
-            if (bd.get(i) < upper)
-                throw new RangeViolatedError("the new range must be within a single subrange (2)");
-            if (data.get(i-1) != null)
-                throw new AssertionError();
-
-            //  --|-------|--------|--
-            //   i-1      i       i+1
-            //       (--]   or
-            //       (----]
-            bd.add(i, lower);
-            data.add(i, sl);
-
-            //  --|--|----|--------|--
-            //   i-1 i   i+1      i+2
-            //       (--]
-            if (bd.get(i+1) > upper) {
-                bd.add(i+1, upper);
-                data.add(i+1, null);
-            }
-            return;
-        }
-    }
-
-    public void consistencyTest() {
-        if (bd.size() < 2) throw new AssertionError(bd);
-        if (data.isEmpty()) throw new AssertionError(data);
-        if (bd.size() != data.size() + 1) throw new AssertionError();
-        if (bd.get(0) != 0) throw new AssertionError();
-        if (bd.get(bd.size() - 1) != Double.POSITIVE_INFINITY) throw new AssertionError();
-        for (int i = 0; i < data.size() - 1; ++i) {
-            if (bd.get(i) >= bd.get(i + 1)) throw new AssertionError();
-        }
+        s.intern();
+        return s;
     }
 
@@ -242,27 +45,6 @@
      * @return style cache
      */
-    public StyleCache intern() {
+    private StyleCache intern() {
         return internPool.putUnique(this);
     }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (obj == null || getClass() != obj.getClass())
-            return false;
-        final StyleCache other = (StyleCache) obj;
-        return bd.equals(other.bd) && data.equals(other.data);
-    }
-
-    @Override
-    public int hashCode() {
-        int hash = 7;
-        hash = 23 * hash + bd.hashCode();
-        hash = 23 * hash + data.hashCode();
-        return hash;
-    }
-
-    @Override
-    public String toString() {
-        return "SC{" + bd + ' ' + data + '}';
-    }
 }
Index: trunk/src/org/openstreetmap/josm/gui/mappaint/StyleElementList.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/mappaint/StyleElementList.java	(revision 9284)
+++ trunk/src/org/openstreetmap/josm/gui/mappaint/StyleElementList.java	(revision 9284)
@@ -0,0 +1,71 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.gui.mappaint;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Objects;
+
+import org.openstreetmap.josm.gui.mappaint.styleelement.StyleElement;
+
+/**
+ * List of {@link StyleElement}s, immutable.
+ */
+public class StyleElementList implements Iterable<StyleElement> {
+    private final List<StyleElement> lst;
+
+    /**
+     * Constructs a new {@code StyleList}.
+     */
+    public StyleElementList() {
+        lst = new ArrayList<>();
+    }
+
+    public StyleElementList(StyleElement... init) {
+        lst = new ArrayList<>(Arrays.asList(init));
+    }
+
+    public StyleElementList(Collection<StyleElement> sl) {
+        lst = new ArrayList<>(sl);
+    }
+
+    public StyleElementList(StyleElementList sl, StyleElement s) {
+        lst = new ArrayList<>(sl.lst);
+        lst.add(s);
+    }
+
+    @Override
+    public Iterator<StyleElement> iterator() {
+        return lst.iterator();
+    }
+
+    public boolean isEmpty() {
+        return lst.isEmpty();
+    }
+
+    public int size() {
+        return lst.size();
+    }
+
+    @Override
+    public String toString() {
+        return lst.toString();
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (obj == null || getClass() != obj.getClass()) {
+            return false;
+        }
+        final StyleElementList other = (StyleElementList) obj;
+        return Objects.equals(lst, other.lst);
+    }
+
+    @Override
+    public int hashCode() {
+        return lst.hashCode();
+    }
+
+}
Index: trunk/src/org/openstreetmap/josm/gui/mappaint/styleelement/NodeElement.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/mappaint/styleelement/NodeElement.java	(revision 9283)
+++ trunk/src/org/openstreetmap/josm/gui/mappaint/styleelement/NodeElement.java	(revision 9284)
@@ -19,5 +19,5 @@
 import org.openstreetmap.josm.gui.mappaint.MapPaintStyles.IconReference;
 import org.openstreetmap.josm.gui.mappaint.MultiCascade;
-import org.openstreetmap.josm.gui.mappaint.StyleCache.StyleList;
+import org.openstreetmap.josm.gui.mappaint.StyleElementList;
 import org.openstreetmap.josm.gui.mappaint.styleelement.BoxTextElement.BoxProvider;
 import org.openstreetmap.josm.gui.mappaint.styleelement.BoxTextElement.SimpleBoxProvider;
@@ -95,6 +95,6 @@
     }
 
-    public static final StyleList DEFAULT_NODE_STYLELIST = new StyleList(NodeElement.SIMPLE_NODE_ELEMSTYLE);
-    public static final StyleList DEFAULT_NODE_STYLELIST_TEXT = new StyleList(NodeElement.SIMPLE_NODE_ELEMSTYLE,
+    public static final StyleElementList DEFAULT_NODE_STYLELIST = new StyleElementList(NodeElement.SIMPLE_NODE_ELEMSTYLE);
+    public static final StyleElementList DEFAULT_NODE_STYLELIST_TEXT = new StyleElementList(NodeElement.SIMPLE_NODE_ELEMSTYLE,
             BoxTextElement.SIMPLE_NODE_TEXT_ELEMSTYLE);
 
Index: trunk/src/org/openstreetmap/josm/tools/ImageProvider.java
===================================================================
--- trunk/src/org/openstreetmap/josm/tools/ImageProvider.java	(revision 9283)
+++ trunk/src/org/openstreetmap/josm/tools/ImageProvider.java	(revision 9284)
@@ -61,5 +61,5 @@
 import org.openstreetmap.josm.gui.mappaint.MapPaintStyles;
 import org.openstreetmap.josm.gui.mappaint.Range;
-import org.openstreetmap.josm.gui.mappaint.StyleCache.StyleList;
+import org.openstreetmap.josm.gui.mappaint.StyleElementList;
 import org.openstreetmap.josm.gui.mappaint.styleelement.MapImage;
 import org.openstreetmap.josm.gui.mappaint.styleelement.StyleElement;
@@ -1299,5 +1299,5 @@
         // Check if the current styles have special icon for tagged nodes.
         if (primitive instanceof org.openstreetmap.josm.data.osm.Node) {
-            Pair<StyleList, Range> nodeStyles = MapPaintStyles.getStyles().generateStyles(primitive, 100, false);
+            Pair<StyleElementList, Range> nodeStyles = MapPaintStyles.getStyles().generateStyles(primitive, 100, false);
             for (StyleElement style : nodeStyles.a) {
                 if (style instanceof NodeElement) {
