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:44 UTC

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

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;
-    }
+
 
     // //////////////////////////////////////