Index: trunk/src/org/openstreetmap/josm/plugins/PluginListParser.java
===================================================================
--- trunk/src/org/openstreetmap/josm/plugins/PluginListParser.java	(revision 18795)
+++ trunk/src/org/openstreetmap/josm/plugins/PluginListParser.java	(revision 18796)
@@ -12,4 +12,6 @@
 import java.util.List;
 import java.util.jar.Attributes;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
 import org.openstreetmap.josm.tools.Logging;
@@ -63,9 +65,14 @@
             String url = null;
             Attributes manifest = new Attributes();
+            final Pattern spaceColonSpace = Pattern.compile("\\s*:\\s*", Pattern.UNICODE_CHARACTER_CLASS);
+            final Matcher matcher = spaceColonSpace.matcher("");
             for (String line = r.readLine(); line != null; line = r.readLine()) {
                 if (line.startsWith("\t")) {
-                    final String[] keyValue = line.split("\\s*:\\s*", 2);
-                    if (keyValue.length >= 2)
-                        manifest.put(new Attributes.Name(keyValue[0].substring(1)), keyValue[1]);
+                    matcher.reset(line);
+                    if (matcher.find() && matcher.start() > 0 && matcher.end() < line.length()) {
+                        final String key = line.substring(1, matcher.start());
+                        final String value = line.substring(matcher.end());
+                        manifest.put(new Attributes.Name(key), value);
+                    }
                     continue;
                 }
Index: trunk/src/org/openstreetmap/josm/plugins/ReadLocalPluginInformationTask.java
===================================================================
--- trunk/src/org/openstreetmap/josm/plugins/ReadLocalPluginInformationTask.java	(revision 18795)
+++ trunk/src/org/openstreetmap/josm/plugins/ReadLocalPluginInformationTask.java	(revision 18796)
@@ -14,4 +14,6 @@
 import java.util.List;
 import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
 import org.openstreetmap.josm.data.Preferences;
@@ -83,5 +85,6 @@
 
     private static File[] listFiles(File pluginsDirectory, final String regex) {
-        return pluginsDirectory.listFiles((FilenameFilter) (dir, name) -> name.matches(regex));
+        final Matcher matcher = Pattern.compile(regex).matcher("");
+        return pluginsDirectory.listFiles((dir, name) -> matcher.reset(name).matches());
     }
 
Index: trunk/src/org/openstreetmap/josm/tools/XmlObjectParser.java
===================================================================
--- trunk/src/org/openstreetmap/josm/tools/XmlObjectParser.java	(revision 18795)
+++ trunk/src/org/openstreetmap/josm/tools/XmlObjectParser.java	(revision 18796)
@@ -10,5 +10,4 @@
 import java.lang.reflect.Method;
 import java.lang.reflect.Modifier;
-import java.util.Arrays;
 import java.util.HashMap;
 import java.util.Iterator;
@@ -190,4 +189,8 @@
         private final Map<String, Field> fields = new HashMap<>();
         private final Map<String, Method> methods = new HashMap<>();
+        /** This is used to avoid array copies in {@link #getUncachedMethod(String)}. Do not modify. */
+        private Method[] cachedKlassMethods;
+        /** This is used to avoid array copies in {@link #getUncachedField(String)}. Do not modify. */
+        private Field[] cachedKlassFields;
 
         Entry(Class<?> klass, boolean onStart, boolean both) {
@@ -198,15 +201,45 @@
 
         Field getField(String s) {
-            return fields.computeIfAbsent(s, ignore -> Arrays.stream(klass.getFields())
-                    .filter(f -> f.getName().equals(s))
-                    .findFirst()
-                    .orElse(null));
+            return fields.computeIfAbsent(s, this::getUncachedField);
+        }
+
+        /**
+         * Get a field (uncached in {@link #fields})
+         * @implNote Please profile startup when changing
+         * @param s The field to get
+         * @return The field, or {@code null}.
+         */
+        private Field getUncachedField(String s) {
+            if (this.cachedKlassFields == null) {
+                this.cachedKlassFields = klass.getFields();
+            }
+            for (Field field : this.cachedKlassFields) {
+                if (field.getName().equals(s)) {
+                    return field;
+                }
+            }
+            return null;
         }
 
         Method getMethod(String s) {
-            return methods.computeIfAbsent(s, ignore -> Arrays.stream(klass.getMethods())
-                    .filter(m -> m.getName().equals(s) && m.getParameterTypes().length == 1)
-                    .findFirst()
-                    .orElse(null));
+            return methods.computeIfAbsent(s, this::getUncachedMethod);
+        }
+
+        /**
+         * Get an uncached method (in {@link #methods})
+         * @implNote Please profile startup when changing
+         * @param s The method to find
+         * @return The method or {@code null}.
+         */
+        private Method getUncachedMethod(String s) {
+            if (cachedKlassMethods == null) {
+                cachedKlassMethods = klass.getMethods();
+            }
+            for (Method method : cachedKlassMethods) {
+                if (method.getParameterCount() == 1 && method.getName().equals(s)) {
+                    return method;
+                }
+            }
+            return null;
         }
     }
