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 2021/09/19 17:17:41 UTC

[isis] branch 2871-value.types.overhaul created (now 5c7ddac)

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

ahuber pushed a change to branch 2871-value.types.overhaul
in repository https://gitbox.apache.org/repos/asf/isis.git.


      at 5c7ddac  ISIS-2871: Value Types need Semantics on a per Member/Param Basis

This branch includes the following new commits:

     new 5c7ddac  ISIS-2871: Value Types need Semantics on a per Member/Param Basis

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


[isis] 01/01: ISIS-2871: Value Types need Semantics on a per Member/Param Basis

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

ahuber pushed a commit to branch 2871-value.types.overhaul
in repository https://gitbox.apache.org/repos/asf/isis.git

commit 5c7ddac021f3b33c3a60cca0c487dfab64ee4978
Author: andi-huber <ah...@apache.org>
AuthorDate: Sun Sep 19 19:17:19 2021 +0200

    ISIS-2871: Value Types need Semantics on a per Member/Param Basis
    
    Task-Url: https://issues.apache.org/jira/browse/ISIS-2871
---
 .../interactions/managed/ActionInteraction.java    |  25 +++-
 .../managed/ParameterNegotiationModel.java         |  20 ++-
 .../interactions/managed/_BindingUtil.java         |   1 +
 .../wicket/pdfjs/applib/config/PdfJsConfig.java    |   2 +
 .../semantics/AsciiDocValueSemantics.java          |   6 -
 .../semantics/ChangesDtoValueSemantics.java        |   2 +-
 .../semantics/CommandDtoValueSemantics.java        |   2 +-
 .../semantics/InteractionDtoValueSemantics.java    |   2 +-
 .../semantics/XmlValueSemanticsAbstract.java       |  13 +-
 .../semantics/MarkdownValueSemantics.java          |   6 -
 .../model/action/form/FormPendingParamUiModel.java |  57 --------
 .../common/model/action/form/FormUiModel.java      |   7 +-
 .../common/model/feature/ParameterUiModel.java     |   1 -
 .../viewer/common/model/feature/ScalarUiModel.java |   2 +
 .../wicket/model/models/ActionArgumentCache.java   | 146 ---------------------
 .../viewer/wicket/model/models/ActionModel.java    |  84 +++++-------
 .../viewer/wicket/model/models/EntityModel.java    |   2 +-
 .../viewer/wicket/model/models/ScalarModel.java    |   6 +-
 .../wicket/model/models/ScalarParameterModel.java  |  75 +++--------
 .../action/ActionInteractionModelWkt.java          | 101 ++++++++++++++
 .../interaction/action/ObjectUiModelWkt.java       |  23 +---
 .../interaction/action/ParameterUiModelWkt.java    | 107 +++++++++++++++
 .../action/_ActionInteractionHolder.java           |  79 +++++++++++
 .../ScalarModel_isScalarSubtypingAnyOf_Test.java   | 106 ---------------
 .../components/actions/ActionParametersForm.java   |  43 +++---
 .../components/entity/fieldset/PropertyGroup.java  | 109 +++++++--------
 .../ui/components/scalars/ScalarPanelAbstract.java |  39 +-----
 .../scalars/ScalarPanelSelectAbstract.java         |   6 +-
 .../components/scalars/markup/MarkupComponent.java |   6 +-
 .../scalars/markup/MarkupPanelFactories.java       |  16 +--
 ...derForReferenceParamOrPropertyAutoComplete.java |  20 +--
 .../viewer/wicket/ui/pages/entity/EntityPage.java  |   2 +-
 32 files changed, 503 insertions(+), 613 deletions(-)

diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/managed/ActionInteraction.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/managed/ActionInteraction.java
index dfc82e0..ad82e12 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/managed/ActionInteraction.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/managed/ActionInteraction.java
@@ -18,6 +18,7 @@
  */
 package org.apache.isis.core.metamodel.interactions.managed;
 
+import java.io.Serializable;
 import java.util.Optional;
 import java.util.function.Function;
 
@@ -78,7 +79,7 @@ public final class ActionInteraction extends MemberInteraction<ManagedAction, Ac
     @Getter
     private final Optional<ObjectAction> metamodel;
 
