You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@isis.apache.org by ah...@apache.org on 2020/05/08 09:56:43 UTC

[isis] branch 2340-new_common_UI created (now 2d4e645)

This is an automated email from the ASF dual-hosted git repository.

ahuber pushed a change to branch 2340-new_common_UI
in repository https://gitbox.apache.org/repos/asf/isis.git.


      at 2d4e645  ISIS-2340: not meant for merge (exploring simplification options)

This branch includes the following new commits:

     new 2d4e645  ISIS-2340: not meant for merge (exploring simplification options)

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.



[isis] 01/01: ISIS-2340: not meant for merge (exploring simplification options)

Posted by ah...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

ahuber pushed a commit to branch 2340-new_common_UI
in repository https://gitbox.apache.org/repos/asf/isis.git

commit 2d4e645f64c7e9fa722fbf2d2fc3f97559a4f702
Author: Andi Huber <ah...@apache.org>
AuthorDate: Fri May 8 11:56:17 2020 +0200

    ISIS-2340: not meant for merge (exploring simplification options)
---
 .../applib/events/domain/AbstractDomainEvent.java  |   1 -
 .../core/metamodel/facets/DomainEventHelper.java   |  65 +++++--
 .../invocation/ActionDomainEventFacetAbstract.java |  41 ++---
 .../action/invocation/ActionInvocationFacet.java   |   8 +-
 ...ctionInvocationFacetForDomainEventAbstract.java |  76 ++++----
 ...ectionAddToFacetForDomainEventFromAbstract.java |  15 +-
 .../modify/CollectionDomainEventFacetAbstract.java |   6 +-
 ...nRemoveFromFacetForDomainEventFromAbstract.java |  10 +-
 .../members/disabled/DisabledFacetAbstract.java    |   7 -
 .../method/DisableForContextFacetViaMethod.java    |   3 +-
 .../method/HideForContextFacetViaMethod.java       |   4 +-
 .../core/metamodel/interactions/AccessContext.java |   7 +-
 .../interactions/ActionArgUsabilityContext.java    |  22 +--
 .../interactions/ActionArgValidityContext.java     |  27 ++-
 .../interactions/ActionArgVisibilityContext.java   |  24 +--
 .../interactions/ActionInteractionContext.java     |   3 +-
 .../interactions/ActionUsabilityContext.java       |  29 ++--
 .../interactions/ActionValidityContext.java        |  26 +--
 .../interactions/ActionVisibilityContext.java      |  29 ++--
 .../interactions/CollectionAccessContext.java      |   7 +-
 .../interactions/CollectionAddToContext.java       |   6 +-
 .../interactions/CollectionRemoveFromContext.java  |   6 +-
 .../interactions/CollectionUsabilityContext.java   |   7 +-
 .../interactions/CollectionVisibilityContext.java  |   8 +-
 .../metamodel/interactions/InteractionContext.java |  89 +++-------
 .../metamodel/interactions/InteractionHead.java    |  21 +++
 .../interactions/MemberInteractionHead.java        |  81 +++++++++
 .../metamodel/interactions/ObjectTitleContext.java |   7 +-
 .../interactions/PropertyAccessContext.java        |   6 +-
 .../interactions/PropertyModifyContext.java        |   6 +-
 .../interactions/PropertyUsabilityContext.java     |   7 +-
 .../interactions/PropertyVisibilityContext.java    |   7 +-
 .../metamodel/interactions/UsabilityContext.java   |   7 +-
 .../metamodel/interactions/ValidityContext.java    |   7 +-
 .../metamodel/interactions/VisibilityContext.java  |   7 +-
 .../ixn/InteractionDtoServiceInternal.java         |  14 +-
 .../isis/core/metamodel/spec/ManagedObject.java    |  21 ---
 .../core/metamodel/spec/feature/ObjectAction.java  |  68 ++------
 .../spec/feature/ObjectActionParameter.java        |  23 +--
 .../core/metamodel/spec/feature/ObjectMember.java  |  10 +-
 .../metamodel/spec/interaction/ManagedAction.java  |   7 +-
 ...erModelHead.java => ActionInteractionHead.java} |  50 ++++--
 .../metamodel/specloader/specimpl/Factories.java   |  17 --
 .../specloader/specimpl/ObjectActionDefault.java   | 154 ++++++-----------
 .../specloader/specimpl/ObjectActionMixedIn.java   |  45 +++--
 .../specimpl/ObjectActionParameterAbstract.java    |  65 ++-----
 .../ObjectActionParameterMixedInAbstract.java      |  60 -------
 .../specloader/specimpl/ObjectMemberAbstract.java  |  34 ++--
 .../specimpl/OneToManyAssociationContributee.java  | 191 ---------------------
 .../specimpl/OneToManyAssociationMixedIn.java      |  23 ++-
 .../specimpl/OneToOneActionParameterMixedIn.java   |  35 ----
 .../specimpl/OneToOneAssociationContributee.java   | 174 -------------------
 .../specimpl/OneToOneAssociationDefault.java       |   7 +-
 .../specimpl/OneToOneAssociationMixedIn.java       |  19 +-
 .../specloader/specimpl/PendingParameterModel.java |  15 +-
 .../command/CommandExecutorServiceDefault.java     |  14 +-
 .../handlers/DomainObjectInvocationHandler.java    |   7 +-
 .../viewer/vaadin/ui/pages/main/MainView.java      |   7 +-
 .../runtime/system/ObjectMemberAbstractTest.java   |  10 +-
 .../model/action/form/FormPendingParamUiModel.java |   7 +-
 .../common/model/action/form/FormUiModel.java      |   8 +-
 .../common/model/feature/ParameterUiModel.java     |   4 +-
 .../viewer/wicket/model/models/ActionModel.java    |  62 +++----
 63 files changed, 642 insertions(+), 1191 deletions(-)

diff --git a/api/applib/src/main/java/org/apache/isis/applib/events/domain/AbstractDomainEvent.java b/api/applib/src/main/java/org/apache/isis/applib/events/domain/AbstractDomainEvent.java
index 4ca383c..3ace7b4 100644
--- a/api/applib/src/main/java/org/apache/isis/applib/events/domain/AbstractDomainEvent.java
+++ b/api/applib/src/main/java/org/apache/isis/applib/events/domain/AbstractDomainEvent.java
@@ -22,7 +22,6 @@ import java.util.HashMap;
 import java.util.Map;
 
 import org.apache.isis.applib.Identifier;
-import org.apache.isis.applib.annotation.Programmatic;
 import org.apache.isis.applib.events.EventObjectBase;
 import org.apache.isis.applib.services.command.CommandContext;
 import org.apache.isis.applib.services.i18n.TranslatableString;
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/DomainEventHelper.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/DomainEventHelper.java
index 9fe41ef..187f1f0 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/DomainEventHelper.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/DomainEventHelper.java
@@ -24,6 +24,7 @@ import java.lang.reflect.InvocationTargetException;
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.List;
+import java.util.Objects;
 
 import org.apache.isis.applib.FatalException;
 import org.apache.isis.applib.Identifier;
@@ -38,11 +39,13 @@ import org.apache.isis.core.commons.internal.collections._Lists;
 import org.apache.isis.core.commons.internal.exceptions._Exceptions;
 import org.apache.isis.core.commons.internal.reflection._Reflect;
 import org.apache.isis.core.metamodel.facetapi.IdentifiedHolder;
+import org.apache.isis.core.metamodel.interactions.InteractionHead;
 import org.apache.isis.core.metamodel.services.events.MetamodelEventService;
 import org.apache.isis.core.metamodel.spec.ManagedObject;
 import org.apache.isis.core.metamodel.spec.ObjectSpecification;
 import org.apache.isis.core.metamodel.spec.feature.ObjectAction;
 import org.apache.isis.core.metamodel.spec.feature.ObjectActionParameter;
+import org.apache.isis.core.metamodel.specloader.specimpl.PendingParameterModel;
 
 import static org.apache.isis.core.commons.internal.base._Casts.uncheckedCast;
 import static org.apache.isis.core.commons.internal.reflection._Reflect.Filter.paramAssignableFrom;
