result = find(ni);
+ return result != null && result.hasRootValue();
+ }
+
+ public KeyMap map(P param, BiFunction conversion) {
+ return map(param, conversion, new IdentityHashMap<>());
+ }
+
+ public KeyMap map(Function conversion) {
+ return map(conversion, Functions.functionBiFunction());
+ }
+
+ KeyMap map(P param, BiFunction conversion, IdentityHashMap, KeyMap> cached) {
+ if (cached.containsKey(this)) {
+ return cached.get(this);
+ }
+ KeyMap newMap = new KeyMap<>(size());
+ cached.put(this, newMap);
+ Set>> entries = entrySet();
+ for (Entry> entry : entries) {
+ newMap.put(entry.getKey(), entry.getValue().map(param, conversion, cached));
+ }
+ KeyMap any = getAny();
+ if (any != null) {
+ newMap.putAny(any.map(param, conversion, cached));
+ }
+ if (hasRootValue()) {
+ newMap.putRootValue(conversion.apply(param, getRootValue()));
+ }
+ return newMap;
+ }
+}
diff --git a/mapper/src/main/java/io/smallrye/config/mapper/MappingContext.java b/mapper/src/main/java/io/smallrye/config/mapper/MappingContext.java
new file mode 100644
index 000000000..b72d1eb35
--- /dev/null
+++ b/mapper/src/main/java/io/smallrye/config/mapper/MappingContext.java
@@ -0,0 +1,195 @@
+package io.smallrye.config.mapper;
+
+import static io.smallrye.config.mapper.ConfigurationInterface.LeafProperty;
+import static io.smallrye.config.mapper.ConfigurationInterface.MapProperty;
+import static io.smallrye.config.mapper.ConfigurationInterface.PrimitiveProperty;
+import static io.smallrye.config.mapper.ConfigurationInterface.Property;
+import static io.smallrye.config.mapper.ConfigurationInterface.getConfigurationInterface;
+import static io.smallrye.config.mapper.ConfigurationValidationException.Problem;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.UndeclaredThrowableException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.IdentityHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.NoSuchElementException;
+
+import org.eclipse.microprofile.config.spi.Converter;
+
+import io.smallrye.config.ConfigValue;
+import io.smallrye.config.SmallRyeConfig;
+
+/**
+ * A mapping context. This is used by generated classes during configuration mapping, and is released once the configuration
+ * mapping has completed.
+ */
+public final class MappingContext {
+
+ private final Map, Map>> enclosedThings = new IdentityHashMap<>();
+ private final Map, Map> roots = new IdentityHashMap<>();
+ private final Map, Map>> convertersByTypeAndField = new IdentityHashMap<>();
+ private final List