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/04 18:01:57 UTC

[isis] branch master updated: ISIS-2319: proposed fix

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

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


The following commit(s) were added to refs/heads/master by this push:
     new 9136cf0  ISIS-2319: proposed fix
9136cf0 is described below

commit 9136cf0a17355d70d5238cd1db2ba2c3e36e2afc
Author: Andi Huber <ah...@apache.org>
AuthorDate: Mon May 4 20:01:40 2020 +0200

    ISIS-2319: proposed fix
    
    moves even more responsibility from components to model
---
 .../wicket/model/models/ActionArgumentModel.java   |  11 ++
 .../viewer/wicket/model/models/ActionModel.java    | 151 +++++++++++++-----
 .../viewer/wicket/model/models/ScalarModel.java    |   7 +-
 .../wicket/model/models/ScalarParameterModel.java  |  58 +++----
 .../wicket/model/models/ScalarPropertyModel.java   |   7 +-
 .../components/actions/ActionParametersForm.java   |  44 +++---
 .../components/scalars/ScalarPanelAbstract2.java   | 176 ++++++++-------------
 .../scalars/ScalarPanelSelect2Abstract.java        |  32 ++--
 .../scalars/ScalarPanelTextFieldAbstract.java      |  17 +-
 .../isisapplib/IsisBlobOrClobPanelAbstract.java    |  35 ++--
 .../components/scalars/primitive/BooleanPanel.java |  10 +-
 .../scalars/reference/ReferencePanel.java          |  16 +-
 .../valuechoices/ValueChoicesSelect2Panel.java     |  15 +-
 ...derForReferenceParamOrPropertyAutoComplete.java |  16 +-
 14 files changed, 328 insertions(+), 267 deletions(-)

diff --git a/viewers/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/ActionArgumentModel.java b/viewers/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/ActionArgumentModel.java
index 6f46c38..b769062 100644
--- a/viewers/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/ActionArgumentModel.java
+++ b/viewers/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/ActionArgumentModel.java
@@ -23,12 +23,16 @@ import org.apache.wicket.model.IModel;
 import org.apache.isis.core.metamodel.spec.ManagedObject;
 import org.apache.isis.core.metamodel.spec.feature.ObjectActionParameter;
 import org.apache.isis.core.metamodel.specloader.SpecificationLoader;
+import org.apache.isis.core.metamodel.specloader.specimpl.PendingParameterModel;
 import org.apache.isis.viewer.wicket.model.mementos.ActionParameterMemento;
 
 public interface ActionArgumentModel extends IModel<ManagedObject> {
 
     ActionParameterMemento getParameterMemento();
     String getCssClass();
+    
+    // transient storage
+    void setActionArgsHint(PendingParameterModel pendingArgs);
 
     // -- SHORTCUTS
     
@@ -36,8 +40,15 @@ public interface ActionArgumentModel extends IModel<ManagedObject> {
         return getParameterMemento().getActionParameter(specificationLoader);
     }
     
+    /** param index */
     default int getNumber() {
         return getParameterMemento().getNumber();
     }
+    
+    /** param value */
+    default ManagedObject getValue() {
+        return getObject();
+    }
+    
 
 }
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 2d18f61..20cee03 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
@@ -23,6 +23,7 @@ import java.io.ByteArrayInputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.util.List;
+import java.util.Objects;
 import java.util.Optional;
 import java.util.regex.Pattern;
 import java.util.stream.Stream;
@@ -89,7 +90,7 @@ public class ActionModel extends BookmarkableModel<ManagedObject> implements For
     }
 
     // -- FACTORY METHODS
-    
+
     /**
      * @param entityModel
      * @param action
@@ -100,11 +101,11 @@ public class ActionModel extends BookmarkableModel<ManagedObject> implements For
         val actionModel = new ActionModel(entityModel, homePageActionMemento);
         return actionModel;
     }
-    
+
     public static ActionModel createForPersistent(
             IsisWebAppCommonContext commonContext, 
             PageParameters pageParameters) {
-        
+
         val entityModel = newEntityModelFrom(commonContext, pageParameters);
         val actionMemento = newActionMementoFrom(commonContext, pageParameters);
         val actionModel = new ActionModel(entityModel, actionMemento);
@@ -122,8 +123,8 @@ public class ActionModel extends BookmarkableModel<ManagedObject> implements For
 
         ManagedObject.stringify(adapter)
         .ifPresent(oidStr->
-            PageParameterNames.OBJECT_OID.addStringTo(pageParameters, oidStr)
-        );
+        PageParameterNames.OBJECT_OID.addStringTo(pageParameters, oidStr)
+                );
 
         val actionType = objectAction.getType();
         PageParameterNames.ACTION_TYPE.addEnumTo(pageParameters, actionType);
@@ -150,22 +151,22 @@ public class ActionModel extends BookmarkableModel<ManagedObject> implements For
         if (!matcher.matches()) {
             return Optional.empty();
         }
-        
+
         try {
-        
+
             val intLiteral = matcher.group(1);
             val oidStr = matcher.group(2);
-            
+
             val parseResult = _Ints.parseInt(intLiteral, 10);
             if(parseResult.isPresent()) {
                 val paramNum = parseResult.getAsInt();
                 return Optional.of(ParamNumAndOidString.of(paramNum, oidStr));
             }
-            
+
         } catch (final Exception e) {
             // ignore and fall through
         }
-        
+
         return Optional.empty();
 
     }
@@ -241,22 +242,22 @@ public class ActionModel extends BookmarkableModel<ManagedObject> implements For
 
     private final EntityModel entityModel;
     private final ActionMemento actionMemento;
-    
+
     // lazy in support of serialization of this class
     private transient ActionArgumentCache argCache;
     private ActionArgumentCache argCache() {
         return argCache!=null
                 ? argCache
-                : (argCache = new ActionArgumentCache(
-                        entityModel, 
-                        actionMemento, 
-                        getActionMemento().getAction(getSpecificationLoader())));
+                        : (argCache = new ActionArgumentCache(
+                                entityModel, 
+                                actionMemento, 
+                                getActionMemento().getAction(getSpecificationLoader())));
     }
-    
+
     private static ActionMemento newActionMementoFrom(
             IsisWebAppCommonContext commonContext,
             PageParameters pageParameters) {
-        
+
         final ObjectSpecId owningSpec = ObjectSpecId.of(PageParameterNames.ACTION_OWNING_SPEC.getStringFrom(pageParameters));
         final ActionType actionType = PageParameterNames.ACTION_TYPE.getEnumFrom(pageParameters, ActionType.class);
         final String actionNameParms = PageParameterNames.ACTION_ID.getStringFrom(pageParameters);
@@ -267,7 +268,7 @@ public class ActionModel extends BookmarkableModel<ManagedObject> implements For
     private static EntityModel newEntityModelFrom(
             IsisWebAppCommonContext commonContext,
             PageParameters pageParameters) {
-        
+
         val rootOid = oidFor(pageParameters);
         val memento = commonContext.mementoFor(rootOid);
         return EntityModel.ofMemento(commonContext, memento);
@@ -301,7 +302,7 @@ public class ActionModel extends BookmarkableModel<ManagedObject> implements For
     }
 
     private void setArgumentsIfPossible(final PageParameters pageParameters) {
-        
+
         final List<String> args = PageParameterNames.ACTION_ARGS.getListFrom(pageParameters);
 
         val action = actionMemento.getAction(getSpecificationLoader());
@@ -494,12 +495,12 @@ public class ActionModel extends BookmarkableModel<ManagedObject> implements For
      * @see {@link PendingParameterModelHead#defaults()}
      */
     public void clearArguments() {
-        
+
         val defaultsFixedPoint = getAction()
                 .newPendingParameterModelHead(getTargetAdapter())
                 .defaults()
                 .getParamValues();
-        
+
         argCache().resetTo(defaultsFixedPoint);
     }
 