@@ -64,19 +67,50 @@ public class DomainEventHelper {
 
     private final MetamodelEventService metamodelEventService;
 
+    // -- USING PENDING PARAMETER MODEL
+    
+    public ActionDomainEvent<?> postEventForActionExecution(
+            @NonNull final Class<? extends ActionDomainEvent<?>> eventType,
+            @NonNull final PendingParameterModel pendingArgs, 
+            final ManagedObject resultAdapter) {
+
+        return postEventForAction(
+                AbstractDomainEvent.Phase.EXECUTED,
+                eventType,
+                pendingArgs.getAction(),
+                pendingArgs,
+                resultAdapter
+                );
+    }
+    
+    public ActionDomainEvent<?> postEventForActionExecution(
+            @NonNull final ActionDomainEvent<?> existingEvent,
+            @NonNull final PendingParameterModel pendingArgs,
+            final ManagedObject resultAdapter) {
+
+        return postEventForActionExecution(
+                (Class<? extends ActionDomainEvent<?>>)existingEvent.getClass(), 
+                pendingArgs,
+                resultAdapter);
+    }
+    
+    // ---
+    
     // -- postEventForAction
     
     // variant using eventType and no existing event
     public ActionDomainEvent<?> postEventForAction(
             final AbstractDomainEvent.Phase phase,
-            @NonNull final Class<? extends ActionDomainEvent<?>> eventType,
-            final ObjectAction objectAction,
+            final Class<? extends ActionDomainEvent<?>> eventType,
             final IdentifiedHolder identified,
-            final ManagedObject targetAdapter,
-            final ManagedObject mixedInAdapter,
-            final Can<ManagedObject> argumentAdapters,
+            final PendingParameterModel pendingArgs,
             final ManagedObject resultAdapter) {
         
+        final ObjectAction objectAction = pendingArgs.getAction();
+        final ManagedObject targetAdapter = pendingArgs.getActionTarget();
+        final ManagedObject mixedInAdapter = pendingArgs.getActionOwner();
+        final Can<ManagedObject> argumentAdapters = pendingArgs.getParamValues();
+        
         return postEventForAction(phase, uncheckedCast(eventType), /*existingEvent*/null, objectAction, identified, 
                 targetAdapter, mixedInAdapter, argumentAdapters, resultAdapter);
     }
@@ -85,12 +119,14 @@ public class DomainEventHelper {
     public ActionDomainEvent<?> postEventForAction(
             final AbstractDomainEvent.Phase phase,
             @NonNull final ActionDomainEvent<?> existingEvent,
-            final ObjectAction objectAction,
             final IdentifiedHolder identified,
-            final ManagedObject targetAdapter,
-            final ManagedObject mixedInAdapter,
-            final Can<ManagedObject> argumentAdapters,
+            final PendingParameterModel pendingArgs,
             final ManagedObject resultAdapter) {
+
+        final ObjectAction objectAction = pendingArgs.getAction();
+        final ManagedObject targetAdapter = pendingArgs.getActionTarget();
+        final ManagedObject mixedInAdapter = pendingArgs.getActionOwner();
+        final Can<ManagedObject> argumentAdapters = pendingArgs.getParamValues(); 
         
         return postEventForAction(phase, 
                 uncheckedCast(existingEvent.getClass()), existingEvent, objectAction, identified, 
@@ -304,8 +340,7 @@ public class DomainEventHelper {
             final Class<? extends CollectionDomainEvent<S, T>> eventType,
                     final CollectionDomainEvent<S, T> existingEvent,
                     final IdentifiedHolder identified,
-                    final ManagedObject targetAdapter,
-                    final ManagedObject mixedInAdapter,
+                    final InteractionHead head,
                     final CollectionDomainEvent.Of of,
                     final T reference) {
         
@@ -318,13 +353,13 @@ public class DomainEventHelper {
                 event = existingEvent;
             } else {
                 // all other phases, create a new event
-                final S source = uncheckedCast(ManagedObject.unwrapSingle(targetAdapter));
+                final S source = uncheckedCast(ManagedObject.unwrapSingle(head.getTarget()));
                 final Identifier identifier = identified.getIdentifier();
                 event = newCollectionDomainEvent(eventType, phase, identifier, source, of, reference);
 
                 // copy over if have
-                if(mixedInAdapter != null ) {
-                    event.setMixedIn(mixedInAdapter.getPojo());
+                if(!Objects.equals(head.getTarget(), head.getOwner())) {
+                    event.setMixedIn(head.getOwner().getPojo());
                 }
             }
 
@@ -413,6 +448,8 @@ public class DomainEventHelper {
                     "failed to invoke constructor %s", constructor, e);
         }
     }
+
+
     
 
 }
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/actions/action/invocation/ActionDomainEventFacetAbstract.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/actions/action/invocation/ActionDomainEventFacetAbstract.java
index 38cd4e5..44c76fa 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/actions/action/invocation/ActionDomainEventFacetAbstract.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/actions/action/invocation/ActionDomainEventFacetAbstract.java
@@ -76,13 +76,15 @@ implements ActionDomainEventFacet {
     
     @Override
     public String hides(final VisibilityContext<? extends VisibilityEvent> ic) {
+        
+        val aic = actionInteractionContextFrom(ic);
 
         final ActionDomainEvent<?> event =
                 domainEventHelper.postEventForAction(
                         AbstractDomainEvent.Phase.HIDE,
                         getEventType(),
-                        actionFrom(ic), getIdentified(),
-                        ic.getTarget(), ic.getMixedIn(), argumentAdaptersFrom(ic),
+                        getIdentified(), 
+                        aic.getPendingParamModel(),
                         null);
         if (event != null && event.isHidden()) {
             return "Hidden by subscriber";
@@ -92,13 +94,15 @@ implements ActionDomainEventFacet {
 
     @Override
     public String disables(UsabilityContext<? extends UsabilityEvent> ic) {
+        
+        val aic = actionInteractionContextFrom(ic);
 
         final ActionDomainEvent<?> event =
                 domainEventHelper.postEventForAction(
                         AbstractDomainEvent.Phase.DISABLE,
                         getEventType(),
-                        actionFrom(ic), getIdentified(),
-                        ic.getTarget(), ic.getMixedIn(), argumentAdaptersFrom(ic),
+                        getIdentified(),
+                        aic.getPendingParamModel(),
                         null);
         if (event != null && event.isDisabled()) {
             final TranslatableString reasonTranslatable = event.getDisabledReasonTranslatable();
@@ -114,16 +118,14 @@ implements ActionDomainEventFacet {
     @Override
     public String invalidates(final ValidityContext<? extends ValidityEvent> ic) {
 
-        _Assert.assertTrue(ic instanceof ActionValidityContext, ()->
-            String.format("expecting an action context but got %s", ic.getIdentifier()));
+        val aic = actionInteractionContextFrom(ic);
         
-        final ActionValidityContext aic = (ActionValidityContext) ic;
         final ActionDomainEvent<?> event =
                 domainEventHelper.postEventForAction(
                         AbstractDomainEvent.Phase.VALIDATE,
                         getEventType(),
-                        actionFrom(ic), getIdentified(),
-                        ic.getTarget(), ic.getMixedIn(), aic.getArgs(),
+                        getIdentified(),
+                        aic.getPendingParamModel(),
                         null);
         if (event != null && event.isInvalid()) {
             final TranslatableString reasonTranslatable = event.getInvalidityReasonTranslatable();
@@ -138,30 +140,13 @@ implements ActionDomainEventFacet {
     
     // -- HELPER
     
-    private static ObjectAction actionFrom(final InteractionContext<?> ic) {
+    private static ActionInteractionContext actionInteractionContextFrom(final InteractionContext<?> ic) {
         if(!(ic instanceof ActionInteractionContext)) {
             throw new IllegalStateException(
                     "Expecting ic to be of type ActionInteractionContext, instead was: " + ic);
         }
-        return ((ActionInteractionContext) ic).getObjectAction();
+        return (ActionInteractionContext) ic;
     }
 
-    private static Can<ManagedObject> argumentAdaptersFrom(
-            final InteractionContext<? extends InteractionEvent> ic) {
-        
-        val contributee = ic.getContributeeWithParamIndex();
-
-        if(contributee!=null) {
-
-            val adapter = contributee.getIndex() == 0
-                    ? contributee.getValue()
-                    : ManagedObject.unspecified();
-            
-            return Can.ofSingleton(adapter);
-                
-        }
-
-        return Can.empty();
-    }
 
 }
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/actions/action/invocation/ActionInvocationFacet.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/actions/action/invocation/ActionInvocationFacet.java
index 8458c8e3..6b1c4a5 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/actions/action/invocation/ActionInvocationFacet.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/actions/action/invocation/ActionInvocationFacet.java
@@ -19,12 +19,11 @@
 
 package org.apache.isis.core.metamodel.facets.actions.action.invocation;
 
-import org.apache.isis.core.commons.collections.Can;
 import org.apache.isis.core.metamodel.consent.InteractionInitiatedBy;
 import org.apache.isis.core.metamodel.facetapi.Facet;
 import org.apache.isis.core.metamodel.spec.ManagedObject;
 import org.apache.isis.core.metamodel.spec.ObjectSpecification;
-import org.apache.isis.core.metamodel.spec.feature.ObjectAction;
+import org.apache.isis.core.metamodel.specloader.specimpl.PendingParameterModel;
 
 /**
  * Represents the mechanism by which the action should be invoked.
@@ -37,10 +36,7 @@ import org.apache.isis.core.metamodel.spec.feature.ObjectAction;
 public interface ActionInvocationFacet extends Facet {
 
     ManagedObject invoke(
-            ObjectAction owningAction,
-            ManagedObject targetAdapter,
-            ManagedObject mixedInAdapter,  // null for regular or contributed (not mixin) actions
-            Can<ManagedObject> argumentAdapters,
+            PendingParameterModel pendingArgs,
             InteractionInitiatedBy interactionInitiatedBy);
     
     ObjectSpecification getReturnType();
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/actions/action/invocation/ActionInvocationFacetForDomainEventAbstract.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/actions/action/invocation/ActionInvocationFacetForDomainEventAbstract.java
index 3b44d6d..5cdaaf1 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/actions/action/invocation/ActionInvocationFacetForDomainEventAbstract.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/actions/action/invocation/ActionInvocationFacetForDomainEventAbstract.java
@@ -29,7 +29,6 @@ import java.util.function.Consumer;
 
 import org.apache.isis.applib.NonRecoverableException;
 import org.apache.isis.applib.RecoverableException;
-import org.apache.isis.applib.events.domain.AbstractDomainEvent;
 import org.apache.isis.applib.events.domain.ActionDomainEvent;
 import org.apache.isis.applib.services.bookmark.Bookmark;
 import org.apache.isis.applib.services.bookmark.BookmarkService;
@@ -46,7 +45,6 @@ import org.apache.isis.applib.services.metamodel.MetaModelService.Mode;
 import org.apache.isis.applib.services.metrics.MetricsService;
 import org.apache.isis.applib.services.queryresultscache.QueryResultsCache;
 import org.apache.isis.applib.services.registry.ServiceRegistry;
-import org.apache.isis.core.commons.collections.Can;
 import org.apache.isis.core.commons.exceptions.IsisException;
 import org.apache.isis.core.commons.internal.base._Casts;
 import org.apache.isis.core.commons.internal.base._Strings;
@@ -66,6 +64,7 @@ import org.apache.isis.core.metamodel.services.publishing.PublisherDispatchServi
 import org.apache.isis.core.metamodel.spec.ManagedObject;
 import org.apache.isis.core.metamodel.spec.ObjectSpecification;
 import org.apache.isis.core.metamodel.spec.feature.ObjectAction;
+import org.apache.isis.core.metamodel.specloader.specimpl.PendingParameterModel;
 import org.apache.isis.schema.ixn.v2.ActionInvocationDto;
 
 import lombok.Getter;
@@ -115,16 +114,12 @@ implements ImperativeFacet {
 
     @Override
     public ManagedObject invoke(
-            final ObjectAction owningAction,
-            final ManagedObject targetAdapter,
-            final ManagedObject mixedInAdapter,
-            final Can<ManagedObject> argumentAdapters,
+            final PendingParameterModel pendingArgs,
             final InteractionInitiatedBy interactionInitiatedBy) {
 
         final ManagedObject executionResult = 
                 getTransactionService().executeWithinTransaction(()->
-                    doInvoke(owningAction, targetAdapter, mixedInAdapter, argumentAdapters, 
-                            interactionInitiatedBy));
+                    doInvoke(pendingArgs, interactionInitiatedBy));
 
         //PersistableTypeGuard.instate(executionResult);
 
@@ -148,21 +143,19 @@ implements ImperativeFacet {
     // -- HELPER
     
     private ManagedObject doInvoke(
-            final ObjectAction owningAction,
-            final ManagedObject targetAdapter,
-            final ManagedObject mixedInAdapter,
-            final Can<ManagedObject> argumentAdapters,
+            final PendingParameterModel pendingArgs,
             final InteractionInitiatedBy interactionInitiatedBy) {
         // similar code in PropertySetterOrClearFacetFDEA
 
-        final CommandContext commandContext = getCommandContext();
-        final Command command = commandContext.getCommand();
+        val commandContext = getCommandContext();
+        val command = commandContext.getCommand();
 
+        val interactionContext = getInteractionContext();
+        val interaction = interactionContext.getInteraction();
+        
+        val owningAction = pendingArgs.getAction();
 
-        final InteractionContext interactionContext = getInteractionContext();
-        final Interaction interaction = interactionContext.getInteraction();
-
-        final String actionId = owningAction.getIdentifier().toClassAndNameIdentityString();
+        val actionId = owningAction.getIdentifier().toClassAndNameIdentityString();
 
         final ManagedObject returnedAdapter;
         if( command.getExecutor() == Command.Executor.USER &&
@@ -171,7 +164,7 @@ implements ImperativeFacet {
             // deal with background commands
 
             // persist command so can it can subsequently be invoked in the 'background'
-            final CommandService commandService = getCommandService();
+            val commandService = getCommandService();
             if (!commandService.persistIfPossible(command)) {
                 throw new IsisException(String.format(
                         "Unable to persist command for action '%s'; CommandService does not support persistent commands ",
@@ -181,15 +174,15 @@ implements ImperativeFacet {
 
         } else {
             // otherwise, go ahead and execute action in the 'foreground'
-            final ManagedObject mixinElseRegularAdapter = mixedInAdapter != null ? mixedInAdapter : targetAdapter;
+            val mixinElseRegularAdapter = pendingArgs.getActionTarget();
 
-            final Object mixinElseRegularPojo = ManagedObject.unwrapSingle(mixinElseRegularAdapter);
+            val mixinElseRegularPojo = ManagedObject.unwrapSingle(mixinElseRegularAdapter);
 
-            final List<Object> argumentPojos = argumentAdapters.stream()
+            final List<Object> argumentPojos = pendingArgs.getParamValues().stream()
                     .map(ManagedObject::unwrapSingle)
                     .collect(_Lists.toUnmodifiable());
 
-            final String targetMember = targetNameFor(owningAction, mixedInAdapter);
+            final String targetMember = targetNameFor(owningAction, pendingArgs.getActionOwner());
             final String targetClass = CommandUtil.targetClassNameFor(mixinElseRegularAdapter);
 
             final Interaction.ActionInvocation execution =
@@ -197,9 +190,7 @@ implements ImperativeFacet {
                             interaction, actionId, mixinElseRegularPojo, argumentPojos, targetMember,
                             targetClass);
             final Interaction.MemberExecutor<Interaction.ActionInvocation> callable =
-                    new DomainEventMemberExecutor(
-                            argumentAdapters, targetAdapter, command, owningAction,
-                            mixinElseRegularAdapter, mixedInAdapter, execution);
+                    new DomainEventMemberExecutor(pendingArgs, command, execution);
 
             // sets up startedAt and completedAt on the execution, also manages the execution call graph
             interaction.execute(callable, execution, getClockService(), getMetricsService());
@@ -255,12 +246,11 @@ implements ImperativeFacet {
     }
 
     private Object invokeMethodElseFromCache(
-            final ManagedObject targetAdapter, 
-            final Can<ManagedObject> arguments)
+            final PendingParameterModel pendingArgs)
                     throws IllegalAccessException, InvocationTargetException {
 
-        final Object[] executionParameters = ManagedObject.unwrapMultipleAsArray(arguments);
-        final Object targetPojo = ManagedObject.unwrapSingle(targetAdapter);
+        final Object[] executionParameters = ManagedObject.unwrapMultipleAsArray(pendingArgs.getParamValues());
+        final Object targetPojo = ManagedObject.unwrapSingle(pendingArgs.getActionTarget());
 
         final ActionSemanticsFacet semanticsFacet = getFacetHolder().getFacet(ActionSemanticsFacet.class);
         final boolean cacheable = semanticsFacet != null && semanticsFacet.value().isSafeAndRequestCacheable();
@@ -415,12 +405,8 @@ implements ImperativeFacet {
     private final class DomainEventMemberExecutor 
     implements Interaction.MemberExecutor<Interaction.ActionInvocation> {
         
-        private final Can<ManagedObject> argumentAdapters;
-        private final ManagedObject targetAdapter;
+        private final PendingParameterModel pendingArgs;
         private final Command command;
-        private final ObjectAction owningAction;
-        private final ManagedObject mixinElseRegularAdapter;
-        private final ManagedObject mixedInAdapter;
         private final ActionInvocation execution;
 
         @Override
@@ -429,8 +415,7 @@ implements ImperativeFacet {
             try {
 
                 // update the current execution with the DTO (memento)
-                val invocationDto = getInteractionDtoServiceInternal()
-                .asActionInvocationDto(owningAction, mixinElseRegularAdapter, argumentAdapters.toList());
+                val invocationDto = getInteractionDtoServiceInternal().asActionInvocationDto(pendingArgs);
                 
                 currentExecution.setDto(invocationDto);
 
@@ -445,33 +430,30 @@ implements ImperativeFacet {
 
                 // ... post the executing event
                 //compiler: cannot use val here, because initializer expression does not have a representable type
-                final ActionDomainEvent<?> actionDomainEvent = domainEventHelper.postEventForAction(
-                        AbstractDomainEvent.Phase.EXECUTING,
+                final ActionDomainEvent<?> actionDomainEvent = domainEventHelper.postEventForActionExecution(
                         getEventType(),
-                        owningAction, owningAction,
-                        targetAdapter, mixedInAdapter, argumentAdapters,
+                        pendingArgs,
                         null);
 
                 // set event onto the execution
                 currentExecution.setEvent(actionDomainEvent);
 
                 // invoke method
-                val resultPojo = invokeMethodElseFromCache(targetAdapter, argumentAdapters);
+                val resultPojo = invokeMethodElseFromCache(pendingArgs);
                 ManagedObject resultAdapterPossiblyCloned = 
-                        cloneIfViewModelCloneable(resultPojo, mixinElseRegularAdapter);
+                        cloneIfViewModelCloneable(resultPojo, pendingArgs.getActionTarget());
 
                 // ... post the executed event
 
-                domainEventHelper.postEventForAction(
-                        AbstractDomainEvent.Phase.EXECUTED,
+                domainEventHelper.postEventForActionExecution(
                         actionDomainEvent,
-                        owningAction, owningAction, targetAdapter, mixedInAdapter, argumentAdapters,
+                        pendingArgs,
                         resultAdapterPossiblyCloned);
 
                 final Object returnValue = actionDomainEvent.getReturnValue();
                 if(returnValue != resultPojo) {
                     resultAdapterPossiblyCloned = 
-                            cloneIfViewModelCloneable(returnValue, mixinElseRegularAdapter);
+                            cloneIfViewModelCloneable(returnValue, pendingArgs.getActionTarget());
                 }
                 return ManagedObject.unwrapSingle(resultAdapterPossiblyCloned);
 
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/collection/modify/CollectionAddToFacetForDomainEventFromAbstract.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/collection/modify/CollectionAddToFacetForDomainEventFromAbstract.java
index 31e8d4b..93b810e 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/collection/modify/CollectionAddToFacetForDomainEventFromAbstract.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/collection/modify/CollectionAddToFacetForDomainEventFromAbstract.java
@@ -33,9 +33,12 @@ import org.apache.isis.core.metamodel.facets.SingleValueFacetAbstract;
 import org.apache.isis.core.metamodel.facets.collections.modify.CollectionAddToFacet;
 import org.apache.isis.core.metamodel.facets.propcoll.accessor.PropertyOrCollectionAccessorFacet;
 import org.apache.isis.core.metamodel.spec.ManagedObject;
+import org.apache.isis.core.metamodel.spec.feature.ObjectMember;
 
 import static org.apache.isis.core.commons.internal.base._Casts.uncheckedCast;
 
+import lombok.val;
+
 public abstract class CollectionAddToFacetForDomainEventFromAbstract
 extends SingleValueFacetAbstract<Class<? extends CollectionDomainEvent<?,?>>>
 implements CollectionAddToFacet {
@@ -66,7 +69,8 @@ implements CollectionAddToFacet {
     @Override
     public void add(
             final ManagedObject targetAdapter,
-            final ManagedObject referencedObjectAdapter, final InteractionInitiatedBy interactionInitiatedBy) {
+            final ManagedObject referencedObjectAdapter, 
+            final InteractionInitiatedBy interactionInitiatedBy) {
         if (this.collectionAddToFacet == null) {
             return;
         }
@@ -88,14 +92,17 @@ implements CollectionAddToFacet {
         // either doesn't contain object, or doesn't have set semantics, so
         // execute the add wrapped between the executing and executed events ...
         final ManagedObject mixedInAdapter = null;
-
+        
+        val member = (ObjectMember) getterFacet.getFacetHolder(); //TODO potential bug
+        val head = member.newInteractionHead(targetAdapter);
+        
         // ... post the executing event
 
         final CollectionDomainEvent<?, ?> event =
                 domainEventHelper.postEventForCollection(
                         AbstractDomainEvent.Phase.EXECUTING,
                         getEventType(), null,
-                        getIdentified(), targetAdapter, mixedInAdapter,
+                        getIdentified(), head,
                         CollectionDomainEvent.Of.ADD_TO,
                         referencedObject);
 
@@ -106,7 +113,7 @@ implements CollectionAddToFacet {
         domainEventHelper.postEventForCollection(
                 AbstractDomainEvent.Phase.EXECUTED,
                 getEventType(), uncheckedCast(event),
-                getIdentified(), targetAdapter, mixedInAdapter,
+                getIdentified(), head,
                 CollectionDomainEvent.Of.ADD_TO,
                 referencedObject);
     }
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/collection/modify/CollectionDomainEventFacetAbstract.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/collection/modify/CollectionDomainEventFacetAbstract.java
index b34d483..911e363 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/collection/modify/CollectionDomainEventFacetAbstract.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/collection/modify/CollectionDomainEventFacetAbstract.java
@@ -79,7 +79,7 @@ public abstract class CollectionDomainEventFacetAbstract extends SingleClassValu
                 domainEventHelper.postEventForCollection(
                         AbstractDomainEvent.Phase.HIDE,
                         getEventType(), null,
-                        getIdentified(), ic.getTarget(), ic.getMixedIn(),
+                        getIdentified(), ic.getHead(),
                         CollectionDomainEvent.Of.ACCESS,
                         null);
         if (event != null && event.isHidden()) {
@@ -95,7 +95,7 @@ public abstract class CollectionDomainEventFacetAbstract extends SingleClassValu
                 domainEventHelper.postEventForCollection(
                         AbstractDomainEvent.Phase.DISABLE,
                         getEventType(), null,
-                        getIdentified(), ic.getTarget(), ic.getMixedIn(),
+                        getIdentified(), ic.getHead(),
                         CollectionDomainEvent.Of.ACCESS,
                         null);
         if (event != null && event.isDisabled()) {
@@ -127,7 +127,7 @@ public abstract class CollectionDomainEventFacetAbstract extends SingleClassValu
                 domainEventHelper.postEventForCollection(
                         AbstractDomainEvent.Phase.VALIDATE,
                         getEventType(), null,
-                        getIdentified(), ic.getTarget(), ic.getMixedIn(),
+                        getIdentified(), ic.getHead(),
                         of,
                         proposed);
         if (event != null && event.isInvalid()) {
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/collection/modify/CollectionRemoveFromFacetForDomainEventFromAbstract.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/collection/modify/CollectionRemoveFromFacetForDomainEventFromAbstract.java
index edd1404..1b1c7e9 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/collection/modify/CollectionRemoveFromFacetForDomainEventFromAbstract.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/collection/modify/CollectionRemoveFromFacetForDomainEventFromAbstract.java
@@ -34,9 +34,12 @@ import org.apache.isis.core.metamodel.facets.SingleValueFacetAbstract;
 import org.apache.isis.core.metamodel.facets.collections.modify.CollectionRemoveFromFacet;
 import org.apache.isis.core.metamodel.facets.propcoll.accessor.PropertyOrCollectionAccessorFacet;
 import org.apache.isis.core.metamodel.spec.ManagedObject;
+import org.apache.isis.core.metamodel.spec.feature.ObjectMember;
 
 import static org.apache.isis.core.commons.internal.base._Casts.uncheckedCast;
 
+import lombok.val;
+
 
 public abstract class CollectionRemoveFromFacetForDomainEventFromAbstract
 extends SingleValueFacetAbstract<Class<? extends CollectionDomainEvent<?,?>>>
@@ -89,13 +92,16 @@ implements CollectionRemoveFromFacet {
         // contains the element, so
         // execute the remove wrapped between the executing and executed events ...
         final ManagedObject mixedInAdapter = null;
+        
+        val member = (ObjectMember) getterFacet.getFacetHolder(); //TODO potential bug
+        val head = member.newMemberInteractionHead(targetAdapter);
 
         // ... post the executing event
         final CollectionDomainEvent<?, ?> event =
                 domainEventHelper.postEventForCollection(
                         AbstractDomainEvent.Phase.EXECUTING,
                         getEventType(), null,
-                        getIdentified(), targetAdapter, mixedInAdapter,
+                        getIdentified(), head,
                         CollectionDomainEvent.Of.REMOVE_FROM,
                         referencedObject);
 
@@ -106,7 +112,7 @@ implements CollectionRemoveFromFacet {
         domainEventHelper.postEventForCollection(
                 AbstractDomainEvent.Phase.EXECUTED,
                 getEventType(), uncheckedCast(event),
-                getIdentified(), targetAdapter, mixedInAdapter,
+                getIdentified(), head,
                 CollectionDomainEvent.Of.REMOVE_FROM,
                 referencedObject);
     }
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/members/disabled/DisabledFacetAbstract.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/members/disabled/DisabledFacetAbstract.java
index 1524db7..fddf865 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/members/disabled/DisabledFacetAbstract.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/members/disabled/DisabledFacetAbstract.java
@@ -26,11 +26,8 @@ import org.apache.isis.applib.services.wrapper.events.UsabilityEvent;
 import org.apache.isis.core.metamodel.facetapi.Facet;
 import org.apache.isis.core.metamodel.facetapi.FacetHolder;
 import org.apache.isis.core.metamodel.facets.WhereValueFacetAbstract;
-import org.apache.isis.core.metamodel.interactions.ActionUsabilityContext;
 import org.apache.isis.core.metamodel.interactions.UsabilityContext;
 import org.apache.isis.core.metamodel.spec.ManagedObject;
-import org.apache.isis.core.metamodel.specloader.specimpl.OneToManyAssociationContributee;
-import org.apache.isis.core.metamodel.specloader.specimpl.OneToOneAssociationContributee;
 
 public abstract class DisabledFacetAbstract extends WhereValueFacetAbstract implements DisabledFacet {
 
@@ -71,10 +68,6 @@ public abstract class DisabledFacetAbstract extends WhereValueFacetAbstract impl
             return null;
         }
 
-        if(ic instanceof ActionUsabilityContext && (getFacetHolder() instanceof OneToOneAssociationContributee || getFacetHolder() instanceof OneToManyAssociationContributee)) {
-            // otherwise ends up vetoing the invocation of the contributing action
-            return null;
-        }
         final ManagedObject target = ic.getTarget();
         final String disabledReason = disabledReason(target);
         if (disabledReason != null) {
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/members/disabled/method/DisableForContextFacetViaMethod.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/members/disabled/method/DisableForContextFacetViaMethod.java
index 4752df3..5f6d6f2 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/members/disabled/method/DisableForContextFacetViaMethod.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/members/disabled/method/DisableForContextFacetViaMethod.java
@@ -74,8 +74,7 @@ implements ImperativeFacet {
         if (target == null) {
             return null;
         }
-        final Object returnValue = ManagedObject.InvokeUtil.invokeC(method, target, 
-                _NullSafe.streamNullable(ic.getContributeeWithParamIndex()));
+        final Object returnValue = ManagedObject.InvokeUtil.invoke(method, target);
         if(returnValue instanceof String) {
             return (String) returnValue;
         }
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/members/hidden/method/HideForContextFacetViaMethod.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/members/hidden/method/HideForContextFacetViaMethod.java
index 2e63c07..68e086c 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/members/hidden/method/HideForContextFacetViaMethod.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/members/hidden/method/HideForContextFacetViaMethod.java
@@ -25,7 +25,6 @@ import java.util.List;
 import java.util.Map;
 
 import org.apache.isis.applib.services.wrapper.events.VisibilityEvent;
-import org.apache.isis.core.commons.internal.base._NullSafe;
 import org.apache.isis.core.metamodel.facetapi.FacetHolder;
 import org.apache.isis.core.metamodel.facets.ImperativeFacet;
 import org.apache.isis.core.metamodel.interactions.VisibilityContext;
@@ -60,8 +59,7 @@ public class HideForContextFacetViaMethod extends HideForContextFacetAbstract im
         if (target == null) {
             return null;
         }
-        final Boolean isHidden = (Boolean) ManagedObject.InvokeUtil.invokeC(method, target, 
-                _NullSafe.streamNullable(ic.getContributeeWithParamIndex()));
+        final Boolean isHidden = (Boolean) ManagedObject.InvokeUtil.invoke(method, target);
         return isHidden.booleanValue() ? "Hidden" : null;
     }
 
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/AccessContext.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/AccessContext.java
index ec3cb1f..fdac6d8 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/AccessContext.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/AccessContext.java
@@ -19,11 +19,9 @@
 
 package org.apache.isis.core.metamodel.interactions;
 
-import org.apache.isis.applib.Identifier;
 import org.apache.isis.applib.services.wrapper.events.AccessEvent;
 import org.apache.isis.core.metamodel.consent.InteractionContextType;
 import org.apache.isis.core.metamodel.consent.InteractionInitiatedBy;
-import org.apache.isis.core.metamodel.spec.ManagedObject;
 
 /**
  * See {@link InteractionContext} for overview; analogous to {@link AccessEvent}
@@ -32,11 +30,10 @@ import org.apache.isis.core.metamodel.spec.ManagedObject;
 public abstract class AccessContext<T extends AccessEvent> extends InteractionContext<T> {
 
     public AccessContext(
+            final MemberInteractionHead head,
             final InteractionContextType interactionType,
-            final Identifier identifier,
-            final ManagedObject target,
             final InteractionInitiatedBy interactionInitiatedBy) {
-        super(interactionType, interactionInitiatedBy, identifier, target);
+        super(head, interactionType, interactionInitiatedBy);
     }
 
 }
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/ActionArgUsabilityContext.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/ActionArgUsabilityContext.java
index 3553512..e0b8837 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/ActionArgUsabilityContext.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/ActionArgUsabilityContext.java
@@ -19,7 +19,6 @@
 
 package org.apache.isis.core.metamodel.interactions;
 
-import org.apache.isis.applib.Identifier;
 import org.apache.isis.applib.annotation.Where;
 import org.apache.isis.applib.events.ActionArgumentUsabilityEvent;
 import org.apache.isis.applib.services.wrapper.events.ActionArgumentEvent;
@@ -28,6 +27,7 @@ import org.apache.isis.core.metamodel.consent.InteractionContextType;
 import org.apache.isis.core.metamodel.consent.InteractionInitiatedBy;
 import org.apache.isis.core.metamodel.spec.ManagedObject;
 import org.apache.isis.core.metamodel.spec.feature.ObjectAction;
+import org.apache.isis.core.metamodel.specloader.specimpl.PendingParameterModel;
 
 import lombok.Getter;
 
@@ -39,27 +39,21 @@ public class ActionArgUsabilityContext
 extends UsabilityContext<ActionArgumentUsabilityEvent> 
 implements ActionInteractionContext {
 
-    @Getter(onMethod = @__(@Override)) private final ObjectAction objectAction;
-    @Getter private final Can<ManagedObject> args;
+    @Getter(onMethod = @__(@Override)) private final PendingParameterModel pendingParamModel;
     @Getter private final int position;
 
     public ActionArgUsabilityContext(
-            final ManagedObject targetAdapter,
-            final ObjectAction objectAction,
-            final Identifier id,
-            final Can<ManagedObject> args,
+            final PendingParameterModel pendingArgs,
             final int position,
             final InteractionInitiatedBy interactionInitiatedBy) {
         
-        super(InteractionContextType.ACTION_PARAMETER_USABLE,
-                targetAdapter, 
-                id, 
+        super(
+                pendingArgs.getHead().toMemberInteractionHead(),
+                InteractionContextType.ACTION_PARAMETER_USABLE,
                 interactionInitiatedBy, 
                 Where.OBJECT_FORMS);
         
-        this.objectAction = objectAction;
-
-        this.args = args;
+        this.pendingParamModel = pendingArgs;
         this.position = position;
     }
 
@@ -68,7 +62,7 @@ implements ActionInteractionContext {
         return new ActionArgumentUsabilityEvent(
                 ManagedObject.unwrapSingle(getTarget()), 
                 getIdentifier(), 
-                ManagedObject.unwrapMultipleAsArray(getArgs().toList()), 
+                ManagedObject.unwrapMultipleAsArray(getPendingParamModel().getParamValues().toList()), 
                 getPosition());
     }
 
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/ActionArgValidityContext.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/ActionArgValidityContext.java
index d819227..a2a8d5c 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/ActionArgValidityContext.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/ActionArgValidityContext.java
@@ -19,13 +19,11 @@
 
 package org.apache.isis.core.metamodel.interactions;
 
-import org.apache.isis.applib.Identifier;
 import org.apache.isis.applib.services.wrapper.events.ActionArgumentEvent;
-import org.apache.isis.core.commons.collections.Can;
 import org.apache.isis.core.metamodel.consent.InteractionContextType;
 import org.apache.isis.core.metamodel.consent.InteractionInitiatedBy;
 import org.apache.isis.core.metamodel.spec.ManagedObject;
-import org.apache.isis.core.metamodel.spec.feature.ObjectAction;
+import org.apache.isis.core.metamodel.specloader.specimpl.PendingParameterModel;
 
 import static org.apache.isis.core.metamodel.spec.ManagedObject.unwrapSingle;
 
@@ -39,28 +37,23 @@ public class ActionArgValidityContext
 extends ValidityContext<ActionArgumentEvent> 
 implements ProposedHolder, ActionInteractionContext {
 
-    @Getter(onMethod = @__(@Override)) private final ObjectAction objectAction;
+    @Getter(onMethod = @__(@Override)) private final PendingParameterModel pendingParamModel;
     @Getter(onMethod = @__(@Override)) private final ManagedObject proposed; 
-    @Getter private final Can<ManagedObject> args;
     @Getter private final int position;
 
     public ActionArgValidityContext(
-            final ManagedObject targetAdapter,
-            final ObjectAction objectAction,
-            final Identifier id,
-            final Can<ManagedObject> args,
+            final PendingParameterModel pendingArgs,
             final int position,
             final InteractionInitiatedBy interactionInitiatedBy) {
         
-        super(InteractionContextType.ACTION_PROPOSED_ARGUMENT, 
-                targetAdapter, 
-                id, 
+        super(
+                pendingArgs.getHead().toMemberInteractionHead(),
+                InteractionContextType.ACTION_PROPOSED_ARGUMENT,
                 interactionInitiatedBy);
-        this.objectAction = objectAction;
-
-        this.args = args;
+        
+        this.pendingParamModel = pendingArgs;
         this.position = position;
-        this.proposed = args.getElseFail(position);
+        this.proposed = pendingArgs.getParamValues().getElseFail(position);
     }
 
     @Override
@@ -68,7 +61,7 @@ implements ProposedHolder, ActionInteractionContext {
         return new ActionArgumentEvent(
                 unwrapSingle(getTarget()), 
                 getIdentifier(), 
-                ManagedObject.unwrapMultipleAsArray(getArgs().toList()), 
+                ManagedObject.unwrapMultipleAsArray(getPendingParamModel().getParamValues().toList()), 
                 getPosition());
     }
 
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/ActionArgVisibilityContext.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/ActionArgVisibilityContext.java
index 8cc07f5..c1828c0 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/ActionArgVisibilityContext.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/ActionArgVisibilityContext.java
@@ -19,15 +19,13 @@
 
 package org.apache.isis.core.metamodel.interactions;
 
-import org.apache.isis.applib.Identifier;
 import org.apache.isis.applib.annotation.Where;
 import org.apache.isis.applib.events.ActionArgumentVisibilityEvent;
 import org.apache.isis.applib.services.wrapper.events.ActionArgumentEvent;
-import org.apache.isis.core.commons.collections.Can;
 import org.apache.isis.core.metamodel.consent.InteractionContextType;
 import org.apache.isis.core.metamodel.consent.InteractionInitiatedBy;
 import org.apache.isis.core.metamodel.spec.ManagedObject;
-import org.apache.isis.core.metamodel.spec.feature.ObjectAction;
+import org.apache.isis.core.metamodel.specloader.specimpl.PendingParameterModel;
 
 import lombok.Getter;
 
@@ -39,27 +37,21 @@ public class ActionArgVisibilityContext
 extends VisibilityContext<ActionArgumentVisibilityEvent> 
 implements ActionInteractionContext {
 
-    @Getter(onMethod = @__(@Override)) private final ObjectAction objectAction;
-    @Getter private final Can<ManagedObject> args;
+    @Getter(onMethod = @__(@Override)) private final PendingParameterModel pendingParamModel;
     @Getter private final int position;
     
     public ActionArgVisibilityContext(
-            final ManagedObject targetAdapter,
-            final ObjectAction objectAction,
-            final Identifier id,
-            final Can<ManagedObject> args,
+            final PendingParameterModel pendingArgs,
             final int position,
             final InteractionInitiatedBy interactionInitiatedBy) {
         
-        super(InteractionContextType.ACTION_PARAMETER_VISIBLE, 
-                targetAdapter, 
-                id, 
+        super(
+                pendingArgs.getHead().toMemberInteractionHead(),
+                InteractionContextType.ACTION_PARAMETER_VISIBLE,
                 interactionInitiatedBy, 
                 Where.OBJECT_FORMS);
-        
-        this.objectAction = objectAction;
 
-        this.args = args;
+        this.pendingParamModel = pendingArgs;
         this.position = position;
     }
 
@@ -68,7 +60,7 @@ implements ActionInteractionContext {
         return new ActionArgumentVisibilityEvent(
                 ManagedObject.unwrapSingle(getTarget()), 
                 getIdentifier(), 
-                ManagedObject.unwrapMultipleAsArray(getArgs().toList()), 
+                ManagedObject.unwrapMultipleAsArray(getPendingParamModel().getParamValues().toList()), 
                 getPosition());
     }
 
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/ActionInteractionContext.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/ActionInteractionContext.java
index 70a1101..e581568 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/ActionInteractionContext.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/ActionInteractionContext.java
@@ -20,12 +20,13 @@
 package org.apache.isis.core.metamodel.interactions;
 
 import org.apache.isis.core.metamodel.spec.feature.ObjectAction;
+import org.apache.isis.core.metamodel.specloader.specimpl.PendingParameterModel;
 
 /**
  * See {@link InteractionContext} relating to {@link ObjectAction}s.
  */
 public interface ActionInteractionContext {
 
-    ObjectAction getObjectAction();
+    PendingParameterModel getPendingParamModel();
 
 }
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/ActionUsabilityContext.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/ActionUsabilityContext.java
index 8894b10..c1ed9bd 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/ActionUsabilityContext.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/ActionUsabilityContext.java
@@ -19,38 +19,38 @@
 
 package org.apache.isis.core.metamodel.interactions;
 
-import org.apache.isis.applib.Identifier;
 import org.apache.isis.applib.annotation.Where;
 import org.apache.isis.applib.services.wrapper.events.ActionUsabilityEvent;
 import org.apache.isis.core.metamodel.consent.InteractionContextType;
 import org.apache.isis.core.metamodel.consent.InteractionInitiatedBy;
-import org.apache.isis.core.metamodel.spec.ManagedObject;
-import org.apache.isis.core.metamodel.spec.feature.ObjectAction;
+import org.apache.isis.core.metamodel.specloader.specimpl.PendingParameterModel;
 
 import static org.apache.isis.core.metamodel.spec.ManagedObject.unwrapSingle;
 
+import lombok.Getter;
+
 /**
  * See {@link InteractionContext} for overview; analogous to
  * {@link ActionUsabilityEvent}.
  */
 public class ActionUsabilityContext extends UsabilityContext<ActionUsabilityEvent> implements ActionInteractionContext {
 
-    private final ObjectAction objectAction;
-
+    @Getter(onMethod = @__(@Override)) private final PendingParameterModel pendingParamModel;
+    
     public ActionUsabilityContext(
-            final ManagedObject targetAdapter,
-            final ObjectAction objectAction,
-            final Identifier id,
+            final PendingParameterModel pendingArgs,
             final InteractionInitiatedBy interactionInitiatedBy,
             final Where where) {
-        super(InteractionContextType.ACTION_USABLE, targetAdapter, id, interactionInitiatedBy, where);
-        this.objectAction = objectAction;
+        
+        super(
+                pendingArgs.getHead().toMemberInteractionHead(), 
+                InteractionContextType.ACTION_USABLE, 
+                interactionInitiatedBy, 
+                where);
+        
+        this.pendingParamModel = pendingArgs;
     }
 
-    @Override
-    public ObjectAction getObjectAction() {
-        return objectAction;
-    }
 
     @Override
     public ActionUsabilityEvent createInteractionEvent() {
@@ -58,3 +58,4 @@ public class ActionUsabilityContext extends UsabilityContext<ActionUsabilityEven
     }
 
 }
+
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/ActionValidityContext.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/ActionValidityContext.java
index 624533b..a97ce90 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/ActionValidityContext.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/ActionValidityContext.java
@@ -19,13 +19,11 @@
 
 package org.apache.isis.core.metamodel.interactions;
 
-import org.apache.isis.applib.Identifier;
 import org.apache.isis.applib.services.wrapper.events.ActionInvocationEvent;
-import org.apache.isis.core.commons.collections.Can;
 import org.apache.isis.core.metamodel.consent.InteractionContextType;
 import org.apache.isis.core.metamodel.consent.InteractionInitiatedBy;
 import org.apache.isis.core.metamodel.spec.ManagedObject;
-import org.apache.isis.core.metamodel.spec.feature.ObjectAction;
+import org.apache.isis.core.metamodel.specloader.specimpl.PendingParameterModel;
 
 import static org.apache.isis.core.metamodel.spec.ManagedObject.unwrapSingle;
 
@@ -39,25 +37,27 @@ public class ActionValidityContext
 extends ValidityContext<ActionInvocationEvent> 
 implements ActionInteractionContext {
 
-    @Getter(onMethod = @__(@Override)) private final ObjectAction objectAction;
-    @Getter private final Can<ManagedObject> args;
+    @Getter(onMethod = @__(@Override)) private final PendingParameterModel pendingParamModel;
 
     public ActionValidityContext(
-            final ManagedObject targetAdapter,
-            final ObjectAction objectAction,
-            final Identifier id,
-            final Can<ManagedObject> args,
+            final PendingParameterModel pendingArgs,
             final InteractionInitiatedBy interactionInitiatedBy) {
         
-        super(InteractionContextType.ACTION_INVOKE, targetAdapter, id, interactionInitiatedBy);
-        this.objectAction = objectAction;
-        this.args = args;
+        super(pendingArgs.getHead().toMemberInteractionHead(), 
+                InteractionContextType.ACTION_INVOKE, 
+                interactionInitiatedBy);
+        
+        this.pendingParamModel = pendingArgs;
     }
 
     @Override
     public ActionInvocationEvent createInteractionEvent() {
         return new ActionInvocationEvent(
-                unwrapSingle(getTarget()), getIdentifier(), ManagedObject.unwrapMultipleAsArray(getArgs().toList()));
+                unwrapSingle(getTarget()), 
+                getIdentifier(), 
+                ManagedObject.unwrapMultipleAsArray(getPendingParamModel().getParamValues().toList()));
     }
 
 }
+
+
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/ActionVisibilityContext.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/ActionVisibilityContext.java
index 4a224f2..a62c2b9 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/ActionVisibilityContext.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/ActionVisibilityContext.java
@@ -19,38 +19,39 @@
 
 package org.apache.isis.core.metamodel.interactions;
 
-import org.apache.isis.applib.Identifier;
 import org.apache.isis.applib.annotation.Where;
 import org.apache.isis.applib.services.wrapper.events.ActionVisibilityEvent;
 import org.apache.isis.core.metamodel.consent.InteractionContextType;
 import org.apache.isis.core.metamodel.consent.InteractionInitiatedBy;
-import org.apache.isis.core.metamodel.spec.ManagedObject;
-import org.apache.isis.core.metamodel.spec.feature.ObjectAction;
+import org.apache.isis.core.metamodel.specloader.specimpl.PendingParameterModel;
 
 import static org.apache.isis.core.metamodel.spec.ManagedObject.unwrapSingle;
 
+import lombok.Getter;
+
 /**
  * See {@link InteractionContext} for overview; analogous to
  * {@link ActionVisibilityEvent}.
  */
 public class ActionVisibilityContext extends VisibilityContext<ActionVisibilityEvent> implements ActionInteractionContext  {
 
-    private final ObjectAction objectAction;
-
+    @Getter(onMethod = @__(@Override)) private final PendingParameterModel pendingParamModel;
+    
     public ActionVisibilityContext(
-            final ManagedObject targetAdapter,
-            final ObjectAction objectAction,
-            final Identifier identifier,
+            
+            final PendingParameterModel pendingArgs,
             final InteractionInitiatedBy interactionInitiatedBy,
             final Where where) {
-        super(InteractionContextType.ACTION_VISIBLE, targetAdapter, identifier, interactionInitiatedBy, where);
-        this.objectAction = objectAction;
+        
+        super(
+                pendingArgs.getHead().toMemberInteractionHead(), 
+                InteractionContextType.ACTION_VISIBLE, 
+                interactionInitiatedBy, 
+                where);
+        
+        this.pendingParamModel = pendingArgs;
     }
 
-    @Override
-    public ObjectAction getObjectAction() {
-        return objectAction;
-    }
 
     @Override
     public ActionVisibilityEvent createInteractionEvent() {
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/CollectionAccessContext.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/CollectionAccessContext.java
index c998083..91dcca7 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/CollectionAccessContext.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/CollectionAccessContext.java
@@ -19,11 +19,9 @@
 
 package org.apache.isis.core.metamodel.interactions;
 
-import org.apache.isis.applib.Identifier;
 import org.apache.isis.applib.services.wrapper.events.CollectionAccessEvent;
 import org.apache.isis.core.metamodel.consent.InteractionContextType;
 import org.apache.isis.core.metamodel.consent.InteractionInitiatedBy;
-import org.apache.isis.core.metamodel.spec.ManagedObject;
 
 import static org.apache.isis.core.metamodel.spec.ManagedObject.unwrapSingle;
 
@@ -34,10 +32,9 @@ import static org.apache.isis.core.metamodel.spec.ManagedObject.unwrapSingle;
 public class CollectionAccessContext extends AccessContext<CollectionAccessEvent> {
 
     public CollectionAccessContext(
-            final ManagedObject target,
-            final Identifier identifier,
+            final MemberInteractionHead head,
             final InteractionInitiatedBy interactionInitiatedBy) {
-        super(InteractionContextType.COLLECTION_READ, identifier, target, interactionInitiatedBy);
+        super(head, InteractionContextType.COLLECTION_READ, interactionInitiatedBy);
     }
 
     @Override
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/CollectionAddToContext.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/CollectionAddToContext.java
index 6ffb00b..083c52a 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/CollectionAddToContext.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/CollectionAddToContext.java
@@ -19,7 +19,6 @@
 
 package org.apache.isis.core.metamodel.interactions;
 
-import org.apache.isis.applib.Identifier;
 import org.apache.isis.applib.services.wrapper.events.CollectionAddToEvent;
 import org.apache.isis.core.metamodel.consent.InteractionContextType;
 import org.apache.isis.core.metamodel.consent.InteractionInitiatedBy;
@@ -34,11 +33,10 @@ public class CollectionAddToContext extends ValidityContext<CollectionAddToEvent
     private final ManagedObject proposed;
 
     public CollectionAddToContext(
-            final ManagedObject targetAdapter,
-            final Identifier id,
+            final MemberInteractionHead head,
             final ManagedObject proposed,
             final InteractionInitiatedBy interactionInitiatedBy) {
-        super(InteractionContextType.COLLECTION_ADD_TO, targetAdapter, id, interactionInitiatedBy);
+        super(head, InteractionContextType.COLLECTION_ADD_TO, interactionInitiatedBy);
 
         this.proposed = proposed;
     }
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/CollectionRemoveFromContext.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/CollectionRemoveFromContext.java
index 0be4241..d8af717 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/CollectionRemoveFromContext.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/CollectionRemoveFromContext.java
@@ -19,7 +19,6 @@
 
 package org.apache.isis.core.metamodel.interactions;
 
-import org.apache.isis.applib.Identifier;
 import org.apache.isis.applib.services.wrapper.events.CollectionRemoveFromEvent;
 import org.apache.isis.core.metamodel.consent.InteractionContextType;
 import org.apache.isis.core.metamodel.consent.InteractionInitiatedBy;
@@ -36,11 +35,10 @@ public class CollectionRemoveFromContext extends ValidityContext<CollectionRemov
     private final ManagedObject proposed;
 
     public CollectionRemoveFromContext(
-            final ManagedObject targetAdapter,
-            final Identifier identifier,
+            final MemberInteractionHead head,
             final ManagedObject proposed,
             final InteractionInitiatedBy interactionInitiatedBy) {
-        super(InteractionContextType.COLLECTION_REMOVE_FROM, targetAdapter, identifier, interactionInitiatedBy);
+        super(head, InteractionContextType.COLLECTION_REMOVE_FROM, interactionInitiatedBy);
 
         this.proposed = proposed;
     }
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/CollectionUsabilityContext.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/CollectionUsabilityContext.java
index 9127a88..455c181 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/CollectionUsabilityContext.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/CollectionUsabilityContext.java
@@ -19,12 +19,10 @@
 
 package org.apache.isis.core.metamodel.interactions;
 
-import org.apache.isis.applib.Identifier;
 import org.apache.isis.applib.annotation.Where;
 import org.apache.isis.applib.services.wrapper.events.CollectionUsabilityEvent;
 import org.apache.isis.core.metamodel.consent.InteractionContextType;
 import org.apache.isis.core.metamodel.consent.InteractionInitiatedBy;
-import org.apache.isis.core.metamodel.spec.ManagedObject;
 
 /**
  * See {@link InteractionContext} for overview; analogous to
@@ -33,11 +31,10 @@ import org.apache.isis.core.metamodel.spec.ManagedObject;
 public class CollectionUsabilityContext extends UsabilityContext<CollectionUsabilityEvent> {
 
     public CollectionUsabilityContext(
-            final ManagedObject targetAdapter,
-            final Identifier identifier,
+            final MemberInteractionHead head,
             final InteractionInitiatedBy interactionInitiatedBy,
             final Where where) {
-        super(InteractionContextType.COLLECTION_USABLE, targetAdapter, identifier, interactionInitiatedBy, where);
+        super(head, InteractionContextType.COLLECTION_USABLE, interactionInitiatedBy, where);
     }
 
     @Override
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/CollectionVisibilityContext.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/CollectionVisibilityContext.java
index a11c1f6..680c27e 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/CollectionVisibilityContext.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/CollectionVisibilityContext.java
@@ -19,12 +19,10 @@
 
 package org.apache.isis.core.metamodel.interactions;
 
-import org.apache.isis.applib.Identifier;
 import org.apache.isis.applib.annotation.Where;
 import org.apache.isis.applib.services.wrapper.events.CollectionVisibilityEvent;
 import org.apache.isis.core.metamodel.consent.InteractionContextType;
 import org.apache.isis.core.metamodel.consent.InteractionInitiatedBy;
-import org.apache.isis.core.metamodel.spec.ManagedObject;
 
 import static org.apache.isis.core.metamodel.spec.ManagedObject.unwrapSingle;
 
@@ -35,11 +33,11 @@ import static org.apache.isis.core.metamodel.spec.ManagedObject.unwrapSingle;
 public class CollectionVisibilityContext extends VisibilityContext<CollectionVisibilityEvent> {
 
     public CollectionVisibilityContext(
-            final ManagedObject target,
-            final Identifier identifierAdapter,
+            final MemberInteractionHead head,
             final InteractionInitiatedBy interactionInitiatedBy,
             final Where where) {
-        super(InteractionContextType.COLLECTION_VISIBLE, target, identifierAdapter, interactionInitiatedBy, where);
+        
+        super(head, InteractionContextType.COLLECTION_VISIBLE, interactionInitiatedBy, where);
     }
 
     @Override
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/InteractionContext.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/InteractionContext.java
index cb73161..044de89 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/InteractionContext.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/InteractionContext.java
@@ -19,18 +19,16 @@
 
 package org.apache.isis.core.metamodel.interactions;
 
-import javax.annotation.Nullable;
-
 import org.apache.isis.applib.Identifier;
 import org.apache.isis.applib.services.wrapper.events.InteractionEvent;
-import org.apache.isis.core.commons.internal.base._Tuples;
-import org.apache.isis.core.commons.internal.base._Tuples.Indexed;
 import org.apache.isis.core.metamodel.consent.InteractionContextType;
 import org.apache.isis.core.metamodel.consent.InteractionInitiatedBy;
 import org.apache.isis.core.metamodel.facetapi.Facet;
 import org.apache.isis.core.metamodel.spec.ManagedObject;
 import org.apache.isis.core.security.authentication.AuthenticationSession;
 
+import lombok.Getter;
+
 /**
  * Represents an interaction between the framework and (a {@link Facet} of) the
  * domain object.
@@ -59,28 +57,7 @@ import org.apache.isis.core.security.authentication.AuthenticationSession;
  */
 public abstract class InteractionContext<T extends InteractionEvent> {
 
-    private final InteractionContextType interactionType;
-    private final InteractionInitiatedBy interactionInitiatedBy;
-    private final Identifier identifier;
-    private final ManagedObject target;
-
-    private int contributeeParam = -1; // no contributee
-    private ManagedObject contributee = null;
     
-    private ManagedObject mixedInAdapter = null; // for mixin members only, obviously
-
-    public InteractionContext(
-            final InteractionContextType interactionType,
-            final InteractionInitiatedBy invocationMethod,
-            final Identifier identifier,
-            final ManagedObject target) {
-        this.interactionType = interactionType;
-        this.interactionInitiatedBy = invocationMethod;
-        this.identifier = identifier;
-        this.target = target;
-    }
-
-
     /**
      * The type of interaction.
      *
@@ -93,10 +70,27 @@ public abstract class InteractionContext<T extends InteractionEvent> {
      * <p>
      * Alternatively, {@link Facet}s can use <tt>instanceof</tt>.
      */
-    public InteractionContextType getInteractionType() {
-        return interactionType;
+    @Getter private final InteractionContextType interactionType;
+
+    
+    /**
+     * How the interaction was initiated.
+     */
+    @Getter private final InteractionInitiatedBy initiatedBy;
+
+    @Getter private final InteractionHead head;
+
+    
+    public InteractionContext(
+            final InteractionHead head,
+            final InteractionContextType interactionType,
+            final InteractionInitiatedBy initiatedBy) {
+        this.head = head;
+        this.interactionType = interactionType;
+        this.initiatedBy = initiatedBy;
     }
 
+
     /**
      * The identifier of the object or member that is being identified with.
      *
@@ -107,15 +101,7 @@ public abstract class InteractionContext<T extends InteractionEvent> {
      * the identifier of the member.
      */
     public Identifier getIdentifier() {
-        return identifier;
-    }
-
-
-    /**
-     * How the interaction was initiated.
-     */
-    public InteractionInitiatedBy getInitiatedBy() {
-        return interactionInitiatedBy;
+        return head.getIdentifier();
     }
 
     /**
@@ -123,43 +109,16 @@ public abstract class InteractionContext<T extends InteractionEvent> {
      * {@link #getInitiatedBy() interaction was invoked} by the framework.
      */
     public boolean isFrameworkInitiated() {
-        return interactionInitiatedBy == InteractionInitiatedBy.FRAMEWORK;
+        return initiatedBy == InteractionInitiatedBy.FRAMEWORK;
     }
 
     /**
      * The target object that this interaction is with.
      */
     public ManagedObject getTarget() {
-        return target;
-    }
-
-    // //////////////////////////////////////
-
-    public void putContributee(int contributeeParam, ManagedObject contributee) {
-        this.contributeeParam = contributeeParam;
-        this.contributee = contributee;
-    }
-
-    public @Nullable Indexed<ManagedObject> getContributeeWithParamIndex() {
-        if(contributee==null) {
-            return null;
-        }
-        return _Tuples.indexed(contributeeParam, contributee);
-    }
-
-    // //////////////////////////////////////
-
-    public void setMixedIn(final ManagedObject mixedInAdapter) {
-        this.mixedInAdapter = mixedInAdapter;
-    }
-
-    public ManagedObject getMixedIn() {
-        return mixedInAdapter;
+        return head.getTarget();
     }
 
-    // //////////////////////////////////////
-
-
 
     /**
      * Factory method to create corresponding {@link InteractionEvent}.
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/InteractionHead.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/InteractionHead.java
new file mode 100644
index 0000000..14943eb
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/InteractionHead.java
@@ -0,0 +1,21 @@
+package org.apache.isis.core.metamodel.interactions;
+
+import org.apache.isis.applib.Identifier;
+import org.apache.isis.core.metamodel.spec.ManagedObject;
+
+import lombok.NonNull;
+
+public interface InteractionHead {
+
+    @NonNull Identifier getIdentifier();
+    
+    @NonNull ManagedObject getOwner();
+    
+    /** 
+     * typically equal to {@code memberOwner}, except for mixins, 
+     * where {@code memberTarget} is the mixin instance 
+     */
+    @NonNull ManagedObject getTarget();
+    
+    
+}
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/MemberInteractionHead.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/MemberInteractionHead.java
new file mode 100644
index 0000000..76f51bf
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/MemberInteractionHead.java
@@ -0,0 +1,81 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.apache.isis.core.metamodel.interactions;
+
+import org.apache.isis.applib.Identifier;
+import org.apache.isis.core.metamodel.spec.ManagedObject;
+import org.apache.isis.core.metamodel.spec.feature.ObjectMember;
+
+import lombok.Getter;
+import lombok.NonNull;
+import lombok.RequiredArgsConstructor;
+
+/**
+ * 
+ * @since 2.0
+ *
+ */
+public interface MemberInteractionHead extends InteractionHead {
+
+    @NonNull ObjectMember getMember();
+    @NonNull ManagedObject getMemberOwner();
+    
+    /** 
+     * typically equal to {@code memberOwner}, except for mixins, 
+     * where {@code memberTarget} is the mixin instance 
+     */
+    @NonNull ManagedObject getMemberTarget(); 
+
+    @Override
+    default @NonNull Identifier getIdentifier() {
+        return getMember().getIdentifier();
+    }
+
+    @Override
+    default @NonNull ManagedObject getOwner() {
+        return getMemberOwner();
+    }
+
+    @Override
+    default @NonNull ManagedObject getTarget() {
+        return getMemberTarget();
+    }
+    
+    public static MemberInteractionHead of(
+            @NonNull final ObjectMember member,
+            @NonNull final ManagedObject memberOwner,
+            @NonNull final ManagedObject memberTarget) {
+        return MemberInteractionHeadImpl.of(member, memberOwner, memberTarget);
+    }
+    
+    @Getter 
+    @RequiredArgsConstructor(staticName = "of")
+    //@Log4j2
+    public class MemberInteractionHeadImpl implements MemberInteractionHead {
+        @NonNull private final ObjectMember member;
+        @NonNull private final ManagedObject memberOwner;
+        
+        /** 
+         * typically equal to {@code memberOwner}, except for mixins, 
+         * where {@code memberTarget} is the mixin instance 
+         */
+        @NonNull private final ManagedObject memberTarget; 
+    }
+    
+}
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/ObjectTitleContext.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/ObjectTitleContext.java
index c794a1f..79312e5 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/ObjectTitleContext.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/ObjectTitleContext.java
@@ -19,11 +19,9 @@
 
 package org.apache.isis.core.metamodel.interactions;
 
-import org.apache.isis.applib.Identifier;
 import org.apache.isis.applib.services.wrapper.events.ObjectTitleEvent;
 import org.apache.isis.core.metamodel.consent.InteractionContextType;
 import org.apache.isis.core.metamodel.consent.InteractionInitiatedBy;
-import org.apache.isis.core.metamodel.spec.ManagedObject;
 
 import static org.apache.isis.core.metamodel.spec.ManagedObject.unwrapSingle;
 
@@ -36,11 +34,10 @@ public class ObjectTitleContext extends AccessContext<ObjectTitleEvent> {
     private final String title;
 
     public ObjectTitleContext(
-            final ManagedObject targetAdapter,
-            final Identifier identifier,
+            final MemberInteractionHead head,
             final String title,
             final InteractionInitiatedBy interactionInitiatedBy) {
-        super(InteractionContextType.OBJECT_TITLE, identifier, targetAdapter, interactionInitiatedBy);
+        super(head, InteractionContextType.OBJECT_TITLE, interactionInitiatedBy);
         this.title = title;
     }
 
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/PropertyAccessContext.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/PropertyAccessContext.java
index ec27c8f..cf6a927 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/PropertyAccessContext.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/PropertyAccessContext.java
@@ -19,7 +19,6 @@
 
 package org.apache.isis.core.metamodel.interactions;
 
-import org.apache.isis.applib.Identifier;
 import org.apache.isis.applib.services.wrapper.events.PropertyAccessEvent;
 import org.apache.isis.core.metamodel.consent.InteractionContextType;
 import org.apache.isis.core.metamodel.consent.InteractionInitiatedBy;
@@ -36,11 +35,10 @@ public class PropertyAccessContext extends AccessContext<PropertyAccessEvent> {
     private final ManagedObject value;
 
     public PropertyAccessContext(
-            final ManagedObject targetAdapter,
-            final Identifier id,
+            final MemberInteractionHead head,
             final ManagedObject value,
             final InteractionInitiatedBy interactionInitiatedBy) {
-        super(InteractionContextType.PROPERTY_READ, id, targetAdapter, interactionInitiatedBy);
+        super(head, InteractionContextType.PROPERTY_READ, interactionInitiatedBy);
 
         this.value = value;
     }
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/PropertyModifyContext.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/PropertyModifyContext.java
index 35e7455..dd4a8ab 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/PropertyModifyContext.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/PropertyModifyContext.java
@@ -19,7 +19,6 @@
 
 package org.apache.isis.core.metamodel.interactions;
 
-import org.apache.isis.applib.Identifier;
 import org.apache.isis.applib.services.wrapper.events.PropertyModifyEvent;
 import org.apache.isis.core.metamodel.consent.InteractionContextType;
 import org.apache.isis.core.metamodel.consent.InteractionInitiatedBy;
@@ -36,11 +35,10 @@ public class PropertyModifyContext extends ValidityContext<PropertyModifyEvent>
     private final ManagedObject proposed;
 
     public PropertyModifyContext(
-            final ManagedObject targetAdapter,
-            final Identifier id,
+            final MemberInteractionHead head,
             final ManagedObject proposed,
             final InteractionInitiatedBy interactionInitiatedBy) {
-        super(InteractionContextType.PROPERTY_MODIFY, targetAdapter, id, interactionInitiatedBy);
+        super(head, InteractionContextType.PROPERTY_MODIFY, interactionInitiatedBy);
 
         this.proposed = proposed;
     }
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/PropertyUsabilityContext.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/PropertyUsabilityContext.java
index 6c64d58..b9f7824 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/PropertyUsabilityContext.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/PropertyUsabilityContext.java
@@ -19,12 +19,10 @@
 
 package org.apache.isis.core.metamodel.interactions;
 
-import org.apache.isis.applib.Identifier;
 import org.apache.isis.applib.annotation.Where;
 import org.apache.isis.applib.services.wrapper.events.PropertyUsabilityEvent;
 import org.apache.isis.core.metamodel.consent.InteractionContextType;
 import org.apache.isis.core.metamodel.consent.InteractionInitiatedBy;
-import org.apache.isis.core.metamodel.spec.ManagedObject;
 
 import static org.apache.isis.core.metamodel.spec.ManagedObject.unwrapSingle;
 
@@ -35,11 +33,10 @@ import static org.apache.isis.core.metamodel.spec.ManagedObject.unwrapSingle;
 public class PropertyUsabilityContext extends UsabilityContext<PropertyUsabilityEvent> {
 
     public PropertyUsabilityContext(
-            final ManagedObject targetAdapter,
-            final Identifier identifier,
+            final MemberInteractionHead head,
             final InteractionInitiatedBy interactionInitiatedBy,
             final Where where) {
-        super(InteractionContextType.PROPERTY_USABLE, targetAdapter, identifier, interactionInitiatedBy, where);
+        super(head, InteractionContextType.PROPERTY_USABLE, interactionInitiatedBy, where);
     }
 
     @Override
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/PropertyVisibilityContext.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/PropertyVisibilityContext.java
index 0439e7d..cb891e3 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/PropertyVisibilityContext.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/PropertyVisibilityContext.java
@@ -19,12 +19,10 @@
 
 package org.apache.isis.core.metamodel.interactions;
 
-import org.apache.isis.applib.Identifier;
 import org.apache.isis.applib.annotation.Where;
 import org.apache.isis.applib.services.wrapper.events.PropertyVisibilityEvent;
 import org.apache.isis.core.metamodel.consent.InteractionContextType;
 import org.apache.isis.core.metamodel.consent.InteractionInitiatedBy;
-import org.apache.isis.core.metamodel.spec.ManagedObject;
 
 import static org.apache.isis.core.metamodel.spec.ManagedObject.unwrapSingle;
 
@@ -35,11 +33,10 @@ import static org.apache.isis.core.metamodel.spec.ManagedObject.unwrapSingle;
 public class PropertyVisibilityContext extends VisibilityContext<PropertyVisibilityEvent> {
 
     public PropertyVisibilityContext(
-            final ManagedObject targetAdapter,
-            final Identifier identifier,
+            final MemberInteractionHead head,
             final InteractionInitiatedBy interactionInitiatedBy,
             final Where where) {
-        super(InteractionContextType.PROPERTY_VISIBLE, targetAdapter, identifier, interactionInitiatedBy, where);
+        super(head, InteractionContextType.PROPERTY_VISIBLE, interactionInitiatedBy, where);
     }
 
     @Override
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/UsabilityContext.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/UsabilityContext.java
index a6506c9..d55da08 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/UsabilityContext.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/UsabilityContext.java
@@ -19,12 +19,10 @@
 
 package org.apache.isis.core.metamodel.interactions;
 
-import org.apache.isis.applib.Identifier;
 import org.apache.isis.applib.annotation.Where;
 import org.apache.isis.applib.services.wrapper.events.UsabilityEvent;
 import org.apache.isis.core.metamodel.consent.InteractionContextType;
 import org.apache.isis.core.metamodel.consent.InteractionInitiatedBy;
-import org.apache.isis.core.metamodel.spec.ManagedObject;
 
 /**
  * See {@link InteractionContext} for overview; analogous to
@@ -35,12 +33,11 @@ public abstract class UsabilityContext<T extends UsabilityEvent> extends Interac
     private final Where where;
 
     public UsabilityContext(
+            final MemberInteractionHead head,
             final InteractionContextType interactionType,
-            final ManagedObject targetAdapter,
-            final Identifier identifier,
             final InteractionInitiatedBy interactionInitiatedBy,
             final Where where) {
-        super(interactionType, interactionInitiatedBy, identifier, targetAdapter);
+        super(head, interactionType, interactionInitiatedBy);
         this.where = where;
     }
 
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/ValidityContext.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/ValidityContext.java
index bd65853..9af75ec 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/ValidityContext.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/ValidityContext.java
@@ -19,11 +19,9 @@
 
 package org.apache.isis.core.metamodel.interactions;
 
-import org.apache.isis.applib.Identifier;
 import org.apache.isis.applib.services.wrapper.events.ValidityEvent;
 import org.apache.isis.core.metamodel.consent.InteractionContextType;
 import org.apache.isis.core.metamodel.consent.InteractionInitiatedBy;
-import org.apache.isis.core.metamodel.spec.ManagedObject;
 
 /**
  * See {@link InteractionContext} for overview; analogous to
@@ -32,11 +30,10 @@ import org.apache.isis.core.metamodel.spec.ManagedObject;
 public abstract class ValidityContext<T extends ValidityEvent> extends InteractionContext<T> {
 
     public ValidityContext(
+            final InteractionHead head,
             final InteractionContextType interactionType,
-            final ManagedObject target,
-            final Identifier identifier,
             final InteractionInitiatedBy invocationMethod) {
-        super(interactionType, invocationMethod, identifier, target);
+        super(head, interactionType, invocationMethod);
     }
 
 }
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/VisibilityContext.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/VisibilityContext.java
index e9f368d..2612a84 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/VisibilityContext.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/VisibilityContext.java
@@ -19,12 +19,10 @@
 
 package org.apache.isis.core.metamodel.interactions;
 
-import org.apache.isis.applib.Identifier;
 import org.apache.isis.applib.annotation.Where;
 import org.apache.isis.applib.services.wrapper.events.VisibilityEvent;
 import org.apache.isis.core.metamodel.consent.InteractionContextType;
 import org.apache.isis.core.metamodel.consent.InteractionInitiatedBy;
-import org.apache.isis.core.metamodel.spec.ManagedObject;
 
 /**
  * See {@link InteractionContext} for overview; analogous to
@@ -35,12 +33,11 @@ public abstract class VisibilityContext<T extends VisibilityEvent> extends Inter
     private Where where;
 
     public VisibilityContext(
+            final MemberInteractionHead head,
             final InteractionContextType interactionType,
-            final ManagedObject targetAdapter,
-            final Identifier identifier,
             final InteractionInitiatedBy interactionInitiatedBy,
             final Where where) {
-        super(interactionType, interactionInitiatedBy, identifier, targetAdapter);
+        super(head, interactionType, interactionInitiatedBy);
         this.where = where;
     }
 
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/ixn/InteractionDtoServiceInternal.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/ixn/InteractionDtoServiceInternal.java
index 5a0e89b..df5b9f8 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/ixn/InteractionDtoServiceInternal.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/ixn/InteractionDtoServiceInternal.java
@@ -20,28 +20,34 @@ package org.apache.isis.core.metamodel.services.ixn;
 
 import java.util.List;
 
-import org.apache.isis.applib.annotation.Programmatic;
 import org.apache.isis.core.metamodel.spec.ManagedObject;
 import org.apache.isis.core.metamodel.spec.feature.ObjectAction;
 import org.apache.isis.core.metamodel.spec.feature.OneToOneAssociation;
+import org.apache.isis.core.metamodel.specloader.specimpl.PendingParameterModel;
 import org.apache.isis.schema.ixn.v2.ActionInvocationDto;
 import org.apache.isis.schema.ixn.v2.PropertyEditDto;
 
 public interface InteractionDtoServiceInternal {
 
-    @Programmatic
+    default ActionInvocationDto asActionInvocationDto(
+            PendingParameterModel pendingArgs) {
+        return asActionInvocationDto(
+                pendingArgs.getAction(), 
+                pendingArgs.getActionTarget(), 
+                pendingArgs.getParamValues().toList());
+    }
+    
     ActionInvocationDto asActionInvocationDto(
             ObjectAction objectAction,
             ManagedObject targetAdapter,
             List<ManagedObject> argumentAdapters);
+    
 
-    @Programmatic
     PropertyEditDto asPropertyEditDto(
             OneToOneAssociation property,
             ManagedObject targetAdapter,
             ManagedObject newValueAdapterIfAny);
 
-    @Programmatic
     ActionInvocationDto updateResult(
             ActionInvocationDto actionInvocationDto,
             ObjectAction objectAction,
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/ManagedObject.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/ManagedObject.java
index a8bc77a..24d3083 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/ManagedObject.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/ManagedObject.java
@@ -655,27 +655,6 @@ public interface ManagedObject {
             return MethodExtensions.invoke(method, unwrapSingle(adapter), unwrapMultipleAsArray(argumentAdapters));
         }
     
-        public static Object invokeC(
-                Method method, 
-                ManagedObject adapter, 
-                Stream<Indexed<? extends ManagedObject>> paramsAndIndexes) {
-            return invoke(method, adapter, asArray(paramsAndIndexes, method.getParameterTypes().length));
-        }
-    
-        private static ManagedObject[] asArray(
-                Stream<Indexed<? extends ManagedObject>> paramsAndIndexes, 
-                int length) {
-            
-            final ManagedObject[] args = new ManagedObject[length];
-            paramsAndIndexes.forEach(entry->{
-                final int paramNum = entry.getIndex();
-                if(paramNum < length) {
-                    args[paramNum] = entry.getValue();
-                }
-            });
-            return args;
-        }
-    
         /**
          * Invokes the method, adjusting arguments as required to make them fit the method's parameters.
          * <p>
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/feature/ObjectAction.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/feature/ObjectAction.java
index c7a70e1..a8d5406 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/feature/ObjectAction.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/feature/ObjectAction.java
@@ -54,8 +54,9 @@ import org.apache.isis.core.metamodel.layout.memberorderfacet.MemberOrderFacetCo
 import org.apache.isis.core.metamodel.spec.ActionType;
 import org.apache.isis.core.metamodel.spec.ManagedObject;
 import org.apache.isis.core.metamodel.spec.ObjectSpecification;
+import org.apache.isis.core.metamodel.specloader.specimpl.ActionInteractionHead;
 import org.apache.isis.core.metamodel.specloader.specimpl.MixedInMember;
-import org.apache.isis.core.metamodel.specloader.specimpl.PendingParameterModelHead;
+import org.apache.isis.core.metamodel.specloader.specimpl.PendingParameterModel;
 
 import static org.apache.isis.core.commons.internal.base._NullSafe.stream;
 
@@ -84,7 +85,6 @@ public interface ObjectAction extends ObjectMember {
     boolean isPrototype();
 
 
-
     // -- ReturnType
     /**
      * Returns the specifications for the return type.
@@ -97,20 +97,18 @@ public interface ObjectAction extends ObjectMember {
      */
     boolean hasReturn();
 
-
-
     // -- execute, executeWithRuleChecking
 
     /**
      * Invokes the action's method on the target object given the specified set
      * of parameters, checking the visibility, usability and validity first.
      *
-     * @param mixedInAdapter - will be null for regular actions, and for mixin actions.  When a mixin action invokes its underlying mixedIn action, then will be populated (so that the ActionDomainEvent can correctly provide the underlying mixin)
+     * @param mixedInAdapter - will be null for regular actions, and for mixin actions.  
+     * When a mixin action invokes its underlying mixedIn action, 
+     * then will be populated (so that the ActionDomainEvent can correctly provide the underlying mixin)
      */
     ManagedObject executeWithRuleChecking(
-            ManagedObject target,
-            ManagedObject mixedInAdapter,
-            Can<ManagedObject> parameters,
+            @NonNull PendingParameterModel pendingArgs,
             InteractionInitiatedBy interactionInitiatedBy,
             Where where) throws AuthorizationException;
 
@@ -123,9 +121,7 @@ public interface ObjectAction extends ObjectMember {
      * (so that the ActionDomainEvent can correctly provide the underlying mixin)
      */
     ManagedObject execute(
-            ManagedObject targetAdapter,
-            ManagedObject mixedInAdapter,
-            Can<ManagedObject> parameters,
+            @NonNull PendingParameterModel pendingArgs,
             InteractionInitiatedBy interactionInitiatedBy);
 
 
@@ -144,24 +140,21 @@ public interface ObjectAction extends ObjectMember {
      * </p>
      */
     Consent isProposedArgumentSetValid(
-            ManagedObject object,
-            Can<ManagedObject> proposedArguments,
+            @NonNull PendingParameterModel pendingArgs,
             InteractionInitiatedBy interactionInitiatedBy);
 
     Consent isEachIndividualArgumentValid(
-            ManagedObject objectAdapter,
-            Can<ManagedObject> proposedArguments,
+            @NonNull PendingParameterModel pendingArgs,
             InteractionInitiatedBy interactionInitiatedBy);
 
     Consent isArgumentSetValid(
-            ManagedObject objectAdapter,
-            Can<ManagedObject> proposedArguments,
+            @NonNull PendingParameterModel pendingArgs,
             InteractionInitiatedBy interactionInitiatedBy);
 
 
     // -- Model for Parameter Negotiation
 
-    PendingParameterModelHead newPendingParameterModelHead(
+    ActionInteractionHead newInteractionHead(
             @NonNull ManagedObject actionOwner);
     
     // -- Parameters (declarative)
@@ -484,52 +477,18 @@ public interface ObjectAction extends ObjectMember {
             return (ObjectAction oa) -> oa.getType() == type;
         }
 
-        //        public static Predicate<ObjectAction> bulk() {
-        //            return new Predicate<ObjectAction>() {
-        //
-        //                @Override
-        //                public boolean test(ObjectAction oa) {
-        //
-        //                    final BulkFacet bulkFacet = oa.getFacet(BulkFacet.class);
-        //                    if(bulkFacet == null || bulkFacet.isNoop() || bulkFacet.value() == InvokeOn.OBJECT_ONLY) {
-        //                        return false;
-        //                    }
-        //                    if (oa.getParameterCount() != 0) {
-        //                        return false;
-        //                    }
-        //
-        //                    // currently don't support returning Blobs or Clobs
-        //                    // (because haven't figured out how to rerender the current page, but also to do a download)
-        //                    ObjectSpecification returnSpec = oa.getReturnType();
-        //                    if (returnSpec != null) {
-        //                        Class<?> returnType = returnSpec.getCorrespondingClass();
-        //                        if (returnType == Blob.class || returnType == Clob.class) {
-        //                            return false;
-        //                        }
-        //                    }
-        //                    return true;
-        //                }
-        //            };
-        //        }
-
         public static Predicate<ObjectAction> dynamicallyVisible(
                 final ManagedObject target,
                 final InteractionInitiatedBy interactionInitiatedBy,
                 final Where where) {
             
             return (ObjectAction objectAction) -> {
-                final Consent visible = objectAction.isVisible(target, interactionInitiatedBy, where);
+                val head = objectAction.newInteractionHead(target);
+                val visible = objectAction.isVisible(head, interactionInitiatedBy, where);
                 return visible.isAllowed();
             };
         }
 
-        //        public static Predicate<ObjectAction> notBulkOnly() {
-        //            return (ObjectAction t) -> {
-        //                    BulkFacet facet = t.getFacet(BulkFacet.class);
-        //                    return facet == null || facet.value() != InvokeOn.COLLECTION_ONLY;
-        //            };
-        //        }
-
         public static Predicate<ObjectAction> excludeWizardActions(final ObjectSpecification objectSpecification) {
             return wizardActions(objectSpecification).negate();
         }
@@ -585,5 +544,4 @@ public interface ObjectAction extends ObjectMember {
     }
 
 
-
 }
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/feature/ObjectActionParameter.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/feature/ObjectActionParameter.java
index b0eaf4c..500a659 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/feature/ObjectActionParameter.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/feature/ObjectActionParameter.java
@@ -28,7 +28,6 @@ import org.apache.isis.core.commons.collections.Can;
 import org.apache.isis.core.metamodel.consent.Consent;
 import org.apache.isis.core.metamodel.consent.InteractionInitiatedBy;
 import org.apache.isis.core.metamodel.facets.all.named.NamedFacet;
-import org.apache.isis.core.metamodel.interactions.ActionArgValidityContext;
 import org.apache.isis.core.metamodel.spec.ManagedObject;
 import org.apache.isis.core.metamodel.spec.ObjectSpecification;
 import org.apache.isis.core.metamodel.specloader.specimpl.PendingParameterModel;
@@ -75,14 +74,6 @@ public interface ObjectActionParameter extends ObjectFeature, CurrentHolder {
     @Override
     String getName();
 
-    // internal API
-    ActionArgValidityContext createProposedArgumentInteractionContext(
-            ManagedObject targetObject,
-            Can<ManagedObject> args,
-            int position,
-            InteractionInitiatedBy interactionInitiatedBy);
-
-
     /**
      * Whether there is an autoComplete provided (eg <tt>autoCompleteXxx</tt> supporting
      * method) for the parameter.
@@ -136,7 +127,7 @@ public interface ObjectActionParameter extends ObjectFeature, CurrentHolder {
     /** default value as result of a initial param value fixed point search */
     default ManagedObject getDefault(ManagedObject actionOnwer) {
         return getAction()
-                .newPendingParameterModelHead(actionOnwer).defaults()
+                .newInteractionHead(actionOnwer).defaults()
                 .getParamValues()
                 .getElseFail(getNumber());
     }
@@ -150,8 +141,7 @@ public interface ObjectActionParameter extends ObjectFeature, CurrentHolder {
      * @return
      */
     Consent isVisible(
-            ManagedObject targetAdapter,
-            Can<ManagedObject> pendingArgs,
+            PendingParameterModel pendingArgs,
             InteractionInitiatedBy interactionInitiatedBy);
 
     /**
@@ -162,8 +152,7 @@ public interface ObjectActionParameter extends ObjectFeature, CurrentHolder {
      * @return
      */
     Consent isUsable(
-            ManagedObject targetAdapter,
-            Can<ManagedObject> pendingArgs,
+            PendingParameterModel pendingArgs,
             InteractionInitiatedBy interactionInitiatedBy);
 
     /**
@@ -175,9 +164,9 @@ public interface ObjectActionParameter extends ObjectFeature, CurrentHolder {
      * @return
      */
     String isValid(
-            final ManagedObject adapter,
-            final Object proposedValue,
-            final InteractionInitiatedBy interactionInitiatedBy);
+            PendingParameterModel pendingArgs,
+            Object proposedValue,
+            InteractionInitiatedBy interactionInitiatedBy);
 
     @Vetoed
     public static class Predicates {
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/feature/ObjectMember.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/feature/ObjectMember.java
index f11e37d..4fe7e11 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/feature/ObjectMember.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/feature/ObjectMember.java
@@ -31,9 +31,11 @@ import org.apache.isis.core.metamodel.consent.Consent;
 import org.apache.isis.core.metamodel.consent.InteractionInitiatedBy;
 import org.apache.isis.core.metamodel.facets.all.hide.HiddenFacet;
 import org.apache.isis.core.metamodel.facets.members.order.MemberOrderFacet;
+import org.apache.isis.core.metamodel.interactions.MemberInteractionHead;
 import org.apache.isis.core.metamodel.layout.memberorderfacet.MemberOrderFacetComparator;
 import org.apache.isis.core.metamodel.spec.ManagedObject;
 
+import lombok.NonNull;
 import lombok.val;
 
 /**
@@ -76,7 +78,7 @@ public interface ObjectMember extends ObjectFeature {
      * @param where
      */
     Consent isVisible(
-            final ManagedObject target,
+            final MemberInteractionHead head,
             final InteractionInitiatedBy interactionInitiatedBy,
             final Where where);
 
@@ -93,7 +95,7 @@ public interface ObjectMember extends ObjectFeature {
      * @param where
      */
     Consent isUsable(
-            final ManagedObject target,
+            final MemberInteractionHead head,
             final InteractionInitiatedBy interactionInitiatedBy,
             final Where where);
 
@@ -203,7 +205,9 @@ public interface ObjectMember extends ObjectFeature {
         return memberById;
     }
 
-
+    public MemberInteractionHead newInteractionHead(
+            @NonNull ManagedObject memberOwner);
+    
     // //////////////////////////////////////////////////////
     // Comparators
     // //////////////////////////////////////////////////////
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/interaction/ManagedAction.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/interaction/ManagedAction.java
index 6389ee0..93c32a3 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/interaction/ManagedAction.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/interaction/ManagedAction.java
@@ -76,9 +76,12 @@ public final class ManagedAction extends ManagedMember {
             
         //TODO validate params, and handle invocation exceptions
         
-        final ManagedObject mixedInAdapter = null; // filled in automatically ?
+        val action = getAction();
+        val pendingArgs = action.newPendingParameterModelHead(getOwner())
+            .model(actionParameters);
+        
         val actionResult = getAction()
-                .execute(getOwner(), mixedInAdapter , actionParameters, InteractionInitiatedBy.USER);
+                .execute(pendingArgs, InteractionInitiatedBy.USER);
         
         return _Either.left(actionResult);
         
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/PendingParameterModelHead.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ActionInteractionHead.java
similarity index 76%
rename from core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/PendingParameterModelHead.java
rename to core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ActionInteractionHead.java
index 92d3676..951d278 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/PendingParameterModelHead.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ActionInteractionHead.java
@@ -21,10 +21,12 @@ package org.apache.isis.core.metamodel.specloader.specimpl;
 import java.util.Objects;
 
 import org.apache.isis.core.commons.collections.Can;
+import org.apache.isis.core.metamodel.interactions.MemberInteractionHead;
 import org.apache.isis.core.metamodel.spec.ManagedObject;
 import org.apache.isis.core.metamodel.spec.feature.ObjectAction;
+import org.apache.isis.core.metamodel.spec.feature.ObjectMember;
 
-import lombok.Getter;
+import lombok.AccessLevel;
 import lombok.NonNull;
 import lombok.RequiredArgsConstructor;
 import lombok.val;
@@ -36,19 +38,34 @@ import lombok.extern.log4j.Log4j2;
  *  
  * @since 2.0.0
  */
-@Getter 
-@RequiredArgsConstructor(staticName = "of")
+@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
 @Log4j2
-public class PendingParameterModelHead {
+public class ActionInteractionHead implements MemberInteractionHead {
 
-    @NonNull private final ObjectAction action;
-    @NonNull private final ManagedObject actionOwner;
+    private final MemberInteractionHead data;
+
+    public static ActionInteractionHead of(
+            @NonNull final ObjectAction action,
+            @NonNull final ManagedObject actionOwner,
+            @NonNull final ManagedObject actionTarget) {
+        return new ActionInteractionHead(MemberInteractionHead.of(action, actionOwner, actionTarget));
+    }
+
+    public ObjectAction getAction() {
+        return (ObjectAction) data.getMember();
+    }
     
+    public ManagedObject getActionOwner() {
+        return data.getOwner();
+    }
+
     /** 
      * typically equal to {@code actionOwner}, except for mixins, 
      * where {@code actionTarget} is the mixin instance 
      */
-    @NonNull private final ManagedObject actionTarget; 
+    public ManagedObject getActionTarget() {
+        return data.getTarget();
+    }
     
     /**  
      * Immutable tuple of ManagedObjects, each representing {@code null} and each holding 
@@ -129,9 +146,22 @@ public class PendingParameterModelHead {
         return true;
     }
 
-   
+    @Override
+    public @NonNull ObjectMember getMember() {
+        // TODO Auto-generated method stub
+        return null;
+    }
 
-    
-    
+    @Override
+    public @NonNull ManagedObject getMemberOwner() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public @NonNull ManagedObject getMemberTarget() {
+        // TODO Auto-generated method stub
+        return null;
+    }
     
 }
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/Factories.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/Factories.java
index ebd10dc..f8f3b0a 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/Factories.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/Factories.java
@@ -20,7 +20,6 @@ package org.apache.isis.core.metamodel.specloader.specimpl;
 
 import java.util.function.Function;
 
-import org.apache.isis.core.commons.internal.ioc.ManagedBeanAdapter;
 import org.apache.isis.core.metamodel.spec.ObjectSpecification;
 import org.apache.isis.core.metamodel.spec.feature.ObjectAssociation;
 
@@ -32,22 +31,6 @@ import lombok.val;
 @NoArgsConstructor(access = AccessLevel.PRIVATE)
 final class Factories {
 
-    // -- CONTRIBUTED
-    
-    static Function<ObjectActionDefault, ObjectAssociation> contributeeAssociation(
-            final ManagedBeanAdapter serviceBean,
-            final ObjectSpecification contributeeType) {
-
-        return objectAction -> {
-            val returnType = objectAction.getReturnType();
-            if (returnType.isNotCollection()) {
-                return new OneToOneAssociationContributee(serviceBean, objectAction, contributeeType);
-            } 
-            return new OneToManyAssociationContributee(serviceBean, objectAction, contributeeType);
-            
-        };
-    }
-    
     // -- MIXINS
     
     static Function<ObjectActionDefault, ObjectActionMixedIn> mixedInAction(
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectActionDefault.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectActionDefault.java
index 3648295..7164b1c 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectActionDefault.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectActionDefault.java
@@ -31,7 +31,6 @@ import org.apache.isis.applib.RecoverableException;
 import org.apache.isis.applib.annotation.SemanticsOf;
 import org.apache.isis.applib.annotation.Where;
 import org.apache.isis.applib.services.command.Command;
-import org.apache.isis.applib.services.command.CommandContext;
 import org.apache.isis.core.commons.collections.Can;
 import org.apache.isis.core.commons.exceptions.UnknownTypeException;
 import org.apache.isis.core.commons.internal._Constants;
@@ -52,10 +51,12 @@ import org.apache.isis.core.metamodel.facets.actions.prototype.PrototypeFacet;
 import org.apache.isis.core.metamodel.facets.actions.semantics.ActionSemanticsFacet;
 import org.apache.isis.core.metamodel.facets.param.choices.ActionChoicesFacet;
 import org.apache.isis.core.metamodel.facets.param.choices.ActionParameterChoicesFacet;
+import org.apache.isis.core.metamodel.interactions.ActionArgValidityContext;
 import org.apache.isis.core.metamodel.interactions.ActionUsabilityContext;
 import org.apache.isis.core.metamodel.interactions.ActionValidityContext;
 import org.apache.isis.core.metamodel.interactions.ActionVisibilityContext;
 import org.apache.isis.core.metamodel.interactions.InteractionUtils;
+import org.apache.isis.core.metamodel.interactions.MemberInteractionHead;
 import org.apache.isis.core.metamodel.interactions.UsabilityContext;
 import org.apache.isis.core.metamodel.interactions.ValidityContext;
 import org.apache.isis.core.metamodel.interactions.VisibilityContext;
@@ -148,8 +149,8 @@ public class ObjectActionDefault extends ObjectMemberAbstract implements ObjectA
     }
 
     @Override
-    public PendingParameterModelHead newPendingParameterModelHead(@NonNull ManagedObject actionOwner) {
-        return PendingParameterModelHead.of(this, actionOwner, actionOwner);
+    public ActionInteractionHead newPendingParameterModelHead(@NonNull ManagedObject actionOwner) {
+        return ActionInteractionHead.of(this, actionOwner, actionOwner);
     }
     
     // -- Parameters
@@ -223,22 +224,22 @@ public class ObjectActionDefault extends ObjectMemberAbstract implements ObjectA
         return parameters.getElseFail(position);
     }
 
-
-
     // -- visable, usable
 
     @Override
     public VisibilityContext<?> createVisibleInteractionContext(
-            final ManagedObject targetObjectAdapter, final InteractionInitiatedBy interactionInitiatedBy,
+            final MemberInteractionHead head, 
+            final InteractionInitiatedBy interactionInitiatedBy,
             Where where) {
-        return new ActionVisibilityContext(targetObjectAdapter, this, getIdentifier(), interactionInitiatedBy, where);
+        return new ActionVisibilityContext(head, interactionInitiatedBy, where);
     }
 
     @Override
     public UsabilityContext<?> createUsableInteractionContext(
-            final ManagedObject targetObjectAdapter, final InteractionInitiatedBy interactionInitiatedBy,
+            final MemberInteractionHead head, 
+            final InteractionInitiatedBy interactionInitiatedBy,
             Where where) {
-        return new ActionUsabilityContext(targetObjectAdapter, this, getIdentifier(), interactionInitiatedBy, where);
+        return new ActionUsabilityContext(head, interactionInitiatedBy, where);
     }
 
 
@@ -258,16 +259,15 @@ public class ObjectActionDefault extends ObjectMemberAbstract implements ObjectA
      */
     @Override
     public Consent isProposedArgumentSetValid(
-            final ManagedObject targetObject,
-            final Can<ManagedObject> proposedArguments,
+            final PendingParameterModel pendingArgs,
             final InteractionInitiatedBy interactionInitiatedBy) {
 
         final InteractionResultSet resultSet = new InteractionResultSet();
 
-        validateArgumentsIndividually(targetObject, proposedArguments, interactionInitiatedBy, resultSet);
+        validateArgumentsIndividually(pendingArgs, interactionInitiatedBy, resultSet);
         if (resultSet.isAllowed()) {
             // only check the action's own validity if all the arguments are OK.
-            validateArgumentSet(targetObject, proposedArguments, interactionInitiatedBy, resultSet);
+            validateArgumentSet(pendingArgs, interactionInitiatedBy, resultSet);
         }
 
         return resultSet.createConsent();
@@ -288,33 +288,31 @@ public class ObjectActionDefault extends ObjectMemberAbstract implements ObjectA
      */
     @Override
     public Consent isEachIndividualArgumentValid(
-            final ManagedObject objectAdapter,
-            final Can<ManagedObject> proposedArguments,
+            final PendingParameterModel pendingArgs,
             final InteractionInitiatedBy interactionInitiatedBy) {
 
         final InteractionResultSet resultSet = new InteractionResultSet();
 
-        validateArgumentsIndividually(objectAdapter, proposedArguments, interactionInitiatedBy, resultSet);
+        validateArgumentsIndividually(pendingArgs, interactionInitiatedBy, resultSet);
 
         return resultSet.createConsent();
     }
 
     private void validateArgumentsIndividually(
-            final ManagedObject objectAdapter,
-            final Can<ManagedObject> proposedArguments,
+            final PendingParameterModel pendingArgs,
             final InteractionInitiatedBy interactionInitiatedBy,
             final InteractionResultSet resultSet) {
         
-        val actionParameters = getParameters();
-        if (proposedArguments != null) {
-            for (int i = 0; i < proposedArguments.size(); i++) {
-                final ValidityContext<?> ic = actionParameters.getElseFail(i)
-                        .createProposedArgumentInteractionContext(
-                                objectAdapter, proposedArguments, i, interactionInitiatedBy);
-                
-                InteractionUtils.isValidResultSet(getParameter(i), ic, resultSet);
-            }
+        val proposedArgs = pendingArgs.getParamValues();
+        
+        for (int i = 0; i < proposedArgs.size(); i++) {
+            
+            final ValidityContext<?> ic =
+                    new ActionArgValidityContext(pendingArgs, i, interactionInitiatedBy);
+            
+            InteractionUtils.isValidResultSet(getParameter(i), ic, resultSet);
         }
+        
     }
 
     /**
@@ -332,67 +330,54 @@ public class ObjectActionDefault extends ObjectMemberAbstract implements ObjectA
      */
     @Override
     public Consent isArgumentSetValid(
-            final ManagedObject objectAdapter,
-            final Can<ManagedObject> proposedArguments,
+            final PendingParameterModel pendingArgs,
             final InteractionInitiatedBy interactionInitiatedBy) {
 
         final InteractionResultSet resultSet = new InteractionResultSet();
-        validateArgumentSet(objectAdapter, proposedArguments, interactionInitiatedBy, resultSet);
+        validateArgumentSet(pendingArgs, interactionInitiatedBy, resultSet);
 
         return resultSet.createConsent();
     }
 
     protected void validateArgumentSet(
-            final ManagedObject objectAdapter,
-            final Can<ManagedObject> proposedArguments,
+            final PendingParameterModel pendingArgs,
             final InteractionInitiatedBy interactionInitiatedBy,
             final InteractionResultSet resultSet) {
         
-        final ValidityContext<?> ic = createActionInvocationInteractionContext(
-                objectAdapter, proposedArguments, interactionInitiatedBy);
+        final ValidityContext<?> ic = new ActionValidityContext(pendingArgs, interactionInitiatedBy);
         InteractionUtils.isValidResultSet(this, ic, resultSet);
     }
 
-    ActionValidityContext createActionInvocationInteractionContext(
-            final ManagedObject targetObject,
-            final Can<ManagedObject> proposedArguments,
-            final InteractionInitiatedBy interactionInitiatedBy) {
-        
-        return new ActionValidityContext(targetObject, this, getIdentifier(), proposedArguments,
-                interactionInitiatedBy);
-    }
-
-
 
     // -- executeWithRuleChecking, execute
 
     @Override
     public ManagedObject executeWithRuleChecking(
-            final ManagedObject target,
-            final ManagedObject mixedInAdapter,
-            final Can<ManagedObject> arguments,
+            final PendingParameterModel pendingArgs,
             final InteractionInitiatedBy interactionInitiatedBy,
             final Where where) {
 
+        val head = pendingArgs.getHead().toMemberInteractionHead();
+        
         // see it?
-        final Consent visibility = isVisible(target, interactionInitiatedBy, where);
+        final Consent visibility = isVisible(head, interactionInitiatedBy, where);
         if (visibility.isVetoed()) {
             throw new HiddenException();
         }
 
         // use it?
-        final Consent usability = isUsable(target, interactionInitiatedBy, where);
+        final Consent usability = isUsable(head, interactionInitiatedBy, where);
         if(usability.isVetoed()) {
             throw new DisabledException(usability.getReason());
         }
 
         // do it?
-        final Consent validity = isProposedArgumentSetValid(target, arguments, interactionInitiatedBy);
+        final Consent validity = isProposedArgumentSetValid(pendingArgs, interactionInitiatedBy);
         if(validity.isVetoed()) {
             throw new RecoverableException(validity.getReason());
         }
 
-        return execute(target, mixedInAdapter, arguments, interactionInitiatedBy);
+        return execute(pendingArgs, interactionInitiatedBy);
     }
 
     /**
@@ -400,32 +385,24 @@ public class ObjectActionDefault extends ObjectMemberAbstract implements ObjectA
      * {@link #executeInternal(ManagedObject, ManagedObject, List, InteractionInitiatedBy) executeInternal}
      * to invoke the {@link ActionInvocationFacet invocation facet}.
      *
-     * @param mixedInAdapter - will be null for regular actions, and for mixin actions.  When a mixin action invokes its underlying mixedIn action, then will be populated (so that the ActionDomainEvent can correctly provide the underlying mixin)
      */
     @Override
     public ManagedObject execute(
-            final ManagedObject targetAdapter,
-            final ManagedObject mixedInAdapter,
-            final Can<ManagedObject> argumentAdapters,
+            final PendingParameterModel pendingArgs,
             final InteractionInitiatedBy interactionInitiatedBy) {
 
-        setupCommand(targetAdapter, argumentAdapters);
-
-        return this.executeInternal(targetAdapter, mixedInAdapter, argumentAdapters, interactionInitiatedBy);
+        return this.executeInternal(pendingArgs, interactionInitiatedBy);
     }
 
     /**
      * private API, called by mixins and contributees.
      */
     public ManagedObject executeInternal(
-            final ManagedObject targetAdapter,
-            final ManagedObject mixedInAdapter,
-            final Can<ManagedObject> argumentAdapters,
+            final PendingParameterModel pendingArgs,
             final InteractionInitiatedBy interactionInitiatedBy) {
         
         val actionInvocationFacet = getFacet(ActionInvocationFacet.class);
-        return actionInvocationFacet
-                .invoke(this, targetAdapter, mixedInAdapter, argumentAdapters, interactionInitiatedBy);
+        return actionInvocationFacet.invoke(pendingArgs, interactionInitiatedBy);
     }
 
     protected ActionInvocationFacet getActionInvocationFacet() {
@@ -580,26 +557,6 @@ public class ObjectActionDefault extends ObjectMemberAbstract implements ObjectA
         return Can.ofCollection(parameterChoicesAdapters);
     }
 
-
-    //    /**
-    //     * Internal API
-    //     */
-    //    @Override
-    //    public void setupBulkActionInvocationContext(final ObjectAdapter targetAdapter) {
-    //
-    //        final Object targetPojo = ObjectAdapter.Util.unwrap(targetAdapter);
-    //
-    //        final BulkFacet bulkFacet = getFacetHolder().getFacet(BulkFacet.class);
-    //        if (bulkFacet != null) {
-    //            final org.apache.isis.applib.services.actinvoc.ActionInvocationContext actionInvocationContext = getActionInvocationContext();
-    //            if (actionInvocationContext != null && actionInvocationContext.getInvokedOn() == null) {
-    //
-    //                actionInvocationContext.setInvokedOn(InvokedOn.OBJECT);
-    //                actionInvocationContext.setDomainObjects(Collections.singletonList(targetPojo));
-    //            }
-    //        }
-    //    }
-
     @Override
     public boolean isPrototype() {
         return getType().isPrototype();
@@ -610,43 +567,40 @@ public class ObjectActionDefault extends ObjectMemberAbstract implements ObjectA
      * {@link ObjectActionMixedIn mixed-in} and {@link ObjectActionContributee contributee}).
      */
     public void setupCommand(
-            final ManagedObject targetAdapter,
-            final Can<ManagedObject> argumentAdapters) {
+            final PendingParameterModel pendingArgs) {
 
-        final CommandContext commandContext = getCommandContext();
-        final Command command = commandContext.getCommand();
+        val commandContext = getCommandContext();
+        val command = commandContext.getCommand();
 
         if (command.getExecutor() != Command.Executor.USER) {
             return;
         }
 
-        setupCommandTarget(targetAdapter, argumentAdapters);
+        setupCommandTarget(pendingArgs);
         setupCommandMemberIdentifier();
-        setupCommandMementoAndExecutionContext(targetAdapter, argumentAdapters);
+        setupCommandMementoAndExecutionContext(pendingArgs);
     }
 
     private void setupCommandTarget(
-            final ManagedObject targetAdapter,
-            final Can<ManagedObject> argumentAdapters) {
+            final PendingParameterModel pendingArgs) {
 
-        final String arguments = CommandUtil.argDescriptionFor(this, argumentAdapters.toList());
-        super.setupCommandTarget(targetAdapter, arguments);
+        final String stringifiedArgs = CommandUtil.argDescriptionFor(this, pendingArgs.getParamValues().toList());
+        super.setupCommandTarget(pendingArgs.getActionTarget(), stringifiedArgs);
     }
 
     private void setupCommandMementoAndExecutionContext(
-            final ManagedObject targetAdapter,
-            final Can<ManagedObject> argumentAdapters) {
+            final PendingParameterModel pendingArgs) {
 
         val commandDtoServiceInternal = getCommandDtoService();
         final List<ManagedObject> commandTargetAdapters =
                 commandTargetAdaptersHolder.get() != null
-                ? commandTargetAdaptersHolder.get()
-                        : Collections.singletonList(targetAdapter);
+                    ? commandTargetAdaptersHolder.get()
+                    : Collections.singletonList(pendingArgs.getActionTarget());
 
-                val commandDto = commandDtoServiceInternal.asCommandDto(
-                        commandTargetAdapters, this, argumentAdapters.toList());
+        val commandDto = commandDtoServiceInternal.asCommandDto(
+                commandTargetAdapters, this, pendingArgs.getParamValues().toList());
 
-                setupCommandDtoAndExecutionContext(commandDto);
+        setupCommandDtoAndExecutionContext(commandDto);
 
     }
 
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectActionMixedIn.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectActionMixedIn.java
index 1396c07..35ecd8c 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectActionMixedIn.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectActionMixedIn.java
@@ -23,6 +23,7 @@ import java.util.List;
 import org.apache.isis.applib.Identifier;
 import org.apache.isis.applib.annotation.Where;
 import org.apache.isis.core.commons.collections.Can;
+import org.apache.isis.core.commons.internal.assertions._Assert;
 import org.apache.isis.core.commons.internal.base._Strings;
 import org.apache.isis.core.commons.internal.collections._Lists;
 import org.apache.isis.core.metamodel.consent.Consent;
@@ -36,6 +37,7 @@ import org.apache.isis.core.metamodel.facets.FacetedMethodParameter;
 import org.apache.isis.core.metamodel.facets.TypedHolder;
 import org.apache.isis.core.metamodel.facets.all.named.NamedFacetInferred;
 import org.apache.isis.core.metamodel.interactions.InteractionUtils;
+import org.apache.isis.core.metamodel.interactions.MemberInteractionHead;
 import org.apache.isis.core.metamodel.interactions.UsabilityContext;
 import org.apache.isis.core.metamodel.interactions.ValidityContext;
 import org.apache.isis.core.metamodel.interactions.VisibilityContext;
@@ -137,8 +139,8 @@ public class ObjectActionMixedIn extends ObjectActionDefault implements MixedInM
     }
 
     @Override
-    public PendingParameterModelHead newPendingParameterModelHead(@NonNull ManagedObject actionOwner) {
-        return PendingParameterModelHead.of(this, actionOwner, mixinAdapterFor(actionOwner));
+    public ActionInteractionHead newPendingParameterModelHead(@NonNull ManagedObject actionOwner) {
+        return ActionInteractionHead.of(this, actionOwner, mixinAdapterFor(actionOwner));
     }
     
     @Override
@@ -171,7 +173,7 @@ public class ObjectActionMixedIn extends ObjectActionDefault implements MixedInM
 
     @Override
     public Consent isVisible(
-            final ManagedObject mixedInAdapter,
+            final MemberInteractionHead interactionHead,
             final InteractionInitiatedBy interactionInitiatedBy,
             final Where where) {
 
@@ -184,8 +186,9 @@ public class ObjectActionMixedIn extends ObjectActionDefault implements MixedInM
 
     @Override
     public Consent isUsable(
-            final ManagedObject mixedInAdapter,
-            final InteractionInitiatedBy interactionInitiatedBy, final Where where) {
+            final MemberInteractionHead interactionHead,
+            final InteractionInitiatedBy interactionInitiatedBy, 
+            final Where where) {
 
         final ManagedObject mixinAdapter = mixinAdapterFor(mixinType, mixedInAdapter);
         final UsabilityContext<?> ic =
@@ -214,11 +217,12 @@ public class ObjectActionMixedIn extends ObjectActionDefault implements MixedInM
 
     @Override
     protected void validateArgumentSet(
-            final ManagedObject mixedInAdapter,
-            final Can<ManagedObject> proposedArguments,
+            final PendingParameterModel pendingArgs,
             final InteractionInitiatedBy interactionInitiatedBy,
             final InteractionResultSet resultSet) {
 
+        assertIsMixin(pendingArgs);
+        
         final ManagedObject targetObject = mixinAdapterFor(mixinType, mixedInAdapter);
 
         final ValidityContext<?> ic =
@@ -228,29 +232,17 @@ public class ObjectActionMixedIn extends ObjectActionDefault implements MixedInM
         InteractionUtils.isValidResultSet(this, ic, resultSet);
     }
 
-
-
     @Override
     public ManagedObject execute(
-            final ManagedObject target,         // will be the mixedInAdapter
-            final ManagedObject mixedInAdapter, // will be passed in as null
-            final Can<ManagedObject> arguments,
+            final PendingParameterModel pendingArgs,
             final InteractionInitiatedBy interactionInitiatedBy) {
 
+        assertIsMixin(pendingArgs);
+        setupCommand(pendingArgs);
 
-        final ManagedObject targetAdapter = mixinAdapterFor(mixinType, target);
-        final ManagedObject actualMixedInAdapter = target;
-
-        setupCommand(actualMixedInAdapter, arguments);
-
-        return mixinAction.executeInternal(
-                targetAdapter, actualMixedInAdapter, arguments,
-                interactionInitiatedBy);
+        return mixinAction.executeInternal(pendingArgs, interactionInitiatedBy);
     }
 
-    /* (non-Javadoc)
-     * @see ObjectMemberAbstract#getIdentifier()
-     */
     @Override
     public Identifier getIdentifier() {
         return identifier;
@@ -262,5 +254,12 @@ public class ObjectActionMixedIn extends ObjectActionDefault implements MixedInM
 
     }
 
+    @Deprecated
+    private void assertIsMixin(PendingParameterModel pendingArgs) {
+        final ManagedObject targetAdapter = mixinAdapterFor(mixinType, pendingArgs.getActionOwner());
+        _Assert.assertEquals(targetAdapter, pendingArgs.getActionTarget());
+    }
+
+
 
 }
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectActionParameterAbstract.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectActionParameterAbstract.java
index dbf0a81..84a51a0 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectActionParameterAbstract.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectActionParameterAbstract.java
@@ -302,82 +302,40 @@ implements ObjectActionParameter, FacetHolder.Delegating {
     }
 
   
-    //region > Visibility
-
-    private ActionArgVisibilityContext createArgumentVisibilityContext(
-            final ManagedObject objectAdapter,
-            final Can<ManagedObject> pendingArgs,
-            final int position,
-            final InteractionInitiatedBy interactionInitiatedBy) {
-        
-        return new ActionArgVisibilityContext(
-                objectAdapter, parentAction, getIdentifier(), pendingArgs, position, interactionInitiatedBy);
-    }
+    // -- Visibility
 
     @Override
     public Consent isVisible(
-            final ManagedObject targetAdapter,
-            final Can<ManagedObject> pendingArgs,
+            final PendingParameterModel pendingArgs,
             final InteractionInitiatedBy interactionInitiatedBy) {
 
-        final VisibilityContext<?> ic = createArgumentVisibilityContext(
-                targetAdapter, pendingArgs, getNumber(), interactionInitiatedBy);
+        final VisibilityContext<?> ic = new ActionArgVisibilityContext(
+                pendingArgs, getNumber(), interactionInitiatedBy);
 
         final InteractionResult visibleResult = InteractionUtils.isVisibleResult(this, ic);
         return visibleResult.createConsent();
     }
 
-    //endregion
 
-    //region > Usability
-
-    private ActionArgUsabilityContext createArgumentUsabilityContext(
-            final ManagedObject objectAdapter,
-            final Can<ManagedObject> pendingArgs,
-            final int position,
-            final InteractionInitiatedBy interactionInitiatedBy) {
-        
-        return new ActionArgUsabilityContext(
-                objectAdapter, 
-                parentAction, 
-                getIdentifier(), 
-                pendingArgs, 
-                position, 
-                interactionInitiatedBy);
-    }
+    // -- Usability
 
     @Override
     public Consent isUsable(
-            final ManagedObject targetAdapter,
-            final Can<ManagedObject> pendingArgs,
+            final PendingParameterModel pendingArgs,
             final InteractionInitiatedBy interactionInitiatedBy) {
 
-        final UsabilityContext<?> ic = createArgumentUsabilityContext(
-                targetAdapter, pendingArgs, getNumber(), interactionInitiatedBy);
+        final UsabilityContext<?> ic = new ActionArgUsabilityContext(
+                pendingArgs, getNumber(), interactionInitiatedBy);
 
         final InteractionResult usableResult = InteractionUtils.isUsableResult(this, ic);
         return usableResult.createConsent();
     }
 
-    //endregion
-
-
     // -- Validation
 
     @Override
-    public ActionArgValidityContext createProposedArgumentInteractionContext(
-            final ManagedObject objectAdapter,
-            final Can<ManagedObject> proposedArguments,
-            final int position,
-            final InteractionInitiatedBy interactionInitiatedBy) {
-        
-        return new ActionArgValidityContext(
-                objectAdapter, parentAction, getIdentifier(), proposedArguments, position, interactionInitiatedBy);
-    }
-
-    @Override
     public String isValid(
-            final ManagedObject objectAdapter,
+            final PendingParameterModel pendingArgs,
             final Object proposedValue,
             final InteractionInitiatedBy interactionInitiatedBy) {
 
@@ -394,9 +352,8 @@ implements ObjectActionParameter, FacetHolder.Delegating {
             }
         }
 
-        val argumentAdapters = arguments(proposedValueAdapter);
-        final ValidityContext<?> ic = createProposedArgumentInteractionContext(
-                objectAdapter, argumentAdapters, getNumber(), interactionInitiatedBy);
+        final ValidityContext<?> ic = new ActionArgValidityContext(
+                pendingArgs, getNumber(), interactionInitiatedBy);
 
         final InteractionResultSet buf = new InteractionResultSet();
         InteractionUtils.isValidResultSet(this, ic, buf);
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectActionParameterMixedInAbstract.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectActionParameterMixedInAbstract.java
deleted file mode 100644
index 9c0ef0c..0000000
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectActionParameterMixedInAbstract.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *        http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- */
-package org.apache.isis.core.metamodel.specloader.specimpl;
-
-import org.apache.isis.core.commons.collections.Can;
-import org.apache.isis.core.metamodel.consent.InteractionInitiatedBy;
-import org.apache.isis.core.metamodel.facetapi.FeatureType;
-import org.apache.isis.core.metamodel.interactions.ActionArgValidityContext;
-import org.apache.isis.core.metamodel.spec.ManagedObject;
-
-import lombok.val;
-
-public abstract class ObjectActionParameterMixedInAbstract
-extends ObjectActionParameterAbstract
-implements ObjectActionParameterMixedIn {
-
-    private final ObjectActionMixedIn mixedInAction;
-
-    public ObjectActionParameterMixedInAbstract(
-            final FeatureType featureType, 
-            final ObjectActionParameterAbstract mixinParameter,
-            final ObjectActionMixedIn mixedInAction) {
-        
-        super(featureType, mixinParameter.getNumber(), mixedInAction, mixinParameter.getPeer());
-        this.mixedInAction = mixedInAction;
-    }
-
-    @Override
-    public ActionArgValidityContext createProposedArgumentInteractionContext(
-            final ManagedObject mixedInAdapter,
-            final Can<ManagedObject> proposedArguments,
-            final int position,
-            final InteractionInitiatedBy interactionInitiatedBy) {
-
-        val targetObject = mixedInAction.mixinAdapterFor(mixedInAdapter);
-
-        val actionArgValidityContext = new ActionArgValidityContext(
-                targetObject, mixedInAction.mixinAction, getIdentifier(), 
-                proposedArguments, position, interactionInitiatedBy);
-        actionArgValidityContext.setMixedIn(mixedInAdapter);
-        return actionArgValidityContext;
-    }
-
-}
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectMemberAbstract.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectMemberAbstract.java
index e0f7f33..5ceabe3 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectMemberAbstract.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectMemberAbstract.java
@@ -48,6 +48,7 @@ import org.apache.isis.core.metamodel.interactions.DisablingInteractionAdvisor;
 import org.apache.isis.core.metamodel.interactions.HidingInteractionAdvisor;
 import org.apache.isis.core.metamodel.interactions.InteractionContext;
 import org.apache.isis.core.metamodel.interactions.InteractionUtils;
+import org.apache.isis.core.metamodel.interactions.MemberInteractionHead;
 import org.apache.isis.core.metamodel.interactions.UsabilityContext;
 import org.apache.isis.core.metamodel.interactions.VisibilityContext;
 import org.apache.isis.core.metamodel.services.command.CommandDtoServiceInternal;
@@ -57,6 +58,7 @@ import org.apache.isis.core.metamodel.spec.feature.ObjectAction;
 import org.apache.isis.core.metamodel.spec.feature.ObjectMember;
 import org.apache.isis.schema.cmd.v2.CommandDto;
 
+import lombok.NonNull;
 import lombok.val;
 
 public abstract class ObjectMemberAbstract 
@@ -65,7 +67,7 @@ implements ObjectMember, MetaModelContext.Delegating, FacetHolder.Delegating {
     protected ObjectSpecification specificationOf(final Class<?> type) {
         return type != null 
                 ? getMetaModelContext().getSpecificationLoader().loadSpecification(type)
-                        : null;
+                : null;
     }
 
     // -- fields
@@ -158,7 +160,7 @@ implements ObjectMember, MetaModelContext.Delegating, FacetHolder.Delegating {
      * {@link AccessContext} accesses) have no corresponding vetoing methods.
      */
     protected abstract VisibilityContext<?> createVisibleInteractionContext(
-            final ManagedObject targetObjectAdapter,
+            final MemberInteractionHead head,
             final InteractionInitiatedBy interactionInitiatedBy,
             final Where where);
 
@@ -180,17 +182,17 @@ implements ObjectMember, MetaModelContext.Delegating, FacetHolder.Delegating {
      */
     @Override
     public Consent isVisible(
-            final ManagedObject target,
+            final MemberInteractionHead head,
             final InteractionInitiatedBy interactionInitiatedBy,
             final Where where) {
-        return isVisibleResult(target, interactionInitiatedBy, where).createConsent();
+        return isVisibleResult(head, interactionInitiatedBy, where).createConsent();
     }
 
     private InteractionResult isVisibleResult(
-            final ManagedObject target,
+            final MemberInteractionHead head,
             final InteractionInitiatedBy interactionInitiatedBy,
             final Where where) {
-        final VisibilityContext<?> ic = createVisibleInteractionContext(target, interactionInitiatedBy, where);
+        final VisibilityContext<?> ic = createVisibleInteractionContext(head, interactionInitiatedBy, where);
         return InteractionUtils.isVisibleResult(this, ic);
     }
 
@@ -207,7 +209,7 @@ implements ObjectMember, MetaModelContext.Delegating, FacetHolder.Delegating {
      * {@link AccessContext} accesses) have no corresponding vetoing methods.
      */
     protected abstract UsabilityContext<?> createUsableInteractionContext(
-            final ManagedObject target,
+            final MemberInteractionHead head,
             final InteractionInitiatedBy interactionInitiatedBy,
             final Where where);
 
@@ -217,17 +219,17 @@ implements ObjectMember, MetaModelContext.Delegating, FacetHolder.Delegating {
      */
     @Override
     public Consent isUsable(
-            final ManagedObject target,
+            final MemberInteractionHead head,
             final InteractionInitiatedBy interactionInitiatedBy,
             final Where where) {
-        return isUsableResult(target, interactionInitiatedBy, where).createConsent();
+        return isUsableResult(head, interactionInitiatedBy, where).createConsent();
     }
 
     private InteractionResult isUsableResult(
-            final ManagedObject target,
+            final MemberInteractionHead head,
             final InteractionInitiatedBy interactionInitiatedBy,
             final Where where) {
-        final UsabilityContext<?> ic = createUsableInteractionContext(target, interactionInitiatedBy, where);
+        final UsabilityContext<?> ic = createUsableInteractionContext(head, interactionInitiatedBy, where);
         return InteractionUtils.isUsableResult(this, ic);
     }
 
@@ -259,7 +261,7 @@ implements ObjectMember, MetaModelContext.Delegating, FacetHolder.Delegating {
     /**
      * For mixins
      */
-    ManagedObject mixinAdapterFor(
+    protected final ManagedObject mixinAdapterFor(
             final Class<?> mixinType,
             final ManagedObject mixedInAdapter) {
         
@@ -302,7 +304,7 @@ implements ObjectMember, MetaModelContext.Delegating, FacetHolder.Delegating {
         final int indexOfSeparator = singularName.lastIndexOf(separator);
         return occursNotAtEnd(singularName, indexOfSeparator)
                 ? singularName.substring(indexOfSeparator + 1)
-                        : singularName;
+                : singularName;
     }
 
     private static boolean occursNotAtEnd(final String singularName, final int indexOfUnderscore) {
@@ -406,4 +408,10 @@ implements ObjectMember, MetaModelContext.Delegating, FacetHolder.Delegating {
         return facetedMethod.getMetaModelContext();
     }
 
+    @Override
+    public MemberInteractionHead newInteractionHead(@NonNull ManagedObject memberOwner) {
+        return MemberInteractionHead.of(this, memberOwner, memberOwner);
+    }
+    
+    
 }
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/OneToManyAssociationContributee.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/OneToManyAssociationContributee.java
deleted file mode 100644
index b660b85..0000000
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/OneToManyAssociationContributee.java
+++ /dev/null
@@ -1,191 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *        http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- */
-package org.apache.isis.core.metamodel.specloader.specimpl;
-
-import java.util.List;
-
-import org.apache.isis.applib.Identifier;
-import org.apache.isis.applib.annotation.Where;
-import org.apache.isis.core.commons.collections.Can;
-import org.apache.isis.core.commons.internal.ioc.ManagedBeanAdapter;
-import org.apache.isis.core.metamodel.consent.Consent;
-import org.apache.isis.core.metamodel.consent.InteractionInitiatedBy;
-import org.apache.isis.core.metamodel.facetapi.FacetHolder;
-import org.apache.isis.core.metamodel.facetapi.FacetHolderImpl;
-import org.apache.isis.core.metamodel.facetapi.FacetUtil;
-import org.apache.isis.core.metamodel.facets.actcoll.typeof.TypeOfFacet;
-import org.apache.isis.core.metamodel.facets.actcoll.typeof.TypeOfFacetAbstract;
-import org.apache.isis.core.metamodel.facets.members.disabled.DisabledFacet;
-import org.apache.isis.core.metamodel.facets.members.disabled.DisabledFacetForContributee;
-import org.apache.isis.core.metamodel.facets.propcoll.notpersisted.NotPersistedFacet;
-import org.apache.isis.core.metamodel.facets.propcoll.notpersisted.NotPersistedFacetAbstract;
-import org.apache.isis.core.metamodel.interactions.InteractionUtils;
-import org.apache.isis.core.metamodel.interactions.UsabilityContext;
-import org.apache.isis.core.metamodel.interactions.VisibilityContext;
-import org.apache.isis.core.metamodel.spec.ManagedObject;
-import org.apache.isis.core.metamodel.spec.ObjectSpecification;
-import org.apache.isis.core.metamodel.spec.feature.ObjectAction;
-
-import lombok.Getter;
-import lombok.val;
-
-public class OneToManyAssociationContributee 
-extends OneToManyAssociationDefault implements ContributeeMember {
-
-    private final ManagedBeanAdapter serviceBean;
-    private final ObjectAction serviceAction;
-
-
-    /**
-     * Hold facets rather than delegate to the contributed action (different types might
-     * use layout metadata to position the contributee in different ways)
-     */
-    @Getter(onMethod = @__(@Override))
-    private final FacetHolder facetHolder = new FacetHolderImpl();
-
-    private final Identifier identifier;
-
-    private static ObjectSpecification typeOfSpec(final ObjectActionDefault objectAction) {
-
-        val actionTypeOfFacet = objectAction.getFacet(TypeOfFacet.class);
-        val specLoader = objectAction.getMetaModelContext().getSpecificationLoader();
-        // TODO: a bit of a hack; ought really to set up a fallback TypeOfFacetDefault which ensures that there is always
-        // a TypeOfFacet for any contributee associations created from contributed actions.
-        val type = actionTypeOfFacet != null? actionTypeOfFacet.value(): (Class)Object.class;
-        return specLoader.loadSpecification(type);
-    }
-
-    public OneToManyAssociationContributee(
-            final ManagedBeanAdapter serviceBean,
-            final ObjectActionDefault serviceAction,
-            final ObjectSpecification contributeeType) {
-
-        super(serviceAction.getFacetedMethod(),
-                typeOfSpec(serviceAction));
-        this.serviceBean = serviceBean;
-        this.serviceAction = serviceAction;
-
-        //
-        // ensure the contributed collection cannot be modified, and derive its TypeOfFaccet
-        //
-        final NotPersistedFacet notPersistedFacet = new NotPersistedFacetAbstract(this) {};
-        final DisabledFacet disabledFacet = disabledFacet();
-        final TypeOfFacet typeOfFacet = new TypeOfFacetAbstract(getSpecification().getCorrespondingClass(), this) {};
-
-        FacetUtil.addFacet(notPersistedFacet);
-        FacetUtil.addFacet(disabledFacet);
-        FacetUtil.addFacet(typeOfFacet);
-
-
-        //
-        // in addition, copy over facets from contributed to own.
-        //
-        // These could include everything under @Collection(...) because the
-        // CollectionAnnotationFacetFactory is also run against actions.
-        //
-        FacetUtil.copyFacets(serviceAction.getFacetedMethod(), facetHolder);
-
-
-        // calculate the identifier
-        final Identifier contributorIdentifier = serviceAction.getFacetedMethod().getIdentifier();
-        final String memberName = contributorIdentifier.getMemberName();
-        List<String> memberParameterNames = contributorIdentifier.getMemberParameterNames();
-
-        identifier = Identifier.actionIdentifier(contributeeType.getCorrespondingClass().getName(), memberName, memberParameterNames);
-    }
-
-    private DisabledFacet disabledFacet() {
-        final DisabledFacet originalFacet = facetHolder.getFacet(DisabledFacet.class);
-        if( originalFacet != null &&
-                originalFacet.where() == Where.ANYWHERE) {
-            return originalFacet;
-        }
-        // ensure that the contributed association is always disabled
-        return new DisabledFacetForContributee("Contributed collection", this);
-    }
-
-    @Override
-    public ManagedObject get(
-            final ManagedObject ownerAdapter, 
-            final InteractionInitiatedBy interactionInitiatedBy) {
-        
-        val params = Can.ofSingleton(ownerAdapter);
-        
-        return serviceAction.execute(getServiceAdapter(), /*mixin*/null, params, interactionInitiatedBy);
-    }
-
-    @Override
-    public ObjectSpecification getOnType() {
-        return serviceAction.getOnType();
-    }
-
-    @Override
-    public Identifier getIdentifier() {
-        return identifier;
-    }
-
-    @Override
-    public boolean isContributedBy(final ObjectAction serviceAction) {
-        return serviceAction == this.serviceAction;
-    }
-
-    @Override
-    public int getContributeeParamIndex() {
-        // always 0 for contributed collections
-        return 0;
-    }
-
-    @Override
-    public Consent isVisible(
-            final ManagedObject contributee,
-            final InteractionInitiatedBy interactionInitiatedBy,
-            Where where) {
-        final VisibilityContext<?> ic = ((ObjectMemberAbstract)serviceAction).createVisibleInteractionContext(
-                getServiceAdapter(), interactionInitiatedBy, where);
-        ic.putContributee(0, contributee); // by definition, the contributee will be the first arg of the service action
-        return InteractionUtils.isVisibleResult(this, ic).createConsent();
-    }
-
-    @Override
-    public Consent isUsable(
-            final ManagedObject contributee,
-            final InteractionInitiatedBy interactionInitiatedBy, final Where where) {
-        final ObjectMemberAbstract serviceAction = (ObjectMemberAbstract) this.serviceAction;
-        final UsabilityContext<?> ic = serviceAction.createUsableInteractionContext(
-                getServiceAdapter(), interactionInitiatedBy, where);
-        ic.putContributee(0, contributee); // by definition, the contributee will be the first arg of the service action
-        return InteractionUtils.isUsableResult(this, ic).createConsent();
-    }
-
-    // -- FacetHolder
-
-    private ManagedObject getServiceAdapter() {
-        return getObjectManager().adapt(serviceBean);
-    }
-
-    // -- ContributeeMember2 impl (getServiceContributedBy)
-
-    @Override
-    public ObjectSpecification getServiceContributedBy() {
-        return getServiceAdapter().getSpecification();
-    }
-
-
-
-}
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/OneToManyAssociationMixedIn.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/OneToManyAssociationMixedIn.java
index 99dbfc7..6a8eb0d 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/OneToManyAssociationMixedIn.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/OneToManyAssociationMixedIn.java
@@ -22,7 +22,6 @@ import java.util.List;
 
 import org.apache.isis.applib.Identifier;
 import org.apache.isis.applib.annotation.Where;
-import org.apache.isis.core.commons.collections.Can;
 import org.apache.isis.core.commons.internal.base._Strings;
 import org.apache.isis.core.metamodel.consent.Consent;
 import org.apache.isis.core.metamodel.consent.InteractionInitiatedBy;
@@ -37,6 +36,7 @@ import org.apache.isis.core.metamodel.facets.members.disabled.DisabledFacetForCo
 import org.apache.isis.core.metamodel.facets.propcoll.notpersisted.NotPersistedFacet;
 import org.apache.isis.core.metamodel.facets.propcoll.notpersisted.NotPersistedFacetAbstract;
 import org.apache.isis.core.metamodel.interactions.InteractionUtils;
+import org.apache.isis.core.metamodel.interactions.MemberInteractionHead;
 import org.apache.isis.core.metamodel.interactions.UsabilityContext;
 import org.apache.isis.core.metamodel.interactions.VisibilityContext;
 import org.apache.isis.core.metamodel.services.publishing.PublisherDispatchService;
@@ -45,6 +45,7 @@ import org.apache.isis.core.metamodel.spec.ObjectSpecification;
 import org.apache.isis.core.metamodel.spec.feature.ObjectAction;
 
 import lombok.Getter;
+import lombok.NonNull;
 import lombok.val;
 
 public class OneToManyAssociationMixedIn extends OneToManyAssociationDefault implements MixedInMember {
@@ -83,7 +84,7 @@ public class OneToManyAssociationMixedIn extends OneToManyAssociationDefault imp
         // created from mixin actions.
         val type = actionTypeOfFacet != null
                 ? actionTypeOfFacet.value()
-                : (Class)Object.class;
+                : (Class<?>)Object.class;
                 
         return objectAction.getSpecificationLoader().loadSpecification(type);
     }
@@ -150,10 +151,12 @@ public class OneToManyAssociationMixedIn extends OneToManyAssociationDefault imp
             final ManagedObject mixedInAdapter,
             final InteractionInitiatedBy interactionInitiatedBy) {
         
-        final ManagedObject mixinAdapter = mixinAdapterFor(mixinType, mixedInAdapter);
+        val pendingArgs = mixinAction
+                .newPendingParameterModelHead(mixedInAdapter)
+                .emptyModel();
+        
         return getPublishingServiceInternal().withPublishingSuppressed(
-                () -> mixinAction.executeInternal(
-                        mixinAdapter, mixedInAdapter, Can.empty(), interactionInitiatedBy));
+                () -> mixinAction.executeInternal(pendingArgs, interactionInitiatedBy));
     }
 
     @Override
@@ -173,7 +176,7 @@ public class OneToManyAssociationMixedIn extends OneToManyAssociationDefault imp
 
     @Override
     public Consent isVisible(
-            final ManagedObject mixedInAdapter,
+            final MemberInteractionHead interactionHead,
             final InteractionInitiatedBy interactionInitiatedBy,
             final Where where) {
 
@@ -186,7 +189,7 @@ public class OneToManyAssociationMixedIn extends OneToManyAssociationDefault imp
 
     @Override
     public Consent isUsable(
-            final ManagedObject mixedInAdapter,
+            final MemberInteractionHead interactionHead,
             final InteractionInitiatedBy interactionInitiatedBy,
             final Where where) {
 
@@ -216,6 +219,12 @@ public class OneToManyAssociationMixedIn extends OneToManyAssociationDefault imp
     private PublisherDispatchService getPublishingServiceInternal() {
         return getServiceRegistry().lookupServiceElseFail(PublisherDispatchService.class);
     }
+    
+    @Override
+    public MemberInteractionHead newMemberInteractionHead(@NonNull ManagedObject memberOwner) {
+        return MemberInteractionHead.of(this, memberOwner, mixinAdapterFor(mixinType, memberOwner));
+    }
+
 
 
 }
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/OneToOneActionParameterMixedIn.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/OneToOneActionParameterMixedIn.java
deleted file mode 100644
index 0697cd4..0000000
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/OneToOneActionParameterMixedIn.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *        http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- */
-package org.apache.isis.core.metamodel.specloader.specimpl;
-
-import org.apache.isis.core.metamodel.facetapi.FeatureType;
-import org.apache.isis.core.metamodel.spec.feature.OneToOneActionParameter;
-
-public class OneToOneActionParameterMixedIn
-extends ObjectActionParameterMixedInAbstract
-implements OneToOneActionParameter {
-
-    public OneToOneActionParameterMixedIn(
-            final ObjectActionParameterAbstract mixinParameter,
-            final ObjectActionMixedIn mixedInAction) {
-        super(FeatureType.ACTION_PARAMETER_SCALAR, mixinParameter, mixedInAction);
-    }
-
-
-}
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/OneToOneAssociationContributee.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/OneToOneAssociationContributee.java
deleted file mode 100644
index 75bb665..0000000
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/OneToOneAssociationContributee.java
+++ /dev/null
@@ -1,174 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *        http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- */
-package org.apache.isis.core.metamodel.specloader.specimpl;
-
-import java.util.List;
-
-import org.apache.isis.applib.Identifier;
-import org.apache.isis.applib.annotation.Where;
-import org.apache.isis.core.commons.collections.Can;
-import org.apache.isis.core.commons.internal.ioc.ManagedBeanAdapter;
-import org.apache.isis.core.metamodel.consent.Consent;
-import org.apache.isis.core.metamodel.consent.InteractionInitiatedBy;
-import org.apache.isis.core.metamodel.facetapi.FacetHolder;
-import org.apache.isis.core.metamodel.facetapi.FacetHolderImpl;
-import org.apache.isis.core.metamodel.facetapi.FacetUtil;
-import org.apache.isis.core.metamodel.facets.FacetedMethod;
-import org.apache.isis.core.metamodel.facets.members.disabled.DisabledFacet;
-import org.apache.isis.core.metamodel.facets.members.disabled.DisabledFacetForContributee;
-import org.apache.isis.core.metamodel.facets.propcoll.notpersisted.NotPersistedFacet;
-import org.apache.isis.core.metamodel.facets.propcoll.notpersisted.NotPersistedFacetAbstract;
-import org.apache.isis.core.metamodel.interactions.InteractionUtils;
-import org.apache.isis.core.metamodel.interactions.UsabilityContext;
-import org.apache.isis.core.metamodel.interactions.VisibilityContext;
-import org.apache.isis.core.metamodel.spec.ManagedObject;
-import org.apache.isis.core.metamodel.spec.ObjectSpecification;
-import org.apache.isis.core.metamodel.spec.feature.ObjectAction;
-
-import lombok.Getter;
-import lombok.val;
-
-public class OneToOneAssociationContributee 
-extends OneToOneAssociationDefault 
-implements ContributeeMember {
-
-    private final ManagedBeanAdapter serviceBean;
-    private final ObjectAction serviceAction;
-
-    /**
-     * Hold facets rather than delegate to the contributed action (different types might
-     * use layout metadata to position the contributee in different ways)
-     */
-    @Getter(onMethod = @__(@Override))
-    private final FacetHolder facetHolder = new FacetHolderImpl();
-
-    private final Identifier identifier;
-
-    public OneToOneAssociationContributee(
-            final ManagedBeanAdapter serviceBean,
-            final ObjectActionDefault serviceAction,
-            final ObjectSpecification contributeeType) {
-
-        super(serviceAction.getFacetedMethod(), serviceAction.getReturnType());
-
-        this.serviceBean = serviceBean;
-
-        this.serviceAction = serviceAction;
-
-        //
-        // ensure the contributed property cannot be modified
-        //
-        final NotPersistedFacet notPersistedFacet = new NotPersistedFacetAbstract(this) {};
-        final DisabledFacet disabledFacet = disabledFacet();
-
-        FacetUtil.addFacet(notPersistedFacet);
-        FacetUtil.addFacet(disabledFacet);
-
-        //
-        // in addition, copy over facets from contributed to own.
-        //
-        // These could include everything under @Property(...) because the
-        // PropertyAnnotationFacetFactory is also run against actions.
-        //
-        final FacetedMethod contributor = serviceAction.getFacetedMethod();
-        FacetUtil.copyFacets(contributor, facetHolder);
-
-        // calculate the identifier
-        final Identifier contributorIdentifier = contributor.getIdentifier();
-        final String memberName = contributorIdentifier.getMemberName();
-        List<String> memberParameterNames = contributorIdentifier.getMemberParameterNames();
-
-        identifier = Identifier.actionIdentifier(contributeeType.getCorrespondingClass().getName(), memberName, memberParameterNames);
-    }
-
-    private DisabledFacet disabledFacet() {
-        final DisabledFacet originalFacet = facetHolder.getFacet(DisabledFacet.class);
-        if( originalFacet != null &&
-                originalFacet.where() == Where.ANYWHERE) {
-            return originalFacet;
-        }
-        // ensure that the contributed association is always disabled
-        return new DisabledFacetForContributee("Contributed property", this);
-    }
-
-    @Override
-    public ManagedObject get(
-            final ManagedObject ownerAdapter, 
-            final InteractionInitiatedBy interactionInitiatedBy) {
-        
-        val params = Can.ofSingleton(ownerAdapter);
-        
-        return serviceAction.execute(getServiceAdapter(), /*mixin*/null, params, interactionInitiatedBy);
-    }
-
-    @Override
-    public ObjectSpecification getOnType() {
-        return serviceAction.getOnType();
-    }
-
-    @Override
-    public Identifier getIdentifier() {
-        return identifier;
-    }
-
-    @Override
-    public boolean isContributedBy(final ObjectAction serviceAction) {
-        return serviceAction == this.serviceAction;
-    }
-
-    @Override
-    public int getContributeeParamIndex() {
-        // always 0 for contributed properties
-        return 0;
-    }
-
-    @Override
-    public Consent isVisible(
-            final ManagedObject contributee,
-            final InteractionInitiatedBy interactionInitiatedBy,
-            Where where) {
-        final VisibilityContext<?> ic = ((ObjectMemberAbstract)serviceAction).createVisibleInteractionContext(
-                getServiceAdapter(), interactionInitiatedBy, where);
-        ic.putContributee(0, contributee); // by definition, the contributee will be the first arg of the service action
-        return InteractionUtils.isVisibleResult(this, ic).createConsent();
-    }
-
-    @Override
-    public Consent isUsable(
-            final ManagedObject contributee,
-            final InteractionInitiatedBy interactionInitiatedBy, final Where where) {
-        final UsabilityContext<?> ic = ((ObjectMemberAbstract)serviceAction).createUsableInteractionContext(
-                getServiceAdapter(), interactionInitiatedBy, where);
-        ic.putContributee(0, contributee); // by definition, the contributee will be the first arg of the service action
-        return InteractionUtils.isUsableResult(this, ic).createConsent();
-    }
-
-    private ManagedObject getServiceAdapter() {
-        return getObjectManager().adapt(serviceBean);
-    }
-
-    // -- Contributee impl - getServiceContributedBy()
-    @Override
-    public ObjectSpecification getServiceContributedBy() {
-        return getServiceAdapter().getSpecification();
-    }
-
-
-
-}
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/OneToOneAssociationDefault.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/OneToOneAssociationDefault.java
index a8c4b49..58bcbb9 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/OneToOneAssociationDefault.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/OneToOneAssociationDefault.java
@@ -44,6 +44,7 @@ import org.apache.isis.core.metamodel.facets.properties.update.clear.PropertyCle
 import org.apache.isis.core.metamodel.facets.properties.update.init.PropertyInitializationFacet;
 import org.apache.isis.core.metamodel.facets.properties.update.modify.PropertySetterFacet;
 import org.apache.isis.core.metamodel.interactions.InteractionUtils;
+import org.apache.isis.core.metamodel.interactions.MemberInteractionHead;
 import org.apache.isis.core.metamodel.interactions.PropertyModifyContext;
 import org.apache.isis.core.metamodel.interactions.PropertyUsabilityContext;
 import org.apache.isis.core.metamodel.interactions.PropertyVisibilityContext;
@@ -76,7 +77,8 @@ public class OneToOneAssociationDefault extends ObjectAssociationAbstract implem
 
     @Override
     public VisibilityContext<?> createVisibleInteractionContext(
-            final ManagedObject ownerAdapter, final InteractionInitiatedBy interactionInitiatedBy,
+            final MemberInteractionHead interactionHead, 
+            final InteractionInitiatedBy interactionInitiatedBy,
             Where where) {
         return new PropertyVisibilityContext(ownerAdapter, getIdentifier(), interactionInitiatedBy, where);
     }
@@ -84,7 +86,8 @@ public class OneToOneAssociationDefault extends ObjectAssociationAbstract implem
 
     @Override
     public UsabilityContext<?> createUsableInteractionContext(
-            final ManagedObject ownerAdapter, final InteractionInitiatedBy interactionInitiatedBy,
+            final MemberInteractionHead interactionHead, 
+            final InteractionInitiatedBy interactionInitiatedBy,
             Where where) {
         return new PropertyUsabilityContext(ownerAdapter, getIdentifier(), interactionInitiatedBy, where);
     }
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/OneToOneAssociationMixedIn.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/OneToOneAssociationMixedIn.java
index e881f94..85aac3f 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/OneToOneAssociationMixedIn.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/OneToOneAssociationMixedIn.java
@@ -35,6 +35,7 @@ import org.apache.isis.core.metamodel.facets.members.disabled.DisabledFacetForCo
 import org.apache.isis.core.metamodel.facets.propcoll.notpersisted.NotPersistedFacet;
 import org.apache.isis.core.metamodel.facets.propcoll.notpersisted.NotPersistedFacetAbstract;
 import org.apache.isis.core.metamodel.interactions.InteractionUtils;
+import org.apache.isis.core.metamodel.interactions.MemberInteractionHead;
 import org.apache.isis.core.metamodel.interactions.UsabilityContext;
 import org.apache.isis.core.metamodel.interactions.VisibilityContext;
 import org.apache.isis.core.metamodel.services.publishing.PublisherDispatchService;
@@ -43,6 +44,7 @@ import org.apache.isis.core.metamodel.spec.ObjectSpecification;
 import org.apache.isis.core.metamodel.spec.feature.ObjectAction;
 
 import lombok.Getter;
+import lombok.NonNull;
 import lombok.val;
 
 public class OneToOneAssociationMixedIn extends OneToOneAssociationDefault implements MixedInMember {
@@ -134,11 +136,12 @@ public class OneToOneAssociationMixedIn extends OneToOneAssociationDefault imple
             final ManagedObject mixedInAdapter,
             final InteractionInitiatedBy interactionInitiatedBy) {
 
-        val mixinAdapter = mixinAdapterFor(mixinType, mixedInAdapter);
-
+        val pendingArgs = mixinAction
+                .newPendingParameterModelHead(mixedInAdapter)
+                .emptyModel();
+        
         return getPublisherDispatchService().withPublishingSuppressed(
-                () -> mixinAction.executeInternal(
-                        mixinAdapter, mixedInAdapter, Can.empty(), interactionInitiatedBy)
+                () -> mixinAction.executeInternal(pendingArgs, interactionInitiatedBy)
         );
     }
 
@@ -159,7 +162,7 @@ public class OneToOneAssociationMixedIn extends OneToOneAssociationDefault imple
 
     @Override
     public Consent isVisible(
-            final ManagedObject mixedInAdapter,
+            final MemberInteractionHead interactionHead,
             final InteractionInitiatedBy interactionInitiatedBy,
             final Where where) {
 
@@ -172,7 +175,7 @@ public class OneToOneAssociationMixedIn extends OneToOneAssociationDefault imple
 
     @Override
     public Consent isUsable(
-            final ManagedObject mixedInAdapter,
+            final MemberInteractionHead interactionHead,
             final InteractionInitiatedBy interactionInitiatedBy,
             final Where where) {
 
@@ -202,5 +205,9 @@ public class OneToOneAssociationMixedIn extends OneToOneAssociationDefault imple
         return getServiceRegistry().lookupServiceElseFail(PublisherDispatchService.class);
     }
 
+    @Override
+    public MemberInteractionHead newMemberInteractionHead(@NonNull ManagedObject memberOwner) {
+        return MemberInteractionHead.of(this, memberOwner, mixinAdapterFor(mixinType, memberOwner));
+    }
 
 }
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/PendingParameterModel.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/PendingParameterModel.java
index 522462f..4f537c4 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/PendingParameterModel.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/PendingParameterModel.java
@@ -20,6 +20,7 @@ package org.apache.isis.core.metamodel.specloader.specimpl;
 
 import org.apache.isis.core.commons.collections.Can;
 import org.apache.isis.core.metamodel.spec.ManagedObject;
+import org.apache.isis.core.metamodel.spec.feature.ObjectAction;
 
 import lombok.Getter;
 import lombok.NonNull;
@@ -34,16 +35,24 @@ import lombok.RequiredArgsConstructor;
 @RequiredArgsConstructor(staticName = "of")
 public class PendingParameterModel {
 
-    @NonNull private final PendingParameterModelHead head;
+    @NonNull private final ActionInteractionHead head;
     @NonNull private final Can<ManagedObject> paramValues;
 
     // -- SHORTCUTS
     
-    @NonNull public ManagedObject getActionTarget() {
+    public @NonNull ObjectAction getAction() {
+        return getHead().getAction();
+    }
+    
+    public @NonNull ManagedObject getActionOwner() {
+        return getHead().getActionOwner();
+    }
+    
+    public @NonNull ManagedObject getActionTarget() {
         return getHead().getActionTarget();
     }
 
-    @NonNull public ManagedObject getParamValue(int paramNum) {
+    public @NonNull ManagedObject getParamValue(int paramNum) {
         return paramValues.getElseFail(paramNum);
     }
 
diff --git a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/command/CommandExecutorServiceDefault.java b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/command/CommandExecutorServiceDefault.java
index 926ad19..f134a75 100644
--- a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/command/CommandExecutorServiceDefault.java
+++ b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/command/CommandExecutorServiceDefault.java
@@ -182,15 +182,13 @@ public class CommandExecutorServiceDefault implements CommandExecutorService {
 
             for (OidDto targetOidDto : targetOidDtos) {
 
-                val targetAdapter = adapterFor(targetOidDto);
-                final ObjectAction objectAction = findObjectAction(targetAdapter, memberId);
+                val actionOwner = adapterFor(targetOidDto);
+                val objectAction = findObjectAction(actionOwner, memberId);
+                
+                val pentingArgs = objectAction.newPendingParameterModelHead(actionOwner)
+                        .model(argAdaptersFor(actionDto));
 
-                // we pass 'null' for the mixedInAdapter; if this action _is_ a mixin then
-                // it will switch the targetAdapter to be the mixedInAdapter transparently
-                val argAdapters = argAdaptersFor(actionDto);
-
-                val resultAdapter = objectAction.execute(
-                        targetAdapter, null, argAdapters, InteractionInitiatedBy.FRAMEWORK);
+                val resultAdapter = objectAction.execute(pentingArgs, InteractionInitiatedBy.FRAMEWORK);
 
                 // flush any Isis PersistenceCommands pending
                 // (else might get transient objects for the return value)
diff --git a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/wrapper/handlers/DomainObjectInvocationHandler.java b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/wrapper/handlers/DomainObjectInvocationHandler.java
index 907ddb2..d05e722 100644
--- a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/wrapper/handlers/DomainObjectInvocationHandler.java
+++ b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/wrapper/handlers/DomainObjectInvocationHandler.java
@@ -645,9 +645,10 @@ public class DomainObjectInvocationHandler<T> extends DelegatingInvocationHandle
         return runExecutionTask(()->{
 
             val interactionInitiatedBy = getInteractionInitiatedBy();
-            val mixedInAdapter = (ManagedObject)null; // if a mixin action, then it will automatically fill in.
-            val returnedAdapter = objectAction.execute(
-                    targetAdapter, mixedInAdapter, argAdapters,
+            val pentingArgs = objectAction.newPendingParameterModelHead(targetAdapter)
+                    .model(argAdapters);
+            
+            val returnedAdapter = objectAction.execute(pentingArgs,
                     interactionInitiatedBy);
             return ManagedObject.unwrapSingle(returnedAdapter);
             
diff --git a/incubator/viewers/vaadin/ui/src/main/java/org/apache/isis/incubator/viewer/vaadin/ui/pages/main/MainView.java b/incubator/viewers/vaadin/ui/src/main/java/org/apache/isis/incubator/viewer/vaadin/ui/pages/main/MainView.java
index dd83715..beee775 100644
--- a/incubator/viewers/vaadin/ui/src/main/java/org/apache/isis/incubator/viewer/vaadin/ui/pages/main/MainView.java
+++ b/incubator/viewers/vaadin/ui/src/main/java/org/apache/isis/incubator/viewer/vaadin/ui/pages/main/MainView.java
@@ -34,6 +34,7 @@ import com.vaadin.flow.theme.lumo.Lumo;
 import org.apache.isis.core.commons.collections.Can;
 import org.apache.isis.core.metamodel.consent.InteractionInitiatedBy;
 import org.apache.isis.core.metamodel.context.MetaModelContext;
+import org.apache.isis.core.metamodel.specloader.specimpl.PendingParameterModel;
 import org.apache.isis.core.webapp.context.IsisWebAppCommonContext;
 import org.apache.isis.incubator.viewer.vaadin.model.action.ActionVaa;
 import org.apache.isis.incubator.viewer.vaadin.ui.components.UiComponentFactoryVaa;
@@ -102,12 +103,12 @@ implements BeforeEnterObserver {
 
         val objectAction = menuActionModel.getObjectAction();
         val actionOwner = menuActionModel.getActionHolder().getManagedObject();
+        val pendingArgs = objectAction.newPendingParameterModelHead(actionOwner)
+                .model(Can.empty());
 
         val result = objectAction
                 .execute(
-                        actionOwner,
-                        null,
-                        Can.empty(),
+                        pendingArgs,
                         InteractionInitiatedBy.USER
                         );
 
diff --git a/persistence/jdo/datanucleus-5/src/test/java/org/apache/isis/core/runtime/system/ObjectMemberAbstractTest.java b/persistence/jdo/datanucleus-5/src/test/java/org/apache/isis/core/runtime/system/ObjectMemberAbstractTest.java
index 4598fbd..a78a062 100644
--- a/persistence/jdo/datanucleus-5/src/test/java/org/apache/isis/core/runtime/system/ObjectMemberAbstractTest.java
+++ b/persistence/jdo/datanucleus-5/src/test/java/org/apache/isis/core/runtime/system/ObjectMemberAbstractTest.java
@@ -20,6 +20,7 @@
 package org.apache.isis.core.runtime.system;
 
 import java.util.Optional;
+import java.util.stream.Stream;
 
 import org.datanucleus.enhancement.Persistable;
 import org.jmock.Expectations;
@@ -44,6 +45,7 @@ import org.apache.isis.core.metamodel.adapter.oid.Oid.Factory;
 import org.apache.isis.core.metamodel.consent.Consent;
 import org.apache.isis.core.metamodel.consent.InteractionInitiatedBy;
 import org.apache.isis.core.metamodel.context.MetaModelContext;
+import org.apache.isis.core.metamodel.facetapi.Facet;
 import org.apache.isis.core.metamodel.facetapi.FacetHolder;
 import org.apache.isis.core.metamodel.facetapi.FeatureType;
 import org.apache.isis.core.metamodel.facets.FacetedMethod;
@@ -53,6 +55,7 @@ import org.apache.isis.core.metamodel.facets.members.hidden.HiddenFacetAbstract;
 import org.apache.isis.core.metamodel.facets.members.hidden.HiddenFacetAbstractAlwaysEverywhere;
 import org.apache.isis.core.metamodel.facets.members.hidden.HiddenFacetAbstractImpl;
 import org.apache.isis.core.metamodel.facets.members.hidden.method.HideForContextFacetNone;
+import org.apache.isis.core.metamodel.interactions.MemberInteractionHead;
 import org.apache.isis.core.metamodel.interactions.PropertyUsabilityContext;
 import org.apache.isis.core.metamodel.interactions.PropertyVisibilityContext;
 import org.apache.isis.core.metamodel.interactions.UsabilityContext;
@@ -65,6 +68,9 @@ import org.apache.isis.core.metamodel.specloader.specimpl.ObjectMemberAbstract;
 import org.apache.isis.core.security.authentication.AuthenticationSession;
 import org.apache.isis.core.security.authentication.AuthenticationSessionTracker;
 import org.apache.isis.persistence.jdo.datanucleus5.objectadapter.PojoAdapter;
+
+import lombok.NonNull;
+
 import org.apache.isis.core.internaltestsupport.jmocking.JUnitRuleMockery2;
 import org.apache.isis.core.internaltestsupport.jmocking.JUnitRuleMockery2.Mode;
 
@@ -215,7 +221,8 @@ class ObjectMemberAbstractImpl extends ObjectMemberAbstract {
 
     @Override
     public UsabilityContext<?> createUsableInteractionContext(
-            final ManagedObject target, final InteractionInitiatedBy interactionInitiatedBy,
+            final ManagedObject target, 
+            final InteractionInitiatedBy interactionInitiatedBy,
             Where where) {
         return new PropertyUsabilityContext(target, getIdentifier(), interactionInitiatedBy, where);
     }
@@ -229,4 +236,5 @@ class ObjectMemberAbstractImpl extends ObjectMemberAbstract {
     }
 
 
+
 }
diff --git a/viewers/common/src/main/java/org/apache/isis/viewer/common/model/action/form/FormPendingParamUiModel.java b/viewers/common/src/main/java/org/apache/isis/viewer/common/model/action/form/FormPendingParamUiModel.java
index 8c9a4d9..b93d85b 100644
--- a/viewers/common/src/main/java/org/apache/isis/viewer/common/model/action/form/FormPendingParamUiModel.java
+++ b/viewers/common/src/main/java/org/apache/isis/viewer/common/model/action/form/FormPendingParamUiModel.java
@@ -24,10 +24,13 @@ import org.apache.isis.core.metamodel.spec.ManagedObject;
 import org.apache.isis.core.metamodel.specloader.specimpl.PendingParameterModel;
 import org.apache.isis.viewer.common.model.feature.ParameterUiModel;
 
-import lombok.Value;
+import lombok.AccessLevel;
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
 import lombok.val;
 
-@Value(staticConstructor = "of")
+@Getter
+@RequiredArgsConstructor(staticName = "of", access = AccessLevel.PRIVATE)
 public class FormPendingParamUiModel {
     
     final ParameterUiModel paramModel;
diff --git a/viewers/common/src/main/java/org/apache/isis/viewer/common/model/action/form/FormUiModel.java b/viewers/common/src/main/java/org/apache/isis/viewer/common/model/action/form/FormUiModel.java
index b05a2ca..1dca692 100644
--- a/viewers/common/src/main/java/org/apache/isis/viewer/common/model/action/form/FormUiModel.java
+++ b/viewers/common/src/main/java/org/apache/isis/viewer/common/model/action/form/FormUiModel.java
@@ -27,7 +27,7 @@ import org.apache.isis.core.metamodel.consent.InteractionInitiatedBy;
 import org.apache.isis.core.metamodel.spec.ManagedObject;
 import org.apache.isis.core.metamodel.spec.ManagedObjects;
 import org.apache.isis.core.metamodel.spec.feature.ObjectAction;
-import org.apache.isis.core.metamodel.specloader.specimpl.PendingParameterModelHead;
+import org.apache.isis.core.metamodel.specloader.specimpl.ActionInteractionHead;
 import org.apache.isis.viewer.common.model.HasTitle;
 import org.apache.isis.viewer.common.model.feature.ParameterUiModel;
 
@@ -40,7 +40,7 @@ public interface FormUiModel extends HasTitle {
     /** action's owner
      * @apiNote for mixins this is not the target to use on mixin actions
      * instead the logic of resolving the target for action invocation is 
-     * encapsulated within the {@link PendingParameterModelHead}
+     * encapsulated within the {@link ActionInteractionHead}
      */
     ManagedObject getOwner();
     
@@ -107,4 +107,8 @@ public interface FormUiModel extends HasTitle {
         return getMetaModel().getParameterCount() > 0;
     }
     
+    default ActionInteractionHead getPendingParamHead() {
+        return getMetaModel().newPendingParameterModelHead(getOwner());
+    }
+    
 }
diff --git a/viewers/common/src/main/java/org/apache/isis/viewer/common/model/feature/ParameterUiModel.java b/viewers/common/src/main/java/org/apache/isis/viewer/common/model/feature/ParameterUiModel.java
index 098766d..a81d369 100644
--- a/viewers/common/src/main/java/org/apache/isis/viewer/common/model/feature/ParameterUiModel.java
+++ b/viewers/common/src/main/java/org/apache/isis/viewer/common/model/feature/ParameterUiModel.java
@@ -23,7 +23,7 @@ import org.apache.isis.core.metamodel.consent.InteractionInitiatedBy;
 import org.apache.isis.core.metamodel.spec.ManagedObject;
 import org.apache.isis.core.metamodel.spec.feature.ObjectActionParameter;
 import org.apache.isis.core.metamodel.specloader.specimpl.PendingParameterModel;
-import org.apache.isis.core.metamodel.specloader.specimpl.PendingParameterModelHead;
+import org.apache.isis.core.metamodel.specloader.specimpl.ActionInteractionHead;
 
 public interface ParameterUiModel extends ScalarUiModel {
 
@@ -81,7 +81,7 @@ public interface ParameterUiModel extends ScalarUiModel {
         return getMetaModel().getAutoComplete(getPendingParameterModel(), searchArg, InteractionInitiatedBy.USER);
     }
 
-    default PendingParameterModelHead getPendingParamHead() {
+    default ActionInteractionHead getPendingParamHead() {
         return getMetaModel().getAction().newPendingParameterModelHead(getOwner());
     }
     
diff --git a/viewers/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/ActionModel.java b/viewers/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/ActionModel.java
index f752d64..4381f22 100644
--- a/viewers/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/ActionModel.java
+++ b/viewers/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/ActionModel.java
@@ -55,7 +55,7 @@ import org.apache.isis.core.metamodel.spec.ObjectSpecification;
 import org.apache.isis.core.metamodel.spec.feature.ObjectAction;
 import org.apache.isis.core.metamodel.spec.feature.ObjectActionParameter;
 import org.apache.isis.core.metamodel.specloader.specimpl.PendingParameterModel;
-import org.apache.isis.core.metamodel.specloader.specimpl.PendingParameterModelHead;
+import org.apache.isis.core.metamodel.specloader.specimpl.ActionInteractionHead;
 import org.apache.isis.core.webapp.context.IsisWebAppCommonContext;
 import org.apache.isis.viewer.common.model.action.form.FormPendingParamUiModel;
 import org.apache.isis.viewer.common.model.action.form.FormUiModel;
@@ -105,6 +105,17 @@ implements FormUiModel, FormExecutorContext {
         return getPageParametersWithoutUiHints();
     }
 
+    /**
+     * Bookmarkable if the {@link ObjectAction action} has a {@link BookmarkPolicyFacet bookmark} policy
+     * of {@link BookmarkPolicy#AS_ROOT root}, and has safe {@link ObjectAction#getSemantics() semantics}.
+     */
+    public boolean isBookmarkable() {
+        final ObjectAction action = getMetaModel();
+        final BookmarkPolicyFacet bookmarkPolicy = action.getFacet(BookmarkPolicyFacet.class);
+        final boolean safeSemantics = action.getSemantics().isSafeInNature();
+        return bookmarkPolicy.value() == BookmarkPolicy.AS_ROOT && safeSemantics;
+    }
+    
     // --
     
     private transient ObjectAction objectAction;
@@ -126,6 +137,11 @@ implements FormUiModel, FormExecutorContext {
         return entityModel;
     }
 
+    @Override
+    public ManagedObject getOwner() {
+        return getParentUiModel().getManagedObject();
+    }
+
     // -- HELPERS
 
     private final EntityModel entityModel;
@@ -160,22 +176,12 @@ implements FormUiModel, FormExecutorContext {
         this.actionMemento = actionModel.actionMemento;
         this.argCache = actionModel.argCache().copy(); 
     }
-
-    @Override
-    public ManagedObject getOwner() {
-        return entityModel.load();
-    }
-
+    
     @Override
     protected ManagedObject load() {
-
         // from getObject()/reExecute
         detach(); // force re-execute
-
-        // TODO: think we need another field to determine if args have been populated.
-        val results = executeAction();
-
-        return results;
+        return executeAction();
     }
 
     // REVIEW: should provide this rendering context, rather than hardcoding.
@@ -187,15 +193,9 @@ implements FormUiModel, FormExecutorContext {
 
     private ManagedObject executeAction() {
 
-        val targetAdapter = getOwner();
-        final Can<ManagedObject> arguments = argCache().snapshot();
-        final ObjectAction action = getMetaModel();
+        val pendingArgs = getArgumentsAsParamModel();
 
-        // if this action is a mixin, then it will fill in the details automatically.
-        val mixedInAdapter = (ManagedObject)null;
-        val resultAdapter =
-                action.executeWithRuleChecking(
-                        targetAdapter, mixedInAdapter, arguments,
+        val resultAdapter = getMetaModel().executeWithRuleChecking(pendingArgs,
                         InteractionInitiatedBy.USER,
                         WHERE_FOR_ACTION_INVOCATION);
 
@@ -219,35 +219,25 @@ implements FormUiModel, FormExecutorContext {
         throw new UnsupportedOperationException("target adapter for ActionModel cannot be changed");
     }
 
-    public PendingParameterModel getArgumentsAsParamModel() {
-        return getMetaModel().newPendingParameterModelHead(getOwner())
+    private PendingParameterModel getArgumentsAsParamModel() {
+        return getPendingParamHead()
                 .model(argCache().snapshot());
     }
 
 
     /** Resets arguments to their fixed point default values
-     * @see {@link PendingParameterModelHead#defaults()}
+     * @see {@link ActionInteractionHead#defaults()}
      */
     public void clearArguments() {
 
-        val defaultsFixedPoint = getMetaModel()
-                .newPendingParameterModelHead(getOwner())
+        val defaultsFixedPoint = getPendingParamHead()
                 .defaults()
                 .getParamValues();
 
         argCache().resetTo(defaultsFixedPoint);
     }
 
-    /**
-     * Bookmarkable if the {@link ObjectAction action} has a {@link BookmarkPolicyFacet bookmark} policy
-     * of {@link BookmarkPolicy#AS_ROOT root}, and has safe {@link ObjectAction#getSemantics() semantics}.
-     */
-    public boolean isBookmarkable() {
-        final ObjectAction action = getMetaModel();
-        final BookmarkPolicyFacet bookmarkPolicy = action.getFacet(BookmarkPolicyFacet.class);
-        final boolean safeSemantics = action.getSemantics().isSafeInNature();
-        return bookmarkPolicy.value() == BookmarkPolicy.AS_ROOT && safeSemantics;
-    }
+
 
     // //////////////////////////////////////