-    public ActionInteraction checkSemanticConstraint(@NonNull SemanticConstraint semanticConstraint) {
+    public ActionInteraction checkSemanticConstraint(@NonNull final SemanticConstraint semanticConstraint) {
 
         chain = chain.mapIfLeft(action->{
 
@@ -114,7 +115,7 @@ public final class ActionInteraction extends MemberInteraction<ManagedAction, Ac
         void onParameterInvalid(ManagedParameter managedParameter, InteractionVeto veto);
     }
 
-    public _Either<ManagedObject, InteractionVeto> invokeWith(ParameterNegotiationModel pendingArgs) {
+    public _Either<ManagedObject, InteractionVeto> invokeWith(final ParameterNegotiationModel pendingArgs) {
         pendingArgs.activateValidationFeedback();
         val veto = validate(pendingArgs);
         if(veto.isPresent()) {
@@ -151,10 +152,28 @@ public final class ActionInteraction extends MemberInteraction<ManagedAction, Ac
      * @throws X if there was any interaction veto within the originating chain
      */
     public <X extends Throwable>
-    ManagedAction getManagedActionElseThrow(Function<InteractionVeto, ? extends X> onFailure) throws X {
+    ManagedAction getManagedActionElseThrow(final Function<InteractionVeto, ? extends X> onFailure) throws X {
         return super.getManagedMemberElseThrow(onFailure);
     }
 
+    public <X extends Throwable>
+    ManagedAction getManagedActionElseFail() {
+        return getManagedActionElseThrow(veto->_Exceptions.unrecoverable("action vetoed: " + veto.getReason()));
+    }
 
+    // -- MEMENTO
+
+    public class Memento implements Serializable {
+        private static final long serialVersionUID = 1L;
+        public ActionInteraction restore() {
+            // TODO Auto-generated method stub
+            return null;
+        }
+    }
+
+    public Memento memento() {
+        // TODO Auto-generated method stub
+        return null;
+    }
 
 }
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/managed/ParameterNegotiationModel.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/managed/ParameterNegotiationModel.java
index c726b7a..31d41cf 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/managed/ParameterNegotiationModel.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/managed/ParameterNegotiationModel.java
@@ -149,6 +149,21 @@ public class ParameterNegotiationModel {
         return paramModels.getElseFail(paramNr).getBindableParamSearchArgument();
     }
 
+    @NonNull public Consent getVisibilityConsent(final int paramNr) {
+        val pendingArgValues = getParamValues();
+        val paramMeta = getParamMetamodel(paramNr);
+        val head = this.getHead();
+        return paramMeta
+                .isVisible(head, pendingArgValues, InteractionInitiatedBy.USER);
+    }
+    @NonNull public Consent getUsabilityConsent(final int paramNr) {
+        val pendingArgValues = getParamValues();
+        val paramMeta = getParamMetamodel(paramNr);
+        val head = this.getHead();
+        return paramMeta
+                .isUsable(head, pendingArgValues, InteractionInitiatedBy.USER);
+    }
+
     // -- RATHER INTERNAL ...
 
     /** validates all, the action and each individual parameter */
@@ -180,6 +195,10 @@ public class ParameterNegotiationModel {
         paramModels.getElseFail(paramNr).getBindableParamValue().setValue(newParamValue);
     }
 
+    public void clearParamValue(final int paramNr) {
+        setParamValue(paramNr, adaptParamValuePojo(paramNr, null));
+    }
+
     @NonNull public ManagedObject adaptParamValuePojo(final int paramNr, final @Nullable Object newParamValuePojo) {
         val paramMeta = getParamMetamodel(paramNr);
         val paramSpec = paramMeta.getSpecification();
@@ -326,5 +345,4 @@ public class ParameterNegotiationModel {
 
     }
 
-
 }
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/managed/_BindingUtil.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/managed/_BindingUtil.java
index 408f4f7..7c3324c 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/managed/_BindingUtil.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/managed/_BindingUtil.java
@@ -80,6 +80,7 @@ class _BindingUtil {
 
     }
 
+    @SuppressWarnings({ "unchecked", "rawtypes" })
     private Bindable<String> bindAsParsableText(
             final @NonNull ObjectSpecification spec,
             final @NonNull _BindableAbstract<ManagedObject> bindableValue,
diff --git a/extensions/vw/pdfjs/applib/src/main/java/org/apache/isis/extensions/viewer/wicket/pdfjs/applib/config/PdfJsConfig.java b/extensions/vw/pdfjs/applib/src/main/java/org/apache/isis/extensions/viewer/wicket/pdfjs/applib/config/PdfJsConfig.java
index c8e6507..4c74749 100644
--- a/extensions/vw/pdfjs/applib/src/main/java/org/apache/isis/extensions/viewer/wicket/pdfjs/applib/config/PdfJsConfig.java
+++ b/extensions/vw/pdfjs/applib/src/main/java/org/apache/isis/extensions/viewer/wicket/pdfjs/applib/config/PdfJsConfig.java
@@ -29,6 +29,8 @@ import de.agilecoders.wicket.jquery.Key;
  */
 public class PdfJsConfig extends AbstractConfig {
 
+    private static final long serialVersionUID = 1L;
+
     private static final IKey<Integer> INITIAL_PAGE = new Key<>("initialPage", 1);
     private static final IKey<String> INITIAL_SCALE = new Key<>("initialScale", Scale._1_00.getValue());
     private static final IKey<Integer> INITIAL_HEIGHT = new Key<>("initialHeight", 800);
diff --git a/valuetypes/asciidoc/metamodel/src/main/java/org/apache/isis/valuetypes/asciidoc/metamodel/semantics/AsciiDocValueSemantics.java b/valuetypes/asciidoc/metamodel/src/main/java/org/apache/isis/valuetypes/asciidoc/metamodel/semantics/AsciiDocValueSemantics.java
index 4583b5f..0ad11cd 100644
--- a/valuetypes/asciidoc/metamodel/src/main/java/org/apache/isis/valuetypes/asciidoc/metamodel/semantics/AsciiDocValueSemantics.java
+++ b/valuetypes/asciidoc/metamodel/src/main/java/org/apache/isis/valuetypes/asciidoc/metamodel/semantics/AsciiDocValueSemantics.java
@@ -26,7 +26,6 @@ import org.apache.isis.applib.adapters.AbstractValueSemanticsProvider;
 import org.apache.isis.applib.adapters.Parser;
 import org.apache.isis.applib.adapters.Renderer;
 import org.apache.isis.applib.adapters.ValueSemanticsProvider;
-import org.apache.isis.applib.value.Markup;
 import org.apache.isis.valuetypes.asciidoc.applib.value.AsciiDoc;
 
 @Component
@@ -44,11 +43,6 @@ implements
         return render(adoc, AsciiDoc::asHtml);
     }
 
-    @Override
-    public Markup presentationValue(final Context context, final AsciiDoc value) {
-        return Markup.valueOf(simpleTextRepresentation(context, value));
-    }
-
     // -- PARSER
 
     @Override
diff --git a/valuetypes/asciidoc/metamodel/src/main/java/org/apache/isis/valuetypes/asciidoc/metamodel/semantics/ChangesDtoValueSemantics.java b/valuetypes/asciidoc/metamodel/src/main/java/org/apache/isis/valuetypes/asciidoc/metamodel/semantics/ChangesDtoValueSemantics.java
index 82ce7c6..3901daa 100644
--- a/valuetypes/asciidoc/metamodel/src/main/java/org/apache/isis/valuetypes/asciidoc/metamodel/semantics/ChangesDtoValueSemantics.java
+++ b/valuetypes/asciidoc/metamodel/src/main/java/org/apache/isis/valuetypes/asciidoc/metamodel/semantics/ChangesDtoValueSemantics.java
@@ -33,7 +33,7 @@ public class ChangesDtoValueSemantics
 extends XmlValueSemanticsAbstract<ChangesDto> {
 
     @Override
-    protected String asXml(@NonNull final ChangesDto value) {
+    protected String asXml(final Context context, @NonNull final ChangesDto value) {
         return ChangesDtoUtils.toXml(value);
     }
 
diff --git a/valuetypes/asciidoc/metamodel/src/main/java/org/apache/isis/valuetypes/asciidoc/metamodel/semantics/CommandDtoValueSemantics.java b/valuetypes/asciidoc/metamodel/src/main/java/org/apache/isis/valuetypes/asciidoc/metamodel/semantics/CommandDtoValueSemantics.java
index 1db01a7..003246d 100644
--- a/valuetypes/asciidoc/metamodel/src/main/java/org/apache/isis/valuetypes/asciidoc/metamodel/semantics/CommandDtoValueSemantics.java
+++ b/valuetypes/asciidoc/metamodel/src/main/java/org/apache/isis/valuetypes/asciidoc/metamodel/semantics/CommandDtoValueSemantics.java
@@ -33,7 +33,7 @@ public class CommandDtoValueSemantics
 extends XmlValueSemanticsAbstract<CommandDto> {
 
     @Override
-    protected String asXml(@NonNull final CommandDto value) {
+    protected String asXml(final Context context, @NonNull final CommandDto value) {
         return CommandDtoUtils.toXml(value);
     }
 
diff --git a/valuetypes/asciidoc/metamodel/src/main/java/org/apache/isis/valuetypes/asciidoc/metamodel/semantics/InteractionDtoValueSemantics.java b/valuetypes/asciidoc/metamodel/src/main/java/org/apache/isis/valuetypes/asciidoc/metamodel/semantics/InteractionDtoValueSemantics.java
index 6bacaa3..237e3be 100644
--- a/valuetypes/asciidoc/metamodel/src/main/java/org/apache/isis/valuetypes/asciidoc/metamodel/semantics/InteractionDtoValueSemantics.java
+++ b/valuetypes/asciidoc/metamodel/src/main/java/org/apache/isis/valuetypes/asciidoc/metamodel/semantics/InteractionDtoValueSemantics.java
@@ -33,7 +33,7 @@ public class InteractionDtoValueSemantics
 extends XmlValueSemanticsAbstract<InteractionDto> {
 
     @Override
-    protected String asXml(@NonNull final InteractionDto value) {
+    protected String asXml(final Context context, @NonNull final InteractionDto value) {
         return InteractionDtoUtils.toXml(value);
     }
 
diff --git a/valuetypes/asciidoc/metamodel/src/main/java/org/apache/isis/valuetypes/asciidoc/metamodel/semantics/XmlValueSemanticsAbstract.java b/valuetypes/asciidoc/metamodel/src/main/java/org/apache/isis/valuetypes/asciidoc/metamodel/semantics/XmlValueSemanticsAbstract.java
index 2aa8cbb..c9a15a5 100644
--- a/valuetypes/asciidoc/metamodel/src/main/java/org/apache/isis/valuetypes/asciidoc/metamodel/semantics/XmlValueSemanticsAbstract.java
+++ b/valuetypes/asciidoc/metamodel/src/main/java/org/apache/isis/valuetypes/asciidoc/metamodel/semantics/XmlValueSemanticsAbstract.java
@@ -38,14 +38,19 @@ implements
 
     @Override
     public String simpleTextRepresentation(final ValueSemanticsProvider.Context context, final T value) {
-        return render(value, xmlContainer->asHtml(asXml(xmlContainer)));
+        return render(value, xmlContainer->presentationValue(context, value).asHtml());
     }
 
-    protected abstract String asXml(@NonNull T value);
+    @Override
+    public AsciiDoc presentationValue(final Context context, final T value) {
+        return asAdoc(asXml(context, value));
+    }
+
+    protected abstract String asXml(Context context, @NonNull T value);
 
-    private String asHtml(final String xml) {
+    private AsciiDoc asAdoc(final String xml) {
         final var adoc = "[source,xml]\n----\n" + xml + "\n----";
-        return AsciiDoc.valueOf(adoc).asHtml();
+        return AsciiDoc.valueOf(adoc);
     }
 
 }
diff --git a/valuetypes/markdown/metamodel/src/main/java/org/apache/isis/valuetypes/markdown/metamodel/semantics/MarkdownValueSemantics.java b/valuetypes/markdown/metamodel/src/main/java/org/apache/isis/valuetypes/markdown/metamodel/semantics/MarkdownValueSemantics.java
index 6037709..e1a16a0 100644
--- a/valuetypes/markdown/metamodel/src/main/java/org/apache/isis/valuetypes/markdown/metamodel/semantics/MarkdownValueSemantics.java
+++ b/valuetypes/markdown/metamodel/src/main/java/org/apache/isis/valuetypes/markdown/metamodel/semantics/MarkdownValueSemantics.java
@@ -26,7 +26,6 @@ import org.apache.isis.applib.adapters.AbstractValueSemanticsProvider;
 import org.apache.isis.applib.adapters.EncoderDecoder;
 import org.apache.isis.applib.adapters.Parser;
 import org.apache.isis.applib.adapters.Renderer;
-import org.apache.isis.applib.value.Markup;
 import org.apache.isis.valuetypes.markdown.applib.value.Markdown;
 
 @Component
@@ -63,11 +62,6 @@ implements
         return render(value, Markdown::asHtml);
     }
 
-    @Override
-    public Markup presentationValue(final Context context, final Markdown value) {
-        return Markup.valueOf(simpleTextRepresentation(context, value));
-    }
-
     // -- PARSER
 
     @Override
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
deleted file mode 100644
index e2c6e5e..0000000
--- a/viewers/common/src/main/java/org/apache/isis/viewer/common/model/action/form/FormPendingParamUiModel.java
+++ /dev/null
@@ -1,57 +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.viewer.common.model.action.form;
-
-import org.apache.isis.core.metamodel.consent.Consent;
-import org.apache.isis.core.metamodel.consent.InteractionInitiatedBy;
-import org.apache.isis.core.metamodel.interactions.InteractionHead;
-import org.apache.isis.core.metamodel.interactions.managed.ParameterNegotiationModel;
-import org.apache.isis.viewer.common.model.feature.ParameterUiModel;
-
-import lombok.Value;
-import lombok.val;
-
-@Value(staticConstructor = "of")
-public class FormPendingParamUiModel {
-
-    final ParameterUiModel paramModel;
-    final Consent visibilityConsent;
-    final Consent usabilityConsent;
-
-    public static FormPendingParamUiModel of(
-            InteractionHead head,
-            ParameterUiModel paramUiModel,
-            ParameterNegotiationModel pendingArgs) {
-
-        val objectActionParamter = paramUiModel.getMetaModel();
-        val pendingArgValues = pendingArgs.getParamValues();
-
-        paramUiModel.setPendingParameterModel(pendingArgs);
-
-        // visibility
-        val visibilityConsent = objectActionParamter
-                .isVisible(head, pendingArgValues, InteractionInitiatedBy.USER);
-
-        // usability
-        val usabilityConsent = objectActionParamter
-                .isUsable(head, pendingArgValues, InteractionInitiatedBy.USER);
-
-        return of(paramUiModel, visibilityConsent, usabilityConsent);
-    }
-}
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 d8003cc..d7179da 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
@@ -47,7 +47,7 @@ public interface FormUiModel extends HasTitle {
      */
     ManagedObject getOwner();
 
-    Stream<FormPendingParamUiModel> streamPendingParamUiModels();
+    Stream<? extends ParameterUiModel> streamPendingParamUiModels();
 
     // -- USABILITY
 
@@ -72,7 +72,6 @@ public interface FormUiModel extends HasTitle {
     default Consent getValidityConsent() {
 
         val proposedArguments = streamPendingParamUiModels()
-                .map(FormPendingParamUiModel::getParamModel)
                 .map(ParameterUiModel::getValue)
                 .collect(Can.toCan());
 
@@ -101,13 +100,11 @@ public interface FormUiModel extends HasTitle {
     @Override
     default String getTitle() {
         val target = getOwner();
-        val objectAction = getMetaModel();
 
         val buf = new StringBuilder();
 
         streamPendingParamUiModels()
-        .filter(argAndConsent->argAndConsent.getVisibilityConsent().isAllowed())
-        .map(FormPendingParamUiModel::getParamModel)
+        .filter(paramModel->paramModel.getPendingParameterModel().getVisibilityConsent(paramModel.getNumber()).isAllowed())
         .map(ParameterUiModel::getValue)
         .forEach(paramValue->{
             if(buf.length() > 0) {
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 f10f924..6b9ef04 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
@@ -45,7 +45,6 @@ public interface ParameterUiModel extends ScalarUiModel {
     // -- PENDING PARAMETER MODEL
 
     ParameterNegotiationModel getPendingParameterModel();
-    void setPendingParameterModel(ParameterNegotiationModel pendingArgs);
 
     // -- SHORTCUTS
 
diff --git a/viewers/common/src/main/java/org/apache/isis/viewer/common/model/feature/ScalarUiModel.java b/viewers/common/src/main/java/org/apache/isis/viewer/common/model/feature/ScalarUiModel.java
index b25c502..803e327 100644
--- a/viewers/common/src/main/java/org/apache/isis/viewer/common/model/feature/ScalarUiModel.java
+++ b/viewers/common/src/main/java/org/apache/isis/viewer/common/model/feature/ScalarUiModel.java
@@ -89,4 +89,6 @@ public interface ScalarUiModel {
     Can<ManagedObject> getChoices();
     Can<ManagedObject> getAutoComplete(final String searchArg);
 
+
+
 }
diff --git a/viewers/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/ActionArgumentCache.java b/viewers/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/ActionArgumentCache.java
deleted file mode 100644
index 8eac2c3..0000000
--- a/viewers/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/ActionArgumentCache.java
+++ /dev/null
@@ -1,146 +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.viewer.wicket.model.models;
-
-import java.util.Map;
-import java.util.Optional;
-import java.util.function.Supplier;
-import java.util.stream.IntStream;
-import java.util.stream.Stream;
-
-import org.apache.isis.commons.collections.Can;
-import org.apache.isis.commons.internal.assertions._Assert;
-import org.apache.isis.commons.internal.collections._Maps;
-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.ObjectActionParameter;
-import org.apache.isis.core.metamodel.spec.feature.memento.ActionMemento;
-import org.apache.isis.core.metamodel.spec.feature.memento.ActionParameterMemento;
-import org.apache.isis.viewer.common.model.action.form.PendingParameterManager;
-import org.apache.isis.viewer.common.model.feature.ParameterUiModel;
-
-import lombok.NonNull;
-import lombok.RequiredArgsConstructor;
-import lombok.val;
-
-@RequiredArgsConstructor
-class ActionArgumentCache implements PendingParameterManager {
-
-    @NonNull private final EntityModel entityModel;
-    @NonNull private final ActionMemento actionMemento;
-    @NonNull private final ObjectAction action;
-
-    private final Map<Integer, ParameterUiModel> arguments = _Maps.newHashMap();
-
-    public ActionArgumentCache copy() {
-        val copy = new ActionArgumentCache(
-                entityModel,
-                actionMemento,
-                action);
-        primeArgumentModels();
-        for (val argumentEntry : arguments.entrySet()) {
-            putArgumentValue(argumentEntry.getKey(), argumentEntry.getValue().getValue());
-        }
-        return copy;
-    }
-
-    public Can<ManagedObject> snapshot() {
-
-        val paramTypes = action.getParameterTypes();
-
-        return streamParamNumbers()
-        .mapToObj(paramIndex->{
-            final var actionArgumentModel = Optional.ofNullable(arguments.get(paramIndex));
-            final var adapter = actionArgumentModel
-                    .map(ParameterUiModel::getValue)
-                    .orElse(ManagedObject.empty(paramTypes.getElseFail(paramIndex)));
-            return adapter;
-
-        })
-        .collect(Can.toCan());
-    }
-
-    public void resetTo(final Can<ManagedObject> defaultsFixedPoint) {
-
-        arguments.clear();
-
-        streamParamUiModels()
-        .forEach(actionArgumentModel -> {
-            int paramIndex = actionArgumentModel.getNumber();
-            final var paramDefaultValue = defaultsFixedPoint.getElseFail(paramIndex);
-            actionArgumentModel.setValue(paramDefaultValue);
-        });
-    }
-
-    public Stream<ParameterUiModel> streamParamUiModels() {
-        return streamParamNumbers()
-                .mapToObj(paramIndex->
-                    arguments.computeIfAbsent(paramIndex, this::createArgumentModel));
-    }
-
-    @Override
-    public void setParameterValue(final ObjectActionParameter actionParameter, final ManagedObject newParamValue) {
-        val actionArgumentModel = computeIfAbsent(actionParameter.getNumber(), actionParameter::getMemento);
-        actionArgumentModel.setValue(newParamValue);
-    }
-
-    @Override
-    public void clearParameterValue(final ObjectActionParameter actionParameter) {
-        setParameterValue(actionParameter, null);
-    }
-
-    // //////////////////////////////////////
-
-    private IntStream streamParamNumbers() {
-        val paramCount = action.getParameterCount();
-        return IntStream.range(0, paramCount);
-    }
-
-    private ParameterUiModel createArgumentModel(final int paramIndex) {
-        val param = action.getParameters().getElseFail(paramIndex);
-        val actionArgumentModel = new ScalarParameterModel(entityModel, param.getMemento());
-        return actionArgumentModel;
-    }
-
-    private void primeArgumentModels() {
-        _Assert.assertEquals(
-                action.getParameterCount(),
-                (int)streamParamUiModels().count());
-    }
-
-    private ParameterUiModel computeIfAbsent(
-            final int paramNumber,
-            final Supplier<ActionParameterMemento> apm) {
-
-        ParameterUiModel actionArgumentModel = arguments.get(paramNumber);
-        if (actionArgumentModel == null) {
-            actionArgumentModel = new ScalarParameterModel(entityModel, apm.get());
-            final int number = actionArgumentModel.getNumber();
-            arguments.put(number, actionArgumentModel);
-        }
-        return actionArgumentModel;
-    }
-
-    private void putArgumentValue(final int paramNum, final ManagedObject argumentAdapter) {
-        val actionParam = action.getParameters().getElseFail(paramNum);
-        setParameterValue(actionParam, argumentAdapter);
-    }
-
-
-}
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 99d9f88..7167069 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
@@ -49,9 +49,8 @@ import org.apache.isis.core.metamodel.facetapi.Facet;
 import org.apache.isis.core.metamodel.facetapi.FacetHolder;
 import org.apache.isis.core.metamodel.facets.object.bookmarkpolicy.BookmarkPolicyFacet;
 import org.apache.isis.core.metamodel.facets.object.promptStyle.PromptStyleFacet;
-import org.apache.isis.core.metamodel.interactions.InteractionHead;
+import org.apache.isis.core.metamodel.interactions.managed.ActionInteraction;
 import org.apache.isis.core.metamodel.interactions.managed.ActionInteractionHead;
-import org.apache.isis.core.metamodel.interactions.managed.ParameterNegotiationModel;
 import org.apache.isis.core.metamodel.spec.ManagedObject;
 import org.apache.isis.core.metamodel.spec.ManagedObjects;
 import org.apache.isis.core.metamodel.spec.ObjectSpecification;
@@ -59,8 +58,9 @@ import org.apache.isis.core.metamodel.spec.feature.ObjectAction;
 import org.apache.isis.core.metamodel.spec.feature.ObjectActionParameter;
 import org.apache.isis.core.metamodel.spec.feature.memento.ActionMemento;
 import org.apache.isis.core.runtime.context.IsisAppCommonContext;
-import org.apache.isis.viewer.common.model.action.form.FormPendingParamUiModel;
 import org.apache.isis.viewer.common.model.action.form.FormUiModel;
+import org.apache.isis.viewer.wicket.model.models.interaction.action.ActionInteractionModelWkt;
+import org.apache.isis.viewer.wicket.model.models.interaction.action.ParameterUiModelWkt;
 
 import lombok.NonNull;
 import lombok.val;
@@ -99,7 +99,7 @@ implements FormUiModel, FormExecutorContext, BookmarkableModel {
     public PageParameters getPageParametersWithoutUiHints() {
         val adapter = getOwner();
         val objectAction = getMetaModel();
-        return PageParameterUtil.createPageParametersForAction(adapter, objectAction, argCache().snapshot());
+        return PageParameterUtil.createPageParametersForAction(adapter, objectAction, snapshotArgs());
     }
 
     @Override
@@ -130,18 +130,7 @@ implements FormUiModel, FormExecutorContext, BookmarkableModel {
     private final ActionMemento actionMemento;
 
     // lazy in support of serialization of this class
-    private transient ActionArgumentCache argCache;
-    private ActionArgumentCache argCache() {
-        return argCache!=null
-                ? argCache
-                : (argCache = createActionArgumentCache());
-    }
-    private ActionArgumentCache createActionArgumentCache() {
-        return new ActionArgumentCache(
-                ownerModel,
-                actionMemento,
-                getMetaModel());
-    }
+    private transient ActionInteractionModelWkt actionInteractionModel;
 
     private ActionModel(final EntityModel entityModel, final ActionMemento actionMemento) {
         super(entityModel.getCommonContext());
@@ -156,7 +145,22 @@ implements FormUiModel, FormExecutorContext, BookmarkableModel {
         super(actionModel.getCommonContext());
         this.ownerModel = actionModel.ownerModel;
         this.actionMemento = actionModel.actionMemento;
-        this.argCache = actionModel.argCache().copy();
+    }
+
+    private ActionInteractionModelWkt actionInteractionModel() {
+        if(actionInteractionModel==null) {
+            actionInteractionModel = new ActionInteractionModelWkt(
+                    getCommonContext(),
+                    ActionInteraction.start(
+                            ownerModel.getManagedObject(),
+                            actionMemento.getIdentifier().getMemberLogicalName(),
+                            WHERE_FOR_ACTION_INVOCATION));
+        }
+        return actionInteractionModel;
+    }
+
+    private Can<ManagedObject> snapshotArgs() {
+        return actionInteractionModel().parameterNegotiationModel().get().getParamValues();
     }
 
     @Override
@@ -186,7 +190,7 @@ implements FormUiModel, FormExecutorContext, BookmarkableModel {
     private ManagedObject executeAction() {
 
         val targetAdapter = getOwner();
-        final Can<ManagedObject> arguments = argCache().snapshot();
+        final Can<ManagedObject> arguments = snapshotArgs();
         final ObjectAction action = getMetaModel();
 
         val head = action.interactionHead(targetAdapter);
@@ -217,23 +221,11 @@ implements FormUiModel, FormExecutorContext, BookmarkableModel {
         throw new UnsupportedOperationException("target adapter for ActionModel cannot be changed");
     }
 
-    public ParameterNegotiationModel getArgumentsAsParamModel() {
-        return getMetaModel().interactionHead(getOwner())
-                .model(argCache().snapshot());
-    }
-
-
     /** Resets arguments to their fixed point default values
      * @see ActionInteractionHead#defaults()
      */
     public void clearArguments() {
-
-        val defaultsFixedPoint = getMetaModel()
-                .interactionHead(getOwner())
-                .defaults()
-                .getParamValues();
-
-        argCache().resetTo(defaultsFixedPoint);
+        actionInteractionModel().resetParametersToDefault();
     }
 
     /**
@@ -394,40 +386,26 @@ implements FormUiModel, FormExecutorContext, BookmarkableModel {
     }
 
     public void setParameterValue(final ObjectActionParameter actionParameter, final ManagedObject newParamValue) {
-        argCache().setParameterValue(actionParameter, newParamValue);
+        actionInteractionModel().parameterNegotiationModel().get().setParamValue(actionParameter.getNumber(), newParamValue);
     }
 
     public void clearParameterValue(final ObjectActionParameter actionParameter) {
-        argCache().clearParameterValue(actionParameter);
+        actionInteractionModel().parameterNegotiationModel().get().clearParamValue(actionParameter.getNumber());
     }
 
     @Override
-    public Stream<FormPendingParamUiModel> streamPendingParamUiModels() {
-
-        val owner = this.getOwner();
-        val target = this.getMetaModel().realTargetAdapter(owner);
-        val pendingArgs = getArgumentsAsParamModel();
-
-        val head = InteractionHead.mixin(owner, target);
-
-        return argCache()
-        .streamParamUiModels()
-        .map(paramUiModel->{
-            return FormPendingParamUiModel.of(head, paramUiModel, pendingArgs);
-        });
-
+    public Stream<ParameterUiModelWkt> streamPendingParamUiModels() {
+        return actionInteractionModel().streamParameterUiModels();
     }
 
     public void reassessPendingParamUiModels(final int skipCount) {
 
-        val pendingArgs = getArgumentsAsParamModel();
-
-        argCache()
-        .streamParamUiModels()
+        actionInteractionModel().streamParameterUiModels()
         .skip(skipCount)
-        .forEach(actionArgumentModel->{
+        .forEach(paramUiModel->{
 
-            val actionParameter = actionArgumentModel.getMetaModel();
+            val pendingArgs = paramUiModel.getPendingParameterModel();
+            val actionParameter = paramUiModel.getMetaModel();
             val paramDefaultValue = actionParameter.getDefault(pendingArgs);
 
             if (ManagedObjects.isNullOrUnspecifiedOrEmpty(paramDefaultValue)) {
diff --git a/viewers/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/EntityModel.java b/viewers/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/EntityModel.java
index ddda36a..832da8b 100644
--- a/viewers/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/EntityModel.java
+++ b/viewers/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/EntityModel.java
@@ -77,7 +77,7 @@ implements HasRenderingHints, ObjectAdapterModel, UiHintContainer, ObjectUiModel
 
     // -- FACTORIES
 
-    public static EntityModel ofParameters(
+    public static EntityModel ofPageParameters(
             final IsisAppCommonContext commonContext,
             final PageParameters pageParameters) {
 
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 83614ae..1cdbefc 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
@@ -32,7 +32,6 @@ import org.apache.isis.core.metamodel.interactions.managed.ManagedValue;
 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.memento.ActionParameterMemento;
 import org.apache.isis.core.metamodel.spec.feature.memento.PropertyMemento;
 import org.apache.isis.viewer.common.model.feature.ScalarUiModel;
 import org.apache.isis.viewer.common.model.object.ObjectUiModel;
@@ -89,8 +88,7 @@ implements HasRenderingHints, ScalarUiModel, LinksProvider, FormExecutorContext
      * value (if any) of that action parameter.
      */
     protected ScalarModel(
-            final EntityModel parentEntityModel,
-            final ActionParameterMemento apm) {
+            final EntityModel parentEntityModel) {
 
         super(parentEntityModel.getCommonContext());
 
@@ -225,7 +223,7 @@ implements HasRenderingHints, ScalarUiModel, LinksProvider, FormExecutorContext
     }
 
     @Override
-    public PromptStyle getPromptStyle() {
+    public final PromptStyle getPromptStyle() {
         final PromptStyleFacet facet = getFacet(PromptStyleFacet.class);
         if(facet == null) {
             // don't think this can happen actually, see PromptStyleFacetFallback
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 b10acd9..361d9b3 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,10 +20,7 @@ package org.apache.isis.viewer.wicket.model.models;
 
 import org.springframework.lang.Nullable;
 
-import org.apache.isis.applib.annotation.Where;
 import org.apache.isis.commons.collections.Can;
-import org.apache.isis.core.metamodel.consent.InteractionInitiatedBy;
-import org.apache.isis.core.metamodel.interactions.managed.ManagedAction;
 import org.apache.isis.core.metamodel.interactions.managed.ManagedValue;
 import org.apache.isis.core.metamodel.interactions.managed.ParameterNegotiationModel;
 import org.apache.isis.core.metamodel.spec.ManagedObject;
@@ -31,12 +28,8 @@ import org.apache.isis.core.metamodel.spec.ManagedObjects;
 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.spec.feature.memento.ActionParameterMemento;
 import org.apache.isis.viewer.common.model.feature.ParameterUiModel;
-
-import lombok.Getter;
-import lombok.Setter;
-import lombok.val;
+import org.apache.isis.viewer.wicket.model.models.interaction.action.ParameterUiModelWkt;
 
 public class ScalarParameterModel
 extends ScalarModel
@@ -44,43 +37,26 @@ implements ParameterUiModel {
 
     private static final long serialVersionUID = 1L;
 
-    private final ActionParameterMemento paramMemento;
+    public static ScalarParameterModel wrap(final ParameterUiModelWkt delegate) {
+        return new ScalarParameterModel(delegate);
+    }
 
-    @Getter(onMethod_ = {@Override})
-    @Setter(onMethod_ = {@Override})
-    private transient ParameterNegotiationModel pendingParameterModel;
+    private final ParameterUiModel delegate;
 
     /**
      * Creates a model representing an action parameter of an action of a parent
      * object, with the {@link #getObject() value of this model} to be default
      * value (if any) of that action parameter.
      */
-    public ScalarParameterModel(
-            final EntityModel parentEntityModel,
-            final ActionParameterMemento paramMemento) {
-        super(parentEntityModel, paramMemento);
-        this.paramMemento = paramMemento;
+    private ScalarParameterModel(
+            final ParameterUiModelWkt delegate) {
+        super(EntityModel.ofAdapter(delegate.getCommonContext(), delegate.getOwner()));
+        this.delegate = delegate;
     }
 
-    private transient ObjectActionParameter actionParameter;
-
     @Override
     public ObjectActionParameter getMetaModel() {
-        if(actionParameter==null) {
-            actionParameter = paramMemento.getActionParameter(this::getSpecificationLoader);
-        }
-        return actionParameter;
-    }
-
-    private transient ManagedAction managedAction;
-
-    public ManagedAction getManagedAction() {
-        if(managedAction==null) {
-            val actionOwner = getParentUiModel().load();
-            // TODO 'where' is not used until whetherDisabled and whetherHidden are implemented
-            managedAction = ManagedAction.of(actionOwner, getMetaModel().getAction(), Where.ANYWHERE);
-        }
-        return managedAction;
+        return delegate.getMetaModel();
     }
 
     @Override
@@ -100,32 +76,17 @@ implements ParameterUiModel {
 
     @Override
     public String whetherDisabled() {
-        // always enabled TODO this is not true
-        return null;
+        return getPendingParameterModel().getUsabilityConsent(getNumber()).getReason();
     }
 
     @Override
     public boolean whetherHidden() {
-        // always enabled TODO this is not true
-        return false;
+        return getPendingParameterModel().getVisibilityConsent(getNumber()).isVetoed();
     }
 
     @Override
     public String validate(final ManagedObject proposedValue) {
-        final ObjectActionParameter parameter = getMetaModel();
-
-        val action = parameter.getAction();
-        try {
-            ManagedObject parentAdapter = getParentUiModel().load();
-
-            val head = action.interactionHead(parentAdapter);
-
-            final String invalidReasonIfAny = parameter
-                    .isValid(head, proposedValue, InteractionInitiatedBy.USER);
-            return invalidReasonIfAny;
-        } catch (final Exception ex) {
-            return ex.getLocalizedMessage();
-        }
+        return getPendingParameterModel().getObservableParamValidation(getNumber()).getValue();
     }
 
     @Override
@@ -135,7 +96,7 @@ implements ParameterUiModel {
 
     @Override
     public String toStringOf() {
-        return getFriendlyName() + ": " + paramMemento.toString();
+        return getFriendlyName() + ": " + getNumber();
     }
 
     @Override
@@ -155,7 +116,12 @@ implements ParameterUiModel {
 
     @Override
     public ManagedValue proposedValue() {
-        return getPendingParameterModel().getParamModels().getElseFail(paramMemento.getNumber());
+        return getPendingParameterModel().getParamModels().getElseFail(getNumber());
+    }
+
+    @Override
+    public ParameterNegotiationModel getPendingParameterModel() {
+        return delegate.getPendingParameterModel();
     }
 
     // -- HELPER
@@ -169,4 +135,5 @@ implements ParameterUiModel {
 
 
 
+
 }
diff --git a/viewers/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/interaction/action/ActionInteractionModelWkt.java b/viewers/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/interaction/action/ActionInteractionModelWkt.java
new file mode 100644
index 0000000..2b281d8
--- /dev/null
+++ b/viewers/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/interaction/action/ActionInteractionModelWkt.java
@@ -0,0 +1,101 @@
+/*
+ *  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.viewer.wicket.model.models.interaction.action;
+
+import java.util.Optional;
+import java.util.stream.IntStream;
+import java.util.stream.Stream;
+
+import org.apache.isis.commons.collections.Can;
+import org.apache.isis.commons.internal.assertions._Assert;
+import org.apache.isis.commons.internal.base._Lazy;
+import org.apache.isis.core.metamodel.interactions.managed.ActionInteraction;
+import org.apache.isis.core.metamodel.interactions.managed.ParameterNegotiationModel;
+import org.apache.isis.core.runtime.context.IsisAppCommonContext;
+import org.apache.isis.viewer.wicket.model.models.ModelAbstract;
+
+/**
+ *
+ * The parent of multiple parameter models which implement
+ * {@link _ActionInteractionHolder}.
+ *
+ * @see _ActionInteractionHolder
+ */
+public final class ActionInteractionModelWkt
+extends ModelAbstract<ActionInteraction> {
+
+    private static final long serialVersionUID = 1L;
+
+    private final ActionInteraction.Memento memento;
+    private final Can<ParameterUiModelWkt> childModels;
+
+    public ActionInteractionModelWkt(
+            final IsisAppCommonContext commonContext,
+            final ActionInteraction model) {
+        super(commonContext, model);
+        this.memento = model.memento();
+
+        final int paramCount = model.getMetamodel().get().getParameterCount();
+        this.childModels = IntStream.range(0, paramCount)
+                .mapToObj(paramIndex -> new ParameterUiModelWkt(this, paramIndex))
+                .collect(Can.toCan());
+    }
+
+    @Override
+    protected final ActionInteraction load() {
+        childModels.forEach(childModel->childModel.attachToContainerModel(this));
+        return memento.restore();
+    }
+
+    @Override
+    public void detach() {
+        childModels.forEach(_ActionInteractionHolder::detachFromContainerModel);
+        super.detach();
+    }
+
+    protected final ActionInteraction actionInteraction() {
+        return getObject();
+    }
+
+    public ParameterUiModelWkt getParameterUiModel(final int paramIndex) {
+        return childModels.getElseFail(paramIndex);
+    }
+
+    public Stream<ParameterUiModelWkt> streamParameterUiModels() {
+        return childModels.stream();
+    }
+
+    // -- PARAMETER NEGOTIATION WITH MEMOIZATION (TRANSIENT)
+
+    private final transient _Lazy<Optional<ParameterNegotiationModel>> parameterNegotiationModel =
+            _Lazy.threadSafe(()->actionInteraction().startParameterNegotiation());
+
+    public final Optional<ParameterNegotiationModel> parameterNegotiationModel() {
+        _Assert.assertTrue(this.isAttached(), "container model is not attached");
+        return parameterNegotiationModel.get();
+    }
+
+    public void resetParametersToDefault() {
+        parameterNegotiationModel.clear();
+    }
+
+
+
+
+}
diff --git a/valuetypes/asciidoc/metamodel/src/main/java/org/apache/isis/valuetypes/asciidoc/metamodel/semantics/ChangesDtoValueSemantics.java b/viewers/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/interaction/action/ObjectUiModelWkt.java
similarity index 60%
copy from valuetypes/asciidoc/metamodel/src/main/java/org/apache/isis/valuetypes/asciidoc/metamodel/semantics/ChangesDtoValueSemantics.java
copy to viewers/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/interaction/action/ObjectUiModelWkt.java
index 82ce7c6..f4d2c4e 100644
--- a/valuetypes/asciidoc/metamodel/src/main/java/org/apache/isis/valuetypes/asciidoc/metamodel/semantics/ChangesDtoValueSemantics.java
+++ b/viewers/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/interaction/action/ObjectUiModelWkt.java
@@ -16,25 +16,12 @@
  *  specific language governing permissions and limitations
  *  under the License.
  */
-package org.apache.isis.valuetypes.asciidoc.metamodel.semantics;
+package org.apache.isis.viewer.wicket.model.models.interaction.action;
 
-import javax.inject.Named;
+import org.apache.isis.viewer.common.model.object.ObjectUiModel;
 
-import org.springframework.stereotype.Component;
-
-import org.apache.isis.applib.util.schema.ChangesDtoUtils;
-import org.apache.isis.schema.chg.v2.ChangesDto;
-
-import lombok.NonNull;
-
-@Component
-@Named("isis.val.ChangesDtoValueSemantics")
-public class ChangesDtoValueSemantics
-extends XmlValueSemanticsAbstract<ChangesDto> {
-
-    @Override
-    protected String asXml(@NonNull final ChangesDto value) {
-        return ChangesDtoUtils.toXml(value);
-    }
+@FunctionalInterface
+public interface ObjectUiModelWkt
+extends ObjectUiModel {
 
 }
diff --git a/viewers/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/interaction/action/ParameterUiModelWkt.java b/viewers/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/interaction/action/ParameterUiModelWkt.java
new file mode 100644
index 0000000..e0d80d3
--- /dev/null
+++ b/viewers/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/interaction/action/ParameterUiModelWkt.java
@@ -0,0 +1,107 @@
+/*
+ *  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.viewer.wicket.model.models.interaction.action;
+
+import org.apache.isis.commons.collections.Can;
+import org.apache.isis.core.metamodel.interactions.managed.ParameterNegotiationModel;
+import org.apache.isis.core.metamodel.spec.ManagedObject;
+import org.apache.isis.core.metamodel.spec.feature.ObjectActionParameter;
+import org.apache.isis.viewer.common.model.HasParentUiModel;
+import org.apache.isis.viewer.common.model.feature.ParameterUiModel;
+import org.apache.isis.viewer.common.model.object.ObjectUiModel.HasRenderingHints;
+import org.apache.isis.viewer.common.model.object.ObjectUiModel.Mode;
+import org.apache.isis.viewer.common.model.object.ObjectUiModel.RenderingHint;
+import org.apache.isis.viewer.wicket.model.links.LinkAndLabel;
+import org.apache.isis.viewer.wicket.model.links.LinksProvider;
+
+import lombok.Getter;
+import lombok.NonNull;
+import lombok.Setter;
+
+public final class ParameterUiModelWkt
+extends _ActionInteractionHolder
+implements
+    HasParentUiModel<ObjectUiModelWkt>,
+    HasRenderingHints, ParameterUiModel, LinksProvider {
+
+    private static final long serialVersionUID = 1L;
+
+    final int paramIndex;
+
+    public ParameterUiModelWkt(
+            final ActionInteractionModelWkt model,
+            final int paramIndex) {
+        super(model);
+        this.paramIndex = paramIndex;
+    }
+
+    @Getter(onMethod = @__(@Override))
+    @Setter(onMethod = @__(@Override))
+    private Mode mode;
+
+    @Getter(onMethod = @__(@Override))
+    @Setter(onMethod = @__(@Override))
+    private RenderingHint renderingHint;
+
+    @Override
+    public ObjectUiModelWkt getParentUiModel() {
+        return ()->getOwner();
+    }
+
+    @Override
+    public ManagedObject getOwner() {
+        return actionInteraction().getManagedAction().get().getOwner();
+    }
+
+    @Override
+    public ObjectActionParameter getMetaModel() {
+        return actionInteraction().getMetamodel().get().getParameters().getElseFail(paramIndex);
+    }
+
+    @Override
+    public Can<LinkAndLabel> getLinks() {
+        return Can.empty();
+    }
+
+    @Override
+    public boolean isInlinePrompt() {
+        return false;
+    }
+
+    @Override
+    public String getCssClass() {
+        return getMetaModel().getCssClass("isis-");
+    }
+
+    @Override
+    public @NonNull ManagedObject getValue() {
+        return getPendingParameterModel().getParamValue(paramIndex);
+    }
+
+    @Override
+    public void setValue(final ManagedObject paramValue) {
+        getPendingParameterModel().setParamValue(paramIndex, paramValue);
+    }
+
+    @Override
+    public ParameterNegotiationModel getPendingParameterModel() {
+        return containerModel().parameterNegotiationModel().get();
+    }
+
+}
diff --git a/viewers/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/interaction/action/_ActionInteractionHolder.java b/viewers/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/interaction/action/_ActionInteractionHolder.java
new file mode 100644
index 0000000..46cd608
--- /dev/null
+++ b/viewers/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/interaction/action/_ActionInteractionHolder.java
@@ -0,0 +1,79 @@
+/*
+ *  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.viewer.wicket.model.models.interaction.action;
+
+import java.io.Serializable;
+
+import org.apache.wicket.model.IModel;
+
+import org.apache.isis.commons.internal.assertions._Assert;
+import org.apache.isis.core.metamodel.interactions.managed.ActionInteraction;
+import org.apache.isis.core.runtime.context.IsisAppCommonContext;
+import org.apache.isis.core.runtime.context.IsisAppCommonContext.HasCommonContext;
+
+import lombok.NonNull;
+import lombok.RequiredArgsConstructor;
+
+/**
+ * Implemented by a <i>Parameter Interaction Model</i>,
+ * which is a holder of a shared <i>Action Interaction Model</i>.
+ * <p>
+ * Multiple param models share a single action interaction.
+ * This sharing relation must survive a de-serialze/serialize cycle.
+ * @apiNote {@link Serializable}, but not an {@link IModel}, such that the
+ * parent <i>Action Interaction Model</i> can take full control of serialization.
+ * That is, it will inject the shared parent instance into this model
+ * which is a <i>transient</i> field.
+ */
+@RequiredArgsConstructor
+abstract class _ActionInteractionHolder
+implements
+    HasCommonContext,
+    Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    private transient @NonNull ActionInteractionModelWkt actionInteractionModelWkt;
+
+    @Override
+    public final IsisAppCommonContext getCommonContext() {
+        return actionInteractionModelWkt.getCommonContext();
+    }
+
+    protected final ActionInteractionModelWkt containerModel() {
+        _Assert.assertNotNull(actionInteractionModelWkt, "detached from container model");
+        return actionInteractionModelWkt;
+    }
+
+    public final ActionInteraction actionInteraction() {
+        _Assert.assertNotNull(this.actionInteractionModelWkt, "already detached from container model");
+        return actionInteractionModelWkt.actionInteraction();
+    }
+
+    public void attachToContainerModel(final @NonNull ActionInteractionModelWkt actionInteractionModelWkt) {
+        _Assert.assertNull(this.actionInteractionModelWkt, "cannot attach, already attached to container model");
+        this.actionInteractionModelWkt = actionInteractionModelWkt;
+    }
+
+    public void detachFromContainerModel() {
+        this.actionInteractionModelWkt = null;
+    }
+
+
+}
diff --git a/viewers/wicket/model/src/test/java/org/apache/isis/viewer/wicket/model/models/ScalarModel_isScalarSubtypingAnyOf_Test.java b/viewers/wicket/model/src/test/java/org/apache/isis/viewer/wicket/model/models/ScalarModel_isScalarSubtypingAnyOf_Test.java
deleted file mode 100644
index 7f4d17f..0000000
--- a/viewers/wicket/model/src/test/java/org/apache/isis/viewer/wicket/model/models/ScalarModel_isScalarSubtypingAnyOf_Test.java
+++ /dev/null
@@ -1,106 +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.viewer.wicket.model.models;
-
-import org.jmock.Expectations;
-import org.jmock.auto.Mock;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-
-import static org.hamcrest.CoreMatchers.equalTo;
-import static org.hamcrest.CoreMatchers.is;
-import static org.hamcrest.MatcherAssert.assertThat;
-
-import org.apache.isis.core.metamodel._testing.MetaModelContext_forTesting;
-import org.apache.isis.core.metamodel.context.MetaModelContext;
-import org.apache.isis.core.metamodel.objectmanager.ObjectManager;
-import org.apache.isis.core.metamodel.spec.ObjectSpecification;
-import org.apache.isis.core.runtime.context.IsisAppCommonContext;
-import org.apache.isis.core.runtime.memento.ObjectMementoService;
-import org.apache.isis.core.internaltestsupport.jmocking.JUnitRuleMockery2;
-
-import lombok.val;
-
-public class ScalarModel_isScalarSubtypingAnyOf_Test {
-
-    @Rule public JUnitRuleMockery2 context = 
-            JUnitRuleMockery2.createFor(JUnitRuleMockery2.Mode.INTERFACES_AND_CLASSES);
-
-    @Mock ObjectSpecification mockObjectSpecification;
-    @Mock EntityModel mockEntityModel;
-    @Mock ObjectMementoService mockObjectAdapterMementoSupport;
-    @Mock ObjectManager mockObjectManager; 
-    
-    MetaModelContext metaModelContext;
-
-    public static class A {}
-    public static class B extends A {}
-    public static class C extends B {}
-
-    @Before
-    public void setup() {
-        
-        metaModelContext = MetaModelContext_forTesting.builder()
-                .objectManager(mockObjectManager)
-                .singleton(mockObjectAdapterMementoSupport)
-                .build();
-        
-        val commonContext = IsisAppCommonContext.of(metaModelContext);
-        
-        context.checking(new Expectations() {{
-            
-            allowing(mockEntityModel).getCommonContext();
-            will(returnValue(commonContext));
-
-
-        }});
-        
-    }
-    
-    @Test
-    public void when_super() {
-        assertThat(newScalarModelFor(A.class).isScalarTypeSubtypeOf(B.class), is(equalTo(false)));
-    }
-
-    @Test
-    public void when_same() {
-        assertThat(newScalarModelFor(B.class).isScalarTypeSubtypeOf(B.class), is(equalTo(true)));
-    }
-
-    @Test
-    public void when_sub() {
-        assertThat(newScalarModelFor(C.class).isScalarTypeSubtypeOf(B.class), is(equalTo(true)));
-    }
-
-    private ScalarModel newScalarModelFor(final Class<?> result) {
-        val scalarModel = new ScalarParameterModel(mockEntityModel, null) {
-            private static final long serialVersionUID = 1L;
-
-            @Override public ObjectSpecification getTypeOfSpecification() {
-                return mockObjectSpecification;
-            }
-        };
-        context.checking(new Expectations() {{
-            allowing(mockObjectSpecification).getCorrespondingClass();
-            will(returnValue(result));
-        }});
-        return scalarModel;
-    }
-}
\ No newline at end of file
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 1c73b4b..228e766 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
@@ -38,15 +38,15 @@ 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.ActionModel;
 import org.apache.isis.viewer.wicket.model.models.ScalarParameterModel;
+import org.apache.isis.viewer.wicket.model.models.interaction.action.ParameterUiModelWkt;
 import org.apache.isis.viewer.wicket.ui.components.scalars.ScalarPanelAbstract;
 import org.apache.isis.viewer.wicket.ui.panels.FormExecutorStrategy;
 import org.apache.isis.viewer.wicket.ui.panels.PromptFormAbstract;
 import org.apache.isis.viewer.wicket.ui.util.CssClassAppender;
 import org.apache.isis.viewer.wicket.ui.util.Decorators;
 
-import lombok.val;
-
 import de.agilecoders.wicket.extensions.markup.html.bootstrap.confirmation.ConfirmationBehavior;
+import lombok.val;
 
 class ActionParametersForm extends PromptFormAbstract<ActionModel> {
 
@@ -66,17 +66,16 @@ class ActionParametersForm extends PromptFormAbstract<ActionModel> {
 
     @Override
     protected void addParameters() {
-        val actionModel = getActionModel();
+        final var actionModel = getActionModel();
 
-        val repeatingView = new RepeatingView(ActionParametersFormPanel.ID_ACTION_PARAMETERS);
+        final var repeatingView = new RepeatingView(ActionParametersFormPanel.ID_ACTION_PARAMETERS);
         add(repeatingView);
 
         paramPanels.clear();
 
         actionModel.streamPendingParamUiModels()
-        .forEach(argsAndConsents->{
-
-            val paramModel = (ScalarParameterModel) argsAndConsents.getParamModel();
+        .map(ParameterUiModelWkt.class::cast)
+        .forEach(paramModel->{
 
             val container = new WebMarkupContainer(repeatingView.newChildId());
             repeatingView.add(container);
@@ -84,27 +83,27 @@ class ActionParametersForm extends PromptFormAbstract<ActionModel> {
             newParamPanel(container, paramModel)
             .ifPresent(paramPanel->{
                 paramPanels.add(paramPanel);
-                //val paramModel = (ScalarParameterModel) paramPanel.getModel();
-                paramPanel.postInit(argsAndConsents);
             });
 
         });
 
         setOutputMarkupId(true);
-
-
     }
 
     private Optional<ScalarPanelAbstract> newParamPanel(
             final WebMarkupContainer container,
-            final ScalarParameterModel paramModel) {
+            final ParameterUiModelWkt paramModel) {
+
+        val id = "scalarNameAndValue"; //paramModel.getNumber()
+
+        val scalarParamModel = ScalarParameterModel.wrap(paramModel);
 
         final Component component = getComponentFactoryRegistry()
-                .addOrReplaceComponent(container, ComponentType.SCALAR_NAME_AND_VALUE, paramModel);
+                .addOrReplaceComponent(container, id, ComponentType.SCALAR_NAME_AND_VALUE, scalarParamModel);
 
         if(component instanceof MarkupContainer) {
             val markupContainer = (MarkupContainer) component;
-            val css = paramModel.getCssClass();
+            val css = scalarParamModel.getCssClass();
             if (!_Strings.isNullOrEmpty(css)) {
                 CssClassAppender.appendCssClassTo(markupContainer, CssClassAppender.asCssStyle(css));
             }
@@ -138,7 +137,7 @@ class ActionParametersForm extends PromptFormAbstract<ActionModel> {
      *
      * @param button The button which action should be confirmed
      */
-    private void applyAreYouSure(AjaxButton button) {
+    private void applyAreYouSure(final AjaxButton button) {
         val actionModel = getActionModel();
         val action = actionModel.getMetaModel();
 
@@ -151,9 +150,9 @@ class ActionParametersForm extends PromptFormAbstract<ActionModel> {
     @Override
     public void onUpdate(final AjaxRequestTarget target, final ScalarPanelAbstract scalarPanelUpdated) {
 
-        val actionModel = getActionModel();
-        val paramModel = (ParameterUiModel)scalarPanelUpdated.getModel();
-        final int paramNumberUpdated = paramModel.getNumber();
+        final var actionModel = getActionModel();
+        final var updatedParamModel = (ParameterUiModel)scalarPanelUpdated.getModel();
+        final int paramNumberUpdated = updatedParamModel.getNumber();
         // only updates subsequent parameter panels starting from (paramNumberUpdated + 1)
         final int skipCount = paramNumberUpdated + 1;
 
@@ -161,11 +160,11 @@ class ActionParametersForm extends PromptFormAbstract<ActionModel> {
 
         actionModel.streamPendingParamUiModels()
         .skip(skipCount)
-        .forEach(argAndConsents->{
+        .forEach(paramModel->{
 
-            val paramNumToUpdate = argAndConsents.getParamModel().getNumber();
-            val paramPanel = paramPanels.get(paramNumToUpdate);
-            val repaint = paramPanel.updateIfNecessary(argAndConsents, Optional.of(target));
+            final var paramNumToUpdate = paramModel.getNumber();
+            final var paramPanel = paramPanels.get(paramNumToUpdate);
+            final var repaint = paramPanel.updateIfNecessary(paramModel, Optional.of(target));
 
             switch (repaint) {
             case ENTIRE_FORM:
diff --git a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/entity/fieldset/PropertyGroup.java b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/entity/fieldset/PropertyGroup.java
index 913c739..0de2885 100644
--- a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/entity/fieldset/PropertyGroup.java
+++ b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/entity/fieldset/PropertyGroup.java
@@ -18,21 +18,19 @@
  */
 package org.apache.isis.viewer.wicket.ui.components.entity.fieldset;
 
-import java.util.Collections;
 import java.util.List;
 import java.util.function.Consumer;
-import java.util.stream.Collectors;
 
 import org.apache.wicket.Component;
 import org.apache.wicket.MarkupContainer;
 import org.apache.wicket.markup.html.WebMarkupContainer;
 import org.apache.wicket.markup.html.basic.Label;
 import org.apache.wicket.markup.repeater.RepeatingView;
+import org.apache.wicket.model.IModel;
 
 import org.apache.isis.applib.annotation.ActionLayout;
 import org.apache.isis.applib.annotation.Where;
 import org.apache.isis.applib.layout.component.FieldSet;
-import org.apache.isis.applib.layout.component.PropertyLayoutData;
 import org.apache.isis.commons.collections.Can;
 import org.apache.isis.commons.internal.base._NullSafe;
 import org.apache.isis.commons.internal.base._Strings;
@@ -40,9 +38,9 @@ import org.apache.isis.commons.internal.collections._Lists;
 import org.apache.isis.core.metamodel.facets.all.hide.HiddenFacet;
 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.ObjectAssociation;
 import org.apache.isis.core.metamodel.spec.feature.OneToOneAssociation;
 import org.apache.isis.viewer.common.model.components.ComponentType;
+import org.apache.isis.viewer.common.model.feature.ScalarUiModel;
 import org.apache.isis.viewer.wicket.model.links.LinkAndLabel;
 import org.apache.isis.viewer.wicket.model.models.EntityModel;
 import org.apache.isis.viewer.wicket.model.models.ScalarModel;
@@ -69,7 +67,7 @@ public class PropertyGroup extends PanelAbstract<ManagedObject, EntityModel> imp
     private static final String ID_PROPERTY = "property";
 
     private final FieldSet fieldSet;
-    private final List<ScalarPanelAbstract> childScalarPanelAbstract2s;
+    private final Can<ScalarPanelAbstract> childScalarPanels;
     private final List<Component> childComponents;
 
     public PropertyGroup(final String id, final EntityModel model, final FieldSet fieldSet) {
@@ -78,11 +76,11 @@ public class PropertyGroup extends PanelAbstract<ManagedObject, EntityModel> imp
 
         // the UI is only ever built once.
         childComponents = buildGui();
-        childScalarPanelAbstract2s =
+        childScalarPanels =
                 _NullSafe.stream(childComponents)
                 .filter(ScalarPanelAbstract.class::isInstance)
                 .map(ScalarPanelAbstract.class::cast)
-                .collect(Collectors.toList());
+                .collect(Can.toCan());
 
     }
 
@@ -91,11 +89,10 @@ public class PropertyGroup extends PanelAbstract<ManagedObject, EntityModel> imp
         return (EntityModel) getDefaultModel();
     }
 
-
-
     private List<Component> buildGui() {
 
         final List<Component> childComponents = _Lists.newArrayList();
+        final List<LinkAndLabel> memberGroupActions = _Lists.newArrayList();
 
         setOutputMarkupPlaceholderTag(true);
         setOutputMarkupId(true);
@@ -103,28 +100,24 @@ public class PropertyGroup extends PanelAbstract<ManagedObject, EntityModel> imp
         final WebMarkupContainer div = new WebMarkupContainer(ID_MEMBER_GROUP);
         div.setMarkupId("fieldSet-" + fieldSet.getId());
 
-        String groupName = fieldSet.getName();
-
-        val associations = getObjectAssociations();
-
-        final List<LinkAndLabel> memberGroupActions = _Lists.newArrayList();
         final RepeatingView propertyRv = new RepeatingView(ID_PROPERTIES);
         div.addOrReplace(propertyRv);
 
-        for (val association : associations) {
+        final var properties = getPropertiesNotStaticallyHidden();
+
+        for (OneToOneAssociation property : properties) {
             final WebMarkupContainer propertyRvContainer = new WebMarkupContainer(propertyRv.newChildId());
             propertyRv.addOrReplace(propertyRvContainer);
-            final Component component = addPropertyToForm(getModel(), (OneToOneAssociation) association,
-                    propertyRvContainer, memberGroupActions::add);
-            childComponents.add(component);
+            childComponents.add(
+                    addPropertyToForm(getModel(), property, propertyRvContainer, memberGroupActions::add));
         }
 
         WebMarkupContainer panelHeading = new WebMarkupContainer("panelHeading");
         div.addOrReplace(panelHeading);
-        if(_Strings.isNullOrEmpty(groupName)) {
+        if(_Strings.isNullOrEmpty(fieldSet.getName())) {
             panelHeading.setVisibilityAllowed(false);
         } else {
-            panelHeading.addOrReplace(new Label(ID_MEMBER_GROUP_NAME, groupName));
+            panelHeading.addOrReplace(new Label(ID_MEMBER_GROUP_NAME, fieldSet.getName()));
             final Can<LinkAndLabel> actionsPanel = LinkAndLabel
                     .positioned(ActionLayout.Position.PANEL, memberGroupActions.stream());
             final Can<LinkAndLabel> actionsPanelDropDown = LinkAndLabel
@@ -140,7 +133,7 @@ public class PropertyGroup extends PanelAbstract<ManagedObject, EntityModel> imp
         }
 
         // either add the built content, or hide entire
-        if(associations.isEmpty()) {
+        if(properties.isEmpty()) {
             Components.permanentlyHide(this, div.getId());
         } else {
             this.addOrReplace(div);
@@ -149,18 +142,10 @@ public class PropertyGroup extends PanelAbstract<ManagedObject, EntityModel> imp
         return childComponents;
     }
 
-    private List<ObjectAssociation> getObjectAssociations() {
-        final List<PropertyLayoutData> properties = this.fieldSet.getProperties();
-        // changed to NO_CHECK because more complex BS3 layouts trip concurrency exception
-        // (haven't investigated as to why).
-        val adapter = getModel().getManagedObject();
-        return getObjectAssociations(properties, adapter);
-    }
-
-    private List<ObjectAssociation> getObjectAssociations(
-            final List<PropertyLayoutData> properties,
-            final ManagedObject adapter) {
+    private Can<OneToOneAssociation> getPropertiesNotStaticallyHidden() {
 
+        final var entity = getModel().getManagedObject();
+        final var propertyLayouts = this.fieldSet.getProperties();
         //
         // previously we filtered out any invisible properties.
         // However, the inline prompt/don't redirect logic introduced in 1.15.0 means that we keep the same page,
@@ -170,28 +155,25 @@ public class PropertyGroup extends PanelAbstract<ManagedObject, EntityModel> imp
         // or not moves to ScalarPanelAbstract2#onConfigure(...)
         //
 
-        val oas = _NullSafe.stream(properties)
-                .filter(propertyLayoutData -> propertyLayoutData.getMetadataError() == null)
-                .map(propertyLayoutData ->
-                    adapter.getSpecification()
-                    .getAssociation(propertyLayoutData.getId())
-                    .orElse(null)
-                )
-                .filter(_NullSafe::isPresent)
-                .filter(objectAssociation -> {
-                    val hiddenFacet = objectAssociation.getFacet(HiddenFacet.class);
-                    if(hiddenFacet != null) {
-                        // static invisible.
-                        if(hiddenFacet.where().isAlways()
-                                || hiddenFacet.where() == Where.OBJECT_FORMS) {
-                            return false;
-                        }
-                    }
-                    return true;
-                })
-                .collect(Collectors.toList());
-
-        return Collections.unmodifiableList(oas);
+        return _NullSafe.stream(propertyLayouts)
+        .filter(propertyLayoutData -> propertyLayoutData.getMetadataError() == null)
+        .map(propertyLayoutData ->
+            entity.getSpecification().getProperty(propertyLayoutData.getId())
+            .orElse(null)
+        )
+        .filter(_NullSafe::isPresent)
+        .filter(property -> {
+            val hiddenFacet = property.getFacet(HiddenFacet.class);
+            if(hiddenFacet != null) {
+                // static invisible.
+                if(hiddenFacet.where().isAlways()
+                        || hiddenFacet.where() == Where.OBJECT_FORMS) {
+                    return false;
+                }
+            }
+            return true;
+        })
+        .collect(Can.toCan());
     }
 
     private Component addPropertyToForm(
@@ -203,25 +185,24 @@ public class PropertyGroup extends PanelAbstract<ManagedObject, EntityModel> imp
         final ScalarModel scalarModel =
                 entityModel.getPropertyModel(property, EntityModel.Mode.VIEW, EntityModel.RenderingHint.REGULAR);
 
-        final Component component = getComponentFactoryRegistry()
+        final Component scalarNameAndValueComponent = getComponentFactoryRegistry()
                 .addOrReplaceComponent(container, ID_PROPERTY, ComponentType.SCALAR_NAME_AND_VALUE, scalarModel);
-        if(component instanceof MarkupContainer) {
-            String identifier = scalarModel.getIdentifier();
-            CssClassAppender.appendCssClassTo((MarkupContainer)component, identifier);
+        if(scalarNameAndValueComponent instanceof MarkupContainer) {
+            CssClassAppender.appendCssClassTo((MarkupContainer)scalarNameAndValueComponent, scalarModel.getIdentifier());
         }
 
-        val adapter = entityModel.getManagedObject();
-        val associatedActions = ObjectAction.Util.findForAssociation(adapter, property);
+        val entity = entityModel.getManagedObject();
+        val associatedActions = ObjectAction.Util.findForAssociation(entity, property);
 
         LinkAndLabelUtil.asActionLinksForAdditionalLinksPanel(entityModel, associatedActions, null)
         .forEach(onEntityAction);
 
-        return component;
+        return scalarNameAndValueComponent;
     }
 
     @Override
     public void onConfigure() {
-        for (final ScalarPanelAbstract childComponent : childScalarPanelAbstract2s) {
+        for (final ScalarPanelAbstract childComponent : childScalarPanels) {
             childComponent.configure();
         }
         super.onConfigure();
@@ -236,12 +217,12 @@ public class PropertyGroup extends PanelAbstract<ManagedObject, EntityModel> imp
         // TODO: should remove this hack.  We need some sort of SPI for ScalarPanelAbstract2's and any other component,
         // (eg PdfJsViewer) that can implement.  It's "probably" just a matter of having PdfJsViewer do its work in the
         // correct Wicket callback (probably onConfigure).
-        if(childComponents.size() > childScalarPanelAbstract2s.size()) {
+        if(childComponents.size() > childScalarPanels.size()) {
             return true;
         }
         // HACK:END
 
-        for (final ScalarPanelAbstract childComponent : childScalarPanelAbstract2s) {
+        for (final ScalarPanelAbstract childComponent : childScalarPanels) {
             if(childComponent.isVisibilityAllowed()) {
                 return true;
             }
diff --git a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/ScalarPanelAbstract.java b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/ScalarPanelAbstract.java
index 7593a65..d4b8d7e 100644
--- a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/ScalarPanelAbstract.java
+++ b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/ScalarPanelAbstract.java
@@ -53,8 +53,8 @@ import org.apache.isis.core.metamodel.spec.ManagedObject;
 import org.apache.isis.core.metamodel.spec.ManagedObjects;
 import org.apache.isis.core.metamodel.spec.ObjectSpecification;
 import org.apache.isis.core.metamodel.spec.feature.ObjectAction;
-import org.apache.isis.viewer.common.model.action.form.FormPendingParamUiModel;
 import org.apache.isis.viewer.common.model.components.ComponentType;
+import org.apache.isis.viewer.common.model.feature.ParameterUiModel;
 import org.apache.isis.viewer.wicket.model.links.LinkAndLabel;
 import org.apache.isis.viewer.wicket.model.models.ActionPrompt;
 import org.apache.isis.viewer.wicket.model.models.ActionPromptProvider;
@@ -119,25 +119,6 @@ implements ScalarModelSubscriber {
         NOTHING
     }
 
-    /** this is a hack for the ScalarParameterModel, which does not support usability constraints in the model*/
-    private transient Runnable postInit;
-    @Deprecated // properly implement ScalarParameterModel
-    public void postInit(final @NonNull FormPendingParamUiModel argAndConsents) {
-        this.postInit = () ->{
-            // visibility
-            val visibilityConsent = argAndConsents.getVisibilityConsent();
-            setVisible(visibilityConsent.isAllowed());
-
-            // usability
-            val usabilityConsent = argAndConsents.getUsabilityConsent();
-            if(usabilityConsent.isAllowed()) {
-                onInitializeEditable();
-            } else {
-                onInitializeReadonly(usabilityConsent.getReason());
-            }
-        };
-    }
-
     /**
      *
      * @param argsAndConsents - the action being invoked
@@ -146,19 +127,17 @@ implements ScalarModelSubscriber {
      * @return - true if changed as a result of these pending arguments.
      */
     public Repaint updateIfNecessary(
-            final @NonNull FormPendingParamUiModel argsAndConsents,
+            final @NonNull ParameterUiModel paramModel,
             final @NonNull Optional<AjaxRequestTarget> target) {
 
-        val argModel = argsAndConsents.getParamModel();
-
         // visibility
-        val visibilityConsent = argsAndConsents.getVisibilityConsent();
+        val visibilityConsent = paramModel.getPendingParameterModel().getVisibilityConsent(paramModel.getNumber());
         val visibilityBefore = isVisible();
         val visibilityAfter = visibilityConsent.isAllowed();
         setVisible(visibilityAfter);
 
         // usability
-        val usabilityConsent = argsAndConsents.getUsabilityConsent();
+        val usabilityConsent = paramModel.getPendingParameterModel().getUsabilityConsent(paramModel.getNumber());
         val usabilityBefore = isEnabled();
         val usabilityAfter = usabilityConsent.isAllowed();
         if(usabilityAfter) {
@@ -167,7 +146,7 @@ implements ScalarModelSubscriber {
             onNotEditable(usabilityConsent.getReason(), target);
         }
 
-        val paramValue = argModel.getValue();
+        val paramValue = paramModel.getValue();
         val valueChanged = !Objects.equals(scalarModel.getObject(), paramValue);
 
         if(valueChanged) {
@@ -268,12 +247,6 @@ implements ScalarModelSubscriber {
 
         final ScalarModel scalarModel = getModel();
 
-        if(postInit!=null) {
-            // ScalarParameterModel hack
-            postInit.run();
-            postInit=null;
-        } else {
-
         final String disableReasonIfAny = scalarModel.whetherDisabled();
         final boolean mustBeEditable = scalarModel.mustBeEditable();
         if (disableReasonIfAny != null) {
@@ -289,8 +262,6 @@ implements ScalarModelSubscriber {
                 onInitializeEditable();
             }
         }
-        }
-
 
     }
 
diff --git a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/ScalarPanelSelectAbstract.java b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/ScalarPanelSelectAbstract.java
index 236a04d..4261465 100644
--- a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/ScalarPanelSelectAbstract.java
+++ b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/ScalarPanelSelectAbstract.java
@@ -33,7 +33,7 @@ import org.apache.wicket.validation.ValidationError;
 import org.wicketstuff.select2.ChoiceProvider;
 
 import org.apache.isis.core.runtime.memento.ObjectMemento;
-import org.apache.isis.viewer.common.model.action.form.FormPendingParamUiModel;
+import org.apache.isis.viewer.common.model.feature.ParameterUiModel;
 import org.apache.isis.viewer.wicket.model.models.ScalarModel;
 import org.apache.isis.viewer.wicket.ui.components.widgets.bootstrap.FormGroup;
 import org.apache.isis.viewer.wicket.ui.components.widgets.select2.Select2;
@@ -176,10 +176,10 @@ public abstract class ScalarPanelSelectAbstract extends ScalarPanelAbstract {
      */
     @Override
     public Repaint updateIfNecessary(
-            final @NonNull FormPendingParamUiModel argAndConsents,
+            final @NonNull ParameterUiModel paramModel,
             final @NonNull Optional<AjaxRequestTarget> target) {
 
-        val repaint = super.updateIfNecessary(argAndConsents, target);
+        val repaint = super.updateIfNecessary(paramModel, target);
         final boolean choicesUpdated = updateChoices();
 
         if (repaint == Repaint.NOTHING) {
diff --git a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/markup/MarkupComponent.java b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/markup/MarkupComponent.java
index d263a01..04a7df1 100644
--- a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/markup/MarkupComponent.java
+++ b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/markup/MarkupComponent.java
@@ -28,7 +28,7 @@ import org.apache.wicket.model.IModel;
 
 import org.apache.isis.core.metamodel.spec.ManagedObject;
 import org.apache.isis.core.metamodel.spec.feature.ObjectFeature;
-import org.apache.isis.viewer.wicket.model.models.ScalarParameterModel;
+import org.apache.isis.viewer.common.model.feature.ParameterUiModel;
 import org.apache.isis.viewer.wicket.model.models.ScalarPropertyModel;
 import org.apache.isis.viewer.wicket.model.models.ValueModel;
 
@@ -88,8 +88,8 @@ public class MarkupComponent extends WebComponent {
         if(model instanceof ScalarPropertyModel) {
             return Optional.of(((ScalarPropertyModel)model).getMetaModel());
         }
-        if(model instanceof ScalarParameterModel) {
-            return Optional.of(((ScalarParameterModel)model).getMetaModel());
+        if(model instanceof ParameterUiModel) {
+            return Optional.of(((ParameterUiModel)model).getMetaModel());
         }
         if(model instanceof ValueModel) {
             return Optional.ofNullable(((ValueModel)model).getActionModelHint())
diff --git a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/markup/MarkupPanelFactories.java b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/markup/MarkupPanelFactories.java
index c3677c9..19e3749 100644
--- a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/markup/MarkupPanelFactories.java
+++ b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/markup/MarkupPanelFactories.java
@@ -63,15 +63,11 @@ public class MarkupPanelFactories {
                 return ApplicationAdvice.DOES_NOT_APPLY;
             }
 
-            val scalarModel = (ScalarModel) model;
+            final var scalarModel = (ScalarModel) model;
+            final var scalarSpec = scalarModel.getTypeOfSpecification();
+            final var scalarType = scalarSpec.getCorrespondingClass();
 
-            val scalarType = scalarModel.getTypeOfSpecification().getCorrespondingClass();
-
-            if(scalarType.equals(valueType)) {
-                return ApplicationAdvice.APPLIES;
-            }
-
-            return appliesIf(valueType.isAssignableFrom(scalarType) );
+            return appliesIf(scalarType.equals(valueType));
 
         }
 
@@ -98,8 +94,10 @@ public class MarkupPanelFactories {
 
         @Override
         public ApplicationAdvice appliesTo(final IModel<?> model) {
-            if (!(model instanceof ValueModel))
+            if (!(model instanceof ValueModel)) {
                 return ApplicationAdvice.DOES_NOT_APPLY;
+            }
+
             val valueModel = (ValueModel) model;
             val objectAdapter = valueModel.getObject();
             if(objectAdapter==null || objectAdapter.getPojo()==null) {
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 53fb9ba..43d3fb1 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
@@ -20,7 +20,6 @@ package org.apache.isis.viewer.wicket.ui.components.widgets.select2.providers;
 
 import org.apache.isis.commons.collections.Can;
 import org.apache.isis.commons.internal.base._NullSafe;
-import org.apache.isis.core.metamodel.interactions.managed.ParameterNegotiationModel;
 import org.apache.isis.core.metamodel.spec.ManagedObject;
 import org.apache.isis.core.runtime.memento.ObjectMemento;
 import org.apache.isis.viewer.common.model.feature.ParameterUiModel;
@@ -35,7 +34,7 @@ extends ObjectAdapterMementoProviderAbstract {
 
     private final Can<ObjectMemento> pendingArgMementos;
 
-    public ObjectAdapterMementoProviderForReferenceParamOrPropertyAutoComplete(ScalarModel scalarModel) {
+    public ObjectAdapterMementoProviderForReferenceParamOrPropertyAutoComplete(final ScalarModel scalarModel) {
         super(scalarModel);
         val commonContext = scalarModel.getCommonContext();
         val pendingArgs = scalarModel.isParameter()
@@ -48,7 +47,7 @@ extends ObjectAdapterMementoProviderAbstract {
     }
 
     @Override
-    protected Can<ObjectMemento> obtainMementos(String term) {
+    protected Can<ObjectMemento> obtainMementos(final String term) {
 
         val scalarModel = getScalarModel();
 
@@ -56,9 +55,13 @@ extends ObjectAdapterMementoProviderAbstract {
 
             if(scalarModel.isParameter()) {
                 // recover any pendingArgs
-                val paramModel = (ParameterUiModel)scalarModel;
-                val pendingArgs = reconstructPendingArgs(paramModel, pendingArgMementos);
-                paramModel.setPendingParameterModel(pendingArgs);
+                final var paramModel = (ParameterUiModel)scalarModel;
+
+                paramModel
+                    .getPendingParameterModel()
+                    .setParamValues(
+                            reconstructPendingArgs(paramModel, pendingArgMementos));
+
             }
 
             val commonContext = super.getCommonContext();
@@ -71,7 +74,7 @@ extends ObjectAdapterMementoProviderAbstract {
 
     }
 
-    private ParameterNegotiationModel reconstructPendingArgs(
+    private Can<ManagedObject> reconstructPendingArgs(
             final ParameterUiModel parameterModel,
             final Can<ObjectMemento> pendingArgMementos) {
 
@@ -81,8 +84,7 @@ extends ObjectAdapterMementoProviderAbstract {
             .map(ManagedObject.class::cast)
             .collect(Can.toCan());
 
-       return parameterModel.getPendingParamHead()
-            .model(pendingArgsList);
+       return pendingArgsList;
     }
 
 }
diff --git a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/pages/entity/EntityPage.java b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/pages/entity/EntityPage.java
index 433c0f8..88e2df5 100644
--- a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/pages/entity/EntityPage.java
+++ b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/pages/entity/EntityPage.java
@@ -91,7 +91,7 @@ public class EntityPage extends PageAbstract {
         if (Strings.isEmpty(oid)) {
             throw new RestartResponseException(Application.get().getHomePage());
         }
-        return EntityModel.ofParameters(commonContext, parameters);
+        return EntityModel.ofPageParameters(commonContext, parameters);
     }
 
     private EntityPage(final PageParameters pageParameters, final EntityModel entityModel) {