Index: trunk/src/org/openstreetmap/josm/data/osm/visitor/paint/StyledMapRenderer.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/osm/visitor/paint/StyledMapRenderer.java	(revision 7446)
+++ trunk/src/org/openstreetmap/josm/data/osm/visitor/paint/StyledMapRenderer.java	(revision 7447)
@@ -69,4 +69,5 @@
 import org.openstreetmap.josm.gui.mappaint.StyleCache.StyleList;
 import org.openstreetmap.josm.gui.mappaint.TextElement;
+import org.openstreetmap.josm.gui.mappaint.mapcss.MapCSSStyleSource;
 import org.openstreetmap.josm.gui.mappaint.mapcss.Selector;
 import org.openstreetmap.josm.tools.CompositeList;
@@ -1342,11 +1343,13 @@
         @Override
         public List<StyleRecord> call() throws Exception {
-            for (int i = from; i<to; i++) {
-                OsmPrimitive osm = input.get(i);
-                if (osm.isDrawable()) {
-                    osm.accept(this);
-                }
-            }
-            return output;
+            synchronized (MapCSSStyleSource.STYLE_SOURCE_LOCK) {
+                for (int i = from; i<to; i++) {
+                    OsmPrimitive osm = input.get(i);
+                    if (osm.isDrawable()) {
+                        osm.accept(this);
+                    }
+                }
+                return output;
+            }
         }
 
Index: trunk/src/org/openstreetmap/josm/gui/NavigatableComponent.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/NavigatableComponent.java	(revision 7446)
+++ trunk/src/org/openstreetmap/josm/gui/NavigatableComponent.java	(revision 7447)
@@ -49,4 +49,5 @@
 import org.openstreetmap.josm.gui.help.Helpful;
 import org.openstreetmap.josm.gui.mappaint.MapPaintStyles;
+import org.openstreetmap.josm.gui.mappaint.mapcss.MapCSSStyleSource;
 import org.openstreetmap.josm.gui.preferences.projection.ProjectionPreference;
 import org.openstreetmap.josm.tools.Predicate;
@@ -90,5 +91,7 @@
             if (!prim.isSelectable()) return false;
             // if it isn't displayed on screen, you cannot click on it
-            return !MapPaintStyles.getStyles().get(prim, getDist100Pixel(), NavigatableComponent.this).isEmpty();
+            synchronized (MapCSSStyleSource.STYLE_SOURCE_LOCK) {
+                return !MapPaintStyles.getStyles().get(prim, getDist100Pixel(), NavigatableComponent.this).isEmpty();
+            }
         }
     };
Index: trunk/src/org/openstreetmap/josm/gui/dialogs/InspectPrimitiveDialog.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/dialogs/InspectPrimitiveDialog.java	(revision 7446)
+++ trunk/src/org/openstreetmap/josm/gui/dialogs/InspectPrimitiveDialog.java	(revision 7447)
@@ -337,29 +337,30 @@
         double scale = nc.getDist100Pixel();
 