@@ -658,9 +659,10 @@ public class ActionModel extends BookmarkableModel<ManagedObject> implements For
     public void clearParameterValue(ObjectActionParameter actionParameter) {
         setParameterValue(actionParameter, null);
     }
-    
+
     @Value(staticConstructor = "of")
     public static class ActionArgumentModelAndConsents {
+        final PendingParameterModel pendingArgs;
         final ActionArgumentModel actionArgumentModel;
         final Consent visibilityConsent;
         final Consent usabilityConsent;
@@ -670,30 +672,101 @@ public class ActionModel extends BookmarkableModel<ManagedObject> implements For
 
         val specificationLoader = getSpecificationLoader();
         val targetAdapter = this.getTargetAdapter();
-        val realTargetAdapter = this.getActionMemento().getAction(specificationLoader)
+        val realTargetAdapter = this.getActionMemento()
+                .getAction(specificationLoader)
                 .realTargetAdapter(targetAdapter);
-        val actionArgsHint = argCache().snapshot();
-        
-        return argCache().streamActionArgumentModels()
-        .map(actionArgumentModel->{
-        
-            // visibility
-            val visibilityConsent = actionArgumentModel.getActionParameter(specificationLoader)
-                    .isVisible(realTargetAdapter, actionArgsHint, InteractionInitiatedBy.USER);
-            
-            // usability
-            val usabilityConsent = actionArgumentModel.getActionParameter(specificationLoader)
-                    .isUsable(realTargetAdapter, actionArgsHint, InteractionInitiatedBy.USER);
+        val pendingArgs = getArgumentsAsParamModel();
+        val pendingArgValues = pendingArgs.getParamValues();
+
+        return argCache()
+                .streamActionArgumentModels()
+                .map(actionArgumentModel->{
+
+                    actionArgumentModel.setActionArgsHint(pendingArgs);
+
+                    val objectActionParamter = actionArgumentModel.getActionParameter(specificationLoader);
+
+                    // visibility
+                    val visibilityConsent = objectActionParamter
+                            .isVisible(realTargetAdapter, pendingArgValues, InteractionInitiatedBy.USER);
+
+                    // usability
+                    val usabilityConsent = objectActionParamter
+                            .isUsable(realTargetAdapter, pendingArgValues, InteractionInitiatedBy.USER);
+
+                    return ActionArgumentModelAndConsents.of(
+                            pendingArgs, actionArgumentModel, visibilityConsent, usabilityConsent);
+
+                });
+
+    }
+
+    public void reassessActionArgumentModels(int skipCount) {
+
+        val specificationLoader = getSpecificationLoader();
+        val pendingArgs = getArgumentsAsParamModel();
+
+        argCache()
+        .streamActionArgumentModels()
+        .skip(skipCount)
+        .forEach(actionArgumentModel->{
+
+            val actionParameter = actionArgumentModel.getActionParameter(specificationLoader);
+            val paramValue = actionArgumentModel.getValue();
+            val hasChoices = actionParameter.hasChoices();
+            val hasAutoComplete = actionParameter.hasAutoComplete();
+            val isEmpty = ManagedObject.isNullOrUnspecifiedOrEmpty(paramValue);
+            // if we have choices or autoSelect, don't override any param value, already chosen by the user
+            val vetoDefaultsToBeSet = !isEmpty 
+                    && (hasChoices||hasAutoComplete);
             
-            return ActionArgumentModelAndConsents.of(
-                    actionArgumentModel, visibilityConsent, usabilityConsent);
+            if(!vetoDefaultsToBeSet) {
+                val paramDefaultValue = actionParameter.getDefault(pendingArgs);
+                if (ManagedObject.isNullOrUnspecifiedOrEmpty(paramDefaultValue)) {
+                    clearParameterValue(actionParameter);
+                } else {
+                    setParameterValue(actionParameter, paramDefaultValue);
+                }
+                return;
+            }
             
+            boolean shouldBlankout = false;
+
+            if(!isEmpty) {
+                if(hasChoices) {
+                    // make sure the object is one of the choices, else blank it out.
+                    
+                    val choices = actionParameter
+                            .getChoices(pendingArgs, InteractionInitiatedBy.USER);
+
+                    shouldBlankout = 
+                            ! isPartOfChoicesConsideringDependentArgs(paramValue, choices);
+
+                } else if(hasAutoComplete) {
+
+                    //XXX poor man's implementation: don't blank-out, even though could fail validation later 
+                    shouldBlankout = false;
+                }
+            }
+
+            if(shouldBlankout) {
+                clearParameterValue(actionParameter);
+            }
+
         });
-        
 
     }
 
-    
+    private boolean isPartOfChoicesConsideringDependentArgs(
+            ManagedObject paramValue, 
+            Can<ManagedObject> choices) {
+
+        val pendingValue = paramValue.getPojo();
+
+        return choices
+                .stream()
+                .anyMatch(choice->Objects.equals(pendingValue, choice.getPojo()));
+    }
 
 
 }
diff --git a/viewers/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/ScalarModel.java b/viewers/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/ScalarModel.java
index b73e622..3c03448 100644
--- a/viewers/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/ScalarModel.java
+++ b/viewers/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/ScalarModel.java
@@ -41,6 +41,7 @@ import org.apache.isis.core.metamodel.spec.ObjectSpecId;
 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.OneToOneAssociation;
+import org.apache.isis.core.metamodel.specloader.specimpl.PendingParameterModel;
 import org.apache.isis.core.webapp.context.memento.ObjectMemento;
 import org.apache.isis.viewer.wicket.model.links.LinkAndLabel;
 import org.apache.isis.viewer.wicket.model.links.LinksProvider;
@@ -276,10 +277,10 @@ implements LinksProvider, FormExecutorContext {
     public abstract String getFileAccept();
 
     public abstract boolean hasChoices();
-    public abstract Can<ManagedObject> getChoices(Can<ManagedObject> pendingArgs);
+    public abstract Can<ManagedObject> getChoices(PendingParameterModel pendingArgs);
 
     public abstract boolean hasAutoComplete();
-    public abstract Can<ManagedObject> getAutoComplete(Can<ManagedObject> pendingArg, String searchTerm);
+    public abstract Can<ManagedObject> getAutoComplete(PendingParameterModel pendingArgs, String searchTerm);
 
     /**
      * for {@link BigDecimal}s only.
@@ -506,7 +507,7 @@ implements LinksProvider, FormExecutorContext {
 
     public abstract int getAutoCompleteOrChoicesMinLength();
 
-    public abstract ManagedObject getDefault(Can<ManagedObject> pendingArgs);
+    public abstract ManagedObject getDefault(PendingParameterModel pendingArgs);
 
     public int getAutoCompleteMinLength() {
         return getAutoCompleteOrChoicesMinLength();
diff --git a/viewers/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/ScalarParameterModel.java b/viewers/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/ScalarParameterModel.java
index d3c9402..45486c7 100644
--- a/viewers/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/ScalarParameterModel.java
+++ b/viewers/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/ScalarParameterModel.java
@@ -20,7 +20,6 @@ package org.apache.isis.viewer.wicket.model.models;
 
 import java.util.Collections;
 import java.util.List;
-import java.util.function.BiFunction;
 
 import org.apache.isis.applib.annotation.Where;
 import org.apache.isis.core.commons.collections.Can;
@@ -37,6 +36,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.webapp.context.memento.ObjectMemento;
 import org.apache.isis.viewer.wicket.model.mementos.ActionParameterMemento;
 
@@ -57,7 +57,7 @@ implements ActionArgumentModel {
      * @implNote transient because only temporary hint.
      */
     @Getter @Setter
-    private transient Can<ManagedObject> actionArgsHint;
+    private transient PendingParameterModel actionArgsHint;
 
     /**
      * Creates a model representing an action parameter of an action of a parent
@@ -118,7 +118,6 @@ implements ActionArgumentModel {
         final ObjectActionParameter parameter = getParameterMemento().getActionParameter(
                 getSpecificationLoader());
         try {
-            //XXX lombok issue, no val
             ManagedObject parentAdapter = getParentEntityModel().load();
             final String invalidReasonIfAny = parameter.isValid(parentAdapter, proposedPojoAsStr,
                     InteractionInitiatedBy.USER
@@ -134,7 +133,6 @@ implements ActionArgumentModel {
         final ObjectActionParameter parameter = getParameterMemento().getActionParameter(
                 getSpecificationLoader());
         try {
-            //XXX lombok issue, no val
             ManagedObject parentAdapter = getParentEntityModel().load();
             final String invalidReasonIfAny = parameter.isValid(parentAdapter, proposedAdapter.getPojo(),
                     InteractionInitiatedBy.USER
@@ -161,11 +159,9 @@ implements ActionArgumentModel {
 
     @Override
     public ManagedObject getDefault(
-            @NonNull final Can<ManagedObject> pendingArgs) {
+            @NonNull final PendingParameterModel pendingArgs) {
         
-        return withPendingParamsDo(pendingArgs, (pendingParamsModel, actionParameter)->
-        actionParameter.getDefault(
-                pendingParamsModel));
+        return getParameter().getDefault(pendingArgs);
     }
 
     @Override
@@ -176,13 +172,8 @@ implements ActionArgumentModel {
     }
     @Override
     public Can<ManagedObject> getChoices(
-            @NonNull final Can<ManagedObject> pendingArgs) {
-        
-        return withPendingParamsDo(pendingArgs, (pendingParamsModel, actionParameter)->
-        actionParameter.getChoices(
-                pendingParamsModel,
-                InteractionInitiatedBy.USER));
-        
+            @NonNull final PendingParameterModel pendingArgs) {
+        return getParameter().getChoices(pendingArgs, InteractionInitiatedBy.USER);
     }
 
     @Override
@@ -193,17 +184,11 @@ implements ActionArgumentModel {
     }
     @Override
     public Can<ManagedObject> getAutoComplete(
-            @NonNull final Can<ManagedObject> pendingArgs,
+            @NonNull final PendingParameterModel pendingArgs,
             final String searchArg) {
         
-        return withPendingParamsDo(pendingArgs, (pendingParamsModel, actionParameter)->
-        actionParameter.getAutoComplete(
-                pendingParamsModel,
-                searchArg,
-                InteractionInitiatedBy.USER)); 
+        return getParameter().getAutoComplete(pendingArgs, searchArg, InteractionInitiatedBy.USER);
     }
-
-
     
     @Override
     public int getAutoCompleteOrChoicesMinLength() {
@@ -298,21 +283,24 @@ implements ActionArgumentModel {
     public String toStringOf() {
         return getName() + ": " + getParameterMemento().toString();
     }
-
-    // pending args helper
-    private <T> T withPendingParamsDo(
-            @NonNull final Can<ManagedObject> pendingArgs,
-            final BiFunction<PendingParameterModel, ObjectActionParameter, T> function) {
-        val parameterMemento = getParameterMemento();
-        val actionParameter = parameterMemento.getActionParameter(getSpecificationLoader());
-        val actionOwner = getParentEntityModel().load();
-        val pendingParamsModel = actionParameter.getAction().newPendingParameterModelHead(actionOwner)
-                .model(pendingArgs);
-        return function.apply(pendingParamsModel, actionParameter);
-    }
     
     @Override
     protected List<ObjectAction> calcAssociatedActions() {
         return Collections.emptyList();
     }
+    
+    public ObjectActionParameter getParameter() {
+        val parameterMemento = getParameterMemento();
+        val actionParameter = parameterMemento.getActionParameter(getSpecificationLoader());
+        return actionParameter;
+    }
+    
+    public PendingParameterModelHead getPendingParamHead() {
+        val actionParameter = getParameter();
+        val actionOwner = getParentEntityModel().load();
+        return actionParameter.getAction().newPendingParameterModelHead(actionOwner);
+    }
+
+
+    
 }
diff --git a/viewers/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/ScalarPropertyModel.java b/viewers/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/ScalarPropertyModel.java
index 3e4f4b6..cc42369 100644
--- a/viewers/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/ScalarPropertyModel.java
+++ b/viewers/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/ScalarPropertyModel.java
@@ -37,6 +37,7 @@ import org.apache.isis.core.metamodel.spec.ObjectSpecId;
 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.OneToOneAssociation;
+import org.apache.isis.core.metamodel.specloader.specimpl.PendingParameterModel;
 import org.apache.isis.core.webapp.context.memento.ObjectMemento;
 import org.apache.isis.viewer.wicket.model.mementos.PropertyMemento;
 
@@ -173,7 +174,7 @@ public class ScalarPropertyModel extends ScalarModel {
 
     @Override
     public ManagedObject getDefault(
-            final Can<ManagedObject> pendingArgs /*not used*/) {
+            final PendingParameterModel pendingArgs /*not used*/) {
 
         final PropertyMemento propertyMemento = getPropertyMemento();
         final OneToOneAssociation property = propertyMemento
@@ -191,7 +192,7 @@ public class ScalarPropertyModel extends ScalarModel {
 
     @Override
     public Can<ManagedObject> getChoices(
-            final Can<ManagedObject> pendingArgs /*not used*/) { 
+            final PendingParameterModel pendingArgs /*not used on properties*/) { 
 
         final PropertyMemento propertyMemento = getPropertyMemento();
         final OneToOneAssociation property = propertyMemento
@@ -213,7 +214,7 @@ public class ScalarPropertyModel extends ScalarModel {
 
     @Override
     public Can<ManagedObject> getAutoComplete(
-            final Can<ManagedObject> pendingArgs, /*not used*/
+            final PendingParameterModel pendingArgs, /*not used on properties*/
             final String searchArg) {
 
         final PropertyMemento propertyMemento = getPropertyMemento();
diff --git a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/actions/ActionParametersForm.java b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/actions/ActionParametersForm.java
index 8e375cd..c3b4fdc 100644
--- a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/actions/ActionParametersForm.java
+++ b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/actions/ActionParametersForm.java
@@ -28,6 +28,7 @@ import org.apache.wicket.markup.html.WebMarkupContainer;
 import org.apache.wicket.markup.html.form.Form;
 import org.apache.wicket.markup.repeater.RepeatingView;
 
+import org.apache.isis.core.commons.internal.base._Strings;
 import org.apache.isis.core.commons.internal.exceptions._Exceptions;
 import org.apache.isis.viewer.common.model.decorator.confirm.ConfirmUiModel;
 import org.apache.isis.viewer.common.model.decorator.confirm.ConfirmUiModel.Placement;
@@ -35,7 +36,6 @@ import org.apache.isis.viewer.wicket.model.hints.IsisActionCompletedEvent;
 import org.apache.isis.viewer.wicket.model.isis.WicketViewerSettings;
 import org.apache.isis.viewer.wicket.model.models.ActionArgumentModel;
 import org.apache.isis.viewer.wicket.model.models.ActionModel;
-import org.apache.isis.viewer.wicket.model.models.ScalarParameterModel;
 import org.apache.isis.viewer.wicket.ui.ComponentType;
 import org.apache.isis.viewer.wicket.ui.components.scalars.ScalarPanelAbstract2;
 import org.apache.isis.viewer.wicket.ui.panels.FormExecutorStrategy;
@@ -76,8 +76,6 @@ class ActionParametersForm extends PromptFormAbstract<ActionModel> {
         .forEach(argsAndConsents->{
             
             val actionArgumentModel = argsAndConsents.getActionArgumentModel(); 
-            val visibilityConsent = argsAndConsents.getVisibilityConsent();
-            val usabilityConsent = argsAndConsents.getUsabilityConsent();
             
             val container = new WebMarkupContainer(repeatingView.newChildId());
             repeatingView.add(container);
@@ -85,8 +83,8 @@ class ActionParametersForm extends PromptFormAbstract<ActionModel> {
             newParamPanel(container, actionArgumentModel)
             .ifPresent(paramPanel->{
                 paramPanels.add(paramPanel);
-                paramPanel.setVisible(visibilityConsent.isAllowed());
-                //paramPanel.onInitializeReadonly(usabilityConsent.getReason());
+                //val paramModel = (ScalarParameterModel) paramPanel.getModel();
+                paramPanel.postInit(argsAndConsents);
             });
             
         });
@@ -106,7 +104,9 @@ class ActionParametersForm extends PromptFormAbstract<ActionModel> {
         if(component instanceof MarkupContainer) {
             val markupContainer = (MarkupContainer) component;
             val css = actionArgumentModel.getCssClass();
-            CssClassAppender.appendCssClassTo(markupContainer, CssClassAppender.asCssStyle(css));
+            if (!_Strings.isNullOrEmpty(css)) {
+                CssClassAppender.appendCssClassTo(markupContainer, CssClassAppender.asCssStyle(css));    
+            }
         }
         
         val paramPanel =
@@ -150,26 +150,22 @@ class ActionParametersForm extends PromptFormAbstract<ActionModel> {
     @Override
     public void onUpdate(final AjaxRequestTarget target, final ScalarPanelAbstract2 scalarPanelUpdated) {
 
-        final ActionModel actionModel = getActionModel();
-
-        val paramModel = (ScalarParameterModel)scalarPanelUpdated.getModel();
+        val actionModel = getActionModel();
+        val paramModel = (ActionArgumentModel)scalarPanelUpdated.getModel();
+        final int paramNumberUpdated = paramModel.getNumber();
+        // only updates subsequent parameter panels starting from (paramNumberUpdated + 1)
+        final int skipCount = paramNumberUpdated + 1;   
         
-        final int paramNumberUpdated = paramModel.getParameterMemento().getNumber();
+        actionModel.reassessActionArgumentModels(skipCount);
         
-        val action = actionModel.getAction();
-
-        final int numParams = action.getParameterCount();
-
-        // only updates subsequent parameter panels starting from [paramNumberUpdated + 1] 
-        for (int i = paramNumberUpdated + 1; i < numParams; i++) {
-
-            val paramNumToUpdate = i;
+        actionModel.streamActionArgumentModels()
+        .skip(skipCount)
+        .forEach(argAndConsents->{
+            
+            val paramNumToUpdate = argAndConsents.getActionArgumentModel().getNumber();
             val paramPanel = paramPanels.get(paramNumToUpdate);
-            val repaint = paramPanel
-                    .updateIfNecessary(actionModel, paramNumberUpdated, paramNumToUpdate, target);
+            val repaint = paramPanel.updateIfNecessary(argAndConsents, Optional.of(target));
             
-            //final boolean multiPart = isMultiPart(); // side-effects(?) or remove
-
             switch (repaint) {
             case ENTIRE_FORM:
                 target.add(this);
@@ -182,7 +178,9 @@ class ActionParametersForm extends PromptFormAbstract<ActionModel> {
             default:
                 throw _Exceptions.unmatchedCase(repaint);
             }
-        }
+            
+        });
+
 
         // previously this method was also doing:
         // target.add(this);
diff --git a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/ScalarPanelAbstract2.java b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/ScalarPanelAbstract2.java
index 3473d3c..560a653 100644
--- a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/ScalarPanelAbstract2.java
+++ b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/ScalarPanelAbstract2.java
@@ -21,6 +21,7 @@ package org.apache.isis.viewer.wicket.ui.components.scalars;
 
 import java.util.List;
 import java.util.Objects;
+import java.util.Optional;
 
 import org.apache.wicket.Component;
 import org.apache.wicket.MarkupContainer;
@@ -41,21 +42,16 @@ import org.apache.isis.applib.annotation.ActionLayout;
 import org.apache.isis.applib.annotation.PromptStyle;
 import org.apache.isis.applib.services.metamodel.BeanSort;
 import org.apache.isis.applib.services.metamodel.MetaModelService;
-import org.apache.isis.core.commons.collections.Can;
 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;
-import org.apache.isis.core.metamodel.consent.InteractionInitiatedBy;
 import org.apache.isis.core.metamodel.facets.all.named.NamedFacet;
 import org.apache.isis.core.metamodel.facets.members.cssclass.CssClassFacet;
 import org.apache.isis.core.metamodel.facets.objectvalue.labelat.LabelAtFacet;
 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 org.apache.isis.viewer.wicket.model.links.LinkAndLabel;
-import org.apache.isis.viewer.wicket.model.models.ActionModel;
+import org.apache.isis.viewer.wicket.model.models.ActionModel.ActionArgumentModelAndConsents;
 import org.apache.isis.viewer.wicket.model.models.ActionPrompt;
 import org.apache.isis.viewer.wicket.model.models.ActionPromptProvider;
 import org.apache.isis.viewer.wicket.model.models.EntityModel;
@@ -77,6 +73,7 @@ import org.apache.isis.viewer.wicket.ui.panels.PanelAbstract;
 import org.apache.isis.viewer.wicket.ui.util.Components;
 import org.apache.isis.viewer.wicket.ui.util.CssClassAppender;
 
+import lombok.NonNull;
 import lombok.val;
 
 import de.agilecoders.wicket.core.markup.html.bootstrap.common.NotificationPanel;
@@ -120,92 +117,67 @@ implements ScalarModelSubscriber2 {
         NOTHING
     }
 
+    /** this is a hack for the ScalarParameterModel, which does not support usability constraints in the model*/
+    private Runnable postInit;
+    public void postInit(@NonNull final ActionArgumentModelAndConsents argsAndConsents) {
+        this.postInit = () ->{
+            // visibility
+            val visibilityConsent = argsAndConsents.getVisibilityConsent();
+            setVisible(visibilityConsent.isAllowed());
+
+            // usability
+            val usabilityConsent = argsAndConsents.getUsabilityConsent();
+            if(usabilityConsent.isAllowed()) {
+                onInitializeEditable();
+            } else {
+                onInitializeReadonly(usabilityConsent.getReason());
+            }            
+        }; 
+    }
+    
     /**
      *
      * @param actionModel - the action being invoked
-     * @param paramNumUpdated - the # of the param that has just been updated by the user
-     * @param paramNumToPossiblyUpdate - the # of the param to be updated if necessary (will be &gt; paramNumUpdated)
      *
      * @param target - in case there's more to be repainted...
      *
      * @return - true if changed as a result of these pending arguments.
      */
     public Repaint updateIfNecessary(
-            final ActionModel actionModel,
-            final int paramNumUpdated,
-            final int paramNumToPossiblyUpdate,
-            final AjaxRequestTarget target) {
-
-        final ObjectAction action = actionModel.getAction();
-        final PendingParameterModel pendingArguments = actionModel.getArgumentsAsParamModel();
-        final Can<ManagedObject> pendingArgumentsReadonly = pendingArguments.getParamValues();
+            @NonNull final ActionArgumentModelAndConsents argsAndConsents,
+            @NonNull final Optional<AjaxRequestTarget> target) {
         
+        val argModel = argsAndConsents.getActionArgumentModel();
         
-        // could almost certainly simplify this... (used by visibility and usability checks)
-        final ObjectActionParameter actionParameter = action.getParameters().getElseFail(paramNumToPossiblyUpdate);
-        val targetAdapter = actionModel.getTargetAdapter();
-        val realTargetAdapter = action.realTargetAdapter(targetAdapter);
-
-        // check visibility
-        final Consent visibilityConsent = actionParameter
-                .isVisible(realTargetAdapter, pendingArgumentsReadonly, InteractionInitiatedBy.USER);
-
-        final boolean visibilityBefore = isVisible();
-        final boolean visibilityAfter = visibilityConsent.isAllowed();
+        // visibility
+        val visibilityConsent = argsAndConsents.getVisibilityConsent();
+        val visibilityBefore = isVisible();
+        val visibilityAfter = visibilityConsent.isAllowed();
         setVisible(visibilityAfter);
 
-
-        // check usability
-        final Consent usabilityConsent = actionParameter
-                .isUsable(realTargetAdapter, pendingArgumentsReadonly, InteractionInitiatedBy.USER);
-
-        final boolean usabilityBefore = isEnabled();
-        final boolean usabilityAfter = usabilityConsent.isAllowed();
+        // usability
+        val usabilityConsent = argsAndConsents.getUsabilityConsent();
+        val usabilityBefore = isEnabled();
+        val usabilityAfter = usabilityConsent.isAllowed();
         if(usabilityAfter) {
-            onEnabled(target);
+            onEditable(target);
         } else {
             onNotEditable(usabilityConsent.getReason(), target);
         }
 
-        // even if now invisible or unusable, we recalculate args and ensure compatible
-        // (else can hit complicated edge cases with stale data when next re-enable/make visible)
-        final ScalarModel model = getModel();
-        val defaultIfAny = model.getDefault(pendingArgumentsReadonly);
-
-        val pendingArg = pendingArgumentsReadonly.getElseFail(paramNumToPossiblyUpdate);
+        val paramValue = argModel.getValue();
+        val valueChanged = !Objects.equals(scalarModel.getObject(), paramValue); 
         
-        if (defaultIfAny != null) {
-            scalarModel.setObject(defaultIfAny);
-            scalarModel.setPendingAdapter(defaultIfAny);
-            actionModel.setParameterValue(actionParameter, defaultIfAny);
-
-        } else {
-
-            boolean shouldBlankout = false;
-            
-            if(ManagedObject.isNullOrUnspecifiedOrEmpty(pendingArg)) {
-                if(scalarModel.hasChoices()) {
-                    // make sure the object is one of the choices, else blank it out.
-                    val choices = scalarModel
-                            .getChoices(pendingArgumentsReadonly);
-                    
-                    shouldBlankout = 
-                            ! isPartOfChoicesConsideringDependentArgs(scalarModel, pendingArg, choices);
-                    
-                } else if(scalarModel.hasAutoComplete()) {
-                    
-                    // poor man's implementation: blank-out in any case 
-                    shouldBlankout = true;
-                }
-            }
-            
-            if(shouldBlankout) {
+        if(valueChanged) {
+            if(ManagedObject.isNullOrUnspecifiedOrEmpty(paramValue)) {
                 scalarModel.setObject(null);
                 scalarModel.setPending(null);
-                actionModel.clearParameterValue(actionParameter);
-            }
-            
+            } else {
+                scalarModel.setObject(paramValue);
+                scalarModel.setPendingAdapter(paramValue);
+            }               
         }
+        
 
         // repaint the entire form if visibility has changed
         if (!visibilityBefore || !visibilityAfter) {
@@ -218,24 +190,11 @@ implements ScalarModelSubscriber2 {
         }
 
         // also repaint the param if its pending arg has changed.
-        return scalarModel.getObject() != pendingArg
+        return valueChanged
                 ? Repaint.PARAM_ONLY
                         : Repaint.NOTHING;
     }
 
-    // blank out the parameter n based on dependent params 0 .. n-1
-    private boolean isPartOfChoicesConsideringDependentArgs(
-            ScalarModel scalarModel, 
-            ManagedObject pendingArg, 
-            Can<ManagedObject> choices) {
-        
-        val pendingValue = pendingArg.getPojo();
-        
-        return choices
-                .stream()
-                .anyMatch(choice->Objects.equals(pendingValue, choice.getPojo()));
-    }
-
     public static class InlinePromptConfig {
         private final boolean supported;
         private final Component componentToHideIfAny;
@@ -308,19 +267,26 @@ implements ScalarModelSubscriber2 {
 
         final ScalarModel scalarModel = getModel();
 
-        final String disableReasonIfAny = scalarModel.whetherDisabled();
-        final boolean mustBeEditable = scalarModel.mustBeEditable();
-        if (disableReasonIfAny != null) {
-            if(mustBeEditable) {
-                onInitializeNotEditable();
-            } else {
-                onInitializeReadonly(disableReasonIfAny);
-            }
+        if(postInit!=null) {
+            // ScalarParameterModel hack
+            postInit.run();
+            postInit=null;
         } else {
-            if (scalarModel.isViewMode()) {
-                onInitializeNotEditable();
-            } else {        
-                onInitializeEditable();
+        
+            final String disableReasonIfAny = scalarModel.whetherDisabled();
+            final boolean mustBeEditable = scalarModel.mustBeEditable();
+            if (disableReasonIfAny != null) {
+                if(mustBeEditable) {
+                    onInitializeNotEditable();
+                } else {
+                    onInitializeReadonly(disableReasonIfAny);
+                }
+            } else {
+                if (scalarModel.isViewMode()) {
+                    onInitializeNotEditable();
+                } else {        
+                    onInitializeEditable();
+                }
             }
         }
 
@@ -460,7 +426,7 @@ implements ScalarModelSubscriber2 {
     /**
      * The widget starts off read-only, and CANNOT be activated into edit mode.
      */
-    protected void onInitializeReadonly(final String disableReason) {
+    protected void onInitializeReadonly(String disableReason) {
     }
 
     /**
@@ -470,25 +436,18 @@ implements ScalarModelSubscriber2 {
     }
 
     /**
-     * The widget is no longer editable.
-     * @apiNote
-     *     the semantics here aren't the same as 'onInitializeWhenDisabled' (the latter is never editable).
+     * The widget is no longer editable, but should be possible to activate into edit mode.
      */
-    protected void onNotEditable(final String disableReason, final AjaxRequestTarget target) {
+    protected void onNotEditable(final String disableReason, final Optional<AjaxRequestTarget> target) {
     }
 
     /**
      * The widget should be made editable.
      *
-     * <p>
-     *     TODO: perhaps rename to 'onEditable'?
-     * </p>
      */
-    protected void onEnabled(final AjaxRequestTarget target) {
+    protected void onEditable(@NonNull final Optional<AjaxRequestTarget> target) {
     }
 
-
-
     private void addCssFromMetaModel() {
         final String cssForMetaModel = getModel().getCssClass();
         if (!_Strings.isNullOrEmpty(cssForMetaModel)) {
@@ -960,4 +919,7 @@ implements ScalarModelSubscriber2 {
     }
 
 
+
+
+
 }
diff --git a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/ScalarPanelSelect2Abstract.java b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/ScalarPanelSelect2Abstract.java
index ca03d4b..72ce315 100644
--- a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/ScalarPanelSelect2Abstract.java
+++ b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/ScalarPanelSelect2Abstract.java
@@ -20,6 +20,7 @@
 package org.apache.isis.viewer.wicket.ui.components.scalars;
 
 import java.util.List;
+import java.util.Optional;
 
 import org.apache.wicket.Component;
 import org.apache.wicket.ajax.AjaxRequestTarget;
@@ -32,10 +33,9 @@ import org.apache.wicket.validation.IValidator;
 import org.apache.wicket.validation.ValidationError;
 import org.wicketstuff.select2.ChoiceProvider;
 
-import org.apache.isis.core.commons.collections.Can;
-import org.apache.isis.core.metamodel.spec.ManagedObject;
+import org.apache.isis.core.metamodel.specloader.specimpl.PendingParameterModel;
 import org.apache.isis.core.webapp.context.memento.ObjectMemento;
-import org.apache.isis.viewer.wicket.model.models.ActionModel;
+import org.apache.isis.viewer.wicket.model.models.ActionModel.ActionArgumentModelAndConsents;
 import org.apache.isis.viewer.wicket.model.models.ScalarModel;
 import org.apache.isis.viewer.wicket.model.models.ScalarParameterModel;
 import org.apache.isis.viewer.wicket.ui.components.widgets.bootstrap.FormGroup;
@@ -44,6 +44,7 @@ import org.apache.isis.viewer.wicket.ui.components.widgets.select2.providers.Obj
 import org.apache.isis.viewer.wicket.ui.util.CssClassAppender;
 import org.apache.isis.viewer.wicket.ui.util.Tooltips;
 
+import lombok.NonNull;
 import lombok.val;
 
 public abstract class ScalarPanelSelect2Abstract extends ScalarPanelAbstract2 {
@@ -117,7 +118,9 @@ public abstract class ScalarPanelSelect2Abstract extends ScalarPanelAbstract2 {
     /**
      * sets up the choices, also ensuring that any currently held value is compatible.
      */
-    private void setProviderAndCurrAndPending(Select2 select2, Can<ManagedObject> pendingArgs) {
+    private void setProviderAndCurrAndPending(
+            final Select2 select2, 
+            final PendingParameterModel pendingArgs) {
 
         final ChoiceProvider<ObjectMemento> choiceProvider = buildChoiceProvider(pendingArgs);
 
@@ -136,7 +139,7 @@ public abstract class ScalarPanelSelect2Abstract extends ScalarPanelAbstract2 {
     /**
      * Mandatory hook (is called by {@link #setProviderAndCurrAndPending(Select2, List<ManagedObject>)})
      */
-    protected abstract ChoiceProvider<ObjectMemento> buildChoiceProvider(Can<ManagedObject> pendingArgs);
+    protected abstract ChoiceProvider<ObjectMemento> buildChoiceProvider(PendingParameterModel pendingArgs);
 
     /**
      * Mandatory hook (is called by {@link #setProviderAndCurrAndPending(Select2, List<ManagedObject>)})
@@ -159,12 +162,12 @@ public abstract class ScalarPanelSelect2Abstract extends ScalarPanelAbstract2 {
     }
 
     @Override
-    protected void onNotEditable(final String disableReason, final AjaxRequestTarget target) {
+    protected void onNotEditable(final String disableReason, final Optional<AjaxRequestTarget> target) {
         setEnabled(false);
     }
 
     @Override
-    protected void onEnabled(final AjaxRequestTarget target) {
+    protected void onEditable(final Optional<AjaxRequestTarget> target) {
         setEnabled(true);
 
     }
@@ -180,17 +183,12 @@ public abstract class ScalarPanelSelect2Abstract extends ScalarPanelAbstract2 {
      */
     @Override
     public Repaint updateIfNecessary(
-            final ActionModel actionModel,
-            final int paramNumUpdated,
-            final int paramNumToPossiblyUpdate,
-            final AjaxRequestTarget target) {
-
-        final Can<ManagedObject> arguments = actionModel.getArgumentsAsParamModel()
-                .getParamValues();
+            @NonNull final ActionArgumentModelAndConsents argsAndConsents,
+            @NonNull final Optional<AjaxRequestTarget> target) {
 
-        val repaint = super.updateIfNecessary(actionModel, paramNumUpdated, paramNumToPossiblyUpdate, target);
+        val repaint = super.updateIfNecessary(argsAndConsents, target);
 
-        final boolean choicesUpdated = updateChoices(arguments);
+        final boolean choicesUpdated = updateChoices(argsAndConsents.getPendingArgs());
 
         if (repaint == Repaint.NOTHING) {
             if (choicesUpdated) {
@@ -203,7 +201,7 @@ public abstract class ScalarPanelSelect2Abstract extends ScalarPanelAbstract2 {
         }
     }
 
-    private boolean updateChoices(Can<ManagedObject> pendingArgs) {
+    private boolean updateChoices(final PendingParameterModel pendingArgs) {
         if (select2 == null) {
             return false;
         }
diff --git a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/ScalarPanelTextFieldAbstract.java b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/ScalarPanelTextFieldAbstract.java
index 1dc37a3..5f21b24 100644
--- a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/ScalarPanelTextFieldAbstract.java
+++ b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/ScalarPanelTextFieldAbstract.java
@@ -20,6 +20,7 @@
 package org.apache.isis.viewer.wicket.ui.components.scalars;
 
 import java.io.Serializable;
+import java.util.Optional;
 
 import org.apache.wicket.AttributeModifier;
 import org.apache.wicket.Component;
@@ -351,21 +352,25 @@ implements TextFieldValueModel.ScalarModelProvider {
     }
 
     @Override
-    protected void onNotEditable(final String disableReason, final AjaxRequestTarget target) {
+    protected void onNotEditable(final String disableReason, final Optional<AjaxRequestTarget> target) {
         textField.setEnabled(false);
         inlinePromptLink.setEnabled(false);
         setTooltip(disableReason);
-        target.add(textField);
-        target.add(inlinePromptLink);
+        target.ifPresent(ajax->{
+            ajax.add(textField);
+            ajax.add(inlinePromptLink);    
+        });
     }
 
     @Override
-    protected void onEnabled(final AjaxRequestTarget target) {
+    protected void onEditable(final Optional<AjaxRequestTarget> target) {
         textField.setEnabled(true);
         inlinePromptLink.setEnabled(true);
         clearTooltip();
-        target.add(textField);
-        target.add(inlinePromptLink);
+        target.ifPresent(ajax->{
+            ajax.add(textField);
+            ajax.add(inlinePromptLink);    
+        });
     }
 
     private void setTooltip(final String tooltip) {
diff --git a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/isisapplib/IsisBlobOrClobPanelAbstract.java b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/isisapplib/IsisBlobOrClobPanelAbstract.java
index 18aafdf..358beb5 100644
--- a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/isisapplib/IsisBlobOrClobPanelAbstract.java
+++ b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/isisapplib/IsisBlobOrClobPanelAbstract.java
@@ -22,6 +22,7 @@ import java.awt.image.BufferedImage;
 import java.io.ByteArrayInputStream;
 import java.io.IOException;
 import java.util.List;
+import java.util.Optional;
 
 import javax.activation.MimeType;
 import javax.imageio.ImageIO;
@@ -236,13 +237,17 @@ public abstract class IsisBlobOrClobPanelAbstract<T extends NamedWithMimeType> e
     }
 
     @Override
-    protected void onNotEditable(final String disableReason, final AjaxRequestTarget target) {
-        updateRegularFormComponents(InputFieldVisibility.VISIBLE, InputFieldEditability.NOT_EDITABLE, disableReason, target);
+    protected void onNotEditable(final String disableReason, final Optional<AjaxRequestTarget> target) {
+        updateRegularFormComponents(
+                InputFieldVisibility.VISIBLE, InputFieldEditability.NOT_EDITABLE, 
+                disableReason, target);
     }
 
     @Override
-    protected void onEnabled(final AjaxRequestTarget target) {
-        updateRegularFormComponents(InputFieldVisibility.VISIBLE, InputFieldEditability.EDITABLE, null, target);
+    protected void onEditable(final Optional<AjaxRequestTarget> target) {
+        updateRegularFormComponents(
+                InputFieldVisibility.VISIBLE, InputFieldEditability.EDITABLE, 
+                null, target);
     }
 
     protected abstract T getBlobOrClobFrom(final List<FileUpload> fileUploads);
@@ -261,7 +266,7 @@ public abstract class IsisBlobOrClobPanelAbstract<T extends NamedWithMimeType> e
             final InputFieldVisibility visibility,
             final InputFieldEditability editability,
             final String disabledReason,
-            final AjaxRequestTarget target) {
+            final Optional<AjaxRequestTarget> target) {
 
         MarkupContainer formComponent = (MarkupContainer) getComponentForRegular();
         sync(formComponent, visibility, editability, disabledReason, target);
@@ -290,7 +295,7 @@ public abstract class IsisBlobOrClobPanelAbstract<T extends NamedWithMimeType> e
             final InputFieldVisibility visibility,
             final InputFieldEditability editability,
             final String disabledReason,
-            final AjaxRequestTarget target) {
+            final Optional<AjaxRequestTarget> target) {
 
         if(component == null) {
             return;
@@ -299,7 +304,10 @@ public abstract class IsisBlobOrClobPanelAbstract<T extends NamedWithMimeType> e
 
         if(visibility != null) {
             component.setVisible(visibility == InputFieldVisibility.VISIBLE);
-            Components.addToAjaxRequest(target, component);
+            target.ifPresent(ajax->{
+                Components.addToAjaxRequest(ajax, component);
+            });
+            
         }
 
 
@@ -360,7 +368,7 @@ public abstract class IsisBlobOrClobPanelAbstract<T extends NamedWithMimeType> e
     private void updateClearLink(
             final InputFieldVisibility visibility,
             final InputFieldEditability editability,
-            final AjaxRequestTarget target) {
+            final Optional<AjaxRequestTarget> target) {
 
         final MarkupContainer formComponent = (MarkupContainer) getComponentForRegular();
         formComponent.setOutputMarkupId(true); // enable ajax link
@@ -385,11 +393,12 @@ public abstract class IsisBlobOrClobPanelAbstract<T extends NamedWithMimeType> e
         clearButton.setVisible(blobOrClob != null && visibility == InputFieldVisibility.VISIBLE);
         clearButton.setEnabled(blobOrClob != null);
 
-        if(target != null) {
-            target.add(formComponent);
-            target.add(clearButton);
-            target.add(ajaxLink);
-        }
+        target.ifPresent(ajax->{
+            ajax.add(formComponent);
+            ajax.add(clearButton);
+            ajax.add(ajaxLink);
+        });
+        
     }
 
     private MarkupContainer updateDownloadLink(String downloadId, MarkupContainer container) {
diff --git a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/primitive/BooleanPanel.java b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/primitive/BooleanPanel.java
index 57cff91..9e39485 100644
--- a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/primitive/BooleanPanel.java
+++ b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/primitive/BooleanPanel.java
@@ -19,6 +19,8 @@
 
 package org.apache.isis.viewer.wicket.ui.components.scalars.primitive;
 
+import java.util.Optional;
+
 import org.apache.wicket.AttributeModifier;
 import org.apache.wicket.Component;
 import org.apache.wicket.MarkupContainer;
@@ -228,16 +230,18 @@ public class BooleanPanel extends ScalarPanelAbstract2 {
     }
 
     @Override
-    protected void onNotEditable(final String disableReason, final AjaxRequestTarget target) {
+    protected void onNotEditable(final String disableReason, final Optional<AjaxRequestTarget> target) {
         checkBox.setEnabled(false);
         final AttributeModifier title = new AttributeModifier("title",
                 Model.of(disableReason != null ? disableReason : ""));
         checkBox.add(title);
-        target.add(checkBox);
+        target.ifPresent(ajax->{
+            ajax.add(checkBox);   
+        });
     }
 
     @Override
-    protected void onEnabled(final AjaxRequestTarget target) {
+    protected void onEditable(final Optional<AjaxRequestTarget> target) {
         checkBox.setEnabled(true);
     }
 
diff --git a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/reference/ReferencePanel.java b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/reference/ReferencePanel.java
index 63f4de7..3104547 100644
--- a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/reference/ReferencePanel.java
+++ b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/reference/ReferencePanel.java
@@ -19,6 +19,8 @@
 
 package org.apache.isis.viewer.wicket.ui.components.scalars.reference;
 
+import java.util.Optional;
+
 import org.apache.wicket.AttributeModifier;
 import org.apache.wicket.Component;
 import org.apache.wicket.MarkupContainer;
@@ -31,10 +33,9 @@ import org.apache.wicket.model.Model;
 import org.wicketstuff.select2.ChoiceProvider;
 import org.wicketstuff.select2.Settings;
 
-import org.apache.isis.core.commons.collections.Can;
 import org.apache.isis.core.metamodel.facets.object.autocomplete.AutoCompleteFacet;
-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;
 import org.apache.isis.core.webapp.context.memento.ObjectMemento;
 import org.apache.isis.viewer.wicket.model.models.EntityModel;
 import org.apache.isis.viewer.wicket.model.models.EntityModelForReference;
@@ -218,7 +219,7 @@ public class ReferencePanel extends ScalarPanelSelect2Abstract {
     }
 
     @Override
-    protected void onNotEditable(final String disableReason, final AjaxRequestTarget target) {
+    protected void onNotEditable(final String disableReason, final Optional<AjaxRequestTarget> target) {
         super.onNotEditable(disableReason, target);
 
         entityLink.setEnabled(false);
@@ -226,8 +227,8 @@ public class ReferencePanel extends ScalarPanelSelect2Abstract {
     }
 
     @Override
-    protected void onEnabled(final AjaxRequestTarget target) {
-        super.onEnabled(target);
+    protected void onEditable(final Optional<AjaxRequestTarget> target) {
+        super.onEditable(target);
 
         entityLink.setEnabled(true);
         entityLink.add(new AttributeModifier("title", Model.of("")));
@@ -336,7 +337,8 @@ public class ReferencePanel extends ScalarPanelSelect2Abstract {
     // //////////////////////////////////////
 
     @Override
-    protected ChoiceProvider<ObjectMemento> buildChoiceProvider(Can<ManagedObject> pendingArgs) {
+    protected ChoiceProvider<ObjectMemento> buildChoiceProvider(
+            final PendingParameterModel pendingArgs) {
         
         val commonContext = super.getCommonContext();
         
@@ -347,7 +349,7 @@ public class ReferencePanel extends ScalarPanelSelect2Abstract {
         }
 
         if(getModel().hasAutoComplete()) {
-            val autoCompleteMementos = pendingArgs
+            val autoCompleteMementos = pendingArgs.getParamValues()
                     .map(commonContext::mementoForParameter);
             return new ObjectAdapterMementoProviderForReferenceParamOrPropertyAutoComplete(
                     getModel(), autoCompleteMementos);
diff --git a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/valuechoices/ValueChoicesSelect2Panel.java b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/valuechoices/ValueChoicesSelect2Panel.java
index 0bf0e3e..0307ae0 100644
--- a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/valuechoices/ValueChoicesSelect2Panel.java
+++ b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/valuechoices/ValueChoicesSelect2Panel.java
@@ -18,6 +18,8 @@
  */
 package org.apache.isis.viewer.wicket.ui.components.scalars.valuechoices;
 
+import java.util.Optional;
+
 import org.apache.wicket.Component;
 import org.apache.wicket.MarkupContainer;
 import org.apache.wicket.ajax.AjaxRequestTarget;
@@ -29,7 +31,7 @@ import org.wicketstuff.select2.ChoiceProvider;
 
 import org.apache.isis.core.commons.collections.Can;
 import org.apache.isis.core.commons.internal.base._Strings;
-import org.apache.isis.core.metamodel.spec.ManagedObject;
+import org.apache.isis.core.metamodel.specloader.specimpl.PendingParameterModel;
 import org.apache.isis.core.webapp.context.memento.ObjectMemento;
 import org.apache.isis.viewer.wicket.model.models.ScalarModel;
 import org.apache.isis.viewer.wicket.ui.components.scalars.ScalarPanelSelect2Abstract;
@@ -71,7 +73,7 @@ public class ValueChoicesSelect2Panel extends ScalarPanelSelect2Abstract {
     }
 
 
-    private Can<ObjectMemento> getChoiceMementos(final Can<ManagedObject> pendingArgs) {
+    private Can<ObjectMemento> getChoiceMementos(final PendingParameterModel pendingArgs) {
         
         val commonContext = super.getCommonContext();
         
@@ -137,7 +139,7 @@ public class ValueChoicesSelect2Panel extends ScalarPanelSelect2Abstract {
     }
 
     @Override
-    protected void onNotEditable(final String disableReason, final AjaxRequestTarget target) {
+    protected void onNotEditable(final String disableReason, final Optional<AjaxRequestTarget> target) {
         super.onNotEditable(disableReason, target);
 
         setTitleAttribute(disableReason);
@@ -145,8 +147,8 @@ public class ValueChoicesSelect2Panel extends ScalarPanelSelect2Abstract {
     }
 
     @Override
-    protected void onEnabled(final AjaxRequestTarget target) {
-        super.onEnabled(target);
+    protected void onEditable(final Optional<AjaxRequestTarget> target) {
+        super.onEditable(target);
 
         setTitleAttribute("");
         select2.setEnabled(true);
@@ -161,7 +163,8 @@ public class ValueChoicesSelect2Panel extends ScalarPanelSelect2Abstract {
     // in corresponding code in ReferencePanelFactory, these is a branch for different types of providers
     // (choice vs autoComplete).  Here though - because values don't currently support autoComplete - no branch is required
     @Override
-    protected ChoiceProvider<ObjectMemento> buildChoiceProvider(Can<ManagedObject> pendingArgs) {
+    protected ChoiceProvider<ObjectMemento> buildChoiceProvider(
+            final PendingParameterModel pendingArgs) {
         final Can<ObjectMemento> choicesMementos = getChoiceMementos(pendingArgs);
         return new ObjectAdapterMementoProviderForValueChoices(scalarModel, choicesMementos);
     }
diff --git a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/select2/providers/ObjectAdapterMementoProviderForReferenceParamOrPropertyAutoComplete.java b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/select2/providers/ObjectAdapterMementoProviderForReferenceParamOrPropertyAutoComplete.java
index f24d73d..f816748 100644
--- a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/select2/providers/ObjectAdapterMementoProviderForReferenceParamOrPropertyAutoComplete.java
+++ b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/select2/providers/ObjectAdapterMementoProviderForReferenceParamOrPropertyAutoComplete.java
@@ -21,8 +21,10 @@ package org.apache.isis.viewer.wicket.ui.components.widgets.select2.providers;
 import org.apache.isis.core.commons.collections.Can;
 import org.apache.isis.core.commons.internal.base._NullSafe;
 import org.apache.isis.core.metamodel.spec.ManagedObject;
+import org.apache.isis.core.metamodel.specloader.specimpl.PendingParameterModel;
 import org.apache.isis.core.webapp.context.memento.ObjectMemento;
 import org.apache.isis.viewer.wicket.model.models.ScalarModel;
+import org.apache.isis.viewer.wicket.model.models.ScalarParameterModel;
 
 import lombok.NonNull;
 import lombok.val;
@@ -45,13 +47,15 @@ extends ObjectAdapterMementoProviderAbstract {
     @Override
     protected Can<ObjectMemento> obtainMementos(String term) {
         
-        if (getScalarModel().hasAutoComplete()) {
+        val parameterModel = (ScalarParameterModel)getScalarModel();
+        
+        if (parameterModel.hasAutoComplete()) {
         
             val commonContext = super.getCommonContext();
             
             // recover any pendingArgs
-            val pendingArgs = reconstructDependentArgs(dependentArgMementos); 
-            return getScalarModel()
+            val pendingArgs = reconstructDependentArgs(parameterModel, dependentArgMementos); 
+            return parameterModel
                     .getAutoComplete(pendingArgs, term)
                     .map(commonContext::mementoFor);
             
@@ -61,7 +65,8 @@ extends ObjectAdapterMementoProviderAbstract {
         
     }
     
-    private Can<ManagedObject> reconstructDependentArgs(
+    private PendingParameterModel reconstructDependentArgs(
+            final ScalarParameterModel parameterModel, 
             final Can<ObjectMemento> dependentArgMementos) {
         
         val commonContext = super.getCommonContext();
@@ -70,7 +75,8 @@ extends ObjectAdapterMementoProviderAbstract {
             .map(ManagedObject.class::cast)
             .collect(Can.toCan());
         
-        return pendingArgsList;
+       return parameterModel.getPendingParamHead()
+            .model(pendingArgsList);
     }
 
 }