Index: trunk/src/org/openstreetmap/josm/data/projection/Projections.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/projection/Projections.java	(revision 12785)
+++ trunk/src/org/openstreetmap/josm/data/projection/Projections.java	(revision 12786)
@@ -14,4 +14,5 @@
 import java.util.Map;
 import java.util.Set;
+import java.util.function.Supplier;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
@@ -42,6 +43,4 @@
 import org.openstreetmap.josm.data.projection.proj.SwissObliqueMercator;
 import org.openstreetmap.josm.data.projection.proj.TransverseMercator;
-import org.openstreetmap.josm.gui.preferences.projection.ProjectionChoice;
-import org.openstreetmap.josm.gui.preferences.projection.ProjectionPreference;
 import org.openstreetmap.josm.io.CachedFile;
 import org.openstreetmap.josm.tools.JosmRuntimeException;
@@ -78,5 +77,5 @@
 
     private static final Set<String> allCodes = new HashSet<>();
-    private static final Map<String, ProjectionChoice> allProjectionChoicesByCode = new HashMap<>();
+    private static final Map<String, Supplier<Projection>> projectionSuppliersByCode = new HashMap<>();
     private static final Map<String, Projection> projectionsByCode_cache = new HashMap<>();
 
@@ -157,12 +156,5 @@
             throw new JosmRuntimeException(ex);
         }
-
-        for (ProjectionChoice pc : ProjectionPreference.getProjectionChoices()) {
-            for (String code : pc.allCodes()) {
-                allProjectionChoicesByCode.put(code, pc);
-            }
-        }
         allCodes.addAll(inits.keySet());
-        allCodes.addAll(allProjectionChoicesByCode.keySet());
     }
 
@@ -242,4 +234,15 @@
     public static void registerBaseProjection(String id, Class<? extends Proj> projClass, String origin) {
         registerBaseProjection(id, new ClassProjFactory(projClass), origin);
+    }
+
+    /**
+     * Register a projection supplier, that is, a factory class for projections.
+     * @param code the code of the projection that will be returned
+     * @param supplier a supplier to return a projection with given code
+     * @since 12786
+     */
+    public static void registerProjectionSupplier(String code, Supplier<Projection> supplier) {
+        projectionSuppliersByCode.put(code, supplier);
+        allCodes.add(code);
     }
 
@@ -351,20 +354,18 @@
         Projection proj = projectionsByCode_cache.get(code);
         if (proj != null) return proj;
-        ProjectionChoice pc = allProjectionChoicesByCode.get(code);
-        if (pc != null) {
-            Collection<String> pref = pc.getPreferencesFromCode(code);
-            pc.setPreferences(pref);
-            try {
-                proj = pc.getProjection();
-            } catch (JosmRuntimeException | IllegalArgumentException | IllegalStateException e) {
-                Logging.log(Logging.LEVEL_WARN, "Unable to get projection "+code+" with "+pc+':', e);
+
+        ProjectionDefinition pd = inits.get(code);
+        if (pd != null) {
+            proj = new CustomProjection(pd.name, code, pd.definition);
+        }
+        if (proj == null) {
+            Supplier<Projection> ps = projectionSuppliersByCode.get(code);
+            if (ps != null) {
+                proj = ps.get();
             }
         }
-        if (proj == null) {
-            ProjectionDefinition pd = inits.get(code);
-            if (pd == null) return null;
-            proj = new CustomProjection(pd.name, code, pd.definition);
-        }
-        projectionsByCode_cache.put(code, proj);
+        if (proj != null) {
+            projectionsByCode_cache.put(code, proj);
+        }
         return proj;
     }
Index: trunk/src/org/openstreetmap/josm/gui/preferences/projection/ProjectionPreference.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/preferences/projection/ProjectionPreference.java	(revision 12785)
+++ trunk/src/org/openstreetmap/josm/gui/preferences/projection/ProjectionPreference.java	(revision 12786)
@@ -32,4 +32,5 @@
 import org.openstreetmap.josm.data.projection.CustomProjection;
 import org.openstreetmap.josm.data.projection.Projection;
+import org.openstreetmap.josm.data.projection.Projections;
 import org.openstreetmap.josm.gui.ExtendedDialog;
 import org.openstreetmap.josm.gui.preferences.PreferenceSetting;
@@ -42,4 +43,5 @@
 import org.openstreetmap.josm.tools.GBC;
 import org.openstreetmap.josm.tools.JosmRuntimeException;
+import org.openstreetmap.josm.tools.Logging;
 
 /**
@@ -255,4 +257,16 @@
         projectionChoices.add(c);
         projectionChoicesById.put(c.getId(), c);
+        for (String code : c.allCodes()) {
+            Projections.registerProjectionSupplier(code, () -> {
+                Collection<String> pref = c.getPreferencesFromCode(code);
+                c.setPreferences(pref);
+                try {
+                    return c.getProjection();
+                } catch (JosmRuntimeException | IllegalArgumentException | IllegalStateException e) {
+                    Logging.log(Logging.LEVEL_WARN, "Unable to get projection "+code+" with "+c+':', e);
+                    return null;
+                }
+            });
+        }
     }
 
