Index: trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/ConditionFactory.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/ConditionFactory.java	(revision 17761)
+++ trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/ConditionFactory.java	(revision 17762)
@@ -2,8 +2,9 @@
 package org.openstreetmap.josm.gui.mappaint.mapcss;
 
-import java.lang.reflect.Method;
 import java.text.MessageFormat;
-import java.util.Arrays;
 import java.util.EnumSet;
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.Map;
 import java.util.Objects;
 import java.util.Set;
@@ -33,5 +34,4 @@
 import org.openstreetmap.josm.gui.mappaint.mapcss.Condition.TagCondition;
 import org.openstreetmap.josm.tools.CheckParameterUtil;
-import org.openstreetmap.josm.tools.JosmRuntimeException;
 import org.openstreetmap.josm.tools.Utils;
 
@@ -883,10 +883,36 @@
     public static class PseudoClassCondition implements Condition {
 
-        final Method method;
-        final boolean not;
-
-        protected PseudoClassCondition(Method method, boolean not) {
-            this.method = method;
-            this.not = not;
+        static final Map<String, PseudoClassCondition> CONDITION_MAP = new HashMap<>();
+
+        static {
+            PseudoClassCondition.register("anticlockwise", PseudoClasses::anticlockwise);
+            PseudoClassCondition.register("areaStyle", PseudoClasses::areaStyle);
+            PseudoClassCondition.register("clockwise", PseudoClasses::clockwise);
+            PseudoClassCondition.register("closed", PseudoClasses::closed);
+            PseudoClassCondition.register("closed2", PseudoClasses::closed2);
+            PseudoClassCondition.register("completely_downloaded", PseudoClasses::completely_downloaded);
+            PseudoClassCondition.register("connection", PseudoClasses::connection);
+            PseudoClassCondition.register("inDownloadedArea", PseudoClasses::inDownloadedArea);
+            PseudoClassCondition.register("modified", PseudoClasses::modified);
+            PseudoClassCondition.register("new", PseudoClasses::_new);
+            PseudoClassCondition.register("righthandtraffic", PseudoClasses::righthandtraffic);
+            PseudoClassCondition.register("sameTags", PseudoClasses::sameTags);
+            PseudoClassCondition.register("selected", PseudoClasses::selected);
+            PseudoClassCondition.register("tagged", PseudoClasses::tagged);
+            PseudoClassCondition.register("unclosed_multipolygon", PseudoClasses::unclosed_multipolygon);
+            PseudoClassCondition.register("unconnected", PseudoClasses::unconnected);
+        }
+
+        private static void register(String name, Predicate<Environment> predicate) {
+            CONDITION_MAP.put(clean(name), new PseudoClassCondition(":" + name, predicate));
+            CONDITION_MAP.put("!" + clean(name), new PseudoClassCondition("!:" + name, predicate.negate()));
+        }
+
+        private final String name;
+        private final Predicate<Environment> predicate;
+
+        protected PseudoClassCondition(String name, Predicate<Environment> predicate) {
+            this.name = name;
+            this.predicate = predicate;
         }
 
@@ -903,35 +929,25 @@
                 return new OpenEndPseudoClassCondition(not);
             }
-            final Method method = getMethod(id);
-            if (method != null) {
-                return new PseudoClassCondition(method, not);
+            String cleanId = not ? clean("!" + id) : clean(id);
+            PseudoClassCondition condition = CONDITION_MAP.get(cleanId);
+            if (condition != null) {
+                return condition;
             }
             throw new MapCSSException("Invalid pseudo class specified: " + id);
-        }
-
-        protected static Method getMethod(String id) {
-            String cleanId = clean(id);
-            return Arrays.stream(PseudoClasses.class.getDeclaredMethods())
-                    .filter(method -> clean(method.getName()).equalsIgnoreCase(cleanId))
-                    .findFirst().orElse(null);
         }
 
         private static String clean(String id) {
             // for backwards compatibility, consider :sameTags == :same-tags == :same_tags (#11150)
-            return id.replaceAll("[-_]", "");
+            return id.toLowerCase(Locale.ROOT).replaceAll("[-_]", "");
         }
 
         @Override
         public boolean applies(Environment e) {
-            try {
-                return not ^ (Boolean) method.invoke(null, e);
-            } catch (ReflectiveOperationException ex) {
-                throw new JosmRuntimeException(ex);
-            }
+            return predicate.test(e);
         }
 
         @Override
         public String toString() {
-            return (not ? "!" : "") + ':' + method.getName();
+            return name;
         }
     }
@@ -941,4 +957,5 @@
      */
     public static class OpenEndPseudoClassCondition extends PseudoClassCondition {
+        final boolean not;
         /**
          * Constructs a new {@code OpenEndPseudoClassCondition}.
@@ -946,10 +963,11 @@
          */
         public OpenEndPseudoClassCondition(boolean not) {
-            super(null, not);
+            super("open_end", null);
+            this.not = not;
         }
 
         @Override
         public boolean applies(Environment e) {
-            return true;
+            return !not;
         }
     }