-        for (OsmPrimitive osm : sel) {
-            txtMappaint.append(tr("Styles Cache for \"{0}\":", osm.getDisplayName(DefaultNameFormatter.getInstance())));
-
-            MultiCascade mc = new MultiCascade();
-
-            for (StyleSource s : elemstyles.getStyleSources()) {
-                if (s.active) {
-                    txtMappaint.append(tr("\n\n> applying {0} style \"{1}\"\n", getSort(s), s.getDisplayString()));
-                    s.apply(mc, osm, scale, null, false);
-                    txtMappaint.append(tr("\nRange:{0}", mc.range));
-                    for (Entry<String, Cascade> e : mc.getLayers()) {
-                        txtMappaint.append("\n " + e.getKey() + ": \n" + e.getValue());
+        synchronized (MapCSSStyleSource.STYLE_SOURCE_LOCK) {
+            for (OsmPrimitive osm : sel) {
+                txtMappaint.append(tr("Styles Cache for \"{0}\":", osm.getDisplayName(DefaultNameFormatter.getInstance())));
+
+                MultiCascade mc = new MultiCascade();
+
+                for (StyleSource s : elemstyles.getStyleSources()) {
+                    if (s.active) {
+                        txtMappaint.append(tr("\n\n> applying {0} style \"{1}\"\n", getSort(s), s.getDisplayString()));
+                        s.apply(mc, osm, scale, null, false);
+                        txtMappaint.append(tr("\nRange:{0}", mc.range));
+                        for (Entry<String, Cascade> e : mc.getLayers()) {
+                            txtMappaint.append("\n " + e.getKey() + ": \n" + e.getValue());
+                        }
+                    } else {
+                        txtMappaint.append(tr("\n\n> skipping \"{0}\" (not active)", s.getDisplayString()));
                     }
-                } else {
-                    txtMappaint.append(tr("\n\n> skipping \"{0}\" (not active)", s.getDisplayString()));
-                }
-            }
-            txtMappaint.append(tr("\n\nList of generated Styles:\n"));
-            StyleList sl = elemstyles.get(osm, scale, nc);
-            for (ElemStyle s : sl) {
-                txtMappaint.append(" * " + s + "\n");
-            }
-            txtMappaint.append("\n\n");
-        }
-
+                }
+                txtMappaint.append(tr("\n\nList of generated Styles:\n"));
+                StyleList sl = elemstyles.get(osm, scale, nc);
+                for (ElemStyle s : sl) {
+                    txtMappaint.append(" * " + s + "\n");
+                }
+                txtMappaint.append("\n\n");
+            }
+        }
         if (sel.size() == 2) {
             List<OsmPrimitive> selList = new ArrayList<>(sel);
Index: trunk/src/org/openstreetmap/josm/gui/mappaint/ElemStyles.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/mappaint/ElemStyles.java	(revision 7446)
+++ trunk/src/org/openstreetmap/josm/gui/mappaint/ElemStyles.java	(revision 7447)
@@ -18,4 +18,5 @@
 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.util.GuiHelper;
 import org.openstreetmap.josm.tools.Pair;
@@ -446,11 +447,13 @@
      */
     public static AreaElemStyle getAreaElemStyle(OsmPrimitive p, boolean pretendWayIsClosed) {
-        if (MapPaintStyles.getStyles() == null)
+        synchronized (MapCSSStyleSource.STYLE_SOURCE_LOCK) {
+            if (MapPaintStyles.getStyles() == null)
+                return null;
+            for (ElemStyle s : MapPaintStyles.getStyles().generateStyles(p, 1.0, null, pretendWayIsClosed).a) {
+                if (s instanceof AreaElemStyle)
+                    return (AreaElemStyle) s;
+            }
             return null;
-        for (ElemStyle s : MapPaintStyles.getStyles().generateStyles(p, 1.0, null, pretendWayIsClosed).a) {
-            if (s instanceof AreaElemStyle)
-                return (AreaElemStyle) s;
-        }
-        return null;
+        }
     }
 
Index: trunk/src/org/openstreetmap/josm/gui/mappaint/MapPaintStyles.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/mappaint/MapPaintStyles.java	(revision 7446)
+++ trunk/src/org/openstreetmap/josm/gui/mappaint/MapPaintStyles.java	(revision 7447)
@@ -143,5 +143,8 @@
             Node virtualNode = new Node(LatLon.ZERO);
             virtualNode.put(tag.getKey(), tag.getValue());
-            StyleList styleList = getStyles().generateStyles(virtualNode, 0.5, null, false).a;
+            StyleList styleList;
+            synchronized (MapCSSStyleSource.STYLE_SOURCE_LOCK) {
+                styleList = getStyles().generateStyles(virtualNode, 0.5, null, false).a;
+            }
             if (styleList != null) {
                 for (ElemStyle style : styleList) {
Index: trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/Condition.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/Condition.java	(revision 7446)
+++ trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/Condition.java	(revision 7447)
@@ -400,4 +400,5 @@
                 return e.osm.hasSameInterestingTags(Utils.firstNonNull(e.child, e.parent));
             case "areaStyle":
+                // only for validator
                 return ElemStyles.hasAreaElemStyle(e.osm, false);
             case "unconnected":
Index: trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/MapCSSStyleSource.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/MapCSSStyleSource.java	(revision 7446)
+++ trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/MapCSSStyleSource.java	(revision 7447)
@@ -70,4 +70,13 @@
 
     /**
+     * This lock prevents concurrent execution of {@link MapCSSRuleIndex#clear() },
+     * {@link MapCSSRuleIndex#initIndex()} and {@link MapCSSRuleIndex#getRuleCandidates }.
+     * 
+     * For efficiency reasons, these methods are synchronized higher up the
+     * stack trace.
+     */
+    public final static Object STYLE_SOURCE_LOCK = new Object();
+    
+    /**
      * A collection of {@link MapCSSRule}s, that are indexed by tag key and value.
      * 
@@ -91,4 +100,6 @@
         public final Set<MapCSSRule> remaining = new HashSet<>();
         
+        private static final boolean DEBUG_LOCKING = false;
+        
         public void add(MapCSSRule rule) {
             rules.add(rule);
@@ -97,6 +108,13 @@
         /**
          * Initialize the index.
+         * 
+         * You must own the lock STYLE_SOURCE_LOCK when calling this method.
          */
         public void initIndex() {
+            if (DEBUG_LOCKING) {
+                if (!Thread.holdsLock(STYLE_SOURCE_LOCK)) {
+                    throw new RuntimeException();
+                }
+            }
             for (MapCSSRule r: rules) {
                 // find the rightmost selector, this must be a GeneralSelector
@@ -135,6 +153,13 @@
          * @return a Collection of rules that filters out most of the rules
          * that cannot match, based on the tags of the primitive
+         * 
+         * You must own the lock STYLE_SOURCE_LOCK when calling this method.
          */
         public Collection<MapCSSRule> getRuleCandidates(OsmPrimitive osm) {
+            if (DEBUG_LOCKING) {
+                if (!Thread.holdsLock(STYLE_SOURCE_LOCK)) {
+                    throw new RuntimeException();
+                }
+            }
             List<MapCSSRule> ruleCandidates = new ArrayList<>(remaining);
             for (Map.Entry<String,String> e : osm.getKeys().entrySet()) {
@@ -151,5 +176,15 @@
         } 
 
+        /**
+         * Clear the index.
+         * 
+         * You must own the lock STYLE_SOURCE_LOCK when calling this method.
+         */
         public void clear() {
+            if (DEBUG_LOCKING) {
+                if (!Thread.holdsLock(STYLE_SOURCE_LOCK)) {
+                    throw new RuntimeException();
+                }
+            }
             rules.clear();
             index.clear();
@@ -181,91 +216,93 @@
     @Override
     public void loadStyleSource() {
-        init();
-        rules.clear();
-        nodeRules.clear();
-        wayRules.clear();
-        wayNoAreaRules.clear();
-        relationRules.clear();
-        multipolygonRules.clear();
-        canvasRules.clear();
-        try (InputStream in = getSourceInputStream()) {
-            try {
-                // evaluate @media { ... } blocks
-                MapCSSParser preprocessor = new MapCSSParser(in, "UTF-8", MapCSSParser.LexicalState.PREPROCESSOR);
-                String mapcss = preprocessor.pp_root(this);
-
-                // do the actual mapcss parsing
-                InputStream in2 = new ByteArrayInputStream(mapcss.getBytes(StandardCharsets.UTF_8));
-                MapCSSParser parser = new MapCSSParser(in2, "UTF-8", MapCSSParser.LexicalState.DEFAULT);
-                parser.sheet(this);
-
-                loadMeta();
-                loadCanvas();
-            } finally {
-                closeSourceInputStream(in);
-            }
-        } catch (IOException e) {
-            Main.warn(tr("Failed to load Mappaint styles from ''{0}''. Exception was: {1}", url, e.toString()));
-            Main.error(e);
-            logError(e);
-        } catch (TokenMgrError e) {
-            Main.warn(tr("Failed to parse Mappaint styles from ''{0}''. Error was: {1}", url, e.getMessage()));
-            Main.error(e);
-            logError(e);
-        } catch (ParseException e) {
-            Main.warn(tr("Failed to parse Mappaint styles from ''{0}''. Error was: {1}", url, e.getMessage()));
-            Main.error(e);
-            logError(new ParseException(e.getMessage())); // allow e to be garbage collected, it links to the entire token stream
-        }
-        // optimization: filter rules for different primitive types
-        for (MapCSSRule r: rules) {
-            // find the rightmost selector, this must be a GeneralSelector
-            Selector selRightmost = r.selector;
-            while (selRightmost instanceof ChildOrParentSelector) {
-                selRightmost = ((ChildOrParentSelector) selRightmost).right;
-            }
-            MapCSSRule optRule = new MapCSSRule(r.selector.optimizedBaseCheck(), r.declaration);
-            final String base = ((GeneralSelector) selRightmost).getBase();
-            switch (base) {
-                case "node":
-                    nodeRules.add(optRule);
-                    break;
-                case "way":
-                    wayNoAreaRules.add(optRule);
-                    wayRules.add(optRule);
-                    break;
-                case "area":
-                    wayRules.add(optRule);
-                    multipolygonRules.add(optRule);
-                    break;
-                case "relation":
-                    relationRules.add(optRule);
-                    multipolygonRules.add(optRule);
-                    break;
-                case "*":
-                    nodeRules.add(optRule);
-                    wayRules.add(optRule);
-                    wayNoAreaRules.add(optRule);
-                    relationRules.add(optRule);
-                    multipolygonRules.add(optRule);
-                    break;
-                case "canvas":
-                    canvasRules.add(r);
-                    break;
-                case "meta":
-                    break;
-                default:
-                    final RuntimeException e = new RuntimeException(MessageFormat.format("Unknown MapCSS base selector {0}", base));
-                    Main.warn(tr("Failed to parse Mappaint styles from ''{0}''. Error was: {1}", url, e.getMessage()));
-                    Main.error(e);
-                    logError(e);
-            }
-        }
-        nodeRules.initIndex();
-        wayRules.initIndex();
-        wayNoAreaRules.initIndex();
-        relationRules.initIndex();
-        multipolygonRules.initIndex();
-        canvasRules.initIndex();
+        synchronized (STYLE_SOURCE_LOCK) {
+            init();
+            rules.clear();
+            nodeRules.clear();
+            wayRules.clear();
+            wayNoAreaRules.clear();
+            relationRules.clear();
+            multipolygonRules.clear();
+            canvasRules.clear();
+            try (InputStream in = getSourceInputStream()) {
+                try {
+                    // evaluate @media { ... } blocks
+                    MapCSSParser preprocessor = new MapCSSParser(in, "UTF-8", MapCSSParser.LexicalState.PREPROCESSOR);
+                    String mapcss = preprocessor.pp_root(this);
+
+                    // do the actual mapcss parsing
+                    InputStream in2 = new ByteArrayInputStream(mapcss.getBytes(StandardCharsets.UTF_8));
+                    MapCSSParser parser = new MapCSSParser(in2, "UTF-8", MapCSSParser.LexicalState.DEFAULT);
+                    parser.sheet(this);
+
+                    loadMeta();
+                    loadCanvas();
+                } finally {
+                    closeSourceInputStream(in);
+                }
+            } catch (IOException e) {
+                Main.warn(tr("Failed to load Mappaint styles from ''{0}''. Exception was: {1}", url, e.toString()));
+                Main.error(e);
+                logError(e);
+            } catch (TokenMgrError e) {
+                Main.warn(tr("Failed to parse Mappaint styles from ''{0}''. Error was: {1}", url, e.getMessage()));
+                Main.error(e);
+                logError(e);
+            } catch (ParseException e) {
+                Main.warn(tr("Failed to parse Mappaint styles from ''{0}''. Error was: {1}", url, e.getMessage()));
+                Main.error(e);
+                logError(new ParseException(e.getMessage())); // allow e to be garbage collected, it links to the entire token stream
+            }
+            // optimization: filter rules for different primitive types
+            for (MapCSSRule r: rules) {
+                // find the rightmost selector, this must be a GeneralSelector
+                Selector selRightmost = r.selector;
+                while (selRightmost instanceof ChildOrParentSelector) {
+                    selRightmost = ((ChildOrParentSelector) selRightmost).right;
+                }
+                MapCSSRule optRule = new MapCSSRule(r.selector.optimizedBaseCheck(), r.declaration);
+                final String base = ((GeneralSelector) selRightmost).getBase();
+                switch (base) {
+                    case "node":
+                        nodeRules.add(optRule);
+                        break;
+                    case "way":
+                        wayNoAreaRules.add(optRule);
+                        wayRules.add(optRule);
+                        break;
+                    case "area":
+                        wayRules.add(optRule);
+                        multipolygonRules.add(optRule);
+                        break;
+                    case "relation":
+                        relationRules.add(optRule);
+                        multipolygonRules.add(optRule);
+                        break;
+                    case "*":
+                        nodeRules.add(optRule);
+                        wayRules.add(optRule);
+                        wayNoAreaRules.add(optRule);
+                        relationRules.add(optRule);
+                        multipolygonRules.add(optRule);
+                        break;
+                    case "canvas":
+                        canvasRules.add(r);
+                        break;
+                    case "meta":
+                        break;
+                    default:
+                        final RuntimeException e = new RuntimeException(MessageFormat.format("Unknown MapCSS base selector {0}", base));
+                        Main.warn(tr("Failed to parse Mappaint styles from ''{0}''. Error was: {1}", url, e.getMessage()));
+                        Main.error(e);
+                        logError(e);
+                }
+            }
+            nodeRules.initIndex();
+            wayRules.initIndex();
+            wayNoAreaRules.initIndex();
+            relationRules.initIndex();
+            multipolygonRules.initIndex();
+            canvasRules.initIndex();
+        }
     }
     
