+ }
+
+ private static final class MultiKey extends IdentifiableItemCodec {
+ private final ImmutableOffsetMapTemplate<QName> predicateTemplate;
+ private final ImmutableOffsetMap<QName, ValueContext> keyValueContexts;
+ private final ImmutableList<QName> keysInBindingOrder;
+ private final MethodHandle ctor;
+
+ MultiKey(final ListEffectiveStatement schema, final Class<? extends Identifier<?>> keyClass,
+ final Class<?> identifiable, final Map<QName, ValueContext> keyValueContexts) {
+ super(schema, keyClass, identifiable);
+
+ final MethodHandle tmpCtor = getConstructor(keyClass, keyValueContexts.size());
+ final MethodHandle inv = MethodHandles.spreadInvoker(tmpCtor.type(), 0);
+ ctor = inv.asType(inv.type().changeReturnType(Identifier.class)).bindTo(tmpCtor);
+
+ /*
+ * We need to re-index to make sure we instantiate nodes in the order in which they are defined. We will
+ * also need to instantiate values in the same order.
+ */
+ final Set<QName> keyDef = schema.findFirstEffectiveSubstatementArgument(KeyEffectiveStatement.class)
+ .orElseThrow();
+ predicateTemplate = ImmutableOffsetMapTemplate.ordered(keyDef);
+ this.keyValueContexts = predicateTemplate.instantiateTransformed(keyValueContexts, (key, value) -> value